diff --git a/bundles/org.xmind.cathy.fonts/META-INF/MANIFEST.MF b/bundles/org.xmind.cathy.fonts/META-INF/MANIFEST.MF index 1f16c918a..1a96f3eb9 100644 --- a/bundles/org.xmind.cathy.fonts/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.cathy.fonts/META-INF/MANIFEST.MF @@ -2,5 +2,5 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.xmind.cathy.fonts -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Vendor: %Bundle-Vendor diff --git a/bundles/org.xmind.cathy.fonts/pom.xml b/bundles/org.xmind.cathy.fonts/pom.xml index e1fe0ac96..57e73351d 100644 --- a/bundles/org.xmind.cathy.fonts/pom.xml +++ b/bundles/org.xmind.cathy.fonts/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.cathy.fonts - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ diff --git a/bundles/org.xmind.cathy.win32/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.cathy.win32/.settings/org.eclipse.jdt.core.prefs index 38ef78db7..8731e42f5 100644 --- a/bundles/org.xmind.cathy.win32/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.cathy.win32/.settings/org.eclipse.jdt.core.prefs @@ -63,6 +63,7 @@ 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.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 @@ -76,8 +77,10 @@ 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 @@ -87,11 +90,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -145,8 +150,10 @@ 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 @@ -339,12 +346,24 @@ 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.cathy.win32/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.cathy.win32/.settings/org.eclipse.jdt.ui.prefs index 6700fc80d..7fa345e81 100644 --- a/bundles/org.xmind.cathy.win32/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.cathy.win32/.settings/org.eclipse.jdt.ui.prefs @@ -2,7 +2,6 @@ eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true diff --git a/bundles/org.xmind.cathy.win32/META-INF/MANIFEST.MF b/bundles/org.xmind.cathy.win32/META-INF/MANIFEST.MF index 9cbf1d555..3b2247e59 100644 --- a/bundles/org.xmind.cathy.win32/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.cathy.win32/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.cathy.win32;singleton:=true -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Vendor: %providerName Fragment-Host: org.xmind.cathy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/bundles/org.xmind.cathy.win32/pom.xml b/bundles/org.xmind.cathy.win32/pom.xml index 3fdde6cab..e14039d05 100644 --- a/bundles/org.xmind.cathy.win32/pom.xml +++ b/bundles/org.xmind.cathy.win32/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.cathy.win32 - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ diff --git a/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.core.prefs index 983067665..fbe4460c8 100644 --- a/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.core.prefs @@ -76,6 +76,7 @@ org.eclipse.jdt.core.compiler.source=1.6 org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL,HIGH,NORMAL org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX,Release,ATTN +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 @@ -89,8 +90,10 @@ 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 @@ -100,11 +103,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -158,6 +163,7 @@ 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 @@ -352,12 +358,24 @@ 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 diff --git a/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.ui.prefs index f5c471f45..0043b9a7f 100644 --- a/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.cathy/.settings/org.eclipse.jdt.ui.prefs @@ -2,7 +2,6 @@ eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true diff --git a/bundles/org.xmind.cathy/Application.e4xmi b/bundles/org.xmind.cathy/Application.e4xmi index 33a57b5e4..d61b8d70c 100644 --- a/bundles/org.xmind.cathy/Application.e4xmi +++ b/bundles/org.xmind.cathy/Application.e4xmi @@ -8,7 +8,7 @@ - + @@ -44,12 +44,21 @@ stretch - - Draggable - + + + + TrimBarLayout:begining + + + TrimBarLayout:center + + + TrimBarLayout:end + + @@ -69,7 +78,7 @@ - + diff --git a/bundles/org.xmind.cathy/META-INF/MANIFEST.MF b/bundles/org.xmind.cathy/META-INF/MANIFEST.MF index 20c4865a1..bc188f91b 100644 --- a/bundles/org.xmind.cathy/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.cathy/META-INF/MANIFEST.MF @@ -1,35 +1,23 @@ Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.cathy;singleton:=true -Bundle-Version: 3.6.51.qualifier -Bundle-Activator: org.xmind.cathy.internal.CathyPlugin -Bundle-Vendor: %providerName -Export-Package: org.xmind.cathy.internal;x-internal:=true, - org.xmind.cathy.internal.css;x-internal:=true, - org.xmind.cathy.internal.dashboard;x-internal:=true, - org.xmind.cathy.internal.handlers;x-internal:=true, - org.xmind.cathy.internal.jobs;x-internal:=true, - org.xmind.cathy.internal.renderer;x-internal:=true, - org.xmind.ui.internal.e4handlers;x-internal:=true Require-Bundle: org.eclipse.core.runtime, org.eclipse.ui, - org.xmind.core.command;bundle-version="[3.6.0,3.7.0)", - org.xmind.core.command.remote;bundle-version="[3.6.0,3.7.0)", - org.xmind.ui;bundle-version="[3.6.0,3.7.0)", - org.xmind.ui.imports;bundle-version="[3.6.0,3.7.0)", - org.xmind.ui.toolkit;bundle-version="[3.6.0,3.7.0)", + 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, - org.eclipse.e4.core.contexts, javax.annotation, org.eclipse.e4.core.services, org.eclipse.e4.ui.services, @@ -39,12 +27,27 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.expressions, org.eclipse.e4.core.commands, org.xmind.ui.dashboard, - org.xmind.core.usagedata;bundle-version="[3.6.50,3.7.0)", + org.xmind.core.usagedata;bundle-version="[3.7.0,3.8.0)", org.json, - org.xmind.ui.browser;bundle-version="[3.6.0,3.7.0)", - org.xmind.core.licensing;bundle-version="[3.6.51,3.7.0)" + 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 15ea9d650..dd6c0e9ac 100644 --- a/bundles/org.xmind.cathy/OSGI-INF/l10n/bundle.properties +++ b/bundles/org.xmind.cathy/OSGI-INF/l10n/bundle.properties @@ -2,15 +2,19 @@ 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=XMind{0} ({1})\n\ +productBlurb=Version: XMind{0} ({1})\n\ \n\ {2}{3}{4}\n\ {5}\n\ -{6} +\n\ +Official Website: {6} view.outline.name = Outline view.properties.name = Properties @@ -70,4 +74,30 @@ 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 \ No newline at end of file +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 diff --git a/bundles/org.xmind.cathy/build.properties b/bundles/org.xmind.cathy/build.properties index e797eabe2..4dd15c799 100644 --- a/bundles/org.xmind.cathy/build.properties +++ b/bundles/org.xmind.cathy/build.properties @@ -12,6 +12,7 @@ bin.includes = plugin.xml,\ css/,\ dashboard/,\ images/,\ - OSGI-INF/ + 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 a1a9f7bef..c6897e959 100644 --- a/bundles/org.xmind.cathy/css/default.css +++ b/bundles/org.xmind.cathy/css/default.css @@ -12,7 +12,7 @@ swt-shadow-visible:false; /*corner radius */ - swt-corner-radius:8px; + swt-corner-radius:0px; /*selected tab color */ swt-selected-tab-fill:#ffffff 100%; @@ -28,7 +28,7 @@ xmind-swt-image-visible:false; - xmind-swt-minimize-visible:true; + xmind-swt-minimize-visible:false; xmind-swt-maximize-visible:false; /*visibility of unselected tabs bg */ @@ -44,7 +44,10 @@ xmind-swt-minimize-image:url("platform:/plugin/org.xmind.cathy/icons/views/view_minimize.png"); /*tab height */ - swt-tab-height:25px; + 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{ @@ -56,14 +59,14 @@ swt-inner-keyline-color:#35a6d9; swt-shadow-visible:false; - swt-corner-radius:8px; + 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:true; + 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"); @@ -73,7 +76,7 @@ * xswt-chevron-visible:false; */ - swt-tab-height:25px; + swt-tab-height:20px; } .MPartStack>CTabItem { @@ -104,12 +107,12 @@ #org-eclipse-ui-editorss .MPartStack{ xmind-swt-minimize-visible:false; - xmind-swt-maximize-visible:true; + xmind-swt-maximize-visible:false; } #org-eclipse-ui-editorss .MPartStack.active{ xmind-swt-minimize-visible:false; - xmind-swt-maximize-visible:true; + xmind-swt-maximize-visible:false; } #org-eclipse-ui-editorss .MArea{ @@ -132,6 +135,10 @@ background-color: #ffffff; } +CTabFolder{ + swt-simple:true; +} + ToolBar{ xmind-swt-view-menu-image:url("platform:/plugin/org.xmind.cathy/images/viewmenu.png"); } @@ -140,14 +147,14 @@ ToolBar{ * Window **************************************************/ Shell.MTrimmedWindow { - margin-top: 2px; - margin-right: 3px; - margin-bottom: 3px; - margin-left: 4px; + margin-top: 0px; + margin-right: 0px; + margin-bottom: 0px; + margin-left: 0px; } .MPartSashContainer { - xmind-sash-width : 5px; + xmind-sash-width : 0px; } /************************************************** diff --git a/bundles/org.xmind.cathy/css/default_gtk.css b/bundles/org.xmind.cathy/css/default_gtk.css index a46c33e2a..88b2b32d9 100644 --- a/bundles/org.xmind.cathy/css/default_gtk.css +++ b/bundles/org.xmind.cathy/css/default_gtk.css @@ -2,41 +2,26 @@ .MPartStack{ /*hover tab color */ - xmind-swt-hover-tab-color:#ffffff; - swt-tab-height:30px; + xmind-swt-hover-tab-color:#d9d9d9; } .MPartStack.active{ /*hover tab color */ - xmind-swt-hover-tab-color:#ffffff; + xmind-swt-hover-tab-color:#d9d9d9; swt-selected-tab-fill:#35a6d9 100%; - swt-tab-height:30px; } #org-eclipse-ui-trim-status, #org-eclipse-ui-trim-status * { - color : #ffffff; + color : #000000; } Shell.MTrimmedWindow { - background-color:#ffffff #2ca5dc 100%; + background-color:#ffffff #e8e8e8 100%; } -.MToolControl.TrimStack { - frame-image: url("./gtkTSFrame.png"); - handle-image: url("./gtkHandle.png"); - frame-cuts: 5px 1px 5px 16px; -} - -.MToolControl.Draggable { - handle-image: url("./dragHandle.png"); -} - -#org-eclipse-ui-trim-status .MToolBar.Draggable { - handle-image: url("./dragHandle.png"); +MTabFolder{ + xmind-tab-folder-bg:#5f5f5f; } -MTabFolder{ - xmind-tab-folder-bg:#3ba8db; -} \ No newline at end of file diff --git a/bundles/org.xmind.cathy/css/default_mac.css b/bundles/org.xmind.cathy/css/default_mac.css index 0e924cd39..31ddb5cfc 100644 --- a/bundles/org.xmind.cathy/css/default_mac.css +++ b/bundles/org.xmind.cathy/css/default_mac.css @@ -21,20 +21,6 @@ Shell.MTrimmedWindow { background-color:#f7f7f7 #e5e5e5 100%; } -.MToolControl.TrimStack { - frame-image: url("./macTSFrame.png"); - handle-image: url("./macHandle.png"); - frame-cuts: 5px 1px 5px 16px; -} - -.MToolControl.Draggable { - handle-image: url("./dragHandle.png"); -} - -#org-eclipse-ui-trim-status .MToolBar.Draggable { - handle-image: url("./dragHandle.png"); -} - MTabFolder{ xmind-tab-folder-bg:#5f5f5f; -} \ No newline at end of file +} diff --git a/bundles/org.xmind.cathy/css/default_win.css b/bundles/org.xmind.cathy/css/default_win.css index 9cd95c3ee..88b2b32d9 100644 --- a/bundles/org.xmind.cathy/css/default_win.css +++ b/bundles/org.xmind.cathy/css/default_win.css @@ -14,28 +14,14 @@ #org-eclipse-ui-trim-status, #org-eclipse-ui-trim-status * { - color : #ffffff; + color : #000000; } Shell.MTrimmedWindow { - background-color:#ffffff #1e7dd2 100%; -} - -.MToolControl.TrimStack { - frame-image: url("./winTSFrame.png"); - handle-image: url("./winHandle.png"); - frame-cuts: 5px 1px 5px 16px; -} - -.MToolControl.Draggable { - handle-image: url("./dragHandle.png"); -} - -#org-eclipse-ui-trim-status .MToolBar.Draggable { - handle-image: url("./dragHandle.png"); + background-color:#ffffff #e8e8e8 100%; } MTabFolder{ - xmind-tab-folder-bg:#1e7dd2; + 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 cfe4c3feb..d04b4993e 100644 --- a/bundles/org.xmind.cathy/css/default_win7.css +++ b/bundles/org.xmind.cathy/css/default_win7.css @@ -14,28 +14,14 @@ #org-eclipse-ui-trim-status, #org-eclipse-ui-trim-status * { - color : #ffffff; + color : #000000; } Shell.MTrimmedWindow { - background-color:#ffffff #2ca5dc 100%; -} - -.MToolControl.TrimStack { - frame-image: url("./winTSFrame.png"); - handle-image: url("./winHandle.png"); - frame-cuts: 5px 1px 5px 16px; -} - -.MToolControl.Draggable { - handle-image: url("./dragHandle.png"); -} - -#org-eclipse-ui-trim-status .MToolBar.Draggable { - handle-image: url("./dragHandle.png"); + background-color:#ffffff #e8e8e8 100%; } MTabFolder{ - xmind-tab-folder-bg:#3ba8db; + 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 d722c07ca..b9776f710 100644 --- a/bundles/org.xmind.cathy/css/default_win8.css +++ b/bundles/org.xmind.cathy/css/default_win8.css @@ -18,21 +18,7 @@ } Shell.MTrimmedWindow { - background-color:#ffffff #f2f2f2 100%; -} - -.MToolControl.TrimStack { - frame-image: url("./win8TSFrame.png"); - handle-image: url("./win8Handle.png"); - frame-cuts: 5px 1px 5px 16px; -} - -.MToolControl.Draggable { - handle-image: url("./dragHandle.png"); -} - -#org-eclipse-ui-trim-status .MToolBar.Draggable { - handle-image: url("./dragHandle.png"); + background-color:#ffffff #e8e8e8 100%; } MTabFolder{ diff --git a/bundles/org.xmind.cathy/dashboard/back.png b/bundles/org.xmind.cathy/dashboard/back.png index b61c8753a..2b59437f8 100644 Binary files a/bundles/org.xmind.cathy/dashboard/back.png and b/bundles/org.xmind.cathy/dashboard/back.png differ diff --git a/bundles/org.xmind.cathy/dashboard/back@2x.png b/bundles/org.xmind.cathy/dashboard/back@2x.png index 7b2a8f0ae..152f1c381 100644 Binary files a/bundles/org.xmind.cathy/dashboard/back@2x.png and b/bundles/org.xmind.cathy/dashboard/back@2x.png differ diff --git a/bundles/org.xmind.cathy/dashboard/cloud.png b/bundles/org.xmind.cathy/dashboard/cloud.png index 847b9a507..24d97e33c 100644 Binary files a/bundles/org.xmind.cathy/dashboard/cloud.png and b/bundles/org.xmind.cathy/dashboard/cloud.png differ diff --git a/bundles/org.xmind.cathy/dashboard/cloud@2x.png b/bundles/org.xmind.cathy/dashboard/cloud@2x.png index b8fb15f36..9d6f09172 100644 Binary files a/bundles/org.xmind.cathy/dashboard/cloud@2x.png and b/bundles/org.xmind.cathy/dashboard/cloud@2x.png differ diff --git a/bundles/org.xmind.cathy/dashboard/dashboard.properties b/bundles/org.xmind.cathy/dashboard/dashboard.properties index 0ae40c518..a4db2ccf7 100644 --- a/bundles/org.xmind.cathy/dashboard/dashboard.properties +++ b/bundles/org.xmind.cathy/dashboard/dashboard.properties @@ -3,4 +3,4 @@ open=Open recent=Recent cloud=Cloud preferences=Preferences -back=Back +back=Workspace diff --git a/bundles/org.xmind.cathy/dashboard/dashboard.xml b/bundles/org.xmind.cathy/dashboard/dashboard.xml index 99a3af659..0fabd475a 100644 --- a/bundles/org.xmind.cathy/dashboard/dashboard.xml +++ b/bundles/org.xmind.cathy/dashboard/dashboard.xml @@ -7,7 +7,7 @@ iconURI="platform:/plugin/org.xmind.cathy/dashboard/back.png" commandId="org.eclipse.ui.file.closePart"> - + - + + contributionURI="bundleclass://org.xmind.cathy/org.xmind.cathy.internal.dashboard.RecentFileGridDashboardPage"> - + - + - + + value="org.xmind.ui.prefPage.General"> - + \ No newline at end of file diff --git a/bundles/org.xmind.cathy/dashboard/new.png b/bundles/org.xmind.cathy/dashboard/new.png index 77d78cc3c..6514fd1e3 100644 Binary files a/bundles/org.xmind.cathy/dashboard/new.png and b/bundles/org.xmind.cathy/dashboard/new.png differ diff --git a/bundles/org.xmind.cathy/dashboard/new/button_import.png b/bundles/org.xmind.cathy/dashboard/new/button_import.png new file mode 100644 index 000000000..c40812b94 Binary files /dev/null and b/bundles/org.xmind.cathy/dashboard/new/button_import.png differ diff --git a/bundles/org.xmind.cathy/dashboard/new/button_import@2x.png b/bundles/org.xmind.cathy/dashboard/new/button_import@2x.png new file mode 100644 index 000000000..db2ecf3f3 Binary files /dev/null and b/bundles/org.xmind.cathy/dashboard/new/button_import@2x.png differ diff --git a/bundles/org.xmind.cathy/dashboard/new/button_import_hover.png b/bundles/org.xmind.cathy/dashboard/new/button_import_hover.png new file mode 100644 index 000000000..e83c4aad8 Binary files /dev/null and b/bundles/org.xmind.cathy/dashboard/new/button_import_hover.png differ diff --git a/bundles/org.xmind.cathy/dashboard/new/button_import_hover@2x.png b/bundles/org.xmind.cathy/dashboard/new/button_import_hover@2x.png new file mode 100644 index 000000000..d15f12fa4 Binary files /dev/null and b/bundles/org.xmind.cathy/dashboard/new/button_import_hover@2x.png differ diff --git a/bundles/org.xmind.cathy/dashboard/new/structures.properties b/bundles/org.xmind.cathy/dashboard/new/structures.properties index 661f3304e..58158eb9d 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_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 142418902..48c3d8c62 100644 --- a/bundles/org.xmind.cathy/dashboard/new/structures.xml +++ b/bundles/org.xmind.cathy/dashboard/new/structures.xml @@ -1,5 +1,5 @@ - + + + + + + + + + + + + - + + + + + 4.0.0 org.xmind.cathy.plugins org.xmind.cathy - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ diff --git a/bundles/org.xmind.cathy/resource/Welcome to XMind.xmind b/bundles/org.xmind.cathy/resource/Welcome to XMind.xmind index 2e44bc37a..bf7baa198 100644 Binary files a/bundles/org.xmind.cathy/resource/Welcome to XMind.xmind and b/bundles/org.xmind.cathy/resource/Welcome to XMind.xmind differ diff --git a/bundles/org.xmind.cathy/splash.bmp b/bundles/org.xmind.cathy/splash.bmp index c20a152a5..3306764e9 100644 Binary files a/bundles/org.xmind.cathy/splash.bmp and b/bundles/org.xmind.cathy/splash.bmp differ diff --git a/bundles/org.xmind.cathy/splash@2x.bmp b/bundles/org.xmind.cathy/splash@2x.bmp deleted file mode 100644 index fa3a2ce9c..000000000 Binary files a/bundles/org.xmind.cathy/splash@2x.bmp and /dev/null differ 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 163b95172..0bd3431ce 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 @@ -13,6 +13,7 @@ *******************************************************************************/ package org.xmind.cathy.internal; +import java.awt.Toolkit; import java.io.File; import org.eclipse.core.runtime.IConfigurationElement; @@ -100,6 +101,12 @@ public Object start(IApplicationContext context) throws Exception { // 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; @@ -177,6 +184,13 @@ private void captureAppSessionInfo(IUsageDataSampler sampler, 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) { 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 36074bd95..d077c2e8a 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 @@ -43,6 +43,11 @@ 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. */ @@ -152,7 +157,7 @@ public class CathyPlugin extends AbstractUIPlugin { /** * Online help page. */ - public static final String ONLINE_HELP_URL = "http://www.xmind.net/xmind/help/"; //$NON-NLS-1$ + public static final String ONLINE_HELP_URL = "https://www.xmind.net/xmind/help"; //$NON-NLS-1$ /** * Boolean value:
@@ -198,6 +203,11 @@ public CathyPlugin() { 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(); @@ -225,7 +235,7 @@ private IStatus toStatus(int severity, String message, } }; - activateNetworkSettings(); +// activateNetworkSettings(); activateXMindCore(); @@ -270,7 +280,7 @@ public void stop(BundleContext context) throws Exception { plugin = null; } - private void activateNetworkSettings() { + public void activateNetworkSettings() { Bundle networkPlugin = Platform.getBundle("org.eclipse.core.net"); //$NON-NLS-1$ if (networkPlugin != null) { try { @@ -517,4 +527,4 @@ public static T getAdapter(Object obj, Class adapter) { return null; } -} \ 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 e154fdea5..6c7588fbd 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 @@ -78,7 +78,7 @@ public String getInitialWindowPerspectiveId() { @Override public String getMainPreferencePageId() { - return "org.eclipse.ui.preferencePages.Workbench"; //$NON-NLS-1$ + return "org.xmind.ui.prefPage.General"; //$NON-NLS-1$ } public void initialize(IWorkbenchConfigurer configurer) { 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 e479f7465..2e884ba61 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 @@ -62,7 +62,7 @@ public class CathyWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor private TitlePathUpdater titlePathUpdater; - private boolean homeShowing = true; + private boolean homeShowing = false; public CathyWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) { super(configurer); @@ -131,6 +131,11 @@ private void addE4PartListener() { 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); @@ -257,27 +262,30 @@ private void doUpdateWindowTitle() { WorkbenchMessages.CathyWorkbenchWindowAdvisor_windowTitle_home_prefix); } - sb.append(WorkbenchMessages.AppWindowTitle); - if (licenseName != null) { - sb.append(' '); - sb.append(licenseName); - } IWorkbenchPage page = window.getActivePage(); + IEditorPart editor = null; if (page != null) { - IEditorPart editor = page.getActiveEditor(); - if (editor != null) { - sb.append(" - "); //$NON-NLS-1$ - 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); + 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) { @@ -343,4 +351,4 @@ public void propertyChanged(Object source, int propId) { // }); // } -} \ 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 new file mode 100644 index 000000000..d3a69477a --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/GeneralPreferencePageSection.java @@ -0,0 +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(); + } + +} 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 new file mode 100644 index 000000000..bb86d66c5 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/IApplicationValidator.java @@ -0,0 +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(); + +} \ 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 a2c0fb0d3..fc1cc5a5e 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,5 +1,7 @@ package org.xmind.cathy.internal; +import org.eclipse.e4.ui.internal.workbench.swt.AbstractPartRenderer; + public interface ICathyConstants { /* @@ -10,6 +12,10 @@ public interface ICathyConstants { 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 */ @@ -20,6 +26,8 @@ public interface ICathyConstants { 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$ @@ -78,6 +86,10 @@ public interface ICathyConstants { 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 */ @@ -86,6 +98,7 @@ public interface ICathyConstants { /* * 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$ /* @@ -99,10 +112,17 @@ public interface ICathyConstants { */ 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/LanguagePreferencePageSection.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LanguagePreferencePageSection.java new file mode 100644 index 000000000..016f311ed --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/LanguagePreferencePageSection.java @@ -0,0 +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() { + } + +} 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 new file mode 100644 index 000000000..ace785d33 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/RecentFilesPreferencePageSection.java @@ -0,0 +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); + } + +} 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 new file mode 100644 index 000000000..8940d08f1 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/SaveBackupPreferencePageSection.java @@ -0,0 +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; + } +} 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 new file mode 100644 index 000000000..124015a71 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/StartupPreferencePageSection.java @@ -0,0 +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; + } +} 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 d1164c987..8b3698502 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,6 +1,8 @@ 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; @@ -12,6 +14,7 @@ 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; @@ -21,6 +24,7 @@ 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; @@ -32,7 +36,6 @@ import org.xmind.ui.resources.FontUtils; /** - * * @author Shawn Liu * @since 3.6.50 */ @@ -60,10 +63,10 @@ protected void configureShell(Shell newShell) { protected Control createContents(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setBackground( - (Color) resources.get(ColorUtils.toDescriptor("#e8e8e8"))); //$NON-NLS-1$ + (Color) resources.get(ColorUtils.toDescriptor("#cccccc"))); //$NON-NLS-1$ GridData gridData = new GridData(GridData.FILL_BOTH); - gridData.widthHint = 580; - gridData.heightHint = 500; + gridData.widthHint = 743; + gridData.heightHint = 432; composite.setLayoutData(gridData); GridLayout gridLayout = new GridLayout(1, false); @@ -84,7 +87,7 @@ protected Control createContents(Composite parent) { composite2.setLayout(gridLayout2); createTopSection(composite2); - createSeperator(composite2); +// createSeperator(composite2); createBottomSection(composite2); return composite; @@ -94,8 +97,8 @@ 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 = 578; - layoutData.heightHint = 220; + layoutData.widthHint = 740; + layoutData.heightHint = 120; composite.setLayoutData(layoutData); GridLayout layout = new GridLayout(1, false); @@ -105,7 +108,7 @@ private void createTopSection(Composite parent) { composite.setLayout(layout); createHeaderSection(composite); - createImageSection(composite); + createTitleSection(composite); createPlaceholderComposite(composite); } @@ -157,12 +160,13 @@ private void createCloseButtonSection(Composite parent) { close.setBackground(composite2.getBackground()); close.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); - final Image focusedImage = CathyPlugin.imageDescriptorFromPlugin( - CathyPlugin.PLUGIN_ID, "icons/welcome/close.png").createImage(); //$NON-NLS-1$ - final Image noFocusedImage = CathyPlugin - .imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "icons/welcome/close-d.png") //$NON-NLS-1$ - .createImage(); + 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); @@ -236,46 +240,72 @@ public void handleEvent(Event event) { return listener; } - private void createImageSection(Composite parent) { + 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(1, false); + GridLayout layout = new GridLayout(2, false); layout.marginWidth = 0; layout.marginHeight = 0; + layout.horizontalSpacing = 31; + layout.marginLeft = 47; composite.setLayout(layout); - 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(CathyPlugin - .imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "icons/welcome/welcome-xmind-logo.png") //$NON-NLS-1$ - .createImage()); + 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 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); @@ -283,12 +313,7 @@ private void createBottomSection(Composite parent) { GridData gridData = new GridData(GridData.FILL_BOTH); composite.setLayoutData(gridData); - GridLayout gridLayout = new GridLayout(1, false); - gridLayout.marginWidth = 0; - gridLayout.marginHeight = 0; - gridLayout.marginTop = 25; - gridLayout.verticalSpacing = 0; - composite.setLayout(gridLayout); + GridLayoutFactory.fillDefaults().applyTo(composite); createNewFeatureItems(composite); createButtonSection(composite); @@ -300,18 +325,17 @@ private void createNewFeatureItems(Composite parent) { GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); composite.setLayoutData(layoutData); - GridLayout layout = new GridLayout(3, true); - layout.marginWidth = 45; + GridLayout layout = new GridLayout(4, true); + layout.marginWidth = 50; layout.marginHeight = 0; - layout.horizontalSpacing = 25; + layout.horizontalSpacing = 10; composite.setLayout(layout); createImageItem(composite, - CathyPlugin - .imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "icons/welcome/cloud.png") //$NON-NLS-1$ - .createImage(), - WorkbenchMessages.WelcomeDialog_item_cloud_title, WorkbenchMessages.WelcomeDialog_item_cloud_description, + (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() { @@ -320,11 +344,10 @@ public void run() { }); createImageItem(composite, - CathyPlugin - .imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "icons/welcome/share.png") //$NON-NLS-1$ - .createImage(), - WorkbenchMessages.WelcomeDialog_item_share_title, WorkbenchMessages.WelcomeDialog_item_share_description, + (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() { @@ -333,11 +356,23 @@ public void run() { }); createImageItem(composite, - CathyPlugin - .imageDescriptorFromPlugin(CathyPlugin.PLUGIN_ID, - "icons/welcome/icon-finder.png") //$NON-NLS-1$ - .createImage(), - WorkbenchMessages.WelcomeDialog_item_iconFinder_title, WorkbenchMessages.WelcomeDialog_item_iconFinder_description, + (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() { @@ -354,11 +389,7 @@ private void createImageItem(Composite parent, Image image, String title, GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); composite.setLayoutData(layoutData); - GridLayout layout = new GridLayout(1, false); - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.verticalSpacing = 20; - composite.setLayout(layout); + GridLayoutFactory.fillDefaults().spacing(0, 20).applyTo(composite); Label imageLabel = new Label(composite, SWT.CENTER); imageLabel.setBackground(composite.getBackground()); @@ -388,17 +419,23 @@ public void mouseDown(MouseEvent e) { layout2.verticalSpacing = 10; composite2.setLayout(layout2); -// Label titleLabel = new Label(composite2, SWT.NONE); -// titleLabel.setBackground(composite2.getBackground()); -// titleLabel.setLayoutData( -// new GridData(SWT.CENTER, SWT.CENTER, true, false)); -// titleLabel.setText(title); -// titleLabel.setFont((Font) resources -// .get(FontDescriptor.createFrom(FontUtils.relativeHeight( -// titleLabel.getFont().getFontData(), 2)))); + 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); @@ -409,8 +446,15 @@ public void mouseDown(MouseEvent e) { } private void createButtonSection(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); + 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); @@ -439,7 +483,8 @@ private void createUploadDataCheck(Composite parent) { uploadDataCheck.setBackground(composite.getBackground()); GridData gridData2 = new GridData(SWT.LEFT, SWT.CENTER, false, false); uploadDataCheck.setLayoutData(gridData2); - uploadDataCheck.setText(WorkbenchMessages.WelcomeDialog_uploadDataCheck_text); + uploadDataCheck + .setText(WorkbenchMessages.WelcomeDialog_uploadDataCheck_text); uploadDataCheck.setSelection(true); // @@ -447,10 +492,13 @@ private void createUploadDataCheck(Composite parent) { privacyHyperlink.setBackground(composite.getBackground()); privacyHyperlink.setLayoutData( new GridData(SWT.LEFT, SWT.CENTER, false, false)); - privacyHyperlink.setText(WorkbenchMessages.WelcomeDialog_seePolicy_link); + privacyHyperlink + .setText(WorkbenchMessages.WelcomeDialog_seePolicy_link); privacyHyperlink.setUnderlined(true); privacyHyperlink.setForeground( - (Color) resources.get(ColorUtils.toDescriptor("#77afe0"))); //$NON-NLS-1$ + (Color) resources.get(ColorUtils.toDescriptor("#006CF9"))); //$NON-NLS-1$ + + composite.setFocus(); privacyHyperlink.addHyperlinkListener(new IHyperlinkListener() { 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 55dd0adc9..1a2402d4c 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 @@ -28,14 +28,14 @@ public class WorkbenchMessages extends NLS { 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 RecentFiles_label; - public static String RecentFileViewer_PinThisMapAction_label; + 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; @@ -52,15 +52,10 @@ public class WorkbenchMessages extends NLS { 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; @@ -76,7 +71,6 @@ public class WorkbenchMessages extends NLS { public static String HomeMap_NotFound_error; public static String appWindow_ListSelectionDialog_Text; - public static String appWindow_ListSelectionDialog_Title; public static String KeyAssist_text; @@ -104,15 +98,10 @@ public class WorkbenchMessages extends NLS { 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; @@ -124,31 +113,18 @@ public class WorkbenchMessages extends NLS { 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; @@ -168,30 +144,23 @@ public class WorkbenchMessages extends NLS { 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_iconFinder_description; - - public static String WelcomeDialog_item_iconFinder_title; - - public static String WelcomeDialog_item_share_description; - - public static String WelcomeDialog_item_share_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; @@ -208,16 +177,11 @@ public class WorkbenchMessages extends NLS { 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; @@ -229,27 +193,29 @@ public class WorkbenchMessages extends NLS { 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); } -} \ No newline at end of file +} 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 e895dc8f9..5c180f592 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 @@ -54,7 +54,7 @@ public class CathyCTabFolderRendering extends CTabFolderRenderer // Item Constants static final int ITEM_TOP_MARGIN = 2; static final int ITEM_BOTTOM_MARGIN = 6; - static final int ITEM_LEFT_MARGIN = 4; + static final int ITEM_LEFT_MARGIN = 8; static final int ITEM_RIGHT_MARGIN = 4; static final int INTERNAL_SPACING = 4; @@ -159,15 +159,16 @@ protected Rectangle computeTrim(int part, int state, int x, int y, int tabHeight = parent.getTabHeight() + 1; y = onBottom ? y - paddingTop - marginHeight - borderTop - - (cornerSize / 4) - bottomDropWidth + - bottomDropWidth : y - paddingTop - marginHeight - tabHeight - borderTop - headerBorderBottom - - (cornerSize / 4) - bottomDropWidth; - width = 2 + paddingLeft + paddingRight + 2 * sideDropWidth + - bottomDropWidth; + width = 2 * (INNER_KEYLINE + OUTER_KEYLINE) + paddingLeft + + paddingRight + 2 * sideDropWidth + 2 * marginWidth; - height += paddingTop + paddingBottom + bottomDropWidth * 2; + height += paddingTop + paddingBottom + bottomDropWidth; height += tabHeight + headerBorderBottom + borderBottom - + cornerSize / 2 + borderTop; + + borderTop; } else { x = x - marginWidth - OUTER_KEYLINE - INNER_KEYLINE - sideDropWidth - (cornerSize / 2) - paddingLeft; @@ -181,15 +182,14 @@ protected Rectangle computeTrim(int part, int state, int x, int y, height = borderTop + borderBottom + tabHeight; } else { y = onBottom - ? y - marginHeight - borderTop - - (cornerSize / 4) - paddingTop + ? y - marginHeight - borderTop - paddingTop - bottomDropWidth : y - marginHeight - tabHeight - borderTop - - (cornerSize / 4) - paddingTop - - headerBorderBottom - bottomDropWidth; + - paddingTop - headerBorderBottom + - bottomDropWidth; height = height + borderBottom + borderTop - + 2 * marginHeight + tabHeight + cornerSize / 2 - + headerBorderBottom + bottomDropWidth * 2 + + 2 * marginHeight + tabHeight + + headerBorderBottom + bottomDropWidth + paddingTop + paddingBottom; } } @@ -427,7 +427,7 @@ protected void draw(int part, int state, Rectangle bounds, GC gc) { private void drawCloseButton(GC gc, Rectangle bounds, int state) { Image hoverImage = closeHoverImage == null ? closeImage : closeHoverImage; - switch (state & (SWT.HOT | SWT.SELECTED)) { + switch (state & (SWT.HOT | SWT.SELECTED | SWT.BACKGROUND)) { case SWT.NONE: gc.drawImage(closeImage, bounds.x, bounds.y); break; @@ -437,6 +437,8 @@ private void drawCloseButton(GC gc, Rectangle bounds, int state) { case SWT.SELECTED: gc.drawImage(hoverImage, bounds.x + 1, bounds.y + 1); break; + case SWT.BACKGROUND: + break; } } @@ -488,13 +490,12 @@ void generateTabArea(Rectangle bounds) { int radius = cornerSize / 2; int marginWidth = parent.marginWidth; int marginHeight = parent.marginHeight; - int delta = (INNER_KEYLINE + OUTER_KEYLINE) + marginWidth * 2; + 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) - - 1); + - (INNER_KEYLINE + OUTER_KEYLINE + marginHeight * 2)); int circX = bounds.x + radius + delta / 2; int circY = bounds.y + radius; @@ -502,7 +503,7 @@ void generateTabArea(Rectangle bounds) { // Body index = 0; int[] ltt = { bounds.x + delta / 2, - bounds.y + parent.getTabHeight() + 1 + delta }; + bounds.y + parent.getTabHeight() + delta }; System.arraycopy(ltt, 0, points, index, ltt.length); index += ltt.length; @@ -516,8 +517,8 @@ void generateTabArea(Rectangle bounds) { System.arraycopy(rb, 0, points, index, rb.length); index += rb.length; - int[] rt = { bounds.x + width, - bounds.y + parent.getTabHeight() + 1 + delta }; + int[] rt = { bounds.x + delta / 2 + width, + bounds.y + parent.getTabHeight() + delta }; System.arraycopy(rt, 0, points, index, rt.length); index += rt.length; @@ -539,13 +540,12 @@ void drawTabBody(GC gc, Rectangle bounds, int state) { int radius = cornerSize / 2; int marginWidth = parent.marginWidth; int marginHeight = parent.marginHeight; - int delta = (INNER_KEYLINE + OUTER_KEYLINE) + marginWidth * 2; + 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) - - 1); + - (INNER_KEYLINE + OUTER_KEYLINE + marginHeight * 2)); int circX = bounds.x + radius + delta / 2; int circY = bounds.y + radius; @@ -603,6 +603,9 @@ void drawTabBody(GC gc, Rectangle bounds, int state) { 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; @@ -614,14 +617,14 @@ void drawSelectedTab(int itemIndex, GC gc, Rectangle bounds, int state) { int 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 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; +// circX -= 1; // points[index++] = circX - radius; // points[index++] = bottomY; @@ -713,6 +716,8 @@ void drawSelectedTab(int itemIndex, GC gc, Rectangle bounds, int state) { 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, @@ -735,7 +740,7 @@ void drawSelectedTab(int itemIndex, GC gc, Rectangle bounds, int state) { outerKeyline = gc.getDevice() .getSystemColor(SWT.COLOR_BLACK); gc.setForeground(outerKeyline); - gc.drawLine(startX + 1, 0, endX, 0); + gc.drawLine(startX + 2, 1, endX - 1, 1); } } 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 1e013a24e..35d666330 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 @@ -63,7 +63,8 @@ public String retrieveCSSProperty(Object element, String property, return null; } - Integer width = (Integer)sashLayout.getFieldValue(FIELD_SASH_WIDTH, (SashLayout)layout); + 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/dashboard/CategorizedTemplateViewer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/CategorizedTemplateViewer.java new file mode 100644 index 000000000..0f5efac2d --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/CategorizedTemplateViewer.java @@ -0,0 +1,379 @@ +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() { + } + +} 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 3734b7bc5..7bc219ab1 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 @@ -13,6 +13,8 @@ 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; @@ -55,6 +57,9 @@ public void showDashboard(MWindow window) { if (doShowDashboard(window)) { updateDashboardToolItems(window); } + + //hide right parts. + hideVisiblePart(window, "org.xmind.ui.stack.right"); //$NON-NLS-1$ } @Inject @@ -184,6 +189,9 @@ public void showDashboardWhenAllEditorsAreRemoved( 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); } @@ -264,4 +272,39 @@ private void updateDashboardToolItems(MWindow window) { } } + 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 23eee4e1a..a5050ef48 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 @@ -11,6 +11,7 @@ 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; @@ -102,10 +103,15 @@ private void loadFromDefaultLocation() { } // set primary selection - tabFolder.setSelection(findPrimarySelection()); + MTabItem primarySelection = findPrimarySelection(); + tabFolder.setSelection(primarySelection); - IDashboardPage page = getDashboardPage(tabFolder.getSelection()); + 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); } } @@ -188,13 +194,14 @@ private MTabItem readPage(Element element, MTabFolder tabFolder) // ignore errors caused contribution not found return null; } - Object contribution = cls.newInstance(); + + 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); @@ -209,8 +216,8 @@ private MTabItem readPage(Element element, MTabFolder tabFolder) item.setText(page.getTitle()); item.setImage(page.getImage()); - page.createControl(this.tabFolder.getBody()); - item.setControl(page.getControl()); +// page.createControl(this.tabFolder.getBody()); +// item.setControl(page.getControl()); item.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { @@ -393,7 +400,7 @@ public IDashboardPage getDashboardPage(MTabItem item) { return data instanceof IDashboardPage ? (IDashboardPage) data : null; } - private void handlePageSelected(final IDashboardPage page) { + 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 c7d44fe5e..0e6e9a83f 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,4 +1,3 @@ - package org.xmind.cathy.internal.dashboard; import java.util.Arrays; @@ -42,6 +41,7 @@ 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; @@ -154,6 +154,10 @@ protected IEclipseContext getContext() { @PostConstruct public void postConstruct(Composite parent) { + + // + context.set(IDashboardContext.class, this); + tabFolder = new MTabFolder(parent); ResourceManager resourceManager = new LocalResourceManager( JFaceResources.getResources(), tabFolder); @@ -175,6 +179,9 @@ public void handleEvent(org.eclipse.swt.widgets.Event event) { } private void handlePageSelected() { + if (tabFolder == null || content == null) { + return; + } MTabItem item = tabFolder.getSelection(); String pageId = item == null ? null : content.getItemId(item); partModel.getTransientData() @@ -194,7 +201,7 @@ protected void executeCommand(String commandId, handlerService.executeHandler(command); } - protected void setSelectionProvider(ISelectionProvider selectionProvider) { + public void setSelectionProvider(ISelectionProvider selectionProvider) { ISelectionProvider oldSelectionProvider = this.selectionProvider; if (selectionProvider == oldSelectionProvider) return; @@ -223,7 +230,6 @@ private void handleSelectionChanged(SelectionChangedEvent event) { * 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 @@ -306,12 +312,17 @@ public void subscribeDashboardTransientData( if (selectedPageId == null || !(selectedPageId instanceof String)) return; - if (this.tabFolder == null) + 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); } @@ -319,7 +330,7 @@ public void subscribeDashboardTransientData( @Focus public void setFocus() { - if (tabFolder != null && !tabFolder.isDisposed()) { + if (tabFolder != null && !tabFolder.isDisposed() && content != null) { MTabItem item = tabFolder.getSelection(); if (item != null) { IDashboardPage page = content.getDashboardPage(item); @@ -351,27 +362,33 @@ public void registerAvailableCommandId(String commandId) { } public boolean registerContextMenu(Object menuParent, final String menuId) { - if (menuService != null) { - if (modelService != null & partModel != null) { - 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 (!(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; } - return menuService.registerContextMenu(menuParent, menuId); } - return false; + 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) { @@ -407,7 +424,6 @@ public boolean showView(final String viewId) { /* * (non-Javadoc) - * * @see * org.xmind.ui.internal.dashboard.pages.IDashboardContext#getPersistedState * (java.lang.String) @@ -420,7 +436,6 @@ public String getPersistedState(String key) { /* * (non-Javadoc) - * * @see * org.xmind.ui.internal.dashboard.pages.IDashboardContext#setPersistedState * (java.lang.String, java.lang.String) @@ -438,7 +453,6 @@ public void setPersistedState(String key, String value) { /* * (non-Javadoc) - * * @see org.xmind.ui.internal.dashboard.pages.IDashboardContext# * getContextVariable(java.lang.Class) */ @@ -448,7 +462,6 @@ public T getContextVariable(Class key) { /* * (non-Javadoc) - * * @see org.xmind.ui.internal.dashboard.pages.IDashboardContext# * getContextVariable(java.lang.String) */ @@ -456,4 +469,4 @@ public Object getContextVariable(String key) { return context.get(key); } -} \ 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 374804738..48f34610e 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,11 +1,15 @@ 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.ToolBarManager; -import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.action.IAction; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.resource.ColorDescriptor; @@ -14,39 +18,37 @@ import org.eclipse.jface.resource.ResourceManager; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.jface.util.Util; -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.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.layout.GridData; 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.eclipse.swt.widgets.ToolBar; +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.ITemplate; 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 ISelectionChangedListener { +public class NewFileDashboardPage extends DashboardPage implements IAdaptable { private class SegmentBarStyleProvider extends StyleProvider { @Override @@ -142,15 +144,29 @@ public int getAlpha(Object widget, String key, int defaultValue) { private Composite titleBar = null; private Composite rightBar = null; private MTabBar tabBar = null; - private ToolBar normalModeEditContainer = null; - private Control editModeContainer = null; - - private boolean normalOrEditMode = true; private Composite pageContainer = null; - private ITemplate selectedTemplate = null; - private Action deleteTemplatesAction = 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); @@ -178,12 +194,11 @@ public void createControl(Composite parent) { this.control = composite; - addPage(new NewFromStructuresDashboardPage(), - WorkbenchMessages.DashboardBlankPage_name, - WorkbenchMessages.DashboardBlankPage_message); - addPage(new NewFromTemplatesDashboardPage(), - WorkbenchMessages.DashboardTemplatesPage_name, - WorkbenchMessages.DashboardTemplatesPage_message); + for (IDashboardPage page : pages) { + MTabBarItem item = new MTabBarItem(tabBar, SWT.RADIO); + item.setText(page.getTitle()); + item.setData(page); + } setTitleBarComponentLayoutData(); @@ -196,8 +211,8 @@ private void setTitleBarComponentLayoutData() { // 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); + tabData.top = new FormAttachment(50, -tabSize.y / 2); + tabData.bottom = new FormAttachment(50, tabSize.y / 2); tabBar.setLayoutData(tabData); FormData rightData = new FormData(); @@ -207,24 +222,12 @@ private void setTitleBarComponentLayoutData() { rightBar.setLayoutData(rightData); } - private void addPage(IDashboardPage page, String title, - String description) { - page.setTitle(title); - page.setDescription(description); - page.setContext(getContext()); - - MTabBarItem item = new MTabBarItem(tabBar, SWT.RADIO); - item.setText(title); - item.setData(page); - } - private Control createTitleBar(Composite parent) { titleBar = new Composite(parent, SWT.NONE); FormLayout titleBarLayout = new FormLayout(); - titleBarLayout.marginLeft = 10; - titleBarLayout.marginRight = 10; - titleBarLayout.marginTop = 9; - titleBarLayout.marginBottom = 9; + titleBarLayout.marginWidth = 10; + titleBarLayout.marginHeight = 0; + titleBarLayout.marginRight = 15; titleBar.setLayout(titleBarLayout); titleBar.setForeground(parent.getForeground()); // titleBar.setBackground(parent.getBackground()); @@ -294,34 +297,53 @@ public void handleEvent(Event event) { private Control createRightBar(Composite composite) { rightBar = new Composite(composite, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(2).applyTo(rightBar); + 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() { - ToolBarManager normalModeToolBarManager = new ToolBarManager(); - Action editModeAction = new Action( - WorkbenchMessages.NewFileDashboardPage_GoToEditTemplateMode_label) { @Override - public void run() { - normalOrEditMode = false; - updateTitleBar(); + public void handleEvent(Event event) { + addTemplateAction.run(); } - }; - editModeAction.setToolTipText( - WorkbenchMessages.NewFileDashboardPage_GoIntoTemplatesManagerMode_tooltip); - normalModeToolBarManager.add(editModeAction); - normalModeEditContainer = normalModeToolBarManager - .createControl(rightBar); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) - .applyTo(normalModeEditContainer); - - editModeContainer = createEditModeContainer(rightBar); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) - .applyTo(editModeContainer); + }); - return rightBar; + 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 Control createEditModeContainer(final Composite rightBar) { - ToolBarManager editModeToolBarManager = new ToolBarManager(); + private IAction getAddTemplateAction() { Action addTemplateAction = new Action( WorkbenchMessages.NewFileDashboardPage_AddTemplates_label) { @Override @@ -352,43 +374,7 @@ public void run() throws Exception { addTemplateAction.setToolTipText( WorkbenchMessages.NewFileDashboardPage_AddTemplates_tooltip); - deleteTemplatesAction = new Action( - WorkbenchMessages.NewFileDashboardPage_DeleteTemplate_label) { - @Override - public void run() { - deleteSelectedTemplate(); - } - }; - deleteTemplatesAction.setToolTipText( - WorkbenchMessages.NewFileDashboardPage_DeleteTemplate_tooltip); - deleteTemplatesAction.setEnabled(false); - Action exitEditModeAction = new Action( - WorkbenchMessages.NewFileDashboardPage_ExitEditTemplatesMode_label) { - @Override - public void run() { - normalOrEditMode = true; - updateTitleBar(); - } - }; - exitEditModeAction.setToolTipText( - WorkbenchMessages.NewFileDashboardPage_ExitEditMode_tooltip); - editModeToolBarManager.add(addTemplateAction); - editModeToolBarManager.add(deleteTemplatesAction); - editModeToolBarManager.add(exitEditModeAction); - return editModeToolBarManager.createControl(rightBar); - } - - private void deleteSelectedTemplate() { - ITemplate template = selectedTemplate; - if (template != null) { - if (!MessageDialog.openConfirm(rightBar.getShell(), - WorkbenchMessages.ConfirmDeleteTemplateDialog_title, - NLS.bind( - WorkbenchMessages.ConfirmDeleteTemplateDialog_message_withTemplateName, - template.getName()))) - return; - MindMapUI.getResourceManager().removeUserTemplate(template); - } + return addTemplateAction; } private Control createPageContainer(Composite parent) { @@ -416,10 +402,6 @@ private void showPage(MTabBarItem item) { if (page != null) { if (page.getControl() == null) { page.createControl(pageContainer); - if (page instanceof NewFromTemplatesDashboardPage) { - ((NewFromTemplatesDashboardPage) page) - .addSelectionChangedListener(this); - } } layout.topControl = page.getControl(); pageContainer.layout(true); @@ -427,25 +409,16 @@ private void showPage(MTabBarItem item) { updateTitleBar(); } + getContext().setSelectionProvider(getAdapter(ISelectionProvider.class)); } private void updateTitleBar() { MTabBarItem item = tabBar.getSelection(); IDashboardPage page = (IDashboardPage) item.getData(); if (page instanceof NewFromTemplatesDashboardPage) { - ((GridData) normalModeEditContainer - .getLayoutData()).exclude = !normalOrEditMode; - normalModeEditContainer.setVisible(normalOrEditMode); - ((GridData) editModeContainer - .getLayoutData()).exclude = normalOrEditMode; - editModeContainer.setVisible(!normalOrEditMode); - ((NewFromTemplatesDashboardPage) page).setState(normalOrEditMode); + rightBar.setVisible(true); } else if (page instanceof NewFromStructuresDashboardPage) { - normalOrEditMode = true; - ((GridData) normalModeEditContainer.getLayoutData()).exclude = true; - normalModeEditContainer.setVisible(false); - ((GridData) editModeContainer.getLayoutData()).exclude = true; - editModeContainer.setVisible(false); + rightBar.setVisible(false); } titleBar.layout(true); } @@ -464,29 +437,14 @@ public void setFocus() { } } - public void selectionChanged(SelectionChangedEvent event) { - ITemplate template = findTemplate(event.getSelection()); - setSelectedTemplate(template); - } - - private ITemplate findTemplate(ISelection selection) { - if (selection instanceof IStructuredSelection) { - Object element = ((IStructuredSelection) selection) - .getFirstElement(); - if (element instanceof ITemplate) { - return (ITemplate) element; - } + 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; - } - private void setSelectedTemplate(ITemplate template) { - this.selectedTemplate = template; - if (deleteTemplatesAction != null) { - boolean enabled = selectedTemplate != null && MindMapUI - .getResourceManager().isUserTemplate(selectedTemplate); - deleteTemplatesAction.setEnabled(enabled); - } + 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 692c60f14..7a5d1bf36 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,11 +1,16 @@ 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; @@ -15,19 +20,25 @@ 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; -public class NewFromStructuresDashboardPage extends DashboardPage { +@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()) { @@ -36,6 +47,9 @@ public void setFocus() { } public void createControl(Composite parent) { + resources = new LocalResourceManager(JFaceResources.getResources(), + parent); + viewer = new GalleryViewer(); EditDomain editDomain = new EditDomain(); @@ -52,12 +66,15 @@ public void createControl(Composite parent) { properties.set(GalleryViewer.FlatFrames, true); properties.set(GalleryViewer.ImageConstrained, true); properties.set(GalleryViewer.Layout, - new GalleryLayout(GalleryLayout.ALIGN_CENTER, - GalleryLayout.ALIGN_TOPLEFT, 10, 10, - new Insets(5, 15, 5, 15))); + 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, - ColorUtils.getColor("#cccccc")); + (Color) resources.get(ColorUtils.toDescriptor("#cccccc"))); //$NON-NLS-1$ + + properties.set(GalleryViewer.ContentPaneSpaceCollaborativeEngine, + new SpaceCollaborativeEngine()); Control control = viewer.createControl(parent); control.setBackground(parent.getBackground()); @@ -101,10 +118,17 @@ public void run() { return; final StructureDescriptor structure = (StructureDescriptor) selectedElement; - final IStyle theme = chooseTheme(viewer.getControl().getShell()); + 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() @@ -112,12 +136,24 @@ public void run() { getContext().openEditor(editorInput, MindMapUI.MINDMAP_EDITOR_ID); } - private IStyle chooseTheme(Shell shell) { - ThemeChooserDialog dialog = new ThemeChooserDialog(shell); + 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 06d198b7c..ac30a7657 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,79 +1,33 @@ package org.xmind.cathy.internal.dashboard; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.draw2d.geometry.Dimension; -import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.jface.dialogs.MessageDialog; +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.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.Display; import org.eclipse.ui.IEditorInput; -import org.xmind.cathy.internal.WorkbenchMessages; -import org.xmind.gef.EditDomain; -import org.xmind.gef.GEF; -import org.xmind.gef.event.KeyEvent; -import org.xmind.gef.util.Properties; -import org.xmind.ui.gallery.GalleryLayout; -import org.xmind.ui.gallery.GallerySelectTool; +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.wizards.TemplateLabelProvider; -import org.xmind.ui.mindmap.IResourceManager; +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; -import org.xmind.ui.resources.ColorUtils; public class NewFromTemplatesDashboardPage extends DashboardPage - implements IResourceManagerListener { - - private static final int FRAME_WIDTH = 225; - private static final int FRAME_HEIGHT = 130; - - 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 = viewer.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( - viewer.getControl().getShell(), - WorkbenchMessages.ConfirmDeleteTemplateDialog_title, - NLS.bind( - WorkbenchMessages.ConfirmDeleteTemplateDialog_message_withTemplateName, - template.getName()))) { - MindMapUI.getResourceManager() - .removeUserTemplate(template); - } - } - } - } - } - return super.handleKeyUp(ke); - } - } + implements IResourceManagerListener, IAdaptable { + + private CategorizedTemplateViewer viewer; - private GalleryViewer viewer; - private boolean normalOrEditMode; private boolean templateOpening; public void setFocus() { @@ -89,58 +43,69 @@ public void dispose() { super.dispose(); } - public void setState(boolean normalOrEditMode) { - this.normalOrEditMode = normalOrEditMode; - } - public void createControl(Composite parent) { - viewer = new GalleryViewer(); - - EditDomain editDomain = new EditDomain(); - editDomain.installTool(GEF.TOOL_SELECT, - new TemplateGallerySelectTool()); - 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, true); - properties.set(GalleryViewer.Layout, - new GalleryLayout(GalleryLayout.ALIGN_CENTER, - GalleryLayout.ALIGN_TOPLEFT, 10, 10, - new Insets(5, 15, 5, 15))); - properties.set(GalleryViewer.FrameContentSize, - new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); - properties.set(GalleryViewer.ContentPaneBorderWidth, 1); - properties.set(GalleryViewer.ContentPaneBorderColor, - ColorUtils.getColor("#cccccc")); - - Control control = viewer.createControl(parent); - control.setBackground(parent.getBackground()); - control.setForeground(parent.getForeground()); - - viewer.setLabelProvider(new TemplateLabelProvider()); - - viewer.setInput(getViewerInput()); + 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 (normalOrEditMode) { - if (!templateOpening) - handleTemplateSelected(event.getSelection()); + 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); - setControl(control); + 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( @@ -150,31 +115,15 @@ public void addSelectionChangedListener( } } - private List getViewerInput() { - ArrayList templates = new ArrayList(); - IResourceManager resourceManager = MindMapUI.getResourceManager(); - templates.addAll(resourceManager.getSystemTemplates()); - templates.addAll(resourceManager.getUserTemplates()); - // move recently added template ahead - Collections.reverse(templates); - return templates; - } - public void userTemplateAdded(ITemplate template) { - if (template instanceof ITemplate) { - if (viewer == null || viewer.getControl() == null - || viewer.getControl().isDisposed()) - return; - viewer.setInput(getViewerInput()); + if (viewer != null) { + viewer.userTemplateAdded(template); } } public void userTemplateRemoved(ITemplate template) { - if (template instanceof ITemplate) { - if (viewer == null || viewer.getControl() == null - || viewer.getControl().isDisposed()) - return; - viewer.setInput(getViewerInput()); + if (viewer != null) { + viewer.userTemplateRemoved(template); } } @@ -209,4 +158,15 @@ public void run() { 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 new file mode 100644 index 000000000..a5682be5e --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentContainerLayout.java @@ -0,0 +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; + } +} 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 new file mode 100644 index 000000000..33f7e7547 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileBlankPage.java @@ -0,0 +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; + } +} 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 new file mode 100644 index 000000000..0d89de052 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileGridDashboardPage.java @@ -0,0 +1,117 @@ +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; + } + +} 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 new file mode 100644 index 000000000..a7ddbe5c1 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileGridPage.java @@ -0,0 +1,177 @@ +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); + } + +} diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileListDashboardPage.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileListDashboardPage.java deleted file mode 100644 index 0e93e4a72..000000000 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileListDashboardPage.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.xmind.cathy.internal.dashboard; - -import java.net.URI; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.resource.JFaceResources; -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.IEditorInput; -import org.eclipse.ui.IWorkbenchCommandConstants; -import org.xmind.cathy.internal.ICathyConstants; -import org.xmind.cathy.internal.WorkbenchMessages; -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.mindmap.MindMapUI; -import org.xmind.ui.resources.ColorUtils; - -public class RecentFileListDashboardPage extends DashboardPage - implements IAdaptable { - - private GalleryViewer viewer; - - public void createControl(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getBackground()); - composite.setForeground(parent.getForeground()); - GridLayoutFactory.fillDefaults().spacing(0, 0).applyTo(composite); - - Composite titleBar = new Composite(composite, SWT.NONE); -// titleBar.setBackground(composite.getBackground()); - titleBar.setBackground((Color) JFaceResources.getResources() - .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(titleBar.getForeground()); - titleLabel.setForeground((Color) JFaceResources.getResources() - .get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$ - titleLabel.setFont((Font) JFaceResources.getResources().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)); - - IDashboardContext context = getContext(); - context.registerAvailableCommandId( - ICathyConstants.COMMAND_RECENTFILE_PIN); - context.registerAvailableCommandId( - ICathyConstants.COMMAND_RECENTFILE_UNPIN); - context.registerAvailableCommandId( - ICathyConstants.COMMAND_RECENTFILE_CLEAR); - context.registerAvailableCommandId( - IWorkbenchCommandConstants.EDIT_DELETE); - Control container = createViewer(composite); - context.registerContextMenu(container, - ICathyConstants.POPUP_RECENTFILE); - setControl(composite); - } - - protected Control createViewer(Composite parent) { - viewer = new RecentFileViewer(parent); - Control control = viewer.getControl(); - GridData viewerLayoutData = new GridData(SWT.FILL, SWT.FILL, true, - true); - control.setLayoutData(viewerLayoutData); - - control.setBackground(parent.getBackground()); - control.setForeground(parent.getForeground()); - - viewer.addOpenListener(new IOpenListener() { - public void open(OpenEvent event) { - ISelection selection = event.getSelection(); - if (selection instanceof IStructuredSelection) { - final Object element = ((IStructuredSelection) selection) - .getFirstElement(); - if (element instanceof URI) { - handleOpenRecentFile((URI) element); - } - } - } - }); - - return control; - } - - private void handleOpenRecentFile(URI uri) { - IEditorInput input = MindMapUI.getEditorInputFactory() - .createEditorInput(uri); - getContext().openEditor(input, MindMapUI.MINDMAP_EDITOR_ID); - } - - public void setFocus() { - if (viewer != null && viewer.getControl() != null - && !viewer.getControl().isDisposed()) { - viewer.getControl().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/RecentFileViewer.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileViewer.java index 413201ce9..f5e810997 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,267 +1,48 @@ package org.xmind.cathy.internal.dashboard; -import java.io.IOException; -import java.io.InputStream; import java.net.URI; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.Graphics; -import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Insets; -import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.jface.resource.ImageDescriptor; 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.jface.viewers.LabelProvider; import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; +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.draw2d.graphics.GraphicsUtils; -import org.xmind.gef.part.GraphicalEditPart; -import org.xmind.gef.part.IPart; -import org.xmind.gef.part.IPartFactory; +import org.xmind.gef.ui.internal.SpaceCollaborativeEngine; import org.xmind.gef.util.Properties; import org.xmind.ui.editor.IEditorHistory; -import org.xmind.ui.gallery.FramePart; 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.protocols.FilePathParser; -import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.resources.ColorUtils; public class RecentFileViewer extends GalleryViewer { - private static class RecentInputURILabelProvider extends LabelProvider { - - private Map labels; - - public void setLabels(Map labels) { - this.labels = labels; - } - - @Override - public String getText(Object element) { - if (!(element instanceof URI)) - return super.getText(element); - URI uri = (URI) element; - String label = labels == null ? null : labels.get(uri); - if (label != null) - return label; - return uri.toString(); - } - } - - private class RecentFileFigure extends Figure { - - private URI recentFile; - - private final Rectangle RECT = new Rectangle(); - - private Image pinImage = null; - - public void setRecentFile(URI recentFile) { - if (this.recentFile == recentFile) - return; - this.recentFile = recentFile; - repaint(); - } - - public void setPinImage(Image pinImage) { - if (pinImage == this.pinImage) - return; - this.pinImage = pinImage; - repaint(); - } - - public void paint(Graphics graphics) { - GraphicsUtils.fixGradientBugForCarbon(graphics, this); - super.paint(graphics); - } - - protected void paintFigure(Graphics graphics) { - super.paintFigure(graphics); - drawRecentFile(graphics); - } - - protected void drawRecentFile(Graphics graphics) { - if (recentFile == null) - return; - - graphics.setAntialias(SWT.ON); - graphics.setTextAntialias(SWT.ON); - - drawRecentFile(graphics, recentFile); - } - - protected void drawRecentFile(Graphics graphics, URI recentFile) { - Image image = getImageFromSource(recentFile); - - if (image != null) { - Dimension imageSize = new Dimension(image); - paintImage(graphics, image, imageSize, - getImageClientArea(imageSize)); - } - - if (pinImage != null) { - Rectangle ca = getClientArea(); - graphics.drawImage(pinImage, ca.x + 1, ca.y + 1); - } - } - - protected Rectangle getImageClientArea(Dimension imageSize) { - Rectangle area = getClientArea(RECT); - Boolean isStretched = (Boolean) RecentFileViewer.this - .getProperty(GalleryViewer.ImageStretched, false); - Boolean isConstrained = (Boolean) RecentFileViewer.this - .getProperty(GalleryViewer.ImageConstrained, false); - if (isConstrained && (isStretched || imageSize.width > area.width - || imageSize.height > area.height)) { - adaptAreaToRatio(area, imageSize, isStretched); - } else { - adaptAreaToSize(area, imageSize); - } - return area; - } - - protected void adaptAreaToSize(Rectangle area, Dimension size) { - area.x += (area.width - size.width) / 2; - area.width = size.width; - area.y += (area.height - size.height) / 2; - area.height = size.height; - } - - protected void adaptAreaToRatio(Rectangle area, Dimension ratio, - boolean bigger) { - int a = ratio.width * area.height; - int b = ratio.height * area.width; - if (bigger ? (a < b) : (a > b)) { - int h = area.width == 0 ? 0 : b / ratio.width; - area.y += (area.height - h) / 2; - area.height = h; - } else if (bigger ? (a > b) : (a < b)) { - int w = area.height == 0 ? 0 : a / ratio.height; - area.x += (area.width - w) / 2; - area.width = w; - } - } - - protected void paintImage(Graphics graphics, Image image, - Dimension imageSize, Rectangle clientArea) { - if (clientArea.width == imageSize.width - && clientArea.height == imageSize.height) { - graphics.drawImage(image, clientArea.x, clientArea.y); - } else { - graphics.drawImage(image, 0, 0, imageSize.width, - imageSize.height, clientArea.x, clientArea.y, - clientArea.width, clientArea.height); - } - } - - private Image getImageFromSource(URI recentFile) { - InputStream thumbnailData = null; - try { - IEditorHistory editorHistory = PlatformUI.getWorkbench() - .getService(IEditorHistory.class); - thumbnailData = editorHistory.loadThumbnailData(recentFile); - if (thumbnailData != null) { - ImageDescriptor imageDescriptor = ImageDescriptor - .createFromImageData(new ImageData(thumbnailData)); - return JFaceResources.getResources() - .createImage(imageDescriptor); - } - } catch (IOException e) { - } finally { - try { - if (thumbnailData != null) - thumbnailData.close(); - } catch (IOException e) { - } - } - return MindMapUI.getImages() - .get(IMindMapImages.THUMBNAIL_LOST, true).createImage(); - } - - } - - private class RecentFilePart extends GraphicalEditPart { - - public RecentFilePart(URI uri) { - setModel(uri); - } - - public URI getURI() { - return (URI) super.getModel(); - } - - protected IFigure createFigure() { - return new RecentFileFigure(); - } - - protected void updateView() { - super.updateView(); - ((RecentFileFigure) getFigure()).setRecentFile(getURI()); - ((RecentFileFigure) getFigure()).setPinImage(getPinImage(getURI())); - - Properties properties = ((GalleryViewer) getSite().getViewer()) - .getProperties(); - Dimension size = (Dimension) properties - .get(GalleryViewer.FrameContentSize); - if (size != null) { - getFigure().setPreferredSize(size); - } - } - - protected void register() { - registerModel(getURI()); - super.register(); - } - - @Override - protected void unregister() { - super.unregister(); - unregisterModel(getURI()); - } - } - - private class RecentFilePartFactory implements IPartFactory { - - private IPartFactory factory; - - public RecentFilePartFactory(IPartFactory factory) { - this.factory = factory; - } - - public IPart createPart(IPart context, Object model) { - if (context instanceof FramePart && model instanceof URI) - return new RecentFilePart((URI) model); - return factory.createPart(context, model); - } - - } - - static Image pinImage; + 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); - createControl(parent); registerHelper(parent.getShell()); } @@ -308,8 +89,11 @@ public void run() { }); } - private void initViewer(Composite parent) { - setPartFactory(new RecentFilePartFactory(getPartFactory())); + @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()); @@ -327,25 +111,38 @@ private void initViewer(Composite parent) { properties.set(GalleryViewer.FlatFrames, true); properties.set(GalleryViewer.ImageConstrained, Boolean.TRUE); properties.set(GalleryViewer.ImageStretched, Boolean.TRUE); - - properties.set(GalleryViewer.FrameContentSize, new Dimension(215, 130)); - properties.set(GalleryViewer.Layout, - new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, - GalleryLayout.ALIGN_TOPLEFT, 10, 10, new Insets(10))); - properties.set(GalleryViewer.ContentPaneBorderWidth, 1); + properties.set(GalleryViewer.CustomContentPaneDecorator, true); properties.set(GalleryViewer.ContentPaneBorderColor, - ColorUtils.getColor("#cccccc")); + resources.get(ColorUtils.toDescriptor(COLOR_CONTENT_BORDER))); - final RecentFileListContentProvider contentProvider = new RecentFileListContentProvider(); - final RecentInputURILabelProvider labelProvider = new RecentInputURILabelProvider(); + 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); @@ -354,7 +151,21 @@ public void run() { 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() { @@ -375,49 +186,15 @@ private void unPinRecentFile(URI fileURI) { updateRecentFilePart(fileURI); } - private void handleRecentFileListChanged( - RecentFileListContentProvider contentProvider, - RecentInputURILabelProvider labelProvider, boolean refresh) { - Map labels = new HashMap(); - FilePathParser.calculateFileURILabels( - contentProvider.getRecentInputURIs(), labels); - labelProvider.setLabels(labels); - if (refresh) { -// refresh(); - setInput(getInput()); - } - } - - private Image getPinImage(URI uri) { - boolean isPin = editorHistory.isPinned(uri); - return isPin ? getPinImage() : null; - } - - private static Image getPinImage() { - if (pinImage == null) { - ImageDescriptor desc = MindMapUI.getImages().get(IMindMapImages.PIN, - true); - if (desc != null) { - try { - pinImage = desc.createImage(); - } catch (Throwable e) { - //e.printStackTrace(); - } - } - } - return pinImage; - } - private void updateRecentFilePart(URI pinURI) { - RecentFilePart part = findRecentFilePart(pinURI); + RecentFilesFramePart part = findRecentFilePart(pinURI); if (part != null) part.update(); } - private RecentFilePart findRecentFilePart(URI pinURI) { + private RecentFilesFramePart findRecentFilePart(URI pinURI) { if (pinURI == null) return null; - return (RecentFilePart) getPartRegistry().getPartByModel(pinURI); + return (RecentFilesFramePart) getPartRegistry().getPartByModel(pinURI); } - } diff --git a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileListContentProvider.java b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesContentProvider.java similarity index 78% rename from bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileListContentProvider.java rename to bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesContentProvider.java index bc123ec54..ec9e6a664 100644 --- a/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFileListContentProvider.java +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesContentProvider.java @@ -1,6 +1,8 @@ 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; @@ -13,11 +15,11 @@ import org.xmind.ui.editor.IEditorHistory; import org.xmind.ui.editor.IEditorHistory.IEditorHistoryListener; -public class RecentFileListContentProvider extends EventManager +public class RecentFilesContentProvider extends EventManager implements IStructuredContentProvider, IEditorHistoryListener, IPropertyChangeListener { - private static final int DEFAULT_ITEM_COUNT = 10; + private static final int DEFAULT_ITEM_COUNT = 20; private IEditorHistory history = null; @@ -64,18 +66,31 @@ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { public Object[] getElements(Object inputElement) { if (inputElement != history) return new Object[0]; - return getRecentInputURIs(); + return getRecentInput(); } - public URI[] getRecentInputURIs() { + public URI[] getRecentInput() { if (history == null) return new URI[0]; int itemsToShow = getItemCount(); if (itemsToShow <= 0) return new URI[0]; - URI[] recentInputURIs = history.getRecentInputURIs(itemsToShow); - return recentInputURIs; + 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() { 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 new file mode 100644 index 000000000..69bbf7e50 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesGalleryPartFactory.java @@ -0,0 +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); + } + +} 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 new file mode 100644 index 000000000..d3925b3fc --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/RecentFilesLabelProvider.java @@ -0,0 +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); + } +} 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 new file mode 100644 index 000000000..11d461945 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/dashboard/TemplatePropertyTester.java @@ -0,0 +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; + } + +} 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 3c9fc670a..5262ce44c 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 @@ -33,11 +33,18 @@ 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; @@ -108,7 +115,8 @@ protected void postInit() { @Override protected void initGalleryViewer(GalleryViewer galleryViewerer) { - galleryViewerer.setLabelProvider(new ThemeLabelProvider()); + galleryViewerer.setLabelProvider( + new ThemeLabelProvider(structureClass)); EditDomain editDomain = new EditDomain(); editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); 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 new file mode 100644 index 000000000..f156c64b5 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DeleteTemplateHandler.java @@ -0,0 +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; + } + +} 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 new file mode 100644 index 000000000..db879371b --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/DuplicateTemplateHandler.java @@ -0,0 +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; + } + +} 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 new file mode 100644 index 000000000..ae13f7001 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/handlers/RenameTemplateHandler.java @@ -0,0 +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; + } + +} 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 b43e7fe4e..29ca952c4 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 @@ -12,6 +12,7 @@ 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 { @@ -27,8 +28,9 @@ public Object execute(ExecutionEvent event) throws ExecutionException { if (activePage == null) return null; + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("WelcomeToXmindCount"); //$NON-NLS-1$ SafeRunner.run(new SafeRunnable() { - @Override public void run() throws Exception { IEditorInput input = MindMapUI.getEditorInputFactory() .createEditorInput(new URI(URL_WELCOME_FILE), 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 8c07d00d6..fbe9f3834 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,17 +1,10 @@ package org.xmind.cathy.internal.handlers; -import java.io.IOException; -import java.net.URL; - import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.jface.util.SafeRunnable; -import org.osgi.framework.Bundle; import org.xmind.cathy.internal.CathyPlugin; import org.xmind.ui.browser.BrowserSupport; @@ -21,32 +14,32 @@ 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); - } +// 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; - } +// 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/messages.properties b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/messages.properties index b80b6b33d..f2bff5c55 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 @@ -9,6 +9,8 @@ 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 @@ -62,7 +64,7 @@ CheckUpdatesJob_NoUpdate_message=No updates found. You are using the latest vers 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=Are you sure you want to delete this template ''{0}''? +ConfirmDeleteTemplateDialog_message_withTemplateName=You are deleting the template ''{0}''. ConfirmDeleteTemplateDialog_title=XMind - Delete Template ConfirmToRestart_cancelButton=Cancel ConfirmToRestart_defaultButton=Restart @@ -109,15 +111,19 @@ OpenXMindCommandFileJob_failed_fileIsNotReadable=Failed to open XMind command fi 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_cloud_description=Access mindmaps across Mac/PCs +WelcomeDialog_item_slide_title=Slide-based Story +WelcomeDialog_item_slide_description=Create slideshows from mind maps WelcomeDialog_item_cloud_title=XMind Cloud -WelcomeDialog_item_iconFinder_description=Search and drag more than 60,000 icons -WelcomeDialog_item_iconFinder_title=Iconfinder -WelcomeDialog_item_share_description=Share maps to Facebook, Twitter, etc. -WelcomeDialog_item_share_title=New Share +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= @@ -129,8 +135,8 @@ 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=Visit http://www.xmind.net/ +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 @@ -146,7 +152,7 @@ DashboardTemplatesPage_name=Templates DashboardBlankPage_message=Choose a Type DashboardTemplatesPage_message=Choose a Template -DashboardRecentFiles_message=Recently Opened Files +DashboardRecentFiles_message=Recent DashboardThemeChoose_message=Choose a Theme DashboardThemeCreate_label=Create @@ -160,3 +166,14 @@ 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 new file mode 100644 index 000000000..0536e8188 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XDialogRenderer.java @@ -0,0 +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--; + } + } + +} 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 new file mode 100644 index 000000000..8a6712a3e --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XMenuManagerRenderer.java @@ -0,0 +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()); + } + +} 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 new file mode 100644 index 000000000..a3606e2e0 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XRightStackRenderer.java @@ -0,0 +1,116 @@ +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 new file mode 100644 index 000000000..bf400bf0f --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XRightTrimBarLayout.java @@ -0,0 +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; + } + +} 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 new file mode 100644 index 000000000..4d9e8027d --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XSashLayout.java @@ -0,0 +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; + } + } +} 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 new file mode 100644 index 000000000..b0cac9c09 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XSashRenderer.java @@ -0,0 +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; + } + } +} 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 new file mode 100644 index 000000000..34db2368d --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/renderer/XStackRenderer.java @@ -0,0 +1,127 @@ +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()); + } + }); + } + +} 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 4086cb85c..0396de0ae 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 @@ -31,7 +31,10 @@ public Object createWidget(final MUIElement element, Object parent) { Control renderedCtrl = newTB; MUIElement parentElement = element.getParent(); if (parentElement instanceof MTrimBar) { - element.getTags().add(IPresentationEngine.DRAGGABLE); + //default can't be draggable +// if (!element.getTags().contains(IPresentationEngine.NO_MOVE)) { +// element.getTags().add(IPresentationEngine.DRAGGABLE); +// } setCSSInfo(element, newTB); @@ -43,8 +46,12 @@ public Object createWidget(final MUIElement element, Object parent) { CSSRenderingUtils cssUtils = parentContext .get(CSSRenderingUtils.class); if (cssUtils != null) { - renderedCtrl = (Composite) cssUtils.frameMeIfPossible(newTB, - null, vertical, true); + MUIElement modelElement = (MUIElement) newTB + .getData(AbstractPartRenderer.OWNING_ME); + boolean draggable = ((modelElement != null) && (modelElement + .getTags().contains(IPresentationEngine.DRAGGABLE))); + renderedCtrl = cssUtils.frameMeIfPossible(newTB, null, vertical, + draggable); } } 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 84addd106..3f51a339a 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 @@ -4,6 +4,7 @@ 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; @@ -57,7 +58,8 @@ protected void layout(Composite composite, boolean flushCache) { // 'Top' spans the entire area if (top != null && top.isVisible()) { - Point topSize = top.computeSize(caRect.width, SWT.DEFAULT, true); + 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; @@ -194,6 +196,18 @@ public void removeContainer(Object child) { @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()); 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 3743d7a1c..639087a88 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 @@ -2,30 +2,75 @@ 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.ToolBarManagerRenderer; +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 ToolBarManagerRenderer xtoolbarRenderer; + 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) { - if (uiElement instanceof MToolBar) { + 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); } 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 new file mode 100644 index 000000000..eb388eb41 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ui/workbench/addons/minmax/MinMaxAddon.java @@ -0,0 +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; + } + +} 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 new file mode 100644 index 000000000..6e2e4b1d4 --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/cathy/internal/ui/workbench/addons/minmax/XTrimStack.java @@ -0,0 +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; + } + +} 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 new file mode 100644 index 000000000..b8298e33e --- /dev/null +++ b/bundles/org.xmind.cathy/src/org/xmind/ui/internal/e4handlers/XResourceHandler.java @@ -0,0 +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; + } +} 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 6e789d95f..9e961115c 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 @@ -15,6 +15,7 @@ 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 @@ -28,8 +29,10 @@ 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 @@ -39,11 +42,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -97,6 +102,7 @@ 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 @@ -291,12 +297,24 @@ 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 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 0759392da..e8a80c475 100644 --- a/bundles/org.xmind.core.command.remote/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.command.remote/META-INF/MANIFEST.MF @@ -2,11 +2,11 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.xmind.core.command.remote;singleton:=true -Bundle-Version: 3.6.51.qualifier +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.6.0,3.7.0)";visibility:=reexport + 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, diff --git a/bundles/org.xmind.core.command.remote/pom.xml b/bundles/org.xmind.core.command.remote/pom.xml index af16a0cd0..45792043d 100644 --- a/bundles/org.xmind.core.command.remote/pom.xml +++ b/bundles/org.xmind.core.command.remote/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.core.command.remote - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ 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 2a7d08cf8..5d49216ca 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 @@ -103,6 +103,7 @@ 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 @@ -116,8 +117,10 @@ 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 @@ -127,11 +130,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -185,6 +190,7 @@ 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 @@ -379,12 +385,24 @@ 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 diff --git a/bundles/org.xmind.core.command/META-INF/MANIFEST.MF b/bundles/org.xmind.core.command/META-INF/MANIFEST.MF index f9468ab23..88a8e346c 100644 --- a/bundles/org.xmind.core.command/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.command/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.xmind.core.command;singleton:=true -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Activator: org.xmind.core.internal.command.XMindCommandPlugin Bundle-Vendor: %Bundle-Vendor Require-Bundle: org.eclipse.core.runtime diff --git a/bundles/org.xmind.core.command/pom.xml b/bundles/org.xmind.core.command/pom.xml index cfb7f1cf6..ed154836d 100644 --- a/bundles/org.xmind.core.command/pom.xml +++ b/bundles/org.xmind.core.command/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.core.command - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ diff --git a/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.core.prefs index f51dc3a8d..0e11c7b5b 100644 --- a/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.core.prefs @@ -72,6 +72,7 @@ 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.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 @@ -85,8 +86,10 @@ 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 @@ -96,11 +99,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -154,6 +159,7 @@ 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 @@ -349,12 +355,24 @@ 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 diff --git a/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.ui.prefs index 7dece21ad..5ff980f2f 100644 --- a/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.core.io/.settings/org.eclipse.jdt.ui.prefs @@ -1,4 +1,3 @@ eclipse.preferences.version=1 formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.text.custom_code_templates= diff --git a/bundles/org.xmind.core.io/META-INF/MANIFEST.MF b/bundles/org.xmind.core.io/META-INF/MANIFEST.MF index 9f550ae1e..402906a08 100644 --- a/bundles/org.xmind.core.io/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.io/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.core.io;singleton:=true -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Vendor: %providerName Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy diff --git a/bundles/org.xmind.core.io/pom.xml b/bundles/org.xmind.core.io/pom.xml index 3e4751744..8610d3993 100644 --- a/bundles/org.xmind.core.io/pom.xml +++ b/bundles/org.xmind.core.io/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.core.io - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ 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 5da2977b9..082f08668 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 @@ -109,6 +109,7 @@ 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 @@ -122,8 +123,10 @@ 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 @@ -133,11 +136,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -191,6 +196,7 @@ 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 @@ -385,12 +391,24 @@ 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 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 4dedfe7bf..082f3415f 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 @@ -2,8 +2,6 @@ eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.javadoc=true -org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true diff --git a/bundles/org.xmind.core.licensing/META-INF/MANIFEST.MF b/bundles/org.xmind.core.licensing/META-INF/MANIFEST.MF index 64ea7be3b..783a145d0 100644 --- a/bundles/org.xmind.core.licensing/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.licensing/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Licensing API Bundle-SymbolicName: org.xmind.core.licensing -Bundle-Version: 3.6.51.qualifier +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/pom.xml b/bundles/org.xmind.core.licensing/pom.xml index cc7ddbc27..cb5f07535 100644 --- a/bundles/org.xmind.core.licensing/pom.xml +++ b/bundles/org.xmind.core.licensing/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.core.licensing - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ 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 be9f785d0..d3a3f618c 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 @@ -104,6 +104,7 @@ 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 @@ -117,8 +118,10 @@ 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 @@ -128,11 +131,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -186,6 +191,7 @@ 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 @@ -380,12 +386,24 @@ 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 diff --git a/bundles/org.xmind.core.net/META-INF/MANIFEST.MF b/bundles/org.xmind.core.net/META-INF/MANIFEST.MF index c60e41128..c32371100 100644 --- a/bundles/org.xmind.core.net/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.net/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.core.net;singleton:=true -Bundle-Version: 3.6.51.qualifier +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" diff --git a/bundles/org.xmind.core.net/pom.xml b/bundles/org.xmind.core.net/pom.xml index b637aa63c..9e92b86ac 100644 --- a/bundles/org.xmind.core.net/pom.xml +++ b/bundles/org.xmind.core.net/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.core.net - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ 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 3c7bcb082..f56afa234 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 @@ -16,6 +16,8 @@ */ 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; @@ -49,15 +51,19 @@ 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.LoggedInputStream; -import org.xmind.core.net.internal.LoggedOutputStream; +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 @@ -305,6 +311,8 @@ public class HttpRequest { private PrintStream logStream; + private byte[] responseBuffer; + public HttpRequest(URL url, String method, FieldSet headers, HttpEntity entity, FieldSet settings, IResponseHandler responseHandler) { @@ -315,8 +323,7 @@ public HttpRequest(URL url, String method, FieldSet headers, this.requestHeaders = new FieldSet(headers); this.requestEntity = entity; this.settings = new FieldSet(settings); - this.responseHandler = responseHandler == null ? new HttpResponse() - : responseHandler; + this.responseHandler = responseHandler; this.statusCode = HTTP_PREPARING; this.statusMessage = null; this.responseHeaders = new FieldSet(); @@ -327,6 +334,7 @@ public HttpRequest(URL url, String method, FieldSet headers, || 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, @@ -378,15 +386,26 @@ public IResponseHandler getResponseHandler() { } public String getResponseAsString() { - if (responseHandler instanceof HttpResponse) - return ((HttpResponse) responseHandler).asString(); - return null; + if (responseBuffer == null) + return null; + return EncodingUtils.toDefaultString(responseBuffer); } public JSONObject getResponseAsJSON() { - if (responseHandler instanceof HttpResponse) - return ((HttpResponse) responseHandler).asJSONObject(); - return null; + 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) { + } + } } /** @@ -463,7 +482,7 @@ public void run() { private void doExecute(IProgressMonitor monitor, HttpURLConnection[] _connection) - throws InterruptedException, IOException { + throws InterruptedException, IOException { if (monitor.isCanceled()) return; @@ -524,9 +543,18 @@ private void doExecute(IProgressMonitor monitor, if (monitor.isCanceled()) throw new InterruptedException(); } catch (IOException e) { - readResponse(monitor, connection, connection.getErrorStream(), - connection.getResponseCode(), - connection.getResponseMessage()); + 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 { @@ -612,7 +640,8 @@ private void writeBody(IProgressMonitor monitor, URLConnection connection) OutputStream output = new MonitoredOutputStream( connection.getOutputStream(), monitor); if (debugging && logStream != null) { - output = new LoggedOutputStream(output, logStream); + output = new TeeOutputStream(output, + new LoggingOutputStream(logStream)); } try { requestEntity.writeTo(output); @@ -661,25 +690,35 @@ private void readResponse(IProgressMonitor monitor, totalBytes); } - final HttpEntity responseEntity; if (readStream != null) { - InputStream responseStream = new MonitoredInputStream(readStream, - monitor); if (debugging && logStream != null) { - responseStream = new LoggedInputStream(responseStream, - logStream); + readStream = new TeeInputStream(readStream, + new LoggingOutputStream(logStream)); } - responseEntity = new StreamedEntity(responseStream, totalBytes); - } else { - responseEntity = null; - } - if (responseEntity != null) { - try { - responseHandler.handleResponseEntity(monitor, this, - responseEntity); - } catch (OperationCanceledException e) { - throw new InterruptedException(); + 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) { @@ -793,8 +832,8 @@ public static void relaxHostChecking(HttpURLConnection conn) static synchronized SSLSocketFactory prepFactory( HttpsURLConnection httpsConnection) - throws NoSuchAlgorithmException, KeyStoreException, - KeyManagementException { + throws NoSuchAlgorithmException, KeyStoreException, + KeyManagementException { if (factory == null) { SSLContext ctx = SSLContext.getInstance("TLS"); //$NON-NLS-1$ diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpResponse.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpResponse.java deleted file mode 100644 index 4be96d553..000000000 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/http/HttpResponse.java +++ /dev/null @@ -1,85 +0,0 @@ -/* ****************************************************************************** - * 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 org.eclipse.core.runtime.IProgressMonitor; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.xmind.core.net.internal.EncodingUtils; - -/** - * @author Frank Shaka - * @since 3.6.50 - */ -public class HttpResponse implements IResponseHandler { - - private byte[] bytes = null; - - public void handleResponseEntity(IProgressMonitor monitor, - HttpRequest request, HttpEntity entity) - throws InterruptedException, IOException { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - try { - entity.writeTo(output); - } finally { - try { - output.close(); - } catch (IOException e) { - } - } - bytes = output.toByteArray(); - } - - /** - * - * @return a string as the response, or null if no response is - * received - */ - public String asString() { - if (bytes == null) - return null; - return EncodingUtils.toDefaultString(bytes); - } - - /** - * - * @return a JSON object as the response, or null if no valid - * JSON object is available - */ - public JSONObject asJSONObject() { - if (bytes == null) - return null; - ByteArrayInputStream input = new ByteArrayInputStream(bytes); - try { - return new JSONObject(new JSONTokener(input)); - } catch (JSONException e) { - // not a valid JSON object - return null; - } finally { - try { - input.close(); - } catch (IOException e) { - } - } - } - -} 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 e54dbdc51..d3c9eb74e 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 @@ -17,7 +17,6 @@ package org.xmind.core.net.http; import static org.xmind.core.net.internal.EncodingUtils.toAsciiBytes; -import static org.xmind.core.net.internal.EncodingUtils.toDefaultBytes; import java.io.IOException; import java.io.OutputStream; @@ -28,6 +27,7 @@ import org.xmind.core.net.internal.EncodingUtils; /** + * * @author Frank Shaka * @since 3.6.50 */ @@ -94,7 +94,7 @@ private byte[] getBoundary() { return boundary; Random rand = new Random(); byte[] bytes = new byte[rand.nextInt(11) + 30]; // a random size - // from 30 to 40 + // from 30 to 40 for (int i = 0; i < bytes.length; i++) { bytes[i] = BOUNDARY_CHARS[rand.nextInt(BOUNDARY_CHARS.length)]; } @@ -123,7 +123,7 @@ public long getContentLength() { length += CONTENT_DISPOSITION.length; length += QUOTE.length; - length += toDefaultBytes(toSafeName(part.name)).length; + length += toAsciiBytes(toSafeName(part.name)).length; length += QUOTE.length; length += CRLF.length; @@ -133,7 +133,7 @@ public long getContentLength() { fileName = part.name; length += FILE_NAME.length; length += QUOTE.length; - length += toDefaultBytes(toSafeName(fileName)).length; + length += toAsciiBytes(toSafeName(fileName)).length; length += QUOTE.length; } @@ -170,7 +170,7 @@ public void writeTo(OutputStream stream) throws IOException { stream.write(CONTENT_DISPOSITION); stream.write(QUOTE); - stream.write(EncodingUtils.toDefaultBytes(toSafeName(part.name))); + stream.write(toAsciiBytes(toSafeName(part.name))); stream.write(QUOTE); if (part.value instanceof HttpEntity) { String fileName = ((HttpEntity) part.value).getFileName(); @@ -178,8 +178,7 @@ public void writeTo(OutputStream stream) throws IOException { fileName = part.name; stream.write(FILE_NAME); stream.write(QUOTE); - stream.write( - EncodingUtils.toDefaultBytes(toSafeName(fileName))); + stream.write(toAsciiBytes(toSafeName(fileName))); stream.write(QUOTE); } stream.write(CRLF); @@ -206,7 +205,8 @@ public void writeTo(OutputStream stream) throws IOException { private static byte[] getContentType(Object value) { if (value instanceof HttpEntity) - return toDefaultBytes(((HttpEntity) value).getContentType()); + return EncodingUtils + .toAsciiBytes(((HttpEntity) value).getContentType()); return TEXT_CONTENT_TYPE; } 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 0869e020a..5a5097fbe 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,23 +1,19 @@ -/* ****************************************************************************** - * 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 +/* + * ***************************************************************************** + * * 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, 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 new file mode 100644 index 000000000..608fcd2ce --- /dev/null +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggingOutputStream.java @@ -0,0 +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) { + } + } + +} diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggedInputStream.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeInputStream.java similarity index 69% rename from bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggedInputStream.java rename to bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeInputStream.java index a3c2a91fe..0911831d4 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggedInputStream.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeInputStream.java @@ -23,70 +23,55 @@ /** * @author Frank Shaka - * @since 3.6.50 + * @since 3.6.51 */ -public class LoggedInputStream extends FilterInputStream { +public class TeeInputStream extends FilterInputStream { - private OutputStream log; + private OutputStream out; /** * @param in */ - public LoggedInputStream(InputStream in, OutputStream log) { + public TeeInputStream(InputStream in, OutputStream out) { super(in); - this.log = log; + this.out = out; } /* * (non-Javadoc) - * * @see java.io.FilterInputStream#read() */ @Override public int read() throws IOException { int b = in.read(); if (b != -1) { - try { - log.write(b); - log.flush(); - } catch (IOException e) { - } + 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) { - try { - log.write(b, 0, n); - log.flush(); - } catch (IOException e) { - } + 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) { - try { - log.write(b, off, n); - log.flush(); - } catch (IOException e) { - } + out.write(b, off, n); } return n; } diff --git a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggedOutputStream.java b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeOutputStream.java similarity index 80% rename from bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggedOutputStream.java rename to bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeOutputStream.java index 8efc518cf..e72636408 100644 --- a/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/LoggedOutputStream.java +++ b/bundles/org.xmind.core.net/src/org/xmind/core/net/internal/TeeOutputStream.java @@ -22,62 +22,58 @@ /** * @author Frank Shaka - * @since 3.6.50 + * @since 3.6.51 */ -public class LoggedOutputStream extends FilterOutputStream { +public class TeeOutputStream extends FilterOutputStream { - private OutputStream log; + private OutputStream out2; /** * @param out */ - public LoggedOutputStream(OutputStream out, OutputStream log) { + public TeeOutputStream(OutputStream out, OutputStream out2) { super(out); - this.log = log; + this.out2 = out2; } /* * (non-Javadoc) - * - * @see java.io.FilterOutputStream#flush() - */ - @Override - public void flush() throws IOException { - super.flush(); - log.flush(); - } - - /* - * (non-Javadoc) - * * @see java.io.FilterOutputStream#write(byte[]) */ @Override public void write(byte[] b) throws IOException { out.write(b); - log.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); - log.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); - log.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.runtime/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.core.runtime/.settings/org.eclipse.jdt.core.prefs index f51dc3a8d..0e11c7b5b 100644 --- a/bundles/org.xmind.core.runtime/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.core.runtime/.settings/org.eclipse.jdt.core.prefs @@ -72,6 +72,7 @@ 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.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 @@ -85,8 +86,10 @@ 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 @@ -96,11 +99,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -154,6 +159,7 @@ 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 @@ -349,12 +355,24 @@ 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 diff --git a/bundles/org.xmind.core.runtime/META-INF/MANIFEST.MF b/bundles/org.xmind.core.runtime/META-INF/MANIFEST.MF index e191d0ac8..d6e05f23e 100644 --- a/bundles/org.xmind.core.runtime/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.runtime/META-INF/MANIFEST.MF @@ -2,13 +2,13 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.core.runtime;singleton:=true -Bundle-Version: 3.6.51.qualifier +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.6.0,3.7.0)";visibility:=reexport + 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, diff --git a/bundles/org.xmind.core.runtime/pom.xml b/bundles/org.xmind.core.runtime/pom.xml index a2d76daa2..45d0c57e8 100644 --- a/bundles/org.xmind.core.runtime/pom.xml +++ b/bundles/org.xmind.core.runtime/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.core.runtime - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 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 6af64876e..11d2d17fd 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 @@ -67,6 +67,14 @@ public List getChildNodes(Object node, String 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) 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 new file mode 100644 index 000000000..1c77cfcfe --- /dev/null +++ b/bundles/org.xmind.core.runtime/src/org/xmind/core/internal/security/PKCS12KeyGenerator.java @@ -0,0 +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; + } + +} 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 73eb494ba..27d9e2f24 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 @@ -19,6 +19,8 @@ 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; @@ -26,16 +28,24 @@ 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 org.bouncycastle.crypto.BufferedBlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.PBEParametersGenerator; -import org.bouncycastle.crypto.digests.MD5Digest; -import org.bouncycastle.crypto.engines.AESEngine; -import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; -import org.bouncycastle.crypto.modes.CBCBlockCipher; -import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; +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; @@ -55,9 +65,11 @@ public class PasswordProtectedNormalizer implements IEntryStreamNormalizer { private static final String ALGORITHM_NAME = "AES/CBC/PKCS5Padding"; //$NON-NLS-1$ - private static final String KEY_DERIVATION_ALGORITHM_NAME = "PKCS12"; //$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 @@ -80,7 +92,6 @@ public PasswordProtectedNormalizer(String password) { /* * (non-Javadoc) - * * @see org.xmind.core.IEntryStreamNormalizer#normalizeOutputStream(java.io. * OutputStream, org.xmind.core.IFileEntry) */ @@ -96,10 +107,14 @@ public OutputStream normalizeOutputStream(OutputStream stream, 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); - BufferedBlockCipher cipher = createCipher(true, encData, password); - OutputStream out = new BlockCipherOutputStream(stream, cipher); + 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)); @@ -107,9 +122,14 @@ public OutputStream normalizeOutputStream(OutputStream stream, 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) */ @@ -119,8 +139,9 @@ public InputStream normalizeInputStream(InputStream stream, if (encData == null) return stream; - BufferedBlockCipher cipher = createCipher(false, encData, password); - InputStream in = new BlockCipherInputStream(stream, cipher); + 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()); @@ -128,33 +149,72 @@ public InputStream normalizeInputStream(InputStream stream, return in; } - private BufferedBlockCipher createCipher(boolean encrypt, + 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; + } - // Create a parameter generator - PKCS12ParametersGenerator paramGen = new PKCS12ParametersGenerator( - new MD5Digest()); - - // Get the password bytes - byte[] pwBytes = password == null ? new byte[0] - : PBEParametersGenerator - .PKCS12PasswordToBytes(password.toCharArray()); - - // Initialize the parameter generator with password bytes, - // salt and iteration counts - paramGen.init(pwBytes, getSalt(encData), getIterationCount(encData)); + 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$ + } - // Generate a parameter - CipherParameters param = paramGen.generateDerivedParameters(128); + 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); + } - // Create a block cipher - BufferedBlockCipher cipher = new PaddedBufferedBlockCipher( - new CBCBlockCipher(new AESEngine())); + 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); + } + } - // Initialize the block cipher - cipher.init(encrypt, param); - return cipher; + 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) @@ -166,8 +226,9 @@ private void checkEncryptionData(IEncryptionData encData) String keyAlgoName = encData.getAttribute(TAG_KEY_DERIVATION, ATTR_KEY_DERIVATION_NAME); - if (keyAlgoName == null - || !KEY_DERIVATION_ALGORITHM_NAME.equals(keyAlgoName)) + if (keyAlgoName == null || !(KEY_DERIVATION_ALGORITHM_NAME + .equals(keyAlgoName) + || OLD37_KEY_DERIVATION_ALGORITHM_NAME.equals(keyAlgoName))) throw new CoreException(Core.ERROR_FAIL_INIT_CRYPTOGRAM); } @@ -183,9 +244,25 @@ private byte[] getSalt(IEncryptionData encData) throws CoreException { 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 @@ -200,7 +277,6 @@ public boolean equals(Object obj) { /* * (non-Javadoc) - * * @see java.lang.Object#hashCode() */ @Override @@ -218,10 +294,20 @@ 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 c72f8a905..e1129b749 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 @@ -18,6 +18,7 @@ public class Evaluator { 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$ @@ -28,6 +29,7 @@ public class Evaluator { 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$ @@ -186,6 +188,10 @@ public List evaluate(EvaluationContext context) { 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)); @@ -742,7 +748,12 @@ private Expression parsePrimaryExpression() { if (!hasToken()) return NULL; - if (TOKEN_SELF.equals(token())) { + 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); } 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 27d5d8a23..43b01876b 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 @@ -8,6 +8,8 @@ public interface IAxisProvider { 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/util/ProgressReporter.java b/bundles/org.xmind.core.runtime/src/org/xmind/core/util/ProgressReporter.java index 89c7e4b87..8d576615a 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 @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubMonitor; +import org.xmind.core.util.IProgressReporter; /** * @author Frank Shaka 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 237d37784..10cd93bd3 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 @@ -99,6 +99,7 @@ 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 @@ -112,8 +113,10 @@ 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 @@ -123,11 +126,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -181,6 +186,7 @@ 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 @@ -375,12 +381,24 @@ 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/META-INF/MANIFEST.MF b/bundles/org.xmind.core.usagedata/META-INF/MANIFEST.MF index 76014ae7f..00336c978 100644 --- a/bundles/org.xmind.core.usagedata/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core.usagedata/META-INF/MANIFEST.MF @@ -1,8 +1,8 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: %Bundle-Name +Bundle-Name: Usage Data API Bundle-SymbolicName: org.xmind.core.usagedata -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy diff --git a/bundles/org.xmind.core.usagedata/OSGI-INF/l10n/bundle.properties b/bundles/org.xmind.core.usagedata/OSGI-INF/l10n/bundle.properties deleted file mode 100644 index 9125acdfe..000000000 --- a/bundles/org.xmind.core.usagedata/OSGI-INF/l10n/bundle.properties +++ /dev/null @@ -1,3 +0,0 @@ -#Properties file for org.xmind.core.usagedata -Bundle-Vendor = XMind Ltd. -Bundle-Name = Usage Data API \ No newline at end of file diff --git a/bundles/org.xmind.core.usagedata/build.properties b/bundles/org.xmind.core.usagedata/build.properties index a65755cb2..a657887e9 100644 --- a/bundles/org.xmind.core.usagedata/build.properties +++ b/bundles/org.xmind.core.usagedata/build.properties @@ -2,4 +2,4 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - OSGI-INF/ + about.html diff --git a/bundles/org.xmind.core.usagedata/pom.xml b/bundles/org.xmind.core.usagedata/pom.xml index 14f564ca1..7945a9b90 100644 --- a/bundles/org.xmind.core.usagedata/pom.xml +++ b/bundles/org.xmind.core.usagedata/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.core.usagedata - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ 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 cf1a6fe1c..582352ed2 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 @@ -56,7 +56,6 @@ *

* * @author Frank Shaka - * @since 3.6.50 */ public interface IUsageDataSampler { 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 88e8c61ba..49bffb015 100644 --- a/bundles/org.xmind.core/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.core/.settings/org.eclipse.jdt.core.prefs @@ -106,6 +106,7 @@ 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 @@ -119,8 +120,10 @@ 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 @@ -130,11 +133,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -189,6 +194,7 @@ 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 @@ -384,12 +390,24 @@ 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 diff --git a/bundles/org.xmind.core/META-INF/MANIFEST.MF b/bundles/org.xmind.core/META-INF/MANIFEST.MF index 998fa88c5..9229606e4 100644 --- a/bundles/org.xmind.core/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.core -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Export-Package: org.xmind.core, org.xmind.core.event, org.xmind.core.internal;x-internal:=true, diff --git a/bundles/org.xmind.core/pom.xml b/bundles/org.xmind.core/pom.xml index 55c7ee9ed..ba6fd0c6a 100644 --- a/bundles/org.xmind.core/pom.xml +++ b/bundles/org.xmind.core/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.core - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 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 ad70055e7..7795b9f6d 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/Core.java +++ b/bundles/org.xmind.core/src/org/xmind/core/Core.java @@ -16,8 +16,6 @@ import java.util.Comparator; import java.util.UUID; -import org.xmind.core.event.ICoreEventSource; -import org.xmind.core.event.ICoreEventSource2; import org.xmind.core.internal.InternalCore; import org.xmind.core.marker.IMarkerSheetBuilder; import org.xmind.core.style.IStyleSheetBuilder; @@ -815,6 +813,8 @@ public class Core { 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'). @@ -846,21 +846,12 @@ public class Core { public static final String WorkbookPreSave = "workbookPreSave"; //$NON-NLS-1$ /** - * - * NOTE: Since 3.6.50, this value is the same with 'workbookPreSave', for - * it's the client's responsibility to determine whether to use - * {@link ICoreEventSource#registerCoreEventListener(String, org.xmind.core.event.ICoreEventListener)} or - * {@link ICoreEventSource2#registerOnceCoreEventListener(String, org.xmind.core.event.ICoreEventListener)}. - * - * - *

* Core event type for going to save a workbook (value is - * 'workbookPreSave'). 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. - *

+ * '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:
@@ -872,7 +863,7 @@ public class Core { * @see org.xmind.core.IWorkbook#save(java.io.OutputStream) * @see org.xmind.core.IWorkbook#save(String) */ - public static final String WorkbookPreSaveOnce = "workbookPreSave"; //$NON-NLS-1$ + public static final String WorkbookPreSaveOnce = "workbookPreSaveOnce"; //$NON-NLS-1$ /** * Core event type for having saved a workbook (value is 'workbookSave'). 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 051971eb2..7c46120df 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IDeserializer.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IDeserializer.java @@ -44,6 +44,11 @@ */ public interface IDeserializer extends ISerializingBase { + IManifest getManifest(); + + void deserializeManifest(IProgressReporter reporter) + throws IOException, CoreException, IllegalStateException; + /** * Returns the deserialized workbook. * 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 b872ab8f9..3910cc33b 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IEncryptionData.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IEncryptionData.java @@ -14,7 +14,7 @@ package org.xmind.core; /** - * @author Frank Shaka + * @author frankshaka * */ public interface IEncryptionData extends IAdaptable { diff --git a/bundles/org.xmind.core/src/org/xmind/core/IExtensionElement.java b/bundles/org.xmind.core/src/org/xmind/core/IExtensionElement.java new file mode 100644 index 000000000..c38edb8ab --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/IExtensionElement.java @@ -0,0 +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); + +} 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 94c2abcf5..b731683fe 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IManifest.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IManifest.java @@ -32,6 +32,10 @@ */ public interface IManifest extends IWorkbookComponent, IAdaptable { + String getPasswordHint(); + + void setPasswordHint(String hint); + /** * Lists all existing file entries that has at least one reference. * diff --git a/bundles/org.xmind.core/src/org/xmind/core/INumbering.java b/bundles/org.xmind.core/src/org/xmind/core/INumbering.java index fe242fe27..3cea4f290 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/INumbering.java +++ b/bundles/org.xmind.core/src/org/xmind/core/INumbering.java @@ -23,6 +23,8 @@ public interface INumbering extends IAdaptable, ITopicComponent { String getSeparator(); + String getDepth(); + boolean prependsParentNumbers(); void setFormat(String format); @@ -33,6 +35,8 @@ public interface INumbering extends IAdaptable, ITopicComponent { void setSeparator(String separator); + void setDepth(String depth); + void setPrependsParentNumbers(boolean prepend); String getParentFormat(); @@ -43,4 +47,8 @@ public interface INumbering extends IAdaptable, ITopicComponent { String getComputedSeparator(); + int getComputedDepth(); + + boolean isInherited(int min); + } \ No newline at end of file diff --git a/bundles/org.xmind.core/src/org/xmind/core/ISerializerFactory.java b/bundles/org.xmind.core/src/org/xmind/core/ISerializerFactory.java new file mode 100644 index 000000000..259ddc906 --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/ISerializerFactory.java @@ -0,0 +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(); + +} 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 99e113ded..a40f2df72 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISettingEntry.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISettingEntry.java @@ -2,11 +2,6 @@ import java.util.Set; -/** - * - * @author Jason Wong - * @since 3.6.50 - */ public interface ISettingEntry extends IAdaptable, ISheetComponent { String getPath(); 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 673b38474..441ddc947 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ISheetSettings.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ISheetSettings.java @@ -4,9 +4,7 @@ import java.util.Set; /** - * * @author Jason Wong - * @since 3.6.50 */ public interface ISheetSettings extends IAdaptable, ISheetComponent { 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 e1d9a03f4..cf052cf99 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/ITopicExtensionElement.java +++ b/bundles/org.xmind.core/src/org/xmind/core/ITopicExtensionElement.java @@ -13,45 +13,11 @@ *******************************************************************************/ package org.xmind.core; -import java.util.List; -import java.util.Set; - -public interface ITopicExtensionElement extends IAdaptable, IWorkbookComponent { +public interface ITopicExtensionElement extends IAdaptable, IWorkbookComponent, + IExtensionElement { ITopicExtension getExtension(); ITopic getTopic(); - List getChildren(); - - List getChildren(String elementName); - - ITopicExtensionElement createChild(String elementName); - - ITopicExtensionElement getCreatedChild(String elementName); - - ITopicExtensionElement getFirstChild(String elementName); - - ITopicExtensionElement getParent(); - - void addChild(ITopicExtensionElement child, int index); - - void deleteChild(ITopicExtensionElement 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); - } \ 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 74f95377f..51cfe5375 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookBuilder.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookBuilder.java @@ -166,7 +166,7 @@ IWorkbook loadFromPath(String path, IEncryptionHandler encryptionHandler) @Deprecated IWorkbook loadFromPath(String path, IStorage storage, IEncryptionHandler encryptionHandler) - throws IOException, CoreException; + throws IOException, CoreException; /** * Creates a workbook instance and loads its content from the specified @@ -238,7 +238,7 @@ IWorkbook loadFromFile(File file, IEncryptionHandler encryptionHandler) @Deprecated IWorkbook loadFromFile(File file, IStorage storage, IEncryptionHandler encryptionHandler) - throws IOException, CoreException; + throws IOException, CoreException; /** * Creates a workbook instance and loads its content from the specified @@ -331,7 +331,7 @@ IWorkbook loadFromStream(InputStream in, IStorage storage) @Deprecated IWorkbook loadFromStream(InputStream in, IStorage storage, IEncryptionHandler encryptionHandler) - throws IOException, CoreException; + throws IOException, CoreException; /** * Creates a workbook instance and loads its content from the specified @@ -374,7 +374,7 @@ IWorkbook loadFromInputSource(IInputSource source) @Deprecated IWorkbook loadFromInputSource(IInputSource source, IEncryptionHandler encryptionHandler) - throws IOException, CoreException; + throws IOException, CoreException; /** * Creates a workbook instance and loads its content from the specified @@ -405,7 +405,7 @@ IWorkbook loadFromInputSource(IInputSource source, @Deprecated IWorkbook loadFromInputSource(IInputSource source, IStorage storage, IEncryptionHandler encryptionHandler) - throws IOException, CoreException; + throws IOException, CoreException; /** * Creates a new workbook instance and loads its content directly @@ -469,7 +469,7 @@ IWorkbook loadFromStorage(IStorage storage) @Deprecated IWorkbook loadFromStorage(IStorage storage, IEncryptionHandler encryptionHandler) - throws IOException, CoreException; + throws IOException, CoreException; /** * Sets the default encryption handler to use for loadFromXXX methods. @@ -506,7 +506,7 @@ IWorkbook loadFromStream(InputStream in, String tempLocation) @Deprecated IWorkbook loadFromStream(InputStream in, String tempLocation, IEncryptionHandler encryptionHandler) - throws IOException, CoreException; + throws IOException, CoreException; /** * @deprecated See {@link org.xmind.core.IDeserializer} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtension.java b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtension.java new file mode 100644 index 000000000..837c20cc4 --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtension.java @@ -0,0 +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); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionElement.java b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionElement.java new file mode 100644 index 000000000..7832cdb8d --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionElement.java @@ -0,0 +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(); + +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionManager.java b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionManager.java new file mode 100644 index 000000000..020d795ae --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkbookExtensionManager.java @@ -0,0 +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(); + +} 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 b5c5ecb6d..c38c22510 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/IWorkspace.java +++ b/bundles/org.xmind.core/src/org/xmind/core/IWorkspace.java @@ -20,9 +20,8 @@ * 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 + * NOTE: This interface is not intended to be implemented by client. + * Use the facade method Core.getWorkspace() to get a singleton * instance. *

* diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/Numbering.java b/bundles/org.xmind.core/src/org/xmind/core/internal/Numbering.java index 23f21041f..2c82e1dd5 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/Numbering.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/Numbering.java @@ -59,4 +59,43 @@ public String getComputedSeparator() { return getParentSeparator(); } + public int getComputedDepth() { + String nf = getNumberFormat(); + String noneFormat = "org.xmind.numbering.none"; //$NON-NLS-1$ + + if (noneFormat.equals(nf)) + return -1; + + String dv = getDepth(); + if (dv != null) + return Integer.parseInt(dv); + + if (isInherited(1)) + return getParent().getParent().getNumbering().getComputedDepth() + - 1; + else if (getNumberFormat() != null) + return 3; + + return -1; + } + + public boolean isInherited(int min) { + ITopic topic = getParent(); + if (!ITopic.ATTACHED.equals(topic.getType())) + return false; + + if (getDepth() != null) + return false; + + if ("org.xmind.numbering.none".equals(getNumberFormat())) //$NON-NLS-1$ + return false; + + ITopic parentTopic = topic.getParent(); + if (parentTopic == null) + return false; + + int pd = parentTopic.getNumbering().getComputedDepth(); + return pd > min; + } + } \ 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 new file mode 100644 index 000000000..65cedfe11 --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtension.java @@ -0,0 +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(); + +} 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 new file mode 100644 index 000000000..beb602e0d --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtensionElement.java @@ -0,0 +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); + } + +} 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 new file mode 100644 index 000000000..2cce88fac --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/WorkbookExtensionManager.java @@ -0,0 +1,11 @@ +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/dom/BaseNotesContentImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/BaseNotesContentImpl.java index 38f937748..95edb3470 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/BaseNotesContentImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/BaseNotesContentImpl.java @@ -38,10 +38,9 @@ public BaseNotesContentImpl(Element implementation, this.ownedWorkbook = ownedWorkbook; } - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return implementation; - + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); return super.getAdapter(adapter); } @@ -105,7 +104,6 @@ public IWorkbook getOwnedWorkbook() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { @@ -123,4 +121,4 @@ protected void updateModifiedTime() { } } -} \ 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 ab485a05d..09ebc1410 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 @@ -51,11 +51,11 @@ public Element getImplementation() { return implementation; } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Node.class || adapter == Element.class) - 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); } @@ -288,4 +288,4 @@ protected void updateModificationInfo() { } } -} \ No newline at end of file +} 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 ec8a28955..8aa06f145 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 @@ -21,7 +21,6 @@ import static org.xmind.core.internal.dom.DOMConstants.TAG_CONTENT; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.xmind.core.Core; import org.xmind.core.IComment; import org.xmind.core.IWorkbook; @@ -33,7 +32,6 @@ /** * @author Frank Shaka - * */ public class CommentImpl implements IComment, ICoreEventSource { @@ -41,11 +39,15 @@ public class CommentImpl implements IComment, ICoreEventSource { private final Element implementation; + private CommentManagerImpl ownedCommentManager; + /** * */ - public CommentImpl(WorkbookImpl ownerWorkbook, Element implementation) { + public CommentImpl(WorkbookImpl ownerWorkbook, + CommentManagerImpl ownedCommentManager, Element implementation) { this.ownerWorkbook = ownerWorkbook; + this.ownedCommentManager = ownedCommentManager; this.implementation = implementation; } @@ -58,13 +60,12 @@ public Element getImplementation() { /* * (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) || Element.class.equals(adapter)) + if (adapter.isAssignableFrom(Element.class)) return adapter.cast(implementation); if (ICoreEventSupport.class.equals(adapter)) return adapter.cast(getCoreEventSupport()); @@ -73,7 +74,6 @@ public T getAdapter(Class adapter) { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#getOwnedWorkbook() */ public IWorkbook getOwnedWorkbook() { @@ -82,7 +82,6 @@ public IWorkbook getOwnedWorkbook() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { @@ -91,7 +90,6 @@ public boolean isOrphan() { /* * (non-Javadoc) - * * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(IComment that) { @@ -100,7 +98,6 @@ public int compareTo(IComment that) { /* * (non-Javadoc) - * * @see org.xmind.core.IComment#getObjectId() */ public String getObjectId() { @@ -109,7 +106,6 @@ public String getObjectId() { /* * (non-Javadoc) - * * @see org.xmind.core.IComment#getAuthor() */ public String getAuthor() { @@ -118,7 +114,6 @@ public String getAuthor() { /* * (non-Javadoc) - * * @see org.xmind.core.IComment#getTime() */ public long getTime() { @@ -129,7 +124,6 @@ public long getTime() { /* * (non-Javadoc) - * * @see org.xmind.core.IComment#getContent() */ public String getContent() { @@ -138,7 +132,6 @@ public String getContent() { /* * (non-Javadoc) - * * @see org.xmind.core.IComment#setContent(java.lang.String) */ public void setContent(String content) { @@ -150,11 +143,11 @@ public void setContent(String content) { 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) @@ -167,11 +160,16 @@ public ICoreEventRegistration registerCoreEventListener(String type, /* * (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 671d0efd9..95b684aeb 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 @@ -41,12 +41,11 @@ /** * @author Frank Shaka - * */ public class CommentManagerImpl implements ICommentManager, INodeAdaptableFactory { - private final WorkbookImpl ownerWorkbook; + private final WorkbookImpl ownedWorkbook; private final Document implementation; @@ -59,7 +58,7 @@ public class CommentManagerImpl */ public CommentManagerImpl(WorkbookImpl ownerWorkbook, Document implementation) { - this.ownerWorkbook = ownerWorkbook; + this.ownedWorkbook = ownerWorkbook; this.implementation = implementation; this.registry = new NodeAdaptableRegistry(implementation, this); this.pendingComments = new HashSet(); @@ -78,7 +77,6 @@ private Element getCommentsElement() { /* * (non-Javadoc) - * * @see org.xmind.core.IAdaptable#getAdapter(java.lang.Class) */ public T getAdapter(Class adapter) { @@ -91,16 +89,14 @@ public T getAdapter(Class adapter) { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#getOwnedWorkbook() */ public IWorkbook getOwnedWorkbook() { - return ownerWorkbook; + return ownedWorkbook; } /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { @@ -118,7 +114,7 @@ protected void objectAddNotify(String objectId, Object obj) { if (ele.getParentNode() != p) { p.appendChild(ele); if (obj instanceof ICoreEventSource) { - ownerWorkbook.getCoreEventSupport() + ownedWorkbook.getCoreEventSupport() .dispatchTargetChange((ICoreEventSource) obj, Core.CommentAdd, c); } @@ -143,7 +139,7 @@ protected void objectRemoveNotify(String objectId, Object obj) { CommentImpl c = (CommentImpl) a; pendingComments.add(c); if (obj instanceof ICoreEventSource) { - ownerWorkbook.getCoreEventSupport() + ownedWorkbook.getCoreEventSupport() .dispatchTargetChange( (ICoreEventSource) obj, Core.CommentRemove, c); @@ -158,7 +154,6 @@ protected void objectRemoveNotify(String objectId, Object obj) { /* * (non-Javadoc) - * * @see org.xmind.core.ICommentManager#createComment(java.lang.String, long, * java.lang.String) */ @@ -175,7 +170,7 @@ public IComment createComment(String author, long time, String objectId) { DOMUtils.setAttribute(ele, ATTR_TIME, Long.toString(time)); DOMUtils.setAttribute(ele, ATTR_OBJECT_ID, objectId); - CommentImpl c = new CommentImpl(ownerWorkbook, ele); + CommentImpl c = new CommentImpl(ownedWorkbook, this, ele); registry.register(c, ele); return c; } @@ -187,7 +182,6 @@ private static boolean isObjectOrphan(Object obj) { /* * (non-Javadoc) - * * @see org.xmind.core.ICommentManager#addCommand(org.xmind.core.IComment) */ public void addComment(IComment comment) { @@ -201,7 +195,7 @@ public void addComment(IComment comment) { if (ele.getParentNode() == p) return; - Object obj = ownerWorkbook.getElementById(c.getObjectId()); + Object obj = ownedWorkbook.getElementById(c.getObjectId()); if (obj == null || isObjectOrphan(obj)) { /// associated object not exist, /// add comment to pending set @@ -211,14 +205,14 @@ public void addComment(IComment comment) { p.appendChild(ele); if (obj instanceof ICoreEventSource) { - ownerWorkbook.getCoreEventSupport().dispatchTargetChange( + ownedWorkbook.getCoreEventSupport().dispatchTargetChange( (ICoreEventSource) obj, Core.CommentAdd, c); } + updateModificationInfo(); } /* * (non-Javadoc) - * * @see * org.xmind.core.ICommentManager#removeComment(org.xmind.core.IComment) */ @@ -238,16 +232,16 @@ public void removeComment(IComment comment) { p.removeChild(ele); - Object obj = ownerWorkbook.getElementById(c.getObjectId()); + Object obj = ownedWorkbook.getElementById(c.getObjectId()); if (obj instanceof ICoreEventSource) { - ownerWorkbook.getCoreEventSupport().dispatchTargetChange( + 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) { @@ -276,7 +270,6 @@ public Set getComments(String objectId) { /* * (non-Javadoc) - * * @see org.xmind.core.ICommentManager#hasComments(java.lang.String) */ public boolean hasComments(String objectId) { @@ -305,7 +298,6 @@ public boolean hasComments(String objectId) { /* * (non-Javadoc) - * * @see org.xmind.core.ICommentManager#getAllComments() */ public Set getAllComments() { @@ -328,7 +320,6 @@ public Set getAllComments() { /* * (non-Javadoc) - * * @see org.xmind.core.ICommentManager#isEmpty() */ public boolean isEmpty() { @@ -350,7 +341,6 @@ public boolean isEmpty() { /* * (non-Javadoc) - * * @see * org.xmind.core.internal.dom.INodeAdaptableFactory#createAdaptable(org.w3c * .dom.Node) @@ -360,10 +350,16 @@ public IAdaptable createAdaptable(Node node) { Element ele = (Element) node; String tag = ele.getTagName(); if (TAG_COMMENT.equals(tag)) { - return new CommentImpl(ownerWorkbook, ele); + 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/ControlPointImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ControlPointImpl.java index a079745ed..96efe8fcf 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ControlPointImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ControlPointImpl.java @@ -26,7 +26,6 @@ import java.util.Iterator; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.xmind.core.Core; import org.xmind.core.IRelationship; import org.xmind.core.ISheet; @@ -83,13 +82,13 @@ public String toString() { return "CP{" + index + "," + parent.toString() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Node.class || adapter == Element.class) - return getImplementation(); - if (adapter == IRelationship.class) - return parent; + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getImplementation()); + if (IRelationship.class.equals(adapter)) + return adapter.cast(parent); return super.getAdapter(adapter); } @@ -284,4 +283,4 @@ public ICoreEventRegistration registerCoreEventListener(String type, listener); } -} \ No newline at end of file +} 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 829b7a559..b6faa1b12 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 @@ -15,7 +15,6 @@ /** * @author briansun - * */ public class DOMConstants { @@ -84,17 +83,21 @@ public class DOMConstants { 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$ @@ -117,6 +120,7 @@ public class DOMConstants { 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$ /* * @@ -193,6 +197,7 @@ public class DOMConstants { 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 @@ -230,4 +235,4 @@ public class DOMConstants { public static final String VAL_UPPERCASE = "uppercase"; //$NON-NLS-1$ public static final String VAL_VISIBLE = "visible"; //$NON-NLS-1$ -} \ No newline at end of file +} 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 249b01e7f..68ebbf1a6 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 @@ -18,6 +18,7 @@ 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; @@ -40,6 +41,7 @@ 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; @@ -170,13 +172,7 @@ public boolean hasInputSource() { || usesWorkbookStorageAsInputSource; } - /* - * (non-Javadoc) - * - * @see org.xmind.core.IDeserializer#deserialize(org.xmind.core.util. - * IProgressReporter) - */ - public void deserialize(IProgressReporter reporter) + public void deserializeManifest(IProgressReporter reporter) throws IOException, CoreException, IllegalStateException { if (inputStream != null) { ZipInputStream zin = new ZipInputStream(inputStream); @@ -196,6 +192,18 @@ public void deserialize(IProgressReporter reporter) 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 @@ -251,6 +259,20 @@ private WorkbookImpl loadWorkbook() throws IOException, CoreException { 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) { @@ -409,7 +431,7 @@ protected Document forceLoadDocumentFromEntry(String entryPath) return document; } - protected ManifestImpl getManifest() { + public ManifestImpl getManifest() { return manifest; } 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 0853f214b..45d3acfff 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 @@ -17,14 +17,12 @@ import static org.xmind.core.internal.dom.DOMConstants.ATTR_CHECKSUM_TYPE; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.xmind.core.IFileEntry; import org.xmind.core.internal.EncryptionData; import org.xmind.core.util.DOMUtils; /** * @author frankshaka - * */ public class EncryptionDataImpl extends EncryptionData { @@ -44,13 +42,12 @@ public EncryptionDataImpl(Element implementation, FileEntryImpl entry) { /* * (non-Javadoc) - * * @see org.xmind.core.internal.EncryptionData#getAdapter(java.lang.Class) */ @Override - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return getImplementation(); + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getImplementation()); return super.getAdapter(adapter); } @@ -63,7 +60,6 @@ public Element getImplementation() { /* * (non-Javadoc) - * * @see org.xmind.core.IEncryptionData#getIntAttribute(int, * java.lang.String[]) */ @@ -80,7 +76,6 @@ public int getIntAttribute(int defaultValue, String... keyPath) { /* * (non-Javadoc) - * * @see org.xmind.core.IEncryptionData#getAttribute(java.lang.String) */ public String getAttribute(String... keys) { @@ -99,7 +94,6 @@ public String getAttribute(String... keys) { /* * (non-Javadoc) - * * @see org.xmind.core.IEncryptionData#setAttribute(java.lang.String, * java.lang.String) */ @@ -123,7 +117,6 @@ public void setAttribute(String value, String... keys) { /* * (non-Javadoc) - * * @see org.xmind.core.IEncryptionData#getChecksum() */ public String getChecksum() { @@ -132,7 +125,6 @@ public String getChecksum() { /* * (non-Javadoc) - * * @see org.xmind.core.IEncryptionData#getChecksumType() */ public String getChecksumType() { @@ -141,7 +133,6 @@ public String getChecksumType() { /* * (non-Javadoc) - * * @see org.xmind.core.IEncryptionData#setChecksum(java.lang.String) */ public void setChecksum(String checksum) { @@ -150,7 +141,6 @@ public void setChecksum(String checksum) { /* * (non-Javadoc) - * * @see org.xmind.core.IEncryptionData#setChecksumType(java.lang.String) */ public void setChecksumType(String checksumType) { @@ -159,7 +149,6 @@ public void setChecksumType(String checksumType) { /* * (non-Javadoc) - * * @see org.xmind.core.IEncryptionData#getFileEntry() */ public IFileEntry getFileEntry() { 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 cb6e9a955..096da07f0 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 @@ -25,7 +25,6 @@ import java.util.Iterator; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.xmind.core.CoreException; import org.xmind.core.IEncryptionData; import org.xmind.core.IEntryStreamNormalizer; @@ -72,9 +71,9 @@ public String getPath() { return implementation.getAttribute(ATTR_FULL_PATH); } - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return implementation; + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); return super.getAdapter(adapter); } @@ -239,7 +238,6 @@ public void setTime(long time) { /* * (non-Javadoc) - * * @see org.xmind.core.IFileEntry#iterSubEntries() */ public Iterator iterSubEntries() { @@ -267,7 +265,6 @@ public long getSize() { /* * (non-Javadoc) - * * @see org.xmind.core.IFileEntry#getEncryptionData() */ public IEncryptionData getEncryptionData() { @@ -287,7 +284,6 @@ public IEncryptionData getEncryptionData() { /* * (non-Javadoc) - * * @see org.xmind.core.IFileEntry#createEncryptionData() */ public IEncryptionData createEncryptionData() { @@ -303,7 +299,6 @@ public IEncryptionData createEncryptionData() { /* * (non-Javadoc) - * * @see org.xmind.core.IFileEntry#deleteEncryptionData() */ public void deleteEncryptionData() { @@ -342,4 +337,4 @@ public boolean isOrphan() { return DOMUtils.isOrphanNode(getImplementation()); } -} \ 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 facc75232..0a79e815a 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 @@ -21,7 +21,6 @@ import static org.xmind.core.internal.dom.NumberUtils.safeParseInt; 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; @@ -61,11 +60,11 @@ public String toString() { return DOMUtils.toString(getImageElement()); } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Node.class || adapter == Element.class) - return 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); } @@ -109,7 +108,8 @@ public int getWidth() { Element img = getImageElement(); if (img == null) return UNSPECIFIED; - return safeParseInt(DOMUtils.getAttribute(img, ATTR_WIDTH), UNSPECIFIED); + return safeParseInt(DOMUtils.getAttribute(img, ATTR_WIDTH), + UNSPECIFIED); } private Element ensureImageElement() { @@ -194,7 +194,6 @@ public IWorkbook getOwnedWorkbook() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { @@ -225,4 +224,4 @@ protected void deactivateHyperlink(IWorkbook workbook) { InternalHyperlinkUtils.deactivateHyperlink(workbook, getSource(), this); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/LegendImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/LegendImpl.java index ca8ef8bcd..042d9f35f 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/LegendImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/LegendImpl.java @@ -81,9 +81,9 @@ public boolean isOrphan() { || getImplementation() == null; } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; + public T getAdapter(Class adapter) { + if (ICoreEventSource.class.equals(adapter)) + return adapter.cast(this); return super.getAdapter(adapter); } @@ -99,7 +99,8 @@ private Element ensureImplementation() { private void checkImplementation() { Element implementation = getImplementation(); - if (!implementation.hasAttributes() && !implementation.hasChildNodes()) { + if (!implementation.hasAttributes() + && !implementation.hasChildNodes()) { sheetElement.removeChild(implementation); } } @@ -115,8 +116,8 @@ public boolean isEmpty() { public boolean isVisible() { Element implementation = getImplementation(); if (implementation != null) { - return DOMConstants.VAL_VISIBLE.equals(implementation - .getAttribute(DOMConstants.ATTR_VISIBILITY)); + return DOMConstants.VAL_VISIBLE.equals( + implementation.getAttribute(DOMConstants.ATTR_VISIBILITY)); } return false; } @@ -218,8 +219,8 @@ public String getMarkerDescription(String markerId) { if (description != null) return description; } - IMarker marker = getOwnedWorkbook().getMarkerSheet().findMarker( - markerId); + IMarker marker = getOwnedWorkbook().getMarkerSheet() + .findMarker(markerId); if (marker != null) return marker.getName(); return ""; //$NON-NLS-1$ @@ -279,8 +280,8 @@ public Set getMarkerIds() { Iterator it = DOMUtils.childElementIterByTag(itemsEle, DOMConstants.TAG_MARKER_DESCRIPTION); if (it.hasNext()) { - ArrayList list = new ArrayList(itemsEle - .getChildNodes().getLength()); + ArrayList list = new ArrayList( + itemsEle.getChildNodes().getLength()); while (it.hasNext()) { Element item = it.next(); String markerId = DOMUtils.getAttribute(item, @@ -302,7 +303,8 @@ public ICoreEventRegistration registerCoreEventListener(String type, listener); } - protected void fireValueChange(String type, Object oldValue, Object newValue) { + protected void fireValueChange(String type, Object oldValue, + Object newValue) { getCoreEventSupport().dispatchValueChange(this, type, oldValue, newValue); } @@ -316,4 +318,4 @@ protected void fireTargetValueChange(String type, Object target, public ICoreEventSupport getCoreEventSupport() { return ownedSheet.getCoreEventSupport(); } -} \ 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 d77b5cb85..921eb63cd 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 @@ -15,6 +15,7 @@ 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; @@ -33,7 +34,6 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.xmind.core.Core; import org.xmind.core.IEncryptionData; import org.xmind.core.IEntryStreamNormalizer; @@ -96,11 +96,11 @@ public Element getManifestElement() { return implementation.getDocumentElement(); } - public Object getAdapter(Class adapter) { - if (adapter == Document.class || adapter == Node.class) - return implementation; - if (adapter == IWorkbook.class) - return ownedWorkbook; + 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); } @@ -110,7 +110,6 @@ public IWorkbook getOwnedWorkbook() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { @@ -118,7 +117,6 @@ public boolean isOrphan() { } /** - * * @param workbook */ protected void setWorkbook(WorkbookImpl workbook) { @@ -151,7 +149,6 @@ protected Collection getAllRegisteredEntries() { /* * (non-Javadoc) - * * @see org.xmind.core.IManifest#iterFileEntries() */ public Iterator iterFileEntries() { @@ -160,7 +157,6 @@ public Iterator iterFileEntries() { /* * (non-Javadoc) - * * @see org.xmind.core.IManifest#iterFileEntries(org.xmind.core.IManifest. * IFileEntryFilter) */ @@ -505,7 +501,6 @@ public String makeAttachmentPath(String source, boolean directory) { /* * (non-Javadoc) - * * @see org.xmind.core.IManifest#getEncryptionData(java.lang.String) */ public IEncryptionData getEncryptionData(String entryPath) { @@ -529,6 +524,16 @@ public CoreEventSupport getCoreEventSupport() { 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(); 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 406407492..1808dfc71 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 @@ -49,11 +49,11 @@ public Element getImplementation() { return implementation; } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Element.class || adapter == Node.class) - 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); } @@ -137,7 +137,6 @@ public List getMarkers() { /* * (non-Javadoc) - * * @see org.xmind.core.marker.IMarkerGroup#isEmpty() */ public boolean isEmpty() { @@ -192,4 +191,4 @@ private void fireIndexedTargetChange(String type, Object target, public ICoreEventSupport getCoreEventSupport() { return ownedSheet.getCoreEventSupport(); } -} \ No newline at end of file +} 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 3e2ce9ce8..cd9aa2cd4 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 @@ -54,11 +54,11 @@ public Element getImplementation() { return implementation; } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Element.class || adapter == Node.class) - 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); } @@ -150,4 +150,4 @@ private void fireValueChange(String type, Object oldValue, public ICoreEventSupport getCoreEventSupport() { return ownedSheet.getCoreEventSupport(); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerRefImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerRefImpl.java index 77e1b84fa..7d57f76eb 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerRefImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MarkerRefImpl.java @@ -58,9 +58,9 @@ public String toString() { return "MKRRef#" + getMarkerId(); //$NON-NLS-1$ } - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return implementation; + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); return super.getAdapter(adapter); } @@ -103,4 +103,4 @@ public boolean isOrphan() { return DOMUtils.isOrphanNode(implementation); } -} \ 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 2c719e288..269c6a497 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 @@ -104,27 +104,27 @@ public void setManifest(ManifestImpl manifest) { this.manifest = manifest; } - public Object getAdapter(Class adapter) { - if (adapter == IManifest.class) - return manifest; - if (adapter == ICoreEventSource.class) - return this; - if (adapter == IMarkerResourceProvider.class) - return realResourceProvider; - if (adapter == ICoreEventSupport.class) - return getCoreEventSupport(); - if (adapter == IPropertiesProvider.class) - return this; - if (adapter == Properties.class) - return getProperties(); - if (adapter == ElementRegistry.class) - return getElementRegistry(); - if (adapter == INodeAdaptableFactory.class) - return this; - if (adapter == INodeAdaptableProvider.class) - return getElementAdapterProvider(); - if (adapter == Document.class || adapter == Node.class) - 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 (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); } @@ -282,6 +282,7 @@ public IAdaptable createAdaptable(Node node) { return null; } + @Deprecated public void save(OutputStream out) throws IOException, CoreException { DOMUtils.save(implementation, out, false); } @@ -295,6 +296,7 @@ public void save(OutputStream out) throws IOException, CoreException { 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); @@ -313,6 +315,7 @@ public void importFrom(String sourcePath) } } + @Deprecated public void importFrom(IInputSource source) throws IOException, CoreException { importFrom(source, null); @@ -320,10 +323,10 @@ public void importFrom(IInputSource source) /* * (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)) { @@ -340,6 +343,7 @@ public void importFrom(IInputSource source, String groupName) } } + @Deprecated private void importAllAsNewGroup(IInputSource source, String groupName) throws IOException { IMarkerGroup group = createMarkerGroup(false); @@ -375,6 +379,7 @@ private String createGroupName() { //return Core.getIdFactory().createId(); } + @Deprecated private void importFromOldMarkerSheet(IInputSource source) throws IOException { InputStream is = source.openEntryStream(OLD_MARKERLISTS_XML); @@ -409,6 +414,7 @@ private void replaceId(IAdaptable adaptable, String newId) { getElementRegistry().registerByKey(newId, adaptable); } + @Deprecated private void importGroupFromOld(IInputSource source, Element listEle, IMarkerGroup targetGroup) throws IOException { targetGroup.setName(listEle.getAttribute(OLD_ATT_NAME)); @@ -453,6 +459,7 @@ public void importFrom(IMarkerSheet sheet) { } } + @Deprecated public void importFromChecked(IMarkerSheet sheet) throws IOException, CoreException { for (IMarkerGroup group : sheet.getMarkerGroups()) { @@ -470,6 +477,7 @@ public IMarkerGroup importGroup(IMarkerGroup group) { } } + @Deprecated public IMarkerGroup importGroupChecked(IMarkerGroup group) throws IOException, CoreException { String id = group.getId(); @@ -490,6 +498,7 @@ public IMarkerGroup importGroupChecked(IMarkerGroup group) return targetGroup; } + @Deprecated private void importGroup(IMarkerGroup sourceGroup, IMarkerGroup targetGroup) throws IOException { for (IMarker sourceMarker : sourceGroup.getMarkers()) { @@ -545,7 +554,6 @@ private void fireIndexedTargetChange(String type, Object target, /* * (non-Javadoc) - * * @see org.xmind.core.marker.IMarkerSheet#createMarkerResourcePath(java.io. * InputStream, java.lang.String) */ @@ -559,4 +567,4 @@ public String allocateMarkerResource(InputStream source, return null; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MetaDataImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MetaDataImpl.java index abdf14ead..df3d94598 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MetaDataImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/MetaDataImpl.java @@ -28,7 +28,6 @@ /** * @deprecated - * * @author Frank Shaka */ public class MetaDataImpl extends MetaData { @@ -59,9 +58,9 @@ public String toString() { return DOMUtils.toString(implementation); } - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return getImplementation(); + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getImplementation()); return super.getAdapter(adapter); } @@ -145,4 +144,4 @@ public void setValue(String value) { } } -} \ No newline at end of file +} 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 2777f0f9a..29dedd2a1 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 @@ -23,7 +23,6 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.xmind.core.Core; import org.xmind.core.IMetaData; import org.xmind.core.IWorkbook; @@ -81,13 +80,13 @@ public String toString() { return DOMUtils.toString(implementation); } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Node.class || adapter == Document.class) - return implementation; - if (adapter == ElementRegistry.class) - return getElementRegistry(); + 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); } @@ -105,7 +104,6 @@ public IWorkbook getOwnedWorkbook() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { @@ -165,7 +163,6 @@ public void setValue(String keyPath, String value) { /* * (non-Javadoc) - * * @see org.xmind.core.IMeta#getKeyPaths() */ public Set getKeyPaths() { @@ -261,7 +258,6 @@ public ElementRegistry getElementRegistry() { /* * (non-Javadoc) - * * @see org.xmind.core.event.ICoreEventSource#getCoreEventSupport() */ public ICoreEventSupport getCoreEventSupport() { @@ -270,7 +266,6 @@ public ICoreEventSupport getCoreEventSupport() { /* * (non-Javadoc) - * * @see * org.xmind.core.event.ICoreEventSource#registerCoreEventListener(java. * lang.String, org.xmind.core.event.ICoreEventListener) 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 3bc623989..e6f26f055 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 @@ -26,6 +26,7 @@ public enum NS { 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$ 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 289b21673..2ff0278b9 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 @@ -18,7 +18,6 @@ import java.util.Iterator; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.xmind.core.Core; import org.xmind.core.INotesContent; import org.xmind.core.ISheet; @@ -29,7 +28,6 @@ /** * @author briansun - * */ public class NotesImpl extends Notes { @@ -63,9 +61,9 @@ public String toString() { return DOMUtils.toString(getNotesElement()); } - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return getNotesElement(); + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getNotesElement()); return super.getAdapter(adapter); } @@ -104,8 +102,8 @@ public void setContent(String format, INotesContent content) { return; Element notesEle = getNotesElement(); - Element oldContentEle = notesEle == null ? null : DOMUtils - .getFirstChildElementByTag(notesEle, format); + Element oldContentEle = notesEle == null ? null + : DOMUtils.getFirstChildElementByTag(notesEle, format); INotesContent oldContent = oldContentEle == null ? null : getNotesContent(oldContentEle); @@ -200,11 +198,10 @@ public IWorkbook getOwnedWorkbook() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { return ownedTopic.isOrphan(); } -} \ 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 c6183c819..ad7e17829 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 @@ -13,6 +13,7 @@ *******************************************************************************/ 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; @@ -22,7 +23,6 @@ import static org.xmind.core.internal.dom.DOMConstants.VAL_NONE; 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; @@ -49,11 +49,11 @@ public Element getNumberingElement() { return DOMUtils.getFirstChildElementByTag(topicElement, TAG_NUMBERING); } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Node.class || adapter == Element.class) - return getNumberingElement(); + 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); } @@ -96,6 +96,13 @@ 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) @@ -118,7 +125,6 @@ public IWorkbook getOwnedWorkbook() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { @@ -135,8 +141,8 @@ private void setAttribute(String key, String value) { } } } else { - Element e = DOMUtils - .ensureChildElement(topicElement, TAG_NUMBERING); + Element e = DOMUtils.ensureChildElement(topicElement, + TAG_NUMBERING); e.setAttribute(key, value); } } @@ -162,8 +168,8 @@ private void setText(String key, String value) { } } } else { - Element e = DOMUtils - .ensureChildElement(topicElement, TAG_NUMBERING); + Element e = DOMUtils.ensureChildElement(topicElement, + TAG_NUMBERING); Element t = DOMUtils.ensureChildElement(e, key); t.setTextContent(value); } @@ -209,6 +215,14 @@ public void setSeparator(String separator) { 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, @@ -225,4 +239,4 @@ public ICoreEventSupport getCoreEventSupport() { return ownedTopic.getCoreEventSupport(); } -} \ No newline at end of file +} 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 75e8da28d..3ad2d9b1b 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 @@ -16,7 +16,6 @@ import java.util.List; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.xmind.core.IParagraph; import org.xmind.core.ISpan; import org.xmind.core.IWorkbook; @@ -83,10 +82,9 @@ public void removeSpan(ISpan span) { getOwner().updateModifiedTime(); } - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return implementation; - + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); return super.getAdapter(adapter); } @@ -110,7 +108,6 @@ public IWorkbook getOwnedWorkbook() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { @@ -131,4 +128,4 @@ protected void removeNotify(WorkbookImpl workbook) { WorkbookUtilsImpl.decreaseStyleRef(workbook, this); } -} \ 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 07f9ef3a3..905acb277 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 @@ -41,7 +41,6 @@ /** * @author briansun - * */ public class RelationshipImpl extends Relationship implements ICoreEventSource { @@ -134,7 +133,6 @@ public void setEnd2Id(String id) { /* * (non-Javadoc) - * * @see org.xmind.core.internal.Relationship#getEnd1() */ @Override @@ -144,7 +142,6 @@ public IRelationshipEnd getEnd1() { /* * (non-Javadoc) - * * @see org.xmind.core.internal.Relationship#getEnd2() */ @Override @@ -209,11 +206,11 @@ public boolean isOrphan() { return DOMUtils.isOrphanNode(implementation); } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Element.class || adapter == Node.class) - 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); } @@ -371,4 +368,4 @@ protected void updateModificationInfo() { } } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ResourceRefImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ResourceRefImpl.java index 7313b271c..1ea4dd060 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ResourceRefImpl.java +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/ResourceRefImpl.java @@ -14,7 +14,6 @@ package org.xmind.core.internal.dom; import org.w3c.dom.Element; -import org.w3c.dom.Node; import org.xmind.core.IFileEntry; import org.xmind.core.IResourceRef; import org.xmind.core.internal.AbstractWorkbookComponent; @@ -25,15 +24,22 @@ public class ResourceRefImpl extends AbstractWorkbookComponent implements IResourceRef { + private Element source; + private Element implementation; private WorkbookImpl ownedWorkbook; public ResourceRefImpl(Element implementation, WorkbookImpl ownedWorkbook) { + this.source = implementation; this.implementation = implementation; this.ownedWorkbook = ownedWorkbook; } + protected void setImplementation(Element implementation) { + this.implementation = implementation; + } + public Element getImplementation() { return implementation; } @@ -44,7 +50,6 @@ public WorkbookImpl getOwnedWorkbook() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { @@ -57,21 +62,20 @@ public boolean equals(Object obj) { if (obj == null || !(obj instanceof ResourceRefImpl)) return false; ResourceRefImpl that = (ResourceRefImpl) obj; - return this.implementation == that.implementation; + return this.source == that.source; } public int hashCode() { - return implementation.hashCode(); + return source.hashCode(); } public String toString() { return "ResRef#" + getResourceId(); //$NON-NLS-1$ } - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return implementation; - + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); return super.getAdapter(adapter); } @@ -130,4 +134,4 @@ public String getType() { return DOMUtils.getAttribute(implementation, DOMConstants.ATTR_TYPE); } -} \ No newline at end of file +} 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 0aa37f5df..af2e9738e 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 @@ -34,7 +34,6 @@ /** * @author Frank Shaka - * */ public class RevisionImpl extends Revision { @@ -65,9 +64,9 @@ public boolean equals(Object obj) { } @Override - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return getImplementation(); + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getImplementation()); return super.getAdapter(adapter); } 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 beb1bc164..18d699939 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 @@ -50,7 +50,6 @@ /** * @author Frank Shaka - * */ public class RevisionManagerImpl extends RevisionManager implements ICoreEventSource, INodeAdaptableFactory { @@ -94,11 +93,11 @@ public boolean equals(Object obj) { } @Override - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Node.class || adapter == Document.class) - return getImplementation(); + 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); } @@ -312,7 +311,6 @@ private IFileEntry getMetaFileEntry() { /* * (non-Javadoc) - * * @see org.xmind.core.event.ICoreEventSource#getCoreEventSupport() */ public ICoreEventSupport getCoreEventSupport() { @@ -324,7 +322,6 @@ public ICoreEventSupport getCoreEventSupport() { /* * (non-Javadoc) - * * @see * org.xmind.core.event.ICoreEventSource#registerCoreEventListener(java. * lang.String, org.xmind.core.event.ICoreEventListener) 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 3d55e4683..376baabc0 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 @@ -17,6 +17,7 @@ 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; @@ -28,6 +29,7 @@ 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; @@ -50,6 +52,8 @@ 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; @@ -324,6 +328,16 @@ public void serialize(IProgressReporter reporter) 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(); 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 3569e7c5f..38ef2efb9 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 @@ -5,7 +5,6 @@ import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; import org.xmind.core.Core; import org.xmind.core.ISheet; import org.xmind.core.IWorkbook; @@ -80,9 +79,9 @@ public boolean isOrphan() { return DOMUtils.isOrphanNode(implementation); } - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return getImplementation(); + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(getImplementation()); return super.getAdapter(adapter); } 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 4970e5d24..a2d572e8e 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 @@ -45,7 +45,6 @@ /** * @author Brian Sun * @author Frank Shaka - * */ public class SheetImpl extends Sheet implements ICoreEventSource { @@ -105,17 +104,17 @@ public String toString() { return "SHT#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Element.class || adapter == Node.class) { - return implementation; - } else if (adapter == IMarkerRefCounter.class) { - return getMarkerRefCounter(); - } else if (adapter == ILabelRefCounter.class) { - return getLabelRefCounter(); - } else if (adapter == ICoreEventSupport.class) { - return getCoreEventSupport(); + 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); } @@ -161,7 +160,6 @@ public IWorkbook getOwnedWorkbook() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbookComponent#isOrphan() */ public boolean isOrphan() { @@ -400,4 +398,4 @@ public ISheetSettings getSettings() { return settings; } -} \ No newline at end of file +} 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 9812f7d48..9dbd8be0e 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 @@ -56,11 +56,12 @@ public String toString() { return implementation.toString(); } - public Object getAdapter(Class adapter) { - if (adapter == Node.class || (adapter == Element.class - && implementation instanceof Element)) - return implementation; - + 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); } @@ -115,4 +116,4 @@ protected void removeNotify(WorkbookImpl workbook) { WorkbookUtilsImpl.decreaseStyleRef(workbook, this); } -} \ No newline at end of file +} 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 82da5b0b7..ced196465 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 @@ -175,11 +175,11 @@ public String toString() { return "STY#" + getId() + "(" + getName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Element.class || adapter == Node.class) - 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); } @@ -300,8 +300,8 @@ public void setDefaultStyleId(String styleFamily, String styleId) { String propEleName = getPropertiesElementName(); if (styleId != null) { - Element p = DOMUtils - .ensureChildElement(implementation, propEleName); + Element p = DOMUtils.ensureChildElement(implementation, + propEleName); Element ds = findDefaultStyleElement(p, styleFamily); if (ds == null) { ds = DOMUtils.createElement(p, TAG_DEFAULT_STYLE); @@ -325,7 +325,8 @@ public void setDefaultStyleId(String styleFamily, String styleId) { } } - private Element findDefaultStyleElement(Element propEle, String styleFamily) { + private Element findDefaultStyleElement(Element propEle, + String styleFamily) { Iterator it = DOMUtils.childElementIterByTag(propEle, TAG_DEFAULT_STYLE); while (it.hasNext()) { @@ -393,7 +394,8 @@ private void fireValueChange(String eventType, Object oldValue, newValue); } - private void firePropertyChange(String key, String oldValue, String newValue) { + private void firePropertyChange(String key, String oldValue, + String newValue) { getCoreEventSupport().dispatchTargetValueChange(this, Core.Property, key, oldValue, newValue); } @@ -402,4 +404,4 @@ public ICoreEventSupport getCoreEventSupport() { return ownedSheet.getCoreEventSupport(); } -} \ 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 34954d0fe..b619b3a30 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 @@ -22,7 +22,6 @@ import java.io.IOException; import java.io.OutputStream; -import java.util.Iterator; import java.util.Properties; import java.util.Set; @@ -41,10 +40,9 @@ import org.xmind.core.internal.StyleSheet; import org.xmind.core.internal.event.CoreEventSupport; import org.xmind.core.style.IStyle; -import org.xmind.core.style.IStyleSheet; +import org.xmind.core.util.CloneHandler; import org.xmind.core.util.DOMUtils; import org.xmind.core.util.IPropertiesProvider; -import org.xmind.core.util.Property; public class StyleSheetImpl extends StyleSheet implements INodeAdaptableFactory, ICoreEventSource, IPropertiesProvider { @@ -77,25 +75,25 @@ public Document getImplementation() { return implementation; } - public Object getAdapter(Class adapter) { - if (adapter == IManifest.class) - return manifest; - if (adapter == ICoreEventSource.class) - return this; - if (adapter == ElementRegistry.class) - return getElementRegistry(); - if (adapter == ICoreEventSupport.class) - return getCoreEventSupport(); - if (adapter == IPropertiesProvider.class) - return this; - if (adapter == Properties.class) - return getProperties(); - if (adapter == INodeAdaptableFactory.class) - return this; - if (adapter == INodeAdaptableProvider.class) - return getNodeAdaptableProvider(); - if (adapter == Document.class || adapter == Node.class) - 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); } @@ -274,33 +272,15 @@ public void save(OutputStream out) throws IOException, CoreException { public IStyle importStyle(IStyle style) { if (style == null) return null; - if (style instanceof StyleImpl) { - StyleImpl s = (StyleImpl) style; - return WorkbookUtilsImpl.importStyle(this, s, - (StyleSheetImpl) style.getOwnedStyleSheet()); - } - return importStyleFromOtherImpl(style); - } - private IStyle importStyleFromOtherImpl(IStyle style) { - IStyle target = createStyle(style.getType()); - Iterator sourcePropIt = style.properties(); - while (sourcePropIt.hasNext()) { - Property sourceProperty = sourcePropIt.next(); - target.setProperty(sourceProperty.key, sourceProperty.value); - } - Iterator sourceDSIt = style.defaultStyles(); - while (sourceDSIt.hasNext()) { - Property sourceDS = sourceDSIt.next(); - target.setDefaultStyleId(sourceDS.key, sourceDS.value); + try { + return (IStyle) new CloneHandler() + .withStyleSheets(style.getOwnedStyleSheet(), this) + .cloneObject(style); + } catch (IOException e) { + Core.getLogger().log(e); } - IStyleSheet sourceSheet = style.getOwnedStyleSheet(); - if (sourceSheet != null) { - String group = sourceSheet.findOwnedGroup(style); - if (group != null) - addStyle(target, group); - } - return target; + return null; } public ICoreEventRegistration registerCoreEventListener(String type, @@ -321,4 +301,4 @@ private void fireTargetChange(String type, Object target) { getCoreEventSupport().dispatchTargetChange(this, type, target); } -} \ No newline at end of file +} 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 3819a92fe..c96b09ba7 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 @@ -51,11 +51,11 @@ public Element getImplementation() { return implementation; } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Node.class || adapter == Element.class) - 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); } @@ -260,4 +260,4 @@ protected void 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 c6935b90f..e9020f44e 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 @@ -30,8 +30,8 @@ import org.xmind.core.internal.TopicExtension; import org.xmind.core.util.DOMUtils; -public class TopicExtensionImpl extends TopicExtension implements - INodeAdaptableProvider { +public class TopicExtensionImpl extends TopicExtension + implements INodeAdaptableProvider { private Element implementation; @@ -101,9 +101,9 @@ public boolean isOrphan() { return DOMUtils.isOrphanNode(implementation); } - public Object getAdapter(Class adapter) { - if (adapter == Node.class || adapter == Element.class) - return implementation; + public T getAdapter(Class adapter) { + if (adapter.isAssignableFrom(Element.class)) + return adapter.cast(implementation); return super.getAdapter(adapter); } @@ -129,9 +129,9 @@ public void addResourceRef(IResourceRef ref) { public List getResourceRefs() { Element refsEle = getRefsElement(); if (refsEle != null) - return DOMUtils.getChildList(refsEle, - DOMConstants.TAG_RESOURCE_REF, ((WorkbookImpl) topic - .getOwnedWorkbook()).getAdaptableRegistry()); + return DOMUtils.getChildList(refsEle, DOMConstants.TAG_RESOURCE_REF, + ((WorkbookImpl) topic.getOwnedWorkbook()) + .getAdaptableRegistry()); return EMPTY_REFS; } @@ -189,4 +189,4 @@ public IAdaptable getAdaptable(Node node) { return null; } -} \ No newline at end of file +} 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 775f44799..c5e6ae0cd 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 @@ -79,7 +79,6 @@ /** * @author briansun - * */ public class TopicImpl extends Topic implements ICoreEventSource { @@ -136,11 +135,11 @@ public String toString() { return "TPC#" + getId() + "(" + getTitleText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - public Object getAdapter(Class adapter) { - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Element.class || adapter == Node.class) - 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); } @@ -1152,14 +1151,24 @@ protected void addNotify(WorkbookImpl workbook, SheetImpl sheet, ((SummaryImpl) s).addNotify(workbook, this); } extensionsAddNotify(workbook); - ((CommentManagerImpl) workbook.getCommentManager()) - .objectAddNotify(getId(), this); + + 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) { - ((CommentManagerImpl) workbook.getCommentManager()) - .objectRemoveNotify(getId(), this); + 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); 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 new file mode 100644 index 000000000..c9515a37f --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionElementImpl.java @@ -0,0 +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$ + } + +} 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 new file mode 100644 index 000000000..f3a0c9153 --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionImpl.java @@ -0,0 +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$ + } + +} 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 new file mode 100644 index 000000000..3b4dea6db --- /dev/null +++ b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookExtensionManagerImpl.java @@ -0,0 +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; + } + +} 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 5dc2ed31f..b0db14360 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,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.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; @@ -56,6 +53,7 @@ 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; @@ -76,7 +74,6 @@ /** * @author briansun - * */ public class WorkbookImpl extends Workbook implements ICoreEventSource, ICoreEventSource2, INodeAdaptableFactory { @@ -105,6 +102,8 @@ public class WorkbookImpl extends Workbook private RevisionRepositoryImpl revisionRepository = null; + private WorkbookExtensionManagerImpl extensionManager; + /** * @param implementation */ @@ -114,7 +113,6 @@ public WorkbookImpl(Document implementation, IStorage storage) { } /** - * * @param implementation * @param manifest */ @@ -195,36 +193,37 @@ public String toString() { return "Workbook{" + hashCode() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ } - public Object getAdapter(Class adapter) { - if (adapter == IStorage.class) - return getStorage(); - if (adapter == IEntryStreamNormalizer.class) - return manifest.getStreamNormalizer(); - if (adapter == ICoreEventSource.class) - return this; - if (adapter == Document.class || adapter == Node.class) - return implementation; - if (adapter == Element.class) - return getWorkbookElement(); - if (adapter == IMarkerSheet.class) - return getMarkerSheet(); - if (adapter == IManifest.class) - return getManifest(); - if (adapter == ICoreEventSupport.class) - return getCoreEventSupport(); - if (adapter == INodeAdaptableFactory.class) - return this; - if (adapter == INodeAdaptableProvider.class) - return getAdaptableRegistry(); - if (adapter == IMarkerRefCounter.class) - return getMarkerRefCounter(); - if (adapter == IStyleRefCounter.class) - return getStyleRefCounter(); - if (adapter == IWorkbookComponentRefManager.class) - return getElementRefCounter(); - if (adapter == IRevisionRepository.class) - return getRevisionRepository(); - + 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); } @@ -522,7 +521,6 @@ public ICloneData clone(Collection sources) { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbook#importElement(org.xmind.core.IAdaptable) */ public IAdaptable importElement(IAdaptable source) { @@ -545,7 +543,6 @@ public IResourceRef createResourceRef(String resourceType, /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbook#findElementById(java.lang.String, * org.xmind.core.IAdaptable) */ @@ -613,7 +610,6 @@ public ICoreEventRegistration registerOnceCoreEventListener(String type, /* * (non-Javadoc) - * * @see * org.xmind.core.event.ICoreEventSource2#hasOnceListeners(java.lang.String) */ @@ -737,7 +733,6 @@ public void setTempLocation(String tempLocation) { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbook#setPassword(java.lang.String) */ @Deprecated @@ -747,7 +742,6 @@ public void setPassword(String password) { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbook#getPassword() */ @Deprecated @@ -777,7 +771,6 @@ protected void updateModificationInfo() { /* * (non-Javadoc) - * * @see org.xmind.core.IWorkbook#getCommentManager() */ public org.xmind.core.ICommentManager getCommentManager() { @@ -839,4 +832,12 @@ private void handleMarkerGroupManagement(IMarkerGroup group, } } + 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/WorkbookUtilsImpl.java b/bundles/org.xmind.core/src/org/xmind/core/internal/dom/WorkbookUtilsImpl.java index e25108fc4..185e2b93d 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 @@ -13,44 +13,17 @@ *******************************************************************************/ package org.xmind.core.internal.dom; -import static org.xmind.core.internal.dom.DOMConstants.ATTR_STYLE_ID; -import static org.xmind.core.internal.dom.DOMConstants.TAG_PROPERTIES; - import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; import org.xmind.core.Core; import org.xmind.core.ICloneData; -import org.xmind.core.IFileEntry; -import org.xmind.core.IManifest; import org.xmind.core.IWorkbook; import org.xmind.core.IWorkbookComponent; 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.IMarkerResource; -import org.xmind.core.marker.IMarkerSheet; -import org.xmind.core.style.IStyle; import org.xmind.core.style.IStyled; import org.xmind.core.util.CloneHandler; -import org.xmind.core.util.DOMUtils; -import org.xmind.core.util.FileUtils; -import org.xmind.core.util.HyperlinkUtils; -import org.xmind.core.util.Property; public class WorkbookUtilsImpl { @@ -78,216 +51,13 @@ public static ICloneData clone(IWorkbook targetWorkbook, try { handler.cloneObject(source); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Core.getLogger().log(e); } } } return result; } - private static Node clone(Document doc, Node source) { - if (source.getOwnerDocument() == doc) { - return source.cloneNode(true); - } - return doc.importNode(source, true); - } - - private static IMarker cloneMarker(WorkbookImpl targetWorkbook, - MarkerSheetImpl targetMarkerSheet, String sourceMarkerId, - IMarker sourceMarker, IMarkerSheet sourceMarkerSheet, - CloneData data) { - if (!sourceMarkerSheet.isPermanent()) { - IMarkerGroup sourceGroup = sourceMarker.getParent(); - if (sourceGroup != null) { - String sourceGroupId = sourceGroup.getId(); - String clonedGroupId = data.getString( - ICloneData.MARKERSHEET_COMPONENTS, sourceGroupId); - if (clonedGroupId == null - && !data.isCloned(ICloneData.MARKERSHEET_COMPONENTS, - sourceGroupId)) { - IMarkerGroup targetGroup = targetMarkerSheet - .getMarkerGroup(sourceGroupId); - if (targetGroup != null && targetMarkerSheet - .equals(targetGroup.getOwnedSheet())) { - data.putString(ICloneData.MARKERSHEET_COMPONENTS, - sourceGroupId, sourceGroupId); - } else { - cloneMarkerGroup(targetWorkbook, targetMarkerSheet, - sourceMarker, sourceGroup, sourceMarkerSheet, - data); - } - String clonedMarkerId = data.getString( - ICloneData.MARKERSHEET_COMPONENTS, sourceMarkerId); - if (clonedMarkerId != null) { - return targetMarkerSheet.getMarker(clonedMarkerId); - } - IMarker targetMarker = targetMarkerSheet - .getMarker(sourceMarkerId); - if (targetMarker == null) { - //TODO clone missing marker - } - } - } - } - return sourceMarker; - } - - private static void cloneMarkerGroup(WorkbookImpl targetWorkbook, - MarkerSheetImpl targetMarkerSheet, IMarker sourceMarker, - IMarkerGroup sourceGroup, IMarkerSheet sourceMarkerSheet, - CloneData data) { - MarkerGroupImpl targetGroup; - - IMarkerGroup existingGroup = targetMarkerSheet - .getMarkerGroup(sourceGroup.getId()); - if (existingGroup != null - && targetMarkerSheet.equals(existingGroup.getOwnedSheet())) { - targetGroup = (MarkerGroupImpl) existingGroup; - //TODO clone ungrouped markers - } else { - Node sourceGroupNode = (Node) sourceGroup.getAdapter(Node.class); - if (sourceGroupNode != null) { - Node clonedGroupNode = targetMarkerSheet.getImplementation() - .importNode(sourceGroupNode, true); - replaceMarkerPath(targetWorkbook, targetMarkerSheet, - clonedGroupNode, data); - MarkerGroupImpl clonedGroup = (MarkerGroupImpl) targetMarkerSheet - .getElementAdapter(clonedGroupNode); - transferMarkerResources(targetWorkbook, targetMarkerSheet, - clonedGroup, sourceGroup, sourceMarkerSheet, data); - targetGroup = clonedGroup; - } else { - targetGroup = (MarkerGroupImpl) targetMarkerSheet - .createMarkerGroup(sourceGroup.isSingleton()); - cloneMarkerGroup(targetWorkbook, targetMarkerSheet, targetGroup, - sourceGroup, sourceMarkerSheet, data); - } - } - data.putString(ICloneData.MARKERSHEET_COMPONENTS, sourceGroup.getId(), - targetGroup.getId()); - } - - private static void transferMarkerResources(WorkbookImpl targetWorkbook, - MarkerSheetImpl targetMarkerSheet, MarkerGroupImpl targetGroup, - IMarkerGroup sourceGroup, IMarkerSheet sourceMarkerSheet, - CloneData data) { - for (IMarker targetMarker : targetGroup.getMarkers()) { - String markerId = targetMarker.getId(); - IMarker sourceMarker = sourceMarkerSheet.getMarker(markerId); - if (sourceMarker != null) { - transferMarkerResource(targetWorkbook, sourceMarker, - targetMarker); - } - data.putString(ICloneData.MARKERSHEET_COMPONENTS, markerId, - markerId); - } - } - - private static void cloneMarkerGroup(WorkbookImpl targetWorkbook, - MarkerSheetImpl targetMarkerSheet, MarkerGroupImpl targetGroup, - IMarkerGroup sourceGroup, IMarkerSheet sourceMarkerSheet, - CloneData data) { - for (IMarker sourceMarker : sourceGroup.getMarkers()) { - IMarker clonedMarker; - String sourceMarkerId = sourceMarker.getId(); - IMarker existingMarker = targetMarkerSheet - .getMarker(sourceMarkerId); - if (existingMarker != null && targetMarkerSheet - .equals(existingMarker.getOwnedSheet())) { - clonedMarker = existingMarker; - } else { - clonedMarker = cloneMarker(targetWorkbook, targetMarkerSheet, - sourceMarkerSheet, sourceMarker, data); - targetGroup.addMarker(clonedMarker); - } - data.putString(ICloneData.MARKERSHEET_COMPONENTS, sourceMarkerId, - clonedMarker.getId()); - } - } - - private static IMarker cloneMarker(WorkbookImpl targetWorkbook, - MarkerSheetImpl targetMarkerSheet, IMarkerSheet sourceMarkerSheet, - IMarker sourceMarker, CloneData data) { - IMarker clonedMarker; - Node sourceMarkerNode = (Node) sourceMarker.getAdapter(Node.class); - if (sourceMarkerNode != null) { - Node clonedMarkerNode = targetMarkerSheet.getImplementation() - .importNode(sourceMarkerNode, true); - replaceMarkerPath(targetWorkbook, targetMarkerSheet, - clonedMarkerNode, data); - clonedMarker = (IMarker) targetMarkerSheet - .getElementAdapter(clonedMarkerNode); - } else { - clonedMarker = createSimilarMarker(targetWorkbook, - targetMarkerSheet, sourceMarker, sourceMarkerSheet, data); - } - transferMarkerResource(targetWorkbook, sourceMarker, clonedMarker); - return clonedMarker; - } - - private static void transferMarkerResource(WorkbookImpl targetWorkbook, - IMarker sourceMarker, IMarker targetMarker) { - IMarkerResource sourceResource = sourceMarker.getResource(); - if (sourceResource != null) { - //IMarkerResource targetResource = targetMarker.getResource(); - try { - InputStream is = sourceResource.openInputStream(); - if (is != null) { - try { - String targetPath = ArchiveConstants.PATH_MARKERS - + targetMarker.getResourcePath(); - IFileEntry entry = targetWorkbook.getManifest() - .createFileEntry(targetPath); - OutputStream out = entry.openOutputStream(); - if (out != null) { - FileUtils.transfer(is, out, true); - } - } finally { - is.close(); - } - } - } catch (IOException e) { - Core.getLogger().log(e, - "Failed to transfer marker resource from " //$NON-NLS-1$ - + sourceMarker.getResourcePath() + " to " //$NON-NLS-1$ - + targetMarker.getResourcePath()); - } - } - } - - private static void replaceMarkerPath(WorkbookImpl targetWorkbook, - MarkerSheetImpl targetMarkerSheet, Node node, CloneData data) { - if (node instanceof Element) { - Element ele = (Element) node; - if (DOMConstants.TAG_MARKER.equals(ele.getTagName())) { - String clonedPath = createNewMarkerPath( - ele.getAttribute(DOMConstants.ATTR_RESOURCE)); - ele.setAttribute(DOMConstants.ATTR_RESOURCE, clonedPath); - } - Iterator it = DOMUtils.childElementIter(ele); - while (it.hasNext()) { - replaceMarkerPath(targetWorkbook, targetMarkerSheet, it.next(), - data); - } - } - } - - private static String createNewMarkerPath(String sourcePath) { - String clonedPath = Core.getIdFactory().createId() - + FileUtils.getExtension(sourcePath); - return clonedPath; - } - - private static MarkerImpl createSimilarMarker(WorkbookImpl targetWorkbook, - MarkerSheetImpl targetMarkerSheet, IMarker sourceMarker, - IMarkerSheet sourceMarkerSheet, CloneData data) { - MarkerImpl newMarker = (MarkerImpl) targetMarkerSheet.createMarker( - createNewMarkerPath(sourceMarker.getResourcePath())); - newMarker.setName(sourceMarker.getName()); - return newMarker; - } - public static void increaseStyleRef(WorkbookImpl workbook, IStyled styled) { if (workbook == null || styled == null) return; @@ -310,269 +80,4 @@ public static void decreaseStyleRef(WorkbookImpl workbook, IStyled styled) { workbook.getStyleRefCounter().decreaseRef(styleId); } - public static IStyle importStyle(StyleSheetImpl targetSheet, - StyleImpl sourceStyle, StyleSheetImpl sourceSheet) { - return importStyle(targetSheet, sourceStyle, sourceSheet, - new CloneData(Arrays.asList(sourceStyle), null)); - } - - public static IStyle importStyle(StyleSheetImpl targetSheet, - StyleImpl sourceStyle, StyleSheetImpl sourceSheet, CloneData data) { - if (sourceSheet != null && sourceSheet.equals(targetSheet)) - return sourceStyle; - - if (sourceSheet == null) - return importNoParentStyle(targetSheet, sourceStyle); - - if (data == null) - data = new CloneData(Arrays.asList(sourceStyle), null); - StyleProperties sourceProp = getStyleProperties(sourceStyle, data); - if (sourceProp.isEmpty()) - return null; - - String sourceGroup = sourceSheet.findOwnedGroup(sourceStyle); - IStyle targetStyle = findSimilarStyle(targetSheet, sourceGroup, - sourceProp, data); - if (targetStyle != null) - return targetStyle; - - cloneStyle(targetSheet, sourceStyle, sourceSheet, data); - targetStyle = (IStyle) data.get(sourceStyle); - - if (targetStyle != null && sourceGroup != null) { - targetSheet.addStyle(targetStyle, sourceGroup); - } - - return targetStyle; - } - - private static IStyle findSimilarStyle(StyleSheetImpl targetSheet, - String group, StyleProperties sourceProp, CloneData data) { - Set styles; - if (group == null) - styles = targetSheet.getAllStyles(); - else - styles = targetSheet.getStyles(group); - for (IStyle style : styles) { - if (sourceProp.equals(getStyleProperties(style, data))) - return style; - } - return null; - } - - private static class StyleProperties { - - Map properties = new HashMap(); - - Map defaultStyles = new HashMap(); - - public StyleProperties(IStyle style, CloneData data) { - if (style == null) - return; - Iterator propIt = style.properties(); - while (propIt.hasNext()) { - Property next = propIt.next(); - properties.put(next.key, next.value); - } - Iterator dsIt = style.defaultStyles(); - while (dsIt.hasNext()) { - Property next = dsIt.next(); - String family = next.key; - IStyle ds = style.getDefaultStyleById(next.value); - StyleProperties dsProp = (StyleProperties) data.getCache(ds); - if (dsProp == null) { - dsProp = new StyleProperties(ds, data); - } - defaultStyles.put(family, dsProp); - } - data.cache(style, this); - } - - public boolean isEmpty() { - return properties.isEmpty() && defaultStyles.isEmpty(); - } - - public int hashCode() { - return properties.hashCode() ^ defaultStyles.hashCode(); - } - - public boolean equals(Object obj) { - if (obj == this) - return true; - if (obj == null || !(obj instanceof StyleProperties)) - return false; - StyleProperties that = (StyleProperties) obj; - return this.properties.equals(that.properties) - && this.defaultStyles.equals(that.defaultStyles); - } - } - - private static StyleProperties getStyleProperties(IStyle style, - CloneData data) { - StyleProperties prop = (StyleProperties) data.getCache(style); - if (prop == null) { - prop = new StyleProperties(style, data); - } - return prop; - } - - private static void cloneStyle(StyleSheetImpl targetSheet, - StyleImpl sourceStyle, StyleSheetImpl sourceSheet, CloneData data) { - Element sourceEle = sourceStyle.getImplementation(); - Node targetEle = clone(targetSheet.getImplementation(), sourceEle); - if (targetEle instanceof Element) { - IStyle sameIdStyle = targetSheet.findStyle(sourceStyle.getId()); - if (sameIdStyle != null) { - DOMUtils.replaceId((Element) targetEle); - } - replaceStyleProperties(targetSheet, (Element) targetEle, sourceEle, - sourceStyle, sourceSheet, data); - } - IStyle targetStyle = (IStyle) targetSheet.getNodeAdaptable(targetEle); - data.put(sourceStyle, targetStyle); - } - - private static void replaceStyleProperties(StyleSheetImpl targetSheet, - Element targetEle, Element sourceEle, StyleImpl sourceStyle, - StyleSheetImpl sourceSheet, CloneData data) { - String type = targetEle.getAttribute(DOMConstants.ATTR_TYPE) - .toLowerCase(); - String propTagName = type + "-" + TAG_PROPERTIES; //$NON-NLS-1$ - Iterator targetPropIt = DOMUtils - .childElementIterByTag(targetEle, propTagName); - while (targetPropIt.hasNext()) { - Element targetPropEle = targetPropIt.next(); - - NamedNodeMap attrs = targetPropEle.getAttributes(); - for (int i = 0; i < attrs.getLength(); i++) { - Node attr = attrs.item(i); -// String key = attr.getNodeName(); - String value = attr.getNodeValue(); - if (HyperlinkUtils.isAttachmentURL(value) - || HyperlinkUtils.isInternalAttachmentURL(value)) { - String newValue = cloneAttachment(value, - sourceSheet.getManifest(), - targetSheet.getManifest(), data); - attr.setNodeValue(newValue); - } - } - - Iterator targetDSIt = DOMUtils.childElementIterByTag( - targetPropEle, DOMConstants.TAG_DEFAULT_STYLE); - while (targetDSIt.hasNext()) { - Element targetDSEle = targetDSIt.next(); - String family = DOMUtils.getAttribute(targetDSEle, - DOMConstants.ATTR_STYLE_FAMILY); - if (family != null) { - String dsId = DOMUtils.getAttribute(targetDSEle, - DOMConstants.ATTR_STYLE_ID); - IStyle sourceDS = sourceStyle.getDefaultStyleById(dsId); - if (sourceDS != null) { - IStyle targetDS = importStyle(targetSheet, - (StyleImpl) sourceDS, sourceSheet, data); - if (targetDS != null) { - DOMUtils.setAttribute(targetDSEle, ATTR_STYLE_ID, - targetDS.getId()); - } - } - } - } - } - } - - private static String cloneAttachment(String sourceURL, - IManifest sourceManifest, IManifest targetManifest, - CloneData data) { - String targetURL = data.getString(ICloneData.URLS, sourceURL); - if (targetURL != null) - return targetURL; - - boolean isSystemAttachment = sourceManifest == null - && HyperlinkUtils.isInternalAttachmentURL(sourceURL); - if (targetManifest == null - || (sourceManifest == null && !isSystemAttachment)) { - return (String) cache(data, sourceURL, sourceURL); - } - - InputStream sourceInputStream = null; - - String sourcePath = null; - String sourceMadiaType = null; - - if (isSystemAttachment) { - try { - URL url = new URL(sourceURL); - sourceInputStream = url.openStream(); - sourcePath = url.getPath(); - String ext = FileUtils.getExtension(sourcePath); - sourceMadiaType = generateMediaType(ext); - } catch (MalformedURLException e1) { - } catch (IOException e1) { - } - } else { - IFileEntry sourceEntry = sourceManifest - .getFileEntry(HyperlinkUtils.toAttachmentPath(sourceURL)); - if (sourceEntry == null) - return (String) cache(data, sourceURL, sourceURL); - try { - sourceInputStream = sourceEntry.openInputStream(); - sourcePath = sourceEntry.getPath(); - } catch (IOException e) { - } - } - - String newPath = Core.getIdFactory().createId() - + FileUtils.getExtension(sourcePath); - String attachmentPath = targetManifest.makeAttachmentPath(newPath); - String mediaType = sourceMadiaType; - IFileEntry targetEntry = targetManifest.createFileEntry(attachmentPath, - mediaType); - targetEntry.increaseReference(); - - if (sourceInputStream != null) { - try { - OutputStream os = targetEntry.openOutputStream(); - try { - FileUtils.transfer(sourceInputStream, os, true); - } finally { - os.close(); - } - } catch (IOException e) { - Core.getLogger().log(e, - "Failed to clone attachment " + sourceURL); //$NON-NLS-1$ - } finally { - try { - sourceInputStream.close(); - } catch (IOException e) { - } - } - } - targetURL = HyperlinkUtils.toAttachmentURL(targetEntry.getPath()); - return (String) cache(data, sourceURL, targetURL); - } - - private static String generateMediaType(String ext) { - String mediaType = "image/png"; //$NON-NLS-1$ - if ("gif".equalsIgnoreCase(ext)) { //$NON-NLS-1$ - mediaType = "image/gif"; //$NON-NLS-1$ - } else if ("jpeg".equalsIgnoreCase(ext)) { //$NON-NLS-1$ - mediaType = "image/jpeg"; //$NON-NLS-1$ - } else if ("bmp".equalsIgnoreCase(ext)) { //$NON-NLS-1$ - mediaType = "image/bmp"; //$NON-NLS-1$ - } - return mediaType; - } - - private static Object cache(CloneData data, Object source, Object target) { - data.cache(source, target); - return target; - } - - private static IStyle importNoParentStyle(StyleSheetImpl targetSheet, - StyleImpl sourceStyle) { - Element sourceEle = sourceStyle.getImplementation(); - Node targetEle = clone(targetSheet.getImplementation(), sourceEle); - return (IStyle) targetSheet.getNodeAdaptable(targetEle); - } - -} \ 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 c411de59f..8cc7180c0 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 @@ -79,4 +79,9 @@ public class ArchiveConstants { */ 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/io/CoreIOException.java b/bundles/org.xmind.core/src/org/xmind/core/io/CoreIOException.java index 3cfded546..a6c09ffb2 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 @@ -8,14 +8,14 @@ * 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.50 + * @since 3.6.2 */ public class CoreIOException extends IOException { /** - * + * */ private static final long serialVersionUID = -5617725226498169561L; 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 796cff553..fe043c530 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 @@ -71,7 +71,6 @@ protected void loadVariations(List variations) { /* * (non-Javadoc) - * * @see org.xmind.core.marker.IMarkerResource#getInputStream() */ public InputStream getInputStream() { @@ -84,9 +83,9 @@ public InputStream getInputStream() { /* * (non-Javadoc) - * * @see org.xmind.core.marker.IMarkerResource#getOutputStream() */ + @Deprecated public OutputStream getOutputStream() { try { return openOutputStream(); @@ -116,6 +115,16 @@ public InputStream openInputStream(IMarkerVariation variation) 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(); @@ -129,4 +138,4 @@ public boolean equals(Object obj) { AbstractMarkerResource that = (AbstractMarkerResource) obj; return this.marker.equals(that.marker); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResource.java b/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResource.java index f33001ed8..b155c3a3a 100644 --- a/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResource.java +++ b/bundles/org.xmind.core/src/org/xmind/core/marker/IMarkerResource.java @@ -28,6 +28,11 @@ public interface IMarkerResource { InputStream openInputStream(IMarkerVariation variation) throws IOException; + InputStream openInputStream(int zoom) throws IOException; + + InputStream openInputStream(IMarkerVariation variation, int zoom) + throws IOException; + /** * @deprecated Use * {@link IMarkerSheet#allocateMarkerResource(InputStream, String)} @@ -72,4 +77,4 @@ OutputStream openOutputStream(IMarkerVariation variation) @Deprecated OutputStream getOutputStream(IMarkerVariation variation); -} \ 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 a1f810a85..b8f420489 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 @@ -113,6 +113,7 @@ public interface IMarkerSheet extends IAdaptable { * @throws IOException * @throws CoreException */ + @Deprecated void save(OutputStream out) throws IOException, CoreException; /** @@ -124,6 +125,7 @@ public interface IMarkerSheet extends IAdaptable { * @throws IOException * @throws CoreException */ + @Deprecated void importFrom(IInputSource source) throws IOException, CoreException; /** @@ -136,6 +138,7 @@ public interface IMarkerSheet extends IAdaptable { * @throws IOException * @throws CoreException */ + @Deprecated void importFrom(IInputSource source, String groupName) throws IOException, CoreException; @@ -148,6 +151,7 @@ void importFrom(IInputSource source, String groupName) * @throws IOException * @throws CoreException */ + @Deprecated void importFrom(String sourcePath) throws IOException, CoreException; /** @@ -157,6 +161,7 @@ void importFrom(IInputSource source, String groupName) * * @param sheet */ + @Deprecated void importFrom(IMarkerSheet sheet); /** @@ -167,6 +172,7 @@ void importFrom(IInputSource source, String groupName) * @param group * @return */ + @Deprecated IMarkerGroup importGroup(IMarkerGroup group); /** @@ -181,4 +187,4 @@ void importFrom(IInputSource source, String groupName) String allocateMarkerResource(InputStream source, String suggestedPath) throws IOException; -} \ No newline at end of file +} 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 9ab06aca5..ffe55c13a 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 @@ -96,37 +96,32 @@ public interface IStyle extends IAdaptable, IIdentifiable, IProperties, INamed { 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); -} \ 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 f00c7db9b..61ba56b71 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 @@ -16,6 +16,9 @@ */ 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; @@ -54,6 +57,9 @@ 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; @@ -204,13 +210,25 @@ public void copyWorkbookContents() throws IOException { 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) *
  • @@ -365,7 +383,7 @@ private IMarkerRef cloneMarkerRef(IMarkerRef sourceMarkerRef) IMarkerRef targetMarkerRef; IMarker sourceMarker = sourceMarkerRef.getMarker(); if (sourceMarker == null) { - targetMarkerRef = null; + targetMarkerRef = sourceMarkerRef; } else { IMarker targetMarker = findOrCloneMarker(sourceMarker); if (targetMarker == null) { @@ -596,6 +614,8 @@ private void copyTopicContents(ITopic sourceTopic, ITopic targetTopic) .setSeparator(sourceTopic.getNumbering().getSeparator()); targetTopic.getNumbering().setPrependsParentNumbers( sourceTopic.getNumbering().prependsParentNumbers()); + targetTopic.getNumbering() + .setDepth(sourceTopic.getNumbering().getDepth()); INotesContent sourcePlainContent = sourceTopic.getNotes() .getContent(INotes.PLAIN); @@ -672,8 +692,7 @@ private void fixInternalHyperlinkFor(List allTargetTopics) { private void copyHtmlNotesContent(IHtmlNotesContent sourceNotesContent, IHtmlNotesContent targetNotesContent) throws IOException { - List paragraphs = sourceNotesContent.getParagraphs(); - for (IParagraph sourceParagraph : paragraphs) { + for (IParagraph sourceParagraph : sourceNotesContent.getParagraphs()) { IParagraph targetParagraph = targetNotesContent.createParagraph(); targetParagraph .setStyleId(convertStyleId(sourceParagraph.getStyleId())); @@ -691,8 +710,9 @@ private void copySpanList(ISpanList sourceSpanList, targetSpan = spanFactory.createTextSpan( ((ITextSpan) sourceSpan).getTextContent()); } else if (sourceSpan instanceof IImageSpan) { - targetSpan = spanFactory - .createImageSpan(((IImageSpan) sourceSpan).getSource()); + String source = ((IImageSpan) sourceSpan).getSource(); + String newImageSource = convertHyperlink(source); + targetSpan = spanFactory.createImageSpan(newImageSource); } else if (sourceSpan instanceof IHyperlinkSpan) { targetSpan = spanFactory.createHyperlinkSpan( ((IHyperlinkSpan) sourceSpan).getHref()); @@ -771,10 +791,15 @@ private void copyRelationshipContents(IRelationship sourceRel, mapper.putString(ICloneData.WORKBOOK_COMPONENTS, sourceRel.getId(), targetRel.getId()); targetRel.setTitleText(sourceRel.getTitleText()); - targetRel.setEnd1Id(mapper.getString(ICloneData.WORKBOOK_COMPONENTS, - sourceRel.getEnd1Id())); - targetRel.setEnd2Id(mapper.getString(ICloneData.WORKBOOK_COMPONENTS, - sourceRel.getEnd2Id())); + + 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); @@ -791,7 +816,8 @@ private void copyControlPointContents(IRelationship sourceRel, IControlPoint targetControlPoint = targetRel.getControlPoint(index); if (sourceControlPoint.hasPosition()) { - targetControlPoint.setPosition(sourceControlPoint.getPosition()); + Point position = sourceControlPoint.getPosition(); + targetControlPoint.setPosition(new Point(position.x, position.y)); } if (sourceControlPoint.hasPolarAngle()) { targetControlPoint @@ -803,6 +829,44 @@ private void copyControlPointContents(IRelationship sourceRel, } } + 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; 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 ad4a8384c..97084e0bf 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.de.erichseifert.vectorgraphics2d;singleton:=true -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-Vendor: %providerName Export-Package: org.xmind.de.erichseifert.vectorgraphics2d, diff --git a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/pom.xml b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/pom.xml index b4f155ee5..46d455785 100644 --- a/bundles/org.xmind.de.erichseifert.vectorgraphics2d/pom.xml +++ b/bundles/org.xmind.de.erichseifert.vectorgraphics2d/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.orbit org.xmind.de.erichseifert.vectorgraphics2d - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ diff --git a/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.core.prefs index 22afb6c4b..550a73a7f 100644 --- a/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.core.prefs @@ -77,6 +77,7 @@ 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.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 @@ -90,8 +91,10 @@ 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 @@ -101,11 +104,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -159,6 +164,7 @@ 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 @@ -353,12 +359,24 @@ 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 diff --git a/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.ui.prefs index f5c471f45..0043b9a7f 100644 --- a/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.gef.ui/.settings/org.eclipse.jdt.ui.prefs @@ -2,7 +2,6 @@ eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true diff --git a/bundles/org.xmind.gef.ui/META-INF/MANIFEST.MF b/bundles/org.xmind.gef.ui/META-INF/MANIFEST.MF index f053bfc29..48bb24832 100644 --- a/bundles/org.xmind.gef.ui/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.gef.ui/META-INF/MANIFEST.MF @@ -2,14 +2,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.gef.ui;singleton:=true -Bundle-Version: 3.6.51.qualifier +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.6.0,3.7.0)";visibility:=reexport, - org.xmind.ui.toolkit;bundle-version="[3.6.0,3.7.0)" + 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, diff --git a/bundles/org.xmind.gef.ui/pom.xml b/bundles/org.xmind.gef.ui/pom.xml index c3302405d..bae503458 100644 --- a/bundles/org.xmind.gef.ui/pom.xml +++ b/bundles/org.xmind.gef.ui/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.gef.ui - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 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 a90c794af..6028466ff 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 @@ -88,4 +88,4 @@ public void setParent(IActionRegistry parent) { this.parent = parent; } -} \ 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 6bdb99f2c..741849383 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,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.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; @@ -38,7 +35,6 @@ * application should create its own subclass of Editable and * provide abilities to access actual content. *

    - * *

    Subclassing Notes

    *
      *
    • Each subclass MUST override {@link #doOpen(IProgressMonitor) @@ -54,7 +50,6 @@ * to perform additional actions while closing the document.
    • *
    * - * * @author Frank Shaka * @since 3.6.50 */ @@ -74,18 +69,17 @@ public abstract class Editable implements IEditable { private final List cleaners = new ArrayList(); - private final ListenerList listenerManager = new ListenerList(); + private final ListenerList listenerManager = new ListenerList(); private int contentRefCount = 0; - private boolean wasDirty = false; - private ICommandStackListener commandStackHook = new ICommandStackListener() { @Override public void handleCommandStackEvent(CommandStackEvent event) { if ((event.getStatus() & GEF.CS_UPDATED) != 0) { - checkDirty(); + boolean isDirty = isDirty(); + firePropertyChanged(PROP_DIRTY, false, isDirty); } doHandleCommandStackChange(event); @@ -273,29 +267,40 @@ public boolean isDirty() { @Override public void markDirtyWith(IEditableCleaner cleaner) { + boolean wasDirty = isDirty(); synchronized (this.cleaners) { this.cleaners.add(cleaner); } - checkDirty(); + 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); } - checkDirty(); + 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(); - checkDirty(); + boolean isDirty = isDirty(); + if (wasDirty != isDirty) { + firePropertyChanged(PROP_DIRTY, wasDirty, isDirty); + } } protected void doDiscardChanges() { @@ -400,7 +405,6 @@ public void open(IProgressMonitor monitor) /** * 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 @@ -460,6 +464,7 @@ public void save(IProgressMonitor monitor) subMonitor.newChild(5); addState(SAVING); try { + boolean wasDirty = isDirty(); if (subMonitor.isCanceled()) throw new InterruptedException(); clean(subMonitor.newChild(5)); @@ -470,7 +475,10 @@ public void save(IProgressMonitor monitor) markSaved(subMonitor.newChild(5)); subMonitor.newChild(4); - checkDirty(); + boolean isDirty = isDirty(); + if (wasDirty != isDirty) { + firePropertyChanged(PROP_DIRTY, wasDirty, isDirty); + } } finally { subMonitor.setWorkRemaining(1); subMonitor.newChild(1); @@ -484,7 +492,6 @@ public void save(IProgressMonitor monitor) /** * 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 @@ -520,7 +527,6 @@ protected void doSave(IProgressMonitor monitor) /** * Called after the save operation has successfully completed. Typically * used to send notifications. - * *

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

    @@ -595,7 +601,6 @@ public void close(IProgressMonitor monitor) /** * Perform actual close operations. - * *

    * This method is, by default, called from {@link #close(IProgressMonitor)} * and its default implementation from {@link Editable} does nothing, so @@ -628,7 +633,6 @@ protected void doClose(IProgressMonitor monitor) /* * (non-Javadoc) - * * @see org.xmind.gef.ui.editor.IEditable#getMessages() */ @Override @@ -638,7 +642,6 @@ public List getMessages() { /* * (non-Javadoc) - * * @see * org.xmind.gef.ui.editor.IEditable#addMessage(org.eclipse.jface.dialogs. * IMessageProvider) @@ -655,7 +658,6 @@ public void addMessage(IInteractiveMessage message) { /* * (non-Javadoc) - * * @see * org.xmind.gef.ui.editor.IEditable#removeMessage(org.eclipse.jface.dialogs * .IMessageProvider) @@ -670,15 +672,6 @@ public void removeMessage(IInteractiveMessage message) { } } - protected void checkDirty() { - boolean dirty = isDirty(); - if (dirty == wasDirty) - return; - - wasDirty = dirty; - firePropertyChanged(PROP_DIRTY, wasDirty, dirty); - } - protected void doHandleCommandStackChange(CommandStackEvent event) { /// do nothing, subclasses may override } 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 5368dc9c3..04cb480b1 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 @@ -36,6 +36,7 @@ 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; @@ -44,6 +45,8 @@ 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; @@ -259,6 +262,7 @@ protected IPageContainerPresentation createContainerPresentation() { * null. */ protected Composite createContainerParent(Composite parent) { + parent.setLayout(new FillLayout()); return parent; } @@ -621,12 +625,19 @@ protected void handlePageChange(int newPageIndex) { activePage.setFocus(); } - IEditorActionBarContributor contributor = getEditorSite() - .getActionBarContributor(); - if (contributor != null - && contributor instanceof GraphicalEditorActionBarContributor) { - ((GraphicalEditorActionBarContributor) contributor) - .setActivePage(activePage); + 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(); diff --git a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/TabFolderContainerPresentation.java b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/TabFolderContainerPresentation.java index f34ec3545..03763031b 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/TabFolderContainerPresentation.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/editor/TabFolderContainerPresentation.java @@ -21,7 +21,6 @@ import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; @@ -39,7 +38,6 @@ public void addPage(Composite container, int index, Control pageControl) { public Composite createContainer(Composite parent) { if (container != null && !container.isDisposed()) return container; - parent.setLayout(new FillLayout()); container = new CTabFolder(parent, SWT.BOTTOM | SWT.FLAT); container.setBackground(container.getDisplay().getSystemColor( SWT.COLOR_WHITE)); 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 new file mode 100644 index 000000000..9b7fc3506 --- /dev/null +++ b/bundles/org.xmind.gef.ui/src/org/xmind/gef/ui/internal/SpaceCollaborativeEngine.java @@ -0,0 +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); + } + } + } + +} 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 ffb8a9b63..68efdec7f 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,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.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; @@ -453,4 +450,4 @@ public void dispose() { super.dispose(); } -} \ No newline at end of file +} 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 82b36776c..af9d25496 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 @@ -3,6 +3,7 @@ */ 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; @@ -140,6 +141,7 @@ public boolean isPreselected() { public void setPreselected(boolean value) { Layer layer = pane.getLayer(PRESELECTED); + if (layer != null) { layer.setVisible(value); } @@ -154,6 +156,8 @@ public void setSelected(boolean value) { Layer layer = pane.getLayer(SELECTED); if (layer != null) { layer.setVisible(value); + this.setForegroundColor( + value ? ColorConstants.white : ColorConstants.black); } } @@ -191,4 +195,4 @@ public Dimension getPreferredSize(int wHint, int hHint) { return psize; } -} \ No newline at end of file +} 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 4d15caa4f..5570bdc64 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 @@ -21,6 +21,7 @@ public String getText(Object element) { } protected String getDateText(Calendar date) { - return String.format("%1$tF %1$tT", date); //$NON-NLS-1$ +// 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/DatePicker.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/DatePicker.java index 6051e851c..17d10a4e0 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 @@ -2,6 +2,8 @@ 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; @@ -11,15 +13,19 @@ 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; @@ -32,8 +38,13 @@ import org.eclipse.jface.viewers.OpenEvent; import org.eclipse.jface.viewers.SelectionChangedEvent; 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.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; @@ -44,6 +55,7 @@ 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; @@ -66,8 +78,14 @@ public class DatePicker extends Viewer { 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; @@ -88,6 +106,8 @@ public class DatePicker extends Viewer { 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; @@ -96,11 +116,15 @@ public class DatePicker extends Viewer { protected static final int TOTAL_DAYS = 42; - protected class EventHandler implements MouseListener, MouseMotionListener, - Listener { + 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) { @@ -130,9 +154,10 @@ public void handleEvent(Event event) { dayPressed = false; if (target != null) { final BaseFigure eventTarget = target; + final BaseFigure eventPreTarget = pretarget; target.setPressed(false); target = null; - selected(eventTarget); + selected(eventTarget, eventPreTarget); } } else if (event.type == SWT.MouseWheel) { if (event.count == 0) @@ -159,6 +184,107 @@ private void handleKeyPress(int key, int mask) { 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) { @@ -182,6 +308,12 @@ public void mouseEntered(MouseEvent me) { 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); } @@ -207,6 +339,12 @@ public void mouseExited(MouseEvent me) { 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); } @@ -223,13 +361,19 @@ public void mouseMoved(MouseEvent me) { public void mousePressed(MouseEvent me) { BaseFigure source = (BaseFigure) me.getSource(); - source.setPressed(true); - source.setPreselected(false); + 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) { @@ -240,17 +384,19 @@ public void mouseReleased(MouseEvent me) { daySelected((DayFigure) me.getSource()); } source.setPreselected(true); + } else if (source instanceof HourFigure + || source instanceof MinutesFigure) { + pretarget = source; } else { if (!source.isSelected()) { - source.setPreselected(true); + 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); @@ -423,12 +569,32 @@ public void updateNewDay(DayFigure figure) { } - private int style; + 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; @@ -441,6 +607,10 @@ public void updateNewDay(DayFigure figure) { private int currentYear; + private int currentHour; + + private int currentMinutes; + private Calendar selection; private IFigure dateLayer; @@ -490,7 +660,6 @@ public void updateNewDay(DayFigure figure) { * instance (cannot be null) * @param style * the style of control to construct - * * @see SWT#SIMPLE * @see SWT#DROP_DOWN * @see SWT#CANCEL @@ -503,6 +672,8 @@ 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); @@ -588,7 +759,8 @@ public void setSelection(ISelection selection, boolean reveal) { public void setDateSelection(Calendar date, boolean reveal) { changeDate(date); if (reveal && date != null) { - changeCalendar(date.get(YEAR), date.get(MONTH)); + changeCalendar(date.get(YEAR), date.get(MONTH), + date.get(HOUR_OF_DAY), date.get(MINUTE)); } update(); } @@ -605,25 +777,51 @@ public void open(OpenEvent event) { }); } + /** + * 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. @@ -632,6 +830,16 @@ 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; @@ -674,11 +882,15 @@ public void handleEvent(Event event) { 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); + GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, + false); parent.add(panel, panelConstraint); GridLayout panelLayout = new GridLayout(12, true); @@ -716,6 +928,7 @@ private YearFigure createYearFigure(IFigure parent) { return figure; } + @SuppressWarnings("deprecation") private ArrowFigure createArrowFigure(IFigure parent, int orientation) { ArrowFigure arrow = new ArrowFigure(); arrow.setOrientation(orientation); @@ -728,6 +941,7 @@ private ArrowFigure createArrowFigure(IFigure parent, int orientation) { return arrow; } + @SuppressWarnings("deprecation") private void createSeparator(IFigure parent) { HorizontalLine line = new HorizontalLine(); line.setMargin(3); @@ -737,9 +951,11 @@ private void createSeparator(IFigure parent) { 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); + GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, + false); parent.add(panel, panelConstraint); GridLayout panelLayout = new GridLayout(7, true); panelLayout.horizontalSpacing = 0; @@ -747,6 +963,7 @@ private void createWeekPanel(IFigure parent) { 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(); @@ -781,32 +998,50 @@ private void createDaysPanel(IFigure parent) { 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); + GridData panelConstraint = new GridData(SWT.FILL, SWT.FILL, true, + false); parent.add(panel, panelConstraint); - GridLayout panelLayout = new GridLayout(hasCancel ? 2 : 1, false); + + 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 = 0; - panelLayout.marginWidth = 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, -2)); - figure.setForegroundColor(ColorUtils.getColor(TODAY)); - GridData constraint = new GridData(SWT.FILL, SWT.FILL, true, true); + 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$ @@ -818,6 +1053,143 @@ private BaseFigure createCancelFigure(IFigure parent) { 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; } @@ -832,13 +1204,17 @@ private static boolean isSameDay(Calendar date1, Calendar date2) { && date1.get(YEAR) == date2.get(YEAR); } - protected void changeCalendar(int newYear, int newMonth) { - changeCalendar(newYear, newMonth, false); + protected void changeCalendar(int newYear, int newMonth, int newHour, + int newMinutes) { + changeCalendar(newYear, newMonth, newHour, newMinutes, false); } - protected void changeCalendar(int newYear, int newMonth, boolean smooth) { + //change the ui of canlendar + protected void changeCalendar(int newYear, int newMonth, int hours, + int minutes, boolean smooth) { boolean calendarChanged = newMonth != currentMonth - || newYear != currentYear; + || newYear != currentYear || currentHour != hours + || currentMinutes != minutes; if (!calendarChanged) return; if (smooth) { @@ -851,9 +1227,13 @@ protected void changeCalendar(int newYear, int newMonth, boolean smooth) { } currentYear = newYear; currentMonth = newMonth; + currentHour = hours; + currentMinutes = minutes; } else { currentYear = newYear; currentMonth = newMonth; + currentHour = hours; + currentMinutes = minutes; if (datePicker != null) { updateCalendar(); } @@ -866,8 +1246,11 @@ private void updateCalendar() { updateDayFigures(datePanel.getChildren(), currentYear, currentMonth); monthFigure.setMonth(currentMonth); yearFigure.setYear(currentYear); - todayFigure.setText(NLS.bind(Messages.TodayPattern, - String.format("%1$tb %1$te, %1$tY", today))); //$NON-NLS-1$ + 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) { @@ -880,8 +1263,10 @@ private void updateDayFigures(List dayFigures, int year, int month) { 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(); @@ -903,10 +1288,14 @@ private void updateSelection() { if (datePicker != null) { for (Object figure : datePanel.getChildren()) { DayFigure dayFigure = (DayFigure) figure; - dayFigure.setSelected(isSameDay(dayFigure.getDate(), - getSelectedDate())); + 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); @@ -981,7 +1370,8 @@ static int calc(int start, int end, int current, int total) { return start + (end - start) * current / total; } - protected void selected(final BaseFigure target) { + protected void selected(final BaseFigure target, + final BaseFigure pretarget) { if (target instanceof MonthFigure) { target.setSelected(true); showMonthPopup(); @@ -1000,6 +1390,18 @@ protected void selected(final BaseFigure target) { 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); } } @@ -1074,83 +1476,183 @@ public void menuAboutToHide(IMenuManager manager) { } protected void monthSelected(int month) { - changeCalendar(currentYear, month); + changeCalendar(currentYear, month, currentHour, currentMinutes); } protected void yearSelected(int year) { - changeCalendar(year, currentMonth); + changeCalendar(year, currentMonth, currentHour, currentMinutes); } protected 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); + 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)); + 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, smooth); + changeCalendar(currentYear - 1, 11, currentHour, currentMinutes, + smooth); } else { - changeCalendar(currentYear, currentMonth - 1, smooth); + changeCalendar(currentYear, currentMonth - 1, currentHour, + currentMinutes, smooth); } } protected void nextMonthSelected(boolean smooth) { if (currentMonth >= 11) { - changeCalendar(currentYear + 1, 0, smooth); + changeCalendar(currentYear + 1, 0, currentHour, currentMinutes, + smooth); } else { - changeCalendar(currentYear, currentMonth + 1, smooth); + changeCalendar(currentYear, currentMonth + 1, currentHour, + currentMinutes, smooth); } } protected void lastYearSelected(boolean smooth) { - changeCalendar(currentYear - 1, currentMonth, smooth); + changeCalendar(currentYear - 1, currentMonth, currentHour, + currentMinutes, smooth); } protected void nextYearSelected(boolean smooth) { - changeCalendar(currentYear + 1, currentMonth, 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), true); + 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; - if (dropdownDatePicker != null) { - control.getDisplay().asyncExec(new Runnable() { - public void run() { - dropdownDatePicker.close(); - } - }); - } - fireSelectionChanged(new SelectionChangedEvent(DatePicker.this, - getSelection())); + fireSelectionChanged( + new SelectionChangedEvent(DatePicker.this, getSelection())); firingSelectionChange = false; -// control.getDisplay().asyncExec(new Runnable() { -// public void run() { -// } -// }); } @Override @@ -1190,5 +1692,4 @@ static Calendar getCalendarStart(Calendar date, int year, int month) { } 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 ec13fb8ff..c0d983cb5 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 @@ -33,7 +33,6 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.Viewer; -import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; @@ -62,7 +61,6 @@ /** * A viewer to pick a date on the calendar. - * */ public class DatePicker2 extends Viewer { @@ -510,7 +508,6 @@ public void updateNewDay(DayFigure figure) { * instance (cannot be null) * @param style * the style of control to construct - * * @see SWT#SIMPLE * @see SWT#DROP_DOWN * @see SWT#CANCEL @@ -1039,8 +1036,9 @@ private void updateCalendar() { updateDayFigures(datePanel.getChildren(), currentYear, currentMonth); monthFigure.setMonth(currentMonth); yearFigure.setYear(currentYear); - todayFigure.setText(NLS.bind(Messages.TodayPattern, - String.format("%1$tb %1$te, %1$tY", today))); //$NON-NLS-1$ + 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) { 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 new file mode 100644 index 000000000..2fa3eeecc --- /dev/null +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/HourFigure.java @@ -0,0 +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(); + } +} 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 63bd5fc94..d976d54ed 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 @@ -50,6 +50,9 @@ public class Messages extends NLS { 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); 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 new file mode 100644 index 000000000..eb5e1d019 --- /dev/null +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/datepicker/MinutesFigure.java @@ -0,0 +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(); + } +} 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 60ef59869..bae040cff 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 @@ -17,10 +17,13 @@ Thursday=T Friday=F Saturday=S Sunday=S -TodayPattern=Today ({0}) +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 1fe9d054f..f735ddeb4 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,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.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; @@ -63,7 +60,7 @@ public class CategorizedGalleryViewer extends CategorizedViewer { private static class DelegatingLabelProvider extends BaseLabelProvider implements ILabelProvider, IColorProvider, IFontProvider, - IToolTipProvider, IGraphicalToolTipProvider { + IToolTipProvider, IGraphicalToolTipProvider, ILabelDecorator { private IBaseLabelProvider labelProvider; @@ -137,6 +134,15 @@ public IFigure getToolTipFigure(Object 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(); @@ -212,7 +218,6 @@ protected void hookControl(Control control) { protected Control createSectionContent(Composite parent, Object category) { hookSelectionClearer(parent); - Composite wrap = getWidgetFactory().createComposite(parent, SWT.WRAP); hookSelectionClearer(wrap); GridLayout wrapLayout = new GridLayout(1, false); @@ -269,10 +274,12 @@ protected GalleryViewer createNestedViewer() { return new GalleryViewer(); } - protected void configureNestedViewer(GalleryViewer viewer, Object category) { + protected void configureNestedViewer(GalleryViewer viewer, + Object category) { viewer.setProperties(properties); viewer.setContentProvider(new ArrayContentProvider()); - viewer.setLabelProvider(new DelegatingLabelProvider(getLabelProvider())); + viewer.setLabelProvider( + new DelegatingLabelProvider(getLabelProvider())); viewer.setFilters(getFilters()); viewer.setSorter(getSorter()); viewer.addSelectionChangedListener(viewerSelectionChangedListener); @@ -280,16 +287,21 @@ protected void configureNestedViewer(GalleryViewer viewer, Object category) { viewer.setEditDomain(getEditDomain()); } - protected void hookNestedViewerControl(GalleryViewer viewer, Object category) { + 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(); - hBar.setEnabled(false); - hBar.setVisible(false); + if (hBar != null) { + hBar.setEnabled(false); + hBar.setVisible(false); + } ScrollBar vBar = viewer.getCanvas().getVerticalBar(); - vBar.setEnabled(false); - vBar.setVisible(false); + if (vBar != null) { + vBar.setEnabled(false); + vBar.setVisible(false); + } } protected void reveal(Object category, final Object element) { @@ -306,10 +318,10 @@ public void run() { return; IFigure fig = ((IGraphicalPart) part).getFigure(); - Point loc = viewer.computeToDisplay(fig.getBounds() - .getLocation(), true); - loc = new Point(getContainer().toControl(loc.x, - loc.y)); + Point loc = viewer.computeToDisplay( + fig.getBounds().getLocation(), true); + loc = new Point( + getContainer().toControl(loc.x, loc.y)); reveal(loc.x, loc.y - 10); } }); @@ -333,8 +345,8 @@ protected void fillSelection(Object category, List selection) { } } - protected void setSelectionToCategory(Object category, - ISelection selection, boolean reveal) { + protected void setSelectionToCategory(Object category, ISelection selection, + boolean reveal) { GalleryViewer viewer = viewers.get(category); if (viewer != null) { setSelectionToNestedViewer(viewer, selection, reveal); @@ -388,7 +400,7 @@ public void removeFilter(ViewerFilter filter) { } } - public void setFilters(ViewerFilter[] filters) { + public void setFilters(ViewerFilter... filters) { super.setFilters(filters); for (GalleryViewer viewer : viewers.values()) { viewer.setFilters(filters); @@ -406,4 +418,4 @@ protected void doUpdateItem(Widget item, Object element, boolean fullMap) { } } -} \ No newline at end of file +} 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 02cf46dca..3129cd0b4 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 @@ -16,13 +16,150 @@ 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; @@ -31,6 +168,8 @@ public class ContentPane extends Figure { private int minorSpacing = -1; + private SpaceCollaborativeEngine spaceCollaborativeEngine = null; + /** * */ @@ -46,7 +185,7 @@ public ContentPane() { public ContentPane(boolean isHorizontal, boolean stretchMinorAxis, boolean wrap) { if (wrap) { - wrapLayout = new FlowLayout(isHorizontal); + wrapLayout = new ContentPaneFlowLayout(isHorizontal); wrapLayout.setStretchMinorAxis(stretchMinorAxis); wrapLayout.setMajorAlignment(FlowLayout.ALIGN_CENTER); wrapLayout.setMinorAlignment(FlowLayout.ALIGN_CENTER); @@ -66,7 +205,7 @@ public ContentPane(boolean isHorizontal, boolean stretchMinorAxis, } public void setLayoutManager(LayoutManager manager) { - // Do nothing to prevent external layout manager to be set. + // Do nothing to prevent external layout manager to be set. } public boolean isHorizontal() { @@ -100,14 +239,14 @@ public void setWrap(boolean wrap) { int minorAlignment = getMinorAlignment(); int majorSpacing = getMajorSpacing(); int minorSpacing = getMinorSpacing(); - wrapLayout = new FlowLayout(horizontal); + 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); + wrapLayout.setMinorAlignment( + fill ? ALIGN_CENTER : minorAlignment); } super.setLayoutManager(wrapLayout); } else { @@ -191,8 +330,25 @@ public void setMinorSpacing(int spacing) { this.minorSpacing = spacing; if (wrapLayout != null) - wrapLayout.setMinorSpacing(spacing); + ((ContentPaneFlowLayout) wrapLayout).setMinorSpacing2(spacing); revalidate(); } -} \ No newline at end of file + @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/ContentPaneDecorator.java b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ContentPaneDecorator.java index 1fc9d45b5..a7ce63743 100644 --- a/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ContentPaneDecorator.java +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/ContentPaneDecorator.java @@ -16,8 +16,10 @@ import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.MarginBorder; import org.eclipse.draw2d.Viewport; +import org.xmind.gef.IViewer; import org.xmind.gef.part.Decorator; import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.ui.internal.SpaceCollaborativeEngine; import org.xmind.gef.util.Properties; public class ContentPaneDecorator extends Decorator { @@ -29,7 +31,8 @@ public class ContentPaneDecorator extends Decorator { public void decorate(IGraphicalPart part, IFigure figure) { super.decorate(part, figure); ContentPane contentPane = (ContentPane) part.getFigure(); - Properties properties = part.getSite().getViewer().getProperties(); + IViewer viewer = part.getSite().getViewer(); + Properties properties = viewer.getProperties(); boolean horizontal = properties.getBoolean(GalleryViewer.Horizontal, false); boolean wrap = properties.getBoolean(GalleryViewer.Wrap, false); @@ -45,6 +48,13 @@ public void decorate(IGraphicalPart part, IFigure figure) { contentPane.setWrap(wrap); contentPane.setBorder(new MarginBorder(layout.getMargins())); + SpaceCollaborativeEngine sce = (SpaceCollaborativeEngine) properties + .get(GalleryViewer.ContentPaneSpaceCollaborativeEngine); + if (sce != null) { + sce.register(viewer, contentPane); + contentPane.setSpaceCollaborativeEngine(sce); + } + Viewport viewport = findViewport(contentPane); if (viewport != null) { boolean fill = layout.minorAlignment == GalleryLayout.ALIGN_FILL; @@ -66,4 +76,4 @@ protected Viewport findViewport(IFigure figure) { return findViewport(figure.getParent()); } -} \ No newline at end of file +} 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 0bf7c449e..73d7b0651 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 @@ -72,7 +72,8 @@ public void decorate(IGraphicalPart part, IFigure figure) { IGraphicalToolTipProvider toolTipProvider = (IGraphicalToolTipProvider) labelProvider; IFigure toolTipFigure = toolTipProvider.getToolTipFigure(model); frame.setToolTip(toolTipFigure); - } else if (labelProvider instanceof IToolTipProvider) { + } + if (labelProvider instanceof IToolTipProvider) { IToolTipProvider toolTipProvider = (IToolTipProvider) labelProvider; String toolTip = toolTipProvider.getToolTip(model); if (toolTip == null || "".equals(toolTip)) { //$NON-NLS-1$ @@ -92,6 +93,7 @@ public void decorate(IGraphicalPart part, IFigure figure) { layer.setBorderAlpha(0xff); layer.setBorderColor((Color) color); } + } private String getText(Object element, IBaseLabelProvider labelProvider) { @@ -117,4 +119,4 @@ protected void decorateTitle(ITextFigure titleFigure, Object model, } } -} \ No newline at end of file +} 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 a6c8051ca..c112d2d02 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 @@ -21,10 +21,12 @@ 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; @@ -60,6 +62,7 @@ public class FrameFigure extends Figure { private ShadowedLayer contentLayer; private int titlePlacement = PositionConstants.TOP; + private Layer contentCover; /** * @@ -84,7 +87,12 @@ public FrameFigure() { 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 @@ -94,11 +102,22 @@ public FrameFigure() { contentContainerLayout .setInnerMinorAlignment(AdvancedToolbarLayout.ALIGN_CENTER); contentContainer.setLayoutManager(contentContainerLayout); - add(contentContainer, FrameBorderLayout.CENTER); 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) { @@ -137,6 +156,10 @@ private void paintBackground(Graphics graphics, Color color, int alpha) { graphics.fillRectangle(b); } + public Layer getContentCover() { + return contentCover; + } + /** * @return the slide */ @@ -161,7 +184,6 @@ public void setTitleRenderStyle(int renderStyle) { } /** - * * @return one of {@link PositionConstants#TOP}, * {@link PositionConstants#BOTTOM}, {@link PositionConstants#LEFT}, * {@link PositionConstants#RIGHT} @@ -171,7 +193,6 @@ public int getTitlePlacement() { } /** - * * @param textPlacement * one of {@link PositionConstants#TOP}, * {@link PositionConstants#BOTTOM}, @@ -294,4 +315,4 @@ public void setHideTitle(boolean hideTitle) { } } -} \ No newline at end of file +} 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 3379f0349..6b529e025 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 @@ -150,6 +150,8 @@ protected void declareEditPolicies(IRequestHandler reqHandler) { NullEditPolicy.getInstance()); reqHandler.installEditPolicy(GEF.ROLE_NAVIGABLE, GalleryViewer.POLICY_NAVIGABLE); + reqHandler.installEditPolicy(GEF.ROLE_MOVABLE, + GalleryViewer.POLICY_MOVABLE); } protected void register() { @@ -228,4 +230,4 @@ public void propertyChange(PropertyChangeEvent evt) { getFigure().setTitleRenderStyle(useAdvancedRenderer ? RotatableWrapLabel.ADVANCED : RotatableWrapLabel.NORMAL); } -} \ No newline at end of file +} 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 new file mode 100644 index 000000000..ed0348bf5 --- /dev/null +++ b/bundles/org.xmind.gef.ui/src/org/xmind/ui/gallery/GalleryMovablePolicy.java @@ -0,0 +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); + +} 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 a7e57f0e1..bf7647bf8 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 @@ -118,7 +118,6 @@ public class GalleryViewer extends GraphicalViewer * 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$ @@ -137,6 +136,10 @@ public class GalleryViewer extends GraphicalViewer 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'. */ @@ -161,6 +164,7 @@ public class GalleryViewer extends GraphicalViewer 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 { @@ -386,4 +390,4 @@ public Object getProperty(String key, Object defaultValue) { return getProperties().get(key, defaultValue); } -} \ No newline at end of file +} 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 5e3a30143..3c0b2a9ed 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 @@ -98,7 +98,7 @@ public void handleEvent(Event event) { } - public static final int PREF_HEIGHT = 90; + public static final int PREF_HEIGHT = 60; public static final int BIG_HEIGHT = 70; diff --git a/bundles/org.xmind.gef/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.gef/.settings/org.eclipse.jdt.core.prefs index e88d17b48..ee0ca75e8 100644 --- a/bundles/org.xmind.gef/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.gef/.settings/org.eclipse.jdt.core.prefs @@ -77,6 +77,7 @@ 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.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 @@ -90,8 +91,10 @@ 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 @@ -101,11 +104,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -160,6 +165,7 @@ 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 @@ -355,12 +361,24 @@ 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 diff --git a/bundles/org.xmind.gef/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.gef/.settings/org.eclipse.jdt.ui.prefs index f5c471f45..0043b9a7f 100644 --- a/bundles/org.xmind.gef/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.gef/.settings/org.eclipse.jdt.ui.prefs @@ -2,7 +2,6 @@ eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true diff --git a/bundles/org.xmind.gef/META-INF/MANIFEST.MF b/bundles/org.xmind.gef/META-INF/MANIFEST.MF index e87f33661..f089ffa3b 100644 --- a/bundles/org.xmind.gef/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.gef/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.gef;singleton:=true -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Vendor: %providerName Eclipse-LazyStart: true Require-Bundle: org.eclipse.core.runtime, diff --git a/bundles/org.xmind.gef/pom.xml b/bundles/org.xmind.gef/pom.xml index 4b32508d2..2601c11c1 100644 --- a/bundles/org.xmind.gef/pom.xml +++ b/bundles/org.xmind.gef/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.gef - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 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 c84288812..882b55c1c 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/AbstractViewer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/AbstractViewer.java @@ -29,6 +29,7 @@ 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; @@ -425,6 +426,8 @@ protected int getSelectionConstraint() { private ViewerSorter sorter = null; + private ViewerComparator comparator = null; + private ISelectionSupport selectionSupport = null; private Properties properties = null; @@ -606,7 +609,6 @@ public boolean setFocus() { /* * (non-Javadoc) - * * @see org.xmind.gef.IViewer#setCursor(org.eclipse.swt.graphics.Cursor) */ public void setCursor(Cursor cursor) { @@ -649,6 +651,10 @@ public ViewerSorter getSorter() { return sorter; } + public ViewerComparator getComparator() { + return comparator; + } + public void removeFilter(ViewerFilter filter) { if (filter == null || filters == null || filters.isEmpty()) return; @@ -682,6 +688,14 @@ public void setSorter(ViewerSorter 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(); @@ -763,7 +777,6 @@ public IPart findPart(int x, int y) { /* * (non-Javadoc) - * * @seeorg.xmind.gef.IViewer#setPartSearchCondition(org.xmind.gef.IViewer. * IPartSearchCondition) */ @@ -773,7 +786,6 @@ public void setPartSearchCondition(IPartSearchCondition condition) { /* * (non-Javadoc) - * * @see org.xmind.gef.IViewer#getPartSearchCondition() */ public IPartSearchCondition getPartSearchCondition() { @@ -853,7 +865,6 @@ public void removePreSelectionChangedListener( /* * (non-Javadoc) - * * @see org.eclipse.jface.viewers.IPostSelectionProvider# * addPostSelectionChangedListener * (org.eclipse.jface.viewers.ISelectionChangedListener) @@ -865,7 +876,6 @@ public void addPostSelectionChangedListener( /* * (non-Javadoc) - * * @see org.eclipse.jface.viewers.IPostSelectionProvider# * removePostSelectionChangedListener * (org.eclipse.jface.viewers.ISelectionChangedListener) @@ -906,11 +916,11 @@ public void run() { AbstractViewer.this, selection); getListenerSupport().fireEvent(POST_SELECTION_CHANGED_KEY, new IEventDispatcher() { - public void dispatch(Object listener) { - ((ISelectionChangedListener) listener) - .selectionChanged(event); - } - }); + public void dispatch(Object listener) { + ((ISelectionChangedListener) listener) + .selectionChanged(event); + } + }); postSelectionChangedEventScheduled = false; } }); @@ -918,7 +928,6 @@ public void dispatch(Object listener) { /* * (non-Javadoc) - * * @see * org.xmind.gef.IViewer#addFocusedChangedListener(org.eclipse.jface.viewers * .ISelectionChangedListener) @@ -930,7 +939,6 @@ public void addFocusedPartChangedListener( /* * (non-Javadoc) - * * @see * org.xmind.gef.IViewer#removeFocusedChangedListener(org.eclipse.jface. * viewers.ISelectionChangedListener) @@ -1094,4 +1102,4 @@ private List getActiveServices() { return null; } -} \ 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 8cb86566d..9f3972cc0 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/GEF.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/GEF.java @@ -114,6 +114,7 @@ public class GEF { 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; 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 cd70fcc42..9f139ee67 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/GraphicalViewer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/GraphicalViewer.java @@ -104,6 +104,8 @@ public GraphicalViewer() { } 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)) @@ -163,15 +165,32 @@ public Control createControl(Composite parent) { } protected Control internalCreateControl(Composite parent, int style) { + //FIXME FigureCanvas canvas = new FigureCanvas(parent, style, - getLightweightSystem()); + 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) */ @@ -275,12 +294,11 @@ public void center(Rectangle area) { /* * (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 / 2, y - clientArea.height / 2); + scrollTo(x - clientArea.width >> 1, y - clientArea.height >> 1); } public void center(Point center) { @@ -563,7 +581,6 @@ public void setDndSupport(IDndSupport dndSupport) { /* * (non-Javadoc) - * * @see * org.xmind.gef.AbstractViewer#setCursor(org.eclipse.swt.graphics.Cursor) */ @@ -572,4 +589,4 @@ public void setCursor(Cursor cursor) { eventDispatcher.setOverridingCursor(cursor); } -} \ 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 d9001b85f..b6340517e 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/IViewer.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/IViewer.java @@ -18,6 +18,7 @@ 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; @@ -34,8 +35,8 @@ /** * @author Brian Sun */ -public interface IViewer extends IAdaptable, IInputSelectionProvider, - IPostSelectionProvider { +public interface IViewer + extends IAdaptable, IInputSelectionProvider, IPostSelectionProvider { public static interface IPartSearchCondition { @@ -73,6 +74,10 @@ public static interface IPartSearchCondition { void setSorter(ViewerSorter sorter); + ViewerComparator getComparator(); + + void setComparator(ViewerComparator comparator); + IRootPart getRootPart(); void setRootPart(IRootPart rootPart); @@ -132,4 +137,4 @@ public static interface IPartSearchCondition { boolean hasService(Class serviceType); -} \ No newline at end of file +} 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 6aaf45b57..aa082f840 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 @@ -17,8 +17,10 @@ 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; @@ -26,6 +28,7 @@ /** * @author Frank Shaka */ +@SuppressWarnings("restriction") public class PathFigure extends Shape { private static final float[] _bounds = new float[4]; @@ -105,6 +108,14 @@ protected void outlineShape(Graphics graphics) { 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; @@ -118,6 +129,13 @@ 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; @@ -167,4 +185,4 @@ public boolean hasFill() { return fill; } -} \ 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 d3bea6011..ad668cc59 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,20 +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 +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.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; @@ -26,10 +25,12 @@ 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; @@ -46,6 +47,7 @@ /** * @author Frank Shaka */ +@SuppressWarnings("restriction") public class RotatableWrapLabel extends Figure implements ITextFigure, IWrapFigure, IRotatableFigure, ITransparentableFigure { @@ -99,6 +101,7 @@ public class RotatableWrapLabel extends Figure implements ITextFigure, private PrecisionDimension nonRotatedPrefSize = null; private PrecisionInsets rotatedInsets = null; private int cachedWidthHint = -1; + private static Map textToLabelWidth = new HashMap(); private PrecisionRotator rotator = new PrecisionRotator(); @@ -109,6 +112,7 @@ public RotatableWrapLabel() { } public RotatableWrapLabel(String text) { + setCachedPrefWidth(text); setText(text); } @@ -117,6 +121,7 @@ public RotatableWrapLabel(int renderStyle) { } public RotatableWrapLabel(String text, int renderStyle) { + setCachedPrefWidth(text); setText(text); this.renderStyle = renderStyle; } @@ -346,7 +351,6 @@ protected void flushCaches() { /* * (non-Javadoc) - * * @see org.eclipse.draw2d.IFigure#getPreferredSize(int, int) */ @Override @@ -414,7 +418,6 @@ protected String getAppliedText(int wHint) { /** * @param wHint - * * @return */ protected String calculateAppliedText(double wHint) { @@ -474,14 +477,18 @@ private static String[] forceSplit(String s) { private String getAbbreviatedText(String theText, Font f, double wHint) { String result = theText; - if (wHint > 0 && result.length() > 0 - && getLooseTextSize(result, f).width > wHint) { - String remaining = result.substring(0, result.length() - 1); - result = remaining + ELLIPSE; - while (remaining.length() > 0 - && getLooseTextSize(result, f).width > wHint) { - remaining = remaining.substring(0, remaining.length() - 1); - result = remaining + ELLIPSE; + 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; @@ -496,7 +503,7 @@ && getLooseTextSize(result, f).width > wHint) { * @param f * font used to draw the text string * @param w - * width in pixles. + * width in pixels. */ protected int getLineWrapPosition(String s, Font f, double w) { // create an iterator for line breaking positions @@ -536,7 +543,7 @@ private Dimension getSubTextSize(String s, int start, int end, Font f) { return size; } - private String getShowText(String t, int textCase) { + protected String getShowText(String t, int textCase) { switch (textCase) { case GEF.MANUAL: return t; @@ -552,8 +559,10 @@ private String getShowText(String t, int textCase) { private String capitalize(String str) { StringBuffer stringbf = new StringBuffer(); - Matcher m = Pattern - .compile("([^\\s])([^\\s]*)", Pattern.CASE_INSENSITIVE) //$NON-NLS-1$ +// 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, @@ -592,6 +601,13 @@ protected Dimension getLooseTextSize(String s, Font f) { 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])); @@ -611,7 +627,6 @@ protected PrecisionRectangle getTextArea() { * Returns the area of the label's text. * * @param wHint - * * @return the area of this label's text */ protected PrecisionRectangle getTextArea(int wHint) { @@ -635,7 +650,6 @@ protected PrecisionRectangle getTextArea(int wHint) { * 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) { @@ -902,6 +916,14 @@ protected void paintText(Graphics graphics, String token, float x, float y, 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) { @@ -943,4 +965,10 @@ public String toString() { return "RotatableWrapLabl (" + getText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } -} \ No newline at end of file + private void setCachedPrefWidth(String text) { + Integer cached = textToLabelWidth.get(text); + if (cached != null) + this.prefWidth = cached; + } + +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/SizeableImageFigure.java b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/SizeableImageFigure.java index c136a1e12..7bb105750 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/SizeableImageFigure.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/draw2d/SizeableImageFigure.java @@ -260,14 +260,19 @@ protected void adaptAreaToRatio(Rectangle area, Dimension ratio, protected void paintImage(Graphics graphics, Image image, Dimension imageSize, Rectangle clientArea) { - if (clientArea.width == imageSize.width - && clientArea.height == imageSize.height) { - graphics.drawImage(image, clientArea.x, clientArea.y); - } else { - graphics.drawImage(image, 0, 0, imageSize.width, imageSize.height, - clientArea.x, clientArea.y, clientArea.width, - clientArea.height); + //TODO FIXME + try { + if (clientArea.width == imageSize.width + && clientArea.height == imageSize.height) { + graphics.drawImage(image, clientArea.x, clientArea.y); + } else { + graphics.drawImage(image, 0, 0, imageSize.width, + imageSize.height, clientArea.x, clientArea.y, + clientArea.width, clientArea.height); + } + } catch (Exception e) { + //TODO FIXME } } -} \ 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 6dc7dd200..c6770cce1 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 @@ -16,13 +16,16 @@ 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 { @@ -95,9 +98,17 @@ public Rectangle getPreferredBounds(IFigure figure) { 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()); + return PrecisionRectangle + .toDraw2DRectangle(bounds[0], bounds[1], bounds[2], bounds[3]) + .expand(getLineWidth(), getLineWidth()); } -} \ 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 465d80d98..60ad3c6a7 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 @@ -23,6 +23,7 @@ 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; /** @@ -92,12 +93,16 @@ 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) { + public void render(GC gc, Image watermark) { if (figures == null) return; @@ -114,6 +119,8 @@ public void render(GC gc) { figure.paint(graphics); graphics.restoreState(); } + + drawWatermarkImage(graphics, watermark); } finally { graphics.popState(); } @@ -124,6 +131,21 @@ public void render(GC gc) { } } + 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 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 b4729b4a3..06d2fd66e 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 @@ -114,11 +114,23 @@ protected IFigure getDefaultFigure() { */ public Rectangle getSourceArea() { if (sourceArea == null) { - sourceArea = calculateSourceArea(getContents()); + 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 diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/part/EditPart.java b/bundles/org.xmind.gef/src/org/xmind/gef/part/EditPart.java index 3d344b318..69818857b 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/part/EditPart.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/part/EditPart.java @@ -65,7 +65,6 @@ protected IAccessible getAccessible() { } /** - * * @param accessible */ protected void setAccessible(IAccessible accessible) { @@ -123,16 +122,15 @@ protected void sendRequest(Request request) { if (domain == null) return; - domain.handleRequest(request.setDomain(domain).setViewer( - getSite().getViewer())); + domain.handleRequest( + request.setDomain(domain).setViewer(getSite().getViewer())); } - @Override - public Object getAdapter(Class adapter) { + public T getAdapter(Class adapter) { if (adapter == IAccessible.class) - return getAccessible(); + return adapter.cast(getAccessible()); if (adapter == IRequestHandler.class) - return getRequestHandler(); + return adapter.cast(getRequestHandler()); return super.getAdapter(adapter); } @@ -148,4 +146,4 @@ public void handleRequest(Request request, String role) { } } -} \ No newline at end of file +} 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 b640ee03d..fb0e31567 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 @@ -29,8 +29,8 @@ /** * @author Brian Sun */ -public abstract class GraphicalEditPart extends EditPart implements - IGraphicalEditPart { +public abstract class GraphicalEditPart extends EditPart + implements IGraphicalEditPart { private IFigure figure = null; @@ -55,7 +55,6 @@ public IFigure getContentPane() { /* * (non-Javadoc) - * * @see org.xmind.gef.part.EditPart#onActivated() */ @Override @@ -132,18 +131,17 @@ protected void updateChildren() { /** * @see org.xmind.gef.part.Part#getAdapter(java.lang.Class) */ - @Override - public Object getAdapter(Class adapter) { + public T getAdapter(Class adapter) { if (adapter == IFigure.class) - return getFigure(); + return adapter.cast(getFigure()); if (adapter == IUseTransparency.class) { IFigure f = getFigure(); if (f instanceof IUseTransparency) { - return (IUseTransparency) f; + return adapter.cast(f); } } if (adapter == IDecorator.class) - return getDecorator(); + return adapter.cast(getDecorator()); return super.getAdapter(adapter); } @@ -156,7 +154,6 @@ public IPart findAt(Point position) { /* * (non-Javadoc) - * * @see * org.xmind.gef.part.IGraphicalEditPart#findAt(org.eclipse.draw2d.geometry * .Point, org.xmind.gef.IViewer.IPartSearchCondition) @@ -237,4 +234,4 @@ protected IFigure createToolTip() { public String getActionId() { return null; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.gef/src/org/xmind/gef/part/GraphicalRootEditPart.java b/bundles/org.xmind.gef/src/org/xmind/gef/part/GraphicalRootEditPart.java index e35c52521..5b826c652 100644 --- a/bundles/org.xmind.gef/src/org/xmind/gef/part/GraphicalRootEditPart.java +++ b/bundles/org.xmind.gef/src/org/xmind/gef/part/GraphicalRootEditPart.java @@ -14,21 +14,29 @@ package org.xmind.gef.part; import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.LayeredPane; +import org.eclipse.draw2d.StackLayout; import org.eclipse.draw2d.Viewport; +import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.ILayerManager; import org.xmind.gef.IViewer; /** * @author Administrator - * */ -public class GraphicalRootEditPart extends GraphicalEditPart implements - IGraphicalRootPart { +public class GraphicalRootEditPart extends GraphicalEditPart + implements IGraphicalRootPart, ILayerManager { private IViewer viewer = null; private IGraphicalEditPart contents = null; + private LayeredPane layeredPane = null; + public IPart getContents() { return contents; } @@ -46,47 +54,127 @@ public IViewer getViewer() { } public void setViewer(IViewer viewer) { + IViewer oldViewer = getViewer(); this.viewer = viewer; + viewerChanged(viewer, oldViewer); } /** - * @see org.xmind.gef.part.GraphicalEditPart#findAt(org.eclipse.draw2d.geometry.Point) + * @param newViewer + * @param oldViewer */ - @Override - public IPart findAt(Point position) { - IPart ret = super.findAt(position); - if (ret != null) - return ret; - return this; + protected void viewerChanged(IViewer newViewer, IViewer oldViewer) { + if (oldViewer instanceof IGraphicalViewer + && ((IGraphicalViewer) oldViewer).getLayerManager() == this) { + ((IGraphicalViewer) oldViewer).setLayerManager(null); + } + if (newViewer instanceof IGraphicalViewer) { + ((IGraphicalViewer) newViewer).setLayerManager(this); + } } protected IFigure createFigure() { + Viewport viewport = createViewport(); + layeredPane = createLayeredPane(); + viewport.setContents(layeredPane); + addLayers(layeredPane); + return viewport; + } + + protected Viewport createViewport() { return new Viewport(true); } -// protected IFigure createFigure(IGenre genre) { -// return genre.createRootFigure(this, (IGraphicalViewer) getViewer()); -// } + protected LayeredPane createLayeredPane() { + return new LayeredPane(); + } + + protected void addLayers(LayeredPane layeredPane) { + final Layer contentsLayer = new Layer(); + contentsLayer.setLayoutManager(new StackLayout()); + layeredPane.add(contentsLayer, GEF.LAYER_CONTENTS); + Layer presentationLayer = new Layer() { + @Override + public Dimension getPreferredSize(int wHint, int hHint) { + return contentsLayer.getPreferredSize(wHint, hHint); + } + }; + layeredPane.add(presentationLayer, GEF.LAYER_PRESENTATION); + } + + /* + * (non-Javadoc) + * @see org.xmind.ui.gantt2.gefext.GraphicalEditPart#getContentPane() + */ + @Override + public IFigure getContentPane() { + return getLayer(GEF.LAYER_CONTENTS); + } - protected void addChildView(IPart child, int index) { - if (getContentPane() instanceof Viewport) { - ((Viewport) getContentPane()).setContents(((IGraphicalPart) child) - .getFigure()); + /* + * (non-Javadoc) + * @see org.xmind.gef.ILayerManager#getLayer(java.lang.Object) + */ + public Layer getLayer(Object key) { + return layeredPane.getLayer(key); + } + + /* + * (non-Javadoc) + * @see org.xmind.gef.ILayerManager#insertLayer(java.lang.Object, + * org.eclipse.draw2d.Layer, java.lang.Object, boolean) + */ + public void insertLayer(Object key, Layer layer, Object before, + boolean scalable) { + if (before == null) { + layeredPane.add(layer, key); } else { - super.addChildView(child, index); + layeredPane.addLayerBefore(layer, key, before); } } - protected void removeChildView(IPart child) { - if (getContentPane() instanceof Viewport) { - Viewport viewport = (Viewport) getContentPane(); - IFigure childFigure = ((IGraphicalPart) child).getFigure(); - if (childFigure == viewport.getContents()) { - viewport.setContents(null); - return; - } - } - super.removeChildView(child); + /* + * (non-Javadoc) + * @see org.xmind.gef.ILayerManager#removeLayer(java.lang.Object) + */ + public void removeLayer(Object key) { + layeredPane.removeLayer(key); + } + + /** + * @see org.xmind.gef.part.GraphicalEditPart#findAt(org.eclipse.draw2d.geometry.Point) + */ + @Override + public IPart findAt(Point position) { + IPart ret = super.findAt(position); + if (ret != null) + return ret; + return this; } -} \ No newline at end of file +// protected IFigure createFigure(IGenre genre) { +// return genre.createRootFigure(this, (IGraphicalViewer) getViewer()); +// } +// +// protected void addChildView(IPart child, int index) { +// if (getContentPane() instanceof Viewport) { +// ((Viewport) getContentPane()) +// .setContents(((IGraphicalPart) child).getFigure()); +// } else { +// super.addChildView(child, index); +// } +// } +// +// protected void removeChildView(IPart child) { +// if (getContentPane() instanceof Viewport) { +// Viewport viewport = (Viewport) getContentPane(); +// IFigure childFigure = ((IGraphicalPart) child).getFigure(); +// if (childFigure == viewport.getContents()) { +// viewport.setContents(null); +// return; +// } +// } +// super.removeChildView(child); +// } + +} 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 c935afd70..f60ea8994 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 @@ -23,8 +23,8 @@ 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.eclipse.jface.viewers.ViewerSorter; import org.xmind.gef.IViewer; import org.xmind.gef.Request; import org.xmind.gef.status.IStatusListener; @@ -32,7 +32,6 @@ /** * @author Administrator - * */ public class Part implements IPart { @@ -254,7 +253,7 @@ protected IPart createChild(Object modelChild, IPartFactory factory) { protected Object[] getSortedModelChildren(IViewer viewer, Object model, Object[] modelChildren) { - ViewerSorter sorter = viewer.getSorter(); + ViewerComparator sorter = viewer.getComparator(); if (sorter != null) { sorter.sort((Viewer) viewer, modelChildren); } @@ -279,12 +278,11 @@ protected Object[] getModelChildren(Object model) { /** * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) */ - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { + public T getAdapter(Class adapter) { if (adapter == IPartSite.class) - return getSite(); + return adapter.cast(getSite()); if (adapter == IPartStatus.class) - return getStatus(); + return adapter.cast(getStatus()); if (getModel() instanceof IAdaptable) return ((IAdaptable) getModel()).getAdapter(adapter); return null; @@ -400,4 +398,4 @@ public void handleRequest(Request request, String role) { // do nothing } -} \ 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 387c26dc1..c62a09fbb 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 @@ -72,9 +72,10 @@ protected IGraphicalViewer getGraphicalViewer(Request req) { return null; } - protected void preserveCenter(final Runnable action, IGraphicalViewer viewer) { - PrecisionPoint center = viewer == null ? null : new PrecisionPoint( - viewer.getCenterPoint()); + 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()); } @@ -126,11 +127,8 @@ protected void performActualSize(final IGraphicalViewer viewer) { if (viewer == null) return; - preserveCenter(new Runnable() { - public void run() { - viewer.getZoomManager().actualSize(); - } - }, viewer); + viewer.getZoomManager().actualSize(); + viewer.center(0, 0); } /** @@ -168,11 +166,12 @@ protected void fitBounds(final IGraphicalViewer viewer, IFigure viewport = ((IGraphicalViewer) viewer).getCanvas() .getViewport(); Dimension viewportSize = getViewportSize(viewer, viewport, zoomManager); - bounds.getCenter().scale(zoomManager.getScale()); zoomManager.fitScale(viewportSize, bounds.getSize()); + bounds.getCenter().scale(zoomManager.getScale()); viewport.getUpdateManager().runWithUpdate(new Runnable() { public void run() { - viewer.center(bounds.getCopy().scale(zoomManager.getScale())); + viewer.center( + bounds.getCopy().scale(zoomManager.getScale() * 2)); } }); } @@ -230,4 +229,4 @@ protected Rectangle getSelectionBounds(IGraphicalViewer viewer, return r; } -} \ No newline at end of file +} 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 bb5a23308..ece1cfaf5 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 @@ -87,13 +87,14 @@ public void run() { double intervals = INTERVALS; if (elapsedSteps < 0) { elapsedSteps = 0; - intervals += 20; + intervals += 10; } else { - intervals += (((double) (currentTime - startTime - INTERVALS - * elapsedSteps)) / elapsedSteps); + intervals += (((double) (currentTime - startTime + - INTERVALS * elapsedSteps)) / elapsedSteps); } - int remainingSteps = (int) ((remainingTime + intervals - 1) / intervals); + int remainingSteps = (int) ((remainingTime + intervals - 1) + / intervals); if (remainingSteps <= 0) { finish(); return; @@ -118,7 +119,7 @@ public void finish() { } - private static final int INTERVALS = 30; + private static final int INTERVALS = 20; private int duration = 200; @@ -297,34 +298,39 @@ protected PrecisionPoint calcLeastTargetCenter( List toReveal, Rectangle revealBounds, double targetScale) { Rectangle clientArea = getViewerClientArea(); + revealBounds.expand(getSpacing(), getSpacing()); if (shouldReveal(revealBounds, clientArea)) { - revealBounds.expand(getSpacing(), getSpacing()); int dx = 0; int dy = 0; - int margin = 20; + 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.getCenter().x - clientArea.getCenter().x; + dx = revealBounds.x - clientArea.getCenter().x; else if (revealBounds.x < clientArea.x) - dx = revealBounds.x - clientArea.x - margin; + dx = revealBounds.x + offsetV - margin - getSpacing(); else if (revealBounds.right() > clientArea.right()) - dx = revealBounds.right() - clientArea.right() + margin; + dx = revealBounds.right() - offsetV + margin + getSpacing(); + if (revealBounds.height > clientArea.height) - dy = revealBounds.getCenter().y - clientArea.getCenter().y; + dy = revealBounds.y - clientArea.getCenter().y; else if (revealBounds.y < clientArea.y) - dy = revealBounds.y - clientArea.y - margin; + dy = revealBounds.y + offsetH - margin - getSpacing(); else if (revealBounds.bottom() > clientArea.bottom()) - dy = revealBounds.bottom() - clientArea.bottom() + margin; + dy = revealBounds.bottom() - offsetH + margin + getSpacing(); return getViewerCenterPoint(getViewerScale()).translate(dx, dy); } return null; } - protected boolean shouldReveal(Rectangle revealBounds, Rectangle clientArea) { + protected boolean shouldReveal(Rectangle revealBounds, + Rectangle clientArea) { if (isShouldRevealOnIntersection()) { return !clientArea.contains(revealBounds) && !revealBounds.contains(clientArea); } - return !revealBounds.intersects(clientArea); + return clientArea.bottom() < revealBounds.bottom() + || clientArea.getTop().y > revealBounds.y; } protected Rectangle getViewerClientArea() { @@ -356,7 +362,8 @@ protected PrecisionPoint getViewerCenterPoint(double scale) { protected List collectPartsToReveal(ISelection selection) { if (selection instanceof IStructuredSelection) { IStructuredSelection ss = (IStructuredSelection) selection; - List list = new ArrayList(ss.size()); + List list = new ArrayList( + ss.size()); for (Object o : ss.toList()) { IGraphicalPart p = getViewer().findGraphicalPart(o); if (p != null && !exclude(p)) { @@ -387,25 +394,25 @@ protected void cancelCurrentJob() { } 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()); - } - } + +// 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) { + protected void doStep(List toReveal, Rectangle revealBounds, + int remainingSteps) { double scale = getViewerScale(); PrecisionPoint center = getViewerCenterPoint(scale); double targetScale = calcTargetScale(toReveal, revealBounds); @@ -416,6 +423,7 @@ protected void doStep(List toReveal, double remainingScale = targetScale - scale; double stepScale = remainingScale / remainingSteps; scale += stepScale; + getViewer().getZoomManager().setScale(scale); } if (targetCenter != null) { @@ -425,14 +433,8 @@ protected void doStep(List toReveal, double stepY = verticalOffset / remainingSteps; center.x += stepX; center.y += stepY; - } - - if (targetScale > 0) { - getViewer().getZoomManager().setScale(scale); - } - if (targetCenter != null) { - getViewer().center( - center.getScaled(getViewerScale()).toRoundedDraw2DPoint()); + getViewer().center(targetCenter.getScaled(getViewerScale()) + .toRoundedDraw2DPoint()); } } diff --git a/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.core.prefs index 83a1840f6..3da5f0d04 100644 --- a/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.neuquant/.settings/org.eclipse.jdt.core.prefs @@ -72,6 +72,7 @@ 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.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 @@ -85,8 +86,10 @@ 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 @@ -96,11 +99,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -154,6 +159,7 @@ 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 @@ -348,12 +354,24 @@ 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 diff --git a/bundles/org.xmind.neuquant/META-INF/MANIFEST.MF b/bundles/org.xmind.neuquant/META-INF/MANIFEST.MF index d65f29414..c122e97ec 100644 --- a/bundles/org.xmind.neuquant/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.neuquant/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.neuquant -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Vendor: %providerName Bundle-RequiredExecutionEnvironment: J2SE-1.5 Require-Bundle: org.eclipse.swt diff --git a/bundles/org.xmind.neuquant/pom.xml b/bundles/org.xmind.neuquant/pom.xml index f98a12261..d39e14eec 100644 --- a/bundles/org.xmind.neuquant/pom.xml +++ b/bundles/org.xmind.neuquant/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.neuquant - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ 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 f4f86e351..7bfa95b83 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.org.freehep.vectorgraphics/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.xmind.org.freehep.vectorgraphics;singleton:=true -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.xmind.org.freehep.graphics2d, org.xmind.org.freehep.graphics2d.font, diff --git a/bundles/org.xmind.org.freehep.vectorgraphics/pom.xml b/bundles/org.xmind.org.freehep.vectorgraphics/pom.xml index 4f1e01341..0c7ff56c0 100644 --- a/bundles/org.xmind.org.freehep.vectorgraphics/pom.xml +++ b/bundles/org.xmind.org.freehep.vectorgraphics/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.orbit org.xmind.org.freehep.vectorgraphics - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ diff --git a/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.core.prefs index ef3b16ab9..dbd9a8b5f 100644 --- a/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.core.prefs @@ -77,6 +77,7 @@ 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 @@ -90,8 +91,10 @@ 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 @@ -101,11 +104,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -159,6 +164,7 @@ 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 @@ -354,12 +360,24 @@ 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 diff --git a/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.ui.prefs index 6700fc80d..7fa345e81 100644 --- a/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.ui.browser/.settings/org.eclipse.jdt.ui.prefs @@ -2,7 +2,6 @@ eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true diff --git a/bundles/org.xmind.ui.browser/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.browser/META-INF/MANIFEST.MF index 4846996e0..85a432d96 100644 --- a/bundles/org.xmind.ui.browser/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.browser/META-INF/MANIFEST.MF @@ -2,14 +2,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.ui.browser;singleton:=true -Bundle-Version: 3.6.51.qualifier +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.6.0,3.7.0)", - org.xmind.core.command;bundle-version="[3.6.0,3.7.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)" Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy Export-Package: org.xmind.ui.browser; diff --git a/bundles/org.xmind.ui.browser/icons/xmind.16.gif b/bundles/org.xmind.ui.browser/icons/xmind.16.gif deleted file mode 100644 index 8da792eeb..000000000 Binary files a/bundles/org.xmind.ui.browser/icons/xmind.16.gif and /dev/null differ diff --git a/bundles/org.xmind.ui.browser/icons/xmind.16.png b/bundles/org.xmind.ui.browser/icons/xmind.16.png new file mode 100644 index 000000000..9e3afe689 Binary files /dev/null and b/bundles/org.xmind.ui.browser/icons/xmind.16.png differ diff --git a/bundles/org.xmind.ui.browser/pom.xml b/bundles/org.xmind.ui.browser/pom.xml index 713fba787..685382216 100644 --- a/bundles/org.xmind.ui.browser/pom.xml +++ b/bundles/org.xmind.ui.browser/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.ui.browser - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ diff --git a/bundles/org.xmind.ui.browser/schema/browserViewerContributions.exsd b/bundles/org.xmind.ui.browser/schema/browserViewerContributions.exsd index 4c94ba059..c5a330937 100644 --- a/bundles/org.xmind.ui.browser/schema/browserViewerContributions.exsd +++ b/bundles/org.xmind.ui.browser/schema/browserViewerContributions.exsd @@ -13,7 +13,7 @@ - + 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 6521fb95d..574511600 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 @@ -26,7 +26,7 @@ public class BrowserImages { public static final String PATH_DISABLED = PATH_ICONS + "d/"; //$NON-NLS-1$ - public static final String XMIND = PATH_ICONS + "xmind.16.gif"; //$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$ @@ -47,8 +47,8 @@ public class BrowserImages { public static ImageDescriptor getImageDescriptor(String path) { ImageDescriptor img = cache.get(path); if (img == null) { - img = BrowserPlugin.imageDescriptorFromPlugin( - BrowserPlugin.PLUGIN_ID, path); + img = BrowserPlugin + .imageDescriptorFromPlugin(BrowserPlugin.PLUGIN_ID, path); if (img != null) cache.put(path, img); } @@ -88,4 +88,4 @@ public static ImageDescriptor[] getBusyImages() { return busyImages; } -} \ No newline at end of file +} 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 45860ae26..d0a82fcaa 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 @@ -77,6 +77,7 @@ 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 @@ -90,8 +91,10 @@ 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 @@ -101,11 +104,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -159,8 +164,10 @@ 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 @@ -353,12 +360,24 @@ 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 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 6700fc80d..7fa345e81 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 @@ -2,7 +2,6 @@ eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true diff --git a/bundles/org.xmind.ui.dashboard/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.dashboard/META-INF/MANIFEST.MF index 44d3e9311..b20cd6834 100644 --- a/bundles/org.xmind.ui.dashboard/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.dashboard/META-INF/MANIFEST.MF @@ -1,10 +1,10 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: %Bundle-Name +Bundle-Name: Dashboard Bundle-SymbolicName: org.xmind.ui.dashboard;singleton:=true -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Activator: org.xmind.ui.internal.dashboard.DashboardPlugin -Bundle-Vendor: %Bundle-Vendor +Bundle-Vendor: XMind Ltd Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime Bundle-RequiredExecutionEnvironment: JavaSE-1.6 diff --git a/bundles/org.xmind.ui.dashboard/OSGI-INF/l10n/bundle.properties b/bundles/org.xmind.ui.dashboard/OSGI-INF/l10n/bundle.properties deleted file mode 100644 index 3dd1e8f6f..000000000 --- a/bundles/org.xmind.ui.dashboard/OSGI-INF/l10n/bundle.properties +++ /dev/null @@ -1,3 +0,0 @@ -#Properties file for org.xmind.ui.dashboard -Bundle-Vendor = XMind Ltd -Bundle-Name = Dashboard \ No newline at end of file diff --git a/bundles/org.xmind.ui.dashboard/build.properties b/bundles/org.xmind.ui.dashboard/build.properties index be12fae82..6663a129e 100644 --- a/bundles/org.xmind.ui.dashboard/build.properties +++ b/bundles/org.xmind.ui.dashboard/build.properties @@ -1,6 +1,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ - .,\ - OSGI-INF/ + . source.. = src/ diff --git a/bundles/org.xmind.ui.dashboard/pom.xml b/bundles/org.xmind.ui.dashboard/pom.xml index 5a1f3afdb..4fa896a9c 100644 --- a/bundles/org.xmind.ui.dashboard/pom.xml +++ b/bundles/org.xmind.ui.dashboard/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.ui.dashboard - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ 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 834be9179..0bc13a64a 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,13 +1,9 @@ package org.xmind.ui.internal.dashboard.pages; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.ui.IEditorInput; -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ public interface IDashboardContext extends IAdaptable { /** @@ -86,17 +82,17 @@ public interface IDashboardContext extends IAdaptable { 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.exports.vector.svg/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.ui.exports.vector.svg/.settings/org.eclipse.jdt.core.prefs index 4023a33e7..a63f9374d 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 @@ -104,6 +104,7 @@ 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 @@ -117,8 +118,10 @@ 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 @@ -128,11 +131,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -186,6 +191,7 @@ 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 @@ -380,12 +386,24 @@ 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 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 1a87d36d7..431cfc813 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 @@ -2,16 +2,16 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.ui.exports.vector.svg;singleton:=true -Bundle-Version: 3.6.51.qualifier +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.6.0,3.7.0)", - org.xmind.de.erichseifert.vectorgraphics2d;bundle-version="[3.6.0,3.7.0)", - org.xmind.ui.exports.vector;bundle-version="[3.6.0,3.7.0)", - org.xmind.ui.toolkit;bundle-version="[3.6.0,3.7.0)", - org.xmind.core.usagedata;bundle-version="[3.6.50,3.7.0)" + 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 diff --git a/bundles/org.xmind.ui.exports.vector.svg/icons/exportsvg.png b/bundles/org.xmind.ui.exports.vector.svg/icons/exportsvg.png index f8157cf38..168696a34 100644 Binary files a/bundles/org.xmind.ui.exports.vector.svg/icons/exportsvg.png and b/bundles/org.xmind.ui.exports.vector.svg/icons/exportsvg.png differ diff --git a/bundles/org.xmind.ui.exports.vector.svg/icons/exportsvg@2x.png b/bundles/org.xmind.ui.exports.vector.svg/icons/exportsvg@2x.png new file mode 100644 index 000000000..1a304a6fb Binary files /dev/null and b/bundles/org.xmind.ui.exports.vector.svg/icons/exportsvg@2x.png differ diff --git a/bundles/org.xmind.ui.exports.vector.svg/plugin.properties b/bundles/org.xmind.ui.exports.vector.svg/plugin.properties index fb83e7d29..9bc3b9868 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 -exportWizard.svg.name = SVG \ No newline at end of file +exportWizard.svg.name = SVG File \ 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 65e16e0e0..d2e299e51 100644 --- a/bundles/org.xmind.ui.exports.vector.svg/pom.xml +++ b/bundles/org.xmind.ui.exports.vector.svg/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.ui.exports.vector.svg - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ 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 73433ff92..b5b6e76dc 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 @@ -33,7 +33,6 @@ import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; -import org.xmind.ui.internal.wizards.WizardMessages; import org.xmind.ui.mindmap.IMindMap; import org.xmind.ui.mindmap.IMindMapImages; import org.xmind.ui.mindmap.MindMapUI; @@ -47,247 +46,267 @@ */ 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); - } + 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 0df2775d7..65d4c0027 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 @@ -35,8 +35,8 @@ 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.MindMap; import org.xmind.ui.mindmap.MindMapExportViewer; import org.xmind.ui.viewers.ICompositeProvider; import org.xmind.ui.wizards.ExportContants; @@ -102,7 +102,8 @@ public void start(final Display display, Shell shell) public void run() { exportViewer = new MindMapExportViewer(compositeProvider, - new MindMap(sheet), viewer.getProperties()); + viewer.getAdapter(IMindMap.class), + viewer.getProperties()); Properties properties = exportViewer.getProperties(); initProperties(properties); 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 4023a33e7..a63f9374d 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 @@ -104,6 +104,7 @@ 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 @@ -117,8 +118,10 @@ 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 @@ -128,11 +131,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -186,6 +191,7 @@ 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 @@ -380,12 +386,24 @@ 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 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 4d57b38e9..8a251b600 100644 --- a/bundles/org.xmind.ui.exports.vector/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.exports.vector/META-INF/MANIFEST.MF @@ -2,12 +2,12 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.ui.exports.vector;singleton:=true -Bundle-Version: 3.6.51.qualifier +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.6.0,3.7.0)" + org.xmind.ui;bundle-version="[3.7.0,3.8.0)" Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin diff --git a/bundles/org.xmind.ui.exports.vector/pom.xml b/bundles/org.xmind.ui.exports.vector/pom.xml index 6987d1f68..363074f51 100644 --- a/bundles/org.xmind.ui.exports.vector/pom.xml +++ b/bundles/org.xmind.ui.exports.vector/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.ui.exports.vector - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ 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 ad838a406..2083c8b90 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 @@ -60,1626 +60,1656 @@ * @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; - - /** - * 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) { - swtGraphics.scale(amount); - } - - @Override - public void scale(float horizontal, float vertical) { - swtGraphics.scale(horizontal, 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) { - 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++] + transX, pathData.points[idx++] + transY); - break; - case SWT.PATH_LINE_TO: - pathAWT.lineTo(pathData.points[idx++] + transX, pathData.points[idx++] + transY); - break; - case SWT.PATH_CUBIC_TO: - pathAWT.curveTo(pathData.points[idx++] + transX, pathData.points[idx++] + transY, - pathData.points[idx++] + transX, pathData.points[idx++] + transY, - pathData.points[idx++] + transX, pathData.points[idx++] + transY); - break; - case SWT.PATH_QUAD_TO: - pathAWT.quadTo(pathData.points[idx++] + transX, pathData.points[idx++] + transY, - pathData.points[idx++] + transX, pathData.points[idx++] + 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) { - 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 - } + 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.fishbone/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.core.prefs index 1b76060de..ef8805739 100644 --- a/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.core.prefs @@ -80,6 +80,7 @@ org.eclipse.jdt.core.compiler.source=1.5 org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL,HIGH,NORMAL org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX,Release,ATTN +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 @@ -93,8 +94,10 @@ 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 @@ -104,11 +107,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -163,6 +168,7 @@ 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 @@ -358,12 +364,24 @@ 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 diff --git a/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.ui.prefs index f5c471f45..0043b9a7f 100644 --- a/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.ui.fishbone/.settings/org.eclipse.jdt.ui.prefs @@ -2,7 +2,6 @@ eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true diff --git a/bundles/org.xmind.ui.fishbone/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.fishbone/META-INF/MANIFEST.MF index ed8c01340..841db1c0d 100644 --- a/bundles/org.xmind.ui.fishbone/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.fishbone/META-INF/MANIFEST.MF @@ -2,13 +2,13 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.ui.fishbone;singleton:=true -Bundle-Version: 3.6.51.qualifier +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.6.0,3.7.0)", - org.xmind.ui.toolkit;bundle-version="[3.6.0,3.7.0)" + 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 diff --git a/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_left.png b/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_left.png index 020ed87ee..1b1e31d69 100644 Binary files a/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_left.png and b/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_left.png differ diff --git a/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_left@2x.png b/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_left@2x.png new file mode 100644 index 000000000..fb43e540e Binary files /dev/null and b/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_left@2x.png differ diff --git a/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_right.png b/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_right.png index 8f3b3e27e..8842d3ef1 100644 Binary files a/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_right.png and b/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_right.png differ diff --git a/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_right@2x.png b/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_right@2x.png new file mode 100644 index 000000000..a0f7006ba Binary files /dev/null and b/bundles/org.xmind.ui.fishbone/icons/structure_fishbone_right@2x.png differ diff --git a/bundles/org.xmind.ui.fishbone/pom.xml b/bundles/org.xmind.ui.fishbone/pom.xml index a5ca8a999..e3c8bf5e3 100644 --- a/bundles/org.xmind.ui.fishbone/pom.xml +++ b/bundles/org.xmind.ui.fishbone/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.ui.fishbone - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ diff --git a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishheadTopicDecoration.java b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishheadTopicDecoration.java index c7c18b02f..564806ca9 100644 --- a/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishheadTopicDecoration.java +++ b/bundles/org.xmind.ui.fishbone/src/org/xmind/ui/internal/fishbone/decorations/FishheadTopicDecoration.java @@ -15,7 +15,6 @@ 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.xmind.gef.draw2d.geometry.Geometry; import org.xmind.gef.draw2d.geometry.IPrecisionTransformer; @@ -115,4 +114,4 @@ private int hor(int margin, int wHint) { private int gap(int margin) { return (int) (margin * FishheadTopicDecoration.headGapScale); } -} \ 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 7f54a7bfb..e4525f65c 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 @@ -76,15 +76,13 @@ public void validate(IFigure figure) { 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)); + 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))); + 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; @@ -104,12 +102,12 @@ private PrecisionRectangle getChildrenBounds(IFigure figure) { PrecisionRectangle r = null; ITopicPart topicPart = branch.getTopicPart(); if (topicPart != null) { - r = Geometry.union(r, new PrecisionRectangle(topicPart.getFigure() - .getBounds())); + r = Geometry.union(r, + new PrecisionRectangle(topicPart.getFigure().getBounds())); } for (IBranchPart subBranch : branch.getSubBranches()) { - r = Geometry.union(r, new PrecisionRectangle(subBranch.getFigure() - .getBounds())); + r = Geometry.union(r, + new PrecisionRectangle(subBranch.getFigure().getBounds())); } if (r != null) return r; @@ -148,7 +146,7 @@ protected void performPaint(IFigure figure, Graphics graphics) { if (lineColor == null) return; - int lineWidth = topicDecoration.getLineWidth(); + int lineWidth = Math.max(1, topicDecoration.getLineWidth()); int lineStyle = topicDecoration.getLineStyle(); graphics.setAlpha(getAlpha()); @@ -158,12 +156,12 @@ protected void performPaint(IFigure figure, Graphics graphics) { 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.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, @@ -264,4 +262,4 @@ private boolean isGradient() { return GEF.IS_PLATFORM_SUPPORT_GRADIENT; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.core.prefs index cada90c0e..02582c585 100644 --- a/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.core.prefs @@ -77,6 +77,7 @@ 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.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 @@ -90,8 +91,10 @@ 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 @@ -101,11 +104,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -159,6 +164,7 @@ 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 @@ -354,12 +360,24 @@ 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 diff --git a/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.ui.prefs index 6700fc80d..7fa345e81 100644 --- a/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.ui.imports/.settings/org.eclipse.jdt.ui.prefs @@ -2,7 +2,6 @@ eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true diff --git a/bundles/org.xmind.ui.imports/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.imports/META-INF/MANIFEST.MF index 058524493..1640b6483 100644 --- a/bundles/org.xmind.ui.imports/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.imports/META-INF/MANIFEST.MF @@ -2,17 +2,19 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.ui.imports;singleton:=true -Bundle-Version: 3.6.51.qualifier +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.6.0,3.7.0)", - org.xmind.ui;bundle-version="[3.6.0,3.7.0)", - org.xmind.ui.toolkit;bundle-version="[3.6.0,3.7.0)" + 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 diff --git a/bundles/org.xmind.ui.imports/icons/import_lighten.png b/bundles/org.xmind.ui.imports/icons/import_lighten.png new file mode 100644 index 000000000..0ec9d5295 Binary files /dev/null and b/bundles/org.xmind.ui.imports/icons/import_lighten.png differ diff --git a/bundles/org.xmind.ui.imports/icons/import_lighten@2x.png b/bundles/org.xmind.ui.imports/icons/import_lighten@2x.png new file mode 100644 index 000000000..0747f85d4 Binary files /dev/null and b/bundles/org.xmind.ui.imports/icons/import_lighten@2x.png differ diff --git a/bundles/org.xmind.ui.imports/icons/import_nmind.png b/bundles/org.xmind.ui.imports/icons/import_nmind.png new file mode 100644 index 000000000..5c55df735 Binary files /dev/null and b/bundles/org.xmind.ui.imports/icons/import_nmind.png differ diff --git a/bundles/org.xmind.ui.imports/icons/import_nmind@2x.png b/bundles/org.xmind.ui.imports/icons/import_nmind@2x.png new file mode 100644 index 000000000..86a5de9b8 Binary files /dev/null and b/bundles/org.xmind.ui.imports/icons/import_nmind@2x.png differ diff --git a/bundles/org.xmind.ui.imports/icons/importfreemind.gif b/bundles/org.xmind.ui.imports/icons/importfreemind.gif deleted file mode 100644 index 58f8c410e..000000000 Binary files a/bundles/org.xmind.ui.imports/icons/importfreemind.gif and /dev/null differ diff --git a/bundles/org.xmind.ui.imports/icons/importfreemind.png b/bundles/org.xmind.ui.imports/icons/importfreemind.png new file mode 100644 index 000000000..93ae1eab8 Binary files /dev/null and b/bundles/org.xmind.ui.imports/icons/importfreemind.png differ diff --git a/bundles/org.xmind.ui.imports/icons/importfreemind@2x.png b/bundles/org.xmind.ui.imports/icons/importfreemind@2x.png new file mode 100644 index 000000000..641f9eb73 Binary files /dev/null and b/bundles/org.xmind.ui.imports/icons/importfreemind@2x.png differ diff --git a/bundles/org.xmind.ui.imports/icons/importmm.gif b/bundles/org.xmind.ui.imports/icons/importmm.gif deleted file mode 100644 index c7c0bdfb5..000000000 Binary files a/bundles/org.xmind.ui.imports/icons/importmm.gif and /dev/null differ diff --git a/bundles/org.xmind.ui.imports/icons/importmm.png b/bundles/org.xmind.ui.imports/icons/importmm.png new file mode 100644 index 000000000..9e50f6ebe Binary files /dev/null and b/bundles/org.xmind.ui.imports/icons/importmm.png differ diff --git a/bundles/org.xmind.ui.imports/icons/importmm@2x.png b/bundles/org.xmind.ui.imports/icons/importmm@2x.png new file mode 100644 index 000000000..77aae2ad3 Binary files /dev/null and b/bundles/org.xmind.ui.imports/icons/importmm@2x.png differ diff --git a/bundles/org.xmind.ui.imports/icons/importopml.png b/bundles/org.xmind.ui.imports/icons/importopml.png new file mode 100644 index 000000000..f1dbcf283 Binary files /dev/null and b/bundles/org.xmind.ui.imports/icons/importopml.png differ diff --git a/bundles/org.xmind.ui.imports/icons/importopml@2x.png b/bundles/org.xmind.ui.imports/icons/importopml@2x.png new file mode 100644 index 000000000..7c67d107f Binary files /dev/null and b/bundles/org.xmind.ui.imports/icons/importopml@2x.png differ diff --git a/bundles/org.xmind.ui.imports/plugin.properties b/bundles/org.xmind.ui.imports/plugin.properties index 76607e027..b4c35afb3 100644 --- a/bundles/org.xmind.ui.imports/plugin.properties +++ b/bundles/org.xmind.ui.imports/plugin.properties @@ -1,6 +1,9 @@ #Properties file for org.xmind.ui.imports providerName = XMind Ltd. pluginName = XMind Import Supports -importWizard.mindmanager.name = Mindjet MindManager +importWizard.mindmanager.name = Mindjet Mindmanager importWizard.freemind.name = FreeMind -importWizard.workbook.name = XMind Workbook \ No newline at end of file +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 e27514906..d0e30d48e 100644 --- a/bundles/org.xmind.ui.imports/plugin.xml +++ b/bundles/org.xmind.ui.imports/plugin.xml @@ -6,17 +6,38 @@ + + + + + + + + + - @@ -2095,13 +2098,17 @@ visible="true"> + name="org.xmind.ui.commandParameter.modelPart.partId" + value="org.xmind.ui.modelPart.markers"> + + @@ -2119,7 +2126,7 @@ name="group.additions" visible="false"> - + --> @@ -2138,6 +2146,19 @@ label="%toolbar.mindmap.insert.hyperlink.label" style="push"> + + + + @@ -2190,11 +2211,11 @@ point="org.eclipse.ui.menus"> + locationURI="popup:org.xmind.ui.MindMapEditor.page?before=new.ext"> @@ -2203,9 +2224,9 @@ locationURI="popup:org.xmind.ui.MindMapEditor.page?after=additions"> + label="%menu.cloorfulSheet.label"> diff --git a/bundles/org.xmind.ui.menus/pom.xml b/bundles/org.xmind.ui.menus/pom.xml index 2e2ee0f96..10fe4d372 100644 --- a/bundles/org.xmind.ui.menus/pom.xml +++ b/bundles/org.xmind.ui.menus/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.ui.menus - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ diff --git a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.core.prefs b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.core.prefs index f5a86c6af..da1448200 100644 --- a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.core.prefs +++ b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.core.prefs @@ -80,6 +80,7 @@ org.eclipse.jdt.core.compiler.source=1.6 org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL,HIGH,NORMAL org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX,Release,ATTN +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 @@ -93,8 +94,10 @@ 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 @@ -104,11 +107,13 @@ org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration 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=1 +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 @@ -162,6 +167,7 @@ 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 @@ -356,12 +362,24 @@ 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 diff --git a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.ui.prefs index 6700fc80d..7fa345e81 100644 --- a/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.ui.prefs +++ b/bundles/org.xmind.ui.mindmap/.settings/org.eclipse.jdt.ui.prefs @@ -2,7 +2,6 @@ eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_XMind Code Formatter formatter_settings_version=12 -org.eclipse.jdt.ui.text.custom_code_templates= sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=true diff --git a/bundles/org.xmind.ui.mindmap/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.mindmap/META-INF/MANIFEST.MF index 164ac5022..39e741697 100644 --- a/bundles/org.xmind.ui.mindmap/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.mindmap/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.ui.mindmap;singleton:=true -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.xmind.ui.internal.MindMapUIPlugin Bundle-Vendor: %providerName @@ -18,13 +18,13 @@ Export-Package: org.xmind.ui, 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.colorful;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, @@ -36,14 +36,17 @@ Export-Package: org.xmind.ui, 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", @@ -60,22 +63,22 @@ Require-Bundle: org.eclipse.ui, org.eclipse.core.filesystem, org.eclipse.core.resources, org.apache.commons.codec, - org.xmind.core.runtime;bundle-version="[3.6.0,3.7.0)";visibility:=reexport, - org.xmind.gef.ui;bundle-version="[3.6.0,3.7.0)";visibility:=reexport, - org.xmind.ui.toolkit;bundle-version="[3.6.0,3.7.0)", - org.xmind.ui.browser;bundle-version="[3.6.0,3.7.0)", - org.xmind.ui.spelling;bundle-version="[3.6.0,3.7.0)", - org.xmind.core.command;bundle-version="[3.6.0,3.7.0)", + 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.eclipse.e4.ui.services, - org.eclipse.e4.core.di.annotations, - org.xmind.core.usagedata;bundle-version="[3.6.50,3.7.0)", + org.xmind.core.usagedata;bundle-version="[3.7.0,3.8.0)", org.xmind.core, - org.eclipse.e4.ui.workbench, - org.eclipse.e4.ui.model.workbench, - org.eclipse.e4.core.contexts -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 + 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 -Import-Package: javax.inject;version="1.0.0" Eclipse-LazyStart: true +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Service-Component: OSGI-INF/serviceManager.xml diff --git a/bundles/org.xmind.ui.mindmap/build.properties b/bundles/org.xmind.ui.mindmap/build.properties index e70ac91ea..4d79ac106 100644 --- a/bundles/org.xmind.ui.mindmap/build.properties +++ b/bundles/org.xmind.ui.mindmap/build.properties @@ -1,9 +1,11 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ + icons/,\ plugin.xml,\ plugin.properties,\ about.html,\ + parts_fragment.e4xmi,\ OSGI-INF/ src.includes = about.html source.. = src/ diff --git a/bundles/org.xmind.ui.mindmap/icons/assignee.gif b/bundles/org.xmind.ui.mindmap/icons/assignee.gif new file mode 100644 index 000000000..ac375b736 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/assignee.gif differ diff --git a/bundles/org.xmind.ui.mindmap/icons/emotion_angry@16.svg b/bundles/org.xmind.ui.mindmap/icons/emotion_angry@16.svg new file mode 100644 index 000000000..f793e1169 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/icons/emotion_angry@16.svg @@ -0,0 +1,30 @@ + + + + Oval 43 Copy 16 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/icons/export_ppt@3x.png b/bundles/org.xmind.ui.mindmap/icons/export_ppt@3x.png new file mode 100644 index 000000000..379b17ad6 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/export_ppt@3x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/export_ps@3x.png b/bundles/org.xmind.ui.mindmap/icons/export_ps@3x.png new file mode 100644 index 000000000..7a5f78993 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/export_ps@3x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/export_word@3x.png b/bundles/org.xmind.ui.mindmap/icons/export_word@3x.png new file mode 100644 index 000000000..ab2c74598 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/export_word@3x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/export_xls@3x.png b/bundles/org.xmind.ui.mindmap/icons/export_xls@3x.png new file mode 100644 index 000000000..e1ed480c9 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/export_xls@3x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/export_xmind@3x.png b/bundles/org.xmind.ui.mindmap/icons/export_xmind@3x.png new file mode 100644 index 000000000..cef2b93e3 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/export_xmind@3x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/hide_overview.png b/bundles/org.xmind.ui.mindmap/icons/hide_overview.png new file mode 100644 index 000000000..f3e5e9951 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/hide_overview.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/hide_overview@2x.png b/bundles/org.xmind.ui.mindmap/icons/hide_overview@2x.png new file mode 100644 index 000000000..45e250459 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/hide_overview@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/ic_clip_art.png b/bundles/org.xmind.ui.mindmap/icons/ic_clip_art.png new file mode 100644 index 000000000..ef0138631 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/ic_clip_art.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/ic_clip_art@2x.png b/bundles/org.xmind.ui.mindmap/icons/ic_clip_art@2x.png new file mode 100644 index 000000000..0bc6f0b5d Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/ic_clip_art@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/ic_marker.png b/bundles/org.xmind.ui.mindmap/icons/ic_marker.png new file mode 100644 index 000000000..31971087c Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/ic_marker.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/ic_marker@2x.png b/bundles/org.xmind.ui.mindmap/icons/ic_marker@2x.png new file mode 100644 index 000000000..1b1eb7160 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/ic_marker@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/ic_style.png b/bundles/org.xmind.ui.mindmap/icons/ic_style.png new file mode 100644 index 000000000..15c6e6700 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/ic_style.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/ic_style@2x.png b/bundles/org.xmind.ui.mindmap/icons/ic_style@2x.png new file mode 100644 index 000000000..37a00408a Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/ic_style@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/ic_template.png b/bundles/org.xmind.ui.mindmap/icons/ic_template.png new file mode 100644 index 000000000..7aaeac0f7 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/ic_template.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/ic_template@2x.png b/bundles/org.xmind.ui.mindmap/icons/ic_template@2x.png new file mode 100644 index 000000000..8e7719632 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/ic_template@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/ic_theme.png b/bundles/org.xmind.ui.mindmap/icons/ic_theme.png new file mode 100644 index 000000000..2bc54f31d Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/ic_theme.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/ic_theme@2x.png b/bundles/org.xmind.ui.mindmap/icons/ic_theme@2x.png new file mode 100644 index 000000000..951b8026c Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/ic_theme@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/index.png b/bundles/org.xmind.ui.mindmap/icons/index.png new file mode 100644 index 000000000..7bc119fe9 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/index.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/marker.png b/bundles/org.xmind.ui.mindmap/icons/marker.png new file mode 100644 index 000000000..e17367041 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/marker.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/marker@2x.png b/bundles/org.xmind.ui.mindmap/icons/marker@2x.png new file mode 100644 index 000000000..9399100ad Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/marker@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/sheet.gif b/bundles/org.xmind.ui.mindmap/icons/sheet.gif new file mode 100644 index 000000000..5c5624259 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/sheet.gif differ diff --git a/bundles/org.xmind.ui.mindmap/icons/show_overview.png b/bundles/org.xmind.ui.mindmap/icons/show_overview.png new file mode 100644 index 000000000..a0ba85139 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/show_overview.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/show_overview@2x.png b/bundles/org.xmind.ui.mindmap/icons/show_overview@2x.png new file mode 100644 index 000000000..1f29c2820 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/show_overview@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/style.png b/bundles/org.xmind.ui.mindmap/icons/style.png new file mode 100644 index 000000000..b55687492 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/style.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/style@2x.png b/bundles/org.xmind.ui.mindmap/icons/style@2x.png new file mode 100644 index 000000000..da90aa11c Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/style@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/template.png b/bundles/org.xmind.ui.mindmap/icons/template.png new file mode 100644 index 000000000..7be296c20 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/template.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/template@2x.png b/bundles/org.xmind.ui.mindmap/icons/template@2x.png new file mode 100644 index 000000000..06c83ad2c Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/template@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/theme.png b/bundles/org.xmind.ui.mindmap/icons/theme.png new file mode 100644 index 000000000..e198dea73 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/theme.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/theme@2x.png b/bundles/org.xmind.ui.mindmap/icons/theme@2x.png new file mode 100644 index 000000000..26e7541e1 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/theme@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/title.png b/bundles/org.xmind.ui.mindmap/icons/title.png new file mode 100644 index 000000000..085561f17 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/title.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/title@2x.png b/bundles/org.xmind.ui.mindmap/icons/title@2x.png new file mode 100644 index 000000000..5d77ce941 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/title@2x.png differ diff --git a/bundles/org.xmind.ui.mindmap/icons/workbook.gif b/bundles/org.xmind.ui.mindmap/icons/workbook.gif new file mode 100644 index 000000000..64c19a3c2 Binary files /dev/null and b/bundles/org.xmind.ui.mindmap/icons/workbook.gif differ diff --git a/bundles/org.xmind.ui.mindmap/parts_fragment.e4xmi b/bundles/org.xmind.ui.mindmap/parts_fragment.e4xmi new file mode 100644 index 000000000..cef262973 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/parts_fragment.e4xmi @@ -0,0 +1,66 @@ + + + + + + DialogPart + + + + + DialogPart + + + + + + DialogPart + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.xmind.ui.mindmap/plugin.properties b/bundles/org.xmind.ui.mindmap/plugin.properties index d554cec24..69f70e4c7 100644 --- a/bundles/org.xmind.ui.mindmap/plugin.properties +++ b/bundles/org.xmind.ui.mindmap/plugin.properties @@ -1,3 +1,75 @@ #Properties file for org.xmind.ui.mindmap providerName = XMind Ltd. -pluginName = XMind MindMap UI \ No newline at end of file +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 20a7224dc..14d68098e 100644 --- a/bundles/org.xmind.ui.mindmap/plugin.xml +++ b/bundles/org.xmind.ui.mindmap/plugin.xml @@ -1,6 +1,13 @@ + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + +
    diff --git a/bundles/org.xmind.ui.mindmap/pom.xml b/bundles/org.xmind.ui.mindmap/pom.xml index b6a93357a..0d6d74727 100644 --- a/bundles/org.xmind.ui.mindmap/pom.xml +++ b/bundles/org.xmind.ui.mindmap/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.ui.mindmap - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ 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 a0e3f17b4..334911688 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 @@ -797,4 +797,4 @@ public IWorkbenchAction create(IWorkbenchWindow window) { return action; } }; -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddSheetCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddSheetCommand.java index b9de6ec39..18ed8686a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddSheetCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/AddSheetCommand.java @@ -30,7 +30,8 @@ public AddSheetCommand(ISheet sourceSheet, IWorkbook targetParent) { this(sourceSheet, targetParent, -1); } - public AddSheetCommand(ISheet sourceSheet, IWorkbook targetParent, int index) { + public AddSheetCommand(ISheet sourceSheet, IWorkbook targetParent, + int index) { super(targetParent); this.sourceSheet = sourceSheet; this.index = index; @@ -50,4 +51,4 @@ public void undo() { super.undo(); } -} \ 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 6c2db9227..69d86215d 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 @@ -17,6 +17,7 @@ import org.xmind.core.IBoundary; import org.xmind.core.IWorkbook; import org.xmind.gef.command.CreateCommand; +import org.xmind.ui.internal.MindMapUIPlugin; public class CreateBoundaryCommand extends CreateCommand { @@ -41,4 +42,11 @@ protected Object create() { return boundary; } -} \ No newline at end of file + @Override + public void execute() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("InsertBoundaryCount"); //$NON-NLS-1$ + super.execute(); + } + +} 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 320957481..0f611b6cd 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 @@ -17,6 +17,7 @@ import org.xmind.core.ISummary; import org.xmind.core.IWorkbook; import org.xmind.gef.command.CreateCommand; +import org.xmind.ui.internal.MindMapUIPlugin; public class CreateSummaryCommand extends CreateCommand { @@ -41,4 +42,10 @@ protected Object create() { return summary; } -} \ No newline at end of file + @Override + public void execute() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("InsertSummaryCount"); //$NON-NLS-1$ + super.execute(); + } +} 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 e65406ad6..742e6333b 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 @@ -18,6 +18,7 @@ import org.xmind.core.ILegend; import org.xmind.gef.ISourceProvider; import org.xmind.gef.command.ModifyCommand; +import org.xmind.ui.internal.MindMapUIPlugin; public class ModifyLegendVisibilityCommand extends ModifyCommand { @@ -52,4 +53,11 @@ protected void setValue(Object source, Object value) { } } -} \ No newline at end of file + @Override + public void execute() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ShowLegendCount"); //$NON-NLS-1$ + super.execute(); + } + +} 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 new file mode 100644 index 000000000..57bd6bc4b --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifyNumberingDepthCommand.java @@ -0,0 +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); + } + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/colorful/ModifySheetTabColorCommand.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifySheetTabColorCommand.java similarity index 94% rename from bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/colorful/ModifySheetTabColorCommand.java rename to bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifySheetTabColorCommand.java index efe8f2eda..60a193e71 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/colorful/ModifySheetTabColorCommand.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/commands/ModifySheetTabColorCommand.java @@ -1,4 +1,4 @@ -package org.xmind.ui.internal.colorful; +package org.xmind.ui.commands; import java.util.List; 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 9887e5c3b..8aa4fee51 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 @@ -22,6 +22,7 @@ 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 { @@ -32,7 +33,8 @@ public class ModifyTopicStructureCommand extends ModifyCommand { private Map extToRightNum = new HashMap(); - public ModifyTopicStructureCommand(ITopic source, String newStructureClass) { + public ModifyTopicStructureCommand(ITopic source, + String newStructureClass) { super(source, newStructureClass); ITopicExtension topicExtension = source .getExtension(EXTENTION_UNBALANCEDSTRUCTURE); @@ -95,9 +97,18 @@ protected void setValue(Object source, Object value) { .setTextContent(rightNum); } } + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("StructureTypeCount:" + value); //$NON-NLS-1$ topic.setStructureClass((String) value); } } } -} \ No newline at end of file + @Override + public void execute() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ModifyStructureCount"); //$NON-NLS-1$ + super.execute(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractArrowDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractArrowDecoration.java index 4584ca2b7..0128aaee2 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractArrowDecoration.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/decorations/AbstractArrowDecoration.java @@ -16,14 +16,17 @@ 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.SWT; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.internal.DPIUtil; import org.eclipse.swt.widgets.Display; import org.xmind.gef.draw2d.decoration.AbstractDecoration; import org.xmind.gef.draw2d.geometry.PrecisionPoint; import org.xmind.gef.draw2d.geometry.PrecisionRectangle; import org.xmind.gef.draw2d.graphics.Path; +@SuppressWarnings("restriction") public abstract class AbstractArrowDecoration extends AbstractDecoration implements IArrowDecoration { @@ -98,9 +101,18 @@ public Rectangle getPreferredBounds(IFigure figure) { Path shape = new Path(Display.getCurrent()); sketch(figure, shape); 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]; + } + shape.dispose(); - return PrecisionRectangle.toDraw2DRectangle(RECT[0], RECT[1], - RECT[2], RECT[3]).expand(getWidth(), getWidth()); + return PrecisionRectangle + .toDraw2DRectangle(RECT[0], RECT[1], RECT[2], RECT[3]) + .expand(getWidth(), getWidth()); } return new PrecisionRectangle(getPosition(), getPosition()) .toDraw2DRectangle(); @@ -153,4 +165,4 @@ public void setWidth(IFigure figure, int 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 f90dfc443..0398f647f 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 @@ -301,6 +301,7 @@ protected void paintPath(IFigure figure, Graphics graphics, Path path, } finally { graphics.popState(); shape.close(); + shape.dispose(); } return; } @@ -315,4 +316,4 @@ private TopicFigure getTopicFigure(IFigure parent) { return null; } -} \ No newline at end of file +} 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 new file mode 100644 index 000000000..71b9e7a1a --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/EditorHistoryItem.java @@ -0,0 +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$ + } + +} 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 a106c2a1a..a5c723fbf 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 @@ -6,14 +6,12 @@ /** * 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. @@ -103,7 +101,6 @@ interface IEditorHistoryListener { * 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 @@ -115,6 +112,10 @@ interface IEditorHistoryListener { */ 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. @@ -149,7 +150,6 @@ interface IEditorHistoryListener { * 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. *

    @@ -216,4 +216,4 @@ void saveThumbnailData(URI inputURI, InputStream thumbnailData) */ void addEditorHistoryListener(IEditorHistoryListener listener); -} \ No newline at end of file +} 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 new file mode 100644 index 000000000..f883cd95b --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/editor/IEditorHistoryItem.java @@ -0,0 +1,11 @@ +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/internal/CategoryManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/CategoryManager.java index 784677fdc..d23f41017 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 @@ -50,7 +50,8 @@ protected static class Category { // name = ""; //$NON-NLS-1$ // } - Category(String id, String objectClass, String elementType, String name) { + Category(String id, String objectClass, String elementType, + String name) { this.id = id; this.objectClass = objectClass; this.name = name; @@ -72,9 +73,9 @@ public String getObjectClazz() { public boolean belongsToThisCategory(Object o) { boolean belongs = Expressions.isInstanceOf(o, objectClass); if (belongs && o instanceof ITopic) { - belongs = belongs - && (((ITopic) o).getType().equals(elementType) || DEFAULT_TYPE - .equals(elementType)); + belongs = belongs && (((ITopic) o).getType() != null) + && (((ITopic) o).getType().equals(elementType) + || DEFAULT_TYPE.equals(elementType)); } return belongs; } @@ -89,7 +90,7 @@ public String getName() { private String[] categoryIds = null; - /* package */CategoryManager() { + /* package */ CategoryManager() { } // public String getElementType(Object element) { @@ -134,11 +135,11 @@ private void lazyLoad() { 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", Category.DEFAULT_TYPE, //$NON-NLS-1$ + 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", Category.DEFAULT_TYPE, //$NON-NLS-1$ + 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$ @@ -149,8 +150,8 @@ private void lazyLoad() { 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", Category.DEFAULT_TYPE, //$NON-NLS-1$ + 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, @@ -215,4 +216,4 @@ private Category getCategory(String categoryId) { return null; } -} \ No newline at end of file +} 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 a7417858d..32f0cdf26 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 @@ -8,7 +8,6 @@ import org.xmind.ui.mindmap.IWorkbookRef; /** - * * @author Frank Shaka * @since 3.6.50 */ diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/colorful/ColorfulSheetMenu.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ColorfulSheetMenu.java similarity index 96% rename from bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/colorful/ColorfulSheetMenu.java rename to bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ColorfulSheetMenu.java index 83dcf3ec7..5a92783eb 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/colorful/ColorfulSheetMenu.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/ColorfulSheetMenu.java @@ -11,7 +11,7 @@ * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ -package org.xmind.ui.internal.colorful; +package org.xmind.ui.internal; import java.util.ArrayList; import java.util.Arrays; @@ -27,7 +27,6 @@ import org.eclipse.ui.menus.IWorkbenchContribution; import org.eclipse.ui.services.IServiceLocator; import org.xmind.ui.commands.MindMapCommandConstants; -import org.xmind.ui.internal.MindMapMessages; import org.xmind.ui.mindmap.MindMapUI; public class ColorfulSheetMenu extends CompoundContributionItem 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 new file mode 100644 index 000000000..a52f2d381 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/EmptyControlContribution.java @@ -0,0 +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; + } + +} 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 9579274a5..a05d1e86e 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 @@ -77,7 +77,6 @@ public ImageDescriptor get(String fileName, boolean enabled) { /* * (non-Javadoc) - * * @see * org.xmind.ui.mindmap.IMindMapImages#getTopicIcon(org.xmind.core.ITopic, * boolean) @@ -105,7 +104,6 @@ public ImageDescriptor getTopicIcon(ITopic topic, boolean enabled) { /* * (non-Javadoc) - * * @see org.xmind.ui.mindmap.IMindMapImages#getElementIcon(java.lang.Object) */ public ImageDescriptor getElementIcon(Object element, boolean enabled) { @@ -199,7 +197,9 @@ private ImageDescriptor createFileIcon(String fileExtension, ImageData data = p.getImageData(); if (data != null) { if (Util.isMac()) - return ImageDescriptor.createFromImageData(data); + return ImageUtils.scaleImage(Display.getCurrent(), + ImageDescriptor.createFromImageData(data), 16, 16); + //fix bug: icon has black shadow in Windows. String tempPath = getTempFileIconPath(); @@ -224,4 +224,4 @@ private String getTempFileIconPath() { return tempFile; } -} \ No newline at end of file +} 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 c7a1db861..575708e8c 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 @@ -163,13 +163,13 @@ public class MindMapMessages extends NLS { public static String DeleteStyleHandler_DeleteStytles; public static String DeleteStyleHandler_DeleteStytlesConfirm; - public static String DeleteStyleHandler_MessageDialog_description; + public static String DeleteStyle_MessageDialog_description; - public static String DeleteStyleHandler_MessageDialog_styles; + public static String DeleteStyle_MessageDialog_styles; - public static String DeleteStyleHandler_MessageDialog_themes; + public static String DeleteStyle_MessageDialog_themes; - public static String DeleteStyleHandler_MessageDialog_title; + public static String DeleteStyles_MessageDialog_title; public static String Delete_OtherSheets_text; public static String Delete_OtherSheets_toolTip; @@ -237,7 +237,6 @@ public class MindMapMessages extends NLS { 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; @@ -267,6 +266,7 @@ public class MindMapMessages extends NLS { 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; @@ -349,7 +349,6 @@ public class MindMapMessages extends NLS { 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; @@ -430,6 +429,10 @@ public class MindMapMessages extends NLS { 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; @@ -498,6 +501,10 @@ public class MindMapMessages extends NLS { 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; @@ -608,10 +615,10 @@ public class MindMapMessages extends NLS { public static String DuplicateSheet_text; public static String DuplicateSheet_toolTip; public static String CopySheet_text; - public static String PasswordProvider_askPassword_message; - public static String PasteSheet_text; + public static String PasswordProvider_askPassword_message; + public static String RemoveAllStyles_text; public static String RemoveAllStyles_tooltip; @@ -652,6 +659,115 @@ public class MindMapMessages extends NLS { 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); @@ -659,4 +775,4 @@ public class MindMapMessages extends NLS { private MindMapMessages() { } -} \ No newline at end of file +} 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 ae9117895..697f605db 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 @@ -13,6 +13,7 @@ *******************************************************************************/ package org.xmind.ui.internal; +import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -31,6 +32,7 @@ import java.util.List; import java.util.Properties; +import javax.imageio.ImageIO; import javax.xml.parsers.DocumentBuilderFactory; import org.eclipse.core.runtime.Assert; @@ -86,6 +88,7 @@ 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; @@ -102,6 +105,8 @@ public class MindMapResourceManager implements IResourceManager { 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$ @@ -112,17 +117,16 @@ public class MindMapResourceManager implements IResourceManager { private static final String DEFAULT_STYLES_XML = "defaultStyles.xml"; //$NON-NLS-1$ - private static final String STYLES_XML = "styles.xml"; //$NON-NLS-1$ - - private static final String THEMES_XML = "themes.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$ @@ -148,11 +152,27 @@ public SystemMarkerResource(IMarker marker) { } public InputStream getInputStream() { - return getInputStreamForPath(getFullPath()); + return getInputStreamForPath(getFullPath(), 100); } - private InputStream getInputStreamForPath(String fullPath) { - URL url = find(fullPath); + @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; @@ -163,6 +183,17 @@ private InputStream getInputStreamForPath(String fullPath) { 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; } @@ -196,15 +227,15 @@ protected void loadVariations(List variations) { @Override public InputStream getInputStream(IMarkerVariation variation) { - return getInputStreamForPath( - variation.getVariedPath(getFullPath())); + return getInputStreamForPath(variation.getVariedPath(getFullPath()), + 100); } @Override public InputStream openInputStream(IMarkerVariation variation) throws IOException { InputStream stream = getInputStreamForPath( - variation.getVariedPath(getFullPath())); + variation.getVariedPath(getFullPath()), 100); if (stream == null) throw new FileNotFoundException(); return stream; @@ -244,7 +275,6 @@ public boolean isPermanent() { /* * (non-Javadoc) - * * @see org.xmind.core.marker.IMarkerResourceAllocator# * allocateMarkerResourcePath(java.io.InputStream, java.lang.String) */ @@ -270,13 +300,34 @@ public String allocateMarkerResource(InputStream source, 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() { - return FileUtils.ensureFileParent(new File( + 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() { @@ -355,7 +406,6 @@ public List getMarkers() { /* * (non-Javadoc) - * * @see org.xmind.core.marker.IMarkerGroup#isEmpty() */ @Override @@ -449,7 +499,6 @@ public ICoreEventSupport getCoreEventSupport() { /* * (non-Javadoc) - * * @see org.xmind.ui.internal.IMarkerSheetManager#getSystemMarkerSheet() */ public IMarkerSheet getSystemMarkerSheet() { @@ -477,7 +526,6 @@ private IMarkerSheet createSystemMarkerShet() { /* * (non-Javadoc) - * * @see org.xmind.ui.internal.IMarkerSheetManager#getUserMarkerSheet() */ public IMarkerSheet getUserMarkerSheet() { @@ -569,7 +617,7 @@ public IStyleSheet getSystemStyleSheet() { } private IStyleSheet createSystemStyleSheet() { - URL url = find(PATH_STYLES, STYLES_XML); + URL url = find(PATH_STYLES, STYLES, EXT_XML); if (url != null) { try { IStyleSheet sheet = Core.getStyleSheetBuilder() @@ -673,7 +721,8 @@ public IStyleSheet getSystemThemeSheet() { } private IStyleSheet createSystemThemeSheet() { - URL url = find(PATH_STYLES, THEMES_XML); +// URL url = find(PATH_STYLES, THEMES_XML); + URL url = find(PATH_STYLES_DIR, THEMES, EXT_XML); if (url != null) { try { IStyleSheet sheet = Core.getStyleSheetBuilder() @@ -822,7 +871,6 @@ private static void loadPropertiesFor(IAdaptable resourceManager, /* * (non-Javadoc) - * * @see org.xmind.ui.mindmap.IResourceManager#findResource(java.lang.String) */ public Object findResource(String uri) { @@ -911,7 +959,6 @@ private IStyleSheet findThemeSheet(String category) { /* * (non-Javadoc) - * * @see * org.xmind.ui.mindmap.IResourceManager#toResourceURI(java.lang.Object) */ @@ -977,13 +1024,67 @@ public String toResourceURI(Object resource) { return null; } - @Override 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) @@ -1005,9 +1106,13 @@ private void loadSystemTemplates(List templates) { if (element == null) return; - java.util.Properties properties = getTemplateListProperties(bundle); 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$ @@ -1030,7 +1135,8 @@ private void loadSystemTemplates(List templates) { } if (!resourceURI.isAbsolute()) { - BundleResource templateResource = new BundleResource(bundle, + BundleResource templateResource = new BundleResource( + Platform.getBundle(MindMapUI.PLUGIN_ID), new Path(SYS_TEMPLATES_DIR + resource)).resolve(); try { resourceURI = templateResource.toPlatformURL().toURI(); @@ -1043,13 +1149,7 @@ private void loadSystemTemplates(List templates) { } 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(resource); } @@ -1059,7 +1159,7 @@ private void loadSystemTemplates(List templates) { private Properties getTemplateListProperties(Bundle bundle) { URL propURL = ResourceFinder.findResource(bundle, SYS_TEMPLATES_DIR, - "templates", ".properties"); //$NON-NLS-1$ //$NON-NLS-2$ + "templates", EXT_PROPERTIES); //$NON-NLS-1$ if (propURL == null) { MindMapUIPlugin.getDefault().getLog().log(new Status( IStatus.WARNING, MindMapUIPlugin.PLUGIN_ID, @@ -1219,7 +1319,7 @@ public void run(IProgressMonitor monitor) try { if (PlatformUI.isWorkbenchRunning()) { - PlatformUI.getWorkbench().getProgressService().run(true, true, + PlatformUI.getWorkbench().getProgressService().run(false, true, runnable); } else { runnable.run(new NullProgressMonitor()); @@ -1229,8 +1329,8 @@ public void run(IProgressMonitor monitor) return null; } - ITemplate template = new ClonedTemplate(templateURI, - userTemplateFile.getName()); + ITemplate template = new ClonedTemplate(templateURI, FileUtils + .getNoExtensionFileName(userTemplateFile.getAbsolutePath())); fireUserTemplateAdded(template); return template; } @@ -1315,7 +1415,15 @@ public boolean isUserTemplate(ITemplate template) { @Override public boolean isSystemTemplate(ITemplate template) { // TODO check source workbook URI to determine system template - return getSystemTemplates().contains(template); + boolean isSysTemplate = getSystemTemplates().contains(template); + + List systemTemplateGroups = getSystemTemplateGroups(); + for (ITemplateGroup group : systemTemplateGroups) { + if (group.getTemplates().contains(template)) + return true; + } + + return isSysTemplate; } -} \ No newline at end of file +} 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 da8f1ce11..7e8e44a63 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 @@ -18,8 +18,10 @@ 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; @@ -74,7 +76,6 @@ public MindMapUIPlugin() { /* * (non-Javadoc) - * * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework. * BundleContext ) */ @@ -91,7 +92,6 @@ public void start(BundleContext context) throws Exception { /* * (non-Javadoc) - * * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework. * BundleContext ) */ @@ -122,6 +122,19 @@ public void stop(BundleContext context) throws Exception { 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( @@ -262,4 +275,4 @@ void setServiceManager(ServiceManager serviceManager) { this.serviceManager = serviceManager; } -} \ No newline at end of file +} 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 7317076d5..5d9e51ac0 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 @@ -17,7 +17,9 @@ 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; @@ -25,7 +27,8 @@ import org.eclipse.jface.util.SafeRunnable; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.osgi.util.NLS; -import org.eclipse.ui.IViewPart; +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; @@ -43,13 +46,14 @@ 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 { @@ -57,6 +61,8 @@ private class TopicWordContext implements IWordContext { private ITopic topic; + private static final String TYPE = "topic"; //$NON-NLS-1$ + public TopicWordContext(ITopic topic) { this.topic = topic; } @@ -74,26 +80,43 @@ public String getName() { } public boolean replaceWord(int start, int length, String replacement) { - return replaceText( - topic, - replaceString(topic.getTitleText(), start, length, - replacement)); + return replaceText(topic, replaceString(topic.getTitleText(), start, + length, replacement)); } public void reveal() { - revealElement(topic); + 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; @@ -113,15 +136,13 @@ public String getName() { } public boolean replaceWord(int start, int length, String replacement) { - return replaceText( - topic, + return replaceText(topic, replaceString(MindMapUtils.getLabelText(topic.getLabels()), start, length, replacement), MindMapUI.REQ_MODIFY_LABEL); } public void reveal() { - editor.getSite().getPage().activate(editor); editor.getSite().getSelectionProvider() .setSelection(new StructuredSelection(topic)); } @@ -129,12 +150,31 @@ public void reveal() { 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; @@ -159,23 +199,30 @@ public String getName() { public boolean replaceWord(int start, int length, String replacement) { revealWord(start, length); - IViewPart view = editor.getSite().getPage() - .findView(MindMapUI.VIEW_NOTES); - if (view != null) { - ITextViewer viewer = (ITextViewer) view - .getAdapter(ITextViewer.class); - if (viewer != null) { - String toFind = viewer.getTextWidget().getText(start, - start + length - 1); - - IFindReplaceTarget target = (IFindReplaceTarget) view - .getAdapter(IFindReplaceTarget.class); - if (target != null) { - int r = target.findAndSelect(start, toFind, true, true, - false); - if (r > -1) { - target.replaceSelection(replacement); - return true; + + 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; + } } } } @@ -184,27 +231,57 @@ public boolean replaceWord(int start, int length, String replacement) { } public void reveal() { - revealElement(topic); + revealElement(topic, false); SafeRunner.run(new SafeRunnable() { public void run() throws Exception { - editor.getSite().getPage().showView(MindMapUI.VIEW_NOTES); + 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(); - IViewPart view = editor.getSite().getPage() - .findView(MindMapUI.VIEW_NOTES); - if (view != null) { - ITextViewer viewer = (ITextViewer) view - .getAdapter(ITextViewer.class); - if (viewer != null) { - viewer.setSelectedRange(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) { + 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 { @@ -228,20 +305,32 @@ public String getName() { } public boolean replaceWord(int start, int length, String replacement) { - return replaceText( - boundary, - replaceString(boundary.getTitleText(), start, length, - replacement)); + return replaceText(boundary, replaceString(boundary.getTitleText(), + start, length, replacement)); } public void reveal() { - revealElement(boundary); + 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 { @@ -265,20 +354,32 @@ public String getName() { } public boolean replaceWord(int start, int length, String replacement) { - return replaceText( - relationship, - replaceString(relationship.getTitleText(), start, length, - replacement)); + return replaceText(relationship, replaceString( + relationship.getTitleText(), start, length, replacement)); } public void reveal() { - revealElement(relationship); + 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; @@ -292,7 +393,6 @@ public MindMapWordContextProvider(IGraphicalEditor editor) { /* * (non-Javadoc) - * * @see org.xmind.ui.IWordContextProvider#getWordContexts() */ public List getWordContexts() { @@ -325,10 +425,6 @@ private void getContexts(ITopic topic, List contexts) { } } - private void revealElement(Object element) { - revealElement(element, true); - } - private void revealElement(Object element, boolean makeActive) { if (makeActive) { editor.getSite().getPage().activate(editor); @@ -346,10 +442,8 @@ private void revealInvalidWord(ISheetComponent element, int start, EditDomain domain = page.getEditDomain(); IPart part = viewer.findPart(element); if (part != null) { - Request request = new Request(reqType) - .setPrimaryTarget(part) - .setDomain(domain) - .setViewer(viewer) + 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)); @@ -386,4 +480,19 @@ private static String replaceString(String text, int start, int length, 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/NumberFormatExtensionManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/NumberFormatExtensionManager.java index db5fb0808..81977fe9e 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 @@ -13,11 +13,19 @@ *******************************************************************************/ 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; @@ -31,11 +39,11 @@ import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.util.Logger; -public class NumberFormatExtensionManager extends RegistryReader implements - INumberFormatManager { +public class NumberFormatExtensionManager extends RegistryReader + implements INumberFormatManager { - private static class NumberFormatProxy implements INumberFormat, - INumberFormatDescriptor { + private static class NumberFormatProxy + implements INumberFormat, INumberFormatDescriptor { private IConfigurationElement element; @@ -57,8 +65,8 @@ public NumberFormatProxy(IConfigurationElement element) this.description = element .getAttribute(RegistryConstants.ATT_DESCRIPTION); if (getClassValue(element, RegistryConstants.ATT_CLASS) == null) - throw new CoreException(new Status(IStatus.ERROR, element - .getNamespaceIdentifier(), 0, + throw new CoreException(new Status(IStatus.ERROR, + element.getNamespaceIdentifier(), 0, "Invalid extension (missing class name): " + id, //$NON-NLS-1$ null)); } @@ -67,11 +75,13 @@ private INumberFormat getImplementation() { if (implementation == null && !failedInitImplementation) { try { implementation = (INumberFormat) element - .createExecutableExtension(RegistryConstants.ATT_CLASS); + .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)); + Logger.log(e, + "Failed to create number format from class: " //$NON-NLS-1$ + + getClassValue(element, + RegistryConstants.ATT_CLASS)); failedInitImplementation = true; } } @@ -99,11 +109,19 @@ public String getDescription() { } + 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; - /* package */NumberFormatExtensionManager() { + private Properties configIniProperties; + + /* package */ NumberFormatExtensionManager() { } protected boolean readElement(IConfigurationElement element) { @@ -123,6 +141,18 @@ private void readFormat(IConfigurationElement element) { 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); @@ -168,4 +198,37 @@ public String getNumberText(String formatId, int 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/SeparatorControlContribution.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/SeparatorControlContribution.java new file mode 100644 index 000000000..da423279e --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/SeparatorControlContribution.java @@ -0,0 +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; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TemplateGroup.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TemplateGroup.java new file mode 100644 index 000000000..ca241ae8b --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/TemplateGroup.java @@ -0,0 +1,42 @@ +package org.xmind.ui.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.xmind.ui.mindmap.ITemplate; +import org.xmind.ui.mindmap.ITemplateGroup; + +public class TemplateGroup implements ITemplateGroup { + + private String name; + + private List templates; + + public TemplateGroup(String name) { + this.name = name; + } + + public TemplateGroup(String name, List templates) { + this(name); + this.templates = templates; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getTemplates() { + if (templates == null) + templates = new ArrayList(); + return templates; + } + + public void setTemplates(List templates) { + this.templates = templates; + } + +} 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 new file mode 100644 index 000000000..297a5afaa --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowManualLayoutAction.java @@ -0,0 +1,24 @@ +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(); + } + +} 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 new file mode 100644 index 000000000..9b4ff25cf --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/AllowManualLayoutMenu.java @@ -0,0 +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); + } +} 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 ac64921f8..ab6645c3b 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 @@ -15,6 +15,7 @@ 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 { @@ -26,4 +27,11 @@ public AllowOverlapsAction(IPreferenceStore prefStore) { setToolTipText(MindMapMessages.AllowOverlaps_toolTip); } -} \ No newline at end of file + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("AllowOverlapCount"); //$NON-NLS-1$ + 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 de77efa04..7b1990d1f 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 @@ -7,13 +7,20 @@ 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 { -public class AllowOverlapsMenu extends ContributionItem implements - IWorkbenchContribution { private boolean dirty = true; + IWorkbenchWindow window; private IMenuListener menuListener = new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { @@ -59,10 +66,27 @@ private void fillMenu(MenuManager manager) { .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/CollapseAllAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/CollapseAllAction.java index 3e5d4d7b1..2c880f812 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 @@ -13,15 +13,22 @@ *******************************************************************************/ 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 class CollapseAllAction extends RequestAction + implements ISelectionAction { public CollapseAllAction(IGraphicalEditorPage page) { super(MindMapActionFactory.COLLAPSE_ALL.getId(), page, @@ -29,5 +36,37 @@ public CollapseAllAction(IGraphicalEditorPage page) { } 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); } -} \ No newline at end of file + +} 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 85450895c..a33c20688 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 @@ -16,6 +16,7 @@ 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 CreateRelationshipAction extends RequestAction { @@ -25,4 +26,11 @@ public CreateRelationshipAction(IGraphicalEditorPage page) { MindMapUI.REQ_CREATE_RELATIONSHIP); } -} \ No newline at end of file + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("InsertRelationshipCount"); //$NON-NLS-1$ + 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 4c01ad1b9..dca3d9669 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 @@ -24,6 +24,7 @@ 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; @@ -42,6 +43,9 @@ public void run() { editor = getEditor(); if (editor != null) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("CreateSheetCount`"); //$NON-NLS-1$ + IWorkbook workbook = (IWorkbook) editor.getAdapter(IWorkbook.class); if (workbook == null) { @@ -71,15 +75,15 @@ protected void saveAndRunCreateSheetCommand(IWorkbook workbook) { } protected void decorateCreatedSheet(ISheet sheet) { - sheet.setTitleText(NLS.bind(MindMapMessages.TitleText_Sheet, sheet - .getParent().getSheets().size())); + sheet.setTitleText(NLS.bind(MindMapMessages.TitleText_Sheet, + sheet.getParent().getSheets().size())); - sheet.getRootTopic().setTitleText( - MindMapMessages.TitleText_CentralTopic); + 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); } -} \ 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 b964cc14c..148809394 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 @@ -26,6 +26,7 @@ public CutAction(IGraphicalEditorPage page) { protected boolean canDelete(ISelection selection) { return !MindMapUtils.hasSuchElements(selection, - MindMapUI.CATEGORY_SHEET); + MindMapUI.CATEGORY_SHEET) + && !MindMapUtils.hasCentralTopic(selection, getViewer()); } -} \ 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 2394f8739..ef900e8a3 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 @@ -18,6 +18,7 @@ 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; @@ -33,4 +34,11 @@ public void setSelection(ISelection selection) { && !MindMapUtils.hasCentralTopic(selection, getViewer())); } -} \ No newline at end of file + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("DrillDownCount"); //$NON-NLS-1$ + super.run(); + } + +} 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 e6f2fe9ba..7d88d6f59 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 @@ -18,6 +18,7 @@ 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; @@ -32,4 +33,11 @@ public void setSelection(ISelection selection) { setEnabled(MindMapUtils.isSingleTopic(selection)); } -} \ No newline at end of file + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("InsertLabelCount"); //$NON-NLS-1$ + 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 9875a41a1..0aa5e592c 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 @@ -24,6 +24,7 @@ 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; @@ -59,6 +60,8 @@ public void run() { if (topicPart == null) return; + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("UseNotesCount"); //$NON-NLS-1$ NotesPopup popup = new NotesPopup(window, topicPart, true, true); popup.open(); } @@ -75,4 +78,4 @@ private ITopicPart getSelectionTopicPart(IGraphicalViewer viewer) { return null; } -} \ No newline at end of file +} 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 5f970bb3f..003c92aed 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 @@ -13,19 +13,59 @@ *******************************************************************************/ 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); + 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); } -} \ No newline at end of file + +} 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 0ecd54fd6..9d7635ba6 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 @@ -18,11 +18,12 @@ 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 InsertAttachmentAction extends RequestAction implements - ISelectionAction { +public class InsertAttachmentAction extends RequestAction + implements ISelectionAction { public InsertAttachmentAction(IGraphicalEditorPage page) { super(MindMapActionFactory.INSERT_ATTACHMENT.getId(), page, @@ -34,4 +35,11 @@ public void setSelection(ISelection selection) { MindMapUI.CATEGORY_TOPIC, false)); } -} \ No newline at end of file + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("AddAttachmentCount"); //$NON-NLS-1$ + super.run(); + } + +} 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 cb8947d69..413c63ceb 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 @@ -13,12 +13,18 @@ *******************************************************************************/ 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; @@ -36,6 +42,10 @@ 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); } @@ -77,7 +87,16 @@ public void run() { 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, @@ -93,4 +112,16 @@ public void setSelection(ISelection selection) { setEnabled(MindMapUtils.isSingleTopic(selection)); } -} \ No newline at end of file + 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/InsertParentTopicAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertParentTopicAction.java index af8f1a5bf..adc8990cd 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,12 +1,15 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/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; @@ -43,18 +46,16 @@ public InsertParentTopicAction(IGraphicalEditorPage page) { public void setSelection(ISelection selection) { setEnabled(MindMapUtils.isSingleTopic(selection) && !MindMapUtils.hasCentralTopic(selection, getViewer()) - && !MindMapUtils.hasSuchElements(selection, - MindMapUI.CATEGORY_SUMMARY)); + && !MindMapUtils.hasSummary(selection, getViewer())); if (MindMapUtils.isSingleTopic(selection)) { setEnabled(!MindMapUtils.hasCentralTopic(selection, getViewer()) - && !MindMapUtils.hasSuchElements(selection, - MindMapUI.CATEGORY_SUMMARY)); + && !MindMapUtils.hasSummary(selection, getViewer())); } else if (MindMapUtils.isAllSuchElements(selection, MindMapUI.CATEGORY_TOPIC)) { List topics = getAllTopics(selection); if (topics == null || topics.size() == 0 || containsCentralTopic(topics) - || containsSummeryTopic(topics)) { + || containsSummaryTopic(topics)) { setEnabled(false); } else { setEnabled(isAllBrothers( @@ -121,21 +122,22 @@ public boolean isCentralTopic(ITopic topic) { return topic.getOwnedSheet().getRootTopic() == topic; } - private boolean containsSummeryTopic(List topics) { - if (topics == null || topics.size() == 0) + private boolean containsSummaryTopic(List topics) { + if (topics == null || topics.isEmpty()) return false; - for (ITopic topic : topics) { - if (isSummaryTopic(topic)) + for (ITopic t : topics) { + if (isSummary(t)) return true; } return false; } - private boolean isSummaryTopic(ITopic topic) { + 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/InsertTopicAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/InsertTopicAction.java index 7e7db96bc..5970b5f1c 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,12 +1,15 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/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; @@ -21,17 +24,17 @@ import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.util.MindMapUtils; -public class InsertTopicAction extends RequestAction - implements ISelectionAction { +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)); + setImageDescriptor(MindMapUI.getImages().get( + IMindMapImages.INSERT_AFTER, true)); + setDisabledImageDescriptor(MindMapUI.getImages().get( + IMindMapImages.INSERT_AFTER, false)); } public void setSelection(ISelection selection) { @@ -39,8 +42,7 @@ public void setSelection(ISelection selection) { } private boolean isCreatable(ISelection selection) { - return (MindMapUtils.isSingleTopic(selection) && !MindMapUtils - .hasSuchElements(selection, MindMapUI.CATEGORY_SUMMARY)) + return MindMapUtils.isSingleTopic(selection) || MindMapUtils.matchesSelection(selection, MindMapUI.CATEGORY_RELATIONSHIP, true); // return true; @@ -53,4 +55,4 @@ private boolean isCreatable(ISelection selection) { // 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 5e8df0b51..401203e91 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,12 +1,15 @@ -/* - * ***************************************************************************** - * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind - * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public - * License (EPL), which is available at - * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public - * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - - * initial API and implementation +/* ****************************************************************************** + * Copyright (c) 2006-2012 XMind Ltd. and others. + * + * This file is a part of XMind 3. XMind releases 3 and + * above are dual-licensed under the Eclipse Public License (EPL), + * which is available at http://www.eclipse.org/legal/epl-v10.html + * and the GNU Lesser General Public License (LGPL), + * which is available at http://www.gnu.org/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; @@ -37,8 +40,7 @@ public InsertTopicBeforeAction(IGraphicalEditorPage page) { public void setSelection(ISelection selection) { setEnabled(MindMapUtils.isSingleTopic(selection) && !MindMapUtils.hasCentralTopic(selection, getViewer()) - && !MindMapUtils.hasSuchElements(selection, - MindMapUI.CATEGORY_SUMMARY)); + && !MindMapUtils.hasSummary(selection, getViewer())); } } 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 a9047904a..8b7812e6d 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 @@ -36,21 +36,20 @@ public NewFromMoreTemplateAction(IWorkbenchWindow window) { /* * (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 }); + 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); } -} \ 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 f033816c9..6098cc547 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 @@ -11,14 +11,12 @@ /** * @author frankshaka - * */ public class NewFromTemplateURLAction extends BaseNewFromTemplateAction { private URL url; /** - * * @param window * @param resourcePath * @param name @@ -34,7 +32,6 @@ public NewFromTemplateURLAction(IWorkbenchWindow window, URL url, /* * (non-Javadoc) - * * @see * org.xmind.ui.internal.actions.BaseNewFromTemplateAction#getTemplateStream * (org.eclipse.swt.widgets.Shell) 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 3864d7011..7bfe18d26 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 @@ -32,4 +32,4 @@ protected String getHandlerId() { protected void runWithNoHandler() { } -} \ No newline at end of file +} 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 2823a1c1f..cfffb1960 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,5 +1,6 @@ package org.xmind.ui.internal.actions; +import java.io.File; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; @@ -21,7 +22,7 @@ public class RecentFileListContributionItem extends CompoundContributionItem implements IWorkbenchContribution { - private static final int MAX_SIZE = 10; + private static final int MAX_SIZE = 50; private IServiceLocator serviceLocator; @@ -70,8 +71,11 @@ private void fillItems(List items) { for (int index = 0; index < inputURIs.length; index++) { URI inputURI = inputURIs[index]; - items.add(makeHistoryCommandItem(inputURI, index, - labels.get(inputURI))); + if (inputURI.getScheme().equalsIgnoreCase("file")) //$NON-NLS-1$ + if (new File(inputURI).exists()) { + items.add(makeHistoryCommandItem(inputURI, index, + labels.get(inputURI))); + } } } 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 6cadb8c24..c82eb53cb 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 @@ -21,10 +21,11 @@ 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 class ResetPositionAction extends RequestAction + implements ISelectionAction { public ResetPositionAction(IGraphicalEditorPage page) { super(MindMapActionFactory.RESET_POSITION.getId(), page, @@ -63,4 +64,11 @@ private boolean isResettable(Object o) { return false; } -} \ No newline at end of file + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ResetPositionCount"); //$NON-NLS-1$ + super.run(); + } + +} 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 b021cf074..4626903b9 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 @@ -6,15 +6,15 @@ import org.xmind.core.ISheet; import org.xmind.gef.ui.editor.IGraphicalEditor; import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.views.NotesView; +import org.xmind.ui.internal.e4models.NotesPart; import org.xmind.ui.mindmap.MindMapUI; public class ShowAllNotesAction extends Action { - private NotesView notesView; + private NotesPart notesPart; - public ShowAllNotesAction(NotesView notesView) { - this.notesView = notesView; + public ShowAllNotesAction(NotesPart notesPart) { + this.notesPart = notesPart; setId("org.xmind.ui.action.showAllNotes"); //$NON-NLS-1$ setText(MindMapMessages.ShowAllNotes_text); @@ -28,10 +28,10 @@ public void run() { } private void reveal() { - if (notesView == null) { + if (notesPart == null) { return; } - IGraphicalEditor editor = (IGraphicalEditor) notesView + IGraphicalEditor editor = (IGraphicalEditor) notesPart .getContributingPart(); if (editor == null) { return; diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowPropertiesAction.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowPropertiesAction.java index f921105f4..210b45d19 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowPropertiesAction.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowPropertiesAction.java @@ -15,10 +15,10 @@ import org.eclipse.jface.action.Action; import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; -import org.xmind.ui.util.Logger; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; public class ShowPropertiesAction extends Action implements IWorkbenchAction { @@ -34,16 +34,13 @@ public void run() { if (window == null) return; - try { - window.getActivePage() - .showView("org.eclipse.ui.views.PropertySheet"); //$NON-NLS-1$ - } catch (PartInitException e) { - Logger.log(e); - } + E4Utils.showPart(IModelConstants.COMMAND_SHOW_MODEL_PART, window, + IModelConstants.PART_ID_PROPERTIES, null, + IModelConstants.PART_STACK_ID_RIGHT); } 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/ShowRevisionsActionDelegate.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/actions/ShowRevisionsActionDelegate.java index b1b33c5b2..03d4677a8 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 @@ -6,7 +6,7 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IEditorActionDelegate; import org.eclipse.ui.IEditorPart; -import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.internal.utils.CommandUtils; @Deprecated public class ShowRevisionsActionDelegate implements IEditorActionDelegate { @@ -21,7 +21,9 @@ public void run(IAction action) { return; SafeRunner.run(new SafeRunnable() { public void run() throws Exception { - editor.getSite().getPage().showView(MindMapUI.VIEW_REVISIONS); + CommandUtils.executeCommand( + "org.xmind.ui.command.editingHistory", //$NON-NLS-1$ + editor.getSite().getWorkbenchWindow()); } }); 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 fff572107..469e658ed 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 @@ -23,8 +23,8 @@ import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.prefs.PrefConstants; -public class TileAction extends RequestAction implements - IPropertyChangeListener { +public class TileAction extends RequestAction + implements IPropertyChangeListener { private IPreferenceStore prefStore; @@ -51,4 +51,11 @@ public void propertyChange(PropertyChangeEvent event) { } } -} \ No newline at end of file + @Override + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("TileCount"); //$NON-NLS-1$ + super.run(); + } + +} 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 e4d3ee6dc..9d602d419 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 @@ -7,6 +7,8 @@ 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; @@ -42,6 +44,7 @@ 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; @@ -65,17 +68,17 @@ 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.internal.views.CommentsView; import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.resources.FontUtils; import org.xmind.ui.richtext.RichTextDamagerRepairer; import org.xmind.ui.richtext.RichTextScanner; import org.xmind.ui.texteditor.ISpellingActivation; @@ -169,6 +172,8 @@ protected int getEmptySelectionChangedEventDelay() { private Menu contextMenu; + private ResourceManager resources; + public CommentTextViewer(IComment comment, String objectId, IWorkbook workbook, ICommentsActionBarContributor contributor, ISelectionProvider selectionProvider, @@ -182,18 +187,26 @@ public CommentTextViewer(IComment comment, String objectId, 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 = ColorUtils.getColor("#f0f0f0"); //$NON-NLS-1$ - selectColor = ColorUtils.getColor("#eaeaea"); //$NON-NLS-1$ - } else if (container instanceof CommentsView) { - originalColor = CommentsView.BG_COLOR; - hoverColor = ColorUtils.getColor("#f9f9f9"); //$NON-NLS-1$ - selectColor = ColorUtils.getColor("#f5f5f5"); //$NON-NLS-1$ + 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$ } } @@ -217,6 +230,13 @@ public void widgetDisposed(DisposeEvent e) { } }); + //restore last editing. + if (comment != null && comment == container.getEditingComment()) { + startEditing(); + container.setModified(false); + container.setEditingComment(null); + } + return control; } @@ -241,7 +261,8 @@ private void createNullContentArea(Composite parent) { Composite marginComposite = new Composite(composite, SWT.NONE); marginComposite.setBackground(parent.getBackground()); - marginComposite.setForeground(ColorUtils.getColor("#ffffff")); //$NON-NLS-1$ + marginComposite.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ marginComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); GridLayout layout2 = new GridLayout(1, false); @@ -252,7 +273,8 @@ private void createNullContentArea(Composite parent) { createNullTextControl(marginComposite); createAddCommentActionBar(composite); - marginComposite.setBackground(ColorUtils.getColor("#298fca")); //$NON-NLS-1$ + marginComposite.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#298fca"))); //$NON-NLS-1$ } private void createNullTextControl(Composite parent) { @@ -262,9 +284,9 @@ private void createNullTextControl(Composite parent) { StyledText text = textViewer.getTextWidget(); text.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); - text.setForeground(ColorUtils.getColor("#000000")); //$NON-NLS-1$ - text.setFont( - FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 0)); + 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; @@ -331,9 +353,10 @@ 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(ColorUtils.getColor("#1877bd")); //$NON-NLS-1$ - link.setFont( - FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 1)); + 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); @@ -385,7 +408,8 @@ private void createNotNullContentArea(Composite parent) { Composite marginComposite = new Composite(composite2, SWT.NONE); marginComposite.setBackground(parent.getBackground()); - marginComposite.setForeground(ColorUtils.getColor("#ffffff")); //$NON-NLS-1$ + marginComposite.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$ marginComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); GridLayout layout2 = new GridLayout(1, false); @@ -425,9 +449,9 @@ private void createNotNullTextControl(Composite parent) { StyledText text = textViewer.getTextWidget(); text.setBackground(parent.getBackground()); - text.setForeground(ColorUtils.getColor("#45464a")); //$NON-NLS-1$ - text.setFont( - FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 0)); + 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; @@ -460,9 +484,10 @@ private void createTimeLabel(Composite parent) { timeLabel = new Label(parent, SWT.NONE); timeLabel.setAlignment(SWT.LEFT); timeLabel.setBackground(parent.getBackground()); - timeLabel.setForeground(ColorUtils.getColor("#999999")); //$NON-NLS-1$ - timeLabel.setFont( - FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, -1)); + 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; @@ -820,8 +845,10 @@ public void focusLost(FocusEvent e) { if (!isLinkHovering) { if (comment == null) { addComment(); + container.setModified(true); } else { - saveComment(); + boolean modified = saveComment(); + container.setModified(modified); } } } @@ -832,12 +859,25 @@ public void focusLost(FocusEvent e) { } 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(ColorUtils.getColor("#000000")); //$NON-NLS-1$ + getTextWidget().setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$ - getTextWidget().getParent() - .setBackground(ColorUtils.getColor("#298fca")); //$NON-NLS-1$ + getTextWidget().getParent().setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#298fca"))); //$NON-NLS-1$ CommentsUtils.removeRecursiveMouseListener(control, getMouseListener(), null); @@ -868,7 +908,8 @@ private void startEditing() { private void cancelEditing() { setRecursiveBackgroundColor(control, originalColor, null); - getTextWidget().setForeground(ColorUtils.getColor("#45464a")); //$NON-NLS-1$ + getTextWidget().setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#45464a"))); //$NON-NLS-1$ CommentsUtils.addRecursiveMouseListener(control, getMouseListener(), null); @@ -893,24 +934,11 @@ private void cancelEditing() { setEditable(false); addMouseFilter(); - Display.getCurrent().timerExec(50, new Runnable() { - - public void run() { - Display.getCurrent().asyncExec(new Runnable() { - - public void run() { - if (container != null - && container.getContentComposite() != null - && !container.getContentComposite() - .isDisposed()) { - container.getContentComposite().pack(); - container.getContentComposite().layout(true, true); - } - } - }); - } - }); - + if (container != null && container.getContentComposite() != null + && !container.getContentComposite().isDisposed()) { + container.getContentComposite().pack(); + container.getContentComposite().layout(true, true); + } } private void showControl() { @@ -1175,7 +1203,13 @@ private boolean addComment() { final IDocument document = (IDocument) textViewer.getInput(); if (document == null || document.get() == null || document.get().equals("")) { //$NON-NLS-1$ - container.cancelCreateComment(); + Display.getCurrent().asyncExec(new Runnable() { + + @Override + public void run() { + container.cancelCreateComment(); + } + }); return false; } @@ -1189,16 +1223,10 @@ private boolean addComment() { container.setLatestCreatedComment(comment); - //todo: maybe this timerExec is unnecessary. - Display.getCurrent().timerExec(40, new Runnable() { + final ICommandStack cs = targetEditor.getCommandStack(); + Display.getCurrent().asyncExec(new Runnable() { public void run() { - - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - ICommandStack cs = targetEditor.getCommandStack(); - cs.execute(cmd); - } - }); + cs.execute(cmd); } }); return true; @@ -1208,37 +1236,33 @@ 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; - final IDocument document = (IDocument) textViewer.getDocument(); if (document == null || document.get() == null || document.get().equals("")) { //$NON-NLS-1$ - DeleteCommentCommand cmd = new DeleteCommentCommand(comment - .getOwnedWorkbook().getElementById(comment.getObjectId()), - comment); - cs.execute(cmd); - return true; + command = new DeleteCommentCommand(comment.getOwnedWorkbook() + .getElementById(comment.getObjectId()), comment); + } else { + command = new ModifyCommentCommand(comment.getOwnedWorkbook() + .getElementById(comment.getObjectId()), comment, + document.get()); } - String oldContent = comment.getContent(); - String newContent = document.get(); - if (newContent.equals(oldContent)) { - cancelEditing(); - return false; - } + final Command command_0 = command; + Display.getCurrent().asyncExec(new Runnable() { - Display.getCurrent().timerExec(40, new Runnable() { + @Override public void run() { - - Display.getCurrent().asyncExec(new Runnable() { - public void run() { - final ModifyCommentCommand cmd = new ModifyCommentCommand( - comment.getOwnedWorkbook() - .getElementById(comment.getObjectId()), - comment, document.get()); - cs.execute(cmd); - } - }); + cs.execute(command_0); } }); @@ -1292,4 +1316,4 @@ public void setTargetEditor(IGraphicalEditor targetEditor) { this.targetEditor = targetEditor; } -} \ No newline at end of file +} 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 a0a494fbb..333a78440 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 @@ -15,6 +15,7 @@ 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; @@ -25,13 +26,14 @@ import org.xmind.ui.internal.MindMapMessages; import org.xmind.ui.mindmap.AbstractInfoItemContributor; import org.xmind.ui.mindmap.IInfoPart; -import org.xmind.ui.mindmap.IMindMapImages; 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; @@ -44,6 +46,13 @@ public ShowCommentsAction(ITopicPart 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; @@ -116,6 +125,10 @@ 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) { @@ -149,6 +162,7 @@ public List getPopupMenuActions(final ITopicPart topicPart, IAction editCommentsAction = createAction(topicPart, topic); editCommentsAction.setText(MindMapMessages.ModifyMenu); + editCommentsAction.setImageDescriptor(null); actions.add(editCommentsAction); IAction deleteCommentsAction = new Action( @@ -159,8 +173,7 @@ public void run() { }; }; deleteCommentsAction.setId("org.xmind.ui.removeComments"); //$NON-NLS-1$ - deleteCommentsAction.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.DELETE, true)); + deleteCommentsAction.setImageDescriptor(null); actions.add(deleteCommentsAction); return actions; @@ -175,4 +188,4 @@ protected void handleTopicEvent(ITopicPart topicPart, CoreEvent event) { topicPart.refresh(); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsViewActionBarContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPartActionBarContributor.java similarity index 55% rename from bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsViewActionBarContributor.java rename to bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPartActionBarContributor.java index 4fcec68bb..756e777ed 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsViewActionBarContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/CommentsPartActionBarContributor.java @@ -3,26 +3,26 @@ import org.eclipse.jface.action.IAction; import org.eclipse.jface.text.TextViewer; import org.xmind.gef.ui.editor.IGraphicalEditor; -import org.xmind.ui.internal.views.CommentsView; +import org.xmind.ui.internal.e4models.CommentsPart; -public class CommentsViewActionBarContributor +public class CommentsPartActionBarContributor extends CommentsActionBarContributor { - private CommentsView view; + private CommentsPart part; - public CommentsViewActionBarContributor(CommentsView view, + public CommentsPartActionBarContributor(CommentsPart part, IGraphicalEditor targetEditor) { super(targetEditor); - this.view = view; + this.part = part; makeActions(); } protected IAction getContextAction(String actionId) { - return view == null ? null : view.getGlobalAction(actionId); + return part == null ? null : part.getGlobalAction(actionId); } public void update(TextViewer textViewer) { - view.updateTextActions(textViewer); + part.updateTextActions(textViewer); } -} \ No newline at end of file +} 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 932627c6f..c989c104b 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 @@ -6,7 +6,11 @@ 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; @@ -39,9 +43,7 @@ import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchCommandConstants; -import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.contexts.IContextActivation; import org.eclipse.ui.contexts.IContextService; @@ -60,12 +62,13 @@ import org.xmind.gef.ui.editor.IGraphicalEditor; import org.xmind.ui.internal.MindMapMessages; import org.xmind.ui.internal.MindMapUIPlugin; -import org.xmind.ui.internal.views.CommentsView; +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; -import org.xmind.ui.util.Logger; public class CommentsPopup extends PopupDialog implements ICoreEventListener, ICommentTextViewerContainer { @@ -212,6 +215,9 @@ private List generateKeyStrokes(Event event) { } } + @Inject + private EPartService partService; + private IWorkbenchWindow window; private ITopicPart topicPart; @@ -255,6 +261,10 @@ private List generateKeyStrokes(Event event) { 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, @@ -394,6 +404,9 @@ public void run() { update(); } else if (Core.CommentContent.equals(type)) { IComment comment = (IComment) event.getSource(); + if (comment.isOrphan()) { + return; + } if (comment.getOwnedWorkbook().getElementById( comment.getObjectId()) == topic) { update(); @@ -426,15 +439,12 @@ public boolean close() { saveComment(); } //mark with CommentsView - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - if (window != null) { - IWorkbenchPage page = window.getActivePage(); - if (page != null) { - CommentsView commentsView = (CommentsView) page - .findView(MindMapUI.VIEW_COMMENTS); - if (commentsView != null) { - Control control = commentsView.getControl(); + 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); @@ -562,6 +572,8 @@ public void run() { private void update() { resetSelectedComment(); updateComments(); + setModified(false); + setEditingComment(null); } private void resetSelectedComment() { @@ -611,15 +623,12 @@ public int open() { } } //mark with CommentsView - IWorkbenchWindow window = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow(); - if (window != null) { - IWorkbenchPage page = window.getActivePage(); - if (page != null) { - CommentsView commentsView = (CommentsView) page - .findView(MindMapUI.VIEW_COMMENTS); - if (commentsView != null) { - Control control = commentsView.getControl(); + 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); @@ -668,6 +677,8 @@ private void registerDialogCommands() { private void saveComment() { if (contentViewer != null) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("AddCommentCount"); //$NON-NLS-1$ contentViewer.save(); } } @@ -699,21 +710,14 @@ private boolean handleCommand(String commandId) { public void gotoCommentsView() { Display.getCurrent().asyncExec(new Runnable() { public void run() { - if (window == null) + if (window == null) { return; - - IWorkbenchPage workbenchPage = window.getActivePage(); - if (workbenchPage == null) - return; - - close(); - try { - workbenchPage.showView(MindMapUI.VIEW_COMMENTS, null, - IWorkbenchPage.VIEW_ACTIVATE); - } catch (PartInitException e) { - Logger.log(e, - "GotoCommentsViewAction failed to show Comments View."); //$NON-NLS-1$ } + close(); + + E4Utils.showPart(IModelConstants.COMMAND_SHOW_MODEL_PART, + window, IModelConstants.PART_ID_COMMENTS, null, + IModelConstants.PART_STACK_ID_RIGHT); } }); } @@ -790,4 +794,20 @@ 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 59dff647e..cf0dc556b 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 @@ -46,9 +46,9 @@ public void update(TextViewer textViewer) { } } - private class GotoCommentsViewAction extends CommentAction { + private class GotoCommentsPartAction extends CommentAction { - public GotoCommentsViewAction(IGraphicalEditor editor) { + public GotoCommentsPartAction(IGraphicalEditor editor) { super(editor); setId("org.xmind.ui.action.gotoCommentsView"); //$NON-NLS-1$ setText(MindMapMessages.EditInCommentsView_text); @@ -107,7 +107,7 @@ protected void makeActions() { targetEditor, commentsPopup); addAction(showNextTopicCommentsAction); - gotoCommentsViewAction = new GotoCommentsViewAction(targetEditor); + gotoCommentsViewAction = new GotoCommentsPartAction(targetEditor); addAction(gotoCommentsViewAction); } 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 8785ebe1f..9139e8f5a 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 @@ -26,4 +26,12 @@ public interface ICommentTextViewerContainer { 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/SheetCommentsViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/comments/SheetCommentsViewer.java index b2040bd3f..91212d27b 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 @@ -8,21 +8,38 @@ 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; @@ -32,12 +49,17 @@ 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 { +public class SheetCommentsViewer + implements ICoreEventListener, ISelectionChangedListener { + + private ResourceManager resources; private ISheet input; @@ -65,6 +87,18 @@ public class SheetCommentsViewer implements ICoreEventListener { 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, @@ -78,20 +112,105 @@ public SheetCommentsViewer(ISheet input, } public void create(Composite parent) { + this.parent = parent; init(); - createAllComments(parent, input); + 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) { @@ -104,38 +223,30 @@ private Control createAllComments(Composite parent, ISheet sheet) { 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 (showTopicsComments && showSheetComments) { + if (showSheetComments) { createSeparatorLine(composite); } - createSheetComments(composite, sheet); - //If have no comment, create null comment content. - if (!showTopicsComments && !showSheetComments) { - container.getScrolledComposite().setExpandVertical(true); - createNullContentArea(parent); - } - - composite.addDisposeListener(new DisposeListener() { - - public void widgetDisposed(DisposeEvent e) { - handleControlDisposed(e); - } - }); + createInsertCommentHyperlink(composite); return composite; } /** - * * @param parent * @param sheet * @return true if create not less than one comment, false otherwise. @@ -145,8 +256,8 @@ private boolean createTopicsComments(Composite parent, ITopic root) { Iterator topicIt = new TopicIterator(root); while (topicIt.hasNext()) { ITopic topic = topicIt.next(); - if (topic.getOwnedWorkbook().getCommentManager() - .hasComments(topic.getId())) { + if (topic.getOwnedWorkbook().getCommentManager().hasComments( + topic.getId()) || topic.getId().equals(creatingTargetId)) { if (hasContent) { createSeparatorLine(parent); } @@ -176,8 +287,13 @@ private void createTopicLabelAndComments(Composite parent, ITopic topic) { topicViewer = new TopicCommentsViewer(topic, contributor, selectionProvider, container, true, targetEditor); topicViewer.create(parent); - controls.addAll(topicViewer.getControls()); - implementations.addAll(topicViewer.getImplementations()); + + if (topicViewer.getControls() != null) { + controls.addAll(topicViewer.getControls()); + } + if (topicViewer.getImplementations() != null) { + implementations.addAll(topicViewer.getImplementations()); + } topicViewers.put(topic, topicViewer); } @@ -218,13 +334,14 @@ private void createSheetLabel(Composite parent, final ISheet sheet) { titleLabel = new Label(composite, SWT.LEFT | SWT.HORIZONTAL); titleLabel.setBackground(parent.getBackground()); - titleLabel.setForeground(ColorUtils.getColor("#353535")); //$NON-NLS-1$ + 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(FontUtils.getBold( - FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 1))); + titleLabel.setFont((Font) resources + .get(FontDescriptor.createFrom(FontUtils.relativeHeight( + titleLabel.getFont().getFontData(), 1)))); titleLabel.setText(MindMapMessages.Comment_SHEET_text + TextFormatter.removeNewLineCharacter(sheet.getTitleText())); @@ -252,7 +369,8 @@ private void createCommentControl(Composite parent, IComment comment) { private void createNullContentArea(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setBackground(composite.getParent().getBackground()); - final GridData layoutData = new GridData(GridData.FILL_BOTH); + GridData layoutData = new GridData(GridData.FILL_BOTH); + composite.setLayoutData(layoutData); GridLayout layout = new GridLayout(1, false); layout.marginWidth = 0; @@ -271,14 +389,14 @@ private void createNullContent(Composite parent) { GridLayout layout = new GridLayout(1, false); layout.marginWidth = 0; layout.marginHeight = 0; - layout.verticalSpacing = 20; + 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(MindMapUI.getImages().get("comment-empty-bg.png", true) //$NON-NLS-1$ - .createImage()); + 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()); @@ -292,21 +410,162 @@ private void createNullContent(Composite parent) { Label label2 = new Label(composite2, SWT.NONE); label2.setBackground(label2.getParent().getBackground()); - label2.setForeground(ColorUtils.getColor("#aaaaaa")); //$NON-NLS-1$ + label2.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#aaaaaa"))); //$NON-NLS-1$ label2.setLayoutData( new GridData(SWT.CENTER, SWT.CENTER, false, false)); - label2.setText(MindMapMessages.Comment_NoComments_text); - label2.setFont( - FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 2)); + 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(ColorUtils.getColor("#aaaaaa")); //$NON-NLS-1$ + 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( - FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 2)); + 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) { @@ -363,14 +622,31 @@ private void handleControlDisposed(DisposeEvent e) { } public void setTargetEditor(IGraphicalEditor targetEditor) { - if (this.targetEditor != targetEditor) { - if (topicViewer != null) { - topicViewer.setTargetEditor(targetEditor); - } - if (implementations != null) { - for (CommentTextViewer implementation : implementations) { - implementation.setTargetEditor(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); } } } @@ -411,9 +687,8 @@ public void cancelCreateNewComment() { if (newCommentControl != null && !newCommentControl.isDisposed()) { newCommentControl.dispose(); newCommentControl = null; + update(); } - - container.getContentComposite().pack(); } public void save() { @@ -423,4 +698,29 @@ public void save() { } } + @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/decorations/CloudTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/CloudTopicDecoration.java index 92cf27249..6fabab810 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 @@ -3,6 +3,7 @@ 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; @@ -20,6 +21,8 @@ public class CloudTopicDecoration extends AbstractTopicDecoration { 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() { @@ -96,13 +99,14 @@ private boolean containsPoint(IFigure figure, float x, float y) { 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; - return new Insets( + Insets insets = new Insets( (int) ((height + getTopMargin() + getLineWidth()) / scaleHeight * scaleTop), (int) ((width + getLeftMargin() + getLineWidth()) / scaleWidth @@ -111,6 +115,32 @@ public Insets getPreferredInsets(IFigure figure, int width, int height) { / 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/ParallelogramTopicDecoration.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorations/ParallelogramTopicDecoration.java index 45cea44bf..19907c51f 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 @@ -15,7 +15,7 @@ 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, + 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, @@ -39,63 +39,42 @@ public Insets getPreferredInsets(IFigure figure, int width, int height) { + getLineWidth() + Math.round(height * SCALE) + 1); } - @Override public PrecisionPoint getAnchorLocation(IFigure figure, double refX, double refY, double expansion) { - boolean isVertical = false; Rectangle r = getOutlineBox(figure); - 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 (Math.abs(dx) >= 99) - if (expansion != 0.0) { - expansion += r.height * SCALE; - } else { - expansion += r.height * SCALE * 0.5; - } - if (Math.abs(dy) > 99) - isVertical = true; + 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 + expansion - : r.x + r.height * SCALE - expansion, + (dx > 0) ? r.right() - r.height * SCALE * SCALE + expansion + : r.x + r.height * SCALE * SCALE - expansion, refY); - double scale = 0.5 + double scale = 0.5f / 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; + dx = Math.round(dx *= scale); + dy = Math.round(dy *= scale); - if (isVertical) - return new PrecisionPoint(centerX, centerY); + 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; - if (centerY >= r.y && centerY <= r.bottom()) { - if (dx > 0) { - double py = centerY - r.y; - centerX -= py * SCALE * 2; - } else { - double py = r.bottom() - centerY; - centerX += py * SCALE * 2; - } } - return new PrecisionPoint(centerX, centerY); + 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 08b84e569..d6e90c1d4 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 @@ -26,6 +26,11 @@ 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; @@ -82,6 +87,43 @@ protected void sketch(IFigure figure, Path shape, Rectangle 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(); @@ -481,20 +523,20 @@ private List collectTopics(IBoundaryPart boundary) { } private void addAllTopics(IBranchPart branch, List topics) { - List subs = branch.getSubBranches(); - List callouts = branch.getCalloutBranches(); - if (subs.isEmpty() && callouts.isEmpty()) - return; - - for (IBranchPart sub : subs) { + for (IBranchPart sub : branch.getSubBranches()) { topics.add(sub.getTopicPart()); addAllTopics(sub, topics); } - for (IBranchPart callout : callouts) { + 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) { @@ -545,4 +587,4 @@ private ITopicPart findTopicByValue(Map map, return null; } -} \ No newline at end of file +} 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 4e316e806..917906002 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 @@ -76,6 +76,7 @@ protected void paintPath(IFigure figure, Graphics graphics, Path path, } finally { graphics.popState(); shape.close(); + shape.dispose(); } return; 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 50d938f44..f8cfc9c51 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 @@ -3,7 +3,6 @@ import org.eclipse.draw2d.IFigure; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.util.Util; -import org.eclipse.swt.graphics.Font; import org.xmind.gef.draw2d.RotatableWrapLabel; import org.xmind.gef.part.Decorator; import org.xmind.gef.part.IGraphicalPart; @@ -31,9 +30,9 @@ public void decorate(IGraphicalPart part, IFigure figure) { if (part instanceof InfoItemContentPart) { topicPart = ((InfoItemContentPart) part).getTopicPart(); if (topicPart != null) { - Font topicFont = topicPart.getTitle().getTextFigure().getFont(); - figure.setFont(FontUtils.getNewHeight(topicFont, - Util.isMac() ? 10 : 8)); + figure.setFont( + FontUtils.getNewHeight(JFaceResources.getDefaultFont(), + Util.isMac() ? 10 : 8)); } else { figure.setFont(JFaceResources.getDefaultFont()); } @@ -57,8 +56,8 @@ private void setPrefWidth(final RotatableWrapLabel itemFigure, final IFigure figure = topicPart.getFigure(); figure.getUpdateManager().runWithUpdate(new Runnable() { public void run() { - itemFigure.setPrefWidth((int) (((figure.getSize().width - + figure.getClientArea().width) / 2) * 1.4 - 10)); + itemFigure.setPrefWidth(Math.abs((int) (((figure.getSize().width + + figure.getClientArea().width) / 2) * 1.1 - 10))); } }); 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 a8b19c8f6..76fa234c6 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 @@ -17,6 +17,10 @@ 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; @@ -26,7 +30,6 @@ import org.xmind.ui.internal.decorations.RectangleInfoDecration; import org.xmind.ui.internal.mindmap.InfoPart; import org.xmind.ui.mindmap.ISheetPart; -import org.xmind.ui.resources.ColorUtils; import org.xmind.ui.style.Styles; public class InformationDecorator extends Decorator { @@ -57,14 +60,17 @@ public void decorate(IGraphicalPart part, IFigure figure) { 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.setLineColor(figure, - ColorUtils.getColor(Styles.YELLOWBOX_LINE_COLOR)); + shape.setLineAlpha(figure, 255); shape.setLineWidth(figure, LINEWIDTH); + shape.setLineStyle(figure, SWT.LINE_SOLID); fig.setDecoration(shape); } } @@ -83,4 +89,4 @@ private ISheetPart getSheetPart(IGraphicalPart part) { public static InformationDecorator getInstance() { return instance; } -} \ No newline at end of file +} 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 b2d8e1853..550d3bb91 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,25 +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 +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/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 { @@ -27,10 +26,11 @@ public class LegendItemDecorator extends Decorator { public void activate(IGraphicalPart part, IFigure figure) { super.activate(part, figure); - figure.setFont(JFaceResources.getDefaultFont()); + figure.setFont(FontUtils.getNewHeight(JFaceResources.getDefaultFont(), + Util.isMac() ? 10 : 8)); figure.setForegroundColor(ColorConstants.black); if (figure instanceof LegendItemFigure) { - ((LegendItemFigure) figure).getIcon().setPreferredSize(24, 24); + ((LegendItemFigure) figure).getIcon().setPreferredSize(15, 15); } } @@ -59,4 +59,4 @@ public static LegendItemDecorator getInstance() { return instance; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/SummaryDecorator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/SummaryDecorator.java index 70d0b1bf7..cb622c412 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/SummaryDecorator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/decorators/SummaryDecorator.java @@ -87,7 +87,7 @@ private void decorateSummary(IGraphicalPart part, IStyleSelector ss, ISummaryPart summary = (ISummaryPart) part; decorateAnchors(figure, decoration, summary); } - decoration.setVisible(figure, true); + decoration.setVisible(figure, figure.isVisible()); } figure.setVisible(isSummaryVisible(part)); 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 new file mode 100644 index 000000000..193d5151b --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/BlackBoxDialog.java @@ -0,0 +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); + } + +} 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 ddd0ad077..ac4a07a92 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 @@ -28,6 +28,7 @@ public class DialogMessages extends NLS { 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; diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/HyperlinkDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/HyperlinkDialog.java index c3ee62ec1..054a1d3e8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/HyperlinkDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/HyperlinkDialog.java @@ -28,6 +28,8 @@ import org.eclipse.jface.dialogs.TitleAreaDialog; 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.IFontProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; @@ -68,17 +70,14 @@ import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.mindmap.IProtocolDescriptor; import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.resources.FontUtils; import org.xmind.ui.util.Logger; import org.xmind.ui.viewers.ImageCachedLabelProvider; /** - * * @author Frank Shaka - * */ -public class HyperlinkDialog extends TitleAreaDialog implements - IHyperlinkPageContainer { +public class HyperlinkDialog extends TitleAreaDialog + implements IHyperlinkPageContainer { private static class NullHyperlinkPage extends HyperlinkPage { @@ -89,8 +88,8 @@ public void init(IEditorPart editor, IStructuredSelection selection) { public void createControl(Composite parent) { label = new Label(parent, SWT.NONE); - label - .setText(DialogMessages.HyperlinkDialog_FailCreatePage_message); + label.setText( + DialogMessages.HyperlinkDialog_FailCreatePage_message); } public void dispose() { @@ -163,7 +162,8 @@ protected Image createImage(Object element) { } public Font getFont(Object element) { - return FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 2); + return resources.createFont(JFaceResources + .getDefaultFontDescriptor().increaseHeight(2)); } } @@ -197,9 +197,13 @@ public Font getFont(Object element) { private SashForm form; + private ResourceManager resources; + public HyperlinkDialog(Shell parentShell, IEditorPart editor, IStructuredSelection selection) { super(parentShell); + resources = new LocalResourceManager(JFaceResources.getResources(), + parentShell); this.editor = editor; this.selection = selection; setShellStyle(SWT.RESIZE | SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); @@ -207,8 +211,8 @@ public HyperlinkDialog(Shell parentShell, IEditorPart editor, @Override protected IDialogSettings getDialogBoundsSettings() { - return MindMapUIPlugin.getDefault().getDialogSettings( - "org.xmind.ui.HyperlinkDialog"); //$NON-NLS-1$ + return MindMapUIPlugin.getDefault() + .getDialogSettings("org.xmind.ui.HyperlinkDialog"); //$NON-NLS-1$ } public void create() { @@ -312,8 +316,8 @@ protected Control createDialogArea(Composite parent) { form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); ((GridData) form.getLayoutData()).widthHint = 400; ((GridData) form.getLayoutData()).heightHint = 300; - form.setBackground(parent.getDisplay().getSystemColor( - SWT.COLOR_LIST_BACKGROUND)); + form.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); form.setSashWidth(4); createTypeViewer(form); @@ -363,9 +367,9 @@ private void createTypeViewer(Composite parent) { properties.set(GalleryViewer.Wrap, Boolean.FALSE); properties.set(GalleryViewer.TitlePlacement, PositionConstants.RIGHT); properties.set(GalleryViewer.FlatFrames, Boolean.TRUE); - properties.set(GalleryViewer.Layout, new GalleryLayout( - GalleryLayout.ALIGN_TOPLEFT, GalleryLayout.ALIGN_FILL, 0, 1, - new Insets(1))); + properties.set(GalleryViewer.Layout, + new GalleryLayout(GalleryLayout.ALIGN_TOPLEFT, + GalleryLayout.ALIGN_FILL, 0, 1, new Insets(1))); properties.set(GalleryViewer.SingleClickToOpen, Boolean.FALSE); properties.set(GEF.SelectionConstraint, GEF.SEL_SINGLE); // properties.set(GalleryViewer.FrameContentSize, new Dimension(32, 32)); @@ -453,7 +457,6 @@ protected void createButtonsForButtonBar(Composite parent) { /* * (non-Javadoc) - * * @see org.eclipse.jface.dialogs.TrayDialog#close() */ @Override 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 6fef9f668..c9401936f 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 @@ -31,6 +31,7 @@ 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 @@ -132,7 +133,10 @@ private Control createTemplatesContainer(Composite parent) { private List loadTemplatesViewerInput() { ArrayList templates = new ArrayList(); IResourceManager resourceManager = MindMapUI.getResourceManager(); - templates.addAll(resourceManager.getSystemTemplates()); +// templates.addAll(resourceManager.getSystemTemplates()); + List groups = resourceManager.getSystemTemplateGroups(); + for (ITemplateGroup group : groups) + templates.addAll(group.getTemplates()); templates.addAll(resourceManager.getUserTemplates()); return templates; } 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 new file mode 100644 index 000000000..1a5f5248c --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ProgressDialogPart.java @@ -0,0 +1,673 @@ +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/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); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ReduceFileSizeDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ReduceFileSizeDialog.java index 711e1ded6..1c339b55c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ReduceFileSizeDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/ReduceFileSizeDialog.java @@ -10,10 +10,13 @@ import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; 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.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; @@ -40,6 +43,13 @@ public void create() { protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); + Label title = new Label(composite, SWT.NONE); + title.setText(DialogMessages.ReduceFileSize_text); + FontData fontData = title.getFont().getFontData()[0]; + Font font = new Font(Display.getDefault(), new FontData( + fontData.getName(), fontData.getHeight() + 2, SWT.BOLD)); + title.setFont(font); + Label label = new Label(composite, SWT.WRAP); label.setText(DialogMessages.ReduceFileSize_Advise_text); GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); @@ -51,13 +61,24 @@ protected Control createDialogArea(Composite parent) { editingHistoryCheckbox.setSelection(true); editingHistoryCheckbox .setText(DialogMessages.DeleteEditingHistory_text); + GridData ehcGridData = new GridData(SWT.FILL, SWT.FILL, true, false); + ehcGridData.widthHint = 380; + ehcGridData.heightHint = SWT.DEFAULT; + ehcGridData.horizontalIndent = 20; + ehcGridData.verticalIndent = 10; + editingHistoryCheckbox.setLayoutData(ehcGridData); previewImageCheckbox = new Button(composite, SWT.CHECK); previewImageCheckbox.setText(DialogMessages.DeletePreviewImage_text); + GridData picGridData = new GridData(SWT.FILL, SWT.FILL, true, false); + picGridData.widthHint = 380; + picGridData.heightHint = SWT.DEFAULT; + picGridData.horizontalIndent = 20; + previewImageCheckbox.setLayoutData(picGridData); SelectionListener listener = new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { - getButton(IDialogConstants.OK_ID).setEnabled( - editingHistoryCheckbox.getSelection() + getButton(IDialogConstants.OK_ID) + .setEnabled(editingHistoryCheckbox.getSelection() || previewImageCheckbox.getSelection()); } }; @@ -108,4 +129,12 @@ protected void configureShell(Shell newShell) { newShell.setText(DialogMessages.ReduceFileSize_text); } + protected void createButtonsForButtonBar(Composite parent) { + // create OK and Cancel buttons by default + createButton(parent, IDialogConstants.OK_ID, + DialogMessages.ReduceAndSave_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/RevisionPreviewDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/RevisionPreviewDialog.java index ae130ff4d..1df62b60b 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 @@ -72,10 +72,18 @@ /** * @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() { @@ -88,14 +96,14 @@ 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)) { + if (SWTUtils.matchKey(ke.getState(), ke.keyCode, 0, + SWT.ARROW_LEFT)) { asyncExec(new Runnable() { public void run() { setIndex(index - 1); @@ -118,7 +126,6 @@ private class ContainerLayout extends Layout { /* * (non-Javadoc) - * * @see * org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets * .Composite, int, int, boolean) @@ -143,15 +150,13 @@ protected org.eclipse.swt.graphics.Point computeSize( /* * (non-Javadoc) - * - * @see - * org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite - * , boolean) + * @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.PREF_HEIGHT; + 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); @@ -175,7 +180,6 @@ public NavigationLabelProvider() { /* * (non-Javadoc) - * * @see * org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) */ @@ -206,7 +210,6 @@ private Image getSheetImage() { /* * (non-Javadoc) - * * @see * org.eclipse.jface.viewers.IFontProvider#getFont(java.lang.Object) */ @@ -224,14 +227,13 @@ public void dispose() { } } - private class NavigationSelectionChangedListener implements - ISelectionChangedListener { + private class NavigationSelectionChangedListener + implements ISelectionChangedListener { private ICancelable updater = null; /* * (non-Javadoc) - * * @see * org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged * (org.eclipse.jface.viewers.SelectionChangedEvent) @@ -285,11 +287,13 @@ private void updateSelection(ISelection selection) { 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)))) { + 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(); } } @@ -313,7 +317,6 @@ public RevisionPreviewDialog(Shell parentShell, ISheet sourceSheet, /* * (non-Javadoc) - * * @see org.eclipse.jface.dialogs.Dialog#isResizable() */ @Override @@ -348,14 +351,14 @@ private Object getSelection() { private void updateShellTitle(Object selection) { String sheetTitle = String.format("\"%s - %s\"", //$NON-NLS-1$ - sourceSheet.getTitleText(), sourceSheet.getRootTopic() - .getTitleText()); + sourceSheet.getTitleText(), + sourceSheet.getRootTopic().getTitleText()); String title; if (selection instanceof IRevision) { - title = NLS - .bind(DialogMessages.RevisionPreviewDialog_Revision_titlePattern, - String.valueOf(((IRevision) selection) - .getRevisionNumber()), sheetTitle); + title = NLS.bind( + DialogMessages.RevisionPreviewDialog_Revision_titlePattern, + String.valueOf(((IRevision) selection).getRevisionNumber()), + sheetTitle); } else { title = NLS.bind( DialogMessages.RevisionPreviewDialog_CurrentRevision_title, @@ -366,15 +369,14 @@ private void updateShellTitle(Object selection) { /* * (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); + Color background = parent.getDisplay() + .getSystemColor(SWT.COLOR_LIST_BACKGROUND); parent.setBackground(background); Composite container = new Composite(parent, SWT.NONE); @@ -412,7 +414,14 @@ private void createNavigationBar(Composite parent) { revisions.toArray(elements); elements[elements.length - 1] = sourceSheet; navBar.setInput(elements); - navBar.addSelectionChangedListener(new NavigationSelectionChangedListener()); + 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()); } @@ -453,7 +462,8 @@ private Control createCorruptionWarning() { Label label = new Label(composite, SWT.NONE); label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); - label.setText(DialogMessages.RevisionPreviewDialog_CorruptedRevision_message); + label.setText( + DialogMessages.RevisionPreviewDialog_CorruptedRevision_message); return composite; } @@ -468,7 +478,7 @@ private MindMapViewer getRevisionViewer(Object selection, ISheet sheet) { } public MindMapViewer createViewer(Composite parent, ISheet sheet) { - MindMapViewer viewer = new MindMapViewer(); + MindMapViewer viewer = new RevisionMindMapViewer(); initViewer(viewer); viewer.createControl(parent); viewer.getCanvas().setScrollBarVisibility(FigureCanvas.AUTOMATIC); @@ -495,8 +505,8 @@ public void initViewer(MindMapViewer viewer) { @Override protected IDialogSettings getDialogBoundsSettings() { - return MindMapUIPlugin.getDefault().getDialogSettings( - "org.xmind.ui.RevisionsDialog"); //$NON-NLS-1$ + return MindMapUIPlugin.getDefault() + .getDialogSettings("org.xmind.ui.RevisionsDialog"); //$NON-NLS-1$ } protected Point getInitialSize() { @@ -528,7 +538,6 @@ public void run() { /* * (non-Javadoc) - * * @see org.eclipse.jface.window.Window#open() */ @Override @@ -618,7 +627,6 @@ private void finishOpening(Shell shell) { /* * (non-Javadoc) - * * @see org.eclipse.jface.dialogs.Dialog#close() */ @Override 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 6d5988d32..f3f1208e3 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 @@ -5,6 +5,8 @@ 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; @@ -22,7 +24,6 @@ import org.xmind.ui.wizards.SaveOptions; /** - * * @author Frank Shaka * @since 3.6.50 */ @@ -34,6 +35,10 @@ public class SaveWizardDialog extends Dialog { private SaveOptions targetOptions; + private boolean prepareForSpace = false; + + private Button defaultButton; + public SaveWizardDialog(Shell parentShell, List wizards, SaveWizardDescriptor targetWizard, SaveOptions targetOptions) { @@ -98,8 +103,42 @@ private void createNameField(Composite parent) { text.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { - targetOptions = targetOptions - .proposalName(((Text) e.widget).getText()); + 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$ + } + } + } } }); } @@ -154,7 +193,8 @@ public void widgetDefaultSelected(SelectionEvent e) { @Override protected void createButtonsForButtonBar(Composite parent) { - createButton(parent, IDialogConstants.OK_ID, MindMapMessages.SaveWizardDialog_okButton_text, true); + 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 742662080..dd79c5444 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 @@ -83,7 +83,6 @@ public ShareOption getSelectedOption() { /* * (non-Javadoc) - * * @see org.eclipse.jface.dialogs.Dialog#create() */ @Override @@ -94,7 +93,6 @@ public void create() { /* * (non-Javadoc) - * * @see * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets. * Shell) @@ -151,7 +149,8 @@ private void createTopSection(Composite parent) { .getOptionsByCategory(RegistryConstants.VAL_CATEGORY_POPULAR); for (ShareOption option : options) { createShareItem(composite, option.getLabel(), - option.getImage().createImage(), option.getId(), 3, 8); + (Image) resources.get(option.getImage()), option.getId(), 3, + 8); } } @@ -194,7 +193,8 @@ private void createBottomSection(Composite parent) { .getOptionsByCategory(RegistryConstants.VAL_CATEGORY_NORMAL); for (ShareOption option : options) { createShareItem(composite, option.getLabel(), - option.getImage().createImage(), option.getId(), 0, 5); + (Image) resources.get(option.getImage()), option.getId(), 0, + 5); } } 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 2fa996756..e7152c9fe 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 @@ -16,17 +16,16 @@ import java.util.ArrayList; import java.util.List; -import org.eclipse.jface.resource.ImageDescriptor; 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.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; @@ -40,13 +39,9 @@ import org.xmind.core.IWorkbook; import org.xmind.core.util.HyperlinkUtils; import org.xmind.ui.dialogs.HyperlinkPage; -import org.xmind.ui.mindmap.MindMapUI; -import org.xmind.ui.viewers.ImageCachedLabelProvider; /** - * * @author Frank Shaka - * */ public class TopicHyperlinkPage extends HyperlinkPage { @@ -90,11 +85,12 @@ public Object getParent(Object element) { public void dispose() { } - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { } } - private class TopicPageLabelProvider extends ImageCachedLabelProvider { + private class TopicPageLabelProvider extends LabelProvider { public String getText(Object element) { if (element instanceof ITopic) { @@ -111,18 +107,17 @@ public String getText(Object 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); - } +// protected Image createImage(Object element) { +// ImageDescriptor icon = MindMapUI.getImages().getElementIcon(element, +// true); +// if (icon == null) +// return null; +// return icon.createImage(false); +// } } @@ -184,11 +179,12 @@ private void createLabel(Composite 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); + 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.getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); topicViewer.setAutoExpandLevel(2); topicViewer.setContentProvider(new TopicPageContentProvider()); 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 d7fcff0f4..90ddef322 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 @@ -792,31 +792,20 @@ private void openLocalImageFileDialog() { 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); - request.setTargets(fillParts()); - mindMapViewer.getEditDomain().handleRequest(request); - changeOpacity(path); - } - - private void changeOpacity(String path) { + int value; if (isPattern(path)) - changeOpacity(10); + value = 10; else - changeOpacity(100); - } - - private void changeOpacity(int value) { - if (mindMapViewer == null) - return; - - Request request = new Request(MindMapUI.REQ_MODIFY_STYLE); - request.setParameter(MindMapUI.PARAM_COMMAND_LABEL, - CommandMessages.Command_ModifyWallpaperOpacity); + value = 100; request.setParameter(MindMapUI.PARAM_STYLE_PREFIX + Styles.Opacity, String.valueOf((double) value * 1.0 / 100)); request.setTargets(fillParts()); @@ -940,4 +929,4 @@ private static Image createFilledImage(Display display, Image src, return image; } -} \ No newline at end of file +} 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 new file mode 100644 index 000000000..b4d1f9040 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WorkbookMetaInspectorDialog.java @@ -0,0 +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; + } + +} 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 new file mode 100644 index 000000000..3c9bd6e4d --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dialogs/WorkbookRevisionDialog.java @@ -0,0 +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(); + } + } + }); + } + +} 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 a30056340..c35e8277b 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 @@ -6,10 +6,11 @@ Save_title=Save ErrorOpen_title=XMind - Open ErrorSave_title=XMind - Save -ReduceFileSize_Advise_text=If you think your XMind file is too big to make you feel cool, you can reduce its size by selecting the checkbox below. -DeleteEditingHistory_text=Delete Editing History -DeletePreviewImage_text=Delete Preview Image +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. @@ -130,7 +131,7 @@ RevisionPreviewDialog_CorruptedRevision_message=Oops, this revision seems to hav RevisionPreviewDialog_CurrentRevision_title=Current Sheet - {0} RevisionPreviewDialog_Revision_titlePattern=Preview( {0} ) workbookRevisionDialog_Title_Label_text=Editing History -workbookRevisionDialog_Description_Label_text=Editing history helps you to restore the previous version of this XMind file. +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 @@ -165,8 +166,8 @@ DND_ConfirmDroppingFileDialog_LinkButton_text=Link DND_ConfirmDroppingFileDialog_CopyButton_text=Copy DND_ConfirmDroppingFileDialog_RememberCheck_text_with_type=Remember my decision for adding ''{0}'' -ConfirmDeleteTemplateDialog_title=XMind - Delete Template -ConfirmDeleteTemplateDialog_message_with_templateName=Are you sure you want to delete this template ''{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? diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/FileDndClient.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/FileDndClient.java index e934a80a6..27a1c7892 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/FileDndClient.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/dnd/FileDndClient.java @@ -31,6 +31,7 @@ import org.eclipse.swt.dnd.TransferData; 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.eclipse.swt.widgets.Shell; import org.xmind.core.IFileEntry; @@ -51,6 +52,7 @@ import org.xmind.ui.util.ImageFormat; import org.xmind.ui.util.Logger; +@SuppressWarnings("restriction") public class FileDndClient extends MindMapDNDClientBase { private static final String CREATE_IMAGE = "CREATE_IMAGE"; //$NON-NLS-1$ @@ -386,9 +388,11 @@ private static Dimension getImageSize(String path) { Image tempImage = new Image(Display.getCurrent(), path); Rectangle imageBounds = tempImage.getBounds(); tempImage.dispose(); - return Geometry.getScaledConstrainedSize(imageBounds.width, - imageBounds.height, MindMapUI.IMAGE_INIT_WIDTH, - MindMapUI.IMAGE_INIT_HEIGHT); + 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; @@ -399,4 +403,4 @@ public boolean canLink(TransferData data, IViewer viewer, Point location, return true; } -} \ No newline at end of file +} 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 bc5b62164..ffbfcd2ee 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 @@ -2,6 +2,7 @@ import java.net.URI; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import org.eclipse.draw2d.geometry.Point; @@ -14,6 +15,7 @@ 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; @@ -30,9 +32,11 @@ 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; @@ -87,7 +91,8 @@ public Command makeDNDCommand(Object transferredData, Request request) { private ITopic findTargetParentTopic(IViewer viewer, IPart parent) { Object targetParentModel = MindMapUtils.getRealModel(parent); ITopic targetParent; - if (targetParentModel == null || !(targetParentModel instanceof ITopic)) { + if (targetParentModel == null + || !(targetParentModel instanceof ITopic)) { targetParent = (ITopic) viewer.getAdapter(ITopic.class); } else { targetParent = (ITopic) targetParentModel; @@ -105,21 +110,24 @@ protected Command makeDNDCommand(Object transferData, Request request, List commands = new ArrayList(); makeDNDCommands(request, workbook, targetParent, elements, commands, - floating); + floating, dropInParent); return new CompoundCommand(commands); } protected void makeDNDCommands(Request request, IWorkbook workbook, ITopic targetParent, Object[] elements, List commands, - boolean floating) { - ISheet sheet = (ISheet) request.getTargetViewer().getAdapter( - ISheet.class); + 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); @@ -145,21 +153,25 @@ protected void makeDNDCommands(Request request, IWorkbook workbook, } else if (element instanceof IRelationship) { if (sheet != null) { IRelationship relationship = (IRelationship) element; - commands.add(new AddRelationshipCommand(relationship, sheet)); + commands.add( + new AddRelationshipCommand(relationship, sheet)); } } else if (element instanceof IBoundary) { if (targetParent != null) { IBoundary boundary = (IBoundary) element; - commands.add(new AddBoundaryCommand(boundary, targetParent)); + commands.add( + new AddBoundaryCommand(boundary, targetParent)); } } else if (element instanceof IMarkerRef || element instanceof IMarker) { if (targetParent != null) { - IMarker marker = (element instanceof IMarker) ? (IMarker) element + IMarker marker = (element instanceof IMarker) + ? (IMarker) element : ((IMarkerRef) element).getMarker(); if (marker != null) { - String markerId = (element instanceof IMarker) ? ((IMarker) element) - .getId() : ((IMarkerRef) element).getMarkerId(); + 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); @@ -167,6 +179,12 @@ protected void makeDNDCommands(Request request, IWorkbook workbook, 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()) { @@ -177,8 +195,8 @@ protected void makeDNDCommands(Request request, IWorkbook workbook, } } } - commands.add(new AddMarkerCommand(targetParent, - markerId)); + commands.add( + new AddMarkerCommand(targetParent, markerId)); } } } else if (element instanceof IImage) { @@ -186,8 +204,8 @@ protected void makeDNDCommands(Request request, IWorkbook workbook, if (targetParent != null) { commands.add(new ModifyImageSourceCommand(targetParent, image.getSource())); - commands.add(new ModifyImageSizeCommand(targetParent, image - .getWidth(), image.getHeight())); + commands.add(new ModifyImageSizeCommand(targetParent, + image.getWidth(), image.getHeight())); commands.add(new ModifyImageAlignmentCommand(targetParent, image.getAlignment())); } @@ -203,8 +221,8 @@ protected void makeDNDCommands(Request request, IWorkbook workbook, if (countForUnbalacedStructure != 0) { IViewer viewer = request.getTargetViewer(); ITopic centralTopic = (ITopic) viewer.getAdapter(ITopic.class); - ITopicExtension extension = centralTopic - .createExtension(UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); + ITopicExtension extension = centralTopic.createExtension( + UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); ITopicExtensionElement element = extension.getContent() .getCreatedChild( UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); @@ -214,8 +232,63 @@ protected void makeDNDCommands(Request request, IWorkbook workbook, preDndRightNum = String.valueOf(0); int postDndRightNum = Integer.valueOf(preDndRightNum); commands.add(new ModifyRightNumberOfUnbalancedStructureCommand( - centralTopic, preDndRightNum, postDndRightNum - + countForUnbalacedStructure)); + 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)); + } + } } } @@ -233,8 +306,8 @@ private int modifyRightNumeberForUnbalancedStructure(Request request, .equalsIgnoreCase(centralTopicStructure); if (isUnbalancedStructure) { - ITopicExtension extension = centralTopic - .createExtension(UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); + ITopicExtension extension = centralTopic.createExtension( + UnbalancedData.EXTENTION_UNBALANCEDSTRUCTURE); ITopicExtensionElement element = extension.getContent() .getCreatedChild( UnbalancedData.EXTENTIONELEMENT_RIGHTNUMBER); @@ -249,11 +322,9 @@ private int modifyRightNumeberForUnbalancedStructure(Request request, 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) { + if (bounds.getCenter() + .getDifference((Point) request.getParameter( + GEF.PARAM_POSITION_ABSOLUTE)).width < 0) { count++; } } else if (postDndRightNum <= 2) { 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 new file mode 100644 index 000000000..5799171cd --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DeleteResourceHandler.java @@ -0,0 +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); + } + +} 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 new file mode 100644 index 000000000..9ce011baa --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DialogPartHandler.java @@ -0,0 +1,148 @@ +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; + } + +} 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 new file mode 100644 index 000000000..71f1e40ca --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/DuplicateResourceHandler.java @@ -0,0 +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); + } + +} 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 new file mode 100644 index 000000000..290db64c0 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/EditResourceHandler.java @@ -0,0 +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); + } + +} 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 new file mode 100644 index 000000000..7c626f2b9 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/ModelPartHandler.java @@ -0,0 +1,91 @@ + +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; + } +} 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 7ab9c6c60..7d576ae93 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 @@ -5,6 +5,7 @@ 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 { @@ -14,6 +15,8 @@ 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( 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 new file mode 100644 index 000000000..36a169443 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenLocalFileHandler.java @@ -0,0 +1,69 @@ +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 new file mode 100644 index 000000000..77bc967a6 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/OpenPopoverHandler.java @@ -0,0 +1,86 @@ +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; + } + +} 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 5f1c3685a..53f85bbac 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 @@ -18,6 +18,7 @@ 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; @@ -59,6 +60,8 @@ public static void execute(IWorkbenchWindow window, List uris) { if (uri != null) { IEditorPart editor = openMindMapEditor(page, uri); if (editor != null) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("OpenWorkbookCount"); //$NON-NLS-1$ lastEditor = editor; } } 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 new file mode 100644 index 000000000..8ac554104 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/RenameResourceHandler.java @@ -0,0 +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); + } + +} 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 1687842fc..cb1adade4 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 @@ -42,15 +42,20 @@ 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; @@ -71,7 +76,7 @@ public void execute( @Named(IServiceConstants.ACTIVE_SELECTION) Object selection, @Optional IProgressService progressProvider, final @Optional IServiceLocator serviceLocator) - throws InvocationTargetException { + throws InvocationTargetException { if (selection instanceof IStructuredSelection) { selection = ((IStructuredSelection) selection).getFirstElement(); } @@ -97,7 +102,6 @@ public T getContextVariable(Class key) { } /** - * * @param context * the context where this operation happens * @param workbookRef @@ -112,12 +116,11 @@ public T getContextVariable(Class key) { * @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 { + throws InvocationTargetException { Assert.isLegal(context != null); Shell shell = context.getContextVariable(Shell.class); @@ -245,23 +248,23 @@ public static IWorkbookRef saveWorkbookAs(ISaveContext context, MessageDialog dialog = new MessageDialog( - shell, + shell, - MindMapMessages.SaveWorkbookAsHandler_saveToOtherDialog_title, + MindMapMessages.SaveWorkbookAsHandler_saveToOtherDialog_title, - null, + null, - na.getMessage(), + na.getMessage(), - MessageDialog.CONFIRM, + MessageDialog.CONFIRM, - new String[] { + new String[] { - saveText, + saveText, - IDialogConstants.CANCEL_LABEL + IDialogConstants.CANCEL_LABEL - }, 0 + }, 0 ); @@ -322,7 +325,7 @@ public void run(IProgressMonitor monitor) public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - doSaveAs(monitor, workbookRef, newWorkbookRef); + doSaveAs(monitor, workbookRef, newWorkbookRef, 0); } }); } catch (InterruptedException e) { @@ -337,18 +340,74 @@ public void run(IProgressMonitor monitor) private static void doSaveAs(final IProgressMonitor monitor, final IWorkbookRef oldWorkbookRef, - final IWorkbookRef newWorkbookRef) - throws InterruptedException, InvocationTargetException { + final IWorkbookRef newWorkbookRef, int times) { SubMonitor subMonitor = SubMonitor.convert(monitor, 100); - oldWorkbookRef.open(subMonitor.newChild(15)); 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); - oldWorkbookRef.close(subMonitor.newChild(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(); 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 new file mode 100644 index 000000000..e8700aef9 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/SetDefaultThemeHandler.java @@ -0,0 +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; + } + +} 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 new file mode 100644 index 000000000..d93f841cb --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4handlers/ToggleModelPartHandler.java @@ -0,0 +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; + } + +} 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 new file mode 100644 index 000000000..9fd574093 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/CommentsPart.java @@ -0,0 +1,771 @@ +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); + } + +} 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 new file mode 100644 index 000000000..43c8687d1 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/IModelConstants.java @@ -0,0 +1,88 @@ +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$ +} 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 new file mode 100644 index 000000000..5e246f3c1 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ImagePart.java @@ -0,0 +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$ + +} 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 new file mode 100644 index 000000000..572e01d7d --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/LocalImageModelPage.java @@ -0,0 +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; + } + +} 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 new file mode 100644 index 000000000..62f2e4876 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/LocalImageProcessor.java @@ -0,0 +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); + } + +} 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 new file mode 100644 index 000000000..3c73e4ca6 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/MarkerPart.java @@ -0,0 +1,757 @@ +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); + } + } + }); + } + } + +} 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 new file mode 100644 index 000000000..ef230695f --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/NotesPart.java @@ -0,0 +1,1220 @@ +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/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); + } + +} 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 new file mode 100644 index 000000000..87aa0f04b --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ProgressProcessor.java @@ -0,0 +1,145 @@ +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; + } + +} 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 new file mode 100644 index 000000000..cdca94e55 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/e4models/ThemesPart.java @@ -0,0 +1,324 @@ +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)); + } + }); + } + +} 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 9604ac257..80e6de538 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 @@ -16,6 +16,8 @@ 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; @@ -40,7 +42,9 @@ 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; @@ -48,12 +52,12 @@ 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 @@ -75,12 +79,11 @@ * the default behavior.
    • *
    * - * * @author Frank Shaka * @since 3.6.50 */ public abstract class AbstractWorkbookRef extends Editable - implements IWorkbookRef, ISchedulingRule { + implements IWorkbookRef, ISchedulingRule, IPropertyChangeListener { protected static final int TEMP_SAVING_DELAY = 500; @@ -114,6 +117,12 @@ protected AbstractWorkbookRef(URI uri, IMemento state) { 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; @@ -123,7 +132,6 @@ protected AbstractWorkbookRef(URI uri, IMemento state) { /* * (non-Javadoc) - * * @see org.xmind.ui.mindmap.IWorkbookRef#getSaveWizardId() */ @Override @@ -178,7 +186,6 @@ private void registerGlobalEvents(CoreEventRegister register, register.register(Core.MarkerRefAdd); register.register(Core.PasswordChange); - register.register(Core.WorkbookPreSave); } } @@ -188,8 +195,6 @@ private void handleGlobalEvent(CoreEvent event) { handleMarkerAdded((String) event.getTarget()); } else if (Core.PasswordChange.equals(type)) { scheduleTempSaving(); - } else if (Core.WorkbookPreSave.equals(type)) { - checkDirty(); } } @@ -272,7 +277,7 @@ protected IWorkbook doLoadWorkbook(IProgressMonitor monitor) protected IWorkbook doLoadWorkbookFromTempStorage(IProgressMonitor monitor, IStorage tempStorage) - throws InterruptedException, InvocationTargetException { + throws InterruptedException, InvocationTargetException { try { IDeserializer deserializer = Core.getWorkbookBuilder() .newDeserializer(); @@ -320,6 +325,9 @@ protected void doSave(IProgressMonitor monitor) } if (workbookAsEventSource != null) { + workbookAsEventSource.getCoreEventSupport().dispatch( + workbookAsEventSource, new CoreEvent(workbookAsEventSource, + Core.WorkbookPreSaveOnce, null)); workbookAsEventSource.getCoreEventSupport().dispatch( workbookAsEventSource, new CoreEvent(workbookAsEventSource, Core.WorkbookPreSave, null)); @@ -339,7 +347,7 @@ workbookAsEventSource, new CoreEvent(workbookAsEventSource, /// subclasses may override to prevent default behavior or add custom behaviors protected void doSaveWorkbookToTempStorage(IProgressMonitor monitor, IWorkbook workbook) - throws InterruptedException, InvocationTargetException { + throws InterruptedException, InvocationTargetException { try { ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); serializer.setWorkbook(workbook); @@ -391,7 +399,7 @@ protected void doSaveWorkbookToTempStorage(IProgressMonitor monitor, */ protected void doSaveWorkbookToURI(IProgressMonitor monitor, IWorkbook workbook, URI uri) - throws InterruptedException, InvocationTargetException { + throws InterruptedException, InvocationTargetException { throw new UnsupportedOperationException(); } @@ -420,14 +428,14 @@ protected void doClose(IProgressMonitor monitor) /// subclasses may override to prevent default behavior or add custom behaviors protected void doUnloadWorkbook(IProgressMonitor monitor, IWorkbook workbook) - throws InterruptedException, InvocationTargetException { + 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 { + throws InterruptedException, InvocationTargetException { IStorage storage = (IStorage) workbook.getAdapter(IStorage.class); if (storage != null) { storage.clear(); @@ -499,7 +507,6 @@ protected void doImportFrom(IProgressMonitor monitor, IWorkbookRef source) /* * (non-Javadoc) - * * @see * org.xmind.ui.mindmap.IWorkbookRef#getPreviewImageData(java.lang.String, * org.xmind.ui.internal.editor.MindMapPreviewOptions) @@ -583,7 +590,7 @@ protected void saveState(IMemento memento) { public boolean isDirty() { return super.isDirty() || (workbook instanceof ICoreEventSource2 && ((ICoreEventSource2) workbook) - .hasOnceListeners(Core.WorkbookPreSave)); + .hasOnceListeners(Core.WorkbookPreSaveOnce)); } protected IMindMapPreviewGenerator findPreviewGenerator() { @@ -592,7 +599,6 @@ protected IMindMapPreviewGenerator findPreviewGenerator() { /* * (non-Javadoc) - * * @see org.xmind.gef.ui.editor.Editable#getService(java.lang.Class) */ @Override @@ -610,7 +616,6 @@ protected WorkbookRefEncryptable createEncryptable() { /* * (non-Javadoc) - * * @see * org.eclipse.core.runtime.jobs.ISchedulingRule#contains(org.eclipse.core. * runtime.jobs.ISchedulingRule) @@ -622,7 +627,6 @@ public boolean contains(ISchedulingRule rule) { /* * (non-Javadoc) - * * @see * org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse. * core.runtime.jobs.ISchedulingRule) @@ -634,7 +638,6 @@ public boolean isConflicting(ISchedulingRule rule) { /* * (non-Javadoc) - * * @see * org.xmind.gef.ui.editor.Editable#doHandleCommandStackChange(org.xmind.gef * .command.CommandStackEvent) @@ -751,4 +754,17 @@ 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/ClonedWorkbookRef.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ClonedWorkbookRef.java index 8d3ce7c53..d24ea9cd8 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 @@ -19,7 +19,6 @@ import org.xmind.ui.mindmap.IWorkbookRef; /** - * * @author Frank Shaka * @since 3.6.50 */ @@ -44,7 +43,16 @@ private static URI getSourceWorkbookURI(URI uri) { @Override public String getName() { - return null; + 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 @@ -79,12 +87,11 @@ protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) private IWorkbook doCloneWorkbook(IProgressMonitor monitor, IWorkbook sourceWorkbook) - throws InterruptedException, InvocationTargetException { + throws InterruptedException, InvocationTargetException { try { IWorkbook workbook = Core.getWorkbookBuilder() .createWorkbook(getTempStorage()); - ISerializer serializer = Core.getWorkbookBuilder() - .newSerializer(); + ISerializer serializer = Core.getWorkbookBuilder().newSerializer(); serializer.setWorkbook(workbook); serializer.setWorkbookStorageAsOutputTarget(); serializer.setEntryStreamNormalizer(getEncryptionHandler()); 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 new file mode 100644 index 000000000..5adcc85a2 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DecryptionDialog.java @@ -0,0 +1,235 @@ +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); + } + +} 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 new file mode 100644 index 000000000..c52152658 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/DefaultEditorLayout.java @@ -0,0 +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; + } + +} 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 217535ce4..fbb03ed78 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 @@ -14,11 +14,12 @@ 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 @@ -33,6 +34,8 @@ public final class EditorHistoryImpl implements IEditorHistory, IDisposable { private final Map inputToThumbnail; + private final Map editorHistoryItems; + private final ListenerList listeners; public EditorHistoryImpl(IEditorHistoryLoader loader) { @@ -41,6 +44,7 @@ public EditorHistoryImpl(IEditorHistoryLoader loader) { this.pinnedInputURIs = new ArrayList(); this.inputToThumbnail = new HashMap(); this.listeners = new ListenerList(); + this.editorHistoryItems = new HashMap(); init(); } @@ -61,6 +65,13 @@ public void pinnedInputURILoaded(URI inputURI) { 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); @@ -106,6 +117,9 @@ 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); @@ -146,6 +160,8 @@ public void remove(URI inputURI) { //REMOVE THUMBNAIL removeThumbnail(inputURI); + removeEditorHistoryItem(inputURI); + if (oldPinnedSize != pinnedInputURIs.size() || oldUnpinnedSize != unpinnedInputURIs.size()) { fireChanged(); @@ -167,6 +183,7 @@ public void clear() { int oldSize = unpinnedInputURIs.size(); for (URI unpinnedInputURI : unpinnedInputURIs) { removeThumbnail(unpinnedInputURI); + removeEditorHistoryItem(unpinnedInputURI); } unpinnedInputURIs.clear(); if (oldSize != unpinnedInputURIs.size()) { @@ -193,13 +210,49 @@ public void saveThumbnailData(URI inputURI, InputStream thumbnailData) 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); @@ -238,7 +291,6 @@ public void run() throws Exception { /* * (non-Javadoc) - * * @see org.eclipse.ui.services.IDisposable#dispose() */ @Override 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 1221f5696..baca18c1b 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,12 +1,14 @@ 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.FileWriter; 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; @@ -21,13 +23,14 @@ 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 @@ -39,6 +42,10 @@ public class EditorHistoryPersistenceHelper 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$ @@ -56,6 +63,7 @@ private static class EditorHistoryState { private final URI[] unpinnedInputURIs; private final URI[] pinnedInputURIs; private final Map thumbnailURIs; + private final Map editorHistoryItems; /** * @@ -65,17 +73,25 @@ private EditorHistoryState(EditorHistoryImpl 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); } } @@ -108,6 +124,14 @@ public URI[] getUnpinnedInputURIs() { 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; @@ -150,7 +174,6 @@ public void setService(EditorHistoryImpl service) { /* * (non-Javadoc) - * * @see org.xmind.ui.internal.editor.IEditorHistoryLoader#load(org.xmind.ui. * internal.editor.IEditorHistoryLoader.IEditorHistoryLoaderCallback) */ @@ -162,6 +185,10 @@ public void load(IEditorHistoryLoaderCallback callback) { 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); @@ -176,10 +203,25 @@ public void load(IEditorHistoryLoaderCallback callback) { 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, @@ -193,6 +235,11 @@ public void load(IEditorHistoryLoaderCallback callback) { 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, @@ -213,13 +260,19 @@ private String fixFileUri(String uri) { 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) @@ -256,7 +309,6 @@ private File getThumbnailDir() { /* * (non-Javadoc) - * * @see org.xmind.ui.internal.editor.IEditorHistoryLoader#dispose() */ @Override @@ -332,6 +384,14 @@ private void save(EditorHistoryState persistable) { 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) @@ -346,6 +406,14 @@ private void save(EditorHistoryState persistable) { 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) @@ -360,12 +428,14 @@ private void save(EditorHistoryState persistable) { file.getParentFile().mkdirs(); } try { - FileWriter writer = new FileWriter(file); + OutputStreamWriter out = new OutputStreamWriter( + new FileOutputStream(file), "UTF-8"); //$NON-NLS-1$ +// FileWriter writer = new FileWriter(file); try { - repository.store(writer, + repository.store(out, "Generated by org.xmind.ui.internal.editor.EditorHistoryService"); //$NON-NLS-1$ } finally { - writer.close(); + out.close(); } } catch (IOException e) { Logger.log(e, "Failed to save workbook history to " //$NON-NLS-1$ @@ -386,7 +456,9 @@ public Properties load() { File file = getHistoryFile(); if (file != null && file.exists()) { try { - FileReader reader = new FileReader(file); + InputStreamReader reader = new InputStreamReader( + new FileInputStream(file), "UTF-8"); //$NON-NLS-1$ +// FileReader reader = new FileReader(file); try { repository.load(reader); } finally { 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 d841391d1..4d7d539c4 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 @@ -6,9 +6,9 @@ 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 */ @@ -57,6 +57,16 @@ public void saveThumbnailData(URI inputURI, InputStream thumbnailData) 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); } 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 new file mode 100644 index 000000000..60b6e7918 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EditorLayoutManager.java @@ -0,0 +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()); + } + +} 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 new file mode 100644 index 000000000..44c33aea5 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/EncryptionDialog.java @@ -0,0 +1,464 @@ +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(); + } + }); + } + +} 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 new file mode 100644 index 000000000..015e44fee --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/ErrorDialog.java @@ -0,0 +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; + } + +} 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 777060c14..085fe7893 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 @@ -20,9 +20,10 @@ import java.io.InputStream; import java.net.URI; +import org.xmind.ui.editor.IEditorHistoryItem; + /** * @author Frank Shaka - * */ public interface IEditorHistoryLoader { @@ -34,6 +35,8 @@ public interface IEditorHistoryLoaderCallback { void thumbnailURILoaded(URI inputURI, URI thumbnailURI); + void editorHistoryItemsLoaded(URI inputURI, IEditorHistoryItem item); + } void load(IEditorHistoryLoaderCallback callback); 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 new file mode 100644 index 000000000..17a83d139 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorLayout.java @@ -0,0 +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(); + +} 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 new file mode 100644 index 000000000..f830690c1 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IEditorLayoutManager.java @@ -0,0 +1,14 @@ +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 4ca463160..17811fb66 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 @@ -25,6 +25,10 @@ */ public interface IEncryptable { + String getPasswordHint(); + + String getPassword(); + /** * Sets the password to be the given one. * @@ -34,6 +38,14 @@ public interface IEncryptable { */ 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. * 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 new file mode 100644 index 000000000..94f45a4fd --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IWorkbookReferrer.java @@ -0,0 +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); + +} 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 new file mode 100644 index 000000000..94720ec93 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/IWorkbookSaver.java @@ -0,0 +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; + +} 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 6788a5cfe..a60b881df 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 @@ -29,6 +29,7 @@ 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; @@ -63,8 +64,10 @@ 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.views.BlackBoxView; +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; @@ -74,7 +77,6 @@ import org.xmind.ui.util.Logger; /** - * * @author Frank Shaka * @since 3.6.50 */ @@ -159,7 +161,6 @@ private class LocalFileErrorSupportProvider /* * (non-Javadoc) - * * @see org.eclipse.ui.statushandlers.AbstractStatusAreaProvider# * createSupportArea(org.eclipse.swt.widgets.Composite, * org.eclipse.ui.statushandlers.StatusAdapter) @@ -217,16 +218,25 @@ public void linkActivated(HyperlinkEvent e) { private void showBlackBoxView() { final File damagedFile = getFile(); if (PlatformUI.isWorkbenchRunning()) { - IWorkbenchWindow window = PlatformUI.getWorkbench() + 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 { - BlackBoxView blackBoxView = (BlackBoxView) page - .showView(MindMapUI.VIEW_BLACKBOX); - blackBoxView.setDamagedFile(damagedFile); + 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); + } } }); } @@ -253,7 +263,6 @@ protected LocalFileWorkbookRef(URI uri, IMemento memento) { /* * (non-Javadoc) - * * @see * org.xmind.ui.internal.editor.AbstractWorkbookRef#getAdapter(java.lang. * Class) @@ -268,7 +277,6 @@ public T getAdapter(Class adapter) { /* * (non-Javadoc) - * * @see org.xmind.ui.internal.editor.AbstractWorkbookRef#getSaveWizardId() */ @Override @@ -332,7 +340,6 @@ public boolean canImportFrom(IWorkbookRef source) { /* * (non-Javadoc) - * * @see org.xmind.gef.ui.editor.Editable#getModificationTime() */ @Override @@ -357,7 +364,12 @@ protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) stream = new FileInputStream(file); deserializer.setInputStream(stream); } - deserializer.deserialize(new ProgressReporter(monitor)); + 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(); @@ -381,14 +393,14 @@ protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) @Override protected void doSaveWorkbookToURI(IProgressMonitor monitor, IWorkbook workbook, URI uri) - throws InterruptedException, InvocationTargetException { + 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 { + throws InterruptedException, InvocationTargetException { final Set encryptionIgnoredEntries = new HashSet(); boolean previewSaved = false; @@ -441,6 +453,17 @@ protected void doSaveWorkbookToURIFromSource(IProgressMonitor monitor, 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 { @@ -484,7 +507,7 @@ protected void doSaveWorkbookToURIFromSource(IProgressMonitor monitor, */ private void savePreviewImage(IWorkbook workbook, final Set encryptionIgnoredEntries) - throws InvocationTargetException { + throws InvocationTargetException { IMindMapPreviewGenerator previewGenerator = findPreviewGenerator(); if (previewGenerator != null) { ImageFormat previewFormat = ImageFormat.PNG; @@ -571,9 +594,12 @@ protected void doImportFrom(IProgressMonitor monitor, IWorkbookRef source) IEncryptable sourceEncryptable = source.getAdapter(IEncryptable.class); if (sourceEncryptable != null && sourceEncryptable.hasPassword() && sourceEncryptable instanceof WorkbookRefEncryptable) { +// getEncryptable() +// .setEncryptor(((WorkbookRefEncryptable) sourceEncryptable) +// .getEncryptor()); + getEncryptable().setPassword(sourceEncryptable.getPassword()); getEncryptable() - .setEncryptor(((WorkbookRefEncryptable) sourceEncryptable) - .getEncryptor()); + .setPasswordHint(sourceEncryptable.getPasswordHint()); } doClearTempStorageBeforeImport(subMonitor.newChild(5), storage); @@ -595,7 +621,7 @@ protected void doImportFrom(IProgressMonitor monitor, IWorkbookRef source) protected void doClearTempStorageBeforeImport(IProgressMonitor monitor, IStorage storage) - throws InterruptedException, InvocationTargetException { + throws InterruptedException, InvocationTargetException { storage.clear(); } @@ -606,7 +632,7 @@ protected void doClearTempStorageAfterImport(IProgressMonitor monitor, protected IWorkbook doCloneWorkbookForImport(IProgressMonitor monitor, IWorkbook sourceWorkbook, URI sourceURI, IStorage storage) - throws InterruptedException, InvocationTargetException { + throws InterruptedException, InvocationTargetException { try { IWorkbook workbook = Core.getWorkbookBuilder() .createWorkbook(storage); 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 b1b7f1532..f0c1488dc 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 @@ -8,11 +8,6 @@ import org.xmind.ui.mindmap.IWorkbookRef; import org.xmind.ui.mindmap.IWorkbookRefFactory; -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ public class LocalFileWorkbookRefFactory implements IWorkbookRefFactory { private Map reversedCache = new WeakHashMap(); @@ -25,7 +20,7 @@ public IWorkbookRef createWorkbookRef(URI uri, IMemento state) { return null; for (IWorkbookRef wr : reversedCache.keySet()) { - if (uri.equals(wr.getURI()) && !wr.isInState(IWorkbookRef.CLOSED)) + if (uri.equals(wr.getURI())) 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 903f9f2e0..aaa0fb4d8 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 @@ -345,7 +345,7 @@ public void run() throws Exception { window.getActivePage() .openEditor(MindMapUI.getEditorInputFactory() .createEditorInputForFile(new File(path)), - MindMapUI.MINDMAP_EDITOR_ID); + MindMapUI.MINDMAP_EDITOR_ID); ret[0] = true; } }); 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 d0a9639f8..f123c38c5 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 @@ -378,13 +378,27 @@ protected void deactivateHandler(IAction action) { 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()); - menu.add(deleteSheetAction); - menu.add(deleteOtherSheetAction); + + 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); @@ -392,18 +406,6 @@ public void contributeToPagePopupMenu(IMenuManager menu) { deleteSheetAction.setEnabled(true); deleteOtherSheetAction.setEnabled(true); } - menu.add(new Separator()); - IAction createSheetAction = getActionRegistry() - .getAction(MindMapActionFactory.NEW_SHEET.getId()); - menu.add(createSheetAction); - menu.add(new Separator(IWorkbenchActionConstants.NEW_EXT)); - if (isCopiedSheetAvailable()) { - menu.add(new Separator()); - menu.add(pasteSheetAction); - } - menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - - super.contributeToPagePopupMenu(menu); } private int getSheetsCountOfCurrentWorkbook() { @@ -503,4 +505,4 @@ private static String getTitle(Object ele) { return ""; //$NON-NLS-1$ } -} \ No newline at end of file +} 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 57e48efd0..368aec062 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,18 +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), + * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/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; @@ -113,6 +114,7 @@ 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; @@ -136,6 +138,7 @@ 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; @@ -287,33 +290,6 @@ public static EditorStatus getInstance() { } } - protected class MindMapEditorBackCover extends DialogPaneContainer { - - @Override - public boolean close() { - boolean ret = super.close(); - if (ret) { - if (pageBook != null && !pageBook.isDisposed()) { - pageBook.showPage(pageContainer); - if (isEditorActive()) { - MindMapEditor.this.setFocus(); - } - } - } - return ret; - } - - @Override - protected void showDialog(IDialogPane dialog) { - pageBook.showPage(getControl()); - if (isEditorActive()) { - MindMapEditor.this.setFocus(); - } - super.showDialog(dialog); - } - - } - private class MindMapEditorSelectionProvider extends MultiPageSelectionProvider { @@ -353,6 +329,8 @@ public void setSelection(ISelection selection) { private ICoreEventRegister workbookEventRegister = null; + private ICoreEventRegister globalEventRegister = null; + private MindMapPageTitleEditor pageTitleEditor = null; private PageMoveHelper pageMoveHelper = null; @@ -388,8 +366,6 @@ public T getAdapter(Class adapter) { } }; - private MindMapEditorBackCover backCover = null; - private IWordContextProvider wordContextProvider = null; private boolean skipNextPreviewImage = false; @@ -406,6 +382,8 @@ public T getAdapter(Class adapter) { private boolean ignoreFileChanged = false; + private IEditorLayoutManager layoutManager = null; + private IContextActivation toolContextActivation = null; private IContextService contextService = null; @@ -492,14 +470,11 @@ public void dispose() { IContextService cs = getSite().getService(IContextService.class); cs.deactivateContext(contextActivation); } - if (backCover != null) { - backCover.dispose(); - backCover = null; - } disposeData(); super.dispose(); deactivateFileNotifier(); workbookEventRegister = null; + globalEventRegister = null; pageTitleEditor = null; pageMoveHelper = null; findReplaceOperationProvider = null; @@ -509,6 +484,7 @@ public void dispose() { // release reference to the workbook reference object this.workbookRef = null; + layoutManager = null; } @Override @@ -551,11 +527,9 @@ protected Composite createContainerParent(Composite parent) { pageBookData.right = new FormAttachment(100, 0); pageBook.setLayoutData(pageBookData); - backCover = new MindMapEditorBackCover(); - backCover.init(getSite()); - backCover.createControl(pageBook); - 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; @@ -599,11 +573,16 @@ protected void createEditorContents() { workbookLoaded(); } else if (workbookRef != null) { final IWorkbookRef theWorkbookRef = workbookRef; - loadWorkbook(theWorkbookRef); + Display.getCurrent().asyncExec(new Runnable() { + @Override + public void run() { + loadWorkbook(theWorkbookRef, 0); + } + }); } } - private void loadWorkbook(final IWorkbookRef workbookRef) { + 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 @@ -631,7 +610,7 @@ public void run(IProgressMonitor monitor) String message = passwordTried ? MindMapMessages.MindMapEditor_passwordPrompt_message1 : MindMapMessages.MindMapEditor_passwordPrompt_message2; - openDecryptionDialog(workbookRef, message); + openDecryptionDialog(workbookRef, message, times); passwordTried = true; return; } @@ -641,8 +620,21 @@ public void run(IProgressMonitor monitor) Throwable cause = e.getTargetException(); if (cause == null) cause = e; - showError(cause, - workbookRef.getAdapter(ErrorSupportProvider.class)); + + 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 @@ -654,45 +646,30 @@ public void run(IProgressMonitor monitor) } private void openDecryptionDialog(final IWorkbookRef workbookRef, - String message) { - DecryptionDialogPane decryptionDialogPane = new DecryptionDialogPane() { - - @Override - protected boolean okPressed() { - boolean result = super.okPressed(); - - if (result) { - IEncryptable encryptable = workbookRef - .getAdapter(IEncryptable.class); - if (encryptable == null) { - /// TODO prompt error? - return result; - } - - encryptable.setPassword(getPassword()); - loadWorkbook(workbookRef); - } - - return result; - } + 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); + }; - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.editor.DecryptionDialogPane#cancelPressed() - */ - @Override - protected boolean cancelPressed() { - boolean result = super.cancelPressed(); - if (result) { - asyncClose(); - } - return result; - } - }; - decryptionDialogPane.setContent(message, false); - backCover.open(decryptionDialogPane); + protected void handleShellCloseEvent() { + super.handleShellCloseEvent(); + asyncClose(); + }; + protected void cancelPressed() { + super.cancelPressed(); + asyncClose(); + }; + }.open(); } private CoreException getCoreException(Throwable e) { @@ -724,19 +701,16 @@ private void showError(Throwable exception, MindMapMessages.LoadWorkbookJob_errorDialog_title, exception)); statusAdapter.setProperty(IStatusAdapterConstants.TIMESTAMP_PROPERTY, Long.valueOf(System.currentTimeMillis())); -// statusAdapter.setProperty(RuntimeErrorDialog.DIALOG_EXTENSION, this); -// StatusManager.getManager().handle(statusAdapter, -// StatusManager.BLOCK | StatusManager.SHOW); - ErrorDialogPane2 pane = new ErrorDialogPane2(statusAdapter, + ErrorDialog errorDialog = new ErrorDialog( + Display.getCurrent().getActiveShell(), statusAdapter, supportProvider); - pane.setCloseCallback(new Runnable() { - + errorDialog.setCloseCallback(new Runnable() { @Override public void run() { asyncClose(); } }); - backCover.open(pane); + errorDialog.open(); } protected void createActions(IActionRegistry actionRegistry) { @@ -1069,6 +1043,14 @@ public IWorkbook getWorkbook() { 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) { @@ -1097,7 +1079,7 @@ protected T getEditorAdapter(Class adapter) { } return adapter.cast(wordContextProvider); } else if (adapter == IDialogPaneContainer.class) { - return adapter.cast(backCover); +// return adapter.cast(backCover); } return super.getEditorAdapter(adapter); } @@ -1110,7 +1092,10 @@ protected void installModelListener() { workbookEventRegister.register(Core.SheetMove); workbookEventRegister.register(Core.PasswordChange); workbookEventRegister.register(Core.WorkbookPreSaveOnce); - workbookEventRegister.register(Core.SheetSettings); + + globalEventRegister = new CoreEventRegister( + workbook.getAdapter(ICoreEventSupport.class), this); + globalEventRegister.register(Core.SheetSettings); } protected void uninstallModelListener() { @@ -1118,6 +1103,10 @@ protected void uninstallModelListener() { workbookEventRegister.unregisterAll(); workbookEventRegister = null; } + if (globalEventRegister != null) { + globalEventRegister.unregisterAll(); + globalEventRegister = null; + } } public void handleCoreEvent(final CoreEvent event) { @@ -1217,11 +1206,11 @@ public void setFocus() { if (workbookRef != null) { workbookRef.setActiveContext(editingContext); } - if (backCover != null && backCover.isOpen()) { - backCover.setFocus(); - } else { - super.setFocus(); - } +// if (backCover != null && backCover.isOpen()) { +// backCover.setFocus(); +// } else { + super.setFocus(); +// } } public void openEncryptionDialog() { @@ -1229,13 +1218,9 @@ public void openEncryptionDialog() { return; final IWorkbookRef theWorkbookRef = workbookRef; - backCover.open(new EncryptionDailogPane() { - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.editor.EncryptionDailogPane#hasPassword() - */ + new EncryptionDialog(Display.getCurrent().getActiveShell()) { + @Override protected boolean hasPassword() { IEncryptable encryptable = theWorkbookRef @@ -1243,12 +1228,6 @@ protected boolean hasPassword() { return encryptable != null && encryptable.hasPassword(); } - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.editor.EncryptionDailogPane#testsPassword( - * java.lang.String) - */ @Override protected boolean testsPassword(String password) { IEncryptable encryptable = theWorkbookRef @@ -1257,25 +1236,22 @@ protected boolean testsPassword(String password) { && encryptable.testsPassword(password); } - /* - * (non-Javadoc) - * @see - * org.xmind.ui.internal.editor.EncryptionDailogPane#okPressed() - */ @Override - protected boolean okPressed() { - boolean result = super.okPressed(); - if (result) { + 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()); } } - return result; } - - }); + }.open(); } public ISelectionProvider getSelectionProvider() { @@ -1329,7 +1305,12 @@ private void workbookLoaded() { passwordTried = false; if (pageBook == null || pageBook.isDisposed()) return; - backCover.close(); + + // TODO + pageBook.showPage(pageContainer); + if (isEditorActive()) + setFocus(); + Assert.isTrue(getWorkbook() != null); createPages(); if (isEditorActive()) { @@ -1424,31 +1405,73 @@ public void run(IProgressMonitor monitor) } private void recordEditorHistory() { - if (workbookRef.getURI() != null - && "file".equalsIgnoreCase(workbookRef.getURI().getScheme())) { //$NON-NLS-1$ - editorHistory.add(workbookRef.getURI()); - IManifest manifest = getWorkbook().getManifest(); - if (manifest != null) { - IFileEntry thumbnailEntry = manifest - .getFileEntry("Thumbnails/thumbnail.png"); //$NON-NLS-1$ - if (thumbnailEntry != null) { - try { - InputStream input = thumbnailEntry.openInputStream(); - try { - editorHistory.saveThumbnailData( - workbookRef.getURI(), input); - } finally { - 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)); - } - } + + 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() { @@ -1476,6 +1499,7 @@ public void doSaveAs(boolean onlyToLocal) { recordEditorHistory(); return; } + try { runner.run(true, true, new IRunnableWithProgress() { @@ -1484,6 +1508,7 @@ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { newWorkbookRef.open(monitor); + newWorkbookRef.save(monitor); } }); } catch (InterruptedException e) { @@ -1609,18 +1634,9 @@ private void reload() { runner.run(true, true, new IRunnableWithProgress() { @Override - public void run(final IProgressMonitor monitor) + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - - safeRun(monitor, true, new IRunnableWithProgress() { - - @Override - public void run(IProgressMonitor monitor) - throws InvocationTargetException, - InterruptedException { - newWorkbookRef.open(monitor); - } - }); + newWorkbookRef.open(monitor); } }); } catch (InvocationTargetException e) { @@ -1796,6 +1812,7 @@ public void run() { } }); } + } private void runInUI(final Runnable runnable) { 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 a5346d6a7..8ec5bffe9 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 @@ -14,11 +14,6 @@ import org.xmind.ui.mindmap.IWorkbookRef; import org.xmind.ui.mindmap.MindMapUI; -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ public class MindMapEditorInput implements IEditorInput, IPersistableElement { private URI uri; @@ -78,7 +73,7 @@ public boolean exists() { } public ImageDescriptor getImageDescriptor() { - return MindMapUI.getImages().get(IMindMapImages.XMIND_ICON); + return MindMapUI.getImages().get(IMindMapImages.XMIND_FILE_ICON); } public String getName() { @@ -86,7 +81,7 @@ public String getName() { if (wr != null) { String workbookName = wr.getName(); if (workbookName == null) - return MindMapMessages.MindMapEditorInput_default_name; + return MindMapMessages.MindMapEditorInput_Workbook_Untitled_title; return workbookName; } 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 ace53e2df..89d5c939b 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 @@ -12,11 +12,6 @@ import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.mindmap.IWorkbookRef; -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ public class MindMapEditorInputFactory implements IElementFactory { public static final String ID = "org.xmind.ui.MindMapEditorInputFactory"; //$NON-NLS-1$ @@ -25,18 +20,17 @@ public class MindMapEditorInputFactory implements IElementFactory { private static final String TAG_STATE = "state"; //$NON-NLS-1$ public IAdaptable createElement(IMemento memento) { - URI uri = null; String uriString = memento.getString(TAG_URI); - if (uriString != null) { - 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; - } + 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); @@ -47,10 +41,6 @@ public IAdaptable createElement(IMemento memento) { return new MindMapEditorInput(workbookRef); } } - - if (uri == null) - return null; - return new MindMapEditorInput(uri); } 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 d86c870c1..50f0aff0e 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 @@ -23,6 +23,8 @@ 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; @@ -52,6 +54,7 @@ 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; @@ -155,8 +158,21 @@ protected IGraphicalViewer createViewer() { protected void createViewerControl(final IGraphicalViewer viewer, Composite parent) { - ((MindMapViewer) viewer).createControl(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) { @@ -253,7 +269,17 @@ protected void uninstallModelListeners(Object input) { } public void propertyChange(PropertyChangeEvent event) { - if (PrefConstants.OVERLAPS_ALLOWED.equals(event.getProperty())) { + 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(); 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 eab152bef..6f7967859 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 @@ -221,8 +221,8 @@ protected void paint(GC gc) { } 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); + gc.drawRoundRectangle(bounds.x + M, bounds.y + M, + bounds.width - W, bounds.height - W, C, C); } int h = getHMargin(); @@ -253,8 +253,10 @@ protected void paint(GC gc) { protected String getText() { if (action != null) { String text = action.getText(); - if (text != null) + if (text != null) { + text = MindMapUtils.trimSingleLine(text); return text; + } return ""; //$NON-NLS-1$ } return ">"; //$NON-NLS-1$ @@ -358,9 +360,9 @@ protected static class CrumbsBar extends Composite { private static final int SPACING = 1; - private class CrumbsBarListener implements PaintListener, - MouseListener, MouseMoveListener, MouseTrackListener, - ControlListener, DisposeListener { + private class CrumbsBarListener + implements PaintListener, MouseListener, MouseMoveListener, + MouseTrackListener, ControlListener, DisposeListener { private CrumbItem sourceItem = null; @@ -413,7 +415,8 @@ private void receiveTarget(int x, int y) { targetItem.setMouseOver(false); } targetItem = item; - if (item != null && item.isEnabled() && !item.isSeparator()) { + if (item != null && item.isEnabled() + && !item.isSeparator()) { if (sourceItem == null || item == sourceItem) { item.setMouseOver(true); } @@ -469,8 +472,8 @@ public CrumbsBar(Composite parent, int style) { addMouseMoveListener(eventHandler); addMouseTrackListener(eventHandler); addControlListener(eventHandler); - setFont(FontUtils - .getRelativeHeight(JFaceResources.DEFAULT_FONT, -1)); + setFont(FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, + -1)); } private void releaseItems() { @@ -657,12 +660,10 @@ public void update() { getPage(), t); if (i == topics.size() - 1) { action.setEnabled(false); - action - .setToolTipText(NLS - .bind( - MindMapMessages.BreadCrumb_CurrentCentral_text, - action.newCentralTopic - .getTitleText())); + action.setImageDescriptor(null); + action.setToolTipText(NLS.bind( + MindMapMessages.BreadCrumb_CurrentCentral_text, + action.newCentralTopic.getTitleText())); } bar.addItem(new CrumbItem(action)); @@ -722,4 +723,4 @@ public void dispose() { crumbs.setTraceService(null); super.dispose(); } -} \ No newline at end of file +} 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 f244420ac..9d3fafafe 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 @@ -7,11 +7,6 @@ import org.xmind.gef.ui.editor.GraphicalEditorPagePopupPreviewHelper; import org.xmind.gef.ui.editor.IGraphicalEditor; -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ public class MindMapEditorPagePopupPreviewHelper extends GraphicalEditorPagePopupPreviewHelper { 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 a6b9508b8..355cc8ae7 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 @@ -24,8 +24,11 @@ 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); } @@ -33,6 +36,9 @@ 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); } @@ -42,7 +48,12 @@ public void dispose() { zoomContribution.dispose(); zoomContribution = null; } + + if (overviewCheckContribution != null) { + overviewCheckContribution.dispose(); + overviewCheckContribution = null; + } super.dispose(); } -} \ No newline at end of file +} 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 90cdd7fbc..4ab91e35f 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 @@ -61,12 +61,18 @@ public void handleEvent(Event 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)); + } + } } /** 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 6ce9c5e7a..0d0d8bf13 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 @@ -18,7 +18,7 @@ /** * @author Frank Shaka - * @since 3.6.50 + * */ public class MindMapPreviewOptions { 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 new file mode 100644 index 000000000..94abd1b96 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/OverviewCheckContribution.java @@ -0,0 +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); + } + +} 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 97ea1f936..b17f5dcfb 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 @@ -76,7 +76,7 @@ protected IWorkbook doLoadWorkbookFromURI(IProgressMonitor monitor, URI uri) @Override protected IWorkbook doLoadWorkbookFromTempStorage(IProgressMonitor monitor, IStorage tempStorage) - throws InterruptedException, InvocationTargetException { + throws InterruptedException, InvocationTargetException { IWorkbook workbook = super.doLoadWorkbookFromTempStorage(monitor, tempStorage); 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 8018c10d8..717a66763 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 @@ -19,11 +19,6 @@ import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.wizards.ISaveWizard; -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ public class SaveWizardManager implements IRegistryEventListener { public static class SaveWizardDescriptor { 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 92e5757d9..c960f2da5 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 @@ -6,11 +6,6 @@ import org.xmind.ui.mindmap.IWorkbookRef; import org.xmind.ui.mindmap.IWorkbookRefFactory; -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ public class TempWorkbookRefFactory implements IWorkbookRefFactory { public static final String URI_SCHEME = "xmind-temp"; //$NON-NLS-1$ 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 49c6e1862..d72b0ba89 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 @@ -9,11 +9,6 @@ import org.eclipse.core.runtime.Assert; -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ public final class URIParser { private URIParser() { 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 9d63992e0..906572b74 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 @@ -157,7 +157,11 @@ private IWorkbook loadFromGenericURI(IProgressMonitor monitor, URI uri) deserializer.setWorkbookStorage(getTempStorage()); deserializer.setEntryStreamNormalizer(getEncryptionHandler()); deserializer.setInputStream(stream); - deserializer.deserialize(new ProgressReporter(monitor)); + 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(); 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 new file mode 100644 index 000000000..d80a115ba --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookBackupManager.java @@ -0,0 +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; + } + +} 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 new file mode 100644 index 000000000..486b7637d --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/editor/WorkbookRef.java @@ -0,0 +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; + } + } + +} 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 b48f12669..aa9910442 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 @@ -28,6 +28,7 @@ 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 @@ -59,7 +60,6 @@ public IEntryStreamNormalizer getDelegate() { /* * (non-Javadoc) - * * @see * org.xmind.core.IEntryStreamNormalizer#normalizeOutputStream(java.io. * OutputStream, org.xmind.core.IFileEntry) @@ -72,7 +72,6 @@ public OutputStream normalizeOutputStream(OutputStream stream, /* * (non-Javadoc) - * * @see * org.xmind.core.IEntryStreamNormalizer#normalizeInputStream(java.io. * InputStream, org.xmind.core.IFileEntry) @@ -99,7 +98,6 @@ public InputStream normalizeInputStream(InputStream stream, /* * (non-Javadoc) - * * @see java.lang.Object#equals(java.lang.Object) */ @Override @@ -114,7 +112,6 @@ public boolean equals(Object obj) { /* * (non-Javadoc) - * * @see java.lang.Object#hashCode() */ @Override @@ -128,6 +125,10 @@ public int hashCode() { private IEntryStreamNormalizer encryptor; + private String password; + + private String passwordHint; + /** * */ @@ -139,12 +140,14 @@ public WorkbookRefEncryptable(AbstractWorkbookRef 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)) @@ -158,11 +161,31 @@ public void setPassword(String newPassword) { 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) @@ -181,7 +204,6 @@ private static boolean encryptorEquals(IEntryStreamNormalizer oldEncryptor, /* * (non-Javadoc) - * * @see org.xmind.ui.internal.editor.IEncryptable#hasPassword() */ @Override 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 627721dc3..f5b71fc57 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 @@ -27,11 +27,6 @@ import org.xmind.ui.mindmap.IWorkbookRefFactory; import org.xmind.ui.mindmap.MindMapUI; -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ public class WorkbookRefFactoryManager implements IWorkbookRefFactory, IRegistryEventListener { @@ -99,14 +94,9 @@ public WorkbookRefFactoryManager() { public synchronized IWorkbookRef createWorkbookRef(URI uri, IMemento state) { - if (uri == null && state != null) { - return PreLoadedWorkbookRef.createFromSavedState(state); - } - IWorkbookRefFactory factory = getWorkbookRefFactoryForURI(uri); if (factory != null) return factory.createWorkbookRef(uri, state); - return URLWorkbookRef.create(uri, state); } 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 8e06ae899..6b03e07e7 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 @@ -5,19 +5,17 @@ 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; -/** - * - * @author Frank Shaka - * @since 3.6.50 - */ 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() { } @@ -38,6 +36,14 @@ public boolean test(Object receiver, String property, Object[] args, 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$ 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 fb85d2dae..65d5d5d80 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,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/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; @@ -42,6 +39,7 @@ 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; @@ -306,6 +304,11 @@ private void modifyNumbering(Request request) { 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; @@ -581,4 +584,4 @@ private String getModifyTitleTextLabel(List ts) { return CommandMessages.Command_ModifyTitle; } -} \ 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 ac0b81426..fdc5ae58d 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 @@ -45,7 +45,6 @@ import org.xmind.ui.internal.dialogs.DialogMessages; /** - * * @author Karelun Huang */ public class SortTopicCommandBuilder extends DeleteCommandBuilder { @@ -76,6 +75,8 @@ public boolean equals(Object obj) { private List cacheRelations = null; + private Map cacheSummaryTopics = null; + public SortTopicCommandBuilder(IViewer viewer, ICommandStack commandStack) { super(viewer, commandStack); } @@ -236,7 +237,7 @@ private void addTopicRanges(ITopic parent) { Range range = entry.getValue(); if (topicRange instanceof ISummary) { ISummary summary = (ISummary) topicRange; - ITopic summaryTopic = summary.getTopic(); + ITopic summaryTopic = cacheSummaryTopics.get(summary); AddTopicCommand addTopicCommand = new AddTopicCommand( summaryTopic, parent, -1, ITopic.SUMMARY); add(addTopicCommand, false); @@ -261,6 +262,8 @@ private void addTopicRanges(ITopic parent) { 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(); @@ -283,7 +286,9 @@ private void cacheTopicRanges(ITopic parent) { 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); } } } 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 1ef103efd..254833615 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 @@ -33,6 +33,7 @@ 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; @@ -569,9 +570,12 @@ private Command createAddImageCommand(IWorkbook workbook, String path, private Dimension getImageSize(String path) { try { Image tempImage = new Image(Display.getCurrent(), path); - Rectangle size = tempImage.getBounds(); + Rectangle imageBounds = tempImage.getBounds(); tempImage.dispose(); - return Geometry.getScaledConstrainedSize(size.width, size.height, + 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) { } @@ -723,6 +727,9 @@ private void createTopic(Request request) { MindMapUtils.getTopics(request.getTargets()), null); sort(topics); + if (!topics.isEmpty()) + sourceTopic = topics.get(0); + builder = new CreateTopicCommandBuilder(viewer, request.getTargetCommandStack(), sourceTopic, reqType, topics); 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 8499c74af..0dae616c4 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 @@ -3,9 +3,7 @@ import java.util.ArrayList; import java.util.List; -import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.swt.graphics.Font; import org.xmind.gef.draw2d.RotatableWrapLabel; @@ -88,7 +86,7 @@ private String[] forceSplitText(String theText, Font f, double wHint) { wHint = wHint - 5; List buffer = new ArrayList(); theText = theText.trim(); - if (getLooseTextSize(theText, f).width < wHint) { + if (getShowLooseTextSize(theText, f).width < wHint) { buffer.add(theText); return buffer.toArray(new String[buffer.size()]); } @@ -100,7 +98,7 @@ private String[] forceSplitText(String theText, Font f, double wHint) { if (lines[i].equals(NULLSTR)) { lines[i] = ONESPACE; } - if (getLooseTextSize(lines[i], f).width >= wHint) { + if (getShowLooseTextSize(lines[i], f).width >= wHint) { if (cachedString.trim() != NULLSTR) { buffer.add(cachedString.trim()); cachedString = NULLSTR; @@ -110,7 +108,7 @@ private String[] forceSplitText(String theText, Font f, double wHint) { continue; } appendString = cachedString + lines[i]; - if (getLooseTextSize(appendString, f).width >= wHint) { + if (getShowLooseTextSize(appendString, f).width >= wHint) { if (cachedString.trim() != NULLSTR) { buffer.add(cachedString.trim()); } @@ -133,11 +131,11 @@ private String truncate(String s, List buffer, double wHint, while (wHint > 0 && !token.equals(NULLSTR)) { boolean isLastSnip = true; String current = token; - while (getLooseTextSize(current, f).width >= wHint) { + while (getShowLooseTextSize(current, f).width >= wHint) { isLastSnip = false; current = current.substring(0, current.length() - 1); } - if (getLooseTextSize(current, f).width < wHint && !isLastSnip) { + if (getShowLooseTextSize(current, f).width < wHint && !isLastSnip) { buffer.add(token.substring(0, current.length()).trim()); token = token.substring(current.length()); } else @@ -155,31 +153,13 @@ private String getForceSplitText(String[] lines) { return sb.toString(); } - protected void paintText(Graphics graphics, String text, - PrecisionRectangle textArea, Font f) { - float textWidth = (float) textArea.width - PADDING * 2; - float y = (float) textArea.y + PADDING; - final int wrapAlignment = getTextAlignment(); - - float x = (float) textArea.x + PADDING; - Dimension tokenSize = getLooseTextSize(text, f); - float tokenWidth = tokenSize.width; - float tokenHeight = tokenSize.height; - - switch (wrapAlignment) { - case PositionConstants.CENTER: - x += (textWidth - tokenWidth) / 2; - break; - case PositionConstants.RIGHT: - x += textWidth - tokenWidth - H_MARGIN; - break; - } - - paintText(graphics, text, x + H_MARGIN / 2, y + V_MARGIN / 2, - tokenWidth, tokenHeight, f); + private Dimension getShowLooseTextSize(String s, Font f) { + int textCase = getTextCase(); + s = getShowText(s, textCase); + return getLooseTextSize(s, f); } - public BoundaryFigure getBoundary() { + private BoundaryFigure getBoundary() { return boundary; } 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 c9e9d8d54..2a7b71606 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 @@ -43,7 +43,6 @@ public class LegendItemFigure extends Figure implements ITitledFigure { public LegendItemFigure(int textRenderStyle, LocalResourceManager resourceManager) { - System.out.println("figure " + resourceManager == null); if (resourceManager != null) { svgIcon = new SVGImageFigure(); svgIcon.setManager(resourceManager); 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 e0f7feab3..f7f1ca7d8 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 @@ -18,6 +18,7 @@ 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; @@ -29,16 +30,19 @@ 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 { + IRotatableReferencedFigure, IRelayerableFigure, ITransparentableFigure { protected static final int FLAG_MINIMIZED = MAX_FLAG << 1; protected static final int FLAG_RELAYERED = MAX_FLAG << 2; @@ -51,6 +55,9 @@ public class TopicFigure extends DecoratedShapeFigure private PrecisionRotator rotator = null; + private int selfAlpha = 0xff; + private int treeAlpha = 0xff; + public ITextFigure getTitle() { return title; } @@ -207,6 +214,72 @@ public void paint(Graphics graphics) { if (isRelayered()) return; - super.paint(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) { + 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/colorful/ColorfulSheetHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ColorfulSheetHandler.java similarity index 93% rename from bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/colorful/ColorfulSheetHandler.java rename to bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ColorfulSheetHandler.java index 200161e1e..8c1a1913b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/colorful/ColorfulSheetHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ColorfulSheetHandler.java @@ -1,4 +1,4 @@ -package org.xmind.ui.internal.colorful; +package org.xmind.ui.internal.handlers; import java.util.List; @@ -14,6 +14,7 @@ import org.xmind.gef.ui.editor.IGraphicalEditor; import org.xmind.gef.ui.editor.IGraphicalEditorPage; import org.xmind.ui.commands.MindMapCommandConstants; +import org.xmind.ui.commands.ModifySheetTabColorCommand; public class ColorfulSheetHandler extends AbstractHandler { diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/CopyStyleHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/CopyStyleHandler.java index 46dd1bfd3..55b7b624a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/CopyStyleHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/CopyStyleHandler.java @@ -20,6 +20,7 @@ import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.internal.tools.StyleCopyPasteTool; import org.xmind.ui.mindmap.IMindMap; +import org.xmind.ui.style.Styles; import org.xmind.ui.util.MindMapUtils; public class CopyStyleHandler extends AbstractHandler { @@ -57,6 +58,11 @@ private void copyStyle(IStyled element, IWorkbenchPart part) { IStyle defaultStyle = getDefaultStyle(element, part); if (defaultStyle != null) setProperties(style, defaultStyle); + + String bg = style.getProperty(Styles.Background); + if (bg != null && !"".equals(bg)) //$NON-NLS-1$ + style.setProperty(Styles.Background, ""); //$NON-NLS-1$ + IWorkbook workbook = Core.getWorkbookBuilder().createWorkbook(); IStyle importStyle = workbook.getStyleSheet().importStyle(style); tool.setSourceStyle(importStyle); diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/DeleteStyleHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/DeleteStyleHandler.java index e578fd1e0..0f10733e1 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/DeleteStyleHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/DeleteStyleHandler.java @@ -90,11 +90,11 @@ private boolean confirmDeletingStyles(Shell parentShell, } String styleNames = sb.toString(); return MessageDialog.openConfirm(parentShell, - NLS.bind(MindMapMessages.DeleteStyleHandler_MessageDialog_title, - isTheme ? MindMapMessages.DeleteStyleHandler_MessageDialog_themes - : MindMapMessages.DeleteStyleHandler_MessageDialog_styles), + NLS.bind(MindMapMessages.DeleteStyles_MessageDialog_title, + isTheme ? MindMapMessages.DeleteStyle_MessageDialog_themes + : MindMapMessages.DeleteStyle_MessageDialog_styles), NLS.bind( - MindMapMessages.DeleteStyleHandler_MessageDialog_description, + MindMapMessages.DeleteStyle_MessageDialog_description, styleNames)); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ExportMarkerHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ExportMarkerHandler.java new file mode 100644 index 000000000..aad8ed3d1 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ExportMarkerHandler.java @@ -0,0 +1,33 @@ +package org.xmind.ui.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.ui.internal.wizards.MarkerExportWizard; + +public class ExportMarkerHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); + if (window == null) + return null; + + Shell shell = window.getShell(); + if (shell == null || shell.isDisposed()) + return null; + + MarkerExportWizard wizard = new MarkerExportWizard(); + wizard.init(PlatformUI.getWorkbench(), + HandlerUtil.getCurrentStructuredSelection(event)); + WizardDialog dialog = new WizardDialog(shell, wizard); + dialog.create(); + dialog.open(); + return null; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ImportMarkerHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ImportMarkerHandler.java new file mode 100644 index 000000000..ed463ef8f --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ImportMarkerHandler.java @@ -0,0 +1,33 @@ +package org.xmind.ui.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.ui.internal.wizards.MarkerImportWizard; + +public class ImportMarkerHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); + if (window == null) + return null; + + Shell shell = window.getShell(); + if (shell == null || shell.isDisposed()) + return null; + + MarkerImportWizard wizard = new MarkerImportWizard(false); + wizard.init(PlatformUI.getWorkbench(), + HandlerUtil.getCurrentStructuredSelection(event)); + WizardDialog dialog = new WizardDialog(shell, wizard); + dialog.create(); + dialog.open(); + return null; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/MindMapHandlerUtil.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/MindMapHandlerUtil.java index 038c62914..fa6ca2d13 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/MindMapHandlerUtil.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/MindMapHandlerUtil.java @@ -1,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ /** * @@ -25,6 +22,7 @@ import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.internal.E4PartWrapper; import org.eclipse.ui.part.IContributedContentsView; import org.xmind.core.style.IStyle; import org.xmind.core.style.IStyleSheet; @@ -74,6 +72,12 @@ public static final IEditorPart findContributingEditor( if (part instanceof IEditorPart) return (IEditorPart) part; + if (part instanceof E4PartWrapper) { + IEditorPart p = HandlerUtil.getActiveEditor(event); + if (p instanceof IEditorPart) + return (IEditorPart) p; + } + IContributedContentsView contributedView = MindMapUIPlugin .getAdapter(part, IContributedContentsView.class); if (contributedView != null) { diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/OpenBlackBoxDialogHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/OpenBlackBoxDialogHandler.java new file mode 100644 index 000000000..d291ace60 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/OpenBlackBoxDialogHandler.java @@ -0,0 +1,48 @@ +package org.xmind.ui.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.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.ui.internal.dialogs.BlackBoxDialog; + +public class OpenBlackBoxDialogHandler extends AbstractHandler { + + public static final String BLACK_BOX_DIALOG_DATA_KEY = "blackBoxDialog"; //$NON-NLS-1$ + + private boolean dialogOpened = false; + + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); + if (window == null) + return null; + + Shell shell = window.getShell(); + if (shell == null || shell.isDisposed()) + return null; + + BlackBoxDialog dialog = new BlackBoxDialog(shell) { + public int open() { + dialogOpened = true; + int returnCode = super.open(); + + getShell().setData(BLACK_BOX_DIALOG_DATA_KEY, this); + return returnCode; + } + + public boolean close() { + dialogOpened = false; + getShell().setData(BLACK_BOX_DIALOG_DATA_KEY, null); + + return super.close(); + } + }; + + if (!dialogOpened) + dialog.open(); + + return null; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/PreviewRevisionHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/PreviewRevisionHandler.java index 243022201..f162bda98 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/PreviewRevisionHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/PreviewRevisionHandler.java @@ -15,6 +15,7 @@ import org.xmind.core.IWorkbook; import org.xmind.ui.internal.dialogs.RevisionPreviewDialog; +@Deprecated public class PreviewRevisionHandler extends AbstractHandler { public Object execute(ExecutionEvent event) throws ExecutionException { diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ReduceFileSizeHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ReduceFileSizeHandler.java index 4b448a766..a3526af6a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ReduceFileSizeHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ReduceFileSizeHandler.java @@ -8,6 +8,7 @@ import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.internal.dialogs.ReduceFileSizeDialog; public class ReduceFileSizeHandler extends AbstractHandler { @@ -22,6 +23,8 @@ public Object execute(ExecutionEvent event) throws ExecutionException { } private void reduceFileSize(final IEditorPart editor) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ReduceFileSizeCount"); //$NON-NLS-1$ SafeRunner.run(new SafeRunnable() { public void run() throws Exception { ReduceFileSizeDialog dialog = new ReduceFileSizeDialog(editor); diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/SaveAsTemplateHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/SaveAsTemplateHandler.java index d673cfed3..ce77c9fcf 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/SaveAsTemplateHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/SaveAsTemplateHandler.java @@ -9,6 +9,7 @@ import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.operation.IRunnableWithProgress; @@ -68,7 +69,7 @@ private void saveAsTemplate(IEditorPart editor) throws ExecutionException { private void importCustomTemplate(final Display display, final IEditorPart editor, final IWorkbook workbook, String name) - throws ExecutionException { + throws ExecutionException { if (tempFolder == null) { tempFolder = new File( Core.getWorkspace().getTempDir("transient-templates")); //$NON-NLS-1$ @@ -84,10 +85,10 @@ private void importCustomTemplate(final Display display, } catch (IOException e) { } + final IWorkbookRef tempWorkbookRef = MindMapUIPlugin.getDefault() + .getWorkbookRefFactory() + .createWorkbookRef(tempFile.toURI(), null); try { - final IWorkbookRef tempWorkbookRef = MindMapUIPlugin.getDefault() - .getWorkbookRefFactory() - .createWorkbookRef(tempFile.toURI(), null); if (tempWorkbookRef == null) return; @@ -111,6 +112,10 @@ public void run(IProgressMonitor monitor) try { tempWorkbookRef.importFrom(subMonitor.newChild(60), sourceWorkbookRef); + + /// Fix save as template, the thumbnail markers error + tempWorkbookRef.open(monitor); + tempWorkbookRef.save(monitor); } finally { sourceWorkbookRef.close(subMonitor.newChild(10)); } @@ -144,6 +149,18 @@ public void run(IProgressMonitor monitor) if (tempFile.exists()) { tempFile.delete(); } + if (tempWorkbookRef != null) { + try { + tempWorkbookRef.close(new NullProgressMonitor()); + } catch (InvocationTargetException e) { + Throwable cause = e.getTargetException(); + if (cause == null) + cause = e; + throw new ExecutionException(cause.getMessage(), cause); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } } } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/SendRequestHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/SendRequestHandler.java index 678cc4766..f55a463c1 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/SendRequestHandler.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/SendRequestHandler.java @@ -63,6 +63,7 @@ public void setInitializationData(IConfigurationElement config, } public Object execute(ExecutionEvent event) throws ExecutionException { + collectUsage(); sendRequest(this.requestType, getViewer(event)); return null; } @@ -81,4 +82,13 @@ private static void sendRequest(String requestType, IViewer viewer) { editDomain.handleRequest(requestType, viewer); } + private void collectUsage() { + if (requestType == null) + return; + if ("create_callout".equals(requestType)) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("InsertCalloutCount"); //$NON-NLS-1$ + } + } + } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowEditingHistoryHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowEditingHistoryHandler.java new file mode 100644 index 000000000..1702fc9d0 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowEditingHistoryHandler.java @@ -0,0 +1,81 @@ +package org.xmind.ui.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.core.IMeta; +import org.xmind.core.ISheet; +import org.xmind.core.IWorkbook; +import org.xmind.gef.IViewer; +import org.xmind.gef.command.Command; +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.CommandMessages; +import org.xmind.ui.commands.ModifyMetadataCommand; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.internal.dialogs.WorkbookRevisionDialog; +import org.xmind.ui.mindmap.IMindMapViewer; + +public class ShowEditingHistoryHandler extends AbstractHandler + implements IHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + IEditorPart editor = HandlerUtil.getActiveEditor(event); + if (editor == null) + return null; + if (!(editor instanceof IGraphicalEditor)) + return null; + + IViewer viewer = MindMapUIPlugin.getAdapter(editor, IViewer.class); + if (viewer == null || !(viewer instanceof IMindMapViewer)) + return null; + + Control control = viewer.getControl(); + if (control == null) + return null; + Shell shell = control.getShell(); + + WorkbookRevisionDialog dialog = new WorkbookRevisionDialog(shell, + (IGraphicalEditor) editor); + IGraphicalEditorPage page = ((IGraphicalEditor) editor) + .getActivePageInstance(); + ISheet sheet = (ISheet) page.getInput(); + IWorkbook workbook = sheet.getOwnedWorkbook(); + IMeta meta = workbook.getMeta(); + if (IMeta.V_NO + .equals(meta.getValue(IMeta.CONFIG_AUTO_REVISION_GENERATION))) { + boolean isOk = MessageDialog.openConfirm(shell, + DialogMessages.EnableRevisionDialog_Title_text, + DialogMessages.EnableRevisionDialog_Confirm_message); + if (isOk) { + enableRevision((IGraphicalEditor) editor, sheet); + } + } + dialog.open(); + return null; + } + + private void enableRevision(IGraphicalEditor editor, ISheet sheet) { + IWorkbook workbook = sheet.getOwnedWorkbook(); + Command command = new ModifyMetadataCommand(workbook, + IMeta.CONFIG_AUTO_REVISION_GENERATION, IMeta.V_YES); + command.setLabel(CommandMessages.Command_TurnOffAutoRevisionSaving); + ICommandStack commandStack = ((IGraphicalEditor) editor) + .getCommandStack(); + if (commandStack != null) { + commandStack.execute(command); + } else { + command.execute(); + } + + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowMarkerManagerHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowMarkerManagerHandler.java new file mode 100644 index 000000000..d4c5db33f --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowMarkerManagerHandler.java @@ -0,0 +1,21 @@ +package org.xmind.ui.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; + +public class ShowMarkerManagerHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); + E4Utils.showPart(IModelConstants.COMMAND_SHOW_DIALOG_PART, window, + IModelConstants.PART_ID_RESOURCE_MANAGER, + IModelConstants.PAGE_ID_RESOURCE_MANAGER_MARKER, null); + return null; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowOverviewHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowOverviewHandler.java new file mode 100644 index 000000000..d00f80a7c --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowOverviewHandler.java @@ -0,0 +1,22 @@ +package org.xmind.ui.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.preference.IPreferenceStore; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.prefs.PrefConstants; + +public class ShowOverviewHandler extends AbstractHandler { + + private IPreferenceStore ps; + + public Object execute(ExecutionEvent event) throws ExecutionException { + ps = MindMapUIPlugin.getDefault().getPreferenceStore(); + + ps.setValue(PrefConstants.SHOW_OVERVIEW, true); + + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowResourceManagerDialogHanlder.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowResourceManagerDialogHanlder.java new file mode 100644 index 000000000..d941fb65f --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowResourceManagerDialogHanlder.java @@ -0,0 +1,23 @@ +package org.xmind.ui.internal.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; + +public class ShowResourceManagerDialogHanlder extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); + if (window != null) { + E4Utils.showPart(IModelConstants.COMMAND_SHOW_DIALOG_PART, window, + IModelConstants.PART_ID_RESOURCE_MANAGER, null, null); + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowWorkbookMetaInspectorHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowWorkbookMetaInspectorHandler.java new file mode 100644 index 000000000..f13a729b7 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/handlers/ShowWorkbookMetaInspectorHandler.java @@ -0,0 +1,39 @@ +package org.xmind.ui.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.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorPart; +import org.xmind.gef.IViewer; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dialogs.WorkbookMetaInspectorDialog; +import org.xmind.ui.mindmap.IMindMapViewer; + +public class ShowWorkbookMetaInspectorHandler extends AbstractHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + final IEditorPart editor = MindMapHandlerUtil + .findContributingEditor(event); + if (editor == null) + return null; + + IViewer viewer = MindMapUIPlugin.getAdapter(editor, IViewer.class); + if (viewer == null || !(viewer instanceof IMindMapViewer)) + return null; + + Control control = viewer.getControl(); + if (control == null) + return null; + Shell shell = control.getShell(); + + WorkbookMetaInspectorDialog dialog = WorkbookMetaInspectorDialog + .getInstance(shell); + dialog.setSourceEditor(editor); + + dialog.open(); + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/layouts/TopicLayout.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/layouts/TopicLayout.java index f6ac25871..2c4b06fa0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/layouts/TopicLayout.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/layouts/TopicLayout.java @@ -380,4 +380,4 @@ public PrecisionRotator r() { return rotator; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/messages.properties b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/messages.properties index 454b6f15f..adaed7874 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/messages.properties +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/messages.properties @@ -48,10 +48,10 @@ ActualSize_text=Actual Size ActualSize_toolTip=Zoom to actual size AddComment_text=Create Comment AddComment_tooltip=Create a New Comment -AddCommentLink_text=Add Comment -AddCommentLink_tooltip=Add Comment -ModifyComment_text=Modify Comment -ModifyComment_tooltip=Modify Comment +AddCommentLink_text=Save +AddCommentLink_tooltip=Save +ModifyComment_text=Save +ModifyComment_tooltip=Save CancelHyperlink_text=Cancel Hyperlink CancelHyperlink_toolTip=Cancel hyperlink of this topic @@ -83,10 +83,10 @@ DeleteSheet_toolTip=Delete the current selected sheet DeleteSingleRevisionCommand_label=Delete Revision DeleteStyleHandler_DeleteStytles=Delete Styles DeleteStyleHandler_DeleteStytlesConfirm=Are your sure that you want to delete styles - {0} ? -DeleteStyleHandler_MessageDialog_description=Are your sure that you want to delete {0} ? -DeleteStyleHandler_MessageDialog_styles=Styles -DeleteStyleHandler_MessageDialog_themes=Themes -DeleteStyleHandler_MessageDialog_title=Delete {0} +DeleteStyle_MessageDialog_description=Are your sure that you want to delete {0} ? +DeleteStyle_MessageDialog_styles=Styles +DeleteStyle_MessageDialog_themes=Themes +DeleteStyles_MessageDialog_title=Delete {0} Delete_OtherSheets_text=Delete Other Sheets Delete_OtherSheets_toolTip=Delete other sheets DeleteComment_label=Delete Comment @@ -213,7 +213,7 @@ ShowAllComments_text=Show All Comments ShowAllComments_tooltip=Show all comments of the current map ShowAllNotes_text=Show All Notes ShowAllNotes_tooltip=Show all notes -ShowMarkerManager_text=Marker Manager +ShowMarkerManager_text=Manage Marker ShowMarkerManager_toolTip=Show marker manager ShowNextTopicComments_text=Next Topic ShowNextTopicComments_tooltip=Show comments of the next topic @@ -250,6 +250,8 @@ AllMarkersMenu_Markers_More_text=More... AllMarkersMenu_Markers_tooltip=Markers AllowOverlaps_text=Allow Overlaps AllowOverlaps_toolTip=Allow overlaps between topics +AllowManualLayout_text=Allow Free Position +AllowManualLayout_toolTip=Allow topics move freely BackgroundWorkbookSaver_SaveWorkbook_taskName=Save workbooks BackgroundWorkbookSaver_SavingWorkbook_taskNamePattern=Saving {0} BreadCrumb_CurrentCentral_text=The current central topic is ''{0}'' @@ -273,7 +275,7 @@ StylesViewer_Summary_label=Summary ThemesView_LinkWithEditor_text=Link With Editor ThemesView_LinkWithEditor_toolTip=Show the theme of the selected sheet -DefaultThemeAction_text=Default Theme +DefaultThemeAction_text=Set As Default DefaultThemeAction_toolTip=Set as default theme ThemeLabel_LoadTheme=Load Theme Preview Image: {0} @@ -293,6 +295,8 @@ RevisionsView_PreviewAction_toolTip=Preview this revision RevisionsView_RevertToRevisionAction_text=Revert To This Revision RevisionsView_RevertToRevisionAction_toolTip=Revert to this revision RevisionsView_TimeColumn_text=Time +RevisionView_DateTimeColumn_text=Date && Time +RevisionView_VersionColumn_text=Version RevisionPage_ShowDetails_message=Double click or press Spacebar on a selected revision to show its details @@ -415,7 +419,7 @@ DuplicateSheet_toolTip=Duplicate RemoveAllStyles_text=Remove All Styles RemoveAllStyles_tooltip=Remove All Styles -Comments_FirstAdd_text=Be the first to add a note +Comments_FirstAdd_text=Be the first to add a note. Comments_lable=Comments Comments_NoComments_text=There are no notes in this sheet. Comment_Delete_label=Delete @@ -425,7 +429,7 @@ Comment_Cancel_text=Cancel Comment_Cancel_tooltip=Cancel Comment_JustNow_text=Just now Comment_NoComments_text=There are no comments in this sheet. -Comment_FirstAdd_text=Be the first to add a comment +Comment_FirstAdd_text=Be the first to insert a comment. Comment_SHEET_text=SHEET: Comment_Add_text=Click to add a comment Comment_TOPIC_text=TOPIC: @@ -466,3 +470,112 @@ MultipageSetupDialog_showPlusCheck_text=Print Expand Icon: MultipageSetupDialog_showMinusCheck_text=Print Collapse Icon: WorkbookMetadata_ModifyAuthorInfo=Modify Author Info + +EditorHistoryItem_defaultName=Untitled + +SheetCommentViewer_Insert_button=Insert +SheetCommentViewer_Insert_hyperlink=Insert Comment + +BlackBoxDialog_title=Black Box + +ProgressDialog_NullContet_message=No operations to display at this time. +ProgressDialog_ShowSystem_check=Show sleeping and system operations +ProgressDialog_RemoveAll_hyperlink=Remove all finished operations + +WorkbookMetaInspectorDialog_message=Display general info and resources of the current XMind file. + +WorkbookRevisionDialog_title=Editing History +WorkbookRevisionDialog_Disable_hyperlink=Disable Revision + +OpenLocalFileHandler_MessageDialog_title=XMind + +LocalImageModelPage_title=Local +LocalImageModelPage_ImageSection_description=Select a topic and then insert an image from your computer +LocalImageModelPage_Insert_button=Insert + +DecryptionDialog_title=Enter Password +DecryptionDialog_message=Enter the correct password to open this XMind file. +DecryptionDialog_FileName_label=File Name: +DecryptionDialog_FileName_untitled=Untitled +DecryptionDialog_Password_label=Password: +DecryptionDialog_WarningLabel_text=The password you entered is not correct. Please try again. +DecryptionDialog_Hint_label=Hint: + +EncrptionDialog_ChangePassword_title=Change Password +EncryptionDialog_SetPassword_title=Set Password +EncryptionDialog_ChangePassword_message=Set a new password or remove password for this XMind file. +EncryptionDialog_SetPassword_message=Set a password to protect this XMind file. +EncryptionDialog_ButtonBar_Set_button=Set +EncryptionDialog_HintInput_label=Password Hint:{0}(Optional) +EncryptionDialog_Warning_NotMatch_label=The passwords don't match. +EncryptionDialog_Warning_NotCorrect_label=The old password is not correct. + +MindMapEditor_Warning_FileNotFoundDialog_title=XMind + +MindMapEditorInput_Workbook_Untitled_title=Untitled + +OverviewCheck_Overview_ON=Overview: ON +OverviewCheck_Overview_OFF=Overview: OFF + +OutlineIndexPart_ShowWorkbookAction_text=Show workbook +OutlineIndexPart_ShowWorkbookAction_toolTip=Show the entire workbook +OutlineIndexPart_ShowCurrentSheetAction_text=Show current sheet +OutlineIndexPart_ShowCurrentSheetAction_toolTip=Show the current sheet only +OutlineIndexPart_DefaultPage_message=Open an XMind workbook to view its outline. + +OutlineType_None=None +OutlineType_Markers=Markers +OutlineType_Labels=Labels +OutlineType_StartDate=Start Date +OutlineType_EndDate=End Date +OutlineType_Assignee=Assignee + +OutlineViewer_StartDate_col=Start date +OutlineViewer_EndData_col=End date +OutlineViewer_Task_col=Task + +ThemePrefPage_ThemeEditor_label=when change map theme: + +NumberingProperty_NumberDepthLabelProvider_Inherit_text=Inherit +NumberingProperty_NumberDepthLabelProvider_Levels_text=levels +NumberingProperty_TieredCheck_text=Tiered Numbers + +PropertiesPart_DefaultPage_message=No contents available... + +MarkerResourceManagerViewer_AddSection_title=Add + +ResourceManagerPart_title=Resource Manager +ResourceManagerPart_message=Help you customize and arrange XMind resource library. + +StyleResourceManager_Editor_button=Edit [Pro] + +StyleResourceManagerViewer_Topic=Topic +StyleResourceManagerViewer_Boundary=Boundary +StyleResourceManagerViewer_Map=Map +StyleResourceManagerViewer_Paragraph=Paragraph +StyleResourceManagerViewer_Relationship=Relationship +StyleResourceManagerViewer_Summary=Summary +StyleResourceManagerViewer_Text=Text +StyleResourceManagerViewer_Theme=Theme +StyleResourceManagerViewer_AddSection_title=Add [Pro] + +TemplateResourceManagerPage_Import_button=Import [Pro] +TemplateResourceManagerPage_Delete_ConfirmDialog_title=XMind - Delete Template +TemplateResourceManagerPage_Delete_ConfirmDialog_message=You are deleting the template {0}. +TemplateResourceManagerPage_AddTemplates_label=Add +TemplateResourceManagerPage_TemplateFilterName_label=XMind Template +TemplateResourceManagerPage_AddTemplates_tooltip=Add Template... + +TemplateResourceManagerViewer_SystemGroup_name=System +TemplateResourceManagerViewer_UserGroup_name=User + +ThemeResourceManagerPage_New_button=New [Pro] +ThemeResourceManagerPage_Edit_button=Edit [Pro] + +ResourceUtil_Copy_name={0} copy +ResourceUtil_Duplicate_name=copy + +ThemeGroupCore_UserGroup_name=User +ThemeGroupCore_DefaultGroup_name=Default + +ExportPage_Categore_Recent_name=Recent diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/BranchPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/BranchPart.java index 9d3781e04..77afd8147 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/BranchPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/BranchPart.java @@ -633,7 +633,6 @@ protected void onDeactivated() { /* * (non-Javadoc) - * * @see org.xmind.ui.internal.mindmap.MindMapPartBase#updateView() */ @Override @@ -1067,4 +1066,4 @@ public Object getAdapter(Class adapter) { return super.getAdapter(adapter); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/DrillDownTraceService.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/DrillDownTraceService.java index c14a6d227..9ef6391b3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/DrillDownTraceService.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/DrillDownTraceService.java @@ -24,8 +24,8 @@ import org.xmind.ui.mindmap.IDrillDownTraceService; import org.xmind.ui.mindmap.IMindMap; -public class DrillDownTraceService extends GraphicalViewerService implements - IDrillDownTraceService { +public class DrillDownTraceService extends GraphicalViewerService + implements IDrillDownTraceService { private List centralTopics = new ArrayList(); @@ -41,6 +41,13 @@ protected void activate() { protected void deactivate() { } + @Override + public void init(List centralTopics) { + if (centralTopics != null && centralTopics.size() != 0) { + this.centralTopics.addAll(centralTopics); + } + } + public List getCentralTopics() { checkEmpty(); return centralTopics; @@ -77,8 +84,8 @@ public void setCentralTopic(ITopic topic) { ITopic t = centralTopics.get(i); if (t.equals(topic)) { while (centralTopics.size() > i + 1) { - ITopic removed = centralTopics.remove(centralTopics - .size() - 1); + ITopic removed = centralTopics + .remove(centralTopics.size() - 1); changed |= removed != null; } if (changed) @@ -137,4 +144,4 @@ public void inputChanged(Object oldInput, Object newInput) { setCentralTopic(null); } } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/HyperlinkInfoItemContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/HyperlinkInfoItemContributor.java index eb30bbe4d..aed2370c5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/HyperlinkInfoItemContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/HyperlinkInfoItemContributor.java @@ -37,7 +37,6 @@ import org.xmind.ui.internal.dialogs.DialogMessages; import org.xmind.ui.mindmap.AbstractInfoItemContributor; import org.xmind.ui.mindmap.IInfoPart; -import org.xmind.ui.mindmap.IMindMapImages; import org.xmind.ui.mindmap.ITopicPart; import org.xmind.ui.mindmap.MindMapUI; @@ -155,8 +154,7 @@ public List getPopupMenuActions(ITopicPart topicPart, IAction modifyHyperlinkAction = new ModifyHyperlinkAction(page); modifyHyperlinkAction.setText(MindMapMessages.InfoItem_Modify_text); - modifyHyperlinkAction.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.HYPERLINK, true)); + modifyHyperlinkAction.setImageDescriptor(null); actions.add(modifyHyperlinkAction); } else { IAction saveAttchmentAsAction = new Action( @@ -177,8 +175,7 @@ public void run() { } }; deleteHyperlinkAction.setId("org.xmind.ui.removeHyperlink"); //$NON-NLS-1$ - deleteHyperlinkAction.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.DELETE, true)); + deleteHyperlinkAction.setImageDescriptor(null); actions.add(deleteHyperlinkAction); return actions; diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/IconTipPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/IconTipPart.java index a7371c956..ffa4c2320 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/IconTipPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/IconTipPart.java @@ -191,8 +191,9 @@ private void registerAction(IAction action) { private void updateImage() { ImageDescriptor oldImageDescriptor = imageRef == null ? null : imageRef.getImageDescriptor(); - ImageDescriptor newImageDescriptor = action == null ? null - : action.getImageDescriptor(); + ImageDescriptor newImageDescriptor = null; + if (action != null) + newImageDescriptor = action.getImageDescriptor(); if (oldImageDescriptor != newImageDescriptor && (oldImageDescriptor == null || !oldImageDescriptor.equals(newImageDescriptor))) { @@ -215,6 +216,7 @@ protected void onDeactivated() { protected void updateView() { super.updateView(); updateToolTip(); + updateImage(); } protected IFigure createToolTip() { @@ -251,12 +253,9 @@ protected IFigure createToolTip() { RotatableWrapLabel description = new RotatableWrapLabel( tooltip, RotatableWrapLabel.NORMAL); description.setTextAlignment(PositionConstants.LEFT); - description - .setPrefWidth( - Math.min( - Display.getCurrent() - .getClientArea().width / 3, - 350)); + description.setPrefWidth(Math.min( + Display.getCurrent().getClientArea().width / 3, + 350)); description.setFont(FontUtils.getRelativeHeight( JFaceResources.DEFAULT_FONT, -1)); // description.setForegroundColor(ColorConstants.gray); @@ -312,4 +311,4 @@ public void propertyChange(PropertyChangeEvent event) { public String getActionId() { return actionId; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/ImagePart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/ImagePart.java index 76e7da13d..27dd8f612 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/ImagePart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/ImagePart.java @@ -1,20 +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 +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ package org.xmind.ui.internal.mindmap; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; import org.eclipse.core.runtime.IStatus; import org.eclipse.draw2d.IFigure; @@ -31,6 +29,7 @@ import org.xmind.core.event.ICoreEventRegister; import org.xmind.core.util.HyperlinkUtils; import org.xmind.gef.GEF; +import org.xmind.gef.Request; import org.xmind.gef.draw2d.SizeableImageFigure; import org.xmind.gef.part.IPart; import org.xmind.gef.part.IRequestHandler; @@ -70,9 +69,8 @@ public ImageDescriptor getImageDescriptor() { protected synchronized void setImageDescriptor( ImageDescriptor imageDescriptor) { - if (imageDescriptor == this.imageDescriptor - || (imageDescriptor != null && imageDescriptor - .equals(this.imageDescriptor))) + if (imageDescriptor == this.imageDescriptor || (imageDescriptor != null + && imageDescriptor.equals(this.imageDescriptor))) return; ImageReference oldImageRef = this.imageRef; this.imageDescriptor = imageDescriptor; @@ -189,9 +187,9 @@ private void updateImageDescriptor() { if (HyperlinkUtils.isAttachmentURL(source)) { setImageURL(null); String path = HyperlinkUtils.toAttachmentPath(source); - setImageDescriptor(AttachmentImageDescriptor - .createFromEntryPath(imageModel.getOwnedWorkbook(), - path)); + setImageDescriptor( + AttachmentImageDescriptor.createFromEntryPath( + imageModel.getOwnedWorkbook(), path)); setToolTip(null); } else { URL url = checkFileURL(source); @@ -228,11 +226,12 @@ private void setImageURL(String newURL) { this.imageURL = newURL; - ImageDownloader.getInstance() - .unregister(oldImageURL, getImageUpdater()); + ImageDownloader.getInstance().unregister(oldImageURL, + getImageUpdater()); if (imageURL != null) { ImageDownloader.getInstance().register(imageURL, getImageUpdater()); - setImageDescriptor(ImageDownloader.getInstance().getImage(imageURL)); + setImageDescriptor( + ImageDownloader.getInstance().getImage(imageURL)); IStatus status = ImageDownloader.getInstance().getStatus(imageURL); if (status.getSeverity() == IStatus.OK) { setToolTip(imageURL); @@ -249,10 +248,10 @@ public void run() { if (imageURL == null) return; - setImageDescriptor(ImageDownloader.getInstance().getImage( - imageURL)); - IStatus status = ImageDownloader.getInstance().getStatus( - imageURL); + setImageDescriptor( + ImageDownloader.getInstance().getImage(imageURL)); + IStatus status = ImageDownloader.getInstance() + .getStatus(imageURL); if (status.getSeverity() == IStatus.OK) { setToolTip(imageURL); } else { @@ -289,7 +288,6 @@ protected ISelectionFeedbackHelper createSelectionFeedbackHelper() { /* * (non-Javadoc) - * * @see * org.xmind.gef.part.GraphicalEditPart#findAt(org.eclipse.draw2d.geometry * .Point) @@ -307,8 +305,8 @@ protected ISelectionFeedbackHelper createSelectionFeedbackHelper() { // } public boolean containsPoint(Point position) { - return super.containsPoint(position) - || (getSelectionOrientation(position) != PositionConstants.NONE); + return super.containsPoint(position) || (getSelectionOrientation( + position) != PositionConstants.NONE); } public Cursor getCursor(Point pos) { @@ -326,4 +324,16 @@ private int getSelectionOrientation(Point point) { return PositionConstants.NONE; } -} \ No newline at end of file + @Override + public void handleRequest(Request request, String role) { + String type = request.getType(); + if (GEF.REQ_PASTE.equals(type)) { + request.setPrimaryTarget(getTopicPart()); + ArrayList parts = new ArrayList(); + parts.add(getTopicPart()); + request.setTargets(parts); + } + super.handleRequest(request, role); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/InfoItemContentPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/InfoItemContentPart.java index dcc8ba0f4..39836149c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/InfoItemContentPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/InfoItemContentPart.java @@ -1,6 +1,9 @@ package org.xmind.ui.internal.mindmap; +import org.eclipse.draw2d.IFigure; import org.xmind.core.ITopic; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.draw2d.RotatableWrapLabel; import org.xmind.gef.part.IPart; import org.xmind.ui.internal.decorators.InfoItemContentDecorator; import org.xmind.ui.mindmap.IInfoPart; @@ -44,4 +47,12 @@ protected void updateView() { updateToolTip(); } + @Override + protected IFigure createFigure() { + boolean useAdvancedRenderer = getSite().getViewer().getProperties() + .getBoolean(IGraphicalViewer.VIEWER_RENDER_TEXT_AS_PATH, false); + return new RotatableWrapLabel(getContent(), useAdvancedRenderer + ? RotatableWrapLabel.ADVANCED : RotatableWrapLabel.NORMAL); + } + } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/InfoItemIconPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/InfoItemIconPart.java index 814698a54..148831385 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/InfoItemIconPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/InfoItemIconPart.java @@ -180,8 +180,11 @@ private void registerAction(IAction action) { private void updateImage() { ImageDescriptor oldImageDescriptor = imageRef == null ? null : imageRef.getImageDescriptor(); - ImageDescriptor newImageDescriptor = action == null ? null - : action.getImageDescriptor(); + ImageDescriptor newImageDescriptor = null; + if (action != null) + newImageDescriptor = action.isEnabled() + ? action.getImageDescriptor() + : action.getDisabledImageDescriptor(); if (oldImageDescriptor != newImageDescriptor && (oldImageDescriptor == null || !oldImageDescriptor.equals(newImageDescriptor))) { @@ -206,6 +209,7 @@ protected void onDeactivated() { protected void updateView() { super.updateView(); updateToolTip(); + updateImage(); } protected IFigure createToolTip() { @@ -235,12 +239,9 @@ protected IFigure createToolTip() { RotatableWrapLabel description = new RotatableWrapLabel( tooltip, RotatableWrapLabel.NORMAL); description.setTextAlignment(PositionConstants.LEFT); - description - .setPrefWidth( - Math.min( - Display.getCurrent() - .getClientArea().width / 3, - 350)); + description.setPrefWidth(Math.min( + Display.getCurrent().getClientArea().width / 3, + 128)); description.setFont(FontUtils.getRelativeHeight( JFaceResources.DEFAULT_FONT, -1)); description.setForegroundColor(ColorConstants.gray); diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/LabelInfoItemContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/LabelInfoItemContributor.java index e17b36255..1d27c20d7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/LabelInfoItemContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/LabelInfoItemContributor.java @@ -80,7 +80,7 @@ public IAction createAction(ITopicPart topicPart, ITopic topic) { action = new DelegatingAction(action); } - if (action == null) { + if (action == null || action.getImageDescriptor() == null) { IViewer viewer = topicPart.getSite().getViewer(); if (viewer != null && viewer instanceof IGraphicalViewer) action = new EditLabelAction((IGraphicalViewer) viewer); @@ -89,6 +89,8 @@ public IAction createAction(ITopicPart topicPart, ITopic topic) { if (action != null) action.setToolTipText(getContent(topic)); + action.setEnabled(true); + return action; } @@ -174,8 +176,7 @@ public List getPopupMenuActions(ITopicPart topicPart, (IGraphicalViewer) viewer); modifyLabelAction.setText(MindMapMessages.ModifyMenu); - modifyLabelAction.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.LABEL, true)); + modifyLabelAction.setImageDescriptor(null); IAction deleteLabelAction = new Action( MindMapMessages.InfoItem_Delete_text) { @@ -185,8 +186,7 @@ public void run() { } }; deleteLabelAction.setId("org.xmind.ui.removeLabel"); //$NON-NLS-1$ - deleteLabelAction.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.DELETE, true)); + deleteLabelAction.setImageDescriptor(null); List actions = new ArrayList(); actions.add(modifyLabelAction); diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/MindMapPartBase.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/MindMapPartBase.java index 70fa056dd..7f50097b7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/MindMapPartBase.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/MindMapPartBase.java @@ -34,8 +34,8 @@ import org.xmind.ui.mindmap.ISelectionFeedbackHelper; import org.xmind.ui.util.MindMapUtils; -public abstract class MindMapPartBase extends GraphicalEditPart implements - IAnimatablePart { +public abstract class MindMapPartBase extends GraphicalEditPart + implements IAnimatablePart { private ICoreEventRegister eventRegister = null; @@ -64,7 +64,8 @@ public void setGraphicalPolicy(IGraphicalPolicy graphicalPolicy) { graphicalPolicyActivated = false; } this.graphicalPolicy = graphicalPolicy; - if (hasFigure() && graphicalPolicy != null && !graphicalPolicyActivated) { + if (hasFigure() && graphicalPolicy != null + && !graphicalPolicyActivated) { graphicalPolicy.activate(this); graphicalPolicyActivated = true; } @@ -146,18 +147,18 @@ public boolean isFigureAnimating() { } protected IAnimationService getAnimationService() { - return (IAnimationService) getSite().getViewer().getService( - IAnimationService.class); + return (IAnimationService) getSite().getViewer() + .getService(IAnimationService.class); } protected IFeedbackService getFeedbackService() { - return (IFeedbackService) getSite().getViewer().getService( - IFeedbackService.class); + return (IFeedbackService) getSite().getViewer() + .getService(IFeedbackService.class); } protected IShadowService getShadowService() { - return (IShadowService) getSite().getViewer().getService( - IShadowService.class); + return (IShadowService) getSite().getViewer() + .getService(IShadowService.class); } protected void onActivated() { @@ -275,20 +276,20 @@ public ICacheManager getCacheManager() { return cacheManager; } - public Object getAdapter(Class adapter) { + public T getAdapter(Class adapter) { if (adapter == IGraphicalPolicy.class) - return getGraphicalPolicy(); + return adapter.cast(getGraphicalPolicy()); if (adapter == IStyleSelector.class) - return getGraphicalPolicy().getStyleSelector(this); + return adapter.cast(getGraphicalPolicy().getStyleSelector(this)); if (adapter == IStructure.class) - return getGraphicalPolicy().getStructure(this); + return adapter.cast(getGraphicalPolicy().getStructure(this)); if (adapter == ISelectionFeedbackHelper.class) - return getSelectionFeedbackHelper(); + return adapter.cast(getSelectionFeedbackHelper()); if (adapter == IFeedback.class) - return getFeedback(); + return adapter.cast(getFeedback()); if (adapter == ICacheManager.class) - return getCacheManager(); + return adapter.cast(getCacheManager()); return super.getAdapter(adapter); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/MindMapViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/MindMapViewer.java index ef9c01f93..02c412bd5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/MindMapViewer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/MindMapViewer.java @@ -1,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ package org.xmind.ui.internal.mindmap; @@ -18,12 +15,21 @@ import org.eclipse.draw2d.FigureCanvas; import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; 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.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +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.Layout; import org.xmind.core.IRelationship; import org.xmind.core.IRelationshipEnd; import org.xmind.core.ISheet; @@ -40,6 +46,7 @@ import org.xmind.gef.part.IRootPart; import org.xmind.gef.service.IRevealService; import org.xmind.ui.commands.ModifyFoldedCommand; +import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.internal.figures.BranchFigure; import org.xmind.ui.mindmap.IBranchPart; import org.xmind.ui.mindmap.IMindMap; @@ -47,9 +54,51 @@ import org.xmind.ui.mindmap.ISheetPart; import org.xmind.ui.mindmap.ITopicPart; import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; import org.xmind.ui.util.MindMapUtils; -public class MindMapViewer extends GraphicalViewer implements IMindMapViewer { +public class MindMapViewer extends GraphicalViewer + implements IMindMapViewer, IPropertyChangeListener { + + public static final int OVERVIEW_WIDTH = 300; + + public static final int OVERVIEW_HEIGHT = 180; + + private class OverviewLayout extends Layout { + + @Override + protected 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 Point(wHint, hHint); + } + + @Override + protected void layout(Composite composite, boolean flushCache) { + org.eclipse.swt.graphics.Rectangle area = composite.getParent() + .getClientArea(); + Control[] children = composite.getChildren(); + if (children.length == 2) { + children[1].setBounds(area); + + children[0].setBounds(area.x + area.width - OVERVIEW_WIDTH, + area.y + area.height - OVERVIEW_HEIGHT, OVERVIEW_WIDTH, + OVERVIEW_HEIGHT); + } + } + + } protected class MindMapSelectionSupport extends GraphicalSelectionSupport { @@ -90,11 +139,17 @@ public ISelection getModelSelection() { private boolean inputChangedOnSelectionChanged = false; + private Composite overviewContainer; + + private IPreferenceStore ps; + public MindMapViewer() { setDndSupport(MindMapUI.getMindMapDndSupport()); setPartFactory(MindMapUI.getMindMapPartFactory()); setRootPart(new MindMapRootPart()); getProperties().set(VIEWER_RENDER_TEXT_AS_PATH, false); + + ps = MindMapUIPlugin.getDefault().getPreferenceStore(); } public T getAdapter(Class adapter) { @@ -119,13 +174,51 @@ public T getAdapter(Class adapter) { } protected Control internalCreateControl(Composite parent, int style) { - FigureCanvas fc = (FigureCanvas) super.internalCreateControl(parent, + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new OverviewLayout()); + container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + Composite composite = createOverview(container); + + FigureCanvas fc = (FigureCanvas) super.internalCreateControl(container, style); fc.setScrollBarVisibility(FigureCanvas.ALWAYS); fc.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + + final Overview overview = new Overview(composite, fc, this); + + composite.setVisible(ps.getBoolean(PrefConstants.SHOW_OVERVIEW)); + ps.removePropertyChangeListener(this); + ps.addPropertyChangeListener(this); + + composite.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + overview.dispose(); + if (ps != null) { + ps = null; + } + } + }); return fc; } + 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); + + overviewContainer = composite; + + return composite; + } + protected ISelectionSupport createSelectionSupport() { return new MindMapSelectionSupport(); } @@ -159,7 +252,6 @@ protected void revealParts(List parts) { /* * (non-Javadoc) - * * @see org.xmind.gef.AbstractViewer#fireFocusedPartChanged() */ @Override @@ -237,7 +329,6 @@ protected void ensureVisible(Rectangle box, Rectangle clientArea, /* * (non-Javadoc) - * * @see * org.xmind.gef.GraphicalViewer#setSelectionOnInputChanged(org.eclipse. * jface.viewers.ISelection) @@ -328,4 +419,25 @@ public IPart findPart(Object element) { return super.findPart(element); } -} \ No newline at end of file + @Override + public void propertyChange(final PropertyChangeEvent event) { + if (overviewContainer == null || overviewContainer.isDisposed()) + return; + + overviewContainer.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + setOverviewVisible(event.getProperty()); + } + + }); + } + + private void setOverviewVisible(String id) { + if (PrefConstants.SHOW_OVERVIEW.equals(id)) { + overviewContainer.setVisible(ps.getBoolean(id)); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/Overview.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/Overview.java new file mode 100644 index 000000000..0b117e834 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/Overview.java @@ -0,0 +1,371 @@ +package org.xmind.ui.internal.mindmap; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import org.eclipse.draw2d.Cursors; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.LayoutListener; +import org.eclipse.draw2d.RangeModel; +import org.eclipse.draw2d.RectangleFigure; +import org.eclipse.draw2d.Viewport; +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.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.SelectionChangedEvent; +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.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IInputChangedListener; +import org.xmind.gef.IViewer; +import org.xmind.gef.IZoomListener; +import org.xmind.gef.ZoomManager; +import org.xmind.gef.ZoomObject; +import org.xmind.gef.draw2d.geometry.PrecisionDimension; +import org.xmind.gef.draw2d.geometry.PrecisionPoint; +import org.xmind.gef.draw2d.graphics.ScaledGraphics; +import org.xmind.ui.resources.ColorUtils; + +public class Overview implements ISelectionChangedListener, + IInputChangedListener, PropertyChangeListener, IZoomListener, Listener { + + private class ContentsFigure extends Figure { + + public ContentsFigure() { + setOpaque(true); + } + + @Override + protected void paintFigure(Graphics graphics) { + super.paintFigure(graphics); + if (sourceContents == null || zoomScale <= 0) + return; + + graphics.setAntialias(SWT.ON); + + graphics.pushState(); + try { + Point offset = getBounds().getLocation(); + graphics.translate(offset); + + Graphics g = graphics; + ScaledGraphics sg = null; + if (ScaledGraphics.SCALED_GRAPHICS_ENABLED) { + sg = new ScaledGraphics(graphics); + sg.scale(zoomScale); + g = sg; + } else { + g.scale(zoomScale); + } + try { + paintDelegate(g, sourceContents); + } finally { + if (sg != null) { + sg.dispose(); + } + } + } finally { + graphics.popState(); + } + + } + + private void paintDelegate(Graphics graphics, IFigure figure) { + Point loc = figure.getBounds().getLocation(); + graphics.translate(-loc.x, -loc.y); + try { + figure.paint(graphics); + } finally { + graphics.translate(loc.x, loc.y); + } + } + + } + + private class ContentsLayoutListener extends LayoutListener.Stub { + + @Override + public void postLayout(IFigure container) { + update(); + } + } + + private IGraphicalViewer sourceViewer; + + private FigureCanvas sourceCanvas; + + private RangeModel sourceHorizontalRangeModel; + + private RangeModel sourceVerticalRangeModel; + + private ZoomManager sourceZoomManager; + + private IFigure sourceContents; + + private FigureCanvas canvas; + + private IFigure contents; + + private IFigure feedback; + + private boolean updating = false; + + private ContentsLayoutListener contentsListener; + + private Point moveStart = null; + + private Point sourceStart = null; + + private double zoomScale = 1.0d; + + private ResourceManager resources; + + public Overview(Composite parent, FigureCanvas sourceCanvas, + IGraphicalViewer viewer) { + this.sourceViewer = viewer; + this.sourceCanvas = sourceCanvas; + createContents(parent); + } + + protected Control createContents(Composite parent) { + Composite composite = new Composite(parent, SWT.BORDER); + + resources = new LocalResourceManager(JFaceResources.getResources(), + composite); + + canvas = new FigureCanvas(composite); + canvas.setSize(MindMapViewer.OVERVIEW_WIDTH, + MindMapViewer.OVERVIEW_HEIGHT); + canvas.addListener(SWT.Resize, this); + canvas.addListener(SWT.MouseDown, this); + canvas.addListener(SWT.MouseMove, this); + canvas.addListener(SWT.MouseUp, this); + canvas.addListener(SWT.MouseWheel, this); + canvas.setBackground( + (Color) resources.get(ColorUtils.toDescriptor("#f9fcfe"))); //$NON-NLS-1$ + contents = new ContentsFigure(); + contents.setCursor(Cursors.HAND); + canvas.setContents(contents); + feedback = createFeedback(); + contents.add(feedback); + + sourceZoomManager = sourceViewer.getZoomManager(); + + sourceViewer.addInputChangedListener(this); + sourceViewer.addSelectionChangedListener(this); + sourceZoomManager.addZoomListener(this); + hookViewport(); + hookContents(); + update(); + + return composite; + } + + public void dispose() { + unhookContents(); + unhookViewport(); + sourceZoomManager.removeZoomListener(this); + sourceViewer.removeSelectionChangedListener(this); + } + + private void moveStarted(int x, int y) { + moveStart = new Point(x, y); + sourceStart = new Point(sourceViewer.getScrollPosition()); + } + + private void moveEnded(int x, int y) { + if (moveStart != null) { + if (moveStart.x == x && moveStart.y == y) { + directMove(x, y); + } + } + moveStart = null; + sourceStart = null; + } + + private void directMove(int x, int y) { + Point start = feedback.getBounds().getCenter(); + Dimension offset = new PrecisionDimension(x - start.x, y - start.y) + .scale(sourceZoomManager.getScale() / zoomScale) + .toDraw2DDimension(); + sourceViewer.scrollDelta(offset); + } + + private void feedbackMoved(int x, int y) { + int dx = x - moveStart.x; + int dy = y - moveStart.y; + Dimension offset = new PrecisionDimension(dx, dy) + .scale(sourceZoomManager.getScale() / zoomScale) + .toDraw2DDimension(); + sourceViewer.scrollTo(sourceStart.getTranslated(offset)); + } + + private void changeZoom(int value) { + if (value > 0) { + sourceZoomManager.zoomIn(); + } else if (value < 0) { + sourceZoomManager.zoomOut(); + } + } + + private void update() { + if (updating) + return; + updating = true; + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + doUpdate(); + updating = false; + } + }); + } + + private void doUpdate() { + Insets margins; + Rectangle feedbackBounds; + Rectangle sourceBounds = sourceContents.getBounds(); + Dimension source = sourceBounds.getSize(); + Rectangle area = contents.getParent().getClientArea(); + if (area.width == 0 || area.height == 0 || source.width == 0 + || source.height == 0) { + zoomScale = -1; + margins = IFigure.NO_INSETS; + feedbackBounds = null; + } else { + double wScale = source.width * 1.0d / area.width; + double hScale = source.height * 1.0d / area.height; + if (wScale > hScale) { + zoomScale = 1 / wScale; + int m = (int) ((area.height - source.height / wScale) / 2); + margins = new Insets(m, 0, m, 0); + } else { + zoomScale = 1 / hScale; + int m = (int) ((area.width - source.width / hScale) / 2); + margins = new Insets(0, m, 0, m); + } + Viewport sourceViewport = sourceViewer.getCanvas().getViewport(); + PrecisionPoint loc = new PrecisionPoint( + sourceViewport.getViewLocation()); + Dimension size = sourceViewport.getSize(); + double sourceScale = sourceZoomManager.getScale(); + feedbackBounds = new Rectangle( + loc.scale(1 / sourceScale) + .translate(new PrecisionPoint( + sourceBounds.getLocation()).negate()) + .scale(zoomScale) + .translate(margins.left, margins.top) + .toDraw2DPoint(), + size.scale(zoomScale / sourceScale)); + } + contents.setBounds(area.getShrinked(margins)); + contents.repaint(); + if (feedbackBounds == null) { + feedback.setBounds(new Rectangle(1, 1, 0, 0)); + feedback.setVisible(false); + } else { + feedback.setBounds(feedbackBounds); + feedback.setVisible(true); + } + } + + private void hookViewport() { + Viewport sourceViewport = sourceCanvas.getViewport(); + sourceHorizontalRangeModel = sourceViewport.getHorizontalRangeModel(); + sourceHorizontalRangeModel.addPropertyChangeListener(this); + sourceVerticalRangeModel = sourceViewport.getVerticalRangeModel(); + sourceVerticalRangeModel.addPropertyChangeListener(this); + } + + private void unhookViewport() { + if (sourceHorizontalRangeModel != null) { + sourceHorizontalRangeModel.removePropertyChangeListener(this); + sourceHorizontalRangeModel = null; + } + if (sourceVerticalRangeModel != null) { + sourceVerticalRangeModel.removePropertyChangeListener(this); + sourceVerticalRangeModel = null; + } + } + + private void hookContents() { + if (contentsListener == null) + contentsListener = new ContentsLayoutListener(); + sourceContents = sourceViewer.getLayer(GEF.LAYER_CONTENTS); + sourceContents.addLayoutListener(contentsListener); + } + + private void unhookContents() { + if (contentsListener != null) { + if (sourceContents != null) { + sourceContents.removeLayoutListener(contentsListener); + } + } + } + + private IFigure createFeedback() { + RectangleFigure figure = new RectangleFigure(); + figure.setForegroundColor( + (Color) resources.get(ColorUtils.toDescriptor("#44c0ff"))); //$NON-NLS-1$ + figure.setLineWidth(1); + figure.setFill(false); + figure.setOutline(true); + return figure; + } + + @Override + public void handleEvent(Event event) { + if (event.type == SWT.MouseDown) { + moveStarted(event.x, event.y); + } else if (event.type == SWT.MouseMove) { + if (moveStart != null) { + feedbackMoved(event.x, event.y); + } + } else if (event.type == SWT.MouseUp) { + moveEnded(event.x, event.y); + } else if (event.type == SWT.MouseWheel) { + changeZoom(event.count); + } else if (event.type == SWT.Resize) { + update(); + } + } + + @Override + public void scaleChanged(ZoomObject source, double oldValue, + double newValue) { + update(); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + update(); + } + + @Override + public void selectionChanged(SelectionChangedEvent event) { + update(); + } + + @Override + public void inputChanged(IViewer viewer, Object newInput, Object oldInput) { + unhookContents(); + unhookViewport(); + hookViewport(); + hookContents(); + update(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/SimpleChineseNumberFormat.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/SimpleChineseNumberFormat.java new file mode 100644 index 000000000..2822aface --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/SimpleChineseNumberFormat.java @@ -0,0 +1,13 @@ +package org.xmind.ui.internal.mindmap; + +import org.xmind.ui.mindmap.INumberFormat; +import org.xmind.ui.util.NumberUtils; + +public class SimpleChineseNumberFormat implements INumberFormat { + + @Override + public String getText(int index) { + return NumberUtils.toSimpleChinese(index); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/TopicPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/TopicPart.java index 8b6eac947..8f9de2e27 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/TopicPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/TopicPart.java @@ -76,7 +76,6 @@ import org.xmind.ui.util.MindMapUtils; /** - * * @author MANGOSOFT */ public class TopicPart extends NodePart implements ITopicPart { @@ -133,7 +132,8 @@ public int compare(IMarkerRef p, IMarkerRef q) { return -2000 + (grouplist.indexOf(pMarkerGroup) - qSheet .getMarkerGroups().indexOf(qMarkerGroup)) - * 100 + pMarkerGroup.getMarkers().indexOf(pMarker) + * 100 + + pMarkerGroup.getMarkers().indexOf(pMarker) - qMarkerGroup.getMarkers().indexOf(qMarker); return 2000 + (grouplist.indexOf(pMarkerGroup) - qSheet @@ -240,7 +240,6 @@ private boolean isCentral() { /* * (non-Javadoc) - * * @see * org.xmind.gef.part.GraphicalEditPart#containsPoint(org.eclipse.draw2d * .geometry.Point) @@ -428,16 +427,15 @@ public IPart findAt(Point position) { return ret; } - @SuppressWarnings("unchecked") - public Object getAdapter(Class adapter) { + public T getAdapter(Class adapter) { if (adapter.isAssignableFrom(ITopic.class)) - return getTopic(); + return adapter.cast(getTopic()); if (adapter == TitleTextPart.class || adapter == ITitleTextPart.class) - return getTitle(); + return adapter.cast(getTitle()); if (adapter == IBranchPart.class) - return getOwnerBranch(); + return adapter.cast(getOwnerBranch()); if (adapter == IActionRegistry.class) - return getActionRegistry(); + return adapter.cast(getActionRegistry()); return super.getAdapter(adapter); } @@ -472,6 +470,7 @@ protected void registerCoreEvents(Object source, register.register(Core.NumberingSuffix); register.register(Core.NumberPrepending); register.register(Core.NumberingSeparator); + register.register(Core.NumberingDepth); } } @@ -500,7 +499,8 @@ public void handleCoreEvent(CoreEvent event) { || Core.NumberingPrefix.equals(type) || Core.NumberingSuffix.equals(type) || Core.NumberPrepending.equals(type) - || Core.NumberingSeparator.equals(type)) { + || Core.NumberingSeparator.equals(type) + || Core.NumberingDepth.equals(type)) { treeRefresh(); } else { super.handleCoreEvent(event); @@ -735,4 +735,4 @@ public String getFullNumberingText() { return MindMapUtils.getFullNumberingText(getTopic(), null, null); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/TraditionalChineseNumberFormat.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/TraditionalChineseNumberFormat.java new file mode 100644 index 000000000..802152a02 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/mindmap/TraditionalChineseNumberFormat.java @@ -0,0 +1,13 @@ +package org.xmind.ui.internal.mindmap; + +import org.xmind.ui.mindmap.INumberFormat; +import org.xmind.ui.util.NumberUtils; + +public class TraditionalChineseNumberFormat implements INumberFormat { + + @Override + public String getText(int index) { + return NumberUtils.toTraditionalChinese(index); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesFindReplaceOperationProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesFindReplaceOperationProvider.java index c5a0428e1..0cda928f5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesFindReplaceOperationProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesFindReplaceOperationProvider.java @@ -13,32 +13,30 @@ *******************************************************************************/ package org.xmind.ui.internal.notes; +import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.text.IFindReplaceTarget; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.graphics.Font; -import org.eclipse.ui.IViewPart; import org.xmind.ui.internal.MindMapMessages; import org.xmind.ui.internal.findreplace.AbstractFindReplaceOperationProvider; import org.xmind.ui.mindmap.ITopicPart; /** - * * @author Karelun huang */ -public class NotesFindReplaceOperationProvider extends - AbstractFindReplaceOperationProvider { +public class NotesFindReplaceOperationProvider + extends AbstractFindReplaceOperationProvider { - private IViewPart view; + private IAdaptable view; // private boolean findingInEditor = false; - public NotesFindReplaceOperationProvider(IViewPart view) { + public NotesFindReplaceOperationProvider(IAdaptable view) { this.view = view; } /* * (non-Javadoc) - * * @see org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider# * getContextName() */ @@ -53,7 +51,6 @@ public String getContextName() { /* * (non-Javadoc) - * * @see org.xmind.ui.internal.findreplace.IFindReplaceOperationProvider# * getContextName(int, org.eclipse.swt.graphics.Font) */ @@ -88,11 +85,14 @@ private boolean findInNotes(String toFind) { private boolean findInNotes(IFindReplaceTarget target, String toFind) { if (target != null && target.canPerformFind()) { - int offset = target.findAndSelect( - isForward() ? target.getSelection().x - + target.getSelection().y - : target.getSelection().x - 1, toFind, isForward(), - isCaseSensitive(), isWholeWord()); + int offset = target + .findAndSelect( + isForward() + ? target.getSelection().x + + target.getSelection().y + : target.getSelection().x - 1, + toFind, isForward(), isCaseSensitive(), + isWholeWord()); return offset >= 0; } return false; @@ -126,8 +126,8 @@ private boolean findInNotes(IFindReplaceTarget target, String toFind) { @Override protected boolean replaceAll(String toFind, String toReplaceWith) { IFindReplaceTarget target = getFindReplaceTarget(); - boolean found = target.findAndSelect(0, toFind, true, - isCaseSensitive(), isWholeWord()) >= 0; + boolean found = target.findAndSelect(0, toFind, true, isCaseSensitive(), + isWholeWord()) >= 0; if (found) { while (replaceInNotes(target, toFind, toReplaceWith)) { } @@ -172,7 +172,6 @@ public boolean canReplaceAll(String toFind, String toReplaceWith) { /* * (non-Javadoc) - * * @see * org.xmind.ui.internal.findreplace.AbstractFindReplaceOperationProvider * #understandsPatameter(int) diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesInfoItemContributor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesInfoItemContributor.java index 28f75c0d0..719081c1a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesInfoItemContributor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesInfoItemContributor.java @@ -5,6 +5,7 @@ import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.xmind.core.Core; @@ -20,7 +21,9 @@ import org.xmind.ui.actions.MindMapActionFactory; import org.xmind.ui.commands.DeleteNotesCommand; import org.xmind.ui.internal.MindMapMessages; -import org.xmind.ui.internal.mindmap.BranchPart; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; import org.xmind.ui.mindmap.AbstractInfoItemContributor; import org.xmind.ui.mindmap.IInfoPart; import org.xmind.ui.mindmap.IMindMapImages; @@ -29,6 +32,8 @@ public class NotesInfoItemContributor extends AbstractInfoItemContributor { + private static final String PRESENTATION_VIERWER_CLASS_NAME = "PresentationViewer"; //$NON-NLS-1$ + private static class ShowNotesAction extends Action { private ITopicPart topicPart; @@ -43,25 +48,34 @@ public ShowNotesAction(ITopicPart 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() + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("UseNotesCount"); //$NON-NLS-1$ + + final IWorkbenchWindow window = PlatformUI.getWorkbench() .getActiveWorkbenchWindow(); if (window == null) return; - NotesPopup popup = new NotesPopup(window, - ((BranchPart) topicPart.getParent()).getTopicPart(), true, - false); - popup.open(); + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + E4Utils.showPart(IModelConstants.COMMAND_SHOW_MODEL_PART, + window, IModelConstants.PART_ID_NOTES, null, + IModelConstants.PART_STACK_ID_RIGHT); + } + }); } } - private static final int NOTES_LENGTH = 24; - - private static final int MININUM = 4; - public IAction createAction(ITopicPart topicPart, ITopic topic) { INotes notes = topic.getNotes(); if (notes.isEmpty()) @@ -76,7 +90,7 @@ public IAction createAction(ITopicPart topicPart, ITopic topic) { if (action != null) action = new DelegatingAction(action); } - if (action == null) + if (action == null || action.getImageDescriptor() == null) action = new ShowNotesAction(topicPart); INotesContent content = notes.getContent(INotes.PLAIN); @@ -86,6 +100,9 @@ public IAction createAction(ITopicPart topicPart, ITopic topic) { text = text.substring(0, 500) + "...\n..."; //$NON-NLS-1$ action.setToolTipText(text); } + + action.setEnabled(true); + return action; } @@ -95,17 +112,10 @@ public String getContent(ITopic topic) { return null; INotesContent content = notes.getContent(INotes.PLAIN); - if (content instanceof IPlainNotesContent) { - String text = ((IPlainNotesContent) content).getTextContent() + if (content instanceof IPlainNotesContent) + return ((IPlainNotesContent) content).getTextContent() .replaceAll("\r\n|\r|\n", " "); //$NON-NLS-1$ //$NON-NLS-2$ - if (text.length() < MININUM) - return text; - return text - .substring(0, - (text.length() - MININUM) < NOTES_LENGTH - ? (text.length() - MININUM) : NOTES_LENGTH) - + "..."; //$NON-NLS-1$ - } + return null; } @@ -156,6 +166,7 @@ public List getPopupMenuActions(ITopicPart topicPart, IAction editNotesAction = createAction(topicPart, topic); editNotesAction.setText(MindMapMessages.ModifyMenu); + editNotesAction.setImageDescriptor(null); IAction deleteNotesAction = new Action( MindMapMessages.InfoItem_Delete_text) { @Override @@ -164,8 +175,7 @@ public void run() { }; }; deleteNotesAction.setId("org.xmind.ui.removeNotes"); //$NON-NLS-1$ - deleteNotesAction.setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.DELETE, true)); + deleteNotesAction.setImageDescriptor(null); actions.add(editNotesAction); actions.add(deleteNotesAction); diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesPopup.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesPopup.java index bd86ae624..6a30524a8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesPopup.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesPopup.java @@ -55,9 +55,7 @@ import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchCommandConstants; -import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; import org.eclipse.ui.contexts.IContextActivation; @@ -82,9 +80,10 @@ import org.xmind.ui.internal.MindMapMessages; import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.internal.e4models.IModelConstants; import org.xmind.ui.internal.editor.MindMapEditor; import org.xmind.ui.internal.spellsupport.SpellingSupport; -import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.internal.utils.E4Utils; import org.xmind.ui.mindmap.ITopicPart; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.richtext.Hyperlink; @@ -98,7 +97,6 @@ import org.xmind.ui.richtext.TextActionConstants; import org.xmind.ui.texteditor.IMenuContributor; import org.xmind.ui.texteditor.ISpellingActivation; -import org.xmind.ui.util.Logger; public class NotesPopup extends PopupDialog implements IDocumentListener, IRichDocumentListener, ISelectionChangedListener { @@ -145,18 +143,18 @@ private class NotesPopupActionBarContributor private Collection textCommandIds = new HashSet(10); - private class GotoNotesViewAction extends Action { - public GotoNotesViewAction() { + private class GotoNotesPartAction extends Action { + public GotoNotesPartAction() { super(MindMapMessages.EditInNotesView_text); setToolTipText(MindMapMessages.EditInNotesView_toolTip); setImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.NOTES, true)); + MindMapUI.getImages().get("notes_part.png", true)); //$NON-NLS-1$ setDisabledImageDescriptor( - MindMapUI.getImages().get(IMindMapImages.NOTES, false)); + MindMapUI.getImages().get("notes_part.png", false)); //$NON-NLS-1$ } public void run() { - gotoNotesView(); + gotoNotesPart(); } } @@ -214,9 +212,9 @@ private void registerTextCommand(String actionId, String commandId) { public void fillToolBar(IToolBarManager toolbar) { super.fillToolBar(toolbar); - if (showGotoNotesView) { + if (showGotoNotesPart) { toolbar.add(new Separator()); - toolbar.add(new GotoNotesViewAction()); + toolbar.add(new GotoNotesPartAction()); } } @@ -421,7 +419,7 @@ private List generateKeyStrokes(Event event) { private IBindingService bindingService; - private boolean showGotoNotesView; + private boolean showGotoNotesPart; private boolean editable; @@ -437,7 +435,7 @@ public NotesPopup(IWorkbenchWindow window, ITopicPart topicPart, null, showGotoNotesView ? "" : null); //$NON-NLS-1$ this.window = window; this.topicPart = topicPart; - this.showGotoNotesView = showGotoNotesView; + this.showGotoNotesPart = showGotoNotesView; this.editable = editable; } @@ -447,7 +445,7 @@ public NotesPopup(Shell parentShell, ITopicPart topicPart, null); this.topicPart = topicPart; this.window = null; - this.showGotoNotesView = false; + this.showGotoNotesPart = false; this.editable = editable; } @@ -596,7 +594,7 @@ private void activateJob() { } protected void registerDialogCommands() { - if (showGotoNotesView) { + if (showGotoNotesPart) { TriggerSequence key = registerCommand(CMD_GOTO_NOTES_VIEW); if (key != null) { setInfoText( @@ -632,8 +630,8 @@ protected TriggerSequence registerCommand(String commandId) { protected boolean handleCommand(String commandId) { if (CMD_GOTO_NOTES_VIEW.equals(commandId)) { - if (showGotoNotesView) { - gotoNotesView(); + if (showGotoNotesPart) { + gotoNotesPart(); } return true; } else if (CMD_COMMIT_NOTES.equals(commandId)) { @@ -712,24 +710,17 @@ private void doSaveNotes() { notes.setContent(INotes.PLAIN, plain); } - private void gotoNotesView() { + private void gotoNotesPart() { Display.getCurrent().asyncExec(new Runnable() { public void run() { - if (window == null) + if (window == null) { return; - - IWorkbenchPage workbenchPage = window.getActivePage(); - if (workbenchPage == null) - return; - - close(); - try { - workbenchPage.showView(MindMapUI.VIEW_NOTES, null, - IWorkbenchPage.VIEW_ACTIVATE); - } catch (PartInitException e) { - Logger.log(e, - "GotoNotesViewAction failed to show Notes View."); //$NON-NLS-1$ } + close(); + + E4Utils.showPart(IModelConstants.COMMAND_SHOW_MODEL_PART, + window, IModelConstants.PART_ID_NOTES, null, + IModelConstants.PART_STACK_ID_RIGHT); } }); } @@ -776,6 +767,7 @@ public void run() { } }); + doSaveNotes(); } private void updateTextActions() { @@ -787,4 +779,4 @@ private void updateTextActions() { contributor.update(textViewer); } } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesTextEditViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesTextEditViewer.java index 45d127da3..87782cea6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesTextEditViewer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/NotesTextEditViewer.java @@ -11,6 +11,9 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.ToolBarManager; +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; @@ -54,12 +57,13 @@ import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.UIPlugin; import org.xmind.core.ISheet; import org.xmind.core.ITopic; import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.richtext.IRichDocument; import org.xmind.ui.richtext.IRichTextActionBarContributor; @@ -102,14 +106,14 @@ public void removeSelectionChangedListener( } public void setSelection(ISelection selection) { - if (this.selection == selection - || (this.selection != null && this.selection - .equals(selection))) { + if (this.selection == selection || (this.selection != null + && this.selection.equals(selection))) { return; } this.selection = selection; - fireSelectionChanged(new SelectionChangedEvent(this, getSelection())); + fireSelectionChanged( + new SelectionChangedEvent(this, getSelection())); } private void fireSelectionChanged(SelectionChangedEvent event) { @@ -162,6 +166,8 @@ private void fireSelectionChanged(SelectionChangedEvent event) { private int width = 0; + private ResourceManager resources; + public NotesTextEditViewer(Composite parent, IRichTextActionBarContributor contributor) { this.contributor = contributor; @@ -170,8 +176,11 @@ public NotesTextEditViewer(Composite parent, protected Composite createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); - composite.setBackground(parent.getDisplay().getSystemColor( - SWT.COLOR_WHITE)); + resources = new LocalResourceManager(JFaceResources.getResources(), + composite); + + composite.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; @@ -209,8 +218,8 @@ public void handleEvent(Event event) { } }); ToolBar toolBar = toolBarManager.createControl(parent); - toolBar.setBackground(parent.getDisplay().getSystemColor( - SWT.COLOR_WIDGET_BACKGROUND)); + toolBar.setBackground(parent.getDisplay() + .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); toolBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); return toolBar; @@ -219,8 +228,8 @@ public void handleEvent(Event event) { protected void createSeparator(Composite parent) { Label sep = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - sep.setBackground(parent.getDisplay().getSystemColor( - SWT.COLOR_WIDGET_BACKGROUND)); + sep.setBackground(parent.getDisplay() + .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); } private Composite createContentComposite(Composite parent) { @@ -279,8 +288,8 @@ private void addHyperlinkListener(TextViewer viewer) { new RichTextScanner()); reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); - reconciler - .setDocumentPartitioning(IDocumentExtension3.DEFAULT_PARTITIONING); + reconciler.setDocumentPartitioning( + IDocumentExtension3.DEFAULT_PARTITIONING); reconciler.install(viewer); } @@ -357,7 +366,8 @@ public void setInput(Object input) { } private void updateView(Object input) { - if (!(this.input instanceof IRichDocument && input instanceof IRichDocument)) { + if (!(this.input instanceof IRichDocument + && input instanceof IRichDocument)) { this.input = input; if (input == null) { this.input = getCurrentSheet(); @@ -413,8 +423,8 @@ private void resetContent() { protected void showSingleNotes(Composite parent, ITopic topic) { - textViewer = createTextViewer(parent, SWT.MULTI | SWT.WRAP - | SWT.V_SCROLL); + textViewer = createTextViewer(parent, + SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); initTextViewer(textViewer); renderer = createRenderer(textViewer); @@ -479,8 +489,9 @@ public void handleEvent(Event event) { width = sc.getClientArea().width; for (Control textControl : textControls) { if (textControl != null && !textControl.isDisposed()) { - ((GridData) textControl.getLayoutData()).widthHint = sc - .getClientArea().width - WIDTH; + ((GridData) textControl + .getLayoutData()).widthHint = sc + .getClientArea().width - WIDTH; } } contentComposite.pack(); @@ -545,8 +556,8 @@ private void createTopicLabel(Composite parent, ITopic topic) { GridData data1 = new GridData(SWT.LEFT, SWT.CENTER, false, false); imageLabel.setLayoutData(data1); imageLabel.setBackground(c.getBackground()); - Image image = MindMapUI.getImages().getTopicIcon(topic, true) - .createImage(); + Image image = (Image) resources + .get(MindMapUI.getImages().getTopicIcon(topic, true)); imageLabel.setImage(image); Label label = new Label(c, SWT.LEFT | SWT.HORIZONTAL); @@ -664,12 +675,10 @@ private void createSeparatorLine(Composite parent) { private void reveal(Composite composite) { MindMapUtils.reveal(editor, getCurrentTopic(composite)); - try { - PlatformUI.getWorkbench().getActiveWorkbenchWindow() - .getActivePage().showView(MindMapUI.VIEW_NOTES); - } catch (PartInitException e1) { - e1.printStackTrace(); - } + E4Utils.showPart(IModelConstants.COMMAND_SHOW_MODEL_PART, + PlatformUI.getWorkbench().getActiveWorkbenchWindow(), + IModelConstants.PART_ID_NOTES, null, + IModelConstants.PART_STACK_ID_RIGHT); } private void addMosuseListener(Control c, MouseListener ml) { @@ -861,7 +870,8 @@ public ISelection getSelection() { return getSelectionProvider().getSelection(); } - public void addSelectionChangedListener(ISelectionChangedListener listener) { + public void addSelectionChangedListener( + ISelectionChangedListener listener) { getSelectionProvider().addSelectionChangedListener(listener); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/RichDocumentNotesAdapter.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/RichDocumentNotesAdapter.java index 667ac163f..7a5924196 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/RichDocumentNotesAdapter.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/RichDocumentNotesAdapter.java @@ -22,6 +22,7 @@ import org.eclipse.jface.util.SafeRunnable; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.widgets.Display; import org.xmind.core.IFileEntry; import org.xmind.core.IHtmlNotesContent; @@ -33,6 +34,7 @@ import org.xmind.core.util.HyperlinkUtils; import org.xmind.ui.internal.AttachmentImageDescriptor; import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.resources.ImageUtils; import org.xmind.ui.richtext.IRichDocument; import org.xmind.ui.richtext.ImagePlaceHolder; @@ -52,7 +54,8 @@ public RichDocumentNotesAdapter(ITopic topic) { INotesContent content = notes.getContent(INotes.HTML); boolean showHTMLContent = false; if (content instanceof IHtmlNotesContent) { - showHTMLContent = !((IHtmlNotesContent) content).getParagraphs().isEmpty(); + showHTMLContent = !((IHtmlNotesContent) content).getParagraphs() + .isEmpty(); } if (!showHTMLContent) @@ -108,6 +111,10 @@ public Image getImageFromFilePath(String path) { Image image = getRegisteredImage(path); if (image == null) { image = new Image(Display.getDefault(), path); + ImageData data = image.getImageData(); + if (data.width > 280) + image = ImageUtils.createScaledImage(image, 280, + data.height * 280 / data.width); registerImage(path, image); } return image; @@ -120,6 +127,10 @@ private Image getImageFromEntryPath(String path) { if (entry != null) { image = AttachmentImageDescriptor .createFromEntry(workbook, entry).createImage(false); + ImageData data = image.getImageData(); + if (data.width > 280) + image = ImageUtils.createScaledImage(image, 280, + data.height * 280 / data.width); registerImage(path, image); } } @@ -202,4 +213,4 @@ public INotesContent makeNewPlainContent() { content.setTextContent(sb.toString()); return content; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/SheetNotesViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/SheetNotesViewer.java index e18eba029..70f293199 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/SheetNotesViewer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/notes/SheetNotesViewer.java @@ -5,10 +5,14 @@ import java.util.List; import java.util.Map; +import org.eclipse.core.runtime.SafeRunner; import org.eclipse.draw2d.ColorConstants; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.MenuManager; 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.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; @@ -34,9 +38,10 @@ import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; 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.event.CoreEvent; @@ -47,6 +52,8 @@ import org.xmind.gef.ui.editor.IGraphicalEditor; import org.xmind.ui.internal.MindMapMessages; import org.xmind.ui.internal.actions.DeleteNotesAction; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.resources.ColorUtils; import org.xmind.ui.resources.FontUtils; @@ -62,6 +69,10 @@ public class SheetNotesViewer private ISheet sheet; + private IBoundary boundary; + + private IRelationship relationship; + private Composite composite; // private ToolBarManager toolBarManager = null; @@ -99,6 +110,8 @@ public class SheetNotesViewer //storage the control of each note, used to handle mouseEnter and mouseClick event private List controls = new ArrayList(); + private ResourceManager resources; + public SheetNotesViewer(IGraphicalEditor editor) { this.editor = editor; } @@ -106,6 +119,9 @@ public SheetNotesViewer(IGraphicalEditor editor) { public Control createControl(Composite parent) { resetCollections(); composite = new Composite(parent, SWT.NONE); + resources = new LocalResourceManager(JFaceResources.getResources(), + composite); + composite.setBackground( parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); GridLayout layout = new GridLayout(); @@ -280,8 +296,8 @@ private void createNullContent(Composite parent) { Label label = new Label(composite, SWT.NONE); label.setBackground(label.getParent().getBackground()); label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); - label.setImage(MindMapUI.getImages().get("comment-empty-bg.png", true) //$NON-NLS-1$ - .createImage()); + label.setImage((Image) resources + .get(MindMapUI.getImages().get("notes-empty-bg.png", true))); //$NON-NLS-1$ Composite composite2 = new Composite(composite, SWT.NONE); composite2.setBackground(composite2.getParent().getBackground()); @@ -298,7 +314,7 @@ private void createNullContent(Composite parent) { label2.setForeground(ColorUtils.getColor("#aaaaaa")); //$NON-NLS-1$ label2.setLayoutData( new GridData(SWT.CENTER, SWT.CENTER, false, false)); - label2.setText(MindMapMessages.Comments_NoComments_text); + label2.setText(""); //$NON-NLS-1$ label2.setFont( FontUtils.getRelativeHeight(JFaceResources.DEFAULT_FONT, 2)); @@ -479,8 +495,8 @@ private void createTopicLabel(Composite parent, ITopic topic) { GridData data1 = new GridData(SWT.LEFT, SWT.CENTER, false, false); imageLabel.setLayoutData(data1); imageLabel.setBackground(c.getBackground()); - Image image = MindMapUI.getImages().getTopicIcon(topic, true) - .createImage(); + Image image = (Image) resources + .get(MindMapUI.getImages().getTopicIcon(topic, true)); imageLabel.setImage(image); Label label = new Label(c, SWT.LEFT | SWT.HORIZONTAL); @@ -623,12 +639,16 @@ private StyledText createText(Composite parent, ITopic topic) { private void reveal(Composite composite) { MindMapUtils.reveal(editor, getCurrentTopic(composite)); - try { - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() - .showView(MindMapUI.VIEW_NOTES); - } catch (PartInitException e1) { - e1.printStackTrace(); - } + SafeRunner.run(new SafeRunnable() { + + @Override + public void run() throws Exception { + E4Utils.showPart(IModelConstants.COMMAND_SHOW_MODEL_PART, + PlatformUI.getWorkbench().getActiveWorkbenchWindow(), + IModelConstants.PART_ID_NOTES, null, + IModelConstants.PART_STACK_ID_RIGHT); + } + }); } private void addMosuseListener(Control c, MouseListener ml) { @@ -675,13 +695,36 @@ private ITopic getCurrentTopic(Composite currentComposite) { } public void setInput(Object input) { - if (input instanceof ISheet && this.sheet != input) { - unhookSheet(); - unhookTitle(); - this.sheet = (ISheet) input; - hookTitle(); - hookSheet(); - update(); + if (input instanceof ISheet || input instanceof IBoundary + || input instanceof IRelationship) { + ISheet sheet = null; + if (input instanceof ISheet) { + if (this.sheet == input) + return; + sheet = (ISheet) input; + } else if (input instanceof IBoundary) { + if (this.boundary == input) + return; + unhookBoundary(); + this.boundary = (IBoundary) input; + sheet = boundary.getOwnedSheet(); + hookBoundary(); + } else if (input instanceof IRelationship) { + if (this.relationship == input) + return; + unhookRelationship(); + this.relationship = (IRelationship) input; + sheet = relationship.getOwnedSheet(); + hookRelationship(); + } + if (sheet != this.sheet) { + unhookSheet(); + unhookTitle(); + this.sheet = sheet; + hookTitle(); + hookSheet(); + update(); + } } } @@ -717,6 +760,34 @@ private void unhookSheet() { } } + private void hookBoundary() { + if (notesEventRegister == null) + notesEventRegister = new CoreEventRegister( + boundary.getAdapter(ICoreEventSupport.class), this); + notesEventRegister.register(Core.TopicNotes); + } + + private void unhookBoundary() { + if (notesEventRegister != null) { + notesEventRegister.unregisterAll(); + notesEventRegister = null; + } + } + + private void hookRelationship() { + if (notesEventRegister == null) + notesEventRegister = new CoreEventRegister( + relationship.getAdapter(ICoreEventSupport.class), this); + notesEventRegister.register(Core.TopicNotes); + } + + private void unhookRelationship() { + if (notesEventRegister != null) { + notesEventRegister.unregisterAll(); + notesEventRegister = null; + } + } + private void hookTitle() { if (titleEventRegister == null) titleEventRegister = new CoreEventRegister( @@ -761,4 +832,4 @@ public Control getControl() { return composite; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/MindMapTreePartBase.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/MindMapTreePartBase.java index d0c6e7831..9da47bcb6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/MindMapTreePartBase.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/MindMapTreePartBase.java @@ -1,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ package org.xmind.ui.internal.outline; @@ -22,7 +19,8 @@ import org.xmind.gef.tree.TreePart; import org.xmind.ui.util.MindMapUtils; -public class MindMapTreePartBase extends TreePart implements ICoreEventListener { +public class MindMapTreePartBase extends TreePart + implements ICoreEventListener { private ICoreEventRegister eventRegister = null; @@ -37,7 +35,8 @@ protected void installModelListeners() { registerCoreEvents(m, eventRegister); } - protected void registerCoreEvents(Object source, ICoreEventRegister register) { + protected void registerCoreEvents(Object source, + ICoreEventRegister register) { } public void handleCoreEvent(CoreEvent event) { @@ -61,6 +60,11 @@ protected void runInUI(Runnable job, boolean async) { } } + @Override + protected void setWidgetImage(Image image) { + /// no image + } + protected String getText() { return MindMapUtils.trimSingleLine(MindMapUtils.getText(getModel())); } @@ -69,4 +73,4 @@ protected Image getImage() { return MindMapUtils.getImage(getModel()); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/OutlineIndexModelPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/OutlineIndexModelPart.java new file mode 100644 index 000000000..abfceb31b --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/OutlineIndexModelPart.java @@ -0,0 +1,1241 @@ +package org.xmind.ui.internal.outline; + +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.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.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.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.TreeEditor; +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.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +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.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.swt.widgets.Widget; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.part.IContributedContentsView; +import org.eclipse.ui.part.PageBook; +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.CoreEvent; +import org.xmind.core.event.CoreEventRegister; +import org.xmind.core.event.ICoreEventListener; +import org.xmind.core.event.ICoreEventSource; +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.dnd.IDndClient; +import org.xmind.gef.part.IGraphicalPart; +import org.xmind.gef.part.IPart; +import org.xmind.gef.service.IRevealService; +import org.xmind.gef.service.IRevealServiceListener; +import org.xmind.gef.service.RevealEvent; +import org.xmind.gef.service.ZoomingAndPanningRevealService; +import org.xmind.gef.tree.ITreeViewer; +import org.xmind.gef.tree.TreeRootPart; +import org.xmind.gef.tree.TreeSelectTool; +import org.xmind.gef.tree.TreeViewer; +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.dnd.MindMapElementTransfer; +import org.xmind.ui.internal.e4models.ViewModelPart; +import org.xmind.ui.internal.editpolicies.ModifiablePolicy; +import org.xmind.ui.internal.outline.resource.OutlineResources; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.ITopicPart; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.tabfolder.IPageClosedListener; +import org.xmind.ui.util.MindMapUtils; + +public class OutlineIndexModelPart extends ViewModelPart + implements IPartListener, IPageChangedListener, + IContributedContentsView, IPageClosedListener, ICoreEventListener { + + private class CenteredRevealHelper implements IRevealServiceListener { + + private ZoomingAndPanningRevealService service; + + private boolean oldCentered; + + /** + * + */ + public CenteredRevealHelper(IViewer viewer) { + Object service = viewer.getService(IRevealService.class); + if (service != null + && service instanceof ZoomingAndPanningRevealService) { + this.service = (ZoomingAndPanningRevealService) service; + this.oldCentered = this.service.isCentered(); + } else { + this.service = null; + this.oldCentered = false; + } + } + + public void start(IGraphicalPart part) { + if (this.service != null) { + this.service.setCentered(true); + this.service.reveal(new StructuredSelection(part)); + this.service.addRevealServiceListener(this); + } + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.service.IRevealServiceListener#revealingStarted(org + * .xmind.gef.service.RevealEvent) + */ + public void revealingStarted(RevealEvent event) { + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.service.IRevealServiceListener#revealingCanceled(org + * .xmind.gef.service.RevealEvent) + */ + public void revealingCanceled(RevealEvent event) { + restore(); + } + + /* + * (non-Javadoc) + * @see + * org.xmind.gef.service.IRevealServiceListener#revealingFinished(org + * .xmind.gef.service.RevealEvent) + */ + public void revealingFinished(RevealEvent event) { + restore(); + } + + void restore() { + this.service.removeRevealServiceListener(this); + this.service.setCentered(this.oldCentered); + } + + } + + private class ShowWorkbookAction extends Action { + + public ShowWorkbookAction() { + super(MindMapMessages.OutlineIndexPart_ShowWorkbookAction_text, + AS_RADIO_BUTTON); + setId("org.xmind.ui.showWorkbook"); //$NON-NLS-1$ + setToolTipText( + MindMapMessages.OutlineIndexPart_ShowWorkbookAction_toolTip); + setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.WORKBOOK, true)); + setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.WORKBOOK, false)); + } + + public void run() { + + showCurrentPage = false; + showCurrentSheetAction.setChecked(showCurrentPage); + showWorkbookAction.setChecked(!showCurrentPage); + + if (sourceEditor == null) + return; + + IWorkbookRef workbookRef = sourceEditor + .getAdapter(IWorkbookRef.class); + if (workbookRef == null) + return; + + if (outlineType == OUTLINE_TYPE_NONE) { + showEditorTreeViewer(); + } else { + OutlineViewer currentViewer = getOutlineViewer(sourceEditor, + parseOutlineTypeToViewerType(outlineType)); + if (currentViewer != null + && !currentViewer.getControl().isDisposed()) { + currentViewer.setInput( + outlineResources.getResourceForWorkbook(workbookRef, + outlineType, false)); + viewerStack.showPage(currentViewer.getControl()); + } + } + + } + } + + private class ShowCurrentSheetAction extends Action { + + public ShowCurrentSheetAction() { + super(MindMapMessages.OutlineIndexPart_ShowCurrentSheetAction_text); + setId("org.xmind.ui.showCurrentSheet"); //$NON-NLS-1$ + setToolTipText( + MindMapMessages.OutlineIndexPart_ShowCurrentSheetAction_toolTip); + setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.SHEET, true)); + setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.SHEET, false)); + } + + public void run() { + + showCurrentPage = true; + showCurrentSheetAction.setChecked(showCurrentPage); + showWorkbookAction.setChecked(!showCurrentPage); + + if (sourcePage == null) + return; + + ISheet sheet = (ISheet) sourcePage.getAdapter(ISheet.class); + if (sheet == null) + return; + + if (outlineType == OUTLINE_TYPE_NONE) { + showCurrentPageViewer(); + } else { + OutlineViewer currentViewer = getOutlineViewer(sourceEditor, + parseOutlineTypeToViewerType(outlineType)); + if (currentViewer != null + && !currentViewer.getControl().isDisposed()) { + currentViewer.setInput(outlineResources + .getResourceForSheet(sheet, outlineType, false)); + viewerStack.showPage(currentViewer.getControl()); + } + } + + } + } + + private class IndexTypeAction extends Action { + + IndexTypeAction(String name) { + super(name, IAction.AS_CHECK_BOX); + } + + @Override + public void run() { + if (indexTypeToolItem != null && !indexTypeToolItem.isDisposed()) { + setOutlineType(OutlineType.findByName(getText()).getType()); + indexTypeToolItem.setText(getText()); + if (topComposite != null && !topComposite.isDisposed()) { + topComposite.pack(true); + topComposite.getParent().layout(true, true); + } + } + } + } + + public static final int OUTLINE_TYPE_NONE = 0; + public static final int OUTLINE_TYPE_BY_MARKERS = 1; + public static final int OUTLINE_TYPE_BY_LABELS = 2; + public static final int OUTLINE_TYPE_BY_STARTDATE = 3; + public static final int OUTLINE_TYPE_BY_ENDDATE = 4; + public static final int OUTLINE_TYPE_BY_ASSIGNEE = 5; + public static final int OUTLINE_TYPE_BY_AZ = 6; + public static final int OUTLINE_TYPE_BY_ZA = 7; + + private static final String VIEWMENU_ID_FOR_OUTLINEPART = "org.eclipse.ui.views.ContentOutline"; //$NON-NLS-1$ + + private CoreEventRegister coreEventRegister = new CoreEventRegister(this); + + private Composite parentComposite; + + private IGraphicalEditor sourceEditor; + + private OutlineResources outlineResources; + + private IGraphicalEditorPage sourcePage; + + private PageBook viewerStack; + + private Control defaultPage; + + private ITreeViewer editorTreeViewer; + + private Map pageViewers = new HashMap(); + + private Map> pages = new HashMap>(); + + private boolean showCurrentPage = false; + + private int outlineType = OUTLINE_TYPE_NONE; + + private Map> outlineViewers = new HashMap>(); + + private EditDomain domain; + + private IAction showWorkbookAction; + + private IAction showCurrentSheetAction; + + private MenuManager dropDownMenuManager; + + private Composite topComposite; + + private ToolItem indexTypeToolItem; + + protected void init() { + super.init(); + registerViewMenu(VIEWMENU_ID_FOR_OUTLINEPART); + } + + protected Control doCreateContent(Composite parent) { + this.parentComposite = parent; + + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + 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)); + + topComposite = createTopComposite(composite); + + new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL) + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + Composite contentComposite = new Composite(composite, SWT.NONE); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.verticalSpacing = 0; + gridLayout.horizontalSpacing = 0; + contentComposite.setLayout(gridLayout); + contentComposite + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + viewerStack = new PageBook(contentComposite, SWT.NONE); + viewerStack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + defaultPage = createDefaultPage(viewerStack); + viewerStack.showPage(defaultPage); + + IWorkbenchWindow window = getAdapter(IWorkbenchWindow.class); + if (window != null) { + IWorkbenchPage activePage = window.getActivePage(); + if (activePage != null) { + partActivated(activePage.getActiveEditor()); + activePage.addPartListener(this); + } + } + return composite; + } + + private Composite createTopComposite(Composite composite) { + Composite topComposite = new Composite(composite, SWT.RIGHT); + topComposite.setBackground( + topComposite.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = 2; + layout.marginHeight = 0; + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + topComposite.setLayout(layout); + topComposite + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + showWorkbookAction = new ShowWorkbookAction(); + showCurrentSheetAction = new ShowCurrentSheetAction(); + + showWorkbookAction.setChecked(!isShowCurrentPage()); + showCurrentSheetAction.setChecked(isShowCurrentPage()); + + ToolBarManager toolBarManager = new ToolBarManager(); + toolBarManager.add(showWorkbookAction); + toolBarManager.add(showCurrentSheetAction); + + ToolBar leftToolBar = toolBarManager.createControl(topComposite); + leftToolBar.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + + ToolBar rightToolBar = new ToolBar(topComposite, SWT.NONE); + rightToolBar + .setLayoutData(new GridData(SWT.END, SWT.CENTER, true, false)); + + indexTypeToolItem = new ToolItem(rightToolBar, SWT.DROP_DOWN); + indexTypeToolItem.setText(OutlineType.None.getName()); + + indexTypeToolItem.addListener(SWT.Dispose, getToolItemListener()); + indexTypeToolItem.addListener(SWT.Selection, getToolItemListener()); + + return topComposite; + } + + private Listener getToolItemListener() { + return new Listener() { + + public void handleEvent(Event event) { + switch (event.type) { + case SWT.Dispose: + handleWidgetDispose(event); + break; + case SWT.Selection: + Widget ew = event.widget; + if (ew != null) { + handleWidgetSelection(event, + ((ToolItem) ew).getSelection()); + } + break; + } + } + }; + } + + private void handleWidgetSelection(Event event, boolean selection) { + if (event.widget instanceof ToolItem) { + ToolItem item = (ToolItem) event.widget; + MenuManager menuMan = getDropDownMenuManager(); + Menu menu = menuMan.createContextMenu(item.getParent()); + if (menu != null) { + Rectangle b = item.getBounds(); + Point p = item.getParent().toDisplay(b.x, b.y + b.height); + menu.setLocation(p.x, p.y); + menu.setVisible(true); + } + } + + } + + private MenuManager getDropDownMenuManager() { + if (dropDownMenuManager == null) { + dropDownMenuManager = new MenuManager(); + dropDownMenuManager.setRemoveAllWhenShown(true); + dropDownMenuManager.addMenuListener(new IMenuListener() { + + public void menuAboutToShow(IMenuManager manager) { + for (String name : OutlineType.getNames()) { + manager.add(new IndexTypeAction(name)); + } + } + }); + } + return dropDownMenuManager; + } + + private void handleWidgetDispose(Event event) { + if (event.widget instanceof ToolItem) { + if (dropDownMenuManager != null) { + dropDownMenuManager.dispose(); + dropDownMenuManager = null; + } + } + } + + private OutlineViewer getOutlineViewer(IGraphicalEditor editor, + String viewerType) { + Map typeToViewers = outlineViewers.get(editor); + if (typeToViewers == null) + return null; + return typeToViewers.get(viewerType); + } + + private String parseOutlineTypeToViewerType(int outlineType) { + if (outlineType == OUTLINE_TYPE_BY_STARTDATE + || outlineType == OUTLINE_TYPE_BY_ENDDATE) + return OutlineViewer.VIEWERTYPE_MULITCOLUMN; + if (outlineType == OUTLINE_TYPE_BY_MARKERS + || outlineType == OUTLINE_TYPE_BY_LABELS + || outlineType == OUTLINE_TYPE_BY_ASSIGNEE + || outlineType == OUTLINE_TYPE_BY_AZ + || outlineType == OUTLINE_TYPE_BY_ZA) + return OutlineViewer.VIEWERTYPE_SINGLECOLUMN; + return null; + } + + private void registerCoreEventForEditor() { + if (sourceEditor != null) { + IWorkbook workbook = (IWorkbook) sourceEditor + .getAdapter(IWorkbook.class); + if (workbook instanceof ICoreEventSource) { + coreEventRegister = new CoreEventRegister( + (ICoreEventSource) workbook, this); + coreEventRegister.register(Core.ModifyTime); + coreEventRegister.register(Core.WorkbookSave); + } + } + } + + public OutlineResources getOutlineResources() { + return outlineResources; + } + + public boolean isShowCurrentPage() { + return showCurrentPage; + } + + public void setOutlineType(int type) { + if (type == OUTLINE_TYPE_NONE) { + outlineType = type; + if (isShowCurrentPage()) { + showCurrentPageViewer(); + } else { + showEditorTreeViewer(); + } + } else { + String oldViewerType = parseOutlineTypeToViewerType(outlineType); + OutlineViewer oldViewer = getOutlineViewer(sourceEditor, + oldViewerType); + + this.outlineType = type; + + String viewerType = parseOutlineTypeToViewerType(type); + OutlineViewer newViewer = getOutlineViewer(sourceEditor, + viewerType); + if (newViewer == null) { + newViewer = createOutlineViewer(viewerStack, viewerType); + Map typeToViewer = outlineViewers + .get(sourceEditor); + typeToViewer.put(viewerType, newViewer); + } + outlineViewerChanged(oldViewer, newViewer); + } + } + + protected void dispose() { + setEditor(null); + IWorkbenchWindow window = getAdapter(IWorkbenchWindow.class); + if (window != null) { + window.getActivePage().removePartListener(this); + } + for (Object editor : pages.keySet().toArray()) { + partClosed((IGraphicalEditor) editor); + } + coreEventRegister.unregisterAll(); + super.dispose(); + } + + private Composite createDefaultPage(Composite parent) { + Composite page = new Composite(parent, SWT.NONE); + page.setLayout(new GridLayout(1, false)); + + Label label = new Label(page, SWT.LEFT | SWT.WRAP); + label.setText(MindMapMessages.OutlineIndexPart_DefaultPage_message); + label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return page; + } + + protected void setFocus() { + OutlineViewer outlineViewer = getOutlineViewer(sourceEditor, + parseOutlineTypeToViewerType(outlineType)); + if (outlineViewer != null && !outlineViewer.getControl().isDisposed()) { + outlineViewer.setFocus(); + } else if (viewerStack != null && !viewerStack.isDisposed()) { + viewerStack.setFocus(); + } else if (parentComposite != null && !parentComposite.isDisposed()) { + parentComposite.setFocus(); + } + } + + public IWorkbenchPart getContributingPart() { + return sourceEditor; + } + + public void pageClosed(Object pageObject) { + if (pageObject instanceof IGraphicalEditorPage) { + IGraphicalEditorPage page = (IGraphicalEditorPage) pageObject; + unregisterSourcePage(page); + } + } + + 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; + setSourcePage(page); + } + }); + } + + public void partActivated(final IWorkbenchPart part) { + if (!(part instanceof IGraphicalEditor)) + return; + + Display.getCurrent().asyncExec(new Runnable() { + + public void run() { + setEditor((IGraphicalEditor) part); + } + }); + } + + private void setEditor(IGraphicalEditor editor) { + if (editor == this.sourceEditor) + return; + + if (this.sourceEditor != null) { + this.sourceEditor.removePageChangedListener(this); + } + + this.sourceEditor = editor; + this.outlineResources = editor == null ? null : new OutlineResources(); + registerCoreEventForEditor(); + + if (editor != null && domain == null) { + domain = new EditDomain(); + domain.installTool(GEF.TOOL_SELECT, new TreeSelectTool()); + domain.setCommandStack(sourceEditor.getCommandStack()); + domain.installEditPolicy(MindMapUI.POLICY_MODIFIABLE, + new ModifiablePolicy()); + } + + if (this.sourceEditor != null) { + if (!outlineViewers.containsKey(sourceEditor)) { + outlineViewers.put(sourceEditor, + new HashMap()); + } + this.sourceEditor.addPageChangedListener(this); + setSourcePage(this.sourceEditor.getActivePageInstance()); + } else { + setSourcePage(null); + viewerStack.showPage(defaultPage); + } + } + + private void setSourcePage(IGraphicalEditorPage page) { + if (page == this.sourcePage) + return; + + this.sourcePage = page; + + if (viewerStack != null && !viewerStack.isDisposed()) { + Control pageToShow = defaultPage; + if (this.sourcePage != null) { + if (outlineType == OUTLINE_TYPE_NONE) { + if (isShowCurrentPage()) + showCurrentPageViewer(); + else + showEditorTreeViewer(); + } else { + OutlineViewer viewer = ensureOutlineViewer(this.sourcePage); + if (viewer != null && !viewer.getControl().isDisposed()) { + pageToShow = viewer.getControl(); + } + viewerStack.showPage(pageToShow); + } + } + } + } + + private void showEditorTreeViewer() { + if (editorTreeViewer == null || editorTreeViewer.getControl() == null + || editorTreeViewer.getControl().isDisposed()) { + editorTreeViewer = createEditorTreeViewer(); + if (editorTreeViewer != null) { + configureEditorTreeViewer(editorTreeViewer); + createEditorTreeViewerControl(editorTreeViewer, viewerStack); + editorTreeViewer + .setInput(sourceEditor.getAdapter(IWorkbook.class)); + } + } + if (editorTreeViewer != null) { + Object newInput = sourceEditor.getAdapter(IWorkbook.class); + if (newInput != editorTreeViewer.getInput()) { + editorTreeViewer.setInput(newInput); + } + viewerStack.showPage(editorTreeViewer.getControl()); + } + + } + + private void showCurrentPageViewer() { + IGraphicalEditorPage page = sourceEditor.getActivePageInstance(); + if (page == null) { + viewerStack.showPage(defaultPage); + 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, viewerStack); + pageTreeViewer.setInput(pageInput); + } + } + if (pageTreeViewer != null) { + Object newInput = pageInput; + if (newInput != pageTreeViewer.getInput()) { + pageTreeViewer.setInput(newInput); + } + viewerStack.showPage(pageTreeViewer.getControl()); + } + } + + private TreeViewer createEditorTreeViewer() { + MindMapTreeViewer viewer = new MindMapTreeViewer(); + viewer.getProperties().set(ITreeViewer.PROP_HEADER_VISIBLE, false); + return viewer; + } + + private ITreeViewer createPageTreeViewer() { + MindMapTreeViewer viewer = new MindMapTreeViewer(); + viewer.getProperties().set(ITreeViewer.PROP_HEADER_VISIBLE, false); + return viewer; + } + + private Control createEditorTreeViewerControl(ITreeViewer viewer, + Composite parent) { + Control control = ((TreeViewer) viewer).createControl(parent, + SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); + hookViewerControl(viewer, control); + return control; + } + + private Control createPageTreeViewerControl(ITreeViewer viewer, + Composite parent) { + Control control = ((TreeViewer) viewer).createControl(parent, + SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); + hookViewerControl(viewer, control); + return control; + } + + private void configureEditorTreeViewer(ITreeViewer viewer) { + configureTreeViewer(viewer); + } + + private void configurePageTreeViewer(ITreeViewer viewer) { + configureTreeViewer(viewer); + } + + protected void configureTreeViewer(ITreeViewer viewer) { +// viewer.addSelectionChangedListener(this); + viewer.setEditDomain(domain); + viewer.setPartFactory(MindMapUI.getMindMapTreePartFactory()); + viewer.setRootPart(new TreeRootPart()); + } + + private void outlineViewerChanged(OutlineViewer oldViewer, + OutlineViewer newViewer) { + if (newViewer != null && !newViewer.getControl().isDisposed() + && sourceEditor != null && sourcePage != null) { + IWorkbookRef workbookRef = sourceEditor + .getAdapter(IWorkbookRef.class); + Object resourceForWorkbook = outlineResources + .getResourceForWorkbook(workbookRef, outlineType, true); + + ISheet sheet = (ISheet) sourcePage.getAdapter(ISheet.class); + Object resourceForSheet = outlineResources + .getResourceForSheet(sheet, outlineType, true); + if (showCurrentPage) { + newViewer.setInput(resourceForSheet); + } else { + newViewer.setInput(resourceForWorkbook); + + } + if (oldViewer != newViewer) { +// IWorkbenchPartSite site = getViewSite(); +// if (site != null) +// site.setSelectionProvider(newViewer); + if (viewerStack != null && !viewerStack.isDisposed()) { + viewerStack.showPage(newViewer.getControl()); + } + } + } + } + + private OutlineViewer ensureOutlineViewer(IGraphicalEditorPage page) { + String viewerType = parseOutlineTypeToViewerType(outlineType); + OutlineViewer viewer = getOutlineViewer(sourceEditor, viewerType); + if (viewer == null) { + if (sourceEditor != null) { + viewer = createOutlineViewer(viewerStack, viewerType); + registerSourcePage(page); + Map typeToViewer = outlineViewers + .get(sourceEditor); + typeToViewer.put(viewerType, viewer); + } + } + + if (viewer != null) { + if (showCurrentPage) { + ISheet sheet = (ISheet) page.getAdapter(ISheet.class); + if (sheet != null && viewer.getInput() != outlineResources + .getResourceForSheet(sheet, outlineType, true)) + viewer.setInput(outlineResources.getResourceForSheet(sheet, + outlineType, true)); + } else { + IWorkbookRef workbookRef = page.getParentEditor() + .getAdapter(IWorkbookRef.class); + Object newInput = outlineResources + .getResourceForWorkbook(workbookRef, outlineType, true); + if (workbookRef != null && viewer.getInput() != newInput) + viewer.setInput(newInput); + } + } + return viewer; + } + + private void registerSourcePage(IGraphicalEditorPage page) { + IGraphicalEditor editor = page.getParentEditor(); + Collection list = pages.get(editor); + if (list == null) { + list = new HashSet(); + pages.put(editor, list); + } + list.add(page); + } + + private void unregisterSourcePage(IGraphicalEditorPage page) { + IGraphicalEditor editor = page.getParentEditor(); + Collection list = pages.get(editor); + if (list != null) { + list.remove(page); + if (list.isEmpty()) { + pages.remove(editor); + } + } + } + + private OutlineViewer createOutlineViewer(PageBook parent, + String viewerType) { + final OutlineViewer viewer = new OutlineViewer(parent, viewerType); + viewer.setAutoExpandLevel(4); + viewer.getTree().setLinesVisible(true); + + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + + @Override + 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) { + reveal((ITopic) element); + } + } + } + }); + + viewer.addDoubleClickListener(new IDoubleClickListener() { + + public void doubleClick(DoubleClickEvent event) { +// handleDoubleClick(viewer.getTree()); + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + Object element = ss.getFirstElement(); + if (element instanceof ITopic) { + handleDoubleClick(viewer.getTree(), + MindMapUtils.findTopicPart( + sourceEditor.getAdapter( + IGraphicalViewer.class), + (ITopic) element)); + } + } + } + }); + viewer.getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return viewer; + } + + private void reveal(ITopic topic) { + if (sourceEditor == null) + return; + + sourceEditor.getSite().getPage().activate(sourceEditor); + if (topic != null) { + ISelectionProvider selectionProvider = sourceEditor.getSite() + .getSelectionProvider(); + if (selectionProvider != null) { + selectionProvider.setSelection(new StructuredSelection(topic)); + } + + Object selectedPage = sourceEditor.getSelectedPage(); + if (selectedPage instanceof IGraphicalEditorPage) { + IGraphicalEditorPage page = (IGraphicalEditorPage) selectedPage; + IGraphicalViewer viewer = page.getViewer(); + if (viewer == null) + return; + + IPart selectedPart = viewer.getFocusedPart(); + if (selectedPart instanceof IGraphicalPart) { + IGraphicalPart part = (IGraphicalPart) selectedPart; + new CenteredRevealHelper(viewer).start(part); + } + } + + } + } + + private void disposeOutlineViewer(OutlineViewer viewer) { + if (viewer != null && viewer.getControl() != null) { + viewer.getControl().dispose(); + viewer = null; + } + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partClosed(IWorkbenchPart part) { + if (!(part instanceof IGraphicalEditor)) + return; + + Collection oldPages = pages.remove(part); + if (part == this.sourceEditor) { + setEditor(null); + + } + if (oldPages != null) { + for (Object page : oldPages.toArray()) { + pageClosed(page); + } + } + + Map typeToViewer = outlineViewers.remove(part); + if (typeToViewer != null) + for (OutlineViewer viewer : typeToViewer.values()) { + disposeOutlineViewer(viewer); + } + } + + public void partDeactivated(IWorkbenchPart part) { + } + + public void partOpened(IWorkbenchPart part) { + } + + public void handleCoreEvent(CoreEvent event) { + if (sourceEditor == null) + return; + + final String type = event.getType(); + if (viewerStack != null && !viewerStack.isDisposed()) + viewerStack.getDisplay().asyncExec(new Runnable() { + + public void run() { + if (Core.WorkbookSave.equals(type)) { + OutlineViewer currentViewer = getOutlineViewer( + sourceEditor, + parseOutlineTypeToViewerType(outlineType)); + if (currentViewer != null) { + currentViewer.refresh(); + } + } else if (Core.ModifyTime.equals(type)) { + if (sourceEditor != null) { + IWorkbookRef workbookRef = sourceEditor + .getAdapter(IWorkbookRef.class); + Object resourceForWorkbook = outlineResources + .getResourceForWorkbook(workbookRef, + outlineType, true); + Object resourceForSheet = null; + if (sourcePage != null) { + ISheet sheet = (ISheet) sourcePage + .getAdapter(ISheet.class); + resourceForSheet = outlineResources + .getResourceForSheet(sheet, outlineType, + true); + } + OutlineViewer currentViewer = getOutlineViewer( + sourceEditor, + parseOutlineTypeToViewerType(outlineType)); + if (currentViewer != null) { + Control control = currentViewer.getControl(); + if (control != null && !control.isDisposed()) { + if (!showCurrentPage) { + if (resourceForWorkbook != null) + currentViewer.setInput( + resourceForWorkbook); + } else { + if (resourceForSheet != null) + currentViewer + .setInput(resourceForSheet); + } + } + } + } + } + } + }); + } + + private void hookViewerControl(final IViewer viewer, + final Control control) { + final DragSource dragSource = new DragSource(control, + DND.DROP_COPY | DND.DROP_MOVE); + dragSource.setTransfer( + new Transfer[] { MindMapElementTransfer.getInstance(), + TextTransfer.getInstance() }); + dragSource.addDragListener(new DragSourceListener() { + + Object[] elements; + + String text; + + public void dragStart(DragSourceEvent event) { + elements = getElements(); + if (elements == null || elements.length == 0) + event.doit = false; + else + text = createText(elements); + } + + private Object[] getElements() { + if (control instanceof Tree) { + TreeItem[] selection = ((Tree) control).getSelection(); + if (selection.length > 0) { + Object[] elements = new Object[selection.length]; + for (int i = 0; i < selection.length; i++) { + TreeItem item = selection[i]; + Object data = item.getData(); + if (data instanceof IPart) { + data = ((IPart) data).getModel(); + } + elements[i] = data; + } + return elements; + } + } + return null; + } + + public void dragSetData(DragSourceEvent event) { + if (MindMapElementTransfer.getInstance() + .isSupportedType(event.dataType)) { + event.data = elements; + } else if (TextTransfer.getInstance() + .isSupportedType(event.dataType)) { + event.data = text; + } + } + + private String createText(Object[] elements) { + IDndClient textClient = MindMapUI.getMindMapDndSupport() + .getDndClient(MindMapUI.DND_TEXT); + if (textClient == null) + return null; + + Object data = textClient.toTransferData(elements, viewer); + return data instanceof String ? (String) data : null; + } + + public void dragFinished(DragSourceEvent event) { + } + + }); + control.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(DisposeEvent e) { + dragSource.dispose(); + } + }); + + control.addListener(SWT.MouseDown, new Listener() { + + @Override + public void handleEvent(Event event) { + Tree tree = (Tree) control; + TreeItem[] selection = tree.getSelection(); + if (selection.length == 0) + return; + + TreeItem item = selection[0]; + if (!(item.getData() instanceof TopicTreePart)) + return; + + TopicTreePart part = (TopicTreePart) item.getData(); + reveal(part.getTopic()); + } + }); + + control.addListener(SWT.MouseDoubleClick, new Listener() { + + public void handleEvent(Event event) { + handleDoubleClick(control, null); + event.doit = false; + } + + }); + } + + private void handleDoubleClick(Control control, ITopicPart topicPart) { + startEditing(control, topicPart); + } + + private void startEditing(Control control, final ITopicPart topicPart) { + Tree tree = (Tree) control; + TreeItem[] selection = tree.getSelection(); + + if (selection.length == 0) + return; + final TreeItem item = selection[0]; + + if (!(item.getData() instanceof TopicTreePart) && topicPart == null) { + return; + } + + TreeEditor editor = new TreeEditor(tree) { + @Override + public void layout() { + super.layout(); + Control editor = getEditor(); + if (editor == null || editor.isDisposed()) + return; + Rectangle bounds = editor.getBounds(); + Point prefSize = editor.computeSize(SWT.DEFAULT, SWT.DEFAULT); + if (prefSize.y > bounds.height) { + bounds.y += (bounds.height - prefSize.y - 1) / 2; + bounds.height = prefSize.y; + } + editor.setBounds(bounds); + } + }; + editor.horizontalAlignment = SWT.LEFT; + editor.grabHorizontal = true; + editor.minimumWidth = 50; + + final Text text = new Text(tree, SWT.SINGLE | SWT.BORDER); + text.setCursor(Display.getCurrent().getSystemCursor(SWT.CURSOR_IBEAM)); + editor.setEditor(text, item); + + final String oldValue = item.getText(); + text.setText(oldValue); + text.setFocus(); + text.selectAll(); + + text.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + if (item != null && !item.isDisposed()) { + item.setText( + text.getText() == null ? oldValue : text.getText()); + modifyTreeItem(item, topicPart); + } + + // This async process fixes a bug on Leopard: + // Whole workbench crashes + e.display.asyncExec(new Runnable() { + public void run() { + text.dispose(); + } + }); + + } + }); + + text.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + switch (e.character) { + case SWT.ESC: + item.setText(oldValue); + + // This async process fixes a bug on Leopard: + // Whole workbench crashes + e.display.asyncExec(new Runnable() { + public void run() { + text.dispose(); + } + }); + + break; + case SWT.CR: + if (item != null && !item.isDisposed()) { + item.setText(text.getText() == null ? oldValue + : text.getText()); + modifyTreeItem(item, topicPart); + } + + // This async process fixes a bug on Leopard: + // Whole workbench crashes + e.display.asyncExec(new Runnable() { + public void run() { + text.dispose(); + } + }); + + break; + } + } + }); + + item.addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + if (text != null && !text.isDisposed()) + text.dispose(); + } + }); + + } + + private void modifyTreeItem(TreeItem item, ITopicPart topicPart) { + if (topicPart != null) { + topicPart.handleRequest( + new Request(GEF.REQ_MODIFY) + .setViewer(topicPart.getSite().getViewer()) + .setParameter(GEF.PARAM_TEXT, item.getText()) + .setPrimaryTarget(topicPart), + GEF.ROLE_MODIFIABLE); + } + + Object o = item.getData(); + if (o instanceof IPart) { + IPart part = (IPart) o; + part.handleRequest(new Request(GEF.REQ_MODIFY) + .setViewer(part.getSite().getViewer()) + .setParameter(GEF.PARAM_TEXT, item.getText()) + .setPrimaryTarget(part), GEF.ROLE_MODIFIABLE); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/OutlineType.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/OutlineType.java new file mode 100644 index 000000000..ae799d74c --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/OutlineType.java @@ -0,0 +1,59 @@ +package org.xmind.ui.internal.outline; + +import org.xmind.ui.internal.MindMapMessages; + +public enum OutlineType { + + None(MindMapMessages.OutlineType_None, + OutlineIndexModelPart.OUTLINE_TYPE_NONE), // + ByAZ("A ~ Z", OutlineIndexModelPart.OUTLINE_TYPE_BY_AZ), // //$NON-NLS-1$ + ByZA("Z ~ A", OutlineIndexModelPart.OUTLINE_TYPE_BY_ZA), // //$NON-NLS-1$ + ByMarkers(MindMapMessages.OutlineType_Markers, + OutlineIndexModelPart.OUTLINE_TYPE_BY_MARKERS), // + ByLabels(MindMapMessages.OutlineType_Labels, + OutlineIndexModelPart.OUTLINE_TYPE_BY_LABELS), // + ByStartDate(MindMapMessages.OutlineType_StartDate, + OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE), // + ByEndDate(MindMapMessages.OutlineType_EndDate, + OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE), // + ByAssignee(MindMapMessages.OutlineType_Assignee, + OutlineIndexModelPart.OUTLINE_TYPE_BY_ASSIGNEE); + + private String name; + + private int type; + + private OutlineType(String name, int type) { + this.name = name; + this.type = type; + } + + public String getName() { + return name; + } + + public int getType() { + return type; + } + + public static String[] getNames() { + OutlineType[] instances = values(); + String[] ids = new String[instances.length]; + for (int i = 0; i < instances.length; i++) + ids[i] = instances[i].getName(); + return ids; + } + + public static OutlineType findByName(String name) { + if (name == null) + return null; + + for (OutlineType outlineType : values()) { + if (outlineType.getName().equals(name)) + return outlineType; + } + + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/OutlineViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/OutlineViewer.java new file mode 100644 index 000000000..bdb6604ce --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/OutlineViewer.java @@ -0,0 +1,437 @@ +package org.xmind.ui.internal.outline; + +import java.net.URL; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +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.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +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.internal.MindMapUIPlugin; +import org.xmind.ui.internal.outline.resource.IAZResource; +import org.xmind.ui.internal.outline.resource.IAssigneeResource; +import org.xmind.ui.internal.outline.resource.ILabelResource; +import org.xmind.ui.internal.outline.resource.IMarkerResource; +import org.xmind.ui.internal.outline.resource.IOutlineResource; +import org.xmind.ui.internal.outline.resource.ITaskDateResource; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MarkerImageDescriptor; + +public class OutlineViewer extends TreeViewer { + + public static final String VIEWERTYPE_SINGLECOLUMN = "singleColumn"; //$NON-NLS-1$ + + public static final String VIEWERTYPE_MULITCOLUMN = "multiColumn"; //$NON-NLS-1$ + + private class OutlineContentProvider implements ITreeContentProvider { + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + if (newInput instanceof ITaskDateResource) { + int taskDateType = ((ITaskDateResource) newInput) + .getTaskDateResourceType(); + Tree tree = getTree(); + if (tree != null && !tree.isDisposed()) { + TreeColumn column = tree.getColumn(1); + if (column != null && !column.isDisposed()) + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) { + column.setText( + MindMapMessages.OutlineViewer_StartDate_col); + } else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + column.setText( + MindMapMessages.OutlineViewer_EndData_col); + } + } + } + + public Object[] getElements(Object inputElement) { + if (inputElement instanceof ITaskDateResource) { + return ((ITaskDateResource) inputElement) + .getAllTopicsForTaskDate().toArray(); + } + if (inputElement instanceof IOutlineResource) { + IOutlineResource input = (IOutlineResource) inputElement; + return new Object[] { input.getSource() }; + } + return null; + } + + public Object[] getChildren(Object parentElement) { + Object input = getInput(); + if (input instanceof IMarkerResource) { + IMarkerResource resource = (IMarkerResource) input; + return getChildrenForMarkerResource(resource, parentElement); + } else if (input instanceof ILabelResource) { + ILabelResource resource = (ILabelResource) input; + return getChildrenForLabelResource(resource, parentElement); + } else if (input instanceof IAssigneeResource) { + return getChildrenForAssigneeResource((IAssigneeResource) input, + parentElement); + } else if (input instanceof ITaskDateResource) { + return null; + } else if (input instanceof IAZResource) { + if (parentElement instanceof IWorkbookRef + || parentElement instanceof ISheet) + return ((IAZResource) input).getTopics().toArray(); + } + return null; + } + + public Object getParent(Object element) { + Object input = getInput(); + if (input instanceof IMarkerResource) { + IMarkerResource resource = (IMarkerResource) input; + return getParentForMarkerResource(resource, element); + } else if (input instanceof ILabelResource) { + ILabelResource resource = (ILabelResource) input; + return getParentForLabelResource(resource, element); + } else if (input instanceof IAssigneeResource) { + return getParentForAssigneeResource((IAssigneeResource) input, + element); + } else if (input instanceof ITaskDateResource) { + return null; + } else if (input instanceof IAZResource) { + if (element instanceof ITopic) + return ((IAZResource) input).getSource(); + } + return null; + } + + public boolean hasChildren(Object element) { + Object input = getInput(); + if (input instanceof IMarkerResource) { + return (element instanceof IWorkbookRef) + || (element instanceof ISheet) + || (element instanceof IMarkerGroup) + || (element instanceof IMarker); + } else if (input instanceof ILabelResource) { + return (element instanceof IWorkbookRef) + || (element instanceof ISheet) + || (element instanceof String); + } else if (input instanceof IAssigneeResource) { + return (element instanceof IWorkbookRef) + || (element instanceof ISheet) + || (element instanceof String); + } else if (input instanceof IAZResource) { + return (element instanceof IWorkbookRef) + || (element instanceof ISheet); + } + return false; + } + + private Object[] getChildrenForMarkerResource(IMarkerResource resource, + Object parentElement) { + Set ids = resource.getMarkerIds(); + if (parentElement instanceof IMarkerGroup) { + Set childrenIds = new HashSet(); + for (String id : ids) { + IMarker marker = resource.getMarker(id); + if (marker.getParent() == parentElement) { + childrenIds.add(marker); + } + } + return childrenIds.toArray(); + } else if (parentElement instanceof IMarker) { + return resource.getTopics(((IMarker) parentElement).getId()) + .toArray(); + } else if ((parentElement instanceof IWorkbookRef) + || (parentElement instanceof ISheet)) { + Set group = new HashSet(); + for (String markerId : ids) { + IMarker marker = resource.getMarker(markerId); + group.add(marker.getParent()); + } + return group.toArray(); + } + return null; + } + + private Object[] getChildrenForLabelResource(ILabelResource resource, + Object parentElement) { + if (parentElement instanceof IWorkbookRef + || parentElement instanceof ISheet) { + return resource.getLabels().toArray(); + } else if (parentElement instanceof String) { + return resource.getTopics((String) parentElement).toArray(); + } + return null; + } + + private Object[] getChildrenForAssigneeResource( + IAssigneeResource resource, Object parentElement) { + if (parentElement instanceof IWorkbookRef + || parentElement instanceof ISheet) { + return resource.getAssignees().toArray(); + } else if (parentElement instanceof String) { + return resource.getTopics((String) parentElement).toArray(); + } + return null; + } + + private Object getParentForMarkerResource(IMarkerResource resource, + Object element) { + if (element instanceof IMarkerGroup) { + return resource.getSource(); + } else if (element instanceof IMarker) { + return ((IMarker) element).getParent(); + } else if (element instanceof ITopic) { + Set ids = resource.getMarkerIds(); + for (String markerId : ids) { + if (resource.getTopics(markerId).contains(element)) { + IMarker marker = resource.getMarker(markerId); + return marker; + } + } + } + return null; + } + + private Object getParentForLabelResource(ILabelResource resource, + Object element) { + if (element instanceof String) { + return resource.getSource(); + } else if (element instanceof ITopic) { + Set labels = resource.getLabels(); + for (String lab : labels) { + if (resource.getTopics(lab).contains(element)) + return lab; + } + } + return null; + } + + private Object getParentForAssigneeResource(IAssigneeResource resource, + Object element) { + if (element instanceof String) { + return resource.getSource(); + } else if (element instanceof ITopic) { + Set assignees = resource.getAssignees(); + for (String assignee : assignees) { + if (resource.getTopics(assignee).contains(element)) + return assignee; + } + } + return null; + } + } + + private class OutlineLabelProvider extends LabelProvider { + + public String getText(Object element) { + if (element instanceof IWorkbookRef) { + return ((IWorkbookRef) element).getName(); + } else if (element instanceof ISheet) { + return ((ISheet) element).getTitleText(); + } else if (element instanceof IMarkerGroup) { + return ((IMarkerGroup) element).getName(); + } else if (element instanceof IMarker) { + return ((IMarker) element).getName(); + } else if (element instanceof ITopic) { + return ((ITopic) element).getTitleText(); + } else if (element instanceof String) { + return (String) element; + } + return super.getText(element); + } + + public Image getImage(Object element) { + if (element instanceof IWorkbookRef) { + ImageDescriptor imageDescriptor = MindMapUI.getImages() + .get(IMindMapImages.WORKBOOK, true); + return localResourceManager.createImage(imageDescriptor); + } else if (element instanceof ISheet) { + return localResourceManager.createImage( + MindMapUI.getImages().get(IMindMapImages.SHEET, true)); + } else if (element instanceof ITopic) { +// return localResourceManager.createImage(MindMapUI.getImages() +// .getTopicIcon((ITopic) element, true)); + } else if (element instanceof IMarker) { + ImageDescriptor imageDescriptor = MarkerImageDescriptor + .createFromMarker((IMarker) element); + return localResourceManager.createImage(imageDescriptor); + } + Object input = getInput(); + if (input instanceof ILabelResource) { + if (element instanceof String) + return localResourceManager.createImage(MindMapUI + .getImages().get(IMindMapImages.LABEL, true)); + } else if (input instanceof IAssigneeResource) { + if (element instanceof String) { + URL url = FileLocator.find( + Platform.getBundle(MindMapUIPlugin.PLUGIN_ID), + new Path("$nl$/icons/assignee.gif"), null); //$NON-NLS-1$ + return localResourceManager + .createImage(ImageDescriptor.createFromURL(url)); + } + } + return super.getImage(element); + } + + } + + private class OutlineViewerSorter extends ViewerComparator { + + public int category(Object element) { + if (element instanceof IWorkbookRef || element instanceof ISheet) + return 1; + else if (element instanceof IMarkerGroup) + return 2; + else if (element instanceof IMarker) + return 4; + else if (element instanceof String) + return 8; + else if (element instanceof ITopic) + return 16; + return super.category(element); + } + + public int compare(Viewer viewer, Object e1, Object e2) { + + Object input = getInput(); + if (input instanceof ITaskDateResource) { + ITaskDateResource resource = (ITaskDateResource) input; + if (e1 instanceof ITopic && e2 instanceof ITopic) { + String pTaskDate = resource.getTaskDate((ITopic) e1); + String qTaskDate = resource.getTaskDate((ITopic) e2); + int compareDate = super.compare(viewer, pTaskDate, + qTaskDate); + return compareDate == 0 ? super.compare(viewer, e1, e2) + : compareDate; + + } + } + + if (input instanceof IAZResource) { + if (e1 instanceof ITopic && e2 instanceof ITopic) { + if (((IAZResource) input).isPositiveSequence()) + return super.compare(viewer, e1, e2); + else + return super.compare(viewer, e2, e1); + } + } + + if (e1 instanceof IMarkerGroup && e2 instanceof IMarkerGroup) { + IMarkerSheet pSheet = ((IMarkerGroup) e1).getOwnedSheet(); + IMarkerSheet qSheet = ((IMarkerGroup) e2).getOwnedSheet(); + + if (pSheet == qSheet) { + List markerGroups = pSheet.getMarkerGroups(); + return markerGroups.indexOf(e1) - markerGroups.indexOf(e2); + } else { + if (MindMapUI.getResourceManager() + .getSystemMarkerSheet() == pSheet) + return -10000; + else + return 10000; + } + + } else if (e1 instanceof IMarker && e2 instanceof IMarker) { + IMarkerGroup pMarkerGroup = ((IMarker) e1).getParent(); + IMarkerGroup qMarkerGroup = ((IMarker) e2).getParent(); + + if (pMarkerGroup == qMarkerGroup && pMarkerGroup != null) { + List markers = pMarkerGroup.getMarkers(); + return markers.indexOf(e1) - markers.indexOf(e2); + } + } + + return super.compare(viewer, e1, e2); + } + } + + private String viewerType; + + private LocalResourceManager localResourceManager; + + public OutlineViewer(Composite parent, String viewerType) { + super(parent, + SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); + this.viewerType = viewerType; + localResourceManager = new LocalResourceManager( + JFaceResources.getResources(), parent); + initViewer(viewerType); + } + + private void initViewer(String viewerType) { + setContentProvider(new OutlineContentProvider()); + setLabelProvider(new OutlineLabelProvider()); + setComparator(new OutlineViewerSorter()); + + if (VIEWERTYPE_MULITCOLUMN.equals(viewerType)) { + getTree().setHeaderVisible(true); + + TreeViewerColumn taskColumn = new TreeViewerColumn(this, SWT.LEFT); + taskColumn.getColumn() + .setText(MindMapMessages.OutlineViewer_Task_col); + taskColumn.getColumn().setWidth(200); + taskColumn.setLabelProvider(new ColumnLabelProvider() { + + public String getText(Object element) { + Object input = getInput(); + if (input instanceof ITaskDateResource) { + if (element instanceof ITopic) { + return ((ITopic) element).getTitleText(); + } + } + return null; + } + }); + + TreeViewerColumn dateColumn = new TreeViewerColumn(this, SWT.LEFT); + dateColumn.getColumn().setWidth(200); + dateColumn.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + Object input = getInput(); + if (input instanceof ITaskDateResource) { + if (element instanceof ITopic) { + return ((ITaskDateResource) input) + .getTaskDate((ITopic) element); + } + } + return null; + } + }); + } + } + + public String getViewerType() { + return viewerType; + } + + public void setFocus() { + Control control = getControl(); + if (control != null && !control.isDisposed()) + control.setFocus(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/TopicTreePart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/TopicTreePart.java index 5feca3573..e383c7718 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/TopicTreePart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/TopicTreePart.java @@ -20,6 +20,7 @@ import org.xmind.core.ITopic; import org.xmind.core.event.CoreEvent; import org.xmind.core.event.ICoreEventRegister; +import org.xmind.ui.internal.protocols.WebProtocol; public class TopicTreePart extends MindMapTreePartBase { @@ -45,12 +46,14 @@ protected Object[] getModelChildren(Object model) { return allChildren.toArray(); } - protected void registerCoreEvents(Object source, ICoreEventRegister register) { + protected void registerCoreEvents(Object source, + ICoreEventRegister register) { super.registerCoreEvents(source, register); register.register(Core.TitleText); register.register(Core.TopicAdd); register.register(Core.TopicRemove); register.register(Core.TopicHyperlink); + register.register(WebProtocol.WEB_ICON_EVENT_TYPE); } public void handleCoreEvent(CoreEvent event) { @@ -61,12 +64,19 @@ public void run() { update(); } }, false); - } else if (Core.TopicAdd.equals(type) || Core.TopicRemove.equals(type)) { + } else if (Core.TopicAdd.equals(type) + || Core.TopicRemove.equals(type)) { runInUI(new Runnable() { public void run() { refresh(); } }, false); + } else if (WebProtocol.WEB_ICON_EVENT_TYPE.equals(type)) { + runInUI(new Runnable() { + public void run() { + setWidgetImage(getImage()); + } + }, false); } else { super.handleCoreEvent(event); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AZResourceForSheet.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AZResourceForSheet.java new file mode 100644 index 000000000..975bc314e --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AZResourceForSheet.java @@ -0,0 +1,59 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; + +public class AZResourceForSheet extends AbstractIndexResource + implements IAZResource { + + private ISheet sheet; + + private Set topics = new HashSet(); + + private boolean isPositiveSequence; + + public AZResourceForSheet(ISheet sheet) { + Assert.isNotNull(sheet); + this.sheet = sheet; + init(false); + } + + private void init(boolean update) { + if (update) { + topics.clear(); + } + + collectResourceForSheet(sheet); + } + + public Object getSource() { + return sheet; + } + + public void reset(Object source, boolean update) { + Assert.isNotNull(source); + this.sheet = (ISheet) source; + init(update); + } + + public Set getTopics() { + return topics; + } + + protected void collectResourceForTopic(ITopic topic) { + topics.add(topic); + } + + public boolean isPositiveSequence() { + return isPositiveSequence; + } + + public void setSequence(boolean isPositiveSequence) { + this.isPositiveSequence = isPositiveSequence; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AZResourceForWorkbook.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AZResourceForWorkbook.java new file mode 100644 index 000000000..17dfb5fc3 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AZResourceForWorkbook.java @@ -0,0 +1,59 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ITopic; +import org.xmind.ui.mindmap.IWorkbookRef; + +public class AZResourceForWorkbook extends AbstractIndexResource + implements IAZResource { + + private IWorkbookRef workbookRef; + + private Set topics = new HashSet(); + + private boolean isPositiveSequence; + + public AZResourceForWorkbook(IWorkbookRef workbookRef) { + Assert.isNotNull(workbookRef); + this.workbookRef = workbookRef; + init(false); + } + + private void init(boolean update) { + if (update) { + topics.clear(); + } + + collectResourceForWorkbook(workbookRef); + } + + public Object getSource() { + return workbookRef; + } + + public void reset(Object source, boolean update) { + Assert.isNotNull(source); + this.workbookRef = (IWorkbookRef) source; + init(update); + } + + public Set getTopics() { + return topics; + } + + protected void collectResourceForTopic(ITopic topic) { + topics.add(topic); + } + + public boolean isPositiveSequence() { + return isPositiveSequence; + } + + public void setSequence(boolean isPositiveSequence) { + this.isPositiveSequence = isPositiveSequence; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AbstractIndexResource.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AbstractIndexResource.java new file mode 100644 index 000000000..0216e4687 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AbstractIndexResource.java @@ -0,0 +1,35 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.List; + +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.ui.mindmap.IWorkbookRef; + +public abstract class AbstractIndexResource implements IOutlineResource { + + protected void collectResourceForWorkbook(IWorkbookRef workbookRef) { + if (workbookRef == null) + return; + + List sheets = workbookRef.getWorkbook().getSheets(); + for (ISheet sheet : sheets) { + collectResourceForSheet(sheet); + } + } + + protected void collectResourceForSheet(ISheet sheet) { + ITopic rootTopic = sheet.getRootTopic(); + collectResourceForTopic(rootTopic); + collectResourceForParentTopic(rootTopic); + } + + protected void collectResourceForParentTopic(ITopic parentTopic) { + for (ITopic child : parentTopic.getAllChildren()) { + collectResourceForTopic(child); + collectResourceForParentTopic(child); + } + } + + protected abstract void collectResourceForTopic(ITopic topic); +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AssigneeResourceForSheet.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AssigneeResourceForSheet.java new file mode 100644 index 000000000..592810107 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AssigneeResourceForSheet.java @@ -0,0 +1,85 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; + +public class AssigneeResourceForSheet extends AbstractIndexResource + implements IAssigneeResource { + + private ISheet sheet; + + private Set assignees = new HashSet(); + + private Map> assigneeToTopics = new HashMap>(); + + public AssigneeResourceForSheet(ISheet sheet) { + Assert.isNotNull(sheet); + this.sheet = sheet; + init(false); + } + + private void init(boolean update) { + if (update) { + assignees.clear(); + assigneeToTopics.clear(); + } + + collectResourceForSheet(sheet); + } + + public Object getSource() { + return sheet; + } + + public void reset(Object source, boolean update) { + Assert.isNotNull(source); + this.sheet = (ISheet) source; + init(update); + } + + public Set getAssignees() { + return assignees; + } + + public Set getTopics(String assignee) { + return assigneeToTopics.get(assignee); + } + + protected void collectResourceForTopic(ITopic topic) { + ITopicExtension ext = topic.getExtension("org.xmind.ui.taskInfo"); //$NON-NLS-1$ + if (ext == null) + return; + + ITopicExtensionElement content = ext.getContent(); + List children = content + .getChildren("assigned-to"); //$NON-NLS-1$ + if (!children.isEmpty()) { + for (ITopicExtensionElement element : children) { + String assignee = element.getTextContent(); + + if (assigneeToTopics.containsKey(assignee)) { + Set assignedTopics = assigneeToTopics.get(assignee); + if (assignedTopics == null) { + assignedTopics = new HashSet(); + assigneeToTopics.put(assignee, assignedTopics); + } + assignedTopics.add(topic); + } else { + assignees.add(assignee); + Set assignedTopics = new HashSet(); + assignedTopics.add(topic); + assigneeToTopics.put(assignee, assignedTopics); + } + } + } + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AssigneeResourceForWorkbook.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AssigneeResourceForWorkbook.java new file mode 100644 index 000000000..5411b4a97 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/AssigneeResourceForWorkbook.java @@ -0,0 +1,86 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.ui.mindmap.IWorkbookRef; + +public class AssigneeResourceForWorkbook extends AbstractIndexResource + implements IAssigneeResource { + + private IWorkbookRef workbookRef; + + private Set assignees = new HashSet(); + + private Map> assigneeToTopics = new HashMap>(); + + public AssigneeResourceForWorkbook(IWorkbookRef workbookRef) { + Assert.isNotNull(workbookRef); + this.workbookRef = workbookRef; + init(false); + } + + private void init(boolean update) { + if (update) { + assignees.clear(); + assigneeToTopics.clear(); + } + + collectResourceForWorkbook(workbookRef); + } + + public Object getSource() { + return workbookRef; + } + + public void reset(Object source, boolean update) { + Assert.isNotNull(source); + this.workbookRef = (IWorkbookRef) source; + init(update); + } + + public Set getAssignees() { + return assignees; + } + + public Set getTopics(String assignee) { + return assigneeToTopics.get(assignee); + } + + protected void collectResourceForTopic(ITopic topic) { + ITopicExtension ext = topic.getExtension("org.xmind.ui.taskInfo"); //$NON-NLS-1$ + if (ext == null) + return; + + ITopicExtensionElement content = ext.getContent(); + List children = content + .getChildren("assigned-to"); //$NON-NLS-1$ + if (!children.isEmpty()) { + for (ITopicExtensionElement element : children) { + String assignee = element.getTextContent(); + + if (assigneeToTopics.containsKey(assignee)) { + Set assignedTopics = assigneeToTopics.get(assignee); + if (assignedTopics == null) { + assignedTopics = new HashSet(); + assigneeToTopics.put(assignee, assignedTopics); + } + assignedTopics.add(topic); + } else { + assignees.add(assignee); + Set assignedTopics = new HashSet(); + assignedTopics.add(topic); + assigneeToTopics.put(assignee, assignedTopics); + } + } + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IAZResource.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IAZResource.java new file mode 100644 index 000000000..c755815d7 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IAZResource.java @@ -0,0 +1,15 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.Set; + +import org.xmind.core.ITopic; + +public interface IAZResource extends IOutlineResource { + + public Set getTopics(); + + public boolean isPositiveSequence(); + + public void setSequence(boolean isPositiveSequence); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IAssigneeResource.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IAssigneeResource.java new file mode 100644 index 000000000..ce777f20b --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IAssigneeResource.java @@ -0,0 +1,13 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.Set; + +import org.xmind.core.ITopic; + +public interface IAssigneeResource extends IOutlineResource { + + public Set getAssignees(); + + public Set getTopics(String assignee); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/ILabelResource.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/ILabelResource.java new file mode 100644 index 000000000..cbc503fb0 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/ILabelResource.java @@ -0,0 +1,13 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.Set; + +import org.xmind.core.ITopic; + +public interface ILabelResource extends IOutlineResource { + + public Set getLabels(); + + public Set getTopics(String label); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IMarkerResource.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IMarkerResource.java new file mode 100644 index 000000000..d827a49a2 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IMarkerResource.java @@ -0,0 +1,16 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.Set; + +import org.xmind.core.ITopic; +import org.xmind.core.marker.IMarker; + +public interface IMarkerResource extends IOutlineResource { + + public Set getMarkerIds(); + + public Set getTopics(String markerId); + + public IMarker getMarker(String markerId); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IOutlineResource.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IOutlineResource.java new file mode 100644 index 000000000..52947aaf0 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/IOutlineResource.java @@ -0,0 +1,8 @@ +package org.xmind.ui.internal.outline.resource; + +public interface IOutlineResource { + + public Object getSource(); + + public void reset(Object source, boolean update); +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/ITaskDateResource.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/ITaskDateResource.java new file mode 100644 index 000000000..dfaf7d835 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/ITaskDateResource.java @@ -0,0 +1,21 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.Set; + +import org.xmind.core.ITopic; + +public interface ITaskDateResource extends IOutlineResource { + + public Set getTaskDates(); + + public Set getTopics(String taskDate); + + public Set getAllTopicsForTaskDate(); + + public String getTaskDate(ITopic topic); + + public void setTaskDateResourceType(int type); + + public int getTaskDateResourceType(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/LabelResourceForSheet.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/LabelResourceForSheet.java new file mode 100644 index 000000000..62dcadcb5 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/LabelResourceForSheet.java @@ -0,0 +1,71 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; + +public class LabelResourceForSheet extends AbstractIndexResource + implements ILabelResource { + + private ISheet sheet; + + private Set labels = new HashSet(); + + private Map> labelToTopics = new HashMap>(); + + public LabelResourceForSheet(ISheet sheet) { + Assert.isNotNull(sheet); + this.sheet = sheet; + init(false); + } + + private void init(boolean update) { + if (update) { + labels.clear(); + labelToTopics.clear(); + } + + collectResourceForSheet(sheet); + } + + protected void collectResourceForTopic(ITopic topic) { + Set labs = topic.getLabels(); + for (String lab : labs) { + if (labelToTopics.containsKey(lab)) { + Set topics = labelToTopics.get(lab); + if (topics == null) + topics = new HashSet(); + topics.add(topic); + } else { + Set topics = new HashSet(); + topics.add(topic); + labelToTopics.put(lab, topics); + } + } + labels.addAll(labs); + } + + public Object getSource() { + return sheet; + } + + public Set getLabels() { + return labels; + } + + public Set getTopics(String label) { + return labelToTopics.get(label); + } + + public void reset(Object source, boolean update) { + Assert.isNotNull(source); + this.sheet = (ISheet) source; + init(update); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/LabelResourceForWorkbook.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/LabelResourceForWorkbook.java new file mode 100644 index 000000000..a17896f59 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/LabelResourceForWorkbook.java @@ -0,0 +1,71 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ITopic; +import org.xmind.ui.mindmap.IWorkbookRef; + +public class LabelResourceForWorkbook extends AbstractIndexResource + implements ILabelResource { + + private IWorkbookRef workbookRef; + + private Set labels = new HashSet(); + + private Map> labelToTopics = new HashMap>(); + + public LabelResourceForWorkbook(IWorkbookRef workbookRef) { + Assert.isNotNull(workbookRef); + this.workbookRef = workbookRef; + init(false); + } + + private void init(boolean update) { + if (update) { + labels.clear(); + labelToTopics.clear(); + } + + collectResourceForWorkbook(workbookRef); + } + + protected void collectResourceForTopic(ITopic topic) { + Set labs = topic.getLabels(); + for (String lab : labs) { + if (labelToTopics.containsKey(lab)) { + Set topics = labelToTopics.get(lab); + if (topics == null) + topics = new HashSet(); + topics.add(topic); + } else { + Set topics = new HashSet(); + topics.add(topic); + labelToTopics.put(lab, topics); + } + } + labels.addAll(labs); + } + + public Object getSource() { + return workbookRef; + } + + public Set getLabels() { + return labels; + } + + public Set getTopics(String label) { + return labelToTopics.get(label); + } + + public void reset(Object source, boolean update) { + Assert.isNotNull(source); + this.workbookRef = (IWorkbookRef) source; + init(update); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/MarkerResourceForSheet.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/MarkerResourceForSheet.java new file mode 100644 index 000000000..943261033 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/MarkerResourceForSheet.java @@ -0,0 +1,89 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerRef; + +public class MarkerResourceForSheet extends AbstractIndexResource + implements IMarkerResource { + + private Set markerIds = new HashSet(); + + private Map> idToTopics = new HashMap>(); + + private Map idToMarker = new HashMap(); + + private ISheet sheet; + + public MarkerResourceForSheet(ISheet sheet) { + Assert.isNotNull(sheet); + this.sheet = sheet; + init(false); + } + + private void init(boolean update) { + if (update) { + markerIds.clear(); + idToTopics.clear(); + idToMarker.clear(); + } + + collectResourceForSheet(sheet); + } + + public Set getMarkerIds() { + return markerIds; + } + + public IMarker getMarker(String markerId) { + return idToMarker.get(markerId); + } + + public Set getTopics(String markerId) { + return idToTopics.get(markerId); + } + + public Object getSource() { + return sheet; + } + + public void reset(Object source, boolean update) { + Assert.isNotNull(source); + this.sheet = (ISheet) source; + init(update); + } + + protected void collectResourceForTopic(ITopic topic) { + Set markerRefs = topic.getMarkerRefs(); + for (IMarkerRef markerRef : markerRefs) { + IMarker marker = markerRef.getMarker(); + String markerId = marker.getId(); + + markerIds.add(markerId); + + Set keySet = idToTopics.keySet(); + if (keySet.contains(markerId)) { + Set topicsCollected = idToTopics.get(markerId); + if (topicsCollected == null) + topicsCollected = new HashSet(); + topicsCollected.add(topic); + idToTopics.put(markerId, topicsCollected); + idToMarker.put(markerId, marker); + } else { + Set topicsCollected = new HashSet(); + topicsCollected.add(topic); + idToTopics.put(markerId, topicsCollected); + idToMarker.put(markerId, marker); + } + + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/MarkerResourceForWorkbook.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/MarkerResourceForWorkbook.java new file mode 100644 index 000000000..c2891695b --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/MarkerResourceForWorkbook.java @@ -0,0 +1,90 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ITopic; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerRef; +import org.xmind.ui.mindmap.IWorkbookRef; + +public class MarkerResourceForWorkbook extends AbstractIndexResource + implements IMarkerResource { + + private Set markerIds = new HashSet(); + + private Map> idToTopics = new HashMap>(); + + private Map idToMarker = new HashMap(); + + private IWorkbookRef workbookRef; + + public MarkerResourceForWorkbook(IWorkbookRef workbookRef) { + Assert.isNotNull(workbookRef); + this.workbookRef = workbookRef; + init(false); + } + + private void init(boolean update) { + if (update) { + markerIds.clear(); + idToTopics.clear(); + idToMarker.clear(); + } + + collectResourceForWorkbook(workbookRef); + } + + public Set getMarkerIds() { + return markerIds; + } + + public IMarker getMarker(String markerId) { + return idToMarker.get(markerId); + } + + public Set getTopics(String markerId) { + return idToTopics.get(markerId); + } + + public Object getSource() { + return workbookRef; + } + + public void reset(Object source, boolean update) { + Assert.isNotNull(source); + this.workbookRef = (IWorkbookRef) source; + init(update); + } + + protected void collectResourceForTopic(ITopic topic) { + for (IMarkerRef markerRef : topic.getMarkerRefs()) { + + IMarker marker = markerRef.getMarker(); + String markerId = marker.getId(); + + markerIds.add(markerId); + + Set keySet = idToTopics.keySet(); + if (keySet.contains(markerId)) { + Set topicsCollected = idToTopics.get(markerId); + if (topicsCollected == null) + topicsCollected = new HashSet(); + topicsCollected.add(topic); + idToTopics.put(markerId, topicsCollected); + idToMarker.put(markerId, marker); + + } else { + Set topicsCollected = new HashSet(); + topicsCollected.add(topic); + idToTopics.put(markerId, topicsCollected); + idToMarker.put(markerId, marker); + } + + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/OutlineResources.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/OutlineResources.java new file mode 100644 index 000000000..6af83e29b --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/OutlineResources.java @@ -0,0 +1,210 @@ +package org.xmind.ui.internal.outline.resource; + +import org.xmind.core.ISheet; +import org.xmind.ui.internal.outline.OutlineIndexModelPart; +import org.xmind.ui.mindmap.IWorkbookRef; + +public class OutlineResources { + + private IOutlineResource markerResourceForWorkbook; + private IOutlineResource markerResourceForSheet; + + private IOutlineResource labelResourceForWorkbook; + private IOutlineResource labelResourceForSheet; + + private IOutlineResource assigneeResourceForWorkbook; + private IOutlineResource assigneeResourceForSheet; + + private ITaskDateResource taskDateResourceForWorkbook; + private ITaskDateResource taskDateResourceForSheet; + + private IAZResource azResourceForWorkbook; + private IAZResource azResourceForSheet; + + public Object getResourceForSheet(ISheet sheet, int indexType, + boolean forceUpdate) { + Object resource = null; + if (sheet != null) + switch (indexType) { + case OutlineIndexModelPart.OUTLINE_TYPE_NONE: + resource = sheet; + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_MARKERS: + resource = getMarkerResourceForSheet(sheet, forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_LABELS: + resource = getLabelResourceForSheet(sheet, forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_ASSIGNEE: + resource = getAssigneeResourceForSheet(sheet, forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE: + resource = getTaskDateResourceForSheet(sheet, indexType, + forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE: + resource = getTaskDateResourceForSheet(sheet, indexType, + forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_AZ: + resource = getAZResourceForSheet(sheet, true, forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_ZA: + resource = getAZResourceForSheet(sheet, false, forceUpdate); + break; + } + return resource; + } + + public Object getResourceForWorkbook(IWorkbookRef workbookRef, + int indexType, boolean forceUpdate) { + Object resource = null; + if (workbookRef != null) + switch (indexType) { + case OutlineIndexModelPart.OUTLINE_TYPE_NONE: + resource = workbookRef; + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_MARKERS: + resource = getMarkerResourceForWorkbook(workbookRef, + forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_LABELS: + resource = getLabelResourceForWorkbook(workbookRef, + forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_ASSIGNEE: + resource = getAssigneeResourceForWorkbook(workbookRef, + forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE: + resource = getTaskDateResourceForWorkbook(workbookRef, + indexType, forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE: + resource = getTaskDateResourceForWorkbook(workbookRef, + indexType, forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_AZ: + resource = getAZResourceForWorkbook(workbookRef, true, + forceUpdate); + break; + case OutlineIndexModelPart.OUTLINE_TYPE_BY_ZA: + resource = getAZResourceForWorkbook(workbookRef, false, + forceUpdate); + break; + } + return resource; + } + + private IOutlineResource getMarkerResourceForWorkbook( + IWorkbookRef workbookRef, boolean forceUpdate) { + if (markerResourceForWorkbook != null && forceUpdate) { + markerResourceForWorkbook.reset(workbookRef, true); + } + if (markerResourceForWorkbook == null) + markerResourceForWorkbook = new MarkerResourceForWorkbook( + workbookRef); + return markerResourceForWorkbook; + } + + private IOutlineResource getMarkerResourceForSheet(ISheet sheet, + boolean forceUpdate) { + if (markerResourceForSheet != null && forceUpdate) { + markerResourceForSheet.reset(sheet, true); + } + if (markerResourceForSheet == null) + markerResourceForSheet = new MarkerResourceForSheet(sheet); + return markerResourceForSheet; + } + + private IOutlineResource getLabelResourceForSheet(ISheet sheet, + boolean forceUpdate) { + if (labelResourceForSheet != null && forceUpdate) { + labelResourceForSheet.reset(sheet, true); + } + if (labelResourceForSheet == null) + labelResourceForSheet = new LabelResourceForSheet(sheet); + return labelResourceForSheet; + } + + private IOutlineResource getLabelResourceForWorkbook( + IWorkbookRef workbookRef, boolean forceUpdate) { + if (labelResourceForWorkbook != null && forceUpdate) { + labelResourceForWorkbook.reset(workbookRef, true); + } + if (labelResourceForWorkbook == null) + labelResourceForWorkbook = new LabelResourceForWorkbook( + workbookRef); + return labelResourceForWorkbook; + } + + private IOutlineResource getAssigneeResourceForSheet(ISheet sheet, + boolean forceUpdate) { + if (assigneeResourceForSheet != null && forceUpdate) { + assigneeResourceForSheet.reset(sheet, true); + } + if (assigneeResourceForSheet == null) + assigneeResourceForSheet = new AssigneeResourceForSheet(sheet); + return assigneeResourceForSheet; + } + + private IOutlineResource getAssigneeResourceForWorkbook( + IWorkbookRef workbookRef, boolean forceUpdate) { + if (assigneeResourceForWorkbook != null && forceUpdate) { + assigneeResourceForWorkbook.reset(workbookRef, true); + } + if (assigneeResourceForWorkbook == null) + assigneeResourceForWorkbook = new AssigneeResourceForWorkbook( + workbookRef); + return assigneeResourceForWorkbook; + } + + private IOutlineResource getTaskDateResourceForSheet(ISheet sheet, + int taskDateType, boolean forceUpdate) { + if (taskDateResourceForSheet != null && forceUpdate) { + taskDateResourceForSheet.reset(sheet, forceUpdate); + } + if (taskDateResourceForSheet == null) + taskDateResourceForSheet = new TaskDateResourceForSheet(sheet, + taskDateType); + taskDateResourceForSheet.setTaskDateResourceType(taskDateType); + return taskDateResourceForSheet; + } + + private IOutlineResource getTaskDateResourceForWorkbook( + IWorkbookRef workbookRef, int taskDateType, boolean forceUpdate) { + if (taskDateResourceForWorkbook != null && forceUpdate) { + taskDateResourceForWorkbook.reset(workbookRef, forceUpdate); + } + if (taskDateResourceForWorkbook == null) + taskDateResourceForWorkbook = new TaskDateResourceForWorkbook( + workbookRef, taskDateType); + taskDateResourceForWorkbook.setTaskDateResourceType(taskDateType); + return taskDateResourceForWorkbook; + } + + private IOutlineResource getAZResourceForSheet(ISheet sheet, + boolean isPositiveSequence, boolean forceUpdate) { + if (azResourceForSheet != null && forceUpdate) { + azResourceForSheet.reset(sheet, true); + } + if (azResourceForSheet == null) { + azResourceForSheet = new AZResourceForSheet(sheet); + } + azResourceForSheet.setSequence(isPositiveSequence); + return azResourceForSheet; + } + + private IOutlineResource getAZResourceForWorkbook(IWorkbookRef workbookRef, + boolean isPositiveSequence, boolean forceUpdate) { + if (azResourceForWorkbook != null && forceUpdate) { + azResourceForWorkbook.reset(workbookRef, true); + } + if (azResourceForWorkbook == null) { + azResourceForWorkbook = new AZResourceForWorkbook(workbookRef); + } + azResourceForWorkbook.setSequence(isPositiveSequence); + return azResourceForWorkbook; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/TaskDateResourceForSheet.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/TaskDateResourceForSheet.java new file mode 100644 index 000000000..01ac30f3f --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/TaskDateResourceForSheet.java @@ -0,0 +1,171 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ISheet; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.ui.internal.outline.OutlineIndexModelPart; + +public class TaskDateResourceForSheet extends AbstractIndexResource + implements ITaskDateResource { + + private ISheet sheet; + + private int taskDateType; + + private Set startDates = new HashSet(); + + private Map> startDateToTopics = new HashMap>(); + + private Set endDates = new HashSet(); + + private Map> endDateToTopics = new HashMap>(); + + private Set allEndDateTopics = new HashSet(); + + private Set allStartDateTopics = new HashSet(); + + private Map topicToEndDate = new HashMap(); + + private Map topicToStartDate = new HashMap(); + + public TaskDateResourceForSheet(ISheet sheet, int taskDateType) { + Assert.isNotNull(sheet); + this.sheet = sheet; + this.taskDateType = taskDateType; + init(false); + } + + private void init(boolean update) { + if (update) { + startDates.clear(); + startDateToTopics.clear(); + endDates.clear(); + endDateToTopics.clear(); + } + + collectResourceForSheet(sheet); + } + + public Object getSource() { + return sheet; + } + + public void reset(Object source, boolean update) { + Assert.isNotNull(source); + this.sheet = (ISheet) source; + init(update); + } + + protected void collectResourceForTopic(ITopic topic) { + ITopicExtension ext = topic.getExtension("org.xmind.ui.taskInfo"); //$NON-NLS-1$ + if (ext == null) + return; + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) + collectStartDateResource(topic, ext); + else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + collectEndDateResource(topic, ext); + } + + private void collectStartDateResource(ITopic topic, ITopicExtension ext) { + ITopicExtensionElement content = ext.getContent(); + List children = content + .getChildren("start-date"); //$NON-NLS-1$ + if (!children.isEmpty()) { + for (ITopicExtensionElement element : children) { + String assignee = element.getTextContent(); + topicToStartDate.put(topic, assignee); + allStartDateTopics.add(topic); + + if (startDateToTopics.containsKey(assignee)) { + Set assignedTopics = startDateToTopics + .get(assignee); + if (assignedTopics == null) { + assignedTopics = new HashSet(); + startDateToTopics.put(assignee, assignedTopics); + } + assignedTopics.add(topic); + } else { + startDates.add(assignee); + Set assignedTopics = new HashSet(); + assignedTopics.add(topic); + startDateToTopics.put(assignee, assignedTopics); + } + } + } + } + + private void collectEndDateResource(ITopic topic, ITopicExtension ext) { + ITopicExtensionElement content = ext.getContent(); + List children = content.getChildren("end-date"); //$NON-NLS-1$ + if (!children.isEmpty()) { + for (ITopicExtensionElement element : children) { + String assignee = element.getTextContent(); + topicToEndDate.put(topic, assignee); + allEndDateTopics.add(topic); + + if (endDateToTopics.containsKey(assignee)) { + Set assignedTopics = endDateToTopics.get(assignee); + if (assignedTopics == null) { + assignedTopics = new HashSet(); + endDateToTopics.put(assignee, assignedTopics); + } + assignedTopics.add(topic); + } else { + endDates.add(assignee); + Set assignedTopics = new HashSet(); + assignedTopics.add(topic); + endDateToTopics.put(assignee, assignedTopics); + } + } + } + } + + public Set getTaskDates() { + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) + return startDates; + else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + return endDates; + return new HashSet(); + } + + public Set getTopics(String taskDate) { + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) + return startDateToTopics.get(taskDate); + else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + return endDateToTopics.get(taskDate); + return new HashSet(); + } + + public void setTaskDateResourceType(int type) { + this.taskDateType = type; + } + + public Set getAllTopicsForTaskDate() { + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) + return allStartDateTopics; + else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + return allEndDateTopics; + return new HashSet(); + } + + public String getTaskDate(ITopic topic) { + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) + return topicToStartDate.get(topic); + else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + return topicToEndDate.get(topic); + return null; + } + + public int getTaskDateResourceType() { + return taskDateType; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/TaskDateResourceForWorkbook.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/TaskDateResourceForWorkbook.java new file mode 100644 index 000000000..3e4ec6e46 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/outline/resource/TaskDateResourceForWorkbook.java @@ -0,0 +1,172 @@ +package org.xmind.ui.internal.outline.resource; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.xmind.core.ITopic; +import org.xmind.core.ITopicExtension; +import org.xmind.core.ITopicExtensionElement; +import org.xmind.ui.internal.outline.OutlineIndexModelPart; +import org.xmind.ui.mindmap.IWorkbookRef; + +public class TaskDateResourceForWorkbook extends AbstractIndexResource + implements ITaskDateResource { + + private IWorkbookRef workbookRef; + + private int taskDateType; + + private Set startDates = new HashSet(); + + private Map> startDateToTopics = new HashMap>(); + + private Set endDates = new HashSet(); + + private Map> endDateToTopics = new HashMap>(); + + private Set allEndDateTopics = new HashSet(); + + private Set allStartDateTopics = new HashSet(); + + private Map topicToEndDate = new HashMap(); + + private Map topicToStartDate = new HashMap(); + + public TaskDateResourceForWorkbook(IWorkbookRef workbookRef, + int taskDateType) { + Assert.isNotNull(workbookRef); + this.workbookRef = workbookRef; + this.taskDateType = taskDateType; + init(false); + } + + private void init(boolean update) { + if (update) { + startDates.clear(); + startDateToTopics.clear(); + endDates.clear(); + endDateToTopics.clear(); + } + + collectResourceForWorkbook(workbookRef); + } + + public Object getSource() { + return workbookRef; + } + + public void reset(Object source, boolean update) { + Assert.isNotNull(source); + this.workbookRef = (IWorkbookRef) source; + init(update); + } + + protected void collectResourceForTopic(ITopic topic) { + ITopicExtension ext = topic.getExtension("org.xmind.ui.taskInfo"); //$NON-NLS-1$ + if (ext == null) + return; + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) + collectStartDateResource(topic, ext); + else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + collectEndDateResource(topic, ext); + } + + private void collectStartDateResource(ITopic topic, ITopicExtension ext) { + ITopicExtensionElement content = ext.getContent(); + List children = content + .getChildren("start-date"); //$NON-NLS-1$ + if (!children.isEmpty()) { + for (ITopicExtensionElement element : children) { + String assignee = element.getTextContent(); + topicToStartDate.put(topic, assignee); + allStartDateTopics.add(topic); + + if (startDateToTopics.containsKey(assignee)) { + Set assignedTopics = startDateToTopics + .get(assignee); + if (assignedTopics == null) { + assignedTopics = new HashSet(); + startDateToTopics.put(assignee, assignedTopics); + } + assignedTopics.add(topic); + } else { + startDates.add(assignee); + Set assignedTopics = new HashSet(); + assignedTopics.add(topic); + startDateToTopics.put(assignee, assignedTopics); + } + } + } + } + + private void collectEndDateResource(ITopic topic, ITopicExtension ext) { + ITopicExtensionElement content = ext.getContent(); + List children = content.getChildren("end-date"); //$NON-NLS-1$ + if (!children.isEmpty()) { + for (ITopicExtensionElement element : children) { + String assignee = element.getTextContent(); + topicToEndDate.put(topic, assignee); + allEndDateTopics.add(topic); + + if (endDateToTopics.containsKey(assignee)) { + Set assignedTopics = endDateToTopics.get(assignee); + if (assignedTopics == null) { + assignedTopics = new HashSet(); + endDateToTopics.put(assignee, assignedTopics); + } + assignedTopics.add(topic); + } else { + endDates.add(assignee); + Set assignedTopics = new HashSet(); + assignedTopics.add(topic); + endDateToTopics.put(assignee, assignedTopics); + } + } + } + } + + public Set getTaskDates() { + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) + return startDates; + else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + return endDates; + return new HashSet(); + } + + public Set getTopics(String taskDate) { + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) + return startDateToTopics.get(taskDate); + else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + return endDateToTopics.get(taskDate); + return new HashSet(); + } + + public void setTaskDateResourceType(int type) { + this.taskDateType = type; + } + + public Set getAllTopicsForTaskDate() { + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) + return allStartDateTopics; + else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + return allEndDateTopics; + return new HashSet(); + } + + public String getTaskDate(ITopic topic) { + if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_STARTDATE) + return topicToStartDate.get(topic); + else if (taskDateType == OutlineIndexModelPart.OUTLINE_TYPE_BY_ENDDATE) + return topicToEndDate.get(topic); + return null; + } + + public int getTaskDateResourceType() { + return taskDateType; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/popover/MarkerPopoverMenuToolItem.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/popover/MarkerPopoverMenuToolItem.java new file mode 100644 index 000000000..b40350949 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/popover/MarkerPopoverMenuToolItem.java @@ -0,0 +1,734 @@ +package org.xmind.ui.internal.popover; + +import static org.xmind.ui.mindmap.MindMapUI.REQ_ADD_MARKER; + +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.action.Action; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.util.SafeRunnable; +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.Transfer; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackAdapter; +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.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.PlatformUI; +import org.eclipse.ui.forms.IFormColors; +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.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.eclipse.ui.handlers.IHandlerService; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.internal.MarkerGroup; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.gef.EditDomain; +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.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; +import org.xmind.ui.internal.views.Messages; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.util.MarkerImageDescriptor; + +public class MarkerPopoverMenuToolItem extends PopoverMenuToolItem { + + private static class MarkerSheetPart { + + private List sheets; + + private Composite composite; + + private ArrayList groupParts = new ArrayList(); + + private List
    groupSections = new ArrayList
    (); + + private Map groupToPart = new HashMap(); + + private Map groupToSection = new HashMap(); + + public MarkerSheetPart(List sheets) { + this.sheets = sheets; + } + + public Control createControl(Composite parent) { + if (composite == null) { + composite = createComposite(parent); + + refresh(false); + + composite.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(DisposeEvent e) { + dispose(); + } + }); + } + + return composite; + } + + private Composite createComposite(Composite parent) { + Composite composite = new Composite(parent, SWT.WRAP); + composite.setBackground(composite.getParent().getBackground()); + + GridLayout layout = new GridLayout(1, true); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 3; + composite.setLayout(layout); + + return composite; + } + + public void refresh(boolean reflow) { + if (composite == null || composite.isDisposed()) { + return; + } + composite.setRedraw(false); + + List newGroups = new ArrayList(); + if (!RecentMarkerGroup.instance.isEmpty()) + newGroups.add(RecentMarkerGroup.instance); + for (IMarkerSheet sheet : sheets) { + List markerGroups = sheet.getMarkerGroups(); + for (IMarkerGroup markerGroup : markerGroups) + if (!markerGroup.isEmpty()) + newGroups.add(markerGroup); + } + + 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()) { + part = createChild(group); + addChild(part, i); + } + } + } + + Object[] toTrim = groupParts.toArray(); + for (; i < toTrim.length; i++) { + removeChild((MarkerGroupPart) toTrim[i]); + } + + composite.setRedraw(true); + } + + private MarkerGroupPart createChild(IMarkerGroup group) { + MarkerGroupPart part = new MarkerGroupPart(group, false); + groupToPart.put(group, part); + + return part; + } + + private void addChild(MarkerGroupPart part, int index) { + index = index < groupParts.size() ? index : groupParts.size(); + 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(); + } + + public void dispose() { + 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(); + } + } + + private static class MarkerGroupPart { + + private IMarkerGroup group; + + private boolean hasTitle; + + private Control control; + + private Section section; + + private ToolBarManager toolbar; + + 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) { + WidgetFactory factory = new WidgetFactory(parent.getDisplay()); + + 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 = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 0; + c.setLayout(layout); + + if (hasTitle) { + factory.createLabel(c, group.getName()); + } + + final ToolBar tb = toolbar.createControl(c); + tb.setBackground( + tb.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); + tb.setLayoutData(data); + + addDragSource(tb); + + control = section; + section.setClient(c); + + refresh(false); + control.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + dispose(); + } + }); + } + + return control; + } + + private Section createSection(Composite parent, String title, + WidgetFactory factory) { + Section section = factory.createSection(parent, SWT.None); + section.setText(title); + return section; + } + + 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); + IMarker marker = group.getMarkers().get(index); + event.data = new Object[] { marker }; + } + + public void dragFinished(DragSourceEvent event) { + } + }); + + toolbar.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + dragSource.dispose(); + } + }); + } + + public void refresh(boolean reflow) { + if (toolbar == null || control == null || control.isDisposed()) + return; + section.setText(group.getName()); + + toolbar.removeAll(); + for (int index = 0; index < group.getMarkers().size(); index++) { + IMarker marker = group.getMarkers().get(index); + if (!group.isHidden() && !marker.isHidden()) { + toolbar.add(new MarkerAction(marker)); + } + } + toolbar.update(false); + } + + public void dispose() { + if (toolbar != null) { + toolbar.dispose(); + toolbar = null; + } + + if (control != null) { + control.dispose(); + control = null; + } + } + } + + private static class RecentMarkerGroup extends MarkerGroup { + + public static final RecentMarkerGroup instance = new RecentMarkerGroup(); + + private static final int CAPACITY = 7; + + private List markers = new ArrayList(CAPACITY); + + 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); + } + + 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); + } + + public void setName(String name) { + } + + public String getId() { + return "org.xmind.ui.RecentMarkerGroup"; //$NON-NLS-1$ + } + + public int hashCode() { + return super.hashCode(); + } + + } + + private static class MarkerAction extends Action { + + private static final int ICON_WIDTH = 24; + + private static final int ICON_HEIGHT = 24; + + private IMarker marker; + + public MarkerAction(IMarker marker) { + super(); + this.marker = marker; + setImageDescriptor(MarkerImageDescriptor.createFromMarker(marker, + ICON_WIDTH, ICON_HEIGHT, false)); + setToolTipText(marker.getName()); + } + + public void run() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("InsertMarkerCount"); //$NON-NLS-1$ + RecentMarkerGroup.instance.addMarker(marker); + IWorkbenchPage page = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().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(); +// } +// } + } + } + } + } + } + + private static final int POPOVER_WIDTH = 255; + private static final int POPOVER_HEIGHT = 380; + + @Override + protected Control createContents(Composite parent) { + Composite composite = (Composite) super.createContents(parent); + + Composite composite2 = new Composite(composite, SWT.WRAP); + composite2.setBackground(composite2.getParent().getBackground()); + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.widthHint = POPOVER_WIDTH; + gridData.heightHint = POPOVER_HEIGHT; + composite2.setLayoutData(gridData); + + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 2; + composite2.setLayout(layout); + + createMarkersContainer(composite2); + createSeperator(composite2); + createHyperlinks(composite2); + + return composite; + } + + private ScrolledForm createForm(Composite parent) { + final WidgetFactory factory = new WidgetFactory(parent.getDisplay()); + final ScrolledForm form = new ScrolledForm(parent, + SWT.V_SCROLL | factory.getOrientation()); + form.setExpandHorizontal(true); + form.setExpandVertical(true); + form.setBackground(factory.getColors().getBackground()); + form.setForeground(factory.getColors().getColor(IFormColors.TITLE)); + form.setFont(JFaceResources.getHeaderFont()); + form.setMinWidth(1); + form.setAlwaysShowScrollBars(true); + form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + form.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + if (factory != null) { + factory.dispose(); + } + } + }); + return form; + } + + private void createMarkersContainer(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(composite.getParent().getBackground()); + GridData gridData = new GridData(GridData.FILL_BOTH); + composite.setLayoutData(gridData); + + GridLayout layout = new GridLayout(1, true); + layout.marginTop = 1; + layout.marginHeight = 3; + layout.marginWidth = 3; + layout.verticalSpacing = 7; + composite.setLayout(layout); + + final ScrolledForm form = createForm(composite); + final Composite formBody = form.getBody(); + final GridLayout layout2 = new GridLayout(1, true); + layout2.marginLeft = 12; + layout2.marginWidth = 0; + formBody.setLayout(layout2); + formBody.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + createMarkersControl(formBody); + form.addListener(SWT.Resize, new Listener() { + public void handleEvent(Event event) { + int width = form.getClientArea().width; + width -= layout2.marginLeft + layout2.marginRight + + layout2.marginWidth * 2; + Control[] controls = formBody.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 void createMarkersControl(Composite parent) { + List sheets = new ArrayList(); + if (MindMapUI.getResourceManager().getSystemMarkerSheet() != null) + sheets.add(MindMapUI.getResourceManager().getSystemMarkerSheet()); + if (MindMapUI.getResourceManager().getUserMarkerSheet() != null) + sheets.add(MindMapUI.getResourceManager().getUserMarkerSheet()); + MarkerSheetPart markerPart = new MarkerSheetPart(sheets); + Control control = markerPart.createControl(parent); + + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + control.setLayoutData(gridData); + } + + private void createSeperator(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + + composite.setBackground(composite.getParent().getBackground()); + GridData gridData = new GridData(GridData.FILL, GridData.CENTER, true, + false); + composite.setLayoutData(gridData); + + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + composite.setLayout(layout); + + Composite seperator = new Composite(composite, SWT.NONE); + seperator.setBackground( + new LocalResourceManager(JFaceResources.getResources(), + composite).createColor(ColorUtils.toRGB("#cbcbcb"))); //$NON-NLS-1$ + GridData gridData2 = new GridData(SWT.FILL, SWT.CENTER, true, false); + gridData2.heightHint = 1; + seperator.setLayoutData(gridData2); + seperator.setLayout(layout); + } + + private void createHyperlinks(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(composite.getParent().getBackground()); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + composite.setLayoutData(gridData); + + GridLayout layout = new GridLayout(); + layout.marginHeight = 5; + layout.marginWidth = 0; + layout.marginBottom = 2; + layout.verticalSpacing = 2; + composite.setLayout(layout); + + createManageMarkersHyperlink(composite); + createImportMarkersHyperlink(composite); + createExportMarkersHyperlink(composite); + } + + private void createManageMarkersHyperlink(Composite parent) { + Hyperlink manageMarkersHyperlink = createHyperlink(parent, + Messages.MarkersPopover_ManageMarkers_label); + + manageMarkersHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + + @Override + public void linkActivated(HyperlinkEvent e) { + E4Utils.showPart(IModelConstants.COMMAND_SHOW_DIALOG_PART, + PlatformUI.getWorkbench().getActiveWorkbenchWindow(), + IModelConstants.PART_ID_RESOURCE_MANAGER, + IModelConstants.PAGE_ID_RESOURCE_MANAGER_MARKER, null); + + } + }); + } + + private void createImportMarkersHyperlink(Composite parent) { + Hyperlink importManagerHyperlink = createHyperlink(parent, + Messages.MarkersPopover_ImportMarkers_label); + importManagerHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + @Override + public void linkActivated(HyperlinkEvent e) { + + handleShellDeactived(); + + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + final IHandlerService handlerService = window + .getService(IHandlerService.class); + SafeRunner.run(new SafeRunnable() { + @Override + public void run() throws Exception { + handlerService.executeCommand( + "org.xmind.ui.command.marker.import", null); //$NON-NLS-1$ + } + }); + } + }); + } + + private void createExportMarkersHyperlink(Composite parent) { + Hyperlink link = createHyperlink(parent, + Messages.MarkersPopover_ExportMarkers_label); + link.addHyperlinkListener(new HyperlinkAdapter() { + @Override + public void linkActivated(HyperlinkEvent e) { + + handleShellDeactived(); + + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + + final IHandlerService handlerService = window + .getService(IHandlerService.class); + SafeRunner.run(new SafeRunnable() { + @Override + public void run() throws Exception { + handlerService.executeCommand( + "org.xmind.ui.command.marker.export", null); //$NON-NLS-1$ + } + }); + } + }); + } + + private Hyperlink createHyperlink(final Composite parent, String message) { + final Composite padding = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 15; + layout.marginHeight = 0; + padding.setBackground(parent.getBackground()); + padding.setLayout(layout); + GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); + padding.setLayoutData(gridData); + + final Hyperlink hyperlink = new Hyperlink(padding, SWT.SINGLE); + hyperlink.setBackground(hyperlink.getParent().getBackground()); + + hyperlink.setLayoutData(gridData); + hyperlink.setUnderlined(false); + hyperlink.setText(message); + + hyperlink.addMouseTrackListener(new MouseTrackAdapter() { + @Override + public void mouseExit(MouseEvent e) { + padding.setBackground(new LocalResourceManager( + JFaceResources.getResources(), parent) + .createColor(ColorUtils.toRGB("#FFFFFF"))); //$NON-NLS-1$ + hyperlink.setBackground(new LocalResourceManager( + JFaceResources.getResources(), parent) + .createColor(ColorUtils.toRGB("#FFFFFF"))); //$NON-NLS-1$ + hyperlink.setForeground(new LocalResourceManager( + JFaceResources.getResources(), parent) + .createColor(ColorUtils.toRGB("#000000"))); //$NON-NLS-1$ + } + + @Override + public void mouseEnter(MouseEvent e) { + padding.setBackground(new LocalResourceManager( + JFaceResources.getResources(), parent) + .createColor(ColorUtils.toRGB("#0070D8"))); //$NON-NLS-1$ + hyperlink.setBackground(new LocalResourceManager( + JFaceResources.getResources(), parent) + .createColor(ColorUtils.toRGB("#0070D8"))); //$NON-NLS-1$ + hyperlink.setForeground(new LocalResourceManager( + JFaceResources.getResources(), parent) + .createColor(ColorUtils.toRGB("#FFFFFF"))); //$NON-NLS-1$ + } + + }); + + return hyperlink; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/popover/PopoverMenuToolItem.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/popover/PopoverMenuToolItem.java new file mode 100644 index 000000000..92be5824f --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/popover/PopoverMenuToolItem.java @@ -0,0 +1,144 @@ +package org.xmind.ui.internal.popover; + +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.graphics.Region; +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.Layout; +import org.eclipse.swt.widgets.Shell; +import org.xmind.ui.internal.e4handlers.DirectToolItem; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.util.RegionUtils; + +public class PopoverMenuToolItem extends DirectToolItem { + + private Shell shell; + + private Control contents; + + private ShellAdapter shellDeactivedListener = new ShellAdapter() { + + @Override + public void shellDeactivated(ShellEvent e) { + handleShellDeactived(); + } + }; + + private LocalResourceManager localResourceManager; + + @Override + protected void showExtensionControl(Rectangle itemBoundsToDisplay) { + if (shell != null && !shell.isDisposed()) { + if (shellDeactivedListener != null) { + shell.removeShellListener(shellDeactivedListener); + } + shell.dispose(); + } + shell = createShell(); + localResourceManager = new LocalResourceManager( + JFaceResources.getResources(), shell); + + configureShell(shell); + contents = createContents(shell); + initializeBounds(itemBoundsToDisplay); + + shell.setActive(); + shell.setVisible(true); + shell.forceFocus(); + } + + protected Shell createShell() { + return new Shell(Display.getCurrent().getActiveShell(), SWT.NO_TRIM); + } + + protected void configureShell(Shell newShell) { + newShell.addShellListener(shellDeactivedListener); + Layout layout = getLayout(); + if (layout != null) { + newShell.setLayout(layout); + } + newShell.setBackground( + localResourceManager.createColor(ColorUtils.toRGB("#c2c2c2"))); //$NON-NLS-1$ + } + + protected Layout getLayout() { + GridLayout layout = new GridLayout(); + layout.marginHeight = 1; + layout.marginWidth = 1; + return layout; + } + + protected Control createContents(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground( + localResourceManager.createColor(ColorUtils.toRGB("#ffffff"))); //$NON-NLS-1$ + GridData gridData = new GridData(GridData.FILL_BOTH); + composite.setLayoutData(gridData); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 0; + layout.marginHeight = 0; + composite.setLayout(layout); + + return composite; + } + + protected void initializeBounds(Rectangle itemBoundsToDisplay) { + Point size = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + Region region = RegionUtils + .getRoundedRectangle(new Rectangle(0, 0, size.x, size.y), 6); + shell.setRegion(region); + + Region region2 = RegionUtils.getRoundedRectangle( + new Rectangle(0, 0, size.x - 2, size.y - 2), 6); + contents.setRegion(region2); + + Point location = getLocation(itemBoundsToDisplay, size); + shell.setLocation(location); + } + + private Point getLocation(Rectangle itemBoundsToDisplay, Point size) { + return new Point( + itemBoundsToDisplay.x + itemBoundsToDisplay.width / 2 + - size.x / 2, + itemBoundsToDisplay.y + itemBoundsToDisplay.height); + } + + protected void handleShellDeactived() { + if (shell == null || shell.isDisposed()) + return; + + shell.removeShellListener(shellDeactivedListener); + Region region = shell.getRegion(); + if (region != null) { + region.dispose(); + region = null; + } + + Region region2 = contents.getRegion(); + if (region2 != null) { + region2.dispose(); + region2 = null; + } + + shell.dispose(); + } + + @Override + public T getAdapter(Class adapter) { + if (LocalResourceManager.class.equals(adapter)) { + return adapter.cast(localResourceManager); + } + return super.getAdapter(adapter); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/popover/ThemePopoverMenuToolItem.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/popover/ThemePopoverMenuToolItem.java new file mode 100644 index 000000000..e87a0a103 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/popover/ThemePopoverMenuToolItem.java @@ -0,0 +1,639 @@ +package org.xmind.ui.internal.popover; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +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 org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.IOpenListener; +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.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.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.PreferencesUtil; +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.handlers.IHandlerService; +import org.osgi.framework.Bundle; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +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.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.Request; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +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.MindMapUIPlugin; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.E4Utils; +import org.xmind.ui.internal.views.Messages; +import org.xmind.ui.internal.views.ThemeLabelProvider; +import org.xmind.ui.mindmap.IResourceManager; +import org.xmind.ui.mindmap.ISheetPart; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.util.MindMapUtils; +import org.xml.sax.SAXException; + +public class ThemePopoverMenuToolItem extends PopoverMenuToolItem { + + private static final String THEME_POPOVER_XML = "styles/themePopover.xml"; //$NON-NLS-1$ + + private static final String TAG_THEME = "theme"; //$NON-NLS-1$ + + private static final String ATTR_ID = "id"; //$NON-NLS-1$ + + private static final String Extract_Theme_Command_ID = "org.xmind.ui.command.extractTheme"; //$NON-NLS-1$ + + private class ChangeThemeListener implements IOpenListener { + + private class ThemeOverrideDialog extends Dialog { + private Button rememberCheck; + + protected ThemeOverrideDialog(Shell parentShell) { + super(parentShell); + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(Messages.ThemesView_Dialog_title); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea( + parent); + + Label label = new Label(composite, SWT.NONE); + label.setText(Messages.ThemesView_Dialog_message); + + createRememberCheck(composite); + + return composite; + } + + private void createRememberCheck(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginTop = 25; + composite.setLayout(gridLayout); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + rememberCheck = new Button(composite, SWT.CHECK); + rememberCheck.setText(Messages.ThemesView_Dialog_Check); + rememberCheck.setLayoutData( + new GridData(SWT.FILL, SWT.BOTTOM, true, true)); + } + + protected Control createButtonBar(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, false)); + GridLayout gridLayout = new GridLayout(2, false); + gridLayout.marginWidth = convertHorizontalDLUsToPixels( + IDialogConstants.HORIZONTAL_MARGIN); + gridLayout.marginHeight = convertVerticalDLUsToPixels( + IDialogConstants.VERTICAL_MARGIN); + gridLayout.marginBottom = convertVerticalDLUsToPixels( + IDialogConstants.VERTICAL_MARGIN); + gridLayout.verticalSpacing = convertVerticalDLUsToPixels( + IDialogConstants.VERTICAL_SPACING); + gridLayout.horizontalSpacing = convertHorizontalDLUsToPixels( + IDialogConstants.HORIZONTAL_SPACING); + composite.setLayout(gridLayout); + + createPrefLink(composite); + + Composite buttonBar = new Composite(composite, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 0; // this is incremented by createButton + layout.makeColumnsEqualWidth = false; + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.horizontalSpacing = convertHorizontalDLUsToPixels( + IDialogConstants.HORIZONTAL_SPACING); + layout.verticalSpacing = convertVerticalDLUsToPixels( + IDialogConstants.VERTICAL_SPACING); + buttonBar.setLayout(layout); + buttonBar.setLayoutData( + new GridData(SWT.END, SWT.CENTER, true, true)); + buttonBar.setFont(parent.getFont()); + + createButtonsForButtonBar(buttonBar); + + return buttonBar; + } + + private void createPrefLink(Composite parent) { + Hyperlink prefLink = new Hyperlink(parent, SWT.SINGLE); + prefLink.setText(Messages.ThemesView_Dialog_PrefLink); + prefLink.setUnderlined(true); + prefLink.setForeground( + parent.getDisplay().getSystemColor(SWT.COLOR_BLUE)); + + prefLink.addHyperlinkListener(new HyperlinkAdapter() { + @Override + public void linkActivated(HyperlinkEvent e) { + PreferencesUtil.createPreferenceDialogOn(null, + "org.xmind.ui.ThemePrefPage", null, null) //$NON-NLS-1$ + .open(); + } + }); + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, + Messages.ThemesView_OverrideButton, true); + createButton(parent, IDialogConstants.NO_ID, + Messages.ThemesView_KeepButton, false); + } + + @Override + protected void buttonPressed(int buttonId) { + super.buttonPressed(buttonId); + if (IDialogConstants.NO_ID == buttonId) + noPressed(); + } + + @Override + protected void okPressed() { + if (rememberCheck.getSelection()) + pref.setValue(PrefConstants.THEME_APPLY, + PrefConstants.THEME_OVERRIDE); + else + pref.setValue(PrefConstants.THEME_APPLY, + PrefConstants.ASK_USER); + super.okPressed(); + } + + private void noPressed() { + if (rememberCheck.getSelection()) + pref.setValue(PrefConstants.THEME_APPLY, + PrefConstants.THEME_KEEP); + else + pref.setValue(PrefConstants.THEME_APPLY, + PrefConstants.ASK_USER); + setReturnCode(IDialogConstants.NO_ID); + close(); + } + } + + private IPreferenceStore pref = MindMapUIPlugin.getDefault() + .getPreferenceStore(); + + public void open(OpenEvent event) { + if (updatingSelection) + return; + + String themeApply = pref.getString(PrefConstants.THEME_APPLY); + if (isThemeModified() && (PrefConstants.ASK_USER.equals(themeApply) + || IPreferenceStore.STRING_DEFAULT_DEFAULT + .equals(themeApply))) { + int code = openCoverDialog(); + if (IDialogConstants.CANCEL_ID == code) + return; + + if (IDialogConstants.OK_ID == code) + themeApply = PrefConstants.THEME_OVERRIDE; + else if (IDialogConstants.NO_ID == code) + themeApply = PrefConstants.THEME_KEEP; + } + + Object o = ((IStructuredSelection) event.getSelection()) + .getFirstElement(); + if (o != null && o instanceof IStyle) { + changeTheme((IStyle) o, themeApply); + } + } + + private int openCoverDialog() { + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getShell(); + if (shell != null) + return new ThemeOverrideDialog(shell).open(); + return IDialogConstants.NO_ID; + } + + private boolean isThemeModified() { + ISheet sheet = getCurrentSheet(); + if (sheet == null) + return false; + + if (sheet.getStyleId() != null) + return true; + + List topics = MindMapUtils.getAllTopics(sheet, true, true); + for (ITopic topic : topics) { + if (topic.getStyleId() != null) + return true; + Set boundaries = topic.getBoundaries(); + for (IBoundary boundary : boundaries) { + if (boundary.getStyleId() != null) + return true; + } + Set summaries = topic.getSummaries(); + for (ISummary summary : summaries) { + if (summary.getStyleId() != null) + return true; + } + } + + Set relationships = sheet.getRelationships(); + for (IRelationship relationship : relationships) { + if (relationship.getStyleId() != null) + return true; + } + + return false; + } + + private ISheet getCurrentSheet() { + IEditorPart activeEditor = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage() + .getActiveEditor(); + + if (activeEditor instanceof IGraphicalEditor) { + IGraphicalEditor editor = (IGraphicalEditor) activeEditor; + if (editor.getActivePageInstance() != null) { + ISheet sheet = (ISheet) editor.getActivePageInstance() + .getAdapter(ISheet.class); + return sheet; + } + } + return null; + } + } + + private GalleryViewer viewer; + + private IGraphicalEditor activeEditor; + + private boolean updatingSelection = false; + + @Override + protected Control createContents(Composite parent) { + Composite composite = (Composite) super.createContents(parent); + + Composite composite2 = new Composite(composite, SWT.NONE); + composite2.setBackground(composite2.getParent().getBackground()); + GridData gridData = new GridData(GridData.FILL_BOTH); + composite2.setLayoutData(gridData); + + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.verticalSpacing = 2; + composite2.setLayout(layout); + + createThemesContainer(composite2); + createSeperator(composite2); + createHyperlinks(composite2); + + return composite; + } + + private void createThemesContainer(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(composite.getParent().getBackground()); + + GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); + composite.setLayoutData(gridData); + + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + layout.marginHeight = 5; + layout.marginTop = 5; + composite.setLayout(layout); + + createThemesViewer(composite); + + IEditorPart editor = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage().getActiveEditor(); + if (editor instanceof IGraphicalEditor) { + setActiveEditor((IGraphicalEditor) editor); + } + } + + private void createThemesViewer(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.Horizontal, Boolean.TRUE); + properties.set(GalleryViewer.Wrap, Boolean.TRUE); + properties.set(GalleryViewer.FlatFrames, true); + properties.set(GalleryViewer.SolidFrames, true); + + properties.set(GalleryViewer.HideTitle, false); + properties.set(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_BOTTOM); + properties.set(GalleryViewer.ImageConstrained, true); + + properties.set(GalleryViewer.SingleClickToOpen, Boolean.FALSE); + properties.set(GalleryViewer.CustomContentPaneDecorator, true); + + properties.set(GalleryViewer.FrameContentSize, new Dimension(94, 48)); + properties.set(GalleryViewer.Layout, + new GalleryLayout(GalleryLayout.ALIGN_CENTER, + GalleryLayout.ALIGN_CENTER, 2, 2, + new Insets(0, 0, 0, 0))); + + Control control = viewer.createControl(parent); + GridData gridData = new GridData(GridData.FILL_BOTH); + gridData.widthHint = 340; + control.setLayoutData(gridData); + + viewer.setLabelProvider(new ThemeLabelProvider()); + viewer.addOpenListener(new ChangeThemeListener()); + viewer.setInput(getViewerInput()); + } + + private void createSeperator(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(composite.getParent().getBackground()); + GridData gridData = new GridData(GridData.FILL, GridData.CENTER, true, + false); + composite.setLayoutData(gridData); + + GridLayout layout = new GridLayout(1, false); + layout.marginWidth = 15; + layout.marginHeight = 0; + composite.setLayout(layout); + + Composite seperator = new Composite(composite, SWT.NONE); + seperator.setBackground( + new LocalResourceManager(JFaceResources.getResources(), + composite).createColor(ColorUtils.toRGB("#cbcbcb"))); //$NON-NLS-1$ + GridData gridData2 = new GridData(SWT.FILL, SWT.CENTER, true, false); + gridData2.heightHint = 1; + seperator.setLayoutData(gridData2); + seperator.setLayout(new GridLayout()); + } + + private void createHyperlinks(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + composite.setBackground(composite.getParent().getBackground()); + GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); + composite.setLayoutData(gridData); + + GridLayout layout = new GridLayout(); + layout.marginWidth = 15; + layout.marginHeight = 5; + layout.marginBottom = 5; + layout.verticalSpacing = 4; + composite.setLayout(layout); + + createMoreThemesHyperlink(composite); + createManageThemesHyperlink(composite); + createExtractThemeHyperlink(composite); + } + + private void createMoreThemesHyperlink(Composite parent) { + Hyperlink moreThemesHyperlink = createHyperlink(parent, + Messages.ThemesPopover_MoreTheme_label); + + moreThemesHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + + @Override + public void linkActivated(HyperlinkEvent e) { + E4Utils.showPart(IModelConstants.COMMAND_SHOW_MODEL_PART, + PlatformUI.getWorkbench().getActiveWorkbenchWindow(), + IModelConstants.PART_ID_THEMES, null, + IModelConstants.PART_STACK_ID_RIGHT); + } + }); + } + + private void createManageThemesHyperlink(Composite parent) { + Hyperlink manageThemesHyperlink = createHyperlink(parent, + Messages.ThemesPopover_ManagerTheme_label); + + manageThemesHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + + @Override + public void linkActivated(HyperlinkEvent e) { + E4Utils.showPart(IModelConstants.COMMAND_SHOW_DIALOG_PART, + PlatformUI.getWorkbench().getActiveWorkbenchWindow(), + IModelConstants.PART_ID_RESOURCE_MANAGER, + IModelConstants.PAGE_ID_RESOURCE_MANAGER_THEME, null); + + } + }); + } + + private void createExtractThemeHyperlink(Composite parent) { + Hyperlink extractThemeHyperlink = createHyperlink(parent, + Messages.ThemesPopover_Extract_Current_Theme_label); + + extractThemeHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + + @Override + public void linkActivated(HyperlinkEvent e) { + IWorkbenchPage page = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + if (page == null) { + return; + } + + IEditorPart editor = page.getActiveEditor(); + if (editor == null) { + return; + } + + final IHandlerService handlerService = (IHandlerService) editor + .getSite().getService(IHandlerService.class); + if (handlerService == null) { + return; + } + + SafeRunner.run(new SafeRunnable() { + + public void run() throws Exception { + handlerService.executeCommand(Extract_Theme_Command_ID, + null); + } + }); + } + }); + } + + private Hyperlink createHyperlink(Composite parent, String message) { + Hyperlink hyperlink = new Hyperlink(parent, SWT.SINGLE); + hyperlink.setBackground(hyperlink.getParent().getBackground()); + GridData gridData = new GridData(SWT.LEFT, SWT.CENTER, false, false); + hyperlink.setLayoutData(gridData); + + hyperlink.setUnderlined(false); + hyperlink.setText(message); + + return hyperlink; + } + + private List getViewerInput() { + List list = new ArrayList(); + + DocumentBuilder documentBuilder = null; + try { + documentBuilder = DocumentBuilderFactory.newInstance() + .newDocumentBuilder(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + + try { + Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); + URL url = FileLocator.find(bundle, new Path(THEME_POPOVER_XML), + null); + Document doc = documentBuilder.parse(url.openStream()); + + IResourceManager rm = MindMapUI.getResourceManager(); + Set systemThemeSets = rm.getSystemThemeSheet() + .getStyles(IStyleSheet.MASTER_STYLES); + + NodeList nodeList = doc.getElementsByTagName(TAG_THEME); + for (int i = 0; i < nodeList.getLength(); i++) { + Element ele = (Element) nodeList.item(i); + String themeId = ele.getAttribute(ATTR_ID); + + Iterator iterSystemTheme = systemThemeSets.iterator(); + while (iterSystemTheme.hasNext()) { + IStyle themeStyle = iterSystemTheme.next(); + if (themeId.equals(themeStyle.getId())) { + list.add(themeStyle); + break; + } + } + } + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return list; + } + + private void setActiveEditor(IGraphicalEditor editor) { + if (editor != activeEditor) { + activeEditor = editor; + updateSelection(); + } + } + + private void updateSelection() { + if (viewer == null || viewer.getControl().isDisposed()) + return; + + String themeId = getCurrentThemeId(); + IStyle theme = MindMapUI.getResourceManager().getBlankTheme(); + if (themeId != null && !theme.getId().equals(themeId)) { + theme = MindMapUI.getResourceManager().getSystemThemeSheet() + .findStyle(themeId); + if (theme == null) + theme = MindMapUI.getResourceManager().getUserThemeSheet() + .findStyle(themeId); + } + + updatingSelection = true; + viewer.setSelection(theme == null ? StructuredSelection.EMPTY + : new StructuredSelection(theme)); + updatingSelection = false; + } + + private void changeTheme(IStyle theme, String apply) { + if (activeEditor == null) + return; + + IGraphicalEditorPage page = activeEditor.getActivePageInstance(); + if (page == null) + return; + + IGraphicalViewer viewer = page.getViewer(); + if (viewer == null) + return; + + ISheetPart sheetPart = (ISheetPart) viewer.getAdapter(ISheetPart.class); + if (sheetPart == null) + return; + + EditDomain domain = page.getEditDomain(); + if (domain == null) + return; + + domain.handleRequest(new Request(MindMapUI.REQ_MODIFY_THEME) + .setViewer(viewer).setPrimaryTarget(sheetPart) + .setParameter(MindMapUI.PARAM_RESOURCE, theme) + .setParameter(MindMapUI.PARAM_OVERRIDE, apply)); + updateSelection(); + Control control = viewer.getControl(); + if (control != null && !control.isDisposed()) { + control.forceFocus(); + } + } + + private String getCurrentThemeId() { + if (activeEditor == null) + return null; + + IGraphicalEditorPage page = activeEditor.getActivePageInstance(); + if (page == null) + return null; + + ISheet sheet = (ISheet) page.getAdapter(ISheet.class); + if (sheet == null) + return null; + + return sheet.getThemeId(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/AuthorInfoPreferenceSection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/AuthorInfoPreferenceSection.java new file mode 100644 index 000000000..ac64f2c6f --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/AuthorInfoPreferenceSection.java @@ -0,0 +1,215 @@ +package org.xmind.ui.internal.prefs; + +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +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.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.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.xmind.core.internal.dom.DOMConstants; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.preference.PreferenceFieldEditorPageSection; +import org.xmind.ui.prefs.PrefConstants; + +public class AuthorInfoPreferenceSection extends + PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { + + private Text nameEditor = null; + + private Text emailEditor = null; + + private Text organizationEditor = null; + + private static final String EMPTY = ""; //$NON-NLS-1$ + + protected IPreferenceStore doGetPreferenceStore() { + return MindMapUIPlugin.getDefault().getPreferenceStore(); + } + + @Override + public void init(IWorkbench workbench) { + String name = doGetPreferenceStore() + .getString(PrefConstants.AUTHOR_INFO_NAME); + if (name == null || "".equals(name)) { //$NON-NLS-1$ + doGetPreferenceStore().setValue(PrefConstants.AUTHOR_INFO_NAME, + System.getProperty("user.name")); //$NON-NLS-1$ + } + } + + @Override + protected Control createContents(Composite parent) { + Label descriptionLabel = new Label(parent, SWT.WRAP); + descriptionLabel + .setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + GridData data = ((GridData) descriptionLabel.getLayoutData()); + data.widthHint = 450; + descriptionLabel.setText(PrefMessages.AuthorInfoPage_Message); + GridLayout layout = (GridLayout) parent.getLayout(); + layout.marginLeft = 25; + layout.verticalSpacing = 5; + createNameItem(parent); + createEmailItem(parent); + createOrganizationItem(parent); + return parent; + } + + private Composite createNameItem(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + createLabel(composite, PrefMessages.AuthorInfoPage_Name_label); + nameEditor = createEditor(composite, doGetPreferenceStore() + .getString(PrefConstants.AUTHOR_INFO_NAME), false); + return composite; + } + + private Composite createEmailItem(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + createLabel(composite, PrefMessages.AuthorInfoPage_Email_label); + emailEditor = createEditor(composite, doGetPreferenceStore() + .getString(PrefConstants.AUTHOR_INFO_EMAIL), true); + return composite; + } + + private Composite createOrganizationItem(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + createLabel(composite, PrefMessages.AuthorInfoPage_Organization_label); + organizationEditor = createEditor(composite, + doGetPreferenceStore().getString(PrefConstants.AUTHOR_INFO_ORG), + true); + + return composite; + } + + private void createLabel(Composite parent, String text) { + Composite composite = new Composite(parent, SWT.NONE); + GridData data = new GridData(SWT.RIGHT, SWT.FILL, false, false); + data.widthHint = 100; + composite.setLayoutData(data); + GridLayoutFactory.fillDefaults().applyTo(composite); + Label label = new Label(composite, SWT.NONE); + label.setText(text); + } + + private Text createEditor(Composite parent, String content, + boolean canBeEmpty) { + + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(composite); + + final Text editor = new Text(composite, SWT.BORDER | SWT.SINGLE); + GridData data = new GridData(SWT.RIGHT, SWT.FILL, false, false); + data.widthHint = 240; + editor.setLayoutData(data); + if (content != null && !EMPTY.equals(content)) + editor.setText(content); + + if (!canBeEmpty) { + editor.addFocusListener(new FocusListener() { + + public void focusLost(FocusEvent e) { + validateLibraryName(editor); + } + + public void focusGained(FocusEvent e) { + e.display.asyncExec(new Runnable() { + public void run() { + if (editor.isDisposed()) + return; + editor.setSelection(0, editor.getCharCount()); + } + }); + } + }); + + editor.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validateLibraryName(editor); + } + }); + } + + return editor; + } + + protected boolean validateLibraryName(Text editor) { + if (EMPTY.equals(editor.getText())) { + setErrorMessage(PrefMessages.PreferencePage_EmptyName_errorMessage); + return false; + } else { + setErrorMessage(null); + return true; + } + } + + @Override + public boolean performOk() { + if (!saveLibraryName()) + return false; + return true; + } + + @Override + protected void performDefaults() { + + System.setProperty(DOMConstants.AUTHOR_NAME, + System.getProperty("user.name")); //$NON-NLS-1$ + System.setProperty(DOMConstants.AUTHOR_EMAIL, EMPTY); + System.setProperty(DOMConstants.AUTHOR_ORG, EMPTY); + + if (nameEditor != null && !nameEditor.isDisposed()) + nameEditor.setText(System.getProperty("user.name")); //$NON-NLS-1$ + if (emailEditor != null && !emailEditor.isDisposed()) + emailEditor.setText(EMPTY); + if (organizationEditor != null && !organizationEditor.isDisposed()) + organizationEditor.setText(EMPTY); + + doGetPreferenceStore().setValue(PrefConstants.AUTHOR_INFO_NAME, + System.getProperty("user.name")); //$NON-NLS-1$ + doGetPreferenceStore().setValue(PrefConstants.AUTHOR_INFO_EMAIL, EMPTY); + doGetPreferenceStore().setValue(PrefConstants.AUTHOR_INFO_ORG, EMPTY); + + super.performDefaults(); + } + + private boolean saveLibraryName() { + if (nameEditor == null || nameEditor.isDisposed()) + return true; + if (!validateLibraryName(nameEditor)) + return false; + + System.setProperty(DOMConstants.AUTHOR_NAME, nameEditor.getText()); + System.setProperty(DOMConstants.AUTHOR_EMAIL, emailEditor.getText()); + System.setProperty(DOMConstants.AUTHOR_ORG, + organizationEditor.getText()); + + doGetPreferenceStore().setValue(PrefConstants.AUTHOR_INFO_NAME, + nameEditor.getText()); + doGetPreferenceStore().setValue(PrefConstants.AUTHOR_INFO_EMAIL, + emailEditor.getText()); + doGetPreferenceStore().setValue(PrefConstants.AUTHOR_INFO_ORG, + organizationEditor.getText()); + + return true; + } + + @Override + protected void createFieldEditors() { + + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/DnDPreferencePageSection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/DnDPreferencePageSection.java new file mode 100644 index 000000000..5c6f5d363 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/DnDPreferencePageSection.java @@ -0,0 +1,42 @@ +package org.xmind.ui.internal.prefs; + +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.ui.IWorkbench; +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 DnDPreferencePageSection extends PreferenceFieldEditorPageSection + implements IWorkbenchPreferencePage { + + IPreferenceStore pre = MindMapUIPlugin.getDefault().getPreferenceStore(); + + private String[][] dndString = new String[][] { + { PrefMessages.DnDPrefPage_LinkButton, + PrefConstants.CREATE_HYPERLINK }, + { PrefMessages.DnDPrefPage_CopyButton, + PrefConstants.CREATE_ATTACHMENT }, + { PrefMessages.DnDPrefPage_AlwaysRequestButton, + PrefConstants.ASK_USER } }; + + @Override + public void init(IWorkbench workbench) { + this.setPreferenceStore(pre); + } + + @Override + protected void createFieldEditors() { + addField(new ComboFieldEditor(PrefConstants.ADD_EXTERNAL_FILE, + PrefMessages.DnDPrefPage_DnDLabel_Text, dndString, + getDecratorParentComposite())); + } + + @Override + protected void performDefaults() { + pre.setValue(PrefConstants.ADD_EXTERNAL_FILE, PrefConstants.ASK_USER); + super.performDefaults(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/EditorPrefPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/EditorPrefPage.java index 82408e5ba..8117a6d3d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/EditorPrefPage.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/EditorPrefPage.java @@ -21,7 +21,6 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkbench; @@ -82,6 +81,7 @@ private void addTopicPositioningGroup() { Composite parent = createGroup( PrefMessages.EditorPage_TopicPositioning_title); addAllowOverlapsField(createFieldContainer(parent)); + addAllowManualLayoutField(createFieldContainer(parent)); addAllowFreePositionField(createFieldContainer(parent)); Label descriptionLabel = new Label(parent, SWT.WRAP); @@ -163,6 +163,12 @@ private void addAllowOverlapsField(Composite parent) { parent)); } + private void addAllowManualLayoutField(Composite parent) { + addField(new BooleanFieldEditor(PrefConstants.MANUAL_LAYOUT_ALLOWED, + PrefMessages.EditorPage_TopicPositioning_AllowManualLayout, + parent)); + } + private void addAllowFreePositionField(Composite parent) { addField(new BooleanFieldEditor(PrefConstants.FREE_POSITION_ALLOWED, PrefMessages.EditorPage_TopicPositioning_AllowFreePosition, @@ -171,13 +177,13 @@ private void addAllowFreePositionField(Composite parent) { private void addZoomField() { if (getPreferenceStore().getInt(PrefConstants.ZOOM_VALUE) == 0) { - int width = Display.getCurrent().getBounds().width; - if (width < 1366) - getPreferenceStore().setValue(PrefConstants.ZOOM_VALUE, 100); - else if (width <= 1920) - getPreferenceStore().setValue(PrefConstants.ZOOM_VALUE, 120); - else - getPreferenceStore().setValue(PrefConstants.ZOOM_VALUE, 150); +// int width = Display.getCurrent().getBounds().width; +// if (width < 1366) + getPreferenceStore().setValue(PrefConstants.ZOOM_VALUE, 100); +// else if (width <= 1920) +// getPreferenceStore().setValue(PrefConstants.ZOOM_VALUE, 120); +// else +// getPreferenceStore().setValue(PrefConstants.ZOOM_VALUE, 150); } addField(new IntegerFieldEditor(PrefConstants.ZOOM_VALUE, diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/OthersPreferenceSection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/OthersPreferenceSection.java new file mode 100644 index 000000000..d8ef357fa --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/OthersPreferenceSection.java @@ -0,0 +1,81 @@ +package org.xmind.ui.internal.prefs; + +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.ui.IWorkbench; +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 OthersPreferenceSection extends PreferenceFieldEditorPageSection + implements IWorkbenchPreferencePage { + + @Override + protected void createFieldEditors() { + addAnimationField(); + addShadowField(); + addZoomField(); + } + + protected IPreferenceStore doGetPreferenceStore() { + return MindMapUIPlugin.getDefault().getPreferenceStore(); + } + + private void addAnimationField() { + addField(new BooleanFieldEditor(PrefConstants.ANIMATION_ENABLED, + PrefMessages.EditorPage_EnableAnimation_text, + getDecratorParentComposite())); + } + + private void addShadowField() { + addField(new BooleanFieldEditor(PrefConstants.SHADOW_ENABLED, + PrefMessages.EditorPage_EnableShadow_text, + getDecratorParentComposite())); + } + + private void addZoomField() { + if (getPreferenceStore().getInt(PrefConstants.ZOOM_VALUE) == 0) { +// int width = Display.getCurrent().getBounds().width; +// if (width <= 1370) + getPreferenceStore().setValue(PrefConstants.ZOOM_VALUE, 100); +// else if (width > 1370 && width <= 1930) +// getPreferenceStore().setValue(PrefConstants.ZOOM_VALUE, 120); +// else +// getPreferenceStore().setValue(PrefConstants.ZOOM_VALUE, 150); + } + + String[][] zoom = new String[][] { { "50%", "50" }, { "75%", "75" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + { "100%", "100" }, { "120%", "120" }, { "150%", "150" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ + { "200%", "200" }, { "300%", "300" } }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + + addField(new ComboFieldEditor(PrefConstants.ZOOM_VALUE, + PrefMessages.EditorPage_Zoom_Scale_text, zoom, + getDecratorParentComposite())); + } + + @Override + public void init(IWorkbench workbench) { + } + + @Override + public void apply() { + this.performApply(); + } + + @Override + public boolean ok() { + return this.performOk(); + } + + @Override + public void excuteDefault() { + this.performDefaults(); + } + + @Override + public boolean cancel() { + return this.performCancel(); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/PrefMessages.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/PrefMessages.java index 658832274..96bbd6f68 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/PrefMessages.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/PrefMessages.java @@ -35,6 +35,7 @@ public class PrefMessages extends NLS { public static String EditorPage_UndoRedo_description; public static String EditorPage_TopicPositioning_title; public static String EditorPage_TopicPositioning_AllowOverlaps; + public static String EditorPage_TopicPositioning_AllowManualLayout; public static String EditorPage_TopicPositioning_AllowFreePosition; public static String EditorPage_TopicPositioning_FreePositioning_description; public static String EditorPage_Preview_text; diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/PreferenceInitializer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/PreferenceInitializer.java index 49bc0c7d2..46f378a15 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/PreferenceInitializer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/PreferenceInitializer.java @@ -1,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ package org.xmind.ui.internal.prefs; @@ -17,6 +14,8 @@ import org.eclipse.core.runtime.preferences.DefaultScope; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.ui.internal.IPreferenceConstants; +import org.eclipse.ui.internal.WorkbenchPlugin; import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.internal.mindmap.UndoRedoTipsService; import org.xmind.ui.prefs.PrefConstants; @@ -26,6 +25,7 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer { private static final String DEFAULT_SAVE_WIZARDS = "org.xmind.ui.saveWizards.localFile,org.xmind.ui.saveWizards.seawind"; //$NON-NLS-1$ // private static final String DEFAULT_SAVE_WIZARD_ID = "org.xmind.ui.saveWizards.seawind"; //$NON-NLS-1$ private static final String DEFAULT_DND_CLIENT_ID_ORDER = "org.xmind.ui.dnd.workbookComponent org.xmind.ui.dnd.image org.xmind.ui.dnd.file org.xmind.ui.dnd.url org.xmind.ui.dnd.text"; //$NON-NLS-1$ + private static final int DEFAULT_RECENT_VALUE = 20; public void initializeDefaultPreferences() { IScopeContext context = DefaultScope.INSTANCE; @@ -36,9 +36,13 @@ public void initializeDefaultPreferences() { node.putBoolean(PrefConstants.OVERLAPS_ALLOWED, false); node.putBoolean(PrefConstants.FREE_POSITION_ALLOWED, true); node.putBoolean(PrefConstants.AUTO_BACKUP_ENABLE, true); + node.putBoolean(PrefConstants.SHOW_OVERVIEW, false); node.put(PrefConstants.DND_CLIENT_ID_ORDER, DEFAULT_DND_CLIENT_ID_ORDER); - node.putInt(PrefConstants.UNDO_LIMIT, 100); + node.putInt(PrefConstants.UNDO_LIMIT, 20); + + WorkbenchPlugin.getDefault().getPreferenceStore().setDefault( + IPreferenceConstants.RECENT_FILES, DEFAULT_RECENT_VALUE); node.putBoolean(PrefConstants.GRADIENT_COLOR, true); @@ -48,7 +52,8 @@ public void initializeDefaultPreferences() { UndoRedoTipsService.DEFAULT_DURATION); node.put(PrefConstants.SAVE_WIZARDS, DEFAULT_SAVE_WIZARDS); + node.putInt(PrefConstants.ZOOM_VALUE, 100); // node.put(PrefConstants.DEFAULT_SAVE_WIZARD, DEFAULT_SAVE_WIZARD_ID); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/ThemePreferencePageSection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/ThemePreferencePageSection.java new file mode 100644 index 000000000..21b775d5a --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/ThemePreferencePageSection.java @@ -0,0 +1,50 @@ +package org.xmind.ui.internal.prefs; + +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.preference.PreferenceFieldEditorPageSection; +import org.xmind.ui.prefs.PrefConstants; + +public class ThemePreferencePageSection extends PreferenceFieldEditorPageSection + implements IWorkbenchPreferencePage { + + private IPreferenceStore pref = MindMapUIPlugin.getDefault() + .getPreferenceStore(); + + private ComboFieldEditor themeCombo; + + private String[][] themes = new String[][] { + { PrefMessages.ThemePrefPage_OverrideButton, + PrefConstants.THEME_OVERRIDE }, + { PrefMessages.ThemePrefPage_KeepButton, PrefConstants.THEME_KEEP }, + { PrefMessages.ThemePrefPage_AskButton, PrefConstants.ASK_USER } }; + + @Override + public void init(IWorkbench workbench) { + this.setPreferenceStore(pref); + } + + @Override + protected void createFieldEditors() { + themeCombo = new ComboFieldEditor(PrefConstants.THEME_APPLY, + MindMapMessages.ThemePrefPage_ThemeEditor_label, themes, + getDecratorParentComposite()); + addField(themeCombo); + } + + @Override + protected void performDefaults() { + pref.setValue(PrefConstants.THEME_APPLY, PrefConstants.ASK_USER); + super.performDefaults(); + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/TopicPositionPreferenceSection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/TopicPositionPreferenceSection.java new file mode 100644 index 000000000..9c0493a58 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/TopicPositionPreferenceSection.java @@ -0,0 +1,70 @@ +package org.xmind.ui.internal.prefs; + +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IWorkbench; +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 TopicPositionPreferenceSection extends + PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { + + private Composite container; + + @Override + public void init(IWorkbench workbench) { + } + + @Override + protected void createFieldEditors() { + GridLayout layout = (GridLayout) container.getLayout(); + layout.marginLeft = 25; + addAllowOverlapsField(); + addAllowManualLayoutField(); +// addAllowFreePositionField(); + +// Label descriptionLabel = new Label(container, SWT.WRAP); +// descriptionLabel +// .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); +// ((GridData) descriptionLabel.getLayoutData()).widthHint = 450; +// descriptionLabel.setText( +// PrefMessages.EditorPage_TopicPositioning_FreePositioning_description); + } + + @Override + protected Control createContents(Composite parent) { + if (null == container) + this.container = parent; + return super.createContents(parent); + } + + // allow overlap + private void addAllowOverlapsField() { + addField(new BooleanFieldEditor(PrefConstants.OVERLAPS_ALLOWED, + PrefMessages.EditorPage_TopicPositioning_AllowOverlaps, + getFieldEditorParent())); + } + +// private void addAllowFreePositionField() { +// addField(new BooleanFieldEditor(PrefConstants.FREE_POSITION_ALLOWED, +// PrefMessages.EditorPage_TopicPositioning_AllowFreePosition, +// getFieldEditorParent())); +// } + + //allow manual layout + private void addAllowManualLayoutField() { + addField(new BooleanFieldEditor(PrefConstants.MANUAL_LAYOUT_ALLOWED, + PrefMessages.EditorPage_TopicPositioning_AllowManualLayout, + getFieldEditorParent())); + } + + protected IPreferenceStore doGetPreferenceStore() { + return MindMapUIPlugin.getDefault().getPreferenceStore(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/UndoRedoPreferencePageSection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/UndoRedoPreferencePageSection.java new file mode 100644 index 000000000..4c61cb032 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/UndoRedoPreferencePageSection.java @@ -0,0 +1,54 @@ +package org.xmind.ui.internal.prefs; + +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +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.Label; +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 UndoRedoPreferencePageSection extends + PreferenceFieldEditorPageSection implements IWorkbenchPreferencePage { + + private Composite container; + + private String[][] undos = new String[][] { { "10", "10" }, { "20", "20" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + { "50", "50" }, { "100", "100" } }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + + @Override + protected Control createContents(Composite parent) { + container = parent; + return super.createContents(parent); + } + + protected IPreferenceStore doGetPreferenceStore() { + return MindMapUIPlugin.getDefault().getPreferenceStore(); + } + + @Override + protected void createFieldEditors() { + addUndoRedoField(); + } + + private void addUndoRedoField() { + Label descriptionLabel = new Label(container, SWT.WRAP); + GridData data = (GridData) descriptionLabel.getLayoutData(); + if (null == data) { + data = new GridData(SWT.FILL, SWT.CENTER, true, false); + data.widthHint = 450; + data.horizontalIndent = 25; + descriptionLabel.setLayoutData(data); + } + descriptionLabel.setText(PrefMessages.EditorPage_UndoRedo_description); + addField(new ComboFieldEditor(PrefConstants.UNDO_LIMIT, + PrefMessages.EditorPage_UndoLimit_label, undos, + getDecratorParentComposite())); + + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/messages.properties b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/messages.properties index 230933302..d554102b2 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/messages.properties +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/prefs/messages.properties @@ -11,6 +11,7 @@ EditorPage_UndoLimit_label=The maximum number of continuous undo operations: EditorPage_UndoRedo_description=Higher values may provide you more chances to restore former work, but meanwhile may take more memory usage. EditorPage_TopicPositioning_title=Topic Positioning EditorPage_TopicPositioning_AllowOverlaps=Allow Topic Overlaps +EditorPage_TopicPositioning_AllowManualLayout=Allow Free Positioning EditorPage_TopicPositioning_AllowFreePosition=Allow Free Positioning EditorPage_TopicPositioning_FreePositioning_description=Hold Alt(on Windows)/Command(on Mac) when dragging a main topic under the 'Map' structure to move it to a more 'hand-drawn' position. EditorPage_Preview_text=Skip preview picture when saving a workbook diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/MultipageImagePreviewViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/MultipageImagePreviewViewer.java index a2875a798..d6572310a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/MultipageImagePreviewViewer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/MultipageImagePreviewViewer.java @@ -24,6 +24,7 @@ import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; import org.eclipse.jface.util.Util; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Font; @@ -179,6 +180,8 @@ public void layout(IFigure container) { private Font footerFont; + private ResourceManager resources; + private Listener eventHandler = new Listener() { public void handleEvent(Event event) { handleWidgetEvent(event); @@ -190,6 +193,9 @@ public MultipageImagePreviewViewer(boolean fill) { public void createControl(Composite parent) { composite = new Composite(parent, SWT.NONE); + resources = new LocalResourceManager(JFaceResources.getResources(), + composite); + GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; @@ -943,10 +949,9 @@ private void setFontHeightToPreview(IFigure target) { } private Image getIcon(String path, boolean enabled) { - return MindMapUIPlugin - .imageDescriptorFromPlugin(MindMapUI.PLUGIN_ID, - "icons/nav/" + (enabled ? "e/" : "d/") + path) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - .createImage(); + return (Image) resources.get( + MindMapUIPlugin.imageDescriptorFromPlugin(MindMapUI.PLUGIN_ID, + "icons/nav/" + (enabled ? "e/" : "d/") + path)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/MultipageSetupDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/MultipageSetupDialog.java index 95c14dfe5..29454e8f5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/MultipageSetupDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/MultipageSetupDialog.java @@ -31,6 +31,8 @@ import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.TrayDialog; import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; import org.eclipse.jface.util.Util; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; @@ -134,14 +136,14 @@ public String getTitle(Image image, boolean largeImage) { }, // Generating(MindMapMessages.MultipageSetupDialog_GeneratingPreview, SWT.COLOR_DARK_GRAY, SWT.NONE), // - Error(MindMapMessages.MultipageSetupDialog_FaildGenerate - + MindMapMessages.MultipageSetupDialog_PrintDirectly, - SWT.COLOR_DARK_RED, SWT.NONE) { - public String getTitle(Image image, boolean largeImage) { - return makeErrorMessage( - super.getTitle(image, largeImage), largeImage); - } - }; + Error(MindMapMessages.MultipageSetupDialog_FaildGenerate + + MindMapMessages.MultipageSetupDialog_PrintDirectly, + SWT.COLOR_DARK_RED, SWT.NONE) { + public String getTitle(Image image, boolean largeImage) { + return makeErrorMessage(super.getTitle(image, largeImage), + largeImage); + } + }; private static String makeErrorMessage(String originalMessage, boolean largeImage) { @@ -226,6 +228,7 @@ public FontAction(String key) { public void run() { FontDialog dialog = new FontDialog(getShell()); + dialog.setEffectsVisible(false); String string = getString(key, null); if (string == null) { dialog.setFontList(JFaceResources.getDefaultFontDescriptor() @@ -306,6 +309,8 @@ public void run() { private boolean isRefreshingPages = false; + private ResourceManager resources; + private Listener eventHandler = new Listener() { public void handleEvent(Event event) { handleWidgetEvent(event); @@ -324,6 +329,8 @@ public MultipageSetupDialog(Shell parentShell, IGraphicalEditorPage page, protected void configureShell(Shell newShell) { super.configureShell(newShell); + resources = new LocalResourceManager(JFaceResources.getResources(), + newShell); newShell.setText(DialogMessages.PageSetupDialog_windowTitle); } @@ -536,13 +543,15 @@ private void createShowPlusMinusIconsSection(Composite parent) { private void createShowPlusCheck(Composite parent) { showPlusCheck = createPlusMinusCheck(parent, MindMapMessages.MultipageSetupDialog_showPlusCheck_text, - MindMapUI.getImages().get("plus.png", true).createImage()); //$NON-NLS-1$ + (Image) resources + .get(MindMapUI.getImages().get("plus.png", true))); //$NON-NLS-1$ } private void createShowMinusCheck(Composite parent) { showMinusCheck = createPlusMinusCheck(parent, MindMapMessages.MultipageSetupDialog_showMinusCheck_text, - MindMapUI.getImages().get("minus.png", true).createImage()); //$NON-NLS-1$ + (Image) resources + .get(MindMapUI.getImages().get("minus.png", true))); //$NON-NLS-1$ } private Button createPlusMinusCheck(Composite parent, String text, @@ -1736,7 +1745,6 @@ private Rectangle getImageBorderBounds(IGraphicalEditorPage page, /** * Multiply the given number by 1000, and then split the result into integer * part and decimal part. - * *

    * Sample:
    * @@ -1749,7 +1757,6 @@ private Rectangle getImageBorderBounds(IGraphicalEditorPage page, * assert parts2[0] == "0034"; * assert parts2[1] == "524000"; * - * *

    * * @param value @@ -1771,7 +1778,6 @@ private static String[] split1000(double value) { /** * Merge prefix(integer part) and suffix(decimal part) into a number and * return result of the number devided by 1000. - * *

    * Sample:
    * @@ -1782,7 +1788,6 @@ private static String[] split1000(double value) { * value = join1000("34", "524000") * assert value == 0.034524 * - * *

    * * @param prefix @@ -1796,4 +1801,4 @@ private static double join1000(String prefix, String suffix) { return Double.parseDouble(prefix + "." + mid + suffix); //$NON-NLS-1$ } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/PrintMultipagePreviewImageCreator.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/PrintMultipagePreviewImageCreator.java index 0bd4ad879..757812a62 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/PrintMultipagePreviewImageCreator.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/print/multipage/PrintMultipagePreviewImageCreator.java @@ -28,7 +28,6 @@ import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.mindmap.MindMapViewerExportSourceProvider; import org.xmind.ui.resources.ColorUtils; -import org.xmind.ui.wizards.ExportContants; public class PrintMultipagePreviewImageCreator { diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/FontPropertySectionPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/FontPropertySectionPart.java index 32de6c80b..23655b66c 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/FontPropertySectionPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/FontPropertySectionPart.java @@ -1,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ package org.xmind.ui.internal.properties; @@ -31,13 +28,11 @@ import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.graphics.TextStyle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.ToolBar; import org.xmind.gef.GEF; -import org.xmind.gef.IGraphicalViewer; import org.xmind.gef.IViewer; import org.xmind.gef.Request; import org.xmind.gef.graphicalpolicy.IStyleSelector; @@ -47,21 +42,16 @@ import org.xmind.ui.color.IColorSelection; import org.xmind.ui.color.PaletteContents; import org.xmind.ui.commands.CommandMessages; -import org.xmind.ui.font.FontDialog; -import org.xmind.ui.font.IFontChooser; -import org.xmind.ui.font.IFontChooserListener; +import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.mindmap.IMindMapImages; -import org.xmind.ui.mindmap.ITopicPart; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.properties.StyledPropertySectionPart; -import org.xmind.ui.resources.ColorUtils; import org.xmind.ui.resources.FontUtils; import org.xmind.ui.richtext.AlignmentGroup; import org.xmind.ui.richtext.TextCaseGroup; import org.xmind.ui.style.StyleUtils; import org.xmind.ui.style.Styles; import org.xmind.ui.style.TextStyleData; -import org.xmind.ui.util.MindMapUtils; import org.xmind.ui.viewers.MComboViewer; public class FontPropertySectionPart extends StyledPropertySectionPart { @@ -81,53 +71,8 @@ public void selectionChanged(SelectionChangedEvent event) { .getFirstElement(); if (o instanceof String) { changeFontName((String) o); - } - } - - } - - private class ChooseFontAction extends Action { - - public ChooseFontAction() { - super(null, - MindMapUI.getImages().get(IMindMapImages.TEXT_FONT, true)); - setToolTipText(PropertyMessages.ChooseFont_toolTip); - } - - public void run() { - if (currentTextStyle == null) - return; - - FontDialog dialog = new FontDialog( - getContainer().getContainerSite().getShell()); - - if (currentTextStyle != null) { - if (currentTextStyle.name != null) - dialog.setFontName(currentTextStyle.name); - if (currentTextStyle.height > 0) - dialog.setFontHeight(currentTextStyle.height); - dialog.setBold(currentTextStyle.bold); - dialog.setItalic(currentTextStyle.italic); - if (currentTextStyle.color != null) - dialog.setColor(currentTextStyle.color); - dialog.setUnderline(currentTextStyle.underline); - dialog.setStrikeout(currentTextStyle.strikeout); - } - - dialog.addFontChooserListener(new IFontChooserListener() { - public void fontChanged(IFontChooser source) { - showTempFont(source); - } - - }); - - int ret = dialog.open(); - showTempFont(null); - if (ret == FontDialog.OK) { - changeFont(dialog.getFontName(), dialog.getFontHeight(), - dialog.getBold(), dialog.getItalic(), - dialog.getUnderline(), dialog.getStrikeout(), - dialog.getColor()); + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("FontChangeCount"); //$NON-NLS-1$ } } @@ -340,7 +285,7 @@ protected void createContent(Composite parent) { Composite line1 = new Composite(parent, SWT.NONE); line1.setLayoutData( new GridData(GridData.FILL, GridData.FILL, true, false)); - GridLayout layout1 = new GridLayout(2, false); + GridLayout layout1 = new GridLayout(1, false); layout1.marginWidth = 0; layout1.marginHeight = 0; layout1.horizontalSpacing = 3; @@ -392,11 +337,11 @@ private void createLineContent1(Composite parent) { // }; // FontUtils.fetchAvailableFontNames(parent.getDisplay(), callback); - ToolBarManager fontBar = new ToolBarManager(SWT.FLAT); - fontBar.add(new ChooseFontAction()); - ToolBar barControl = fontBar.createControl(parent); - barControl.setLayoutData( - new GridData(GridData.END, GridData.CENTER, false, false)); +// ToolBarManager fontBar = new ToolBarManager(SWT.FLAT); +// fontBar.add(new ChooseFontAction()); +// ToolBar barControl = fontBar.createControl(parent); +// barControl.setLayoutData( +// new GridData(GridData.END, GridData.CENTER, false, false)); } private void createLineContent2(Composite parent) { @@ -623,24 +568,6 @@ private void changeFontName(String name) { Styles.FontFamily, name)); } - private void changeFont(String fontName, int fontHeight, boolean bold, - boolean italic, boolean underline, boolean strikeout, RGB color) { - Request req = createStyleRequest(CommandMessages.Command_ModifyFont); - if (fontName != null) - addStyle(req, Styles.FontFamily, fontName); - if (fontHeight > 0) - addStyle(req, Styles.FontSize, StyleUtils.addUnitPoint(fontHeight)); - addStyle(req, Styles.FontWeight, - bold ? Styles.FONT_WEIGHT_BOLD : Styles.NORMAL); - addStyle(req, Styles.FontStyle, - italic ? Styles.FONT_STYLE_ITALIC : Styles.NORMAL); - addStyle(req, Styles.TextDecoration, - StyleUtils.toTextDecoration(underline, strikeout)); - addStyle(req, Styles.TextColor, - color == null ? null : ColorUtils.toString(color)); - sendRequest(req); - } - private void changeFontSize(int fontHeight) { sendRequest( addStyle(createStyleRequest(CommandMessages.Command_ModifyFont), @@ -737,40 +664,4 @@ private void changeTextCapitalize() { sendRequest(request); } - private void showTempFont(IFontChooser source) { - IGraphicalViewer viewer = getActiveViewer(); - if (viewer == null) - return; - - TextStyle textStyle; - if (source == null) { - textStyle = null; - } else { - textStyle = new TextStyle( - FontUtils.getFont(source.getFontName(), - source.getFontHeight(), source.getBold(), - source.getItalic()), - ColorUtils.getColor(source.getColor()), null); - textStyle.strikeout = source.getStrikeout(); - textStyle.underline = source.getUnderline(); - } - for (Object o : getSelectedElements()) { - IGraphicalPart part = getGraphicalPart(o, viewer); - if (part != null) { - IGraphicalPart p = part instanceof ITopicPart - ? ((ITopicPart) part).getOwnerBranch() : part; -// (ITitleTextPart) part -// .getAdapter(ITitleTextPart.class); - if (p != null) { - if (textStyle == null) { - MindMapUtils.flushCache(p, MindMapUI.CACHE_TEXT_STYLE); - } else { - MindMapUtils.setCache(p, MindMapUI.CACHE_TEXT_STYLE, - textStyle); - } - p.refresh(); - } - } - } - } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LegendPropertySectionPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LegendPropertySectionPart.java index 3812bdc1c..ddd15ccc8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LegendPropertySectionPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LegendPropertySectionPart.java @@ -34,6 +34,7 @@ import org.xmind.ui.color.IColorSelection; import org.xmind.ui.color.PaletteContents; import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.properties.StyledPropertySectionPart; import org.xmind.ui.style.Styles; @@ -43,6 +44,8 @@ public class LegendPropertySectionPart extends StyledPropertySectionPart { private class BackgroundColorOpenListener implements IOpenListener { public void open(OpenEvent event) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ChangeLegendBackgroudCount"); //$NON-NLS-1$ changeBackgroundColor((IColorSelection) event.getSelection()); } @@ -56,8 +59,8 @@ public void open(OpenEvent event) { protected void createContent(Composite parent) { visibilityCheck = new Button(parent, SWT.CHECK); - visibilityCheck.setLayoutData(new GridData(GridData.FILL, - GridData.CENTER, true, false)); + visibilityCheck.setLayoutData( + new GridData(GridData.FILL, GridData.CENTER, true, false)); visibilityCheck.setText(PropertyMessages.ShowLegend_text); visibilityCheck.setToolTipText(PropertyMessages.ShowLegend_toolTip); visibilityCheck.addListener(SWT.Selection, new Listener() { @@ -77,13 +80,14 @@ private void createBackgroundPart(Composite parent) { Label caption = new Label(composite, SWT.NONE); caption.setText(PropertyMessages.BackgroundColor_label); - caption.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, - false, false)); - - backgroundColorPicker = new ColorPicker(ColorPicker.AUTO - | ColorPicker.CUSTOM, PaletteContents.getDefault()); - backgroundColorPicker.getAction().setToolTipText( - PropertyMessages.LegendBackground_toolTip); + caption.setLayoutData( + new GridData(GridData.FILL, GridData.CENTER, false, false)); + + backgroundColorPicker = new ColorPicker( + ColorPicker.AUTO | ColorPicker.CUSTOM, + PaletteContents.getDefault()); + backgroundColorPicker.getAction() + .setToolTipText(PropertyMessages.LegendBackground_toolTip); backgroundColorPicker .addOpenListener(new BackgroundColorOpenListener()); ToolBarManager colorBar = new ToolBarManager(SWT.FLAT); @@ -144,4 +148,4 @@ private void changeBackgroundColor(IColorSelection selection) { CommandMessages.Command_ModifyLegendBackgroundColor); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LinePatternLabelProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LinePatternLabelProvider.java index ebf6e5955..de07b2c78 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LinePatternLabelProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LinePatternLabelProvider.java @@ -15,9 +15,11 @@ import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.graphics.Image; +import org.xmind.ui.resources.ImageDescriptorProvider; import org.xmind.ui.viewers.ImageCachedLabelProvider; -public class LinePatternLabelProvider extends ImageCachedLabelProvider { +public class LinePatternLabelProvider extends ImageCachedLabelProvider + implements ImageDescriptorProvider { public String getText(Object element) { LinePattern value; @@ -50,4 +52,20 @@ protected Image createImage(Object element) { return null; } -} \ No newline at end of file + @Override + public ImageDescriptor getImageDescriptor(Object element) { + LinePattern value; + if (element instanceof LinePattern) { + value = (LinePattern) element; + } else if (element instanceof String) { + value = LinePattern.findByValue((String) element); + } else { + value = null; + } + if (value != null) { + return value.getIcon(); + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LineWidth.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LineWidth.java index 818de8d07..6aa469792 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LineWidth.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LineWidth.java @@ -19,19 +19,18 @@ public enum LineWidth { - None("0pt", PropertyMessages.LineWidth_None, null), //$NON-NLS-1$ + None("0pt", PropertyMessages.LineWidth_None, IMindMapImages.LINE_NONE), //$NON-NLS-1$ Thinnest("1pt", PropertyMessages.LineWidth_Thinnest, //$NON-NLS-1$ IMindMapImages.LINE_THINNEST), // - Thin("2pt", PropertyMessages.LineWidth_Thin, //$NON-NLS-1$ - IMindMapImages.LINE_THIN), // - Medium("3pt", PropertyMessages.LineWidth_Medium, //$NON-NLS-1$ - IMindMapImages.LINE_MEDIUM), // - Fat("4pt", PropertyMessages.LineWdith_Fat, //$NON-NLS-1$ - IMindMapImages.LINE_FAT), // - Fattest("5pt", //$NON-NLS-1$ - PropertyMessages.LineWidth_Fattest, - IMindMapImages.LINE_FATTEST); + Thin("2pt", PropertyMessages.LineWidth_Thin, //$NON-NLS-1$ + IMindMapImages.LINE_THIN), // + Medium("3pt", PropertyMessages.LineWidth_Medium, //$NON-NLS-1$ + IMindMapImages.LINE_MEDIUM), // + Fat("4pt", PropertyMessages.LineWdith_Fat, //$NON-NLS-1$ + IMindMapImages.LINE_FAT), // + Fattest("5pt", //$NON-NLS-1$ + PropertyMessages.LineWidth_Fattest, IMindMapImages.LINE_FATTEST); private String value; @@ -77,4 +76,4 @@ public static LineWidth findByValue(String value) { } return null; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LineWidthLabelProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LineWidthLabelProvider.java index b17fc791d..52e2c3258 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LineWidthLabelProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/LineWidthLabelProvider.java @@ -15,9 +15,11 @@ import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.graphics.Image; +import org.xmind.ui.resources.ImageDescriptorProvider; import org.xmind.ui.viewers.ImageCachedLabelProvider; -public class LineWidthLabelProvider extends ImageCachedLabelProvider { +public class LineWidthLabelProvider extends ImageCachedLabelProvider + implements ImageDescriptorProvider { public String getText(Object element) { LineWidth value; @@ -50,4 +52,20 @@ protected Image createImage(Object element) { return null; } -} \ No newline at end of file + @Override + public ImageDescriptor getImageDescriptor(Object element) { + LineWidth value; + if (element instanceof LineWidth) { + value = (LineWidth) element; + } else if (element instanceof String) { + value = LineWidth.findByValue((String) element); + } else { + value = null; + } + if (value != null) { + return value.getIcon(); + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/NumberingPropertySectionPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/NumberingPropertySectionPart.java index 5431a5940..77a3e2f90 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/NumberingPropertySectionPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/NumberingPropertySectionPart.java @@ -14,11 +14,9 @@ package org.xmind.ui.internal.properties; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -28,14 +26,16 @@ import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; 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.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolBar; import org.xmind.core.Core; import org.xmind.core.INumbering; import org.xmind.core.ITopic; @@ -43,7 +43,8 @@ import org.xmind.core.event.ICoreEventRegister; import org.xmind.gef.Request; import org.xmind.gef.draw2d.graphics.GraphicsUtils; -import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.mindmap.INumberFormatDescriptor; import org.xmind.ui.mindmap.INumberSeparatorDescriptor; import org.xmind.ui.mindmap.MindMapUI; @@ -51,105 +52,10 @@ import org.xmind.ui.util.MindMapUtils; import org.xmind.ui.viewers.MComboViewer; -public class NumberingPropertySectionPart extends - MindMapPropertySectionPartBase { - -// private static class BalanceLayout extends Layout { -// -// public Control left; -// -// public Control center; -// -// public Control right; -// -// public int spacing = 3; -// -// protected Point computeSize(Composite composite, int wHint, int hHint, -// boolean flushCache) { -// Point size = new Point(0, 0); -// if (wHint >= 0) -// size.x = wHint; -// if (hHint >= 0) -// size.y = hHint; -// if (wHint < 0 || hHint < 0) { -// Point centerSize; -// if (center == null) { -// centerSize = null; -// } else { -// centerSize = center.computeSize(SWT.DEFAULT, hHint, -// flushCache); -// } -// Point leftSize; -// Point rightSize; -// if (left != null || right != null) { -// leftSize = left == null ? null : left.computeSize( -// SWT.DEFAULT, hHint, flushCache); -// rightSize = right == null ? null : right.computeSize( -// SWT.DEFAULT, hHint, flushCache); -// } else { -// leftSize = null; -// rightSize = null; -// } -// if (hHint < 0) { -// if (centerSize != null) -// size.y = Math.max(size.y, centerSize.y); -// if (leftSize != null) -// size.y = Math.max(size.y, leftSize.y); -// if (rightSize != null) -// size.y = Math.max(size.y, rightSize.y); -// } -// if (wHint < 0) { -// int width = 0; -// if (leftSize != null) -// width = Math.max(width, leftSize.x); -// if (rightSize != null) -// width = Math.max(width, rightSize.x); -// if (centerSize != null) -// width += centerSize.x; -// size.x = Math.max(size.x, width); -// } -// } -// -// // avoid using default width or height -// size.x = Math.max(1, size.x); -// size.y = Math.max(1, size.y); -// return size; -// } -// -// protected void layout(Composite composite, boolean flushCache) { -// Rectangle area = composite.getClientArea(); -// if (center != null) { -// if (left != null || right != null) { -// Point centerSize = center.computeSize(SWT.DEFAULT, -// area.height, flushCache); -// int maxCenterWidth = area.width - spacing * 2 - 20; -// int centerWidth = Math.min(centerSize.x, maxCenterWidth); -// center.setBounds(area.x + (area.width - centerWidth) / 2, -// area.y, centerWidth, area.height); -// int sideWidth = (area.width - spacing * 2 - centerSize.x) / 2; -// if (left != null) -// left.setBounds(area.x, area.y, sideWidth, area.height); -// if (right != null) -// right.setBounds(area.x + area.width - sideWidth, -// area.y, sideWidth, area.height); -// } else { -// center.setBounds(area); -// } -// } else if (left != null) { -// int sideWidth = Math.max(0, area.width -// - (right == null ? 0 : spacing)) / 2; -// left.setBounds(area.x, area.y, sideWidth, area.height); -// if (right != null) -// right.setBounds(area.x + area.width - sideWidth, area.y, -// sideWidth, area.height); -// } else if (right != null) { -// int rightWidth = Math.max(0, area.width / 2); -// right.setBounds(area.x + area.width - rightWidth, area.y, -// rightWidth, area.height); -// } -// } -// -// } +public class NumberingPropertySectionPart + extends MindMapPropertySectionPartBase { + + private static final Object INHERIT = new Object(); private class NumberFormatLabelProvider extends LabelProvider { public String getText(Object element) { @@ -179,8 +85,22 @@ public String getText(Object element) { } } - private class NumberFormatSelectionChangedListener implements - ISelectionChangedListener { + private class NumberDepthLabelProvider extends LabelProvider { + @Override + public String getText(Object element) { + if (INHERIT.equals(element)) + return MindMapMessages.NumberingProperty_NumberDepthLabelProvider_Inherit_text; + if (element instanceof String) { + String depth = (String) element; + return NLS.bind("{0} {1}", depth, //$NON-NLS-1$ + MindMapMessages.NumberingProperty_NumberDepthLabelProvider_Levels_text); + } + return super.getText(element); + } + } + + private class NumberFormatSelectionChangedListener + implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { if (isRefreshing()) @@ -189,14 +109,17 @@ public void selectionChanged(SelectionChangedEvent event) { Object o = ((IStructuredSelection) event.getSelection()) .getFirstElement(); if (o instanceof INumberFormatDescriptor) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("NumberingTypeCount:" //$NON-NLS-1$ + + ((INumberFormatDescriptor) o).getId()); changeNumberFormat(((INumberFormatDescriptor) o).getId()); } } } - private class SeparatorFormatSelectionChangedListener implements - ISelectionChangedListener { + private class SeparatorFormatSelectionChangedListener + implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { if (isRefreshing()) @@ -204,6 +127,7 @@ public void selectionChanged(SelectionChangedEvent event) { Object o = ((IStructuredSelection) event.getSelection()) .getFirstElement(); + if (o instanceof INumberSeparatorDescriptor) { changeNumberSeparator(((INumberSeparatorDescriptor) o).getId()); } @@ -212,81 +136,84 @@ public void selectionChanged(SelectionChangedEvent event) { } - private class PrependingAction extends Action { + private class NumberDepthSelectionChangedListener + implements ISelectionChangedListener { - public PrependingAction() { - super(null, AS_CHECK_BOX); - setImageDescriptor(MindMapUI.getImages().get( - IMindMapImages.NUMBERING_INHERIT, true)); - setDisabledImageDescriptor(MindMapUI.getImages().get( - IMindMapImages.NUMBERING_INHERIT, false)); - setToolTipText(PropertyMessages.PrependNumbering_toolTip); - setChecked(true); - } + @Override + public void selectionChanged(SelectionChangedEvent event) { + if (isRefreshing()) + return; + + Object o = ((IStructuredSelection) event.getSelection()) + .getFirstElement(); - public void run() { - changePrepending(isChecked()); + if (INHERIT == o) { + changeNumberDepth(null); + } else if (o instanceof String) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("NumberDepthCount" + o); //$NON-NLS-1$ + changeNumberDepth((String) o); + } } } private MComboViewer formatViewer; - private IAction prependingAction; + private Button tieredCheck; - private Label separatorLabel; + private MComboViewer depthViewer; private MComboViewer separatorViewer; - private Composite line3; - private Text prefixInput; private Text suffixInput; private Text numberLabel; - private Composite line2; - protected void createContent(Composite parent) { - Composite line1 = new Composite(parent, SWT.NONE); - line1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, - false)); - GridLayout layout1 = new GridLayout(2, false); - layout1.marginWidth = 0; - layout1.marginHeight = 0; - layout1.horizontalSpacing = 3; - layout1.verticalSpacing = 3; - line1.setLayout(layout1); - createLineContent1(line1); - - line3 = new Composite(parent, SWT.NONE); - line3.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, - false)); - GridLayout layout3 = new GridLayout(2, false); - layout3.marginWidth = 0; - layout3.marginHeight = 0; - layout3.verticalSpacing = 0; - layout3.horizontalSpacing = 3; - line3.setLayout(layout3); - createLineContent3(line3); - - line2 = new Composite(parent, SWT.NONE); - line2.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, - false)); - GridLayout layout2 = new GridLayout(3, false); - layout2.marginWidth = 0; - layout2.marginHeight = 0; - layout2.verticalSpacing = 0; - layout2.horizontalSpacing = 3; - line2.setLayout(layout2); - createLineContent2(line2); + Composite line1 = createLine(parent); + line1.setLayout(generateGridLayout(1)); + createNumberingFormatLine(line1); + + Composite line2 = createLine(parent); + line2.setLayout(generateGridLayout(1)); + createTieredCheckLine(line2); + + Composite line3 = createLine(parent); + line3.setLayout(generateGridLayout(2)); + createNumberingDepthLine(line3); + + Composite line4 = createLine(parent); + line4.setLayout(generateGridLayout(2)); + createNumberingSeparatorLine(line4); + + Composite line5 = createLine(parent); + line5.setLayout(generateGridLayout(3)); + createPrefixAndSuffixLine(line5); prefixInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); numberLabel .setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); suffixInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); } - private void createLineContent1(Composite parent) { + private GridLayout generateGridLayout(int cols) { + GridLayout gridLayout = new GridLayout(cols, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + gridLayout.horizontalSpacing = 3; + gridLayout.verticalSpacing = 3; + return gridLayout; + } + + private Composite createLine(Composite parent) { + Composite line = new Composite(parent, SWT.NONE); + line.setLayoutData( + new GridData(GridData.FILL, GridData.FILL, true, false)); + return line; + } + + private void createNumberingFormatLine(Composite parent) { formatViewer = new MComboViewer(parent, MComboViewer.NORMAL); formatViewer.getControl().setLayoutData( new GridData(GridData.FILL, GridData.FILL, true, false)); @@ -297,8 +224,8 @@ private void createLineContent1(Composite parent) { List list = new ArrayList(descriptors.size() + 1); Object separator = new Object(); INumberFormatDescriptor defaultDescriptor = MindMapUI - .getNumberFormatManager().getDescriptor( - MindMapUI.DEFAULT_NUMBER_FORMAT); + .getNumberFormatManager() + .getDescriptor(MindMapUI.DEFAULT_NUMBER_FORMAT); for (INumberFormatDescriptor desc : descriptors) { if (desc != null && defaultDescriptor != null && desc != defaultDescriptor) { @@ -311,24 +238,17 @@ private void createLineContent1(Composite parent) { } formatViewer.setSeparatorImitation(separator); formatViewer.setInput(list); - formatViewer - .addSelectionChangedListener(new NumberFormatSelectionChangedListener()); - - prependingAction = new PrependingAction(); - ToolBarManager bar = new ToolBarManager(SWT.FLAT); - bar.add(prependingAction); - ToolBar barControl = bar.createControl(parent); - barControl.setLayoutData(new GridData(GridData.END, GridData.CENTER, - false, false)); + formatViewer.addSelectionChangedListener( + new NumberFormatSelectionChangedListener()); } - private void createLineContent3(Composite parent) { - separatorLabel = new Label(parent, SWT.NONE); + private void createNumberingSeparatorLine(Composite parent) { + Label separatorLabel = new Label(parent, SWT.NONE); separatorLabel.setText(PropertyMessages.Separator_label); separatorViewer = new MComboViewer(parent, MComboViewer.NORMAL); - separatorViewer.getControl().setLayoutData( - new GridData(SWT.FILL, SWT.FILL, true, false)); + separatorViewer.getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); separatorViewer.setContentProvider(new ArrayContentProvider()); separatorViewer.setLabelProvider(new NumberSeparatorLabelProvider()); List descriptions = MindMapUI @@ -336,8 +256,8 @@ private void createLineContent3(Composite parent) { List list = new ArrayList(descriptions.size() + 1); Object separator = new Object(); INumberSeparatorDescriptor defautDescriptor = MindMapUI - .getNumberSeparatorManager().getDescriptor( - MindMapUI.DEFAULT_NUMBER_SEPARATOR); + .getNumberSeparatorManager() + .getDescriptor(MindMapUI.DEFAULT_NUMBER_SEPARATOR); if (defautDescriptor != null) { list.add(defautDescriptor); list.add(separator); @@ -350,15 +270,15 @@ private void createLineContent3(Composite parent) { } separatorViewer.setSeparatorImitation(separator); separatorViewer.setInput(list); - separatorViewer - .addSelectionChangedListener(new SeparatorFormatSelectionChangedListener()); + separatorViewer.addSelectionChangedListener( + new SeparatorFormatSelectionChangedListener()); } - private void createLineContent2(Composite parent) { + private void createPrefixAndSuffixLine(Composite parent) { prefixInput = new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.CENTER); - prefixInput.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, - true, false)); + prefixInput.setLayoutData( + new GridData(GridData.FILL, GridData.CENTER, true, false)); prefixInput.setToolTipText(PropertyMessages.Prefix_toolTip); Listener eventHandler = new Listener() { public void handleEvent(Event event) { @@ -379,23 +299,57 @@ public void handleEvent(Event event) { prefixInput.addListener(SWT.FocusOut, eventHandler); prefixInput.addListener(SWT.FocusIn, eventHandler); - numberLabel = new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY - | SWT.CENTER); - numberLabel.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, - false, false)); + numberLabel = new Text(parent, + SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY | SWT.CENTER); + numberLabel.setLayoutData( + new GridData(GridData.FILL, GridData.CENTER, false, false)); numberLabel.setEditable(false); - numberLabel.setBackground(numberLabel.getDisplay().getSystemColor( - SWT.COLOR_LIST_BACKGROUND)); + numberLabel.setBackground(numberLabel.getDisplay() + .getSystemColor(SWT.COLOR_LIST_BACKGROUND)); suffixInput = new Text(parent, SWT.SINGLE | SWT.BORDER | SWT.CENTER); - suffixInput.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, - true, false)); + suffixInput.setLayoutData( + new GridData(GridData.FILL, GridData.CENTER, true, false)); suffixInput.setToolTipText(PropertyMessages.Suffix_toolTip); suffixInput.addListener(SWT.DefaultSelection, eventHandler); suffixInput.addListener(SWT.FocusOut, eventHandler); suffixInput.addListener(SWT.FocusIn, eventHandler); } + private void createTieredCheckLine(Composite parent) { + tieredCheck = new Button(parent, SWT.CHECK); + tieredCheck.setText(MindMapMessages.NumberingProperty_TieredCheck_text); + tieredCheck.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + changePrepending(tieredCheck.getSelection()); + } + }); + } + + private void createNumberingDepthLine(Composite parent) { + Label label = new Label(parent, SWT.NONE); + label.setText(PropertyMessages.Depth_label); + + depthViewer = new MComboViewer(parent, MComboViewer.NORMAL); + depthViewer.getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + depthViewer.setContentProvider(new ArrayContentProvider()); + depthViewer.setLabelProvider(new NumberDepthLabelProvider()); + @SuppressWarnings("nls") + String[] values = new String[] { "1", "2", "3", "4", "5", "6", "7", "8", + "9", "10" }; + List input = new ArrayList(values.length + 1); + input.addAll(Arrays.asList(values)); + Object sep = new Object(); + input.add(sep); + input.add(INHERIT); + depthViewer.setSeparatorImitation(sep); + depthViewer.setInput(input); + depthViewer.addSelectionChangedListener( + new NumberDepthSelectionChangedListener()); + } + public void setFocus() { if (formatViewer != null && !formatViewer.getControl().isDisposed()) { formatViewer.getControl().setFocus(); @@ -405,14 +359,12 @@ public void setFocus() { public void dispose() { super.dispose(); formatViewer = null; - prependingAction = null; prefixInput = null; numberLabel = null; suffixInput = null; - line2 = null; - separatorLabel = null; separatorViewer = null; - line3 = null; + depthViewer = null; + tieredCheck = null; } protected void doRefresh() { @@ -430,51 +382,76 @@ protected void doRefresh() { numbering = null; } boolean hasFormat = false; - if (formatViewer != null && !formatViewer.getControl().isDisposed()) { - String format = numbering == null ? null : numbering - .getComputedFormat(); + if (formatViewer != null + && !formatViewer.getControl().isDisposed()) { + String format = numbering == null ? null + : numbering.getComputedFormat(); if (format == null) { format = MindMapUI.DEFAULT_NUMBER_FORMAT; + } else if (parent.getNumbering().getNumberFormat() == null + && !topic.getNumbering().isInherited(0)) { + format = MindMapUI.DEFAULT_NUMBER_FORMAT; } else { hasFormat = !MindMapUI.DEFAULT_NUMBER_FORMAT.equals(format); } INumberFormatDescriptor descriptor = MindMapUI .getNumberFormatManager().getDescriptor(format); - formatViewer - .setSelection(descriptor == null ? StructuredSelection.EMPTY + formatViewer.setSelection( + descriptor == null ? StructuredSelection.EMPTY : new StructuredSelection(descriptor)); } + if (depthViewer != null && !depthViewer.getControl().isDisposed()) { + Object select = INHERIT; + if (numbering != null) { + if (numbering.getDepth() != null) + select = numbering.getDepth(); + else if (numbering.getNumberFormat() != null + && !numbering.isInherited(1)) + select = "3"; //$NON-NLS-1$ + + depthViewer.setSelection(new StructuredSelection(select)); + + if (MindMapUI.DEFAULT_NUMBER_FORMAT + .equals(numbering.getNumberFormat())) { + depthViewer.setEnabled(false); + } else { + depthViewer + .setEnabled(numbering.getNumberFormat() != null + || topic.getNumbering().isInherited(0)); + } + } + } if (separatorViewer != null && !separatorViewer.getControl().isDisposed()) { - String separator = numbering == null ? null : numbering - .getComputedSeparator(); + String separator = numbering == null ? null + : numbering.getComputedSeparator(); if (separator == null) separator = MindMapUI.DEFAULT_NUMBER_SEPARATOR; INumberSeparatorDescriptor descriptor = MindMapUI .getNumberSeparatorManager().getDescriptor(separator); - separatorViewer - .setSelection(descriptor == null ? StructuredSelection.EMPTY + separatorViewer.setSelection( + descriptor == null ? StructuredSelection.EMPTY : new StructuredSelection(descriptor)); } - if (prependingAction != null) { - prependingAction.setChecked(numbering != null - && numbering.prependsParentNumbers()); + if (tieredCheck != null) { + tieredCheck.setSelection( + numbering != null && numbering.prependsParentNumbers()); } if (prefixInput != null && !prefixInput.isDisposed()) { - String prefix = numbering == null ? null : numbering - .getPrefix(); + String prefix = numbering == null ? null + : numbering.getPrefix(); prefixInput.setText(prefix == null ? "" : prefix); //$NON-NLS-1$ } if (suffixInput != null && !suffixInput.isDisposed()) { - String suffix = numbering == null ? null : numbering - .getSuffix(); + String suffix = numbering == null ? null + : numbering.getSuffix(); suffixInput.setText(suffix == null ? "" : suffix); //$NON-NLS-1$ } if (numberLabel != null && !numberLabel.isDisposed()) { String number; - number = MindMapUtils.getNumberingText(topic, hasFormat ? null - : MindMapUI.PREVIEW_NUMBER_FORMAT, hasFormat ? null - : MindMapUI.DEFAULT_NUMBER_SEPARATOR); + number = MindMapUtils.getNumberingText(topic, + hasFormat ? null : MindMapUI.PREVIEW_NUMBER_FORMAT, + hasFormat ? null : MindMapUI.DEFAULT_NUMBER_SEPARATOR); if (number == null || "".equals(number)) { //$NON-NLS-1$ numberLabel.setText(" "); //$NON-NLS-1$ } else { @@ -491,9 +468,6 @@ protected void doRefresh() { .getSystemColor(SWT.COLOR_DARK_GRAY)); } } - if (line2 != null && !line2.isDisposed()) { - line2.layout(); - } } } @@ -513,6 +487,7 @@ protected void registerEventListener(Object source, register.register(Core.NumberingSuffix); register.register(Core.NumberPrepending); register.register(Core.NumberingSeparator); + register.register(Core.NumberingDepth); } } @@ -555,7 +530,13 @@ private void changeNumberSeparator(String separatorId) { } } sendRequest(fillTargets(new Request(MindMapUI.REQ_MODIFY_NUMBERING)) - .setParameter(MindMapUI.PARAM_NUMBERING_SEPARATOR, separatorId)); + .setParameter(MindMapUI.PARAM_NUMBERING_SEPARATOR, + separatorId)); + } + + private void changeNumberDepth(String depth) { + sendRequest(fillTargets(new Request(MindMapUI.REQ_MODIFY_NUMBERING)) + .setParameter(MindMapUI.PARAM_NUMBERING_DEPTH, depth)); } private void changePrepending(boolean prepend) { diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/PropertiesPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/PropertiesPart.java new file mode 100644 index 000000000..27c387112 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/PropertiesPart.java @@ -0,0 +1,779 @@ + +package org.xmind.ui.internal.properties; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +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.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.jface.action.IAction; +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.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.custom.CTabItem; +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.Font; +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.IActionBars; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +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.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; +import org.eclipse.ui.internal.E4PartWrapper; +import org.eclipse.ui.internal.e4.compatibility.CompatibilityPart; +import org.eclipse.ui.part.IContributedContentsView; +import org.eclipse.ui.part.IPageSite; +import org.eclipse.ui.part.PageBook; +import org.eclipse.ui.services.IServiceLocator; +import org.xmind.core.style.IStyled; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; +import org.xmind.gef.ui.properties.IPropertyPartContainer; +import org.xmind.gef.ui.properties.IPropertySectionPart; +import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.commands.ModifyStyleCommand; +import org.xmind.ui.forms.WidgetFactory; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.e4models.ViewModelFolderRenderer; +import org.xmind.ui.internal.e4models.ViewModelPart; +import org.xmind.ui.mindmap.ICategoryAnalyzation; +import org.xmind.ui.mindmap.ICategoryManager; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; + +public class PropertiesPart extends ViewModelPart + implements ISelectionChangedListener, IPropertyPartContainer, + IContributedContentsView { + + private static class SectionRecord { + + String id; + + IPropertySectionPart section; + + Section control; + + boolean visible; + + public SectionRecord(String id, IPropertySectionPart section) { + this.id = id; + this.section = section; + } + + } + + private static final int DEFAULT_SECTION_WIDTH = 200; + + private IGraphicalEditor sourceEditor; + + private static PropertySectionContributorManager manager = PropertySectionContributorManager + .getInstance(); + + private List sections = new ArrayList(); + + private CTabItem ti; + + private String modeLabel; + + private Composite composite; + + private PageBook viewerStack; + + private Control defaultPage; + + private Composite contentComposite; + + private WidgetFactory widgetFactory; + + private ScrolledForm form; + + private String title; + + private Hyperlink resetStyleControl; + + private ResourceManager resources; + + protected void init() { + super.init(); + + EModelService modelService = getAdapter(EModelService.class); + MApplication application = getAdapter(MApplication.class); + ArrayList tags = new ArrayList(); + tags.add(IModelConstants.TAG_EDITOR); + tags.add(IModelConstants.TAG_ACTIVE); + List editors = modelService.findElements(application, + IModelConstants.PART_ID_COMPATIBILITY_EDITOR, MPart.class, + tags); + if (editors != null && !editors.isEmpty()) { + MPart editor = editors.get(0); + handlePartActivated(editor); + } + + initContent(); + } + + private void initContent() { + for (SectionRecord rec : sections) { + rec.section.init(this, getContributedEditor()); + } + + if (sourceEditor != null) { + sourceEditor.getSite().getSelectionProvider() + .addSelectionChangedListener(this); + + final ISelection selection = sourceEditor.getSite() + .getSelectionProvider().getSelection(); + if (selection != null && !selection.isEmpty()) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + selectionChanged(new SelectionChangedEvent( + sourceEditor.getSite().getSelectionProvider(), + selection)); + } + }); + } + } + } + + protected void createContent(Composite parent) { + CTabFolder ctf = new CTabFolder(parent, SWT.BORDER); + ctf.setRenderer(new ViewModelFolderRenderer(ctf)); + ctf.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + ti = new CTabItem(ctf, SWT.NONE); + MPart partModel = getAdapter(MPart.class); + modeLabel = partModel.getLocalizedLabel(); +// ti.setToolTipText(getToolTip(partModel.getLocalizedTooltip())); + ti.setText(modeLabel); + ctf.setSelection(ti); + + Composite contentContainer = new Composite(ctf, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + contentContainer.setLayout(layout); + + ti.setControl(contentContainer); + + Control content = doCreateContent(contentContainer); + content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + addTopRight(ctf, true); + adjustViewMenuBar(true); + } + + protected Control doCreateContent(Composite parent) { + resources = new LocalResourceManager(JFaceResources.getResources(), + parent); + + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + 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)); + + viewerStack = new PageBook(composite, SWT.NONE); + viewerStack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + defaultPage = createDefaultPage(viewerStack); + + contentComposite = new Composite(viewerStack, SWT.NONE); + GridLayout contantLayout = new GridLayout(); + contantLayout.marginWidth = 0; + contantLayout.marginHeight = 0; + contantLayout.verticalSpacing = 0; + contantLayout.horizontalSpacing = 0; + contentComposite.setLayout(contantLayout); + contentComposite + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + this.widgetFactory = new WidgetFactory(contentComposite.getDisplay()); + + form = widgetFactory.createScrolledForm(contentComposite); + form.setLayoutData(new GridData(GridData.FILL_BOTH)); + form.setMinWidth(DEFAULT_SECTION_WIDTH); + 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); + + viewerStack.showPage( + sourceEditor == null ? defaultPage : contentComposite); + + this.composite = composite; + + return composite; + } + + private Composite createDefaultPage(Composite parent) { + Composite page = new Composite(parent, SWT.NONE); + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = 0; + gridLayout.marginHeight = 0; + page.setLayout(gridLayout); + + Label label = new Label(page, SWT.LEFT | SWT.WRAP); + label.setText(MindMapMessages.PropertiesPart_DefaultPage_message); + label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return page; + } + + @SuppressWarnings("restriction") + protected boolean postConfiguration(IWorkbenchPart workbenchPart, + MPart part) { + super.postConfiguration(workbenchPart, part); + IWorkbenchPartSite site = workbenchPart.getSite(); + IGraphicalEditor editor = getContributedEditor(); + if (site instanceof IViewSite && editor != null) { + IActionBars sourceActionBars = editor.getEditorSite() + .getActionBars(); + IActionBars targetActionBars = ((IViewSite) site).getActionBars(); + if (sourceActionBars == null || targetActionBars == null) + return false; + + IServiceLocator serviceLocator = targetActionBars + .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)); + + retargetAction(sourceActionBars, targetActionBars, + ActionFactory.UNDO.getId()); + retargetAction(sourceActionBars, targetActionBars, + ActionFactory.REDO.getId()); + return true; + } + return false; + } + + private void retargetAction(IActionBars sourceActionBars, + IActionBars targetActionBars, String actionId) { + IAction handler = sourceActionBars.getGlobalActionHandler(actionId); + if (handler != null) { + targetActionBars.setGlobalActionHandler(actionId, handler); + } + } + + private void setEditor(IGraphicalEditor editor) { + if (this.sourceEditor == editor) + return; + + if (this.sourceEditor != null) + this.sourceEditor.getSite().getSelectionProvider() + .removeSelectionChangedListener(this); + + this.sourceEditor = editor; + + if (viewerStack != null && !viewerStack.isDisposed()) { + if (sourceEditor != null) { + if (contentComposite != null + && !contentComposite.isDisposed()) { + + initContent(); + viewerStack.showPage(contentComposite); + } + } else { + if (defaultPage != null && !defaultPage.isDisposed()) + viewerStack.showPage(defaultPage); + } + } + + } + + public IGraphicalEditor getContributedEditor() { + return sourceEditor; + } + + private void addSection(String id, IPropertySectionPart section) { + Assert.isNotNull(id); + Assert.isNotNull(section); + removeSection(id); + SectionRecord rec = new SectionRecord(id, section); + sections.add(rec); + section.init(this, sourceEditor); + if (form != null && !form.isDisposed()) { + createSectionControl(form.getBody(), rec); + } + } + + private void removeSection(String id) { + SectionRecord rec = getRec(id); + if (rec == null) + return; + + if (sections.remove(rec)) { + rec.section.dispose(); + if (rec.control != null && !rec.control.isDisposed()) { + rec.control.dispose(); + } + } + } + + private List getSectionIds() { + ArrayList list = new ArrayList(sections.size()); + for (SectionRecord rec : sections) { + list.add(rec.id); + } + return list; + } + + private List getVisibleSectionIds() { + ArrayList list = new ArrayList(sections.size()); + for (SectionRecord rec : sections) { + if (rec.visible) + list.add(rec.id); + } + return list; + } + + private void setSectionVisible(String id, boolean visible) { + SectionRecord 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); + } + } + + private void reflow() { + if (form != null && !form.isDisposed()) { + form.reflow(true); + form.getParent().layout(); + } + } + + private void moveSectionFirst(SectionRecord rec) { + if (rec.control != null && !rec.control.isDisposed()) { + rec.control.moveAbove(null); + rec.control.getParent().layout(); + } + } + + private void moveSectionAfter(String id, String lastId) { + SectionRecord rec = getRec(id); + if (rec == null) + return; + SectionRecord 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 SectionRecord getRec(String id) { + if (id == null) + return null; + + for (SectionRecord rec : sections) { + if (id.equals(rec.id)) + return rec; + } + return null; + } + + private void createExtendSectionControls(WidgetFactory widgetFactory, + Composite parent) { + createResetStyleControl(widgetFactory, parent); + } + + private void createResetStyleControl(WidgetFactory widgetFactory, + Composite parent) { + resetStyleControl = widgetFactory.createHyperlink(parent, + MindMapMessages.MindMapPropertySheetPage_ResetStyle_text, + SWT.NONE); + resetStyleControl.setUnderlined(false); + resetStyleControl.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, true, false)); + resetStyleControl.addHyperlinkListener(new IHyperlinkListener() { + + public void linkExited(HyperlinkEvent e) { + resetStyleControl.setUnderlined(false); + } + + public void linkEntered(HyperlinkEvent e) { + resetStyleControl.setUnderlined(true); + } + + public void linkActivated(HyperlinkEvent e) { + resetStyles(); + } + }); + + resetStyleControl.setFont((Font) resources.get( + JFaceResources.getDefaultFontDescriptor().increaseHeight(-1))); + resetStyleControl.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#0082F9"))); //$NON-NLS-1$ + } + + private boolean shouldHasResetStyleControl(ISelection selection) { + if (!(selection instanceof StructuredSelection)) + return false; + + boolean result = true; + + Object[] resetedStyleds = ((StructuredSelection) selection).toArray(); + if (resetedStyleds != null) { + for (Object styled : resetedStyleds) { + if (!(styled instanceof IStyled)) { + result = false; + } + } + } + return result; + } + + private void resetStyles() { + IGraphicalEditor editor = getContributedEditor(); + if (editor == null) + return; + + IGraphicalEditorPage activePageInstance = editor + .getActivePageInstance(); + if (activePageInstance == null) + return; + + ISelectionProvider selectionProvider = activePageInstance + .getSelectionProvider(); + if (selectionProvider == null) + return; + + ISelection selection = selectionProvider.getSelection(); + if (!(selection instanceof StructuredSelection)) + return; + + Object[] resetedStyleds = ((StructuredSelection) selection).toArray(); + if (resetedStyleds != null) { + for (Object styled : resetedStyleds) { + if (styled instanceof IStyled) { + IStyled resetedStyled = (IStyled) styled; + ModifyStyleCommand modifyStyleCommand = new ModifyStyleCommand( + resetedStyled, (String) null); + modifyStyleCommand + .setLabel(CommandMessages.Command_ModifyStyle); + editor.getCommandStack().execute(modifyStyleCommand); + } + } + } + } + + private void createSectionControls(final ScrolledForm form, + final Composite formBody) { + GridLayout layout = new GridLayout(1, true); + formBody.setLayout(layout); + for (SectionRecord 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, SectionRecord 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) { + SectionRecord rec = findRecord(section); + if (rec != null) { + updateSectionTitle(rec); + } + } + + private SectionRecord findRecord(IPropertySectionPart section) { + for (SectionRecord rec : sections) { + if (rec.section == section) + return rec; + } + return null; + } + + private void updateSectionTitle(SectionRecord 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 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); + } + + private void selectionChanged(ISelection selection) { + if (getControl() != null && !getControl().isDisposed()) + getControl().setRedraw(false); + + if (resetStyleControl != null && !resetStyleControl.isDisposed()) { + boolean resetStyleControlVisible = shouldHasResetStyleControl( + selection); + GridData gd = (GridData) resetStyleControl.getLayoutData(); + gd.exclude = !resetStyleControlVisible; + resetStyleControl.setVisible(resetStyleControlVisible); + } + + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + List newVisibleSectionIds = manager + .getApplicableSectionIds(ss.toArray()); + List oldVisibleSectionIds = getVisibleSectionIds(); + if (!equalsList(oldVisibleSectionIds, newVisibleSectionIds)) { + List oldSectionIds = getSectionIds(); + List toAdd = new ArrayList( + newVisibleSectionIds); + toAdd.removeAll(oldSectionIds); + for (String id : toAdd) { + addSection(id, newVisibleSectionIds, oldSectionIds); + oldSectionIds = getSectionIds(); + } + + List toHide = new ArrayList(oldSectionIds); + toHide.removeAll(newVisibleSectionIds); + for (String id : oldSectionIds) { + setSectionVisible(id, !toHide.contains(id)); + } + + reflow(); + } + ti.setText(calcTitle(ss.toArray()) + " " + modeLabel); //$NON-NLS-1$ + } else { + ti.setText(modeLabel); + } + if (getControl() != null && !getControl().isDisposed()) + getControl().setRedraw(true); + } + + private void addSection(String id, List newVisibleSectionIds, + List oldSectionIds) { + addSection(id, manager.createSection(id)); + String aboveId = findAboveId(id, oldSectionIds, newVisibleSectionIds); + moveSectionAfter(id, aboveId); + } + + private String findAboveId(String id, List oldSectionIds, + List newSectionIds) { + int index = newSectionIds.indexOf(id); + for (int i = index - 1; i >= 0; i--) { + String aboveId = newSectionIds.get(i); + if (oldSectionIds.contains(aboveId)) + return aboveId; + } + return null; + } + + private static boolean equalsList(List list1, List list2) { + if (list1.size() != list2.size()) + return false; + for (int i = 0; i < list1.size(); i++) { + String s1 = list1.get(i); + String s2 = list2.get(i); + if (!s1.equals(s2)) + return false; + } + return true; + } + + private String calcTitle(Object[] objects) { + if (objects == null || objects.length == 0) + return null; + String category = getCategoryName(objects); + return category; + } + + private String getCategoryName(Object[] objects) { + ICategoryManager typeManager = MindMapUI.getCategoryManager(); + ICategoryAnalyzation result = typeManager.analyze(objects); + return typeManager.getCategoryName(result.getMainCategory()); + } + + private void setSelectionToSections(ISelection selection) { + for (SectionRecord rec : sections) { + if (rec.visible) { + rec.section.setSelection(selection); + updateSectionTitle(rec); + } + } + } + + public String getTitle() { + return title; + } + + public void refresh() { + for (SectionRecord rec : sections) { + if (rec.visible) { + rec.section.refresh(); + } + } + if (form != null && !form.isDisposed()) { + form.reflow(true); + } + } + + public void dispose() { + if (sourceEditor != null) { + sourceEditor.getSite().getSelectionProvider() + .removeSelectionChangedListener(this); + } + + for (SectionRecord rec : sections) { + rec.section.dispose(); + rec.visible = false; + rec.control = null; + } + if (composite != null) { + composite.dispose(); + composite = null; + } + form = null; + title = null; + super.dispose(); + } + + @Override + protected void handlePartActivated(MPart part) { + + super.handlePartActivated(part); + Object partObject = part.getObject(); + if (partObject instanceof CompatibilityPart) { + IWorkbenchPart editorPart = ((CompatibilityPart) partObject) + .getPart(); + if (editorPart instanceof IGraphicalEditor) { + setEditor((IGraphicalEditor) editorPart); + } + + MPart partModel = getAdapter(MPart.class); + Object wp = partModel.getTransientData() + .get(E4PartWrapper.E4_WRAPPER_KEY); + if (wp instanceof E4PartWrapper) { + postConfiguration((IWorkbenchPart) wp, partModel); + } + } else if (sourceEditor == null) { + IWorkbenchWindow window = getAdapter(IWorkbenchWindow.class); + IEditorPart editorPart = window.getActivePage().getActiveEditor(); + if (editorPart instanceof IGraphicalEditor) { + setEditor((IGraphicalEditor) editorPart); + } + } + } + + public IPageSite getContainerSite() { + return null; + } + + public IWorkbenchPart getContributingPart() { + return sourceEditor; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/PropertyMessages.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/PropertyMessages.java index c2bf48398..e89614d9f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/PropertyMessages.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/PropertyMessages.java @@ -52,6 +52,7 @@ public class PropertyMessages extends NLS { public static String Prefix_toolTip; public static String Suffix_toolTip; public static String Separator_label; + public static String Depth_label; public static String RelationshipShape_toolTip; public static String BeginArrowShape_toolTip; public static String EndArrowShape_toolTip; diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/SheetAdvancedStylePropertySectionPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/SheetAdvancedStylePropertySectionPart.java index 8812f3da4..80862d32e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/SheetAdvancedStylePropertySectionPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/SheetAdvancedStylePropertySectionPart.java @@ -39,6 +39,8 @@ protected void createContent(Composite parent) { taperedLinesCheck.setText(PropertyMessages.TaperedLines_text); taperedLinesCheck.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ToggleTaperedlineCount"); //$NON-NLS-1$ changeTaperedLines(); } @@ -51,6 +53,8 @@ public void widgetDefaultSelected(SelectionEvent e) { .setText(PrefMessages.EditorPage_UndoRedo_gradientColor); gradientColorCheck.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ToggleGradientColorCount"); //$NON-NLS-1$ changeGradientColor(); } @@ -60,7 +64,8 @@ public void widgetDefaultSelected(SelectionEvent e) { } protected void changeGradientColor() { - Request request = createStyleRequest(CommandMessages.Command_ToggleGradientColor); + Request request = createStyleRequest( + CommandMessages.Command_ToggleGradientColor); if (gradientColorCheck.getSelection()) { addStyle(request, Styles.GradientColor, Styles.GRADIENT); } else { @@ -70,7 +75,8 @@ protected void changeGradientColor() { } private void changeTaperedLines() { - Request request = createStyleRequest(CommandMessages.Command_ToggleTaperedLines); + Request request = createStyleRequest( + CommandMessages.Command_ToggleTaperedLines); if (taperedLinesCheck.getSelection()) { addStyle(request, Styles.LineTapered, Styles.TAPERED); } else { @@ -83,8 +89,8 @@ protected void doRefresh() { if (taperedLinesCheck != null && !taperedLinesCheck.isDisposed()) { String value = getStyleValue(Styles.LineTapered, null); - taperedLinesCheck.setSelection(value != null - && !Styles.NONE.equals(value)); + taperedLinesCheck + .setSelection(value != null && !Styles.NONE.equals(value)); } if (gradientColorCheck != null && !gradientColorCheck.isDisposed()) { boolean hasGradient = MindMapUIPlugin.getDefault() @@ -109,4 +115,4 @@ public void setFocus() { taperedLinesCheck.setFocus(); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/SheetMultiBranchColorsStylePropertySectionPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/SheetMultiBranchColorsStylePropertySectionPart.java index 53fef95c3..1b1e4020a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/SheetMultiBranchColorsStylePropertySectionPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/SheetMultiBranchColorsStylePropertySectionPart.java @@ -26,6 +26,7 @@ import org.eclipse.swt.widgets.Display; import org.xmind.gef.Request; import org.xmind.ui.commands.CommandMessages; +import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.properties.StyledPropertySectionPart; import org.xmind.ui.style.Styles; import org.xmind.ui.viewers.ImageCachedLabelProvider; @@ -178,6 +179,8 @@ protected void createContent(Composite parent) { multiLineColorsCheck.setText("Multi Branch Color"); //$NON-NLS-1$ multiLineColorsCheck.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ToggleMultiColorCount"); //$NON-NLS-1$ multiLineColorsSelectionViewer.setEnabled( !multiLineColorsSelectionViewer.isEnabled()); if (multiLineColorsSelectionViewer.isEnabled()) { diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/StructurePropertySectionPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/StructurePropertySectionPart.java index 473bfc001..da83f280b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/StructurePropertySectionPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/StructurePropertySectionPart.java @@ -39,12 +39,13 @@ import org.xmind.ui.mindmap.IBranchPart; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.properties.MindMapPropertySectionPartBase; +import org.xmind.ui.resources.ImageDescriptorProvider; import org.xmind.ui.util.MindMapUtils; import org.xmind.ui.viewers.ImageCachedLabelProvider; import org.xmind.ui.viewers.MComboViewer; -public class StructurePropertySectionPart extends - MindMapPropertySectionPartBase { +public class StructurePropertySectionPart + extends MindMapPropertySectionPartBase { private static final List NO_BRANCH_POLICY = Collections .emptyList(); @@ -52,7 +53,7 @@ public class StructurePropertySectionPart extends private static final String FOLLOW = "org.xmind.ui.properties.structure.follow"; //$NON-NLS-1$ private static class BranchPolicyLabelProvider extends - ImageCachedLabelProvider { + ImageCachedLabelProvider implements ImageDescriptorProvider { protected Image createImage(Object element) { if (element instanceof IBranchPolicyDescriptor) { @@ -64,6 +65,15 @@ protected Image createImage(Object element) { return null; } + @Override + public ImageDescriptor getImageDescriptor(Object element) { + if (element instanceof IBranchPolicyDescriptor) { + IBranchPolicyDescriptor desc = (IBranchPolicyDescriptor) element; + return desc.getIcon(); + } + return null; + } + public String getText(Object element) { if (element instanceof IBranchPolicyDescriptor) { IBranchPolicyDescriptor desc = (IBranchPolicyDescriptor) element; @@ -77,8 +87,8 @@ public String getText(Object element) { } } - private class BranchPolicySelectionChangedListener implements - ISelectionChangedListener { + private class BranchPolicySelectionChangedListener + implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { if (isRefreshing()) @@ -108,12 +118,12 @@ protected void createContent(Composite parent) { structureViewer = new MComboViewer(parent, SWT.NONE); structureViewer.getControl().setLayoutData( new GridData(GridData.FILL, GridData.FILL, true, false)); - structureViewer.getControl().setToolTipText( - PropertyMessages.Structure_toolTip); + structureViewer.getControl() + .setToolTipText(PropertyMessages.Structure_toolTip); structureViewer.setContentProvider(new ArrayContentProvider()); structureViewer.setLabelProvider(new BranchPolicyLabelProvider()); - structureViewer - .addSelectionChangedListener(new BranchPolicySelectionChangedListener()); + structureViewer.addSelectionChangedListener( + new BranchPolicySelectionChangedListener()); } public void setFocus() { @@ -225,8 +235,8 @@ private ISelection getCurrentStructure() { } if (branchPolicyId != null) { IBranchPolicyDescriptor descriptor = MindMapUI - .getBranchPolicyManager().getBranchPolicyDescriptor( - branchPolicyId); + .getBranchPolicyManager() + .getBranchPolicyDescriptor(branchPolicyId); if (descriptor != null) { return new StructuredSelection(descriptor); } @@ -241,8 +251,8 @@ private boolean getCurrentFollowParentStructure() { for (Object o : getSelectedElements()) { if (!(o instanceof ITopic)) return false; - IBranchPart branch = MindMapUtils.findBranch(getGraphicalPart(o, - viewer)); + IBranchPart branch = MindMapUtils + .findBranch(getGraphicalPart(o, viewer)); if (branch == null || !isFollowParentStructure(branch)) return false; } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/WallpaperPropertySectionPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/WallpaperPropertySectionPart.java index 5c653443a..2bc230970 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/WallpaperPropertySectionPart.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/WallpaperPropertySectionPart.java @@ -67,8 +67,8 @@ public String getText(Object element) { } } - private class OpacitySelectionChangedListener implements - ISelectionChangedListener { + private class OpacitySelectionChangedListener + implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { int value = getOpacityValueFromScaleSelection(event.getSelection()); @@ -80,8 +80,8 @@ public void selectionChanged(SelectionChangedEvent event) { } - private class OpacityPostSelectionChangedListener implements - ISelectionChangedListener { + private class OpacityPostSelectionChangedListener + implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { int value = getOpacityValueFromScaleSelection(event.getSelection()); @@ -97,10 +97,10 @@ private class RemoveWallpaperAction extends Action { public RemoveWallpaperAction() { super(null, AS_PUSH_BUTTON); - setImageDescriptor(MindMapUI.getImages().get(IMindMapImages.REMOVE, - true)); - setDisabledImageDescriptor(MindMapUI.getImages().get( - IMindMapImages.REMOVE, false)); + setImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.REMOVE, true)); + setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.REMOVE, false)); setToolTipText(PropertyMessages.RemoveWallpaper_toolTip); }; @@ -127,8 +127,8 @@ public void run() { protected void createContent(Composite parent) { Composite line1 = new Composite(parent, SWT.NONE); - line1.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, - false)); + line1.setLayoutData( + new GridData(GridData.FILL, GridData.FILL, true, false)); GridLayout layout1 = new GridLayout(2, false); layout1.marginWidth = 0; layout1.marginHeight = 0; @@ -137,8 +137,8 @@ protected void createContent(Composite parent) { createLineContent1(line1); opacityGroup = new Composite(parent, SWT.NONE); - opacityGroup.setLayoutData(new GridData(GridData.FILL, GridData.FILL, - true, false)); + opacityGroup.setLayoutData( + new GridData(GridData.FILL, GridData.FILL, true, false)); GridLayout layout2 = new GridLayout(4, false); layout2.marginWidth = 0; layout2.marginHeight = 0; @@ -159,8 +159,8 @@ private void createLineContent1(Composite parent) { new GridData(GridData.FILL, GridData.FILL, true, false)); selectWallpaperWidget.setImage(getSelectWallpaperImage()); selectWallpaperWidget.setText(PropertyMessages.SelectWallpaper_text); - selectWallpaperWidget.getControl().setToolTipText( - PropertyMessages.SelectWallpaper_toolTip); + selectWallpaperWidget.getControl() + .setToolTipText(PropertyMessages.SelectWallpaper_toolTip); selectWallpaperWidget.addOpenListener(new IOpenListener() { public void open(OpenEvent event) { openSelectWallpaperDialog(); @@ -183,8 +183,8 @@ private void createLineContent2(Composite parent) { opacityInput = new Text(parent, SWT.BORDER | SWT.SINGLE | SWT.TRAIL); SWTUtils.makeNumeralInput(opacityLabel, false, false); - GridData inputData = new GridData(GridData.FILL, GridData.CENTER, - false, false); + GridData inputData = new GridData(GridData.FILL, GridData.CENTER, false, + false); inputData.widthHint = 25; opacityInput.setLayoutData(inputData); opacityInput.setTextLimit(3); @@ -212,18 +212,18 @@ public void handleEvent(Event event) { Label percentageLabel = new Label(parent, SWT.NONE); percentageLabel.setText("%"); //$NON-NLS-1$ - percentageLabel.setLayoutData(new GridData(GridData.FILL, - GridData.CENTER, false, false)); + percentageLabel.setLayoutData( + new GridData(GridData.FILL, GridData.CENTER, false, false)); opacityScale = new SliderViewer(parent, SWT.HORIZONTAL); opacityScale.setLabelProvider(new OpacityLabelProvider()); opacityScale.getControl().setLayoutData( new GridData(GridData.FILL, GridData.CENTER, true, false)); opacityScale.getControl().setBackground(parent.getBackground()); - opacityScale - .addSelectionChangedListener(new OpacitySelectionChangedListener()); - opacityScale - .addPostSelectionChangedListener(new OpacityPostSelectionChangedListener()); + opacityScale.addSelectionChangedListener( + new OpacitySelectionChangedListener()); + opacityScale.addPostSelectionChangedListener( + new OpacityPostSelectionChangedListener()); } private void selectAllOpacityText(final boolean takeFocus) { @@ -265,8 +265,8 @@ private int getOpacityValueFromScaleElement(Object o) { private Image getSelectWallpaperImage() { if (selectWallpaperImage == null || selectWallpaperImage.isDisposed()) { - ImageDescriptor icon = MindMapUI.getImages().get( - IMindMapImages.INSERT_IMAGE, true); + ImageDescriptor icon = MindMapUI.getImages() + .get(IMindMapImages.INSERT_IMAGE, true); if (icon != null) { selectWallpaperImage = icon.createImage(false); } @@ -276,8 +276,8 @@ private Image getSelectWallpaperImage() { private Image getOpacityImage() { if (opacityImage == null) { - ImageDescriptor icon = MindMapUI.getImages().get( - IMindMapImages.OPAQUE); + ImageDescriptor icon = MindMapUI.getImages() + .get(IMindMapImages.OPAQUE); if (icon != null) { opacityImage = icon.createImage(false); } @@ -328,12 +328,12 @@ private void updateOpacityToWidget() { double doubleValue = parseOpacityValue(value); doubleValue = Math.max(0, Math.min(1, doubleValue)); if (opacityInput != null && !opacityInput.isDisposed()) { - opacityInput.setText(String.valueOf((int) Math - .round(doubleValue * 100))); + opacityInput.setText( + String.valueOf((int) Math.round(doubleValue * 100))); } if (opacityScale != null && !opacityScale.getControl().isDisposed()) { - opacityScale.setSelection(new StructuredSelection(Double - .valueOf(doubleValue))); + opacityScale.setSelection( + new StructuredSelection(Double.valueOf(doubleValue))); } } @@ -376,13 +376,15 @@ public void handleEvent(Event event) { } private void removeWallpaper() { - Request request = createStyleRequest(CommandMessages.Command_ModifyWallpaper); + Request request = createStyleRequest( + CommandMessages.Command_ModifyWallpaper); addStyle(request, Styles.Background, ""); //$NON-NLS-1$ sendRequest(request); } private void changeOpacity(int opacityValue) { - Request request = createStyleRequest(CommandMessages.Command_ModifyWallpaperOpacity); + Request request = createStyleRequest( + CommandMessages.Command_ModifyWallpaperOpacity); String value = String.valueOf((double) opacityValue * 1.0 / 100); addStyle(request, Styles.Opacity, value); sendRequest(request); @@ -399,4 +401,4 @@ private void previewOpacity(int value) { } } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/messages.properties b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/messages.properties index f0521e960..1845c1192 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/messages.properties +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/properties/messages.properties @@ -33,6 +33,7 @@ PrependNumbering_toolTip=Tiered numbers (2, 2.1, 2.1.1...) Prefix_toolTip=Enter the prefix of this level's numbering Suffix_toolTip=Enter the suffix of this level's numbering Separator_label=Separator: +Depth_label=Depth: RelationshipShape_toolTip=Select the shape of this relationship BeginArrowShape_toolTip=Select the shape of this relationship's beginning arrow EndArrowShape_toolTip=Select the shape of this relationship's ending arrow diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/AttachmentProtocol.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/AttachmentProtocol.java index 155ab7352..d83160758 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/AttachmentProtocol.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/AttachmentProtocol.java @@ -14,6 +14,7 @@ package org.xmind.ui.internal.protocols; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -26,6 +27,8 @@ import org.eclipse.jface.action.IAction; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IWindowListener; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; @@ -59,6 +62,8 @@ private static class AttachmentAction extends Action { private String fileName; + private IWindowListener windowListener; + public AttachmentAction(IWorkbenchWindow window, IWorkbook workbook, String path, String fileName) { this.window = window; @@ -104,6 +109,71 @@ public void run() { ((ICoreEventSource2) workbook).registerOnceCoreEventListener( Core.WorkbookPreSaveOnce, ICoreEventListener.NULL); } + + //write temp file back to entry. + if (window != null) { + window.getWorkbench().addWindowListener( + getWindowListener(fileEntry, hiberFile)); + } + + window.getActivePage().addPartListener(new IPartListener() { + + @Override + public void partOpened(IWorkbenchPart part) { + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + } + + @Override + public void partClosed(IWorkbenchPart part) { + window.getWorkbench().removeWindowListener( + getWindowListener(null, null)); + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + } + + @Override + public void partActivated(IWorkbenchPart part) { + } + }); + } + + private IWindowListener getWindowListener(final IFileEntry fileEntry, + final File hiberFile) { + 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) { + try { + InputStream is = new FileInputStream(hiberFile); + OutputStream os = fileEntry.openOutputStream(); + FileUtils.transfer(is, os); + } catch (IOException e) { + Logger.log(e, + "Failed to transfer temp-attachments to attachment dir."); //$NON-NLS-1$ + return; + } + } + }; + } + return windowListener; } } @@ -205,4 +275,4 @@ public boolean isHyperlinkModifiable(Object source, String uri) { return false; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/FilePathParser.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/FilePathParser.java index b683e0841..ff0dd5ded 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/FilePathParser.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/FilePathParser.java @@ -20,7 +20,6 @@ import java.util.Map; /** - * * @author Karelun Huang */ public class FilePathParser { @@ -209,10 +208,9 @@ public static String toAbsolutePath(String base, String relativePath) { } /* - * ECMA 3, 15.1.3 URI Handling Function Properties - * - * The following are implementations of the algorithms given in the ECMA - * specification for the hidden functions 'Encode' and 'Decode'. + * ECMA 3, 15.1.3 URI Handling Function Properties The following are + * implementations of the algorithms given in the ECMA specification for the + * hidden functions 'Encode' and 'Decode'. */ private static String encode(String str, boolean fullUri) { byte[] utf8buf = null; @@ -502,6 +500,8 @@ public static void calculateFileURILabels(URI[] inputURIs, List paths = new ArrayList(); for (int i = 0; i < inputURIs.length; i++) { URI uri = inputURIs[i]; + if (uri == null) + continue; String uriValue = uri.toString(); if (FilePathParser.isFileURI(uriValue)) { String path = FilePathParser.toPath(uriValue); diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/WebProtocol.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/WebProtocol.java new file mode 100644 index 000000000..231083ee2 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/protocols/WebProtocol.java @@ -0,0 +1,316 @@ +package org.xmind.ui.internal.protocols; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; + +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.xmind.core.Core; +import org.xmind.core.IAdaptable; +import org.xmind.core.ITopic; +import org.xmind.core.event.ICoreEventSource; +import org.xmind.core.util.FileUtils; +import org.xmind.gef.image.ImageExportUtils; +import org.xmind.ui.browser.BrowserSupport; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.browser.BrowserUtil; +import org.xmind.ui.io.WebImageManager; +import org.xmind.ui.io.WebImageManager.WebImageCallback; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.IProtocol; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ImageUtils; +import org.xmind.ui.util.MindMapUtils; + +public class WebProtocol implements IProtocol { + + private static interface Callback { + + void handleWith(ImageDescriptor icon); + } + + public static final String WEB_ICON_EVENT_TYPE = "webIcon"; //$NON-NLS-1$ + + private static String DEFAULT_BROWSER_ID = "org.xmind.ui.defaultProtocol.browser"; //$NON-NLS-1$ + + private static final String PATH_FAVICONS = "favicons/"; //$NON-NLS-1$ + + private static class OpenURLAction extends Action { + + private String url; + + public OpenURLAction(String url) { + super(MindMapMessages.OpenHyperlink_text, + MindMapUI.getImages().get(IMindMapImages.HYPERLINK, true)); + this.url = url; + setDisabledImageDescriptor( + MindMapUI.getImages().get(IMindMapImages.HYPERLINK, false)); + setToolTipText(url); + } + + public void run() { + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + String theURL = url; + try { + URI uri = new URI(theURL); + if ("www.xmind.net".equals(uri.getHost())) { //$NON-NLS-1$ + theURL = BrowserUtil.makeRedirectURL(theURL); + } + } catch (Exception ignored) { + } + BrowserSupport.getInstance() + .createBrowser(DEFAULT_BROWSER_ID).openURL(theURL); + } + }); + } + } + + public IAction createOpenHyperlinkAction(final Object context, + final String url) { + final IAction action = new OpenURLAction(url); + ImageDescriptor image = getWebIcon(url, new Callback() { + + public void handleWith(final ImageDescriptor icon) { + if (icon == null) { + return; + } + + Display.getDefault().asyncExec(new Runnable() { + + public void run() { + ImageDescriptor oldImage = action.getImageDescriptor(); + action.setImageDescriptor(icon); + + ITopic topic = null; + if (context instanceof ITopic) { + topic = (ITopic) context; + } else if (context instanceof IAdaptable) { + topic = (ITopic) ((IAdaptable) context) + .getAdapter(ITopic.class); + } + + if (topic != null) { + ICoreEventSource source = topic + .getAdapter(ICoreEventSource.class); + if (source != null) { + source.getCoreEventSupport() + .dispatchValueChange(source, + WebProtocol.WEB_ICON_EVENT_TYPE, + oldImage, icon); + } + } + } + }); + } + }); + + if (image != null) { + action.setImageDescriptor(image); + } + + return action; + } + + private ImageDescriptor getWebIcon(String url, final Callback callback) { + final String iconUrl = getWebIconUrl(url); + if (iconUrl == null) { + return null; + } + + final String key = "org.xmind.ui.webIcon(" + iconUrl + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + ImageDescriptor image = ImageUtils.getDescriptor(key); + + if (image != null) { + return image; + } + + image = getFaviconFromFile(iconUrl); + if (image != null) { + ImageUtils.putImageDescriptor(key, image); + return image; + } + + WebImageManager.getInstance().requestWebImage(iconUrl, + new WebImageCallback() { + + public void handleWith(String imagePath) { + if (imagePath == null + || !new File(imagePath).exists()) { + return; + } + + String newPath = saveFaviconToFile(iconUrl, imagePath); + if (newPath == null || !new File(newPath).exists()) { + return; + } + + ImageDescriptor image = null; + try { + image = ImageDescriptor.createFromURL( + new File(newPath).toURI().toURL()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + if (image == null) { + return; + } + ImageUtils.putImageDescriptor(key, image); + + if (callback != null) { + callback.handleWith(image); + } + } + }); + + return null; + } + + private String getWebIconUrl(String url) { + if (url == null) { + return null; + } + + int domainEnd = -1; + if (url.contains("://")) { //$NON-NLS-1$ + int start = url.indexOf("://") + "://".length(); //$NON-NLS-1$ //$NON-NLS-2$ + domainEnd = url.indexOf("/", start); //$NON-NLS-1$ + } else { + domainEnd = url.indexOf("/"); //$NON-NLS-1$ + } + String domain = url.substring(0, + domainEnd == -1 ? url.length() : domainEnd); + + return domain + "/favicon.ico"; //$NON-NLS-1$ + } + + private ImageDescriptor getFaviconFromFile(String key) { + String fileName = getFileName(key); + String path = Core.getWorkspace() + .getAbsolutePath(PATH_FAVICONS + fileName); + if (path == null) { + return null; + } + + File file = new File(path); + if (file.exists()) { + long lastModified = file.lastModified(); + long currentTime = System.currentTimeMillis(); + //the validity of image file is 30 days. + if ((currentTime - lastModified) / (24 * 3600 * 1000) > 30) { + file.delete(); + } else { + try { + return ImageDescriptor + .createFromURL(new File(path).toURI().toURL()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + } + + return null; + } + + private String saveFaviconToFile(String key, String tempImagePath) { + if (tempImagePath == null) { + return null; + } + + String fileName = getFileName(key); + String path = Core.getWorkspace() + .getAbsolutePath(PATH_FAVICONS + fileName); + if (path == null) { + return null; + } + + File file = new File(path); + if (file.exists()) { + return path; + } + + Image image = null; + try { + image = new Image(Display.getCurrent(), tempImagePath); + } catch (Exception e) { + return null; + } + Image image1x = ImageUtils.createScaledImage(image, 16, 16); + Image image2x = ImageUtils.createScaledImage(image, 32, 32); + + FileUtils.ensureFileParent(file); + FileOutputStream outputStream = null; + FileOutputStream outputStream2x = null; + + try { + //get @1x + File file1x = new File(path); + file1x.createNewFile(); + outputStream = new FileOutputStream(file1x); + ImageExportUtils.saveImage(image1x, outputStream, SWT.IMAGE_PNG); + + //get @2x + String path2x = Core.getWorkspace() + .getAbsolutePath(PATH_FAVICONS + get2xFileName(key)); + File file2x = new File(path2x); + file2x.createNewFile(); + outputStream2x = new FileOutputStream(file2x); + ImageExportUtils.saveImage(image2x, outputStream2x, SWT.IMAGE_PNG); + + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + outputStream.close(); + outputStream2x.close(); + } catch (IOException e) { + e.printStackTrace(); + } + new File(tempImagePath).delete(); + image.dispose(); + image1x.dispose(); + image2x.dispose(); + } + + return path; + } + + private String getFileName(String key) { + if (key == null) { + return null; + } + + key = key.substring(0, key.lastIndexOf(".ico")); //$NON-NLS-1$ + key = key.replace("://", "-"); //$NON-NLS-1$ //$NON-NLS-2$ + key = key.replace(".", "-"); //$NON-NLS-1$ //$NON-NLS-2$ + key = key.replace("/", "-"); //$NON-NLS-1$ //$NON-NLS-2$ + key += ".png"; //$NON-NLS-1$ + key = MindMapUtils.trimFileName(key); + + return key; + } + + private String get2xFileName(String key) { + String fileName = getFileName(key); + if (fileName != null) { + fileName = fileName.substring(0, fileName.length() - 4) + "@2x" //$NON-NLS-1$ + + fileName.substring(fileName.length() - 4); + } + + return fileName; + } + + public boolean isHyperlinkModifiable(Object source, String uri) { + return true; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/IResourceManagerDialogPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/IResourceManagerDialogPage.java new file mode 100644 index 000000000..1d2192c36 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/IResourceManagerDialogPage.java @@ -0,0 +1,31 @@ +package org.xmind.ui.internal.resourcemanager; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.xmind.core.IAdaptable; + +public interface IResourceManagerDialogPage extends IAdaptable { + + public Image getImage(); + + public String getTitle(); + + public String getId(); + + public Control getControl(); + + public void setImageDescriptor(ImageDescriptor image); + + public void setTitle(String title); + + public void setId(String id); + + public void createControl(Composite parent); + + public void dispose(); + + public void refresh(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/MarkerResourceManagerPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/MarkerResourceManagerPage.java new file mode 100644 index 000000000..427b86e2d --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/MarkerResourceManagerPage.java @@ -0,0 +1,237 @@ +package org.xmind.ui.internal.resourcemanager; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +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.ICoreEventSupport; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.e4models.IContextRunnable; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.ResourceUtils; +import org.xmind.ui.mindmap.MindMapUI; + +public class MarkerResourceManagerPage extends ResourceManagerDialogPage + implements ICoreEventListener { + + private final static int ADD_GROUP_BUTTON_ID = IDialogConstants.CLIENT_ID + + 1; + private CoreEventRegister coreEventRegister; + private MarkerResourceManagerViewer viewer; + + static final String USER_MARKER_PATH = "markers/markerSheet.xml"; //$NON-NLS-1$ + + private static final String USER_GROUP_PREFIX = "User Group "; //$NON-NLS-1$ + + @Override + protected ResourceManagerViewer createViewer() { + viewer = new MarkerResourceManagerViewer(); + registerCoreEvent(); + return viewer; + } + + private void registerCoreEvent() { + ICoreEventSupport ces = (ICoreEventSupport) MindMapUI + .getResourceManager().getUserMarkerSheet() + .getAdapter(ICoreEventSupport.class); + if (ces != null) { + coreEventRegister = new CoreEventRegister(this); + coreEventRegister.setNextSupport(ces); + coreEventRegister.register(Core.MarkerAdd); + coreEventRegister.register(Core.MarkerGroupAdd); + coreEventRegister.register(Core.MarkerRefAdd); + coreEventRegister.register(Core.TitleText); + coreEventRegister.register(Core.MarkerRemove); + coreEventRegister.register(Core.MarkerGroupRemove); + coreEventRegister.register(Core.MarkerRefRemove); + coreEventRegister.register(Core.Name); + } + } + + @Override + protected void createButtonsForButtonBar(Composite buttonBar) { + Button button = createButton(buttonBar, ADD_GROUP_BUTTON_ID, + "Add Group", false); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("UserMarkerCount"); //$NON-NLS-1$ + IMarkerSheet markerSheet = MindMapUI.getResourceManager() + .getUserMarkerSheet(); + int groupNo = getNewGroupNo(markerSheet); + IMarkerGroup group = MindMapUI.getResourceManager() + .getUserMarkerSheet().createMarkerGroup(true); + group.setName(USER_GROUP_PREFIX + groupNo); + markerSheet.addMarkerGroup(group); + try { + MindMapUI.getResourceManager().saveUserMarkerSheet(); + } catch (Exception ex) { + // TODO: handle exception + ; + } + viewer.updateInput(); + viewer.activateGroup(group); + viewer.reveal(group); + viewer.renameMarkerGroup(); + } + }); + + } + + @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() { + viewer.refresh(); + viewer.setSelection(new StructuredSelection(event.getSource()), + true); + } + }); + } + + @Override + public void dispose() { + if (coreEventRegister != null) + coreEventRegister.unregisterAll(); + super.dispose(); + } + + @Override + protected void registerRunnable(IEclipseContext eclipseContext) { + super.registerRunnable(eclipseContext); + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_DELETE, //$NON-NLS-1$ + new IContextRunnable() { + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + if (viewer.canEditMarkerGroup()) { + viewer.deleteMarkerGroup(); + } + + List markers = getSelectedMarker(); + if (!markers.isEmpty()) { + ResourceUtils.deleteMarkers(markers); + } + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + if (viewer.canEditMarkerGroup()) + return true; + } + List markers = getSelectedMarker(); + boolean canExecute = !markers.isEmpty(); + IMarkerSheet userMarkerSheet = MindMapUI + .getResourceManager().getUserMarkerSheet(); + for (IMarker marker : markers) { + canExecute = canExecute && userMarkerSheet + .getMarker(marker.getId()) != null; + } + return canExecute; + } + }); + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_RENAME, //$NON-NLS-1$ + new IContextRunnable() { + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + viewer.renameMarkerGroup(); + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + return viewer.canEditMarkerGroup(); + } + return false; + } + }); + } + + private List getSelectedMarker() { + List markers = 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()) { + markers.add((IMarker) element); + } + } + } + return markers; + } + + @Override + protected String getContextMenuId() { + return IModelConstants.POPUPMENU_ID_RESOURCEMANAGER_MARKER; + } + + @Override + public String getModelPageId() { + return IModelConstants.PAGE_ID_RESOURCE_MANAGER_MARKER; + } + + @Override + public String getModelPageTitle() { + return null; + } + + private int getNewGroupNo(IMarkerSheet sheet) { + List markerGroups = sheet.getMarkerGroups(); + int i = 0; + for (IMarkerGroup group : markerGroups) { + String groupName = group.getName(); + if (groupName.startsWith(USER_GROUP_PREFIX)) { + try { + Integer toCompare = Integer.valueOf(groupName + .substring(groupName.lastIndexOf(' ') + 1)); + if (toCompare > i) { + i = toCompare; + } + } catch (Exception e) { + ;//nothing + } + } + } + + return i + 1; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/MarkerResourceManagerViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/MarkerResourceManagerViewer.java new file mode 100644 index 000000000..cc4d22276 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/MarkerResourceManagerViewer.java @@ -0,0 +1,458 @@ +package org.xmind.ui.internal.resourcemanager; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.ITextViewer; +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.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.MenuDetectEvent; +import org.eclipse.swt.events.MenuDetectListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.RGB; +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.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.ui.forms.widgets.ExpandableComposite; +import org.eclipse.ui.forms.widgets.Section; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.FramePart; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.utils.ResourceUtils; +import org.xmind.ui.mindmap.IResourceManager; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.texteditor.FloatingTextEditor; +import org.xmind.ui.texteditor.IFloatingTextEditorListener; +import org.xmind.ui.texteditor.TextEvent; +import org.xmind.ui.util.MarkerImageDescriptor; +import org.xmind.ui.viewers.IToolTipProvider; + +public class MarkerResourceManagerViewer extends ResourceManagerViewer { + + private static final int FRAME_HEIGHT = 32; + + private static final int FRAME_WIDTH = 32; + + private static final int RENAME_COMPOSITE_HEIGHT = 20; + + private static final int RENAME_COMPOSITE_WIDTH = 80; + + private FloatingTextEditor lastEditor; + + private static class MarkerCategorizedContentProvider + implements ITreeContentProvider { + + public void dispose() { + + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + + } + + @SuppressWarnings("unchecked") + public Object[] getElements(Object inputElement) { + if (inputElement instanceof List) + return ((List) inputElement).toArray(); + else + return null; + } + + @SuppressWarnings("unchecked") + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof List) + return ((List) parentElement).toArray(); + else if (parentElement instanceof IMarkerGroup) { + List markers = new ArrayList(); + for (IMarker marker : ((IMarkerGroup) parentElement) + .getMarkers()) + if (!marker.isHidden()) + markers.add(marker); + return markers.toArray(); + } else + return null; + } + + public Object getParent(Object element) { + if (element instanceof IMarker) { + IMarker marker = (IMarker) element; + return marker.getParent(); + } + return null; + } + + public boolean hasChildren(Object element) { + return element instanceof IMarkerGroup + || element instanceof List; + } + + } + + private class MarkerCategorizedLabelProvider + extends CategorizedLabelProvider implements IToolTipProvider { + + @Override + public String getText(Object element) { + if (element instanceof IMarker) + return ((IMarker) element).getName(); + else if (element instanceof IMarkerGroup) + return ((IMarkerGroup) element).getName(); + else + return super.getText(element); + } + + @Override + public Image getImage(Object element) { + if (element instanceof IMarker) { + + IMarker marker = (IMarker) element; + Image image = null; + Dimension size = (Dimension) getProperties() + .get(GalleryViewer.FrameContentSize); + if (size == null) + size = new Dimension(64, 64); + + ImageDescriptor imageDescriptor = MarkerImageDescriptor + .createFromMarker(marker, size.width, size.height, + false); + + image = getResourceManager().createImage(imageDescriptor); + + if (image != null) + return image; + } + return super.getImage(element); + } + + public String getToolTip(Object element) { + + if (element instanceof IMarker) { + return getText((IMarker) element); + } + + return ""; //$NON-NLS-1$ + } + + } + + private Section activeSectionForSectionMenu; + private IMarkerGroup activeMarkerGroupForSectionMenu; + + @Override + public void createControl(Composite container) { + super.createControl(container); + setContentProvider(new MarkerCategorizedContentProvider()); + setLabelProvider(new MarkerCategorizedLabelProvider()); + EditDomain domain = new EditDomain(); + domain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); + setEditDomain(domain); + initProperties(); + createControl(container, SWT.WRAP); + getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + setInput(getMarkerGroups()); + } + + @Override + protected void initNestedGalleryViewer(GalleryViewer galleryViewerer) { + super.initNestedGalleryViewer(galleryViewerer); + Properties properties = galleryViewerer.getProperties(); + properties.set(GalleryViewer.HideTitle, Boolean.TRUE); + } + + @Override + protected void initProperties() { + super.initProperties(); + Properties properties = getProperties(); + properties.set(GalleryViewer.FrameContentSize, + new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); + } + + @Override + protected void configureSection(final Section section, + final Object category) { + super.configureSection(section, category); + if (category instanceof IMarkerGroup) { + final IMarkerGroup group = (IMarkerGroup) category; + + try { + Field field = ExpandableComposite.class + .getDeclaredField("textLabel"); //$NON-NLS-1$ + field.setAccessible(true); + Object textLabel = field.get(section); + if (textLabel instanceof Control) { + ((Control) textLabel) + .addMenuDetectListener(new MenuDetectListener() { + @Override + public void menuDetected(MenuDetectEvent e) { + activeMarkerGroupForSectionMenu = null; + activeSectionForSectionMenu = null; + IStructuredSelection ss = getStructuredSelection(); + if (ss != null && ss.isEmpty()) { + activeSectionForSectionMenu = section; + activeMarkerGroupForSectionMenu = group; + } + } + }); + } + } catch (NoSuchFieldException e1) { + e1.printStackTrace(); + } catch (SecurityException e1) { + e1.printStackTrace(); + } catch (IllegalArgumentException e1) { + e1.printStackTrace(); + } catch (IllegalAccessException e1) { + e1.printStackTrace(); + } + + getNestedViewer(category).getControl() + .addMenuDetectListener(new MenuDetectListener() { + @Override + public void menuDetected(MenuDetectEvent e) { + activeMarkerGroupForSectionMenu = null; + activeSectionForSectionMenu = null; + } + }); + + section.addMenuDetectListener(new MenuDetectListener() { + + @Override + public void menuDetected(MenuDetectEvent e) { + activeMarkerGroupForSectionMenu = null; + activeSectionForSectionMenu = null; + IStructuredSelection ss = getStructuredSelection(); + if (ss != null && ss.isEmpty()) { + activeSectionForSectionMenu = section; + activeMarkerGroupForSectionMenu = group; + } + } + }); + + IMarkerSheet userSheet = MindMapUI.getResourceManager() + .getUserMarkerSheet(); + if (!userSheet.getMarkerGroups().contains(group)) + return; + + createSectionTextClient(section, + MindMapMessages.MarkerResourceManagerViewer_AddSection_title, + category); + } + } + + private List getMarkerGroups() { + ArrayList mgs = new ArrayList(); + IResourceManager resourceManager = MindMapUI.getResourceManager(); + IMarkerSheet userSheet = resourceManager.getUserMarkerSheet(); + IMarkerSheet sysSheet = resourceManager.getSystemMarkerSheet(); + for (IMarkerGroup group : sysSheet.getMarkerGroups()) { + if (!group.isHidden()) + mgs.add(group); + } + for (IMarkerGroup group : userSheet.getMarkerGroups()) { + if (!group.isHidden()) + mgs.add(group); + } + + return mgs; + } + + public boolean canEditMarkerGroup() { + if (activeMarkerGroupForSectionMenu == null + || activeSectionForSectionMenu == null + || activeSectionForSectionMenu.isDisposed()) { + return false; + } + + IMarkerSheet userSheet = MindMapUI.getResourceManager() + .getUserMarkerSheet(); + if (!userSheet.getMarkerGroups() + .contains(activeMarkerGroupForSectionMenu)) + return false; + IStructuredSelection ss = getStructuredSelection(); + if (ss != null && !ss.isEmpty()) + return false; + return true; + } + + public void renameMarkerGroup() { + if (activeMarkerGroupForSectionMenu == null + || activeSectionForSectionMenu == null + || activeSectionForSectionMenu.isDisposed()) { + activeMarkerGroupForSectionMenu = null; + activeSectionForSectionMenu = null; + return; + } + + final IMarkerGroup markerGroup = activeMarkerGroupForSectionMenu; + final Section section = activeSectionForSectionMenu; + + activeMarkerGroupForSectionMenu = null; + activeSectionForSectionMenu = null; + + Rectangle textLabelBounds = null; + final String groupName = markerGroup.getName(); + for (Control control : section.getChildren()) + if (control instanceof Label + && groupName.equals(((Label) control).getText())) + textLabelBounds = control.getBounds(); + + if (lastEditor != null) { + lastEditor.close(); + lastEditor = null; + } + final FloatingTextEditor editor = new FloatingTextEditor(section); + if (textLabelBounds != null) { + section.setText(""); //$NON-NLS-1$ + int x = textLabelBounds.x - 2; + int y = textLabelBounds.y - 2; + editor.setInitialLocation(new Point(x, y)); + editor.setInitialSize(new Point(100, 18)); + } else { + editor.setInitialLocation(new Point(100, 0)); + editor.setInitialSize(new Point(100, 18)); + } + + editor.setInput(new Document(groupName)); + editor.open(); + editor.doOperation(FloatingTextEditor.SELECT_ALL); + editor.addFloatingTextEditorListener( + new IFloatingTextEditorListener.Stub() { + @Override + public void editingFinished(TextEvent e) { + String text = e.text; + if (null == text || "".equals(text) //$NON-NLS-1$ + || text.equals(groupName)) { + section.setText(groupName); + editor.close(); + } else + markerGroup.setName(text); + MindMapUI.getResourceManager().saveUserMarkerSheet(); + } + + @Override + public void editingCanceled(TextEvent e) { + refresh(); + } + + }); + final Listener listener = new Listener() { + @Override + public void handleEvent(Event event) { + if (editor != null && !editor.isClosed()) { + if (!editor.getControl().getBounds().contains(event.x, + event.y)) + editor.close(true); + } + } + }; + Display.getCurrent().addFilter(SWT.MouseDown, listener); + editor.getControl().addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + if (listener != null) + Display.getCurrent().removeFilter(SWT.MouseDown, listener); + + } + }); + lastEditor = editor; + ITextViewer textViewer = editor.getTextViewer(); + textViewer.getTextWidget().setBackground( + getResourceManager().createColor(new RGB(255, 255, 255))); + textViewer.getTextWidget().setForeground( + getResourceManager().createColor(new RGB(0, 0, 0))); + } + + @Override + protected void handleClickSectionTextClient(Object category) { + if (category instanceof IMarkerGroup) { + List newMarkers = ResourceUtils + .addMarkersFor((IMarkerGroup) category); + refresh(); + reveal(category); + setSelection(new StructuredSelection(newMarkers), true); + MindMapUI.getResourceManager().saveUserMarkerSheet(); + } + } + + public void startEditing(IMarker marker) { + List markerGroups = getMarkerGroups(); + for (IMarkerGroup markerGroup : markerGroups) { + List styles = markerGroup.getMarkers(); + if (styles.contains(marker)) { + GalleryViewer galleryViewer = getNestedViewer(markerGroup); + FramePart part = (FramePart) galleryViewer + .findGraphicalPart(marker); + renameMarker((Composite) galleryViewer.getControl(), marker, + part.getFigure().getBounds()); + break; + } + } + } + + private void renameMarker(Composite composite, final IMarker marker, + org.eclipse.draw2d.geometry.Rectangle bounds) { + + int x = bounds.x + (bounds.width - RENAME_COMPOSITE_WIDTH) / 2; + int y = bounds.y + (bounds.height - RENAME_COMPOSITE_HEIGHT) / 2; + + final FloatingTextEditor editor = new FloatingTextEditor(composite); + editor.setInitialLocation(new Point(x, y)); + editor.setInitialSize( + new Point(RENAME_COMPOSITE_WIDTH, RENAME_COMPOSITE_HEIGHT)); + editor.setInput(new Document(marker.getName())); + editor.open(); + editor.doOperation(FloatingTextEditor.SELECT_ALL); + editor.addFloatingTextEditorListener( + new IFloatingTextEditorListener.Stub() { + public void editingFinished(TextEvent e) { + String text = e.text; + if (null != text && !("".equals(text))) //$NON-NLS-1$ + marker.setName(text); + } + }); + } + + public void updateInput() { + setInput(getMarkerGroups()); + } + + public void deleteMarkerGroup() { + IMarkerSheet markerSheet = MindMapUI.getResourceManager() + .getUserMarkerSheet(); + markerSheet.removeMarkerGroup(activeMarkerGroupForSectionMenu); + try { + MindMapUI.getResourceManager().saveUserMarkerSheet(); + } catch (Exception e) { + // TODO: handle exception + } + updateInput(); + } + + public void activateGroup(IMarkerGroup markerGroup) { + activeMarkerGroupForSectionMenu = markerGroup; + activeSectionForSectionMenu = (Section) getSection(markerGroup); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerDialogPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerDialogPage.java new file mode 100644 index 000000000..73f641338 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerDialogPage.java @@ -0,0 +1,188 @@ +package org.xmind.ui.internal.resourcemanager; + +import javax.inject.Inject; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.ISelectionProvider; +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.xmind.ui.internal.e4models.IModelPartContext; +import org.xmind.ui.internal.e4models.ModelPageContainer; + +public abstract class ResourceManagerDialogPage extends ModelPageContainer + implements IResourceManagerDialogPage { + + private final static int BUTTON_MIN_WIDTH = Util.isMac() ? 150 : 120; + private Image image; + private ImageDescriptor imageDescriptor; + private String pageId; + private String title; + + @Inject + protected IModelPartContext context; + + private ResourceManagerViewer viewer; + + @Override + protected Control createMainPage(Composite parent) { + Composite composite = new Composite(parent, SWT.BORDER); + GridLayoutFactory.swtDefaults().spacing(0, 0).margins(0, 0) + .applyTo(composite); + Composite viewerComposite = new Composite(composite, SWT.NONE); + GridLayoutFactory.fillDefaults().extendedMargins(0, 0, 0, 0) + .applyTo(viewerComposite); + viewerComposite + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + viewer = createViewer(); + + context.setSelectionProvider(viewer); + context.registerContextMenu(viewerComposite, getContextMenuId()); + viewer.createControl(viewerComposite); + + createButtonBar(composite); + + registerRunnable(context.getAdapter(MPart.class).getContext()); + + return composite; + } + + protected void registerRunnable(IEclipseContext eclipseContext) { + } + + protected abstract ResourceManagerViewer createViewer(); + + protected Control createButtonBar(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().extendedMargins(0, 0, 0, 0) + .applyTo(composite); + GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.heightHint = 40; + composite.setLayoutData(gridData); + + Composite buttonBar = new Composite(composite, 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 = 15; + layout.marginHeight = 0; + layout.marginTop = 0; + layout.marginBottom = 0; + buttonBar.setLayout(layout); + buttonBar.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, true)); + buttonBar.setFont(parent.getFont()); + + // Add buttons to the button bar. + createButtonsForButtonBar(buttonBar); + return buttonBar; + } + + protected void createButtonsForButtonBar(Composite composite) { + // create OK and Cancel buttons by default + createButton(composite, IDialogConstants.OK_ID, + IDialogConstants.OK_LABEL, true); + createButton(composite, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + + } + + protected 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 | SWT.NONE); + button.setText(label); + button.setFont(JFaceResources.getDialogFont()); + button.setData(new Integer(id)); + + GridData gridData = new GridData(SWT.FILL, SWT.NONE, false, false); + button.setLayoutData(gridData); + gridData.widthHint = Math.max(gridData.widthHint, BUTTON_MIN_WIDTH); + return button; + } + + public void setFocus() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + viewer.getControl().setFocus(); + } + } + + @Override + public void dispose() { + } + + @Override + public T getAdapter(Class adapter) { + if (ISelectionProvider.class.equals(adapter)) { + return adapter.cast(viewer); + } else if (Viewer.class.equals(adapter)) { + return adapter.cast(viewer); + } + return null; + } + + public String getId() { + return pageId == null ? getModelPageId() : pageId; + } + + public void setId(String id) { + this.pageId = id; + } + + @Override + public String getTitle() { + return title == null ? getModelPageTitle() : title; + } + + @Override + public void setTitle(String title) { + this.title = title; + } + + @Override + public void setImageDescriptor(ImageDescriptor imageDes) { + this.imageDescriptor = imageDes; + if (image != null) { + image.dispose(); + image = null; + } + } + + public ImageDescriptor getImageDescriptor() { + return imageDescriptor; + } + + @Override + public Image getImage() { + if (image == null) { + if (imageDescriptor != null) { + image = imageDescriptor.createImage(); + } + } + return image; + } + + @Override + public void refresh() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + viewer.refresh(); + } + } + + protected abstract String getContextMenuId(); +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerDialogPart.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerDialogPart.java new file mode 100644 index 000000000..9e3fd71c3 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerDialogPart.java @@ -0,0 +1,329 @@ +package org.xmind.ui.internal.resourcemanager; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Map; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.Platform; +import org.eclipse.e4.core.contexts.ContextInjectionFactory; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +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.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.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.Listener; +import org.osgi.framework.Bundle; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.e4models.IContextRunnable; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.e4models.IModelPartContext; +import org.xmind.ui.internal.e4models.ModelPart; +import org.xmind.ui.tabfolder.MTabFolder; +import org.xmind.ui.tabfolder.MTabItem; + +public class ResourceManagerDialogPart extends ModelPart + implements IModelPartContext { + + private static final int TITLE_AREA_LABEL_MARGIN = 10; + private static final String RESOURCE_MANAGER_EXTENSION_ID = "org.xmind.ui.resourceManager"; //$NON-NLS-1$ + private static final String DATA_ID = "org.xmind.ui.resourceManager.itemId"; //$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_ID = "id"; //$NON-NLS-1$ + private static final String TITLE_IMAGE_PATH = "platform:/plugin/org.xmind.ui.mindmap/icons/title.png"; //$NON-NLS-1$ + + private MTabFolder tabFolder; + private ResourceManager resourceManagerForPart; + + private ArrayList registedPages; + + @Override + protected void createContent(Composite parent) { + final Composite composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().margins(0, 0).spacing(0, 0) + .applyTo(composite); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + composite.setBackground(parent.getBackground()); + resourceManagerForPart = new LocalResourceManager( + JFaceResources.getResources(), parent); + + createTitleComposite(composite); + createContentComposite(composite); + + parent.layout(true, true); + } + + private void createTitleComposite(Composite parent) { + Composite title = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false) + .margins(0, 0).spacing(0, 0).extendedMargins(0, 0, 0, 0) + .applyTo(title); + title.setBackground( + parent.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + GridDataFactory.fillDefaults().grab(true, false).applyTo(title); + ((GridData) title.getLayoutData()).heightHint = 70; + + Composite labelsComposite = new Composite(title, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(1).equalWidth(true) + .margins(0, 0).spacing(0, 0) + .extendedMargins(TITLE_AREA_LABEL_MARGIN, 0, 0, 0) + .applyTo(labelsComposite); + GridDataFactory.fillDefaults().grab(true, true) + .applyTo(labelsComposite); + Label text = new Label(labelsComposite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true) + .align(SWT.FILL, SWT.BOTTOM).applyTo(text); + text.setFont(JFaceResources.getBannerFont()); + text.setText(MindMapMessages.ResourceManagerPart_title); + Label message = new Label(labelsComposite, SWT.WRAP); + GridDataFactory.fillDefaults().grab(true, true) + .align(SWT.FILL, SWT.CENTER).applyTo(message); + message.setFont(JFaceResources.getDialogFont()); + message.setText(MindMapMessages.ResourceManagerPart_message); + + Composite imageComposite = new Composite(title, SWT.NONE); + imageComposite.setLayout(new GridLayout(1, true)); + + Label titleImageLabel = new Label(imageComposite, SWT.CENTER); + GridDataFactory.fillDefaults().grab(true, true) + .applyTo(titleImageLabel); + + ImageDescriptor imageDescriptor = null; + try { + imageDescriptor = ImageDescriptor + .createFromURL(new URL(TITLE_IMAGE_PATH)); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + if (imageDescriptor != null) { + Image img = resourceManagerForPart.createImage(imageDescriptor); + titleImageLabel.setImage(img); + } else { + titleImageLabel.setImage(JFaceResources + .getImage(TitleAreaDialog.DLG_IMG_TITLE_BANNER)); + } + + } + + private void createContentComposite(Composite composite) { + Composite content = new Composite(composite, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false) + .margins(0, 0).spacing(0, 0).applyTo(content); + GridDataFactory.fillDefaults().grab(true, true).applyTo(content); + + tabFolder = new MTabFolder(content, SWT.BORDER); + tabFolder.setStyleProvider( + new ResourceManagerStyleProvider(resourceManagerForPart)); + tabFolder.setBackground( + composite.getDisplay().getSystemColor(SWT.COLOR_TRANSPARENT)); + tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + tabFolder.addListener(SWT.Selection, new Listener() { + public void handleEvent(org.eclipse.swt.widgets.Event event) { + showPage((MTabItem) event.item); + } + }); + + final Map persistedState = getAdapter(MPart.class) + .getPersistedState(); + + tabFolder.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + MTabItem item = tabFolder.getSelection(); + String pageId = (String) item.getData(DATA_ID); + if (pageId != null) { + persistedState.put( + IModelConstants.KEY_MODEL_PART_CURRENT_PAGE_ID, + pageId); + } + } + }); + + String persistedSelectedPageId = persistedState + .get(IModelConstants.KEY_MODEL_PART_CURRENT_PAGE_ID); + MTabItem selectedItem = null; + for (final IResourceManagerDialogPage page : registedPages) { + MTabItem item = new MTabItem(tabFolder, SWT.RADIO); + item.setText(page.getTitle()); + item.setImage(page.getImage()); + + 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, page.getId()); + if (page.getId().equals(persistedSelectedPageId)) { + selectedItem = item; + } + } + + if (selectedItem == null && tabFolder.getItemCount() > 0) { + selectedItem = tabFolder.getItem(0); + } + + tabFolder.setSelection(selectedItem); + showPage(selectedItem); + + } + + @Override + protected void init() { + super.init(); + registedPages = new ArrayList(); + + IExtensionPoint extPoint = Platform.getExtensionRegistry() + .getExtensionPoint(RESOURCE_MANAGER_EXTENSION_ID); + IConfigurationElement[] elements = extPoint.getConfigurationElements(); + for (IConfigurationElement ele : elements) { + try { + IResourceManagerDialogPage page = readPage(ele); + if (page != null) { + registedPages.add(page); + } + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + getAdapter(MPart.class).getContext().set( + IModelConstants.KEY_MODEL_PART_REFRESH_PAGE, + new IContextRunnable() { + @Override + public void run() { + if (tabFolder != null && !tabFolder.isDisposed()) { + Object page = tabFolder.getSelection().getData(); + if (page instanceof IResourceManagerDialogPage) { + ((IResourceManagerDialogPage) page).refresh(); + } + } + } + }); + + } + + private IResourceManagerDialogPage readPage(IConfigurationElement element) + throws InstantiationException, IllegalAccessException, + MalformedURLException { + 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, + getAdapter(MPart.class).getContext()); + if (!(contribution instanceof IResourceManagerDialogPage)) + return null; + + final IResourceManagerDialogPage page = (IResourceManagerDialogPage) contribution; + page.setId(id); + + String label = element.getAttribute(ATTR_LABEL); + page.setTitle(label); + + ImageDescriptor icon = readIcon(element); + page.setImageDescriptor(icon); + + return page; + } + + private ImageDescriptor readIcon(IConfigurationElement 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; + } + + @Override + protected void handleBringToTop() { + super.handleBringToTop(); + if (tabFolder != null && !tabFolder.isDisposed()) { + String pageId = getAdapter(MPart.class).getPersistedState() + .get(IModelConstants.KEY_MODEL_PART_CURRENT_PAGE_ID); + MTabItem itemToShow = null; + MTabItem[] items = tabFolder.getItems(); + for (MTabItem item : items) { + if (item.getData(DATA_ID).equals(pageId)) { + itemToShow = item; + break; + } + } + if (itemToShow == null && tabFolder.getItemCount() > 0) { + itemToShow = tabFolder.getItem(0); + } + tabFolder.setSelection(itemToShow); + showPage(itemToShow); + } + } + + private void showPage(MTabItem item) { + Object resourcePage = item.getData(); + if (resourcePage instanceof IResourceManagerDialogPage) { + IResourceManagerDialogPage page = (IResourceManagerDialogPage) resourcePage; + + Control control = page.getControl(); + if (control == null || control.isDisposed()) { + page.createControl(this.tabFolder.getBody()); + item.setControl(page.getControl()); + } + setSelectionProvider(page.getAdapter(ISelectionProvider.class)); + MPart part = getAdapter(MPart.class); + part.getPersistedState().put( + IModelConstants.KEY_MODEL_PART_CURRENT_PAGE_ID, + page.getId()); + part.getContext().set( + IModelConstants.KEY_MODEL_PART_CURRENT_PAGE_ID, + page.getId()); + } + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerStyleProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerStyleProvider.java new file mode 100644 index 000000000..0b8f94811 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerStyleProvider.java @@ -0,0 +1,142 @@ +package org.xmind.ui.internal.resourcemanager; + +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.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.RGB; +import org.xmind.ui.resources.ColorUtils; +import org.xmind.ui.tabfolder.MTabFolder; +import org.xmind.ui.tabfolder.MTabItem; +import org.xmind.ui.util.IStyleProvider; + +public class ResourceManagerStyleProvider implements IStyleProvider { + + private ResourceManager resourceManager; + + private Map keyToRGB = new HashMap(); + + public ResourceManagerStyleProvider(ResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + 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 = "#008EFC"; //$NON-NLS-1$ + } else if (TEXT.equals(key)) { + if (item.isSelected()) { + defaultValue = "#FFFFFF"; //$NON-NLS-1$ + } else { + defaultValue = "#000000"; //$NON-NLS-1$ + } + } + } else if (widget instanceof MTabFolder) { + if (MTabFolder.TAB_BAR.equals(key)) { + defaultValue = "#FFFFFF"; //$NON-NLS-1$ + } + if (MTabFolder.BODY.equals(key)) { + defaultValue = "#F2F2F2"; //$NON-NLS-1$ + } + } + if (defaultValue != null) { + RGB rgb = ColorUtils.toRGB(defaultValue); + return (Color) resourceManager.get(ColorDescriptor.createFrom(rgb)); + } + return null; + } + + 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 0xFF; + if (item.isPreselected()) + return 0x13; + } + } + return defaultValue; + } + + public Font getFont(Object widget, String key) { + int fontHeight; + if (Util.isMac()) { + fontHeight = 12;//font size + } else { + fontHeight = 8;//font pixels + } + if (widget instanceof MTabItem) { + if (TEXT.equals(key)) + return (Font) resourceManager.get(JFaceResources + .getDefaultFontDescriptor().setHeight(fontHeight)); + } + return null; + } + + public int getWidth(Object widget, String key, int defaultValue) { + if (widget instanceof MTabItem) { + if (IMAGE.equals(key)) + return 26; + if (MARGIN.equals(key)) + return 17; + if (SEPARATOR.equals(key)) + return 2;//TODO:system-based + if (key == null) + return 131; + } + return defaultValue; + } + + public int getHeight(Object widget, String key, int defaultValue) { + if (widget instanceof MTabItem) { + if (IMAGE.equals(key)) + return 26; + if (MARGIN.equals(key)) + return 10; + if (SEPARATOR.equals(key)) + return 2; + if (key == null) + return 46; + } + return defaultValue; + } + + public int getPosition(Object widget, String key, int defaultValue) { + if (widget instanceof MTabItem && TEXT.equals(key)) { + return SWT.RIGHT; + } else if (widget instanceof MTabFolder + && MTabFolder.TAB_BAR.equals(key)) { + return SWT.LEFT; + } + return defaultValue; + } + + @Override + public int getTextAlign(Object widget, String key, int defaultValue) { + if (widget instanceof MTabItem && TEXT_ALIGN.equals(key)) { + return SWT.LEFT; + } + + return defaultValue; + } + + public void setColor(String key, RGB value) { + keyToRGB.put(key, value); + } + + public boolean getVisibility(Object widget, String key, + boolean defaultValue) { + return defaultValue; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerViewer.java new file mode 100644 index 000000000..8f28f12e0 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ResourceManagerViewer.java @@ -0,0 +1,247 @@ +package org.xmind.ui.internal.resourcemanager; + +import java.util.List; + +import org.eclipse.draw2d.AbstractHintLayout; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.forms.widgets.Section; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.draw2d.SizeableImageFigure; +import org.xmind.gef.part.IPart; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.CategorizedGalleryViewer; +import org.xmind.ui.gallery.FramePart; +import org.xmind.ui.gallery.GalleryLayout; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.gallery.IDecorationContext; +import org.xmind.ui.gallery.ILabelDecorator; +import org.xmind.ui.resources.ColorUtils; + +public abstract class ResourceManagerViewer extends CategorizedGalleryViewer { + + private static final int DEFAULT_FRAME_HEIGHT = 100; + private static final int DEFAULT_FRAME_WIDTH = 200; + public static final int DEFAULT_FLOATING_TEXT_EDITOR_WIDTH_EXPAND = 10; +// private static final RGB BACKGROUND_SECTION = new RGB(248, 248, 248); +// private static final RGB FOREGROUND_SECTION_TITLE_TEXT_CLIENT = new RGB(95, +// 64, 213); + + protected class ResourceCategorizedSelectTool extends GallerySelectTool { + + protected boolean handleMouseDown(org.xmind.gef.event.MouseEvent me) { + FramePart targetFrame = findFrame(me.target); + if (targetFrame != null && targetFrame.getFigure().isSelected()) { + return super.handleMouseDown(me); + } else { + return handleSelectionOnMouseDown(me); + } + } + + private FramePart findFrame(IPart part) { + while (part != null) { + if (part instanceof FramePart) + return (FramePart) part; + part = part.getParent(); + } + return null; + } + } + + protected static class Layout extends AbstractHintLayout { + + private IDecorationContext properties; + + public Layout(IDecorationContext properties) { + this.properties = properties; + } + + 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); + figure.setBounds( + new Rectangle(area.x, area.y, 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()); + + Insets insets = figure.getInsets(); + Dimension contentSize = (Dimension) properties + .getProperty(GalleryViewer.FrameContentSize, null); + if (contentSize != null) + return new Dimension(contentSize.width + insets.getWidth(), + contentSize.height + insets.getHeight()); + Dimension d = new Dimension(); + @SuppressWarnings("rawtypes") + 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; + } + + } + + protected class CategorizedLabelProvider extends LabelProvider + implements ILabelDecorator { + + public IFigure decorateFigure(IFigure figure, Object element, + IDecorationContext context) { + @SuppressWarnings("rawtypes") + List children = figure.getChildren(); + boolean needInitFigureContent = children.isEmpty(); + if (needInitFigureContent) { + SizeableImageFigure themeContentFigure = new SizeableImageFigure( + getImage(element)); + figure.add(themeContentFigure); + + if (context != null) { + figure.setLayoutManager(new Layout(context)); + boolean imageConstrained = Boolean.TRUE.equals( + context.getProperty(GalleryViewer.ImageConstrained, + false)); + boolean imageStretched = Boolean.TRUE.equals(context + .getProperty(GalleryViewer.ImageStretched, false)); + themeContentFigure.setConstrained(imageConstrained); + themeContentFigure.setStretched(imageStretched); + } + } + + children = figure.getChildren(); + if (children.size() == 1) { + Object themeContentFigure = children.get(0); + if (themeContentFigure instanceof SizeableImageFigure) { + ((SizeableImageFigure) themeContentFigure) + .setImage(getImage(element)); + } + } + + return figure; + } + + } + + private ResourceManager resourceManager; + + public void createControl(Composite container) { + resourceManager = new LocalResourceManager( + JFaceResources.getResources(), container); + } + + @Override + protected void configureNestedViewer(GalleryViewer viewer, + Object category) { + super.configureNestedViewer(viewer, category); + initNestedGalleryViewer(viewer); + } + + protected void initNestedGalleryViewer(GalleryViewer galleryViewerer) { + EditDomain editDomain = new EditDomain(); + editDomain.installTool(GEF.TOOL_SELECT, + new ResourceCategorizedSelectTool()); + 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); + } + + protected void initProperties() { + Properties properties = getProperties(); + properties.set(GalleryViewer.Horizontal, Boolean.TRUE); + properties.set(GalleryViewer.Wrap, Boolean.TRUE); + properties.set(GalleryViewer.FrameContentSize, + new Dimension(DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT)); + properties.set(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_BOTTOM); + properties.set(GalleryViewer.SingleClickToOpen, Boolean.FALSE); + properties.set(GalleryViewer.SolidFrames, Boolean.TRUE); + properties.set(GalleryViewer.FlatFrames, Boolean.TRUE); + properties.set(GalleryViewer.HideTitle, Boolean.FALSE); + properties.set(GalleryViewer.ImageConstrained, Boolean.TRUE); + properties.set(GalleryViewer.Layout, new GalleryLayout().align( + GalleryLayout.ALIGN_TOPLEFT, GalleryLayout.ALIGN_TOPLEFT)); + } + + @Override + protected void configureSection(final Section section, + final Object category) { + super.configureSection(section, category); +// Color bg = resourceManager.createColor(BACKGROUND_SECTION); +// section.setTitleBarBackground(bg); +// section.setTitleBarBorderColor(bg); +// section.setTitleBarGradientBackground(bg); + } + + protected void createSectionTextClient(Section section, String text, + final Object category) { + Label label = new Label(section, SWT.NONE); + label.setText(text); + + label.setForeground((Color) resourceManager + .get(ColorUtils.toDescriptor("#0082F9"))); //$NON-NLS-1$ + label.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + handleClickSectionTextClient(category); + } + }); + label.setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_HAND)); + section.setTextClient(label); + } + + protected void handleClickSectionTextClient(Object category) { + } + + protected ResourceManager getResourceManager() { + return resourceManager; + } + + protected org.eclipse.swt.widgets.Layout createFormLayout() { + GridLayout layout = new GridLayout(1, true); + layout.marginWidth = -3; + layout.marginHeight = 0; + return layout; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/StyleResourceManagerPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/StyleResourceManagerPage.java new file mode 100644 index 000000000..ef83a7819 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/StyleResourceManagerPage.java @@ -0,0 +1,262 @@ +package org.xmind.ui.internal.resourcemanager; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.jface.dialogs.IDialogConstants; +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.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +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.ICoreEventSupport; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.e4models.IContextRunnable; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.utils.ResourceUtils; +import org.xmind.ui.mindmap.MindMapUI; + +public class StyleResourceManagerPage extends ResourceManagerDialogPage + implements ICoreEventListener { + + private final static int editStyleButtonID = IDialogConstants.CLIENT_ID + 1; + private CoreEventRegister coreEventRegister; + private Button editStyleButton; + private StyleResourceManagerViewer viewer; + + @Override + protected ResourceManagerViewer createViewer() { + viewer = new StyleResourceManagerViewer(); + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection sel = (IStructuredSelection) selection; + Object obj = sel.getFirstElement(); + if (obj != null && obj instanceof IStyle) { + editStyleButton.setEnabled(true); + return; + } + } + editStyleButton.setEnabled(false); + } + }); + registerCoreEvent(); + return viewer; + } + + @Override + protected void createButtonsForButtonBar(Composite buttonBar) { + editStyleButton = createButton(buttonBar, editStyleButtonID, + MindMapMessages.StyleResourceManager_Editor_button, false); + editStyleButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + StyleResourceManagerViewer styleViewer = (StyleResourceManagerViewer) viewer; + styleViewer.editStyle(); + } + }); + editStyleButton.setEnabled(false); + } + + private void registerCoreEvent() { + ICoreEventSupport ces = (ICoreEventSupport) MindMapUI + .getResourceManager().getUserStyleSheet() + .getAdapter(ICoreEventSupport.class); + if (ces != null) { + coreEventRegister = new CoreEventRegister(this); + coreEventRegister.setNextSupport(ces); + coreEventRegister.register(Core.StyleAdd); + coreEventRegister.register(Core.StyleRemove); + coreEventRegister.register(Core.TitleText); + coreEventRegister.register(Core.Name); + } + } + + @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() { + viewer.refresh(); + viewer.setSelection(new StructuredSelection(event.getSource()), + true); + } + }); + } + + @Override + public void dispose() { + if (coreEventRegister != null) + coreEventRegister.unregisterAll(); + super.dispose(); + } + + @Override + protected void registerRunnable(IEclipseContext eclipseContext) { + super.registerRunnable(eclipseContext); + + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_RENAME, //$NON-NLS-1$ + new IContextRunnable() { + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + List styles = getSelectedStyles(); + if (styles.size() == 1) + viewer.startEditing(styles.get(0)); + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + return isOneUserStyleSelected(); + } + }); + + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_DUPLICATE, //$NON-NLS-1$ + new IContextRunnable() { + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + List styles = getSelectedStyles(); + if (!styles.isEmpty()) { + List newStyles = ResourceUtils + .duplicateStyles(styles); + viewer.setSelection( + new StructuredSelection(newStyles)); + } + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + List styles = getSelectedStyles(); + boolean canExecute = !styles.isEmpty(); + return canExecute; + } + + }); + + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_DELETE, //$NON-NLS-1$ + new IContextRunnable() { + + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + List styles = getSelectedStyles(); + if (!styles.isEmpty() + && ResourceUtils.confirmToDeleteStyles( + viewer.getControl().getShell(), + styles)) { + ResourceUtils.deleteStyles(styles); + } + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + return isAllUserStyles(); + } + }); + + eclipseContext.set(getId() + "/" + IModelConstants.KEY_MODEL_PART_EDIT, //$NON-NLS-1$ + new IContextRunnable() { + + @Override + public void run() { + StyleResourceManagerViewer styleViewer = (StyleResourceManagerViewer) viewer; + styleViewer.editStyle(); + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + List selected = getSelectedStyles(); + return selected != null && !selected.isEmpty(); + } + }); + + } + + private List getSelectedStyles() { + 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; + } + + @Override + protected String getContextMenuId() { + return IModelConstants.POPUPMENU_ID_RESOURCEMANAGER_STYLE; + } + + @Override + public String getModelPageId() { + return IModelConstants.PAGE_ID_RESOURCE_MANAGER_STYLE; + } + + @Override + public String getModelPageTitle() { + return null; + } + + private boolean isAllUserStyles() { + List styles = getSelectedStyles(); + Set userStyles = MindMapUI.getResourceManager() + .getUserStyleSheet().getAllStyles(); + boolean canExecute = !styles.isEmpty(); + for (IStyle style : styles) { + canExecute = canExecute && userStyles.contains(style); + } + return canExecute; + } + + private boolean isOneUserStyleSelected() { + List styles = getSelectedStyles(); + IStyleSheet userStyleSheet = MindMapUI.getResourceManager() + .getUserStyleSheet(); + Set userStyles = userStyleSheet.getAllStyles(); + boolean canExecute = styles.size() == 1; + for (IStyle style : styles) { + canExecute = canExecute && userStyles.contains(style); + } + return canExecute; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/StyleResourceManagerViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/StyleResourceManagerViewer.java new file mode 100644 index 000000000..7c428d038 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/StyleResourceManagerViewer.java @@ -0,0 +1,436 @@ +package org.xmind.ui.internal.resourcemanager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +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.runtime.SafeRunner; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.SWTGraphics; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.forms.widgets.Section; +import org.eclipse.ui.handlers.IHandlerService; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IViewer; +import org.xmind.gef.part.IPart; +import org.xmind.gef.tool.ITool; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.GalleryEditTool; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.handlers.IMindMapCommandConstants; +import org.xmind.ui.internal.views.StyleFigure; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.texteditor.FloatingTextEditor; +import org.xmind.ui.viewers.IToolTipProvider; + +public class StyleResourceManagerViewer extends ResourceManagerViewer { + + private static final int FRAME_HEIGHT = 72; + + private static final int FRAME_WIDTH = 132; + + //FIXME how to dispose cachedImageData??? + public static Map cachedImageData = new HashMap(); + + private static final String EDIT_STYLE_COMMAND_ID = "org.xmind.ui.command.style.edit2"; //$NON-NLS-1$ + + private class StyleGalleryViewer extends GalleryViewer { + protected boolean isTitleEditable(IPart p) { + IStyleSheet styleSheet = MindMapUI.getResourceManager() + .getUserStyleSheet(); + return styleSheet == null ? false + : styleSheet.getAllStyles().contains(p.getModel()); + } + } + + private static class StyleGroup { + public StyleGroup(String type) { + this.type = type; + } + + private String type; + private List styles = new ArrayList(); + + public String getType() { + return type; + } + + public String getName() { + if (IStyle.TOPIC.equals(type)) + return MindMapMessages.StyleResourceManagerViewer_Topic; + if (IStyle.BOUNDARY.equals(type)) + return MindMapMessages.StyleResourceManagerViewer_Boundary; + if (IStyle.MAP.equals(type)) + return MindMapMessages.StyleResourceManagerViewer_Map; + if (IStyle.PARAGRAPH.equals(type)) + return MindMapMessages.StyleResourceManagerViewer_Paragraph; + if (IStyle.RELATIONSHIP.equals(type)) + return MindMapMessages.StyleResourceManagerViewer_Relationship; + if (IStyle.SUMMARY.equals(type)) + return MindMapMessages.StyleResourceManagerViewer_Summary; + if (IStyle.TEXT.equals(type)) + return MindMapMessages.StyleResourceManagerViewer_Text; + if (IStyle.THEME.equals(type)) + return MindMapMessages.StyleResourceManagerViewer_Theme; + return ""; //$NON-NLS-1$ + } + + public List getItems() { + return styles; + } + + public void addStyle(IStyle style) { + styles.add(style); + } + + public int hashCode() { + return type.hashCode(); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof StyleGroup)) + return false; + if (((StyleGroup) obj).type.equals(this.type)) + return true; + return false; + } + } + + private static class StyleGalleryCore { + private List groups = new ArrayList(); + private static StyleGalleryCore instance = new StyleGalleryCore(); + + public StyleGalleryCore() { + } + + private StyleGroup getGroup(IStyle style) { + String type = style.getType(); + if (type != null) + for (StyleGroup group : groups) { + if (type.equals(group.type)) + return group; + } + + StyleGroup group = new StyleGroup(type); + groups.add(group); + return group; + } + + private List getElements() { + groups.clear(); + Set systemStyles = MindMapUI.getResourceManager() + .getSystemStyleSheet() + .getStyles(IStyleSheet.AUTOMATIC_STYLES); + Set userStyles = MindMapUI.getResourceManager() + .getUserStyleSheet().getAllStyles(); + + for (IStyle style : systemStyles) { + StyleGroup group = getGroup(style); + group.addStyle(style); + } + for (IStyle style : userStyles) { + StyleGroup group = getGroup(style); + group.addStyle(style); + } + return groups; + } + + public static StyleGalleryCore getInstance() { + return instance; + } + } + + private class StyleCategorizedLabelProvider extends CategorizedLabelProvider + implements IToolTipProvider, IFontProvider { + + @Override + public String getText(Object element) { + if (element instanceof IStyle) { + IStyle style = (IStyle) element; + return style.getName(); + } else if (element instanceof StyleGroup) + return ((StyleGroup) element).getName(); + return super.getText(element); + } + + @Override + public Image getImage(Object element) { + if (element instanceof IStyle) { + final IStyle style = (IStyle) element; + Properties properties = StyleResourceManagerViewer.this + .getProperties(); + + ImageData imageData = cachedImageData.get(style.getId()); + if (imageData == null) { + final Dimension size = (Dimension) properties + .get(GalleryViewer.FrameContentSize); + Image image = new Image(Display.getDefault(), size.width, + size.height); + GC gc = new GC(image); + Graphics graphics = new SWTGraphics(gc); + StyleFigure figure = new StyleFigure(); + figure.setStyle(style); + figure.setSize(size); + figure.paint(graphics); + + imageData = image.getImageData(); + cachedImageData.put(style.getId(), imageData); + image.dispose(); + gc.dispose(); + graphics.dispose(); + } + + ImageDescriptor imageDescriptor = ImageDescriptor + .createFromImageData(imageData); + return getResourceManager().createImage(imageDescriptor); + } + return super.getImage(element); + } + + public String getToolTip(Object element) { + + if (element != null && element instanceof IStyle) { + IStyle style = (IStyle) element; + String typeName = style.getType(); + String styleName = getText(style); + return typeName + "-" + styleName; //$NON-NLS-1$ + } + + return ""; //$NON-NLS-1$ + } + + @Override + public Font getFont(Object element) { + + FontData data = getContainer().getFont().getFontData()[0]; + if (Util.isMac()) { + data.setHeight(12); + } else { + data.setHeight(9); + } + data.setStyle(SWT.NONE); + + FontDescriptor fontDescriptor = FontDescriptor.createFrom(data); + + return getResourceManager().createFont(fontDescriptor); + } + } + + private static class StyleCategorizedContentProvider + implements ITreeContentProvider { + + public void dispose() { + + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + + } + + public Object[] getElements(Object inputElement) { + if (inputElement instanceof StyleGalleryCore) + return ((StyleGalleryCore) inputElement).getElements() + .toArray(); + else + return null; + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof StyleGalleryCore) + return ((StyleGalleryCore) parentElement).getElements() + .toArray(); + else if (parentElement instanceof StyleGroup) + return ((StyleGroup) parentElement).getItems().toArray(); + else + return null; + } + + public Object getParent(Object element) { + StyleGalleryCore styleGalleryCore = StyleGalleryCore.getInstance(); + if (element instanceof IStyle) + return styleGalleryCore.getGroup((IStyle) element); + else if (element instanceof StyleGroup) + return styleGalleryCore; + else + return null; + } + + public boolean hasChildren(Object element) { + return element instanceof StyleGroup + || element instanceof StyleGalleryCore; + } + + } + + private class StyleNestedViewerNameEditTool extends GalleryEditTool { + + protected IDocument getTextContents(IPart source) { + return new org.eclipse.jface.text.Document( + ((IStyle) source.getModel()).getName()); + } + + protected void handleTextModified(IPart source, IDocument document) { + //FIXME + ((IStyle) source.getModel()).setName(document.get()); + MindMapUI.getResourceManager().saveUserStyleSheet(); + } + + protected void hookEditor(FloatingTextEditor editor) { + super.hookEditor(editor); + getHelper().setPrefWidth( + FRAME_WIDTH + DEFAULT_FLOATING_TEXT_EDITOR_WIDTH_EXPAND); + } + + } + + @Override + public void createControl(Composite container) { + super.createControl(container); + setContentProvider(new StyleCategorizedContentProvider()); + setLabelProvider(new StyleCategorizedLabelProvider()); + EditDomain domain = new EditDomain(); + domain.installTool(GEF.TOOL_SELECT, + new ResourceCategorizedSelectTool()); + setEditDomain(domain); + initProperties(); + createControl(container, SWT.WRAP); + getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + setInput(StyleGalleryCore.getInstance()); + + } + + @Override + protected void initNestedGalleryViewer(GalleryViewer galleryViewerer) { + super.initNestedGalleryViewer(galleryViewerer); + Properties properties = galleryViewerer.getProperties(); + properties.set(GalleryViewer.HideTitle, Boolean.FALSE); + galleryViewerer.getEditDomain().installTool(GEF.TOOL_EDIT, + new StyleNestedViewerNameEditTool()); + } + + @Override + protected void initProperties() { + super.initProperties(); + Properties properties = getProperties(); + properties.set(GalleryViewer.FrameContentSize, + new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); + } + + @Override + protected void configureSection(Section section, Object category) { + if (category instanceof StyleGroup) { + createSectionTextClient(section, + MindMapMessages.StyleResourceManagerViewer_AddSection_title, + category); + } + } + + @Override + protected void handleClickSectionTextClient(Object category) { + if (category instanceof StyleGroup) { + StyleGroup group = (StyleGroup) category; + + final IStyle dummyStyle = MindMapUI.getResourceManager() + .getSystemStyleSheet().createStyle(group.type); + openStyleEditDialog(dummyStyle); + } + } + + protected void editStyle() { + IStructuredSelection selection = (IStructuredSelection) getSelection(); + for (Object obj : selection.toArray()) { + if (obj instanceof IStyle) { + openStyleEditDialog((IStyle) obj); + } + } + } + + private void openStyleEditDialog(final IStyle style) { + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + final IHandlerService handlers = (IHandlerService) window + .getService(IHandlerService.class); + final ICommandService commands = (ICommandService) window + .getService(ICommandService.class); + if (handlers == null || commands == null) + return; + + final Command command = commands.getCommand(EDIT_STYLE_COMMAND_ID); + if (command == null || !command.isDefined()) + return; + + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + IParameter param = command + .getParameter(IMindMapCommandConstants.RESOURCE_URI); + if (param == null) + return; + + ParameterizedCommand pc = new ParameterizedCommand(command, + new Parameterization[] { new Parameterization(param, + MindMapUI.getResourceManager() + .toResourceURI(style)) }); + handlers.executeCommand(pc, null); + } + }); + } + + public void startEditing(IStyle style) { + List styleGroups = StyleGalleryCore.getInstance() + .getElements(); + for (StyleGroup styleGroup : styleGroups) { + List styles = styleGroup.getItems(); + if (styles.contains(style)) { + GalleryViewer galleryViewer = getNestedViewer(styleGroup); + EditDomain domain = galleryViewer.getEditDomain(); + ITool tool = domain.getDefaultTool(); + + ((GallerySelectTool) tool).getStatus().setStatus(GEF.ST_ACTIVE, + true); + domain.handleRequest(GEF.REQ_EDIT, (IViewer) galleryViewer); + break; + } + } + } + + protected GalleryViewer createNestedViewer() { + return new StyleGalleryViewer(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/TemplateResourceManagerPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/TemplateResourceManagerPage.java new file mode 100644 index 000000000..471e01416 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/TemplateResourceManagerPage.java @@ -0,0 +1,281 @@ +package org.xmind.ui.internal.resourcemanager; + +import java.io.File; +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.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.jface.viewers.ISelection; +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.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.e4models.IContextRunnable; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.resourcemanager.TemplateResourceManagerViewer.TemplateGalleryCore; +import org.xmind.ui.internal.utils.ResourceUtils; +import org.xmind.ui.mindmap.IResourceManagerListener; +import org.xmind.ui.mindmap.ITemplate; +import org.xmind.ui.mindmap.ITemplateGroup; +import org.xmind.ui.mindmap.MindMapUI; + +public class TemplateResourceManagerPage extends ResourceManagerDialogPage + implements IResourceManagerListener { + + private static final int IMPORT_BUTTON_ID = IDialogConstants.CLIENT_ID + 1; + private static final String IMPORT_RESOURCE_BUNDLE_COMMAND_ID = "org.xmind.ui.command.importXMindResourceBundle"; //$NON-NLS-1$ + private TemplateResourceManagerViewer viewer; + + @Override + protected ResourceManagerViewer createViewer() { + viewer = new TemplateResourceManagerViewer(); + MindMapUI.getResourceManager().addResourceManagerListener(this); + return viewer; + } + + @Override + public void dispose() { + MindMapUI.getResourceManager().removeResourceManagerListener(this); + super.dispose(); + } + + public void userTemplateAdded(ITemplate template) { + if (!(template instanceof ITemplate)) + return; + if (viewer == null || viewer.getControl() == null + || viewer.getControl().isDisposed()) + return; + + viewer.refresh(); + viewer.reveal(TemplateGalleryCore.getInstance() + .getGroupByName(TemplateGalleryCore.USER_GROUP_NAME)); + viewer.setSelection(new StructuredSelection(template)); + } + + public void userTemplateRemoved(ITemplate template) { + if (template instanceof ITemplate) { + if (viewer == null || viewer.getControl() == null + || viewer.getControl().isDisposed()) + return; + viewer.refresh(); + } + } + + @Override + protected void createButtonsForButtonBar(Composite composite) { + Button importButton = createButton(composite, IMPORT_BUTTON_ID, + MindMapMessages.TemplateResourceManagerPage_Import_button, + false); + + final IAction addTemplateAction = getAddTemplateAction(); + importButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + addTemplateAction.run(); + } + }); + } + + private IAction getAddTemplateAction() { + Action addTemplateAction = new Action( + MindMapMessages.TemplateResourceManagerPage_AddTemplates_label) { + @Override + public void run() { + FileDialog dialog = new FileDialog( + Display.getCurrent().getActiveShell(), 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$ + MindMapMessages.TemplateResourceManagerPage_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( + MindMapMessages.TemplateResourceManagerPage_AddTemplates_tooltip); + + return addTemplateAction; + } + + @Override + protected void registerRunnable(IEclipseContext eclipseContext) { + super.registerRunnable(eclipseContext); + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_DELETE, //$NON-NLS-1$ + new IContextRunnable() { + + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + List templates = getSelectedTemplates(); + if (templates.isEmpty()) { + return; + } + StringBuilder sb = new StringBuilder( + templates.size() * 10); + for (ITemplate template : templates) { + if (sb.length() > 0) { + sb.append(','); + sb.append(' '); + } + sb.append('\''); + sb.append(template.getName()); + sb.append('\''); + } + if (!MessageDialog.openConfirm( + viewer.getControl().getShell(), + MindMapMessages.TemplateResourceManagerPage_Delete_ConfirmDialog_title, + NLS.bind( + MindMapMessages.TemplateResourceManagerPage_Delete_ConfirmDialog_message, + sb.toString()))) { + return; + } + ResourceUtils.deleteTemplates(templates); + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + List templates = getSelectedTemplates(); + List sysTemplates = MindMapUI + .getResourceManager().getSystemTemplates(); + boolean canExecute = !templates.isEmpty(); + for (ITemplate template : templates) { + canExecute = canExecute + && !sysTemplates.contains(template); + } + + List sysGroups = MindMapUI + .getResourceManager().getSystemTemplateGroups(); + for (ITemplateGroup group : sysGroups) { + List gTemplates = group.getTemplates(); + for (ITemplate template : templates) + canExecute = canExecute + && !gTemplates.contains(template); + } + return canExecute; + } + }); + + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_DUPLICATE, //$NON-NLS-1$ + new IContextRunnable() { + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + List selectedTemplates = getSelectedTemplates(); + if (!selectedTemplates.isEmpty()) { + ResourceUtils + .duplicateTemplates(selectedTemplates); + } + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + List templates = getSelectedTemplates(); + boolean canExecute = !templates.isEmpty(); + return canExecute; + } + }); + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_RENAME, //$NON-NLS-1$ + new IContextRunnable() { + @Override + public void run() { + if (viewer != null && viewer.getControl() != null + && !viewer.getControl().isDisposed()) { + List selectedTemplates = getSelectedTemplates(); + if (selectedTemplates.size() == 1) { + ITemplate template = selectedTemplates.get(0); + viewer.startEditing(template); + } + } + } + + @Override + public boolean canExecute(IEclipseContext context, + String contextKey) { + List selectedTemplates = getSelectedTemplates(); + List systemTemplates = MindMapUI + .getResourceManager().getSystemTemplates(); + boolean canExecute = selectedTemplates.size() == 1; + for (ITemplate template : selectedTemplates) { + canExecute = canExecute + && !systemTemplates.contains(template); + } + List sysGroups = MindMapUI + .getResourceManager().getSystemTemplateGroups(); + for (ITemplateGroup group : sysGroups) { + List gTemplates = group.getTemplates(); + for (ITemplate template : selectedTemplates) + canExecute = canExecute + && !gTemplates.contains(template); + } + return canExecute; + } + }); + } + + private List getSelectedTemplates() { + ArrayList templates = 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()) { + templates.add((ITemplate) element); + } + } + } + return templates; + } + + @Override + protected String getContextMenuId() { + return IModelConstants.POPUPMENU_ID_RESOURCEMANAGER_TEMPLATE; + } + + @Override + public String getModelPageId() { + return IModelConstants.PAGE_ID_RESOURCE_MANAGER_TEMPLATE; + } + + @Override + public String getModelPageTitle() { + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/TemplateResourceManagerViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/TemplateResourceManagerViewer.java new file mode 100644 index 000000000..b79401984 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/TemplateResourceManagerViewer.java @@ -0,0 +1,322 @@ +package org.xmind.ui.internal.resourcemanager; + +import java.io.File; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +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.draw2d.SizeableImageFigure; +import org.xmind.gef.part.IPart; +import org.xmind.gef.tool.ITool; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.GalleryEditTool; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.gallery.IDecorationContext; +import org.xmind.ui.gallery.ILabelDecorator; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.TemplateGroup; +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; +import org.xmind.ui.texteditor.FloatingTextEditor; + +public class TemplateResourceManagerViewer extends ResourceManagerViewer { + + private static final int FRAME_WIDTH = 132; + private static final int FRAME_HEIGHT = 72; + + private class TemplateGalleryViewer extends GalleryViewer { + protected boolean isTitleEditable(IPart p) { + List userTemplates = MindMapUI.getResourceManager() + .getUserTemplates(); + return userTemplates.contains(p.getModel()); + } + } + + static class TemplateGalleryCore { + + static final String SYSTEM_GROUP_NAME = MindMapMessages.TemplateResourceManagerViewer_SystemGroup_name; + static final String USER_GROUP_NAME = MindMapMessages.TemplateResourceManagerViewer_UserGroup_name; + + private static TemplateGalleryCore instance = new TemplateGalleryCore(); + List groups = new ArrayList(); + + public static TemplateGalleryCore getInstance() { + return instance; + } + + private TemplateGalleryCore() { + + } + + public List getElements() { + groups.clear(); + IResourceManager resourceManager = MindMapUI.getResourceManager(); + + groups.addAll(resourceManager.getSystemTemplateGroups()); + + ITemplateGroup userGroup = new TemplateGroup(USER_GROUP_NAME, + resourceManager.getUserTemplates()); + if (!(userGroup.getTemplates().isEmpty())) + groups.add(userGroup); + return groups; + } + + public ITemplateGroup getGroupByName(String name) { + for (ITemplateGroup group : groups) + if (group.getName().equals(name)) + return group; + return null; + } + } + + private static class TemplateCategorizedContentProvider + implements ITreeContentProvider { + + public void dispose() { + + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + + } + + public Object[] getElements(Object inputElement) { + if (inputElement instanceof TemplateGalleryCore) + return ((TemplateGalleryCore) inputElement).getElements() + .toArray(); + else + return null; + } + + @SuppressWarnings("unchecked") + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof TemplateGalleryCore) + return ((TemplateGalleryCore) parentElement).getElements() + .toArray(); + else if (parentElement instanceof ITemplateGroup) + return ((ITemplateGroup) parentElement).getTemplates() + .toArray(); + else + return null; + } + + public Object getParent(Object element) { + TemplateGalleryCore templatesGalleryCore = TemplateGalleryCore + .getInstance(); + if (element instanceof ITemplate) { + for (ITemplateGroup group : templatesGalleryCore + .getElements()) { + if (group.getTemplates().contains(element)) + return group; + } + } else if (element instanceof List) + return TemplateGalleryCore.getInstance(); + + return null; + } + + public boolean hasChildren(Object element) { + return element instanceof List + || element instanceof TemplateGalleryCore; + } + + } + + private class TemplateCategorizedLabelProvider extends TemplateLabelProvider + implements ILabelDecorator, IFontProvider { + @Override + public String getText(Object element) { + if (element instanceof ITemplateGroup) + return ((ITemplateGroup) element).getName(); + else + return super.getText(element); + } + + @Override + public IFigure decorateFigure(IFigure figure, Object element, + IDecorationContext context) { + @SuppressWarnings("rawtypes") + List children = figure.getChildren(); + boolean needInitFigureContent = children.isEmpty(); + if (needInitFigureContent) { + SizeableImageFigure contentFigure = new SizeableImageFigure( + getImage(element)); + figure.add(contentFigure); + + if (context != null) { + figure.setLayoutManager(new Layout(context)); + boolean imageConstrained = Boolean.TRUE.equals( + context.getProperty(GalleryViewer.ImageConstrained, + false)); + boolean imageStretched = Boolean.TRUE.equals(context + .getProperty(GalleryViewer.ImageStretched, false)); + contentFigure.setConstrained(imageConstrained); + contentFigure.setStretched(imageStretched); + } + } + + return figure; + } + + @Override + protected void fireLabelProviderChanged( + LabelProviderChangedEvent event) { + super.fireLabelProviderChanged(event); + TemplateResourceManagerViewer.this.refresh(); + } + + @Override + public Font getFont(Object element) { + FontData fontData = TemplateResourceManagerViewer.this.font + .getFontData()[0]; + if (Util.isMac()) { + fontData.setHeight(12); + } else { + fontData.setHeight(9); + } + + FontDescriptor fontDescriptor = FontDescriptor.createFrom(fontData); + + return getResourceManager().createFont(fontDescriptor); + } + + } + + 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(FRAME_WIDTH); + } + } + + private Font font; + + public TemplateResourceManagerViewer() { + super(); + } + + @Override + public void createControl(Composite container) { + super.createControl(container); + this.font = container.getFont(); + + setContentProvider(new TemplateCategorizedContentProvider()); + setLabelProvider(new TemplateCategorizedLabelProvider()); + EditDomain domain = new EditDomain(); + domain.installTool(GEF.TOOL_SELECT, + new ResourceCategorizedSelectTool()); + setEditDomain(domain); + initProperties(); + createControl(container, SWT.WRAP); + getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + setInput(TemplateGalleryCore.getInstance()); + } + + @Override + protected void initProperties() { + super.initProperties(); + Properties properties = getProperties(); + properties.set(GalleryViewer.FrameContentSize, + new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); + } + + @Override + protected void initNestedGalleryViewer(GalleryViewer galleryViewerer) { + super.initNestedGalleryViewer(galleryViewerer); + galleryViewerer.getEditDomain().installTool(GEF.TOOL_EDIT, + new TemplateNameEditTool()); + } + + public void startEditing(ITemplate template) { + Object input = getInput(); + if (input instanceof TemplateGalleryCore) { + List groups = ((TemplateGalleryCore) input) + .getElements(); + 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; + } + + //if this name has already exist. + List userTemplates = MindMapUI.getResourceManager() + .getUserTemplates(); + for (ITemplate t : userTemplates) { + if (newName.equals(t.getName())) { + return false; + } + } + + // delete old file, and create a new. + URI uri = template.getSourceWorkbookURI(); + File sourceFile = URIUtil.toFile(uri); + + String newPath = sourceFile.getParent() + + System.getProperty("file.separator") + newName //$NON-NLS-1$ + + FileUtils.getExtension(sourceFile.getAbsolutePath()); + sourceFile.renameTo(new File(newPath)); + + ((TemplateCategorizedLabelProvider) getLabelProvider()) + .fireLabelProviderChanged(new LabelProviderChangedEvent( + getLabelProvider(), template)); + return true; + } + + protected GalleryViewer createNestedViewer() { + return new TemplateGalleryViewer(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ThemeResourceManagerPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ThemeResourceManagerPage.java new file mode 100644 index 000000000..49ce33443 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ThemeResourceManagerPage.java @@ -0,0 +1,452 @@ +package org.xmind.ui.internal.resourcemanager; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; + +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IParameter; +import org.eclipse.core.commands.NotEnabledException; +import org.eclipse.core.commands.NotHandledException; +import org.eclipse.core.commands.Parameterization; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.core.commands.common.NotDefinedException; +import org.eclipse.core.runtime.SafeRunner; +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.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.UIEvents; +import org.eclipse.jface.dialogs.IDialogConstants; +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.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.IHandlerService; +import org.osgi.service.event.Event; +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.MindMapMessages; +import org.xmind.ui.internal.e4models.IContextRunnable; +import org.xmind.ui.internal.e4models.IModelConstants; +import org.xmind.ui.internal.editor.MindMapEditor; +import org.xmind.ui.internal.handlers.IMindMapCommandConstants; +import org.xmind.ui.internal.utils.ResourceUtils; +import org.xmind.ui.mindmap.MindMapUI; + +public class ThemeResourceManagerPage extends ResourceManagerDialogPage + implements ICoreEventListener, IPageChangedListener { + + private static final String EDIT_THEME_COMMAND_ID = "org.xmind.ui.command.theme.edit"; //$NON-NLS-1$ + private static final String NEW_THEME_COMMAND_ID = "org.xmind.ui.command.newTheme"; //$NON-NLS-1$ + private final static int NEW_THEME_BUTTON_ID = IDialogConstants.CLIENT_ID + + 1; + private final static int EDIT_THEME_BUTTON_ID = IDialogConstants.CLIENT_ID + + 2; + + private CoreEventRegister coreEventRegister; + private Button newThemeButton; + private Button editThemeButton; + private ThemeResourceManagerViewer viewer; + + private IGraphicalEditor sourceEditor; + private ICoreEventRegister topicRegister = null; + private ITopic rootTopic; + + @Override + protected ResourceManagerViewer createViewer() { + viewer = new ThemeResourceManagerViewer(); + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection sel = (IStructuredSelection) selection; + Object obj = sel.getFirstElement(); + if (obj != null && obj instanceof IStyle + && IStyle.THEME.equals(((IStyle) obj).getType())) { + editThemeButton.setEnabled(true); + return; + } + } + editThemeButton.setEnabled(false); + } + }); + registerCoreEvent(); + return viewer; + } + + @Override + protected void registerRunnable(IEclipseContext eclipseContext) { + super.registerRunnable(eclipseContext); + + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_RENAME, //$NON-NLS-1$ + 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; + } + }); + + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_DUPLICATE, //$NON-NLS-1$ + 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; + } + + }); + + eclipseContext.set( + getId() + "/" + IModelConstants.KEY_MODEL_PART_DELETE, //$NON-NLS-1$ + 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(); + IStyleSheet userThemeSheet = MindMapUI + .getResourceManager().getUserThemeSheet(); + Set styles = userThemeSheet + .getStyles(IStyleSheet.MASTER_STYLES); + boolean canExecute = !themes.isEmpty(); + for (IStyle theme : themes) { + canExecute = canExecute && styles.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; + } + + @Override + protected void createButtonsForButtonBar(final Composite composite) { + final ThemeResourceManagerViewer themeViewer = (ThemeResourceManagerViewer) viewer; + newThemeButton = createButton(composite, NEW_THEME_BUTTON_ID, + MindMapMessages.ThemeResourceManagerPage_New_button, false); + newThemeButton.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent e) { + composite.getShell().getDisplay().syncExec(new Runnable() { + public void run() { + newTheme(); + } + }); + } + }); + editThemeButton = createButton(composite, EDIT_THEME_BUTTON_ID, + MindMapMessages.ThemeResourceManagerPage_Edit_button, false); + editThemeButton.setEnabled(false); + editThemeButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + IStructuredSelection selection = (IStructuredSelection) themeViewer + .getSelection(); + Object[] objs = selection.toArray(); + + for (Object obj : objs) + if (obj instanceof IStyle) { + IStyle theme = (IStyle) obj; + if (IStyle.THEME.equals(theme.getType())) + editTheme(theme); + } + } + }); + } + + private void newTheme() { + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + final IHandlerService handlerService = (IHandlerService) window + .getService(IHandlerService.class); + try { + handlerService.executeCommand(NEW_THEME_COMMAND_ID, null); + } catch (ExecutionException e) { + e.printStackTrace(); + } catch (NotDefinedException e) { + e.printStackTrace(); + } catch (NotEnabledException e) { + e.printStackTrace(); + } catch (NotHandledException e) { + e.printStackTrace(); + } + + } + + private void editTheme(final IStyle theme) { + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + final IHandlerService handlers = (IHandlerService) window + .getService(IHandlerService.class); + final ICommandService commands = (ICommandService) window + .getService(ICommandService.class); + if (handlers == null || commands == null) + return; + + final Command command = commands.getCommand(EDIT_THEME_COMMAND_ID); + if (command == null || !command.isDefined()) + return; + + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + IParameter param = command + .getParameter(IMindMapCommandConstants.RESOURCE_URI); + if (param == null) + return; + + ParameterizedCommand pc = new ParameterizedCommand(command, + new Parameterization[] { new Parameterization(param, + MindMapUI.getResourceManager() + .toResourceURI(theme)) }); + handlers.executeCommand(pc, null); + } + }); + } + + private void registerCoreEvent() { + ICoreEventSupport ces = (ICoreEventSupport) MindMapUI + .getResourceManager().getUserThemeSheet() + .getAdapter(ICoreEventSupport.class); + if (ces != null) { + coreEventRegister = new CoreEventRegister(this); + coreEventRegister.setNextSupport(ces); + coreEventRegister.register(Core.StyleAdd); + coreEventRegister.register(Core.StyleRemove); + coreEventRegister.register(Core.TitleText); + coreEventRegister.register(Core.Name); + } + } + + @Inject + @Optional + public void activePartChanged( + @UIEventTopic(UIEvents.UILifeCycle.ACTIVATE) Event event) { + Object element = event.getProperty(UIEvents.EventTags.ELEMENT); + if (!(element instanceof MPart)) + return; + + MPart part = (MPart) element; + final IEditorPart editorPart = part.getContext().get(IEditorPart.class); + if (editorPart instanceof MindMapEditor) { + Display.getCurrent().asyncExec(new Runnable() { + public void run() { + setEditor((MindMapEditor) editorPart); + } + }); + } + } + + 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)); + } + } + + private ITopic findRootTopic(IGraphicalEditorPage page) { + ISheet sheet = page.getAdapter(ISheet.class); + if (sheet != null) + return sheet.getRootTopic(); + + return null; + } + + 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)); + } + }); + } + + @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 (coreEventRegister != null) { + coreEventRegister.unregisterAll(); + coreEventRegister = null; + } + if (topicRegister != null) { + topicRegister.unregisterAll(); + topicRegister = null; + } + if (sourceEditor != null) { + sourceEditor.removePageChangedListener(this); + sourceEditor = null; + } + super.dispose(); + } + + @Override + protected String getContextMenuId() { + return IModelConstants.POPUPMENU_ID_RESOURCEMANAGER_THEME; + } + + @Override + public String getModelPageId() { + return IModelConstants.PAGE_ID_RESOURCE_MANAGER_THEME; + } + + @Override + public String getModelPageTitle() { + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ThemeResourceManagerViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ThemeResourceManagerViewer.java new file mode 100644 index 000000000..b5512a473 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/resourcemanager/ThemeResourceManagerViewer.java @@ -0,0 +1,246 @@ +package org.xmind.ui.internal.resourcemanager; + +import java.util.List; +import java.util.Set; + +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.util.Util; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.gef.EditDomain; +import org.xmind.gef.GEF; +import org.xmind.gef.IViewer; +import org.xmind.gef.part.IPart; +import org.xmind.gef.tool.ITool; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.GalleryEditTool; +import org.xmind.ui.gallery.GallerySelectTool; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.internal.views.ThemeGroupCore; +import org.xmind.ui.internal.views.ThemeGroupCore.CategorizedThemeGroup; +import org.xmind.ui.internal.views.ThemeLabelProvider; +import org.xmind.ui.mindmap.IResourceManager; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.texteditor.FloatingTextEditor; + +public class ThemeResourceManagerViewer extends ResourceManagerViewer { + + private static final int FRAME_HEIGHT = 72; + private static final int FRAME_WIDTH = 132; + + private class ThemeGalleryViewer extends GalleryViewer { + protected boolean isTitleEditable(IPart p) { + IStyleSheet styleSheet = MindMapUI.getResourceManager() + .getUserThemeSheet(); + return styleSheet == null ? false + : styleSheet.getAllStyles().contains(p.getModel()); + } + } + + private class ThemeCategorizedContentProvider + implements ITreeContentProvider { + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + + public Object[] getElements(Object inputElement) { + return ((ThemeGroupCore) inputElement).getThemeGroups().toArray(); + } + + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof CategorizedThemeGroup) { + return ((CategorizedThemeGroup) parentElement).getItems() + .toArray(); + } + return null; + } + + public Object getParent(Object element) { + if (element instanceof CategorizedThemeGroup) { + return ThemeGroupCore.getInstance(); + } else if (element instanceof IStyle) { + List themeGroups = ThemeGroupCore + .getInstance().getThemeGroups(); + for (CategorizedThemeGroup themeGroup : themeGroups) { + List styles = themeGroup.getItems(); + if (styles.contains(element)) { + return themeGroup; + } + } + } + return null; + } + + public boolean hasChildren(Object element) { + return element instanceof ThemeGroupCore + || element instanceof CategorizedThemeGroup; + } + + } + + private class ThemeCategorizedLabelProvider extends ThemeLabelProvider + implements IFontProvider { + public String getText(Object element) { + if (element instanceof CategorizedThemeGroup) { + return ((CategorizedThemeGroup) element).getName(); + } else if (element instanceof IStyle + && IStyle.THEME.equals(((IStyle) element).getType())) { + return ((IStyle) element).getName(); + } + return super.getText(element); + } + + @Override + public Font getFont(Object element) { + FontData data = getContainer().getFont().getFontData()[0]; + if (Util.isMac()) { + data.setHeight(12); + } else { + data.setHeight(9); + } + data.setStyle(SWT.NONE); + FontDescriptor fontDescriptor = FontDescriptor.createFrom(data); + return getResourceManager().createFont(fontDescriptor); + } + + } + + class ThemeNestedGalleryViewer extends GalleryViewer { + protected boolean isTitleEditable(IPart p) { + + if (p.getModel() instanceof IStyle) { + IStyle style = (IStyle) p.getModel(); + final IResourceManager rm = MindMapUI.getResourceManager(); + Set systemThemeSets = rm.getUserThemeSheet() + .getStyles(IStyleSheet.MASTER_STYLES); + return systemThemeSets.contains(style); + } + return false; + } + } + + private class ThemeNestedViewerNameEditTool extends GalleryEditTool { + + protected IDocument getTextContents(IPart source) { + return new org.eclipse.jface.text.Document( + ((IStyle) source.getModel()).getName()); + } + + protected void handleTextModified(IPart source, IDocument document) { + ((IStyle) source.getModel()).setName(document.get()); + MindMapUI.getResourceManager().saveUserThemeSheet(); + ThemeResourceManagerViewer.this.refresh(); + } + + protected void hookEditor(FloatingTextEditor editor) { + super.hookEditor(editor); + getHelper().setPrefWidth( + FRAME_WIDTH + DEFAULT_FLOATING_TEXT_EDITOR_WIDTH_EXPAND); + } + + } + + @Override + public void createControl(Composite container) { + super.createControl(container); + setContentProvider(new ThemeCategorizedContentProvider()); + setLabelProvider(new ThemeCategorizedLabelProvider()); + EditDomain domain = new EditDomain(); + domain.installTool(GEF.TOOL_SELECT, + new ResourceCategorizedSelectTool()); + setEditDomain(domain); + initProperties(); + createControl(container, SWT.WRAP); + getControl() + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + setInput(ThemeGroupCore.getInstance()); + } + + @Override + protected void initNestedGalleryViewer(GalleryViewer galleryViewerer) { + super.initNestedGalleryViewer(galleryViewerer); + galleryViewerer.getEditDomain().installTool(GEF.TOOL_EDIT, + new ThemeNestedViewerNameEditTool()); + } + + @Override + protected void initProperties() { + super.initProperties(); + Properties properties = getProperties(); + properties.set(GalleryViewer.FrameContentSize, + new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); + } + + protected ITool createNestedViewerEditTool() { + return new ThemeNestedViewerNameEditTool(); + } + + public void update(Object[] elements) { + Object[] themeGroupList = ((ThemeCategorizedContentProvider) getContentProvider()) + .getElements(getInput()); + for (Object tg : themeGroupList) { + CategorizedThemeGroup themeGroup = (CategorizedThemeGroup) tg; + GalleryViewer galleryViewer = getNestedViewer(themeGroup); + galleryViewer.update(elements); + } + } + + public void startEditing(IStyle theme) { + List themeGroups = ThemeGroupCore.getInstance() + .getThemeGroups(); + for (CategorizedThemeGroup themeGroup : themeGroups) { + List styles = themeGroup.getItems(); + if (styles.contains(theme)) { + GalleryViewer galleryViewer = getNestedViewer(themeGroup); + EditDomain domain = galleryViewer.getEditDomain(); + ITool tool = domain.getDefaultTool(); + + ((GallerySelectTool) tool).getStatus().setStatus(GEF.ST_ACTIVE, + true); + domain.handleRequest(GEF.REQ_EDIT, (IViewer) galleryViewer); + break; + } + } + } + + public void selectDefault() { + List categories = getCategories(); + if (categories == null || categories.isEmpty() + || !(categories.get(0) instanceof CategorizedThemeGroup)) { + return; + } + Object defaultCategory = null; + for (Object category : getCategories()) { + if ("default".equals(((CategorizedThemeGroup) category).getId())) { //$NON-NLS-1$ + defaultCategory = category; + setSelectionToCategory(category, new StructuredSelection( + MindMapUI.getResourceManager().getDefaultTheme()), + true); + } else { + setSelectionToCategory(category, StructuredSelection.EMPTY, + false); + } + } + reveal(defaultCategory); + } + + protected GalleryViewer createNestedViewer() { + return new ThemeGalleryViewer(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/LinearGradient.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/LinearGradient.java index e964a8310..2e590a3e1 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/LinearGradient.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/LinearGradient.java @@ -8,9 +8,7 @@ import org.w3c.dom.NodeList; /** - * * @author Enki Xiong - * */ class LinearGradient implements SVGDefinition { @@ -106,7 +104,7 @@ private static Stop parseStop(Element ele) { if (opacity != null && !opacity.equals("")) //$NON-NLS-1$ stop.setOpacity(Float.valueOf(opacity)); stop.setOffset( - Integer.parseInt(ele.getAttribute(SVGDefinitionConstants.OFFSET) + Float.parseFloat(ele.getAttribute(SVGDefinitionConstants.OFFSET) .split(SVGDefinitionConstants.HUNDRED_PERCENT)[0])); return stop; } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/SVGImageData.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/SVGImageData.java index e72943d9e..98b4c4a6e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/SVGImageData.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/SVGImageData.java @@ -27,15 +27,14 @@ import org.w3c.dom.NodeList; /** - * * @author Enki Xiong - * */ public class SVGImageData { private boolean isInit; private boolean documentContainError = false; private String filePath; private Dimension size = new Dimension(-1, -1); + private static final Dimension INVALID_DIMENSION = new Dimension(-1, -1); private List list; public SVGImageData(String filePath) { @@ -185,12 +184,14 @@ private void paint(Graphics graphics, Display device) { */ public ImageData createImage(Dimension imageSize, RGB background) { + if (imageSize != null && imageSize.equals(INVALID_DIMENSION)) { + if (size.equals(INVALID_DIMENSION)) + init(); + imageSize = size; + } - Display device = Display.getDefault(); - if (imageSize == null || imageSize.width <= 0 || imageSize.height <= 0) - imageSize = new Dimension(16, 16); - - Image image = new Image(device, imageSize.width, imageSize.height); + Image image = new Image(Display.getDefault(), imageSize.width, + imageSize.height); Rectangle rect = new Rectangle(0, 0, imageSize.width, imageSize.height); paintImage(image, rect, background); @@ -212,7 +213,6 @@ public void paintImage(Image image, Rectangle paintArea, RGB background) { GC gc = new GC(image); SWTGraphics graphics = new SWTGraphics(gc); - paintFigure(graphics, paintArea, null, background); graphics.dispose(); @@ -262,7 +262,11 @@ public void paintFigure(Graphics graphics, Rectangle paintArea, boolean isNewManager = false; if (manager == null) { - manager = new LocalResourceManager(JFaceResources.getResources()); + ResourceManager resources = JFaceResources.getResources(); + resources = resources == null + ? JFaceResources.getResources(Display.getDefault()) + : resources; + manager = new LocalResourceManager(resources); isNewManager = true; } @@ -277,6 +281,9 @@ public void paintFigure(Graphics graphics, Rectangle paintArea, setResourceManager(manager); paint(graphics, Display.getDefault()); + /// reset scale for export + graphics.scale(1.0f); + if (isNewManager) manager.dispose(); diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/SVGShape.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/SVGShape.java index 990186fc6..8d7f0d73b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/SVGShape.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/svgsupport/SVGShape.java @@ -5,16 +5,19 @@ import org.eclipse.draw2d.Graphics; import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.util.Util; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.LineAttributes; import org.eclipse.swt.graphics.PathData; import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.internal.DPIUtil; import org.eclipse.swt.widgets.Display; import org.w3c.dom.Element; import org.xmind.gef.draw2d.geometry.PrecisionRectangle; import org.xmind.gef.draw2d.graphics.Path; +@SuppressWarnings("restriction") abstract class SVGShape implements SVGDefinition, Cloneable { public static final PrecisionRectangle INVALID_RECT = new PrecisionRectangle( @@ -88,6 +91,14 @@ private void paint(Graphics graphics, PrecisionRectangle rect, Path path) { if (rect == INVALID_RECT) { float[] rectNums = new float[4]; path.getBounds(rectNums); + if (Util.isWindows()) { + float[] autoScaleDown = DPIUtil.autoScaleDown(rectNums); + rectNums[0] = autoScaleDown[0]; + rectNums[1] = autoScaleDown[1]; + rectNums[2] = autoScaleDown[2]; + rectNums[3] = autoScaleDown[3]; + } + correctRect = new PrecisionRectangle(rectNums[0], rectNums[1], rectNums[2], rectNums[3]); } else { diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/ImageResizeTool.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/ImageResizeTool.java index fe578e594..4259ea821 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/ImageResizeTool.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/ImageResizeTool.java @@ -33,8 +33,8 @@ import org.xmind.gef.tool.ISourceTool; import org.xmind.ui.mindmap.IImagePart; -public class ImageResizeTool extends FeedbackResizeTool implements ISourceTool, - IStatusListener { +public class ImageResizeTool extends FeedbackResizeTool + implements ISourceTool, IStatusListener { private static final int MIN_IMAGE_WIDTH = 2; @@ -43,6 +43,7 @@ public class ImageResizeTool extends FeedbackResizeTool implements ISourceTool, private IImagePart source; public ImageResizeTool() { + setKeepRatio(true); getStatus().addStatusListener(this); } @@ -69,8 +70,8 @@ protected void initFeedback(IBendPointsFeedback feedback) { if (layer != null) { Image sourceImage = ((IImagePart) getSource()).getImage(); Rectangle sourceBounds = getSource().getFigure().getBounds(); - Image image = new Image(sourceImage.getDevice(), - sourceBounds.width, sourceBounds.height); + Image image = new Image(sourceImage.getDevice(), sourceBounds.width, + sourceBounds.height); GC gc = new GC(image); try { gc.setAntialias(SWT.ON); @@ -131,7 +132,7 @@ protected int constrainHeight(int h) { public void statusChanged(StatusEvent event) { if (event.key == GEF.ST_SHIFT_PRESSED) { - setKeepRatio(event.newValue); + setKeepRatio(!event.newValue); updateArea(getResultArea(), getCursorPosition(), null); } } @@ -143,4 +144,4 @@ protected void keepRatio(Dimension result, int w, int h, int initW, Integer.MAX_VALUE)); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/LabelEditTool.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/LabelEditTool.java index 3f63ec96c..9084c3ab7 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/LabelEditTool.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/LabelEditTool.java @@ -25,13 +25,11 @@ import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Display; import org.xmind.gef.GEF; import org.xmind.gef.Request; import org.xmind.gef.part.IGraphicalEditPart; import org.xmind.gef.part.IPart; import org.xmind.ui.mindmap.ILabelPart; -import org.xmind.ui.mindmap.IMindMapImages; import org.xmind.ui.mindmap.ITopicPart; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.texteditor.ContentProposalAdapter; @@ -58,7 +56,8 @@ protected Font getPreferredFont(IFigure figure) { return JFaceResources.getDefaultFont(); } - protected Rectangle calcPreferredBounds(IFigure figure, Rectangle bounds) { + protected Rectangle calcPreferredBounds(IFigure figure, + Rectangle bounds) { if (label == null || figure != label.getFigure()) { bounds = bounds.getTranslated(0, bounds.height); if (prefHeight < 0) { @@ -88,7 +87,6 @@ public ILabelPart getLabelPart() { /* * (non-Javadoc) - * * @see * org.xmind.gef.tool.EditTool#canEdit(org.xmind.gef.part.IGraphicalEditPart * ) @@ -107,8 +105,8 @@ public void setSource(IGraphicalEditPart source) { protected String getInitialText(IPart source) { if (label != null) return label.getLabelText(); - return MindMapUtils.getLabelText(((ITopicPart) source).getTopic() - .getLabels()); + return MindMapUtils + .getLabelText(((ITopicPart) source).getTopic().getLabels()); } protected Request createTextRequest(IPart source, IDocument document) { @@ -150,8 +148,8 @@ protected void hookEditorControl(FloatingTextEditor editor, if (contentProposalAdapter == null) { contentProposalAdapter = new FloatingTextEditorContentAssistAdapter( editor, proposalProvider); - contentProposalAdapter - .setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); + contentProposalAdapter.setProposalAcceptanceStyle( + ContentProposalAdapter.PROPOSAL_REPLACE); contentProposalAdapter.setPopupSize(new Point(180, 80)); final Image labelImage = createLabelProposalImage(); if (labelImage != null) { @@ -175,8 +173,7 @@ public void widgetDisposed(DisposeEvent e) { } private Image createLabelProposalImage() { - return MindMapUI.getImages().get(IMindMapImages.LABEL, true) - .createImage(false, Display.getCurrent()); + return null; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/MindMapDndTool.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/MindMapDndTool.java index 4da7c63e7..66d084e5a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/MindMapDndTool.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/MindMapDndTool.java @@ -52,7 +52,8 @@ public class MindMapDndTool extends GraphicalTool { private class RoundedRectDecoration extends PathShapeDecoration { - public Insets getPreferredInsets(IFigure figure, int width, int height) { + public Insets getPreferredInsets(IFigure figure, int width, + int height) { int lineWidth = getLineWidth(); return new Insets(lineWidth, lineWidth, lineWidth, lineWidth); } @@ -179,8 +180,9 @@ protected boolean isInsideTopicAllowed(DragDropEvent de) { protected boolean handleDragOver(DragDropEvent de) { if (acceptEvent(de)) { if (dummy != null) { - key = new ParentSearchKey(null, (IReferencedFigure) dummy - .getBranch().getTopicPart().getFigure(), + key = new ParentSearchKey( + null, (IReferencedFigure) dummy.getBranch() + .getTopicPart().getFigure(), getCursorPosition()); key.setFeedback(dummy.getBranch()); targetParent = updateTargetParent(); @@ -195,8 +197,8 @@ protected boolean handleDragOver(DragDropEvent de) { } private IBranchPart updateTargetParent() { - return getParentSearcher().searchTargetParent( - getTargetViewer().getRootPart(), key); + return getParentSearcher() + .searchTargetParent(getTargetViewer().getRootPart(), key); } private void updateWithParent(IBranchPart parent) { @@ -212,7 +214,8 @@ private void updateDummyWithParent(IBranchPart parent) { private void updateInventVisible(IBranchPart parent) { if (invent != null) - invent.setVisible(parent != null); + invent.setVisible(parent != null && !parent.getTopicPart() + .getFigure().containsPoint(getCursorPosition())); } private void updateInventPosition(Point cursorPosition) { @@ -231,7 +234,8 @@ private void updateInventPosition(Point cursorPosition) { } } - private Point calcInsertionPosition(IBranchPart parent, ParentSearchKey key) { + private Point calcInsertionPosition(IBranchPart parent, + ParentSearchKey key) { UpdateManager um = key.getFigure().getUpdateManager(); if (um != null) um.performValidation(); @@ -318,8 +322,8 @@ private Request createRequest(DragDropEvent de) { .getAdapter(ISheetPart.class); } req.setPrimaryTarget(target); - ITopicPart targetTopic = targetParent == null ? null : targetParent - .getTopicPart(); + ITopicPart targetTopic = targetParent == null ? null + : targetParent.getTopicPart(); if (targetTopic != null) { req.setParameter(GEF.PARAM_PARENT, targetTopic); int targetIndex = -1; @@ -335,8 +339,8 @@ private Request createRequest(DragDropEvent de) { } req.setParameter(GEF.PARAM_DROP_OPERATION, de.detail); if (targetParent != null) { - IStructure structure = targetParent.getBranchPolicy().getStructure( - targetParent); + IStructure structure = targetParent.getBranchPolicy() + .getStructure(targetParent); if (structure instanceof IMovableBranchStructureExtension) { ((IMovableBranchStructureExtension) structure) .decorateMoveInRequest(targetParent, key, null, req); @@ -372,11 +376,10 @@ public void run() throws Exception { BusyIndicator.showWhile( Display.getCurrent(), new Runnable() { - public void run() { - getDomain().handleRequest( - req); - } - }); + public void run() { + getDomain().handleRequest(req); + } + }); } }); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/MindMapSelectTool.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/MindMapSelectTool.java index 8b3f8b04c..f359b94ba 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/MindMapSelectTool.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/MindMapSelectTool.java @@ -100,6 +100,7 @@ import org.xmind.ui.branch.IBranchDoubleClickSupport; import org.xmind.ui.branch.IBranchMoveSupport; import org.xmind.ui.commands.DeleteMarkerCommand; +import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.internal.actions.ReplaceMarkerAction; import org.xmind.ui.internal.actions.ViewerAction; import org.xmind.ui.internal.editor.IMESupport; @@ -133,8 +134,12 @@ public class MindMapSelectTool extends SelectTool { + private static final int DRAG_DETECT_DELTA = 3; + private IBranchPart movingSourceBranch = null; + private boolean isDragDetect = false; + public MindMapSelectTool() { setContextId(MindMapUI.CONTEXT_MINDMAP_EDIT); } @@ -144,16 +149,34 @@ public String getType() { } public boolean handleMouseDown(MouseEvent me) { + isDragDetect = false; if (me.target instanceof IPlusMinusPart) { if (me.target.getParent() instanceof IBranchPart) { IBranchPart branch = (IBranchPart) me.target.getParent(); handleMouseDownOnPlusMinus(me, branch); return true; } + } else if (me.target instanceof IconTipPart) { + if (!me.leftOrRight) { + if (handleMouseDownOnIconTip(me)) { + return true; + } + } } return super.handleMouseDown(me); } + private boolean handleMouseDownOnIconTip(MouseEvent me) { + IconTipPart iconTip = (IconTipPart) me.target; + if (iconTip.getPopupMenu() == null) { + getStatus().setStatus(GEF.ST_MOUSE_PRESSED, true); + getStatus().setStatus(GEF.ST_MOUSE_RIGHT, !me.leftOrRight); + selectSingle(iconTip.getTopicPart()); + return true; + } + return false; + } + protected void handleMouseDownOnPlusMinus(MouseEvent me, IBranchPart branch) { getStatus().setStatus(GEF.ST_MOUSE_PRESSED, true); @@ -474,10 +497,27 @@ protected String getAttachmentAbsolutePath(ITopic topic, String uri) { } protected boolean handleMouseDrag(MouseDragEvent me) { + if (!isDragDetect) { + isDragDetect = shouldDragDetect(me); + } + if (!isDragDetect) { + return false; + } + movingSourceBranch = null; return super.handleMouseDrag(me); } + private boolean shouldDragDetect(MouseDragEvent me) { + if (me == null) { + return false; + } + + int delta = Math.abs(me.cursorLocation.x - me.startingLocation.x) + + Math.abs(me.cursorLocation.y - me.startingLocation.y); + return delta >= DRAG_DETECT_DELTA; + } + protected boolean canMove(IPart host, MouseDragEvent me) { boolean canMove = super.canMove(host, me); if (!canMove) { @@ -681,7 +721,6 @@ public void start(IGraphicalPart part) { /* * (non-Javadoc) - * * @see * org.xmind.gef.service.IRevealServiceListener#revealingStarted(org * .xmind.gef.service.RevealEvent) @@ -691,7 +730,6 @@ public void revealingStarted(RevealEvent event) { /* * (non-Javadoc) - * * @see * org.xmind.gef.service.IRevealServiceListener#revealingCanceled(org * .xmind.gef.service.RevealEvent) @@ -702,7 +740,6 @@ public void revealingCanceled(RevealEvent event) { /* * (non-Javadoc) - * * @see * org.xmind.gef.service.IRevealServiceListener#revealingFinished(org * .xmind.gef.service.RevealEvent) @@ -878,6 +915,15 @@ protected Request createAddAttachmentRequest(Request request, String[] fileNames = dialog.getFileNames(); List paths = new ArrayList(fileNames.length); for (String fileName : fileNames) { + if (fileName.contains(".")) { //$NON-NLS-1$ + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase(String.format("AttachmentFormatCount:%s", //$NON-NLS-1$ + fileName.toLowerCase().substring( + fileName.lastIndexOf('.') + 1))); + } else { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("AttachmentFormatCount:BlankFormat"); //$NON-NLS-1$ + } String path = new File(parentPath, fileName).getAbsolutePath(); paths.add(path); } @@ -1063,6 +1109,9 @@ private void drillDown(IViewer viewer, ISheet sheet, ITopic newRoot) { } private void initTopicRightNumber(ITopic newRoot) { + if (newRoot == null) + return; + String structureClass = newRoot.getStructureClass(); if ("org.xmind.ui.map.unbalanced".equals(structureClass) //$NON-NLS-1$ || structureClass == null) { @@ -1169,7 +1218,9 @@ protected boolean handleDragStarted(DragDropEvent de) { protected void showMarkerMenu(IMarkerPart target) { if (getTargetViewer() == null || getTargetViewer().getEditDomain() == null - || getTargetViewer().getEditDomain().getCommandStack() == null) + || getTargetViewer().getEditDomain().getCommandStack() == null + || "PresentationViewer" //$NON-NLS-1$ + .equals(getTargetViewer().getClass().getSimpleName())) return; MenuManager menuManager = new MenuManager(); @@ -1324,7 +1375,7 @@ private boolean handleNavScroll(Request request) { .intersect(contents.getBounds()); Rectangle clientArea = viewport.getClientArea(); Point center = ((IGraphicalViewer) viewer).getCenterPoint().getCopy(); - int d; + int d = 0; if (GEF.REQ_NAV_LEFT.equals(type)) { d = Math.min(MindMapUI.NAV_SCROLL_STEP, Math.abs(contentsBounds.x - clientArea.x)); @@ -1336,11 +1387,11 @@ private boolean handleNavScroll(Request request) { } else if (GEF.REQ_NAV_RIGHT.equals(type)) { d = Math.min(MindMapUI.NAV_SCROLL_STEP, Math.abs(contentsBounds.right() - clientArea.right())); - center.translate(d, 0); + center.translate(-d, 0); } else if (GEF.REQ_NAV_DOWN.equals(type)) { d = Math.min(MindMapUI.NAV_SCROLL_STEP, Math.abs(contentsBounds.bottom() - clientArea.bottom())); - center.translate(0, d); + center.translate(0, -d); } else { return false; } @@ -1363,4 +1414,4 @@ protected void handleEditRequest(Request request) { super.handleEditRequest(request); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/TopicMoveTool.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/TopicMoveTool.java index 2f300d231..476fea2e9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/TopicMoveTool.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/TopicMoveTool.java @@ -25,6 +25,7 @@ import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.Util; import org.eclipse.swt.graphics.Cursor; import org.xmind.core.ISummary; @@ -46,10 +47,12 @@ import org.xmind.ui.branch.IInsertableBranchStructureExtension; import org.xmind.ui.branch.ILockableBranchStructureExtension; import org.xmind.ui.branch.IMovableBranchStructureExtension; +import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.mindmap.IBranchPart; import org.xmind.ui.mindmap.IMindMapImages; import org.xmind.ui.mindmap.ITopicPart; import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.prefs.PrefConstants; import org.xmind.ui.tools.DummyMoveTool; import org.xmind.ui.tools.ITopicMoveToolHelper; import org.xmind.ui.tools.ParentSearchKey; @@ -60,10 +63,10 @@ public class TopicMoveTool extends DummyMoveTool implements IStatusListener { private class RoundedRectDecoration extends PathShapeDecoration { - public Insets getPreferredInsets(IFigure figure, int width, int height) { + public Insets getPreferredInsets(IFigure figure, int width, + int height) { int lineWidth = getLineWidth(); - return new Insets(lineWidth, lineWidth, lineWidth, - lineWidth); + return new Insets(lineWidth, lineWidth, lineWidth, lineWidth); } @Override @@ -105,9 +108,18 @@ protected void sketch(IFigure figure, Path shape, Rectangle box, private int specialIndex = -1; public TopicMoveTool() { + initMoveTopicMoveTool(); getStatus().addStatusListener(this); } + private void initMoveTopicMoveTool() { + IPreferenceStore prefStore = MindMapUIPlugin.getDefault() + .getPreferenceStore(); + boolean status = prefStore + .getBoolean(PrefConstants.MANUAL_LAYOUT_ALLOWED); + getStatus().setStatus(GEF.ST_FREE_MOVE_MODE, status); + } + public void setSource(IGraphicalEditPart source) { Assert.isTrue(source instanceof ITopicPart); super.setSource(source); @@ -211,8 +223,8 @@ private IFigure createInvent() { DecoratedShapeFigure figure = new DecoratedShapeFigure(); Point loc = getDummyStartLoc(); if (loc != null) - figure.setLocation(loc.getTranslated(-INVENT_WIDTH / 2, - -INVENT_HEIGHT / 2)); + figure.setLocation( + loc.getTranslated(-INVENT_WIDTH / 2, -INVENT_HEIGHT / 2)); figure.setSize(INVENT_WIDTH, INVENT_HEIGHT); figure.setDecoration(new RoundedRectDecoration()); @@ -229,8 +241,8 @@ private void collectDisabledBranches() { addDisabledPart(part); } List topics = MindMapUtils.getTopics(selectedParts); - Set ranges = MindMapUtils.findContainedRanges(topics, - true, false); + Set ranges = MindMapUtils.findContainedRanges(topics, true, + false); if (!ranges.isEmpty()) { for (ITopicRange r : ranges) { ITopic st = ((ISummary) r).getTopic(); @@ -287,9 +299,10 @@ protected void onMoving(Point currentPos, MouseDragEvent me) { } super.onMoving(currentPos, me); if (branchDummy != null) { - key = new ParentSearchKey(getSourceTopic(), - (IReferencedFigure) branchDummy.getBranch().getTopicPart() - .getFigure(), currentPos); + key = new ParentSearchKey( + getSourceTopic(), (IReferencedFigure) branchDummy + .getBranch().getTopicPart().getFigure(), + currentPos); key.setFeedback(branchDummy.getBranch()); targetParent = updateTargetParent(); if (specialIndex < 0) { @@ -378,8 +391,8 @@ private IBranchPart updateTargetParent() { IPart parent = getSourceBranch().getParent(); return parent instanceof IBranchPart ? (IBranchPart) parent : null; } - return getParentSearcher().searchTargetParent( - getTargetViewer().getRootPart(), key); + return getParentSearcher() + .searchTargetParent(getTargetViewer().getRootPart(), key); } private void updateWithParent(IBranchPart parent) { @@ -412,9 +425,8 @@ private void updateHelperWithParent(IBranchPart parent) { this.helper = newHelper; } if (helper != null) { - helper.update(parent, - isBranchMoved(parent, getSourceBranch(), key), key, - specialIndex); + helper.update(parent, isBranchMoved(parent, getSourceBranch(), key), + key, specialIndex); } } @@ -453,6 +465,8 @@ private boolean isFloatMove() { } private boolean isFreeMove() { + if (isFreeMovePattern()) + return true; if (isSpecialFreeMove()) return true; if (Util.isMac()) @@ -460,6 +474,16 @@ private boolean isFreeMove() { return getStatus().isStatus(GEF.ST_ALT_PRESSED); } + private boolean isFreeMovePattern() { + ITopicPart topicPart = getSourceParentTopic(); + ITopic topic = null; + if (topicPart != null) + topic = topicPart.getTopic(); + + return topic == null ? getStatus().isStatus(GEF.ST_FREE_MOVE_MODE) + : getStatus().isStatus(GEF.ST_FREE_MOVE_MODE) && topic.isRoot(); + } + private boolean isCopyMove() { if (Util.isMac()) return getStatus().isStatus(GEF.ST_ALT_PRESSED); @@ -524,6 +548,15 @@ protected void end() { unlockBranchStructures(getTargetViewer().getRootPart()); } + protected void suspend() { + if (helper != null) { + helper.deactivate(getDomain(), getTargetViewer()); + helper = null; + } + super.end(); + destroyInvent(); + } + private void destroyInvent(IFigure invent) { if (invent.getParent() != null) invent.getParent().remove(invent); @@ -546,7 +579,8 @@ protected Request createRequest() { if (!isFloatMove()) { index = getParentSearcher().getIndex(targetParentBranch, key); if (free) { - if (!isFreeable() && !isAlreadyFloat() && !isSpecialFreeMove()) { + if (!isFreeable() && !isAlreadyFloat() + && !isSpecialFreeMove()) { free = false; } } else { @@ -579,7 +613,8 @@ protected Request createRequest() { // fillTargets(request, getTargetViewer(), false); request.setPrimaryTarget(getSourceTopic()); request.setParameter(GEF.PARAM_POSITION, position); - request.setParameter(GEF.PARAM_POSITION_ABSOLUTE, getAbsolutePosition()); + request.setParameter(GEF.PARAM_POSITION_ABSOLUTE, + getAbsolutePosition()); request.setParameter(GEF.PARAM_POSITION_RELATIVE, Boolean.valueOf(relative)); request.setParameter(GEF.PARAM_PARENT, targetParent); @@ -685,4 +720,4 @@ public Cursor getCurrentCursor(Point pos, IPart host) { return super.getCurrentCursor(pos, host); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/TopicTitleEditTool.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/TopicTitleEditTool.java index 0b0b2ebd6..86166ba87 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/TopicTitleEditTool.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/tools/TopicTitleEditTool.java @@ -102,7 +102,6 @@ public String getType() { /* * (non-Javadoc) - * * @see * org.xmind.gef.tool.EditTool#canEdit(org.xmind.gef.part.IGraphicalEditPart * ) @@ -144,25 +143,27 @@ private void locateHandle(final Control control) { return; locatingHandle = true; - Display.getCurrent().asyncExec(new Runnable() { public void run() { - if (widthHandle == null || getTargetViewer() == null - || getTargetViewer().getControl() == null - || getTargetViewer().getControl().isDisposed() - || control.isDisposed()) - return; - - if (width < 0 && control.getBounds().width > 500) { - widthChanged = true; - getHelper().setPrefWidth(500); + try { + if (widthHandle == null || getTargetViewer() == null + || getTargetViewer().getControl() == null + || getTargetViewer().getControl().isDisposed() + || control.isDisposed()) + return; + + if (width < 0 && control.getBounds().width > 500) { + widthChanged = true; + getHelper().setPrefWidth(500); + } + Rectangle bounds = new Rectangle(control.getBounds()); + Point loc = getTargetViewer() + .computeToLayer(bounds.getLocation(), false); + widthHandle.setBounds(new Rectangle(loc.x + bounds.width, + loc.y, HANDLE_WIDTH, bounds.height)); + } finally { + locatingHandle = false; } - Rectangle bounds = new Rectangle(control.getBounds()); - Point loc = getTargetViewer().computeToLayer( - bounds.getLocation(), false); - widthHandle.setBounds(new Rectangle(loc.x + bounds.width, - loc.y, HANDLE_WIDTH, bounds.height)); - locatingHandle = false; } }); } @@ -193,7 +194,8 @@ protected boolean shouldFinishOnMouseDown(MouseEvent me) { } @Override - protected boolean openEditor(FloatingTextEditor editor, IDocument document) { + protected boolean openEditor(FloatingTextEditor editor, + IDocument document) { boolean opened = super.openEditor(editor, document); mouseDownOnHandle = false; draggingHandle = false; @@ -262,8 +264,9 @@ protected boolean handleMouseUp(MouseEvent me) { protected Request createTextRequest(IPart source, IDocument document) { Request request = super.createTextRequest(source, document); if (widthChanged) { - request.setParameter(MindMapUI.PARAM_PROPERTY_PREFIX - + Core.TitleWidth, getHelper().getPrefWidth()); + request.setParameter( + MindMapUI.PARAM_PROPERTY_PREFIX + Core.TitleWidth, + getHelper().getPrefWidth()); } return request; } @@ -283,9 +286,8 @@ private Point getScaled(Point p) { } public IFigure findToolTip(IPart source, Point position) { - if (!mouseDownOnHandle - && !draggingHandle - && (widthHandle != null && handleContains(widthHandle, position))) { + if (!mouseDownOnHandle && !draggingHandle && (widthHandle != null + && handleContains(widthHandle, position))) { return new Label(MindMapMessages.ModifyWrapWidth_toolTip0); } return super.getToolTip(source, position); @@ -298,4 +300,4 @@ public Cursor getCurrentCursor(Point pos, IPart host) { } return super.getCurrentCursor(pos, host); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/utils/CommandUtils.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/utils/CommandUtils.java new file mode 100644 index 000000000..65424a8fc --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/utils/CommandUtils.java @@ -0,0 +1,34 @@ +package org.xmind.ui.internal.utils; + +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.IHandlerService; + +public class CommandUtils { + + public static void executeCommand(String commandId, + IWorkbenchWindow window) { + if (window == null || commandId == null || commandId.equals("")) { //$NON-NLS-1$ + return; + } + + final IHandlerService hs = window.getService(IHandlerService.class); + final ICommandService cs = window.getService(ICommandService.class); + final Command command = cs.getCommand(commandId); + + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + + ParameterizedCommand pc = new ParameterizedCommand(command, + null); + hs.executeCommand(pc, null); + } + }); + + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/utils/E4Utils.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/utils/E4Utils.java new file mode 100644 index 000000000..b2f335c73 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/utils/E4Utils.java @@ -0,0 +1,80 @@ +package org.xmind.ui.internal.utils; + +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.IParameter; +import org.eclipse.core.commands.Parameterization; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.e4.core.contexts.IEclipseContext; +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.workbench.modeling.EPartService; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.handlers.IHandlerService; +import org.xmind.ui.internal.e4models.IContextRunnable; +import org.xmind.ui.internal.e4models.IModelConstants; + +public class E4Utils { + + public static final void showPart(String commandId, IWorkbenchWindow window, + final String partId, final String pageId, + final String partStackId) { + + final IHandlerService hs = window.getService(IHandlerService.class); + final ICommandService cs = window.getService(ICommandService.class); + final Command command = cs.getCommand(commandId); + SafeRunner.run(new SafeRunnable() { + public void run() throws Exception { + IParameter partIdParam = command.getParameter( + IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PART_ID); + IParameter pageIdParam = command.getParameter( + IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PAGE_ID); + IParameter stackIdParam = command.getParameter( + IModelConstants.KEY_MODEL_PART_COMMAND_PARAMETER_PARTSTACK_ID); + + if (partIdParam == null || pageIdParam == null + || stackIdParam == null) + return; + + Parameterization[] parameters = new Parameterization[] { + new Parameterization(partIdParam, partId), + new Parameterization(pageIdParam, pageId), + new Parameterization(stackIdParam, partStackId) }; + + ParameterizedCommand pc = new ParameterizedCommand(command, + parameters); + hs.executeCommand(pc, null); + } + }); + + } + + public static final MPart findPart(IWorkbenchWindow window, String partId) { + EPartService partService = window.getService(EPartService.class); + return partService.findPart(partId); + } + + public static final IEclipseContext getEclipseContext( + ExecutionEvent event) { + Object eclipseContext = HandlerUtil.getVariable(event, + IEclipseContext.class.getName()); + return (IEclipseContext) eclipseContext; + } + + public static final IContextRunnable getContextRunnable( + IEclipseContext context, String key) { + String pageId = (String) context + .get(IModelConstants.KEY_MODEL_PART_CURRENT_PAGE_ID); + String contextRunnableKey = pageId == null ? key : pageId + "/" + key; //$NON-NLS-1$ + Object contextRunnable = context.get(contextRunnableKey); + if (contextRunnable == null) { + contextRunnable = context.get(key); + } + return (contextRunnable instanceof IContextRunnable) + ? (IContextRunnable) contextRunnable : null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/utils/ResourceUtils.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/utils/ResourceUtils.java new file mode 100644 index 000000000..4039b68cc --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/utils/ResourceUtils.java @@ -0,0 +1,295 @@ +package org.xmind.ui.internal.utils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.SafeRunnable; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.xmind.core.Core; +import org.xmind.core.internal.ElementRegistry; +import org.xmind.core.marker.IMarker; +import org.xmind.core.marker.IMarkerGroup; +import org.xmind.core.marker.IMarkerSheet; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.core.util.FileUtils; +import org.xmind.core.util.Property; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.internal.dialogs.DialogUtils; +import org.xmind.ui.mindmap.IResourceManager; +import org.xmind.ui.mindmap.ITemplate; +import org.xmind.ui.mindmap.IWorkbookRef; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.style.Styles; +import org.xmind.ui.util.Logger; + +public class ResourceUtils { + + public static List duplicateStyles(List styles) { + ArrayList newStyles = new ArrayList(); + IStyleSheet styleSheet = MindMapUI.getResourceManager() + .getUserStyleSheet(); + for (IStyle styleDuplicated : styles) { + IStyle newStyle = styleSheet.createStyle(styleDuplicated.getType()); + Iterator ps = styleDuplicated.properties(); + while (ps.hasNext()) { + Property p = ps.next(); + newStyle.setProperty(p.key, p.value); + } + newStyle.setName(NLS.bind(MindMapMessages.ResourceUtil_Copy_name, + styleDuplicated.getName())); + styleSheet.addStyle(newStyle, IStyleSheet.NORMAL_STYLES); + + newStyles.add(newStyle); + } + MindMapUI.getResourceManager().saveUserStyleSheet(); + return newStyles; + } + + public static List duplicateThemes(List themes) { + ArrayList newThemes = new ArrayList(); + IStyleSheet styleSheet = MindMapUI.getResourceManager() + .getUserThemeSheet(); + for (IStyle styleDuplicated : themes) { + IStyle themeCreated = styleSheet + .createStyle(styleDuplicated.getType()); + themeCreated + .setName(NLS.bind(MindMapMessages.ResourceUtil_Copy_name, + styleDuplicated.getName())); + Iterator defaultStyles = styleDuplicated.defaultStyles(); + while (defaultStyles.hasNext()) { + Property p = defaultStyles.next(); + IStyle defaultStyle = styleDuplicated.getDefaultStyle(p.key); + if (defaultStyle != null) { + IStyle styleCreated = styleSheet.createStyle( + transformStyleFamilyToStyleType(p.key)); + Iterator ps = defaultStyle.properties(); + while (ps.hasNext()) { + Property next = ps.next(); + styleCreated.setProperty(next.key, next.value); + } + themeCreated.setDefaultStyleId(p.key, styleCreated.getId()); + styleSheet.addStyle(styleCreated, + IStyleSheet.AUTOMATIC_STYLES); + } + } + styleSheet.addStyle(themeCreated, IStyleSheet.MASTER_STYLES); + newThemes.add(themeCreated); + } + MindMapUI.getResourceManager().saveUserThemeSheet(); + return newThemes; + } + + private static String transformStyleFamilyToStyleType(String family) { + if (Styles.FAMILY_CENTRAL_TOPIC.equals(family) + || Styles.FAMILY_MAIN_TOPIC.equals(family) + || Styles.FAMILY_SUB_TOPIC.equals(family) + || Styles.FAMILY_SUMMARY_TOPIC.equals(family) + || Styles.FAMILY_FLOATING_TOPIC.equals(family) + || Styles.FAMILY_CALLOUT_TOPIC.equals(family)) + return IStyle.TOPIC; + else if (Styles.FAMILY_RELATIONSHIP.equals(family)) + return IStyle.RELATIONSHIP; + else if (Styles.FAMILY_BOUNDARY.equals(family)) + return IStyle.BOUNDARY; + else if (Styles.FAMILY_MAP.equals(family)) + return IStyle.MAP; + else if (Styles.FAMILY_SUMMARY.equals(family)) + return IStyle.SUMMARY; + return null; + } + + public static void deleteStyles(List styles) { + boolean isTheme = false; + for (IStyle style : styles) { + if (IStyle.THEME.equals(style.getType())) + isTheme = true; + IStyleSheet sheet = style.getOwnedStyleSheet(); + ElementRegistry elementRegistry = (ElementRegistry) sheet + .getAdapter(ElementRegistry.class); + elementRegistry.unregister(style); + sheet.removeStyle(style); + } + if (isTheme) + MindMapUI.getResourceManager().saveUserThemeSheet(); + else + MindMapUI.getResourceManager().saveUserStyleSheet(); + } + + public static boolean confirmToDeleteStyles(Shell shell, + List styles) { + StringBuilder sb = new StringBuilder(styles.size() * 10); + boolean isTheme = false; + for (IStyle style : styles) { + if (IStyle.THEME.equals(style.getType())) + isTheme = true; + if (sb.length() > 0) { + sb.append(','); + sb.append(' '); + } + sb.append('\''); + sb.append(style.getName()); + sb.append('\''); + } + String styleNames = sb.toString(); + return MessageDialog.openConfirm(shell, + NLS.bind(MindMapMessages.DeleteStyles_MessageDialog_title, + isTheme ? MindMapMessages.DeleteStyle_MessageDialog_themes + : MindMapMessages.DeleteStyle_MessageDialog_styles), + NLS.bind(MindMapMessages.DeleteStyle_MessageDialog_description, + styleNames)); + } + + public static void deleteTemplates(List templates) { + IResourceManager resourceManager = MindMapUI.getResourceManager(); + List userTemplates = resourceManager.getUserTemplates(); + for (ITemplate template : templates) + if (userTemplates.contains(template)) { + resourceManager.removeUserTemplate(template); + } + } + + public static List duplicateTemplates( + List templates) { + final ArrayList newTemplates = new ArrayList(); + + File tempFolder = new File( + Core.getWorkspace().getTempDir("transient-templates")); //$NON-NLS-1$ + tempFolder.mkdirs(); + + for (ITemplate template : templates) { + final File tempFile = new File(tempFolder, + template.getName() + " " //$NON-NLS-1$ + + MindMapMessages.ResourceUtil_Duplicate_name + + MindMapUI.FILE_EXT_TEMPLATE); + if (!tempFile.exists()) { + try { + tempFile.createNewFile(); + } catch (IOException e) { + } + } + final IWorkbookRef tempWR = MindMapUIPlugin.getDefault() + .getWorkbookRefFactory() + .createWorkbookRef(tempFile.toURI(), null); + final IWorkbookRef clonedWR = template.createWorkbookRef(); + SafeRunnable.run(new SafeRunnable() { + @Override + public void run() throws Exception { + NullProgressMonitor monitor = new NullProgressMonitor(); + try { + SubMonitor subMonitor = SubMonitor.convert(monitor, + 100); + clonedWR.open(subMonitor.newChild(30)); + try { + tempWR.importFrom(subMonitor.newChild(60), + clonedWR); + + /// Fix duplicate template, thumbnail lose. + tempWR.open(monitor); + tempWR.save(monitor); + } finally { + subMonitor.setWorkRemaining(10); + clonedWR.close(subMonitor.newChild(5)); + tempWR.close(subMonitor.newChild(5)); + } + } finally { + if (monitor != null) + monitor.done(); + } + + ITemplate newTemplate = MindMapUI.getResourceManager() + .addUserTemplateFromWorkbookURI(tempWR.getURI()); + newTemplates.add(newTemplate); + + if (tempFile != null && tempFile.exists()) { + tempFile.delete(); + } + } + }); + } + return newTemplates; + } + + public static void deleteMarkers(List markers) { + for (IMarker marker : markers) + marker.getParent().removeMarker(marker); + } + + public static List addMarkersFor(IMarkerGroup markerGroup) { + List newMarkers = new ArrayList(); + String[] sourcePaths = selectImageFile( + Display.getCurrent().getActiveShell()); + if (sourcePaths == null) + return newMarkers; + + IMarkerSheet ownedSheet = markerGroup.getOwnedSheet(); + for (String sourcePath : sourcePaths) { + if (imageValid(sourcePath)) { + String targetPath = null; + FileInputStream sourceFIS = null; + try { + sourceFIS = new FileInputStream(sourcePath); + targetPath = ownedSheet.allocateMarkerResource(sourceFIS, + sourcePath); + } catch (IOException e) { + Logger.log(e); + } finally { + if (sourceFIS != null) { + try { + sourceFIS.close(); + } catch (IOException e) { + Logger.log(e); + } + } + } + + if (targetPath != null) { + IMarker marker = ownedSheet.createMarker(targetPath); + marker.setName(FileUtils.getFileName(sourcePath)); + markerGroup.addMarker(marker); + newMarkers.add(marker); + } + + } + } + return newMarkers; + } + + private static String[] selectImageFile(Shell shell) { + FileDialog dialog = new FileDialog(shell, SWT.OPEN | SWT.MULTI); + DialogUtils.makeDefaultImageSelectorDialog(dialog, true); + String open = dialog.open(); + if (open == null) + return null; + String parent = dialog.getFilterPath(); + String[] fileNames = dialog.getFileNames(); + String[] paths = new String[fileNames.length]; + for (int i = 0; i < fileNames.length; i++) { + paths[i] = new File(parent, fileNames[i]).getAbsolutePath(); + } + return paths; + } + + private static boolean imageValid(String sourcePath) { + try { + new Image(Display.getCurrent(), sourcePath).dispose(); + return true; + } catch (Throwable e) { + } + return false; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/BlackBoxView.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/BlackBoxView.java index 946e0e062..84f3d56a6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/BlackBoxView.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/BlackBoxView.java @@ -151,7 +151,7 @@ public String getText(Object element) { public Image getImage(Object element) { if (element instanceof IBlackBoxMap) { ImageDescriptor image = MindMapUI.getImages() - .get(IMindMapImages.XMIND_ICON); + .get(IMindMapImages.XMIND_FILE_ICON); if (image != null) return image.createImage(); } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/CategorizedThemeViewer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/CategorizedThemeViewer.java index 4fd2b9922..d508d7579 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/CategorizedThemeViewer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/CategorizedThemeViewer.java @@ -11,6 +11,7 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; @@ -31,12 +32,14 @@ import org.xmind.gef.IGraphicalViewer; import org.xmind.gef.IViewer; import org.xmind.gef.Request; +import org.xmind.gef.event.MouseEvent; import org.xmind.gef.part.IPart; import org.xmind.gef.tool.ITool; import org.xmind.gef.ui.editor.IGraphicalEditor; import org.xmind.gef.ui.editor.IGraphicalEditorPage; import org.xmind.gef.util.Properties; import org.xmind.ui.gallery.CategorizedGalleryViewer; +import org.xmind.ui.gallery.FramePart; import org.xmind.ui.gallery.GalleryEditTool; import org.xmind.ui.gallery.GalleryLayout; import org.xmind.ui.gallery.GallerySelectTool; @@ -50,12 +53,35 @@ import org.xmind.ui.util.MindMapUtils; /** - * * @author Ren Siu * @since 3.6.50 */ public class CategorizedThemeViewer extends CategorizedGalleryViewer { + private static final int FRAME_WIDTH = 200; + private static final int FRAME_HEIGHT = 100; + + private class ThemeSelectTool extends GallerySelectTool { + + protected boolean handleMouseDown(MouseEvent me) { + FramePart targetFrame = findFrame(me.target); + if (targetFrame != null && targetFrame.getFigure().isSelected()) { + return super.handleMouseDown(me); + } else { + return handleSelectionOnMouseDown(me); + } + } + + private FramePart findFrame(IPart part) { + while (part != null) { + if (part instanceof FramePart) + return (FramePart) part; + part = part.getParent(); + } + return null; + } + } + private class CategorizedThemeContentProvider implements ITreeContentProvider { @@ -138,7 +164,7 @@ protected void handleTextModified(IPart source, IDocument document) { protected void hookEditor(FloatingTextEditor editor) { super.hookEditor(editor); - getHelper().setPrefWidth(130); + getHelper().setPrefWidth(FRAME_WIDTH); } } @@ -232,6 +258,8 @@ private IGraphicalEditorPage getCurrentPage() { } private void changeTheme(IStyle theme, String apply) { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ChangeThemeCount"); //$NON-NLS-1$ IGraphicalEditorPage page = getCurrentPage(); if (page == null) return; @@ -283,7 +311,8 @@ private void initProperties() { Properties properties = getProperties(); properties.set(GalleryViewer.Horizontal, Boolean.TRUE); properties.set(GalleryViewer.Wrap, Boolean.TRUE); - properties.set(GalleryViewer.FrameContentSize, new Dimension(200, 100)); + properties.set(GalleryViewer.FrameContentSize, + new Dimension(FRAME_WIDTH, FRAME_HEIGHT)); properties.set(GalleryViewer.TitlePlacement, GalleryViewer.TITLE_BOTTOM); properties.set(GalleryViewer.SingleClickToOpen, Boolean.FALSE); @@ -306,7 +335,7 @@ protected void configureNestedViewer(GalleryViewer viewer, protected void initGalleryViewer(GalleryViewer galleryViewerer) { galleryViewerer.setLabelProvider(new ThemeLabelProvider()); EditDomain editDomain = new EditDomain(); - editDomain.installTool(GEF.TOOL_SELECT, new GallerySelectTool()); + editDomain.installTool(GEF.TOOL_SELECT, new ThemeSelectTool()); editDomain.installTool(GEF.TOOL_EDIT, new ThemeNameEditTool()); galleryViewerer.setEditDomain(editDomain); @@ -356,4 +385,24 @@ public void startEditing(IStyle theme) { } + public void selectDefault() { + List categories = getCategories(); + if (categories == null || categories.isEmpty() + || !(categories.get(0) instanceof ThemeUIGroup)) { + return; + } + Object defaultCategory = null; + for (Object category : getCategories()) { + if ("default".equals(((ThemeUIGroup) category).getId())) { //$NON-NLS-1$ + defaultCategory = category; + setSelectionToCategory(category, new StructuredSelection( + MindMapUI.getResourceManager().getDefaultTheme()), + true); + } else { + setSelectionToCategory(category, StructuredSelection.EMPTY, + false); + } + } + reveal(defaultCategory); + } } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/CommentsView.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/CommentsView.java index cb67e2cc4..bd0b9988e 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/CommentsView.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/CommentsView.java @@ -52,8 +52,8 @@ 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.CommentsViewActionBarContributor; import org.xmind.ui.internal.comments.ICommentTextViewerContainer; import org.xmind.ui.internal.comments.ICommentsActionBarContributor; import org.xmind.ui.internal.comments.SheetCommentsViewer; @@ -147,7 +147,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException { } } - private CommentsViewActionBarContributor contributor; + private CommentsPartActionBarContributor contributor; private ISelectionProvider selectionProvider = new CommentsSelectionProvider(); @@ -183,7 +183,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException { private IComment selectedComment; public void createPartControl(Composite parent) { - contributor = new CommentsViewActionBarContributor(this, + contributor = new CommentsPartActionBarContributor(null, contributingEditor); control = createControl(parent); setInitialInput(); @@ -660,4 +660,22 @@ public void cancelCreateComment() { contentViewer.cancelCreateNewComment(); } -} \ No newline at end of file + @Override + public void setEditingComment(IComment comment) { + } + + @Override + public IComment getEditingComment() { + return null; + } + + @Override + public void setModified(boolean modified) { + } + + @Override + public boolean isModified() { + return false; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/FileInfoInspectorSection.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/FileInfoInspectorSection.java index 3b2a4434c..626ae1a22 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/FileInfoInspectorSection.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/FileInfoInspectorSection.java @@ -11,7 +11,6 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; @@ -33,11 +32,11 @@ import org.xmind.core.event.ICoreEventRegister; import org.xmind.core.event.ICoreEventSource; import org.xmind.core.internal.dom.NumberUtils; -import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.internal.utils.CommandUtils; import org.xmind.ui.util.MindMapUtils; -public class FileInfoInspectorSection extends InspectorSection implements - ICoreEventListener { +public class FileInfoInspectorSection extends InspectorSection + implements ICoreEventListener { private ICoreEventRegister register; @@ -87,8 +86,8 @@ private Composite createEstimateSizeItem(Composite parent) { if (estimateSizeLabel == null) estimateSizeLabel = new Label(item, SWT.NONE); - estimateSizeLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); + estimateSizeLabel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); estimateSizeLabel.setText(getSize()); return item; } @@ -100,8 +99,8 @@ private Composite createWordsItem(Composite parent) { if (wordsCountLabel == null) wordsCountLabel = new Label(item, SWT.NONE); - wordsCountLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); + wordsCountLabel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); wordsCountLabel.setText(getWordsCount()); return item; } @@ -113,8 +112,8 @@ private Composite createTopicsItem(Composite parent) { if (topicsCountLabel == null) topicsCountLabel = new Label(item, SWT.NONE); - topicsCountLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); + topicsCountLabel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); topicsCountLabel.setText(getTopicsCount()); return item; } @@ -131,8 +130,8 @@ private Composite createRevisionsItem(Composite parent) { if (revisions == null) revisions = new Hyperlink(item, SWT.NONE); - revisions.setForeground(Display.getCurrent().getSystemColor( - SWT.COLOR_BLUE)); + revisions.setForeground( + Display.getCurrent().getSystemColor(SWT.COLOR_BLUE)); revisions.setUnderlined(true); revisions.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); revisions.setText(getRevisions()); @@ -150,11 +149,8 @@ public void linkActivated(HyperlinkEvent e) { if (window != null) { IWorkbenchPage page = window.getActivePage(); if (page != null) - try { - page.showView(MindMapUI.VIEW_REVISIONS); - } catch (PartInitException e1) { - e1.printStackTrace(); - } + CommandUtils.executeCommand( + "org.xmind.ui.command.editingHistory", window); //$NON-NLS-1$ } } }); @@ -167,8 +163,8 @@ private Composite createModifiedTimeItem(Composite parent) { if (modifyTimeLabel == null) modifyTimeLabel = new Label(item, SWT.NONE); - modifyTimeLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); + modifyTimeLabel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); modifyTimeLabel.setText(getModifiedTime()); return item; } @@ -180,8 +176,8 @@ private Composite createModifiedByItem(Composite parent) { if (modifyByLabel == null) modifyByLabel = new Label(item, SWT.NONE); - modifyByLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); + modifyByLabel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); modifyByLabel.setText(getModifiedBy()); return item; } @@ -193,8 +189,8 @@ private Composite createCreatedTimeItem(Composite parent) { if (createdTimeLabel == null) createdTimeLabel = new Label(item, SWT.NONE); - createdTimeLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); + createdTimeLabel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); createdTimeLabel.setText(getCreatedTime()); return item; } @@ -416,7 +412,8 @@ else if (Core.ModifyTime.equals(type)) { refreshEstimateSize(); } else if (Core.WorkbookSave.equals(type)) { refreshEstimateSize(); - } else if (Core.TopicAdd.equals(type) || Core.TopicRemove.equals(type)) { + } else if (Core.TopicAdd.equals(type) + || Core.TopicRemove.equals(type)) { refreshTopicsCount(); refreshWordsCount(); } else if (Core.TitleText.equals(type) || Core.TopicNotes.equals(type) diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/Messages.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/Messages.java index 238781e6d..2137e05a6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/Messages.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/Messages.java @@ -44,6 +44,14 @@ public class Messages extends NLS { public static String ThemeUICore_group_default_name; public static String ThemeUICore_group_user_name; + public static String ThemesPopover_MoreTheme_label; + public static String ThemesPopover_ManagerTheme_label; + public static String ThemesPopover_Extract_Current_Theme_label; + + public static String MarkersPopover_ManageMarkers_label; + public static String MarkersPopover_ImportMarkers_label; + public static String MarkersPopover_ExportMarkers_label; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/NotesHyperlinkDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/NotesHyperlinkDialog.java index 459906cd9..4a3fdac27 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/NotesHyperlinkDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/NotesHyperlinkDialog.java @@ -35,7 +35,7 @@ public class NotesHyperlinkDialog extends Dialog { private String displayText; - protected NotesHyperlinkDialog(Shell parentShell, String oldHyperlink, + public NotesHyperlinkDialog(Shell parentShell, String oldHyperlink, String oldText) { super(parentShell); this.displayText = oldText == null ? "" : oldText; //$NON-NLS-1$ @@ -81,10 +81,10 @@ private void createDisplayTextInputArea(Composite parent) { label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); label.setText(MindMapMessages.NotesHyperlinkDialog_display_text); - Text displayTextInput = new Text(area, SWT.SINGLE | SWT.LEAD - | SWT.BORDER); - displayTextInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); + Text displayTextInput = new Text(area, + SWT.SINGLE | SWT.LEAD | SWT.BORDER); + displayTextInput + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); displayTextInput.setText(displayText); displayTextInput.addListener(SWT.Modify, new Listener() { public void handleEvent(Event event) { @@ -111,8 +111,8 @@ private void createHrefInputArea(Composite parent) { Label label = new Label(area, SWT.NONE); label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - label - .setText(MindMapMessages.NotesHyperlinkDialog_hyperlinkReference_text); + label.setText( + MindMapMessages.NotesHyperlinkDialog_hyperlinkReference_text); Text text = new Text(area, SWT.SINGLE | SWT.LEAD | SWT.BORDER); text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); @@ -147,4 +147,4 @@ public String getHref() { return href; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/NotesView.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/NotesView.java index 2cae82294..53df418b1 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/NotesView.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/NotesView.java @@ -1,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ package org.xmind.ui.internal.views; @@ -346,7 +343,7 @@ protected void makeActions(IRichTextEditViewer viewer) { insertHyperlinkAction = new InsertHyperlinkAction(viewer); addRichTextAction(insertHyperlinkAction); - showAllNotesAction = new ShowAllNotesAction(NotesView.this); + showAllNotesAction = new ShowAllNotesAction(null); // addRichTextAction(showAllNotesAction); } @@ -1057,7 +1054,6 @@ public void run() { /* * (non-Javadoc) - * * @see * org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse * .jface.util.PropertyChangeEvent) @@ -1161,4 +1157,4 @@ public void selectionChanged(SelectionChangedEvent event) { return listener; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/RevisionsPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/RevisionsPage.java index 2bbf2f404..4f29b0d70 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/RevisionsPage.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/RevisionsPage.java @@ -339,7 +339,9 @@ public void handleCoreEvent(CoreEvent event) { if (Core.RevisionAdd.equals(type) || Core.RevisionRemove.equals(type)) { asyncExec(new Runnable() { public void run() { - viewer.refresh(); + if (viewer != null) { + viewer.refresh(); + } } }); } else if (Core.TitleText.equals(type)) { diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeFigure.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeFigure.java index cdd8ff747..6771adaa8 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeFigure.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeFigure.java @@ -238,6 +238,10 @@ public void setDefaultImage(Image defaultImage) { repaint(); } + public Image getPreviewImage(IStyle theme) { + return getImageFromSource(theme, new Rectangle(0, 0, 200, 100)); + } + // public boolean isDefault() { // return isDefault; // } @@ -282,6 +286,9 @@ protected void drawTheme(Graphics graphics, IStyle theme, Rectangle r) { } private Image getImageFromSource(IStyle theme, Rectangle r) { + if (this.theme != theme) + this.theme = theme; + File root = MindMapUIPlugin.getDefault().getStateLocation().toFile(); root = new File(root, ".themePreview"); //$NON-NLS-1$ @@ -302,4 +309,4 @@ private Image getImageFromSource(IStyle theme, Rectangle r) { return new Image(Display.getCurrent(), preview.getAbsolutePath()); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeGroupCore.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeGroupCore.java new file mode 100644 index 000000000..4d34dcef9 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeGroupCore.java @@ -0,0 +1,257 @@ +package org.xmind.ui.internal.views; + +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 java.util.Set; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xmind.core.style.IStyle; +import org.xmind.core.style.IStyleSheet; +import org.xmind.ui.internal.MindMapMessages; +import org.xmind.ui.mindmap.IResourceManager; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.Logger; +import org.xml.sax.SAXException; + +public class ThemeGroupCore { + + private ThemeGroupCore() { + }; + + private static ThemeGroupCore instance = null; + + public class CategorizedThemeGroup { + List items = new ArrayList(); + + private String name; + + private String id; + + public CategorizedThemeGroup(String id, String name, + List items) { + this.id = id; + this.name = name; + this.items = items; + } + + public String getName() { + return name; + } + + public List getItems() { +// List list = new ArrayList(items); + +// for (IStyle style : items) { +// if (!this.equals(defaultThemeGroup) +// && style.getId().equals(getDefaultThemeId())) { +//// list.remove(style); +// return list; +// } +// } + return items; + } + + public String getId() { + return id; + } + + public int hashCode() { + return id.hashCode(); + } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj == null || !(obj instanceof CategorizedThemeGroup)) + return false; + if (((CategorizedThemeGroup) obj).id.equals(this.id)) + return true; + return false; + } + + } + + private static final String GROUP_ID = "id"; //$NON-NLS-1$ + + private static final String GROUP_NAME = "name"; //$NON-NLS-1$ + + private static final String THEME_ID = "id"; //$NON-NLS-1$ + + private static final String THEME_GROUP = "theme-group"; //$NON-NLS-1$ + + private static final String THEME_ELEMENT = "theme"; //$NON-NLS-1$ + + private static final String DEFAULT_GROUP_ID = "default"; //$NON-NLS-1$ + + private static final String USER_GROUP_ID = "user";//$NON-NLS-1$ + + private static final String PATH_STYLES = "styles/"; //$NON-NLS-1$ + + private static final String THEME_GROUP_XML = "themeGroups.xml"; //$NON-NLS-1$ + + private static final String THEME_PROPERTIES = "themeGroups.properties"; //$NON-NLS-1$ + + private List systemGroups = null; + + private Properties properties = null; + + private CategorizedThemeGroup defaultThemeGroup = null; + + public List getThemeGroups() { + + ArrayList list = new ArrayList(); + list.add(getDefaultGroup()); + list.addAll(getSystemGroups()); + CategorizedThemeGroup group = getUserGroup(); + if (group.getItems() != null && !group.getItems().isEmpty()) + list.add(group); + + return list; + } + + private CategorizedThemeGroup getUserGroup() { + IResourceManager rm = MindMapUI.getResourceManager(); + Set userThemeSets = rm.getUserThemeSheet() + .getStyles(IStyleSheet.MASTER_STYLES); + List userThemeList = new ArrayList(); + Iterator iterUserTheme = userThemeSets.iterator(); + + while (iterUserTheme.hasNext()) { + IStyle userStyle = iterUserTheme.next(); +// if (!userStyle.getId().equals(getDefaultThemeId())) { + userThemeList.add(userStyle); +// } + } + CategorizedThemeGroup userGroup = new CategorizedThemeGroup( + USER_GROUP_ID, MindMapMessages.ThemeGroupCore_UserGroup_name, + userThemeList); + return userGroup; + } + + private List getSystemGroups() { + if (systemGroups == null) + systemGroups = createSystemGroups(); + return systemGroups; + } + + private List createSystemGroups() { + IResourceManager rm = MindMapUI.getResourceManager(); + Set systemThemeSets = rm.getSystemThemeSheet() + .getStyles(IStyleSheet.MASTER_STYLES); + Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); + String path = PATH_STYLES + THEME_GROUP_XML; + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory + .newInstance(); + DocumentBuilder documentBuilder = null; + List systemGroups = new ArrayList(); + try { + documentBuilder = documentBuilderFactory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + + try { + + URL url = FileLocator.find(bundle, new Path(path), null); + Document doc = documentBuilder.parse(url.openStream()); + NodeList nodeList = doc.getElementsByTagName(THEME_GROUP); + for (int i = 0; i < nodeList.getLength(); i++) { + Element ele = (Element) nodeList.item(i); + String groupId = ele.getAttribute(GROUP_ID); + String groupName = ele.getAttribute(GROUP_NAME).substring(1); + groupName = getProperties().getProperty(groupName); + NodeList themeList = ele.getElementsByTagName(THEME_ELEMENT); + List themeGroupList = new ArrayList(); + for (int j = 0; j < themeList.getLength(); j++) { + Element theme = (Element) themeList.item(j); + String themeId = theme.getAttribute(THEME_ID); + Iterator iterSystemTheme = systemThemeSets + .iterator(); + while (iterSystemTheme.hasNext()) { + IStyle themeStyle = iterSystemTheme.next(); + if (themeId.equals(themeStyle.getId())) { + themeGroupList.add(themeStyle); + systemThemeSets.remove(themeStyle); + break; + } + } + } + CategorizedThemeGroup themeGroup = new CategorizedThemeGroup( + groupId, groupName, themeGroupList); + systemGroups.add(themeGroup); + } + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return systemGroups; + + } + + private CategorizedThemeGroup getDefaultGroup() { + IResourceManager rm = MindMapUI.getResourceManager(); + IStyle defaultTheme = rm.getDefaultTheme(); + List defaultThemeList = new ArrayList(); + defaultThemeList.add(defaultTheme); + defaultThemeGroup = new CategorizedThemeGroup(DEFAULT_GROUP_ID, + MindMapMessages.ThemeGroupCore_DefaultGroup_name, + defaultThemeList); + + return defaultThemeGroup; + } + + public Properties getProperties() { + if (properties == null) { + properties = loadProperties(); + } + return properties; + } + + private Properties loadProperties() { + Bundle bundle = Platform.getBundle(MindMapUI.PLUGIN_ID); + URL propertiesUrl = FileLocator.find(bundle, + new Path(PATH_STYLES + THEME_PROPERTIES), null); + Properties properties = new Properties(); + InputStream stream = null; + try { + stream = propertiesUrl.openStream(); + properties.load(stream); + } catch (IOException e) { + Logger.log(e, "Failed to load default properties file from: " //$NON-NLS-1$ + + THEME_PROPERTIES); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return properties; + } + + public static ThemeGroupCore getInstance() { + if (instance == null) { + instance = new ThemeGroupCore(); + } + return instance; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeLabelProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeLabelProvider.java index cd87ea565..466f01729 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeLabelProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeLabelProvider.java @@ -31,6 +31,10 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; import org.xmind.core.Core; import org.xmind.core.IBoundary; import org.xmind.core.IControlPoint; @@ -51,6 +55,8 @@ import org.xmind.gef.draw2d.SizeableImageFigure; import org.xmind.gef.image.ImageExportUtils; import org.xmind.gef.image.ResizeConstants; +import org.xmind.gef.ui.editor.IGraphicalEditor; +import org.xmind.gef.ui.editor.IGraphicalEditorPage; import org.xmind.gef.util.Properties; import org.xmind.ui.gallery.GalleryViewer; import org.xmind.ui.gallery.IDecorationContext; @@ -80,9 +86,13 @@ private static class ThemePreviewImageProviderManager public static final ThemePreviewImageProviderManager INSTANCE = new ThemePreviewImageProviderManager(); - private Map images = new HashMap(); + private Map> imageGroups = new HashMap>(); - private Map loaders = new HashMap(); + private Map> loaderGroups = new HashMap>(); + +// private Map images = new HashMap(); +// +// private Map loaders = new HashMap(); private ListenerList listeners = new ListenerList(); @@ -94,10 +104,14 @@ public void done(IJobChangeEvent event) { super.done(event); ThemePreviewImageLoader loader = (ThemePreviewImageLoader) event .getJob(); - loaders.remove(loader.getTheme()); + Map loaderGroup = loaderGroups + .get(loader.getStructureClass()); + if (loaderGroup != null && !loaderGroup.isEmpty()) + loaderGroup.remove(loader.getTheme()); Image image = loader.getPreviewImage(); if (image != null) { - setPreviewImage(loader.getTheme(), image); + setPreviewImage(loader.getTheme(), + loader.getStructureClass(), image); } } }; @@ -174,20 +188,29 @@ public void handleCoreEvent(CoreEvent event) { } } - public Image getThemePreviewImage(IStyle theme) { - Image image; + public Image getThemePreviewImage(IStyle theme, String structureClass) { + Image image = null; - image = images.get(theme); + Map imageGroup = imageGroups.get(structureClass); + if (imageGroup != null) + image = imageGroup.get(theme); if (image != null) return image; - if (!loaders.containsKey(theme)) { + Map loaderGroup = loaderGroups + .get(structureClass); + if (loaderGroup == null) { + loaderGroup = new HashMap(); + loaderGroups.put(structureClass, loaderGroup); + } + if (!loaderGroup.containsKey(theme)) { +// if (!loaders.containsKey(theme)) { ThemePreviewImageLoader loader = new ThemePreviewImageLoader( - theme, Display.getCurrent()); + theme, structureClass, Display.getCurrent()); loader.setRule(this); loader.setSystem(true); loader.addJobChangeListener(loaderListener); - loaders.put(theme, loader); + loaderGroup.put(theme, loader); MindMapUIPlugin.getDefault().registerJob(loader); loader.schedule(); } @@ -196,53 +219,75 @@ public Image getThemePreviewImage(IStyle theme) { } private void deletePreviewImageCacheForTheme(IStyle theme) { - File cacheFile = getPreviewImageCacheFileForTheme(theme); - if (cacheFile.exists()) { - cacheFile.delete(); - } + for (String structureClass : imageGroups.keySet()) { + File cacheFile = getPreviewImageCacheFileForTheme(theme, + structureClass); + if (cacheFile.exists()) { + cacheFile.delete(); + } - deletePreviewImageCacheInMemory(theme); + deletePreviewImageCacheInMemory(theme, structureClass); + } } - private void deletePreviewImageCacheInMemory(final IStyle theme) { + private void deletePreviewImageCacheInMemory(final IStyle theme, + String structureClass) { Display display = null; - final Image image = images.remove(theme); - if (image != null) { - display = (Display) image.getDevice(); - if (!display.isDisposed()) { - display.asyncExec(new Runnable() { - public void run() { - Display display = Display.getCurrent(); - if (!display.isDisposed()) { - display.asyncExec(new Runnable() { - public void run() { - image.dispose(); - } - }); +// final Image image = images.remove(theme); + Map imageGroup = imageGroups.get(structureClass); + if (imageGroup != null && !imageGroup.isEmpty()) { + final Image image = imageGroup.remove(theme); + if (image != null) { + display = (Display) image.getDevice(); + if (!display.isDisposed()) { + display.asyncExec(new Runnable() { + public void run() { + Display display = Display.getCurrent(); + if (!display.isDisposed()) { + display.asyncExec(new Runnable() { + public void run() { + image.dispose(); + } + }); + } } - } - }); + }); + } } - } - final ThemePreviewImageLoader loader = loaders.remove(theme); - if (loader != null) { - loader.cancel(); } - if (display != null && !display.isDisposed()) { - display.syncExec(new Runnable() { - public void run() { - fireThemePreviewImageChanged(theme); - } - }); +// final ThemePreviewImageLoader loader = loaders.remove(theme); + Map loaderGroup = loaderGroups + .get(structureClass); + if (loaderGroup != null && !loaderGroup.isEmpty()) { + final ThemePreviewImageLoader loader = loaderGroup + .remove(theme); + if (loader != null) { + loader.cancel(); + } + + if (display != null && !display.isDisposed()) { + display.syncExec(new Runnable() { + + public void run() { + fireThemePreviewImageChanged(theme); + } + }); + } } } - private void setPreviewImage(final IStyle theme, Image image) { + private void setPreviewImage(final IStyle theme, String structureClass, + Image image) { Display display = null; - final Image oldImage = images.put(theme, image); + Map imageGroup = imageGroups.get(structureClass); + if (imageGroup == null) { + imageGroup = new HashMap(); + imageGroups.put(structureClass, imageGroup); + } + final Image oldImage = imageGroup.put(theme, image); if (oldImage != null) { display = (Display) oldImage.getDevice(); if (!display.isDisposed()) { @@ -264,9 +309,11 @@ public void run() { display = (Display) image.getDevice(); if (!display.isDisposed()) { display.syncExec(new Runnable() { + public void run() { fireThemePreviewImageChanged(theme); } + }); } } @@ -285,14 +332,18 @@ private static class ThemePreviewImageLoader extends Job { private IStyle theme; + private String structureClass; + private Display display; private Image previewImage; - public ThemePreviewImageLoader(IStyle theme, Display display) { + public ThemePreviewImageLoader(IStyle theme, String structureClass, + Display display) { super(NLS.bind(MindMapMessages.ThemeLabel_LoadTheme, theme.getName())); this.theme = theme; + this.structureClass = structureClass; this.display = display; this.previewImage = null; } @@ -369,11 +420,11 @@ protected IStatus run(IProgressMonitor monitor) { } private Image createPreviewImage() { - return createPreviewImageForTheme(theme, display); + return createPreviewImageForTheme(theme, structureClass, display); } private File getPreviewImageCacheFile() { - return getPreviewImageCacheFileForTheme(theme); + return getPreviewImageCacheFileForTheme(theme, structureClass); } public Image getPreviewImage() { @@ -384,6 +435,10 @@ public IStyle getTheme() { return theme; } + public String getStructureClass() { + return structureClass; + } + } private static class Layout extends AbstractHintLayout { @@ -437,11 +492,19 @@ protected Dimension calculatePreferredSize(IFigure figure, int wHint, } + private String structureClass; + public ThemeLabelProvider() { ThemePreviewImageProviderManager.INSTANCE .addThemePreviewImageListener(this); } + public ThemeLabelProvider(String structureClass) { + this.structureClass = structureClass; + ThemePreviewImageProviderManager.INSTANCE + .addThemePreviewImageListener(this); + } + @Override public String getText(Object element) { if (element instanceof IStyle @@ -455,8 +518,13 @@ public String getText(Object element) { public Image getImage(Object element) { if (element instanceof IStyle && IStyle.THEME.equals(((IStyle) element).getType())) { + return ThemePreviewImageProviderManager.INSTANCE - .getThemePreviewImage((IStyle) element); + .getThemePreviewImage((IStyle) element, + (structureClass == null + || "".equals(structureClass)) //$NON-NLS-1$ + ? getCurrentCentralStructure() + : structureClass); } return super.getImage(element); } @@ -472,7 +540,8 @@ private void themePreviewImageChanged(IStyle theme) { fireLabelProviderChanged(new LabelProviderChangedEvent(this, theme)); } - private static File getPreviewImageCacheFileForTheme(IStyle theme) { + private static File getPreviewImageCacheFileForTheme(IStyle theme, + String structureClass) { File root = MindMapUIPlugin.getDefault().getStateLocation().toFile(); File cacheDir = new File(root, THEME_PREVIEWS_DIR); String themeId = theme.getId(); @@ -486,13 +555,14 @@ private static File getPreviewImageCacheFileForTheme(IStyle theme) { } else { parentId = "other"; //$NON-NLS-1$ } - String fileName = String.format("%s-%s.png", parentId, themeId); //$NON-NLS-1$ + String fileName = String.format("%s-%s-%s.png", parentId, //$NON-NLS-1$ + structureClass, themeId); return new File(cacheDir, fileName); } private static Image createPreviewImageForTheme(IStyle theme, - Display display) { - IWorkbook workbook = createTemplateWorkbook(); + String structureClass, Display display) { + IWorkbook workbook = createTemplateWorkbook(structureClass); IStyle appliedTheme = workbook.getStyleSheet().importStyle(theme); if (appliedTheme != null) { workbook.getPrimarySheet().setThemeId(appliedTheme.getId()); @@ -520,7 +590,7 @@ public void run() { return image[0]; } - private static IWorkbook createTemplateWorkbook() { + private static IWorkbook createTemplateWorkbook(String structureClass) { IStorage tempStorage = new ByteArrayStorage(); IWorkbook workbook = Core.getWorkbookBuilder() .createWorkbook(tempStorage); @@ -528,7 +598,9 @@ private static IWorkbook createTemplateWorkbook() { ITopic rootTopic = sheet.getRootTopic(); rootTopic.setTitleText(MindMapMessages.TitleText_CentralTopic); - rootTopic.setStructureClass("org.xmind.ui.map.clockwise"); //$NON-NLS-1$ + rootTopic.setStructureClass( + (structureClass == null || "".equals(structureClass)) //$NON-NLS-1$ + ? "org.xmind.ui.map.clockwise" : structureClass); //$NON-NLS-1$ ITopic mainTopic1 = workbook.createTopic(); mainTopic1 @@ -629,4 +701,35 @@ private static Image getDefaultImage() { } return defaultImage; } + + private String getCurrentCentralStructure() { + if (this.structureClass != null && !"".equals(this.structureClass)) //$NON-NLS-1$ + return this.structureClass; + + String defaultStructureClass = "org.xmind.ui.map.clockwise"; //$NON-NLS-1$ + IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + if (activeWorkbenchWindow == null) + return defaultStructureClass; + + IWorkbenchPage activePage = activeWorkbenchWindow.getActivePage(); + if (activePage == null) + return defaultStructureClass; + + IEditorPart activeEditor = activePage.getActiveEditor(); + if (activeEditor == null || !(activeEditor instanceof IGraphicalEditor)) + return defaultStructureClass; + + IGraphicalEditorPage page = ((IGraphicalEditor) activeEditor) + .getActivePageInstance(); + if (page == null) + return defaultStructureClass; + + ISheet sheet = (ISheet) page.getAdapter(ISheet.class); + if (sheet == null) + return defaultStructureClass; + + ITopic topic = sheet.getRootTopic(); + return topic.getStructureClass(); + } } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeOverrideDialog.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeOverrideDialog.java index c9e430aae..b251da6f3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeOverrideDialog.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeOverrideDialog.java @@ -3,6 +3,9 @@ import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; 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.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -17,13 +20,18 @@ import org.eclipse.ui.forms.widgets.Hyperlink; import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.prefs.PrefConstants; +import org.xmind.ui.resources.ColorUtils; class ThemeOverrideDialog extends Dialog { private Button rememberCheck; + private ResourceManager resources; + protected ThemeOverrideDialog(Shell parentShell) { super(parentShell); + resources = new LocalResourceManager(JFaceResources.getResources(), + parentShell); } @Override @@ -96,9 +104,9 @@ protected Control createButtonBar(Composite parent) { private void createPrefLink(Composite parent) { Hyperlink prefLink = new Hyperlink(parent, SWT.SINGLE); prefLink.setText(Messages.ThemesView_Dialog_PrefLink); - prefLink.setUnderlined(true); + prefLink.setUnderlined(false); prefLink.setForeground( - parent.getDisplay().getSystemColor(SWT.COLOR_BLUE)); + resources.createColor(ColorUtils.toDescriptor("#0082F9"))); //$NON-NLS-1$ prefLink.addHyperlinkListener(new HyperlinkAdapter() { @Override @@ -109,6 +117,7 @@ public void linkActivated(HyperlinkEvent e) { .open(); } }); + prefLink.getParent().setFocus(); } @Override diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeUICore.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeUICore.java index 31abc13c2..c017f8878 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeUICore.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemeUICore.java @@ -28,11 +28,10 @@ import org.xml.sax.SAXException; /** - * * @author Ren Siu * @since 3.6.50 */ -class ThemeUICore { +public class ThemeUICore { protected class ThemeUIGroup { diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemesView.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemesView.java index 27009731b..c111b20d1 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemesView.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/ThemesView.java @@ -1,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ package org.xmind.ui.internal.views; @@ -135,8 +132,6 @@ private IStyle getSelectionStyle() { private boolean linkingToEditor; - private boolean updatingSelection = false; - private ICoreEventRegister register = null; private SetDefaultThemeAction setDefaultThemeAction; @@ -294,10 +289,8 @@ private void updateSelection() { theme = MindMapUI.getResourceManager().getUserThemeSheet() .findStyle(themeId); } - updatingSelection = true; viewer.setSelection(theme == null ? StructuredSelection.EMPTY : new StructuredSelection(theme)); - updatingSelection = false; } private String getCurrentThemeId() { @@ -389,6 +382,7 @@ public void partOpened(IWorkbenchPart part) { public void pageChanged(PageChangedEvent event) { setCurrentSheet(findCurrentSheet()); + viewer.refresh(true); updateSelection(); } @@ -415,4 +409,4 @@ public void run() { }); } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/messages.properties b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/messages.properties index 069a76acb..8db928104 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/messages.properties +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/views/messages.properties @@ -36,3 +36,11 @@ ThemesView_OverrideButton=Override ThemesView_KeepButton=Keep ThemeUICore_group_default_name=Default ThemeUICore_group_user_name=User + +ThemesPopover_MoreTheme_label=More Themes... +ThemesPopover_ManagerTheme_label=Manage Themes... +ThemesPopover_Extract_Current_Theme_label=Extract Current Theme[Pro] + +MarkersPopover_ManageMarkers_label=Manage Markers... +MarkersPopover_ImportMarkers_label=Import Markers... +MarkersPopover_ExportMarkers_label=Export Markers... diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ExportPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ExportPage.java new file mode 100644 index 000000000..3d3a2a987 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ExportPage.java @@ -0,0 +1,275 @@ +package org.xmind.ui.internal.wizards; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.dialogs.IPageChangingListener; +import org.eclipse.jface.dialogs.PageChangingEvent; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.activities.ITriggerPoint; +import org.eclipse.ui.internal.IWorkbenchHelpContextIds; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.eclipse.ui.internal.activities.ws.WorkbenchTriggerPoints; +import org.eclipse.ui.internal.dialogs.WizardCollectionElement; +import org.eclipse.ui.internal.dialogs.WorkbenchWizardElement; +import org.eclipse.ui.internal.dialogs.WorkbenchWizardNode; +import org.eclipse.ui.wizards.IWizardCategory; +import org.eclipse.ui.wizards.IWizardDescriptor; +import org.xmind.ui.internal.MindMapMessages; + +/** + * Wizard page class from which an export wizard is selected. + * + * @since 3.2 + */ +public class ExportPage extends ImportExportPage { + + private static final String STORE_SELECTED_EXPORT_WIZARD_ID = DIALOG_SETTING_SECTION_NAME + + "STORE_SELECTED_EXPORT_WIZARD_ID"; //$NON-NLS-1$ + + private static final String STORE_EXPANDED_EXPORT_CATEGORIES = DIALOG_SETTING_SECTION_NAME + + "STORE_EXPANDED_EXPORT_CATEGORIES"; //$NON-NLS-1$ + + private static final String STORE_RECENTLY_USED_WIZARD_IDS = DIALOG_SETTING_SECTION_NAME + + "store_recently_used_wizard_ids"; //$NON-NLS-1$ + + private static final String WIZARD_ID_SPLIT = ";"; //$NON-NLS-1$ + + private static final int RECENTLY_USED_WIZARD_ID_SIZE = 5; + + private CategorizedWizardSelectionTree exportTree; + + /** + * Constructor for export wizard selection page. + * + * @param aWorkbench + * @param currentSelection + */ + public ExportPage(IWorkbench aWorkbench, + IStructuredSelection currentSelection) { + super(aWorkbench, currentSelection); + wizardsOrder = ImportExportPage.getWizardsOrder("export-wizards"); //$NON-NLS-1$ + } + + @Override + protected void initialize() { + workbench.getHelpSystem().setHelp(getControl(), + IWorkbenchHelpContextIds.EXPORT_WIZARD_SELECTION_WIZARD_PAGE); + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + + final IPageChangingListener listener = new IPageChangingListener() { + + @Override + public void handlePageChanging(PageChangingEvent event) { + if (event.getCurrentPage() == ExportPage.this) { + IWizardDescriptor wizardDescriptor = ((WorkbenchWizardNode) getSelectedNode()) + .getWizardElement(); + String selectedId = wizardDescriptor.getId(); + + List recentWizardIds = getRecentWizardIds(); + if (recentWizardIds.contains(selectedId)) { + recentWizardIds.remove(selectedId); + } + if (recentWizardIds.size() > RECENTLY_USED_WIZARD_ID_SIZE + - 1) { + recentWizardIds + .remove(RECENTLY_USED_WIZARD_ID_SIZE - 1); + } + recentWizardIds.add(0, selectedId); + + putRecentWizardIds(recentWizardIds); + } + } + }; + ((WizardDialog) getContainer()).addPageChangingListener(listener); + + getControl().addDisposeListener(new DisposeListener() { + + @Override + public void widgetDisposed(DisposeEvent e) { + if (getContainer() != null) { + ((WizardDialog) getContainer()) + .removePageChangingListener(listener); + } + } + }); + } + + private List getRecentWizardIds() { + String recentIds = getDialogSettings() + .get(STORE_RECENTLY_USED_WIZARD_IDS); + if (recentIds != null && !recentIds.equals("")) { //$NON-NLS-1$ + String[] ids = recentIds.split(WIZARD_ID_SPLIT); + return new ArrayList(Arrays.asList(ids)); + } + return new ArrayList(); + } + + private void putRecentWizardIds(List recentWizardIds) { + String recentIds = ""; //$NON-NLS-1$ + if (recentWizardIds.size() >= 1) { + recentIds += recentWizardIds.get(0); + } + if (recentWizardIds.size() >= 2) { + for (int i = 1; i < recentWizardIds.size(); i++) { + recentIds += WIZARD_ID_SPLIT + recentWizardIds.get(i); + } + } + getDialogSettings().put(STORE_RECENTLY_USED_WIZARD_IDS, recentIds); + } + + @Override + protected Composite createTreeViewer(Composite parent) { + IWizardCategory root = WorkbenchPlugin.getDefault() + .getExportWizardRegistry().getRootCategory(); + root = insertRecentWizards(root); + + exportTree = new CategorizedWizardSelectionTree(root, + WorkbenchMessages.ExportWizard_selectWizard); + Composite exportComp = exportTree.createControl(parent); + exportTree.getViewer() + .addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + listSelectionChanged(event.getSelection()); + } + }); + exportTree.getViewer() + .addDoubleClickListener(new IDoubleClickListener() { + @Override + public void doubleClick(DoubleClickEvent event) { + treeDoubleClicked(event); + } + }); + setTreeViewer(exportTree.getViewer()); + return exportComp; + } + + private IWizardCategory insertRecentWizards(IWizardCategory root) { + List recentWizardIds = getRecentWizardIds(); + if (recentWizardIds.size() == 0) { + return root; + } + + List wizardDescriptors = new ArrayList(); + collectWizardDescriptors(wizardDescriptors, root); + + List recentWizards = new ArrayList(); + for (String wizardId : recentWizardIds) { + for (IWizardDescriptor wizardDescriptor : wizardDescriptors) { + if (wizardId.contains(wizardDescriptor.getId())) { + recentWizards.add(wizardDescriptor); + break; + } + } + } + + if (recentWizards.size() == 0) { + return root; + } + + //create new root. + WizardCollectionElement newRoot = new WizardCollectionElement("root", //$NON-NLS-1$ + null, "root", null); //$NON-NLS-1$ + + //add recent use + WizardCollectionElement recentCategory = new WizardCollectionElement( + RECENTLY_USED_CATEGORY_ID, null, + MindMapMessages.ExportPage_Categore_Recent_name, newRoot); + for (IWizardDescriptor wizardDescriptor : recentWizards) { + WorkbenchWizardElement newDescriptor = new WorkbenchWizardElement( + ((WorkbenchWizardElement) wizardDescriptor) + .getConfigurationElement()); + newDescriptor.setParent(recentCategory); + recentCategory.add(newDescriptor); + } + newRoot.add(recentCategory); + + //add old + for (IWizardCategory wizardCategory : root.getCategories()) { + newRoot.add((WizardCollectionElement) wizardCategory); + } + for (IWizardDescriptor wizardDescriptor : root.getWizards()) { + newRoot.add(wizardDescriptor); + } + + return newRoot; + } + + private void collectWizardDescriptors(List descriptors, + IWizardCategory wizardCategory) { + if (wizardCategory != null) { + descriptors.addAll(Arrays.asList(wizardCategory.getWizards())); + for (IWizardCategory category : wizardCategory.getCategories()) { + collectWizardDescriptors(descriptors, category); + } + } + } + + @Override + public void saveWidgetValues() { + storeExpandedCategories(STORE_EXPANDED_EXPORT_CATEGORIES, + exportTree.getViewer()); + storeSelectedCategoryAndWizard(STORE_SELECTED_EXPORT_WIZARD_ID, + exportTree.getViewer()); + super.saveWidgetValues(); + } + + @Override + protected void restoreWidgetValues() { + IWizardCategory exportRoot = WorkbenchPlugin.getDefault() + .getExportWizardRegistry().getRootCategory(); + expandPreviouslyExpandedCategories(STORE_EXPANDED_EXPORT_CATEGORIES, + exportRoot, exportTree.getViewer()); + selectPreviouslySelected(STORE_SELECTED_EXPORT_WIZARD_ID, exportRoot, + exportTree.getViewer()); + super.restoreWidgetValues(); + } + + @Override + protected ITriggerPoint getTriggerPoint() { + return getWorkbench().getActivitySupport().getTriggerPointManager() + .getTriggerPoint(WorkbenchTriggerPoints.EXPORT_WIZARDS); + } + + @Override + protected void updateMessage() { + setMessage(WorkbenchMessages.ImportExportPage_chooseExportWizard); + super.updateMessage(); + } + + @Override + protected void expandPreviouslyExpandedCategories(String setting, + IWizardCategory wizardCategories, TreeViewer viewer) { + String[] expandedCategoryPaths = getDialogSettings().getArray(setting); + if (expandedCategoryPaths == null + || expandedCategoryPaths.length == 0) { + return; + } + + List idList = Arrays.asList(expandedCategoryPaths); + for (IWizardCategory category : wizardCategories.getCategories()) { + if (!idList.contains(category.getId())) { + viewer.setExpandedState(wizardCategories + .findCategory(new Path(category.getId())), false); + } + } + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/HtmlExporter.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/HtmlExporter.java index f8895bf5d..eca97696b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/HtmlExporter.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/HtmlExporter.java @@ -28,6 +28,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.internal.DPIUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; @@ -75,20 +76,21 @@ public TitlePart(HtmlExporter exporter, ITopic topic, int level) { protected Node createNode() { ITopic topic = (ITopic) getElement(); - String tag = HtmlConstants.TAGS_H[Math.min( - HtmlConstants.TAGS_H.length - 1, level)]; + String tag = HtmlConstants.TAGS_H[Math + .min(HtmlConstants.TAGS_H.length - 1, level)]; Element ele = createDOMElement(tag); boolean isRoot = isCentralTopic(topic); - ele.setAttribute(HtmlConstants.ATT_CLASS, isRoot ? "root" : "topic"); //$NON-NLS-1$ //$NON-NLS-2$ + ele.setAttribute(HtmlConstants.ATT_CLASS, + isRoot ? "root" : "topic"); //$NON-NLS-1$ //$NON-NLS-2$ if (isRoot) { ele.setAttribute(HtmlConstants.ATT_ALIGN, HtmlConstants.CENTER); } writeStyle(ele, topic); - String num = ExportUtils.getNumberingText(topic, getExporter() - .getCentralTopic()); + String num = ExportUtils.getNumberingText(topic, + getExporter().getCentralTopic()); if (num != null) { ele.appendChild(createText(num)); ele.appendChild(createText(" ")); //$NON-NLS-1$ @@ -101,15 +103,18 @@ protected Node createNode() { String hyperlink = topic.getHyperlink(); if (HyperlinkUtils.isAttachmentURL(hyperlink) && !isLinkToWeb(hyperlink)) { - if (getExporter().getBoolean(ExportContants.INCLUDE_ATTACHMENT)) { + if (getExporter() + .getBoolean(ExportContants.INCLUDE_ATTACHMENT)) { hyperlink = getExporter().createFilePath(hyperlink, title); } else { hyperlink = null; } } else { - if (!getExporter().getBoolean(ExportContants.INCLUDE_HYPERLINK)) { + if (!getExporter() + .getBoolean(ExportContants.INCLUDE_HYPERLINK)) { hyperlink = null; - } else if (hyperlink != null && hyperlink.startsWith("xmind:")) { //$NON-NLS-1$ + } else if (hyperlink != null + && hyperlink.startsWith("xmind:")) { //$NON-NLS-1$ hyperlink = hyperlink.substring(6); } else if (isLinkToWeb(hyperlink) && !hyperlink.startsWith("http:") //$NON-NLS-1$ @@ -141,7 +146,8 @@ private boolean isLinkToWeb(String hyperlink) { if (hyperlink.contains("www.") || hyperlink.contains(".com") || hyperlink.contains(".cn") || hyperlink.contains(".org") - || hyperlink.contains(".cc") || hyperlink.contains(".net")) { + || hyperlink.contains(".cc") + || hyperlink.contains(".net")) { return true; } return false; @@ -418,7 +424,8 @@ protected Node createNode() { while (topicIt.hasNext()) { ITopic topic = topicIt.next(); Element anchor = createDOMElement(HtmlConstants.TAG_A); - anchor.setAttribute(HtmlConstants.ATT_HREF, "#" + topic.getId()); //$NON-NLS-1$ + anchor.setAttribute(HtmlConstants.ATT_HREF, + "#" + topic.getId()); //$NON-NLS-1$ anchor.setTextContent(topic.getTitleText()); ele.appendChild(anchor); if (topicIt.hasNext()) { @@ -558,8 +565,8 @@ private void appendTopicContent(ITopic topic, int level, boolean hasLabel = getBoolean(ExportContants.INCLUDE_LABELS) && !labels.isEmpty(); if (hasMarker || hasLabel) { - TagsPart tags = new TagsPart(this, topic, hasMarker ? markers - : null, hasLabel ? labels : null); + TagsPart tags = new TagsPart(this, topic, + hasMarker ? markers : null, hasLabel ? labels : null); tags.setParent(parent); append(tags); } @@ -760,8 +767,8 @@ public Document getDocument() { protected Element getHeadElement() { if (headEle == null) { - headEle = DOMUtils.ensureChildElement(getDocument() - .getDocumentElement(), HtmlConstants.TAG_HEAD); + headEle = DOMUtils.ensureChildElement( + getDocument().getDocumentElement(), HtmlConstants.TAG_HEAD); } return headEle; } @@ -804,8 +811,8 @@ public String addStyle(String styleId) { if (styleId == null) return null; - String cachedStyleId = styleIdMap == null ? null : styleIdMap - .get(styleId); + String cachedStyleId = styleIdMap == null ? null + : styleIdMap.get(styleId); if (cachedStyleId != null) return cachedStyleId; @@ -942,11 +949,11 @@ private void createStyle(String tag, String styleId, IStyle style, public String createOverview(ITopic topic, ImageFormat format) { String title = topic.getTitleText(); - String path = newPath(getImagesPath(), - MindMapUtils.trimFileName(title), format.getExtensions().get(0)); + String path = newPath(getImagesPath(), MindMapUtils.trimFileName(title), + format.getExtensions().get(0)); FileUtils.ensureFileParent(new File(path)); - String relativePath = connectPath(getRelativeImagesPath(), new File( - path).getName()); + String relativePath = connectPath(getRelativeImagesPath(), + new File(path).getName()); MindMapImageExporter exporter = createOverviewExporter(topic); exporter.setTargetFile(new File(path)); @@ -1036,12 +1043,19 @@ public String createMarkerPath(String markerId) { String path = newPath(getImagesPath(), name, ext); FileUtils.ensureFileParent(new File(path)); + int zoom = DPIUtil.getDeviceZoom(); + List variations = resource.getVariations(); - InputStream in; - if (variations.size() > 0) { - in = resource.getInputStream(variations.get(variations.size() - 1)); - } else { - in = resource.getInputStream(); + InputStream in = null; + try { + if (variations.size() > 0) { + in = resource.openInputStream( + variations.get(variations.size() - 1), zoom); + } else { + in = resource.openInputStream(zoom); + } + } catch (IOException e) { + e.printStackTrace(); } if (in != null) { @@ -1063,4 +1077,4 @@ private String cacheMarker(String markerId, Object path) { markerPaths.put(markerId, path); return path == NULL ? null : (String) path; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ImportExportPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ImportExportPage.java new file mode 100644 index 000000000..b6436d27e --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ImportExportPage.java @@ -0,0 +1,833 @@ +package org.xmind.ui.internal.wizards; + +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.xml.parsers.DocumentBuilderFactory; + +import org.eclipse.core.runtime.Adapters; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +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.jface.dialogs.Dialog; +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.DoubleClickEvent; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.jface.wizard.IWizardNode; +import org.eclipse.jface.wizard.IWizardPage; +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.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWizard; +import org.eclipse.ui.activities.ITriggerPoint; +import org.eclipse.ui.activities.WorkbenchActivityHelper; +import org.eclipse.ui.dialogs.FilteredTree; +import org.eclipse.ui.dialogs.PatternFilter; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.eclipse.ui.internal.dialogs.DialogUtil; +import org.eclipse.ui.internal.dialogs.WizardActivityFilter; +import org.eclipse.ui.internal.dialogs.WizardContentProvider; +import org.eclipse.ui.internal.dialogs.WizardPatternFilter; +import org.eclipse.ui.internal.dialogs.WorkbenchWizardElement; +import org.eclipse.ui.internal.dialogs.WorkbenchWizardNode; +import org.eclipse.ui.internal.dialogs.WorkbenchWizardSelectionPage; +import org.eclipse.ui.model.AdaptableList; +import org.eclipse.ui.model.IWorkbenchAdapter; +import org.eclipse.ui.wizards.IWizardCategory; +import org.eclipse.ui.wizards.IWizardDescriptor; +import org.osgi.framework.Bundle; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xmind.core.io.BundleResource; +import org.xmind.core.util.DOMUtils; +import org.xmind.ui.internal.MindMapUIPlugin; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ColorUtils; + +/** + * Abstract wizard page class from which an import or export wizard can be + * chosen. + * + * @since 3.2 + */ +public abstract class ImportExportPage extends WorkbenchWizardSelectionPage { + + public static final String RECENTLY_USED_CATEGORY_ID = "recentlyUsed"; //$NON-NLS-1$ + + protected static final String DIALOG_SETTING_SECTION_NAME = "ImportExportPage."; //$NON-NLS-1$ + + private static final String WIZARDS_ORDER_XML_PATH = "src/org/xmind/ui/internal/wizards/" //$NON-NLS-1$ + + "wizards_order.xml"; //$NON-NLS-1$ + + protected static class Category { + + private String id; + + private List descriptorIds; + + public Category(String id, List descriptorIds) { + this.id = id; + this.descriptorIds = descriptorIds; + } + + public String getId() { + return id; + } + + public List getDescriptorIds() { + return descriptorIds; + } + } + + private static class DataTransferWizardCollectionComparator + extends ViewerComparator { + + public final static DataTransferWizardCollectionComparator INSTANCE = new DataTransferWizardCollectionComparator(); + + private List wizardsOrder; + + private DataTransferWizardCollectionComparator() { + super(); + } + + public void setWizardsOrder(List wizardsOrder) { + this.wizardsOrder = wizardsOrder; + } + + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + if (e1 instanceof IWizardCategory + && e2 instanceof IWizardCategory) { + return indexOf((IWizardCategory) e1) + - indexOf((IWizardCategory) e2); + + } else if (e1 instanceof IWizardDescriptor + && e2 instanceof IWizardDescriptor) { + //sort recently used + if (RECENTLY_USED_CATEGORY_ID + .equals(((IWizardDescriptor) e1).getCategory().getId()) + && RECENTLY_USED_CATEGORY_ID + .equals(((IWizardDescriptor) e2).getCategory() + .getId())) { + return 1; + } else { + return indexOf((IWizardDescriptor) e1) + - indexOf((IWizardDescriptor) e2); + } + } + + return super.compare(viewer, e1, e2); + } + + private int indexOf(Object object) { + if (object instanceof IWizardCategory) { + IWizardCategory wizardCategory = (IWizardCategory) object; + + for (Object category : wizardsOrder) { + if (((Category) category).getId() + .equals(wizardCategory.getId())) { + return wizardsOrder.indexOf(category); + } + } + + } else if (object instanceof IWizardDescriptor) { + IWizardCategory wizardCategory = ((IWizardDescriptor) object) + .getCategory(); + + for (Object category : wizardsOrder) { + if (((Category) category).getId() + .equals(wizardCategory.getId())) { + + return ((Category) category).getDescriptorIds() + .indexOf(((IWizardDescriptor) object).getId()); + } + } + + } + + return -1; + } + } + + private static class InternalFilteredTree extends FilteredTree { + + private ResourceManager resources; + + private Label messageLabel; + + public InternalFilteredTree(Composite parent, int treeStyle, + PatternFilter filter, String message) { + super(parent, treeStyle, filter, true); + messageLabel.setText(message); + } + + protected void createControl(Composite parent, int treeStyle) { + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.verticalSpacing = 10; + setLayout(layout); + + if (parent.getLayout() instanceof GridLayout) { + setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + } + + if (showFilterControls) { + Composite composite = new Composite(this, SWT.NONE); + resources = new LocalResourceManager( + JFaceResources.getResources(), composite); + + composite.setBackground(parent.getBackground()); + composite.setLayoutData( + new GridData(SWT.FILL, SWT.TOP, true, false)); + composite.setFont(parent.getFont()); + GridLayout layout2 = new GridLayout(2, false); + layout2.marginWidth = 0; + layout2.marginHeight = 0; + layout2.horizontalSpacing = 32; + composite.setLayout(layout2); + + messageLabel = new Label(composite, SWT.NONE); + messageLabel.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, true)); + messageLabel.setFont(composite.getFont()); + messageLabel.setBackground(composite.getBackground()); + messageLabel.setForeground((Color) resources + .get(ColorUtils.toDescriptor("#323232"))); //$NON-NLS-1$ + + filterComposite = new Composite(composite, SWT.BORDER); + filterComposite.setBackground( + getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + GridLayout filterLayout = new GridLayout(2, false); + filterLayout.marginHeight = 0; + filterLayout.marginWidth = 0; + filterComposite.setLayout(filterLayout); + filterComposite.setFont(composite.getFont()); + + createFilterControls(filterComposite); + filterComposite.setLayoutData( + new GridData(SWT.FILL, SWT.BEGINNING, true, false)); + } + + treeComposite = new Composite(this, SWT.NONE); + GridLayout treeCompositeLayout = new GridLayout(); + treeCompositeLayout.marginHeight = 0; + treeCompositeLayout.marginWidth = 0; + treeComposite.setLayout(treeCompositeLayout); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + treeComposite.setLayoutData(data); + createTreeControl(treeComposite, treeStyle); + } + + @Override + protected void createFilterText(Composite parent) { + super.createFilterText(parent); + filterText.setForeground( + (Color) resources.get(ColorUtils.toDescriptor("#b2b2b2"))); //$NON-NLS-1$ + } + + @Override + protected void textChanged() { + super.textChanged(); + if (getFilterString() == null || getFilterString().equals("")) { //$NON-NLS-1$ + Display.getCurrent().timerExec( + (int) getRefreshJobDelay() * 3 / 2, new Runnable() { + + @Override + public void run() { + getViewer().expandAll(); + } + }); + } + } + } + + private static class ImportExportLabelProvider extends LabelProvider + implements IColorProvider { + + private ResourceManager resources; + + public ImportExportLabelProvider(ResourceManager resources) { + this.resources = resources; + } + + @Override + public Color getForeground(Object element) { + return null; + } + + @Override + public Color getBackground(Object element) { + return null; + } + + @Override + public String getText(Object element) { + //query the element for its label + IWorkbenchAdapter adapter = getAdapter(element); + if (adapter == null) { + return ""; //$NON-NLS-1$ + } + String label = adapter.getLabel(element); + + //return the decorated label + return decorateText(label, element); + } + + private IWorkbenchAdapter getAdapter(Object o) { + return Adapters.adapt(o, IWorkbenchAdapter.class); + } + + private String decorateText(String input, Object element) { + return input; + } + + @Override + public Image getImage(Object element) { + if (element instanceof IWizardCategory) { + return (Image) resources.get( + MindMapUI.getImages().get("icons/impexp/folder.png")); //$NON-NLS-1$ + } + + //obtain the base image by querying the element + IWorkbenchAdapter adapter = getAdapter(element); + if (adapter == null) { + return null; + } + ImageDescriptor descriptor = adapter.getImageDescriptor(element); + if (descriptor == null) { + return null; + } + + //add any annotations to the image descriptor + descriptor = decorateImage(descriptor, element); + + return (Image) resources.get(descriptor); + } + + private ImageDescriptor decorateImage(ImageDescriptor input, + Object element) { + return input; + } + } + + /* + * Class to create a control that shows a categorized tree of wizard types. + */ + protected class CategorizedWizardSelectionTree { + private final static int SIZING_LISTS_HEIGHT = 200; + + private IWizardCategory wizardCategories; + private String message; + private TreeViewer viewer; + + /** + * Constructor for CategorizedWizardSelectionTree + * + * @param categories + * root wizard category for the wizard type + * @param msg + * message describing what the user should choose from the + * tree. + */ + protected CategorizedWizardSelectionTree(IWizardCategory categories, + String msg) { + this.wizardCategories = categories; + this.message = msg; + } + + /** + * Create the tree viewer and a message describing what the user should + * choose from the tree. + * + * @param parent + * Composite on which the tree viewer is to be created + * @return Comoposite with all widgets + */ + protected Composite createControl(Composite parent) { + Font font = parent.getFont(); + + // create composite for page. + Composite outerContainer = new Composite(parent, SWT.NONE); + outerContainer.setLayout(new GridLayout()); + outerContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); + outerContainer.setFont(font); + + createFilteredTree(outerContainer); + layoutTopControl(viewer.getControl()); + + return outerContainer; + } + + /** + * Create the categorized tree viewer. + * + * @param parent + */ + @SuppressWarnings("unchecked") + private void createFilteredTree(Composite parent) { + // Create a FilteredTree for the categories and wizards + InternalFilteredTree filteredTree = new InternalFilteredTree(parent, + SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER + | SWT.FULL_SELECTION, + new WizardPatternFilter(), message); + viewer = filteredTree.getViewer(); + filteredTree.setFont(parent.getFont()); + filteredTree.setQuickSelectionMode(true); + + viewer.setContentProvider(new WizardContentProvider()); + viewer.setLabelProvider(new ImportExportLabelProvider(resources)); + DataTransferWizardCollectionComparator comparator = DataTransferWizardCollectionComparator.INSTANCE; + comparator.setWizardsOrder(wizardsOrder); + viewer.setComparator(comparator); + + ArrayList inputArray = new ArrayList(); + + if (wizardCategories != null) { + if (wizardCategories.getParent() == null) { + IWizardCategory[] children = wizardCategories + .getCategories(); + for (int i = 0; i < children.length; i++) { + inputArray.add(children[i]); + } + } else { + inputArray.add(wizardCategories); + } + } + + viewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS); + + AdaptableList input = new AdaptableList(inputArray); + + // filter wizard list according to capabilities that are enabled + viewer.addFilter(new WizardActivityFilter()); + + viewer.setInput(input); + } + + /** + * @return the categorized tree viewer + */ + protected TreeViewer getViewer() { + return viewer; + } + + /** + * Layout for the given control. + * + * @param control + */ + private void layoutTopControl(Control control) { + GridData data = new GridData(GridData.FILL_BOTH); + + int availableRows = DialogUtil.availableRows(control.getParent()); + + //Only give a height hint if the dialog is going to be too small + if (availableRows > 50) { + data.heightHint = SIZING_LISTS_HEIGHT; + } else { + data.heightHint = availableRows * 3; + } + + control.setLayoutData(data); + } + } + + protected ResourceManager resources; + + private TreeViewer treeViewer; + + protected List wizardsOrder; + + /** + * Constructor for import/export wizard page. + * + * @param aWorkbench + * current workbench + * @param currentSelection + * current selection + */ + protected ImportExportPage(IWorkbench aWorkbench, + IStructuredSelection currentSelection) { + super("importExportPage", aWorkbench, currentSelection, null, null); //$NON-NLS-1$ + setTitle(WorkbenchMessages.Select); + } + + @Override + public void createControl(Composite parent) { + Font font = parent.getFont(); + + // create composite for page. + Composite outerContainer = new Composite(parent, SWT.NONE); + resources = new LocalResourceManager(JFaceResources.getResources(), + outerContainer); + + outerContainer.setLayout(new GridLayout()); + outerContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); + outerContainer.setFont(font); + + Composite comp = createTreeViewer(outerContainer); + + Dialog.applyDialogFont(comp); + + restoreWidgetValues(); + + setControl(outerContainer); + + initialize(); + } + + /** + * Create the tree viewer from which a wizard is selected. + */ + protected abstract Composite createTreeViewer(Composite parent); + + /** + * Method to call when an item in one of the lists is double-clicked. Shows + * the first page of the selected wizard or expands a collapsed tree. + * + * @param event + */ + protected void treeDoubleClicked(DoubleClickEvent event) { + ISelection selection = event.getViewer().getSelection(); + IStructuredSelection ss = (IStructuredSelection) selection; + listSelectionChanged(ss); + + Object element = ss.getFirstElement(); + TreeViewer v = (TreeViewer) event.getViewer(); + if (v.isExpandable(element)) { + v.setExpandedState(element, !v.getExpandedState(element)); + } else if (element instanceof WorkbenchWizardElement) { + if (canFlipToNextPage()) { + getContainer().showPage(getNextPage()); + return; + } + } + getContainer().showPage(getNextPage()); + } + + /* + * Update the wizard's message based on the given (selected) wizard element. + */ + private void updateSelectedNode(WorkbenchWizardElement wizardElement) { + setErrorMessage(null); + if (wizardElement == null) { + updateMessage(); + setSelectedNode(null); + return; + } + + setSelectedNode(createWizardNode(wizardElement)); + setMessage(wizardElement.getDescription()); + } + + /* + * Update the wizard's message based on the currently selected tab and the + * selected wizard on that tab. + */ + protected void updateMessage() { + TreeViewer viewer = getTreeViewer(); + if (viewer != null) { + ISelection selection = viewer.getSelection(); + IStructuredSelection ss = (IStructuredSelection) selection; + Object sel = ss.getFirstElement(); + if (sel instanceof WorkbenchWizardElement) { + updateSelectedNode((WorkbenchWizardElement) sel); + } else { + setSelectedNode(null); + } + } else { + setMessage(null); + } + } + + /* + * Method to call whenever the selection in one of the lists has changed. + * Updates the wizard's message to relect the description of the currently + * selected wizard. + */ + protected void listSelectionChanged(ISelection selection) { + setErrorMessage(null); + IStructuredSelection ss = (IStructuredSelection) selection; + Object sel = ss.getFirstElement(); + if (sel instanceof WorkbenchWizardElement) { + WorkbenchWizardElement currentWizardSelection = (WorkbenchWizardElement) sel; + updateSelectedNode(currentWizardSelection); + } else { + updateSelectedNode(null); + } + } + + /* + * Create a wizard node given a wizard's descriptor. + */ + private IWizardNode createWizardNode(IWizardDescriptor element) { + return new WorkbenchWizardNode(this, element) { + @Override + public IWorkbenchWizard createWizard() throws CoreException { + return wizardElement.createWizard(); + } + }; + } + + /** + * Uses the dialog store to restore widget values to the values that they + * held last time this wizard was used to completion. + */ + protected void restoreWidgetValues() { + updateMessage(); + } + + /** + * Expands the wizard categories in this page's category viewer that were + * expanded last time this page was used. If a category that was previously + * expanded no longer exists then it is ignored. + */ + @SuppressWarnings("unchecked") + protected void expandPreviouslyExpandedCategories(String setting, + IWizardCategory wizardCategories, TreeViewer viewer) { + String[] expandedCategoryPaths = getDialogSettings().getArray(setting); + if (expandedCategoryPaths == null + || expandedCategoryPaths.length == 0) { + return; + } + + List categoriesToExpand = new ArrayList(expandedCategoryPaths.length); + + if (wizardCategories != null) { + for (int i = 0; i < expandedCategoryPaths.length; i++) { + IWizardCategory category = wizardCategories + .findCategory(new Path(expandedCategoryPaths[i])); + if (category != null) { + categoriesToExpand.add(category); + } + } + } + + if (!categoriesToExpand.isEmpty()) { + viewer.setExpandedElements(categoriesToExpand.toArray()); + } + + } + + /** + * Selects the wizard category and wizard in this page that were selected + * last time this page was used. If a category or wizard that was previously + * selected no longer exists then it is ignored. + */ + protected void selectPreviouslySelected(String setting, + IWizardCategory wizardCategories, final TreeViewer viewer) { + String selectedId = getDialogSettings().get(setting); + if (selectedId == null) { + return; + } + + if (wizardCategories == null) { + return; + } + + Object selected = wizardCategories.findCategory(new Path(selectedId)); + + if (selected == null) { + selected = wizardCategories.findWizard(selectedId); + + if (selected == null) { + // if we cant find either a category or a wizard, abort. + return; + } + } + + viewer.setSelection(new StructuredSelection(selected), true); + } + + /** + * Stores the collection of currently-expanded categories in this page's + * dialog store, in order to recreate this page's state in the next instance + * of this page. + */ + @SuppressWarnings("unchecked") + protected void storeExpandedCategories(String setting, TreeViewer viewer) { + Object[] expandedElements = viewer.getExpandedElements(); + List expandedElementPaths = new ArrayList(expandedElements.length); + for (int i = 0; i < expandedElements.length; ++i) { + if (expandedElements[i] instanceof IWizardCategory) { + expandedElementPaths.add(((IWizardCategory) expandedElements[i]) + .getPath().toString()); + } + } + getDialogSettings().put(setting, (String[]) expandedElementPaths + .toArray(new String[expandedElementPaths.size()])); + } + + /** + * Stores the currently-selected element in this page's dialog store, in + * order to recreate this page's state in the next instance of this page. + */ + protected void storeSelectedCategoryAndWizard(String setting, + TreeViewer viewer) { + Object selected = ((IStructuredSelection) viewer.getSelection()) + .getFirstElement(); + + if (selected != null) { + if (selected instanceof IWizardCategory) { + getDialogSettings().put(setting, + ((IWizardCategory) selected).getPath().toString()); + } else { + // else its a wizard + getDialogSettings().put(setting, + ((IWizardDescriptor) selected).getId()); + } + } + } + + /** + * When Finish is pressed, write widget values to the dialog store so that + * they will persist into the next invocation of the wizard page. + */ + public void saveWidgetValues() { + // do nothing by default - subclasses should override + } + + @Override + public IWizardPage getNextPage() { + ITriggerPoint triggerPoint = getTriggerPoint(); + + if (triggerPoint == null || WorkbenchActivityHelper + .allowUseOf(triggerPoint, getSelectedNode())) { + return super.getNextPage(); + } + return null; + } + + /** + * Get the trigger point for the wizard type, if one exists. + * + * @return the wizard's trigger point + */ + protected ITriggerPoint getTriggerPoint() { + return null; // default implementation + } + + /** + * Set the tree viewer that is used for this wizard selection page. + * + * @param viewer + */ + protected void setTreeViewer(TreeViewer viewer) { + treeViewer = viewer; + } + + /** + * Get the tree viewer that is used for this wizard selection page. + * + * @return tree viewer used for this wizard's selection page + */ + protected TreeViewer getTreeViewer() { + return treeViewer; + } + + /** + * Perform any initialization of the wizard page that needs to be done after + * widgets are created and main control is set. + */ + protected void initialize() { + // do nothing by default + } + + protected static List getWizardsOrder(String tag) { + List wizardsOrder = new ArrayList(); + loadWizardsOrder(wizardsOrder, tag); + return wizardsOrder; + } + + private static void loadWizardsOrder(List wizardsOrder, + String tag) { + Bundle bundle = Platform.getBundle(MindMapUIPlugin.PLUGIN_ID); + if (bundle == null) { + return; + } + + BundleResource xmLResource = new BundleResource(bundle, + new Path(WIZARDS_ORDER_XML_PATH)).resolve(); + if (xmLResource == null) { + MindMapUIPlugin.getDefault().getLog() + .log(new Status(IStatus.ERROR, MindMapUIPlugin.PLUGIN_ID, + "Failed to locate wizards order xml: " //$NON-NLS-1$ + + bundle.getSymbolicName() + "/" //$NON-NLS-1$ + + WIZARDS_ORDER_XML_PATH)); + return; + } + + URL listXMLURL = xmLResource.toPlatformURL(); + Element element = getWizardsOrderElement(listXMLURL); + if (element == null) { + return; + } + + Element orderEle = DOMUtils.getFirstChildElementByTag(element, tag); + + Iterator it = DOMUtils.childElementIterByTag(orderEle, + "category"); //$NON-NLS-1$ + while (it.hasNext()) { + Element categoryEle = it.next(); + + String categoryId = categoryEle.getAttribute("id"); //$NON-NLS-1$ + + List wizardIds = new ArrayList(); + for (Element wizardEle : DOMUtils.getChildElementsByTag(categoryEle, + "wizard")) { //$NON-NLS-1$ + wizardIds.add(wizardEle.getAttribute("id")); //$NON-NLS-1$ + } + wizardsOrder.add(new Category(categoryId, wizardIds)); + } + } + + private static Element getWizardsOrderElement(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 wizards order list from " //$NON-NLS-1$ + + xmlURL.toExternalForm(), + e)); + } + return null; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ImportExportWizard.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ImportExportWizard.java new file mode 100644 index 000000000..aac708b5d --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ImportExportWizard.java @@ -0,0 +1,96 @@ +package org.xmind.ui.internal.wizards; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.xmind.ui.mindmap.IMindMapImages; +import org.xmind.ui.mindmap.MindMapUI; + +/** + * The import/export wizard allows users to choose whether to show the import + * wizard or the export wizard. + * + * @since 3.2 + */ +public class ImportExportWizard extends Wizard { + /** + * Constant used to to specify to the import/export wizard which page should + * initially be shown. + */ + public static final String IMPORT = "import"; //$NON-NLS-1$ + /** + * Constant used to to specify to the import/export wizard which page should + * initially be shown. + */ + public static final String EXPORT = "export"; //$NON-NLS-1$ + + private IWorkbench workbench; + private IStructuredSelection selection; + private ImportExportPage importExportPage; + private String page = null; + + /** + * Create an import/export wizard and show the page with the given id. + * + * @param pageId + */ + public ImportExportWizard(String pageId) { + page = pageId; + } + + /** + * Subclasses must implement this IWizard method to perform any + * special finish processing for their wizard. + */ + @Override + public boolean performFinish() { + importExportPage.saveWidgetValues(); + return true; + } + + /** + * Creates the wizard's pages lazily. + */ + @Override + public void addPages() { + if (page.equals(IMPORT)) { + importExportPage = new ImportPage(this.workbench, this.selection); + } else if (page.equals(EXPORT)) { + importExportPage = new ExportPage(this.workbench, this.selection); + } + if (importExportPage != null) { + addPage(importExportPage); + } + } + + /** + * Initializes the wizard. + * + * @param aWorkbench + * the workbench + * @param currentSelection + * the current selection + */ + public void init(IWorkbench aWorkbench, + IStructuredSelection currentSelection) { + this.workbench = aWorkbench; + this.selection = currentSelection; + + ImageDescriptor wizardBannerImage = null; + if (IMPORT.equals(page)) { + wizardBannerImage = MindMapUI.getImages() + .getWizBan(IMindMapImages.WIZ_IMPORT); + setWindowTitle(WorkbenchMessages.ImportWizard_title); + } else if (EXPORT.equals(page)) { + wizardBannerImage = MindMapUI.getImages() + .getWizBan(IMindMapImages.WIZ_EXPORT); + setWindowTitle(WorkbenchMessages.ExportWizard_title); + } + if (wizardBannerImage != null) { + setDefaultPageImageDescriptor(wizardBannerImage); + } + setNeedsProgressMonitor(true); + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ImportPage.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ImportPage.java new file mode 100644 index 000000000..6a6998c5f --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/ImportPage.java @@ -0,0 +1,106 @@ +package org.xmind.ui.internal.wizards; + +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.activities.ITriggerPoint; +import org.eclipse.ui.internal.IWorkbenchHelpContextIds; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.eclipse.ui.internal.activities.ws.WorkbenchTriggerPoints; +import org.eclipse.ui.wizards.IWizardCategory; + +/** + * Wizard page class from which an import wizard is selected. + * + * @since 3.2 + */ +public class ImportPage extends ImportExportPage { + private static final String STORE_SELECTED_IMPORT_WIZARD_ID = DIALOG_SETTING_SECTION_NAME + + "STORE_SELECTED_IMPORT_WIZARD_ID"; //$NON-NLS-1$ + + private static final String STORE_EXPANDED_IMPORT_CATEGORIES = DIALOG_SETTING_SECTION_NAME + + "STORE_EXPANDED_IMPORT_CATEGORIES"; //$NON-NLS-1$ + + protected CategorizedWizardSelectionTree importTree; + + /** + * Constructor for import wizard selection page. + * + * @param aWorkbench + * @param currentSelection + */ + public ImportPage(IWorkbench aWorkbench, + IStructuredSelection currentSelection) { + super(aWorkbench, currentSelection); + wizardsOrder = ImportExportPage.getWizardsOrder("import-wizards"); //$NON-NLS-1$ + } + + @Override + protected void initialize() { + workbench.getHelpSystem().setHelp(getControl(), + IWorkbenchHelpContextIds.IMPORT_WIZARD_SELECTION_WIZARD_PAGE); + } + + @Override + protected Composite createTreeViewer(Composite parent) { + IWizardCategory root = WorkbenchPlugin.getDefault() + .getImportWizardRegistry().getRootCategory(); + importTree = new CategorizedWizardSelectionTree(root, + WorkbenchMessages.ImportWizard_selectWizard); + Composite importComp = importTree.createControl(parent); + importTree.getViewer() + .addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + listSelectionChanged(event.getSelection()); + } + }); + importTree.getViewer() + .addDoubleClickListener(new IDoubleClickListener() { + @Override + public void doubleClick(DoubleClickEvent event) { + treeDoubleClicked(event); + } + }); + setTreeViewer(importTree.getViewer()); + return importComp; + } + + @Override + public void saveWidgetValues() { + storeExpandedCategories(STORE_EXPANDED_IMPORT_CATEGORIES, + importTree.getViewer()); + storeSelectedCategoryAndWizard(STORE_SELECTED_IMPORT_WIZARD_ID, + importTree.getViewer()); + super.saveWidgetValues(); + } + + @Override + protected void restoreWidgetValues() { + IWizardCategory importRoot = WorkbenchPlugin.getDefault() + .getImportWizardRegistry().getRootCategory(); + expandPreviouslyExpandedCategories(STORE_EXPANDED_IMPORT_CATEGORIES, + importRoot, importTree.getViewer()); + selectPreviouslySelected(STORE_SELECTED_IMPORT_WIZARD_ID, importRoot, + importTree.getViewer()); + super.restoreWidgetValues(); + } + + @Override + protected ITriggerPoint getTriggerPoint() { + return getWorkbench().getActivitySupport().getTriggerPointManager() + .getTriggerPoint(WorkbenchTriggerPoints.IMPORT_WIZARDS); + } + + @Override + protected void updateMessage() { + setMessage(WorkbenchMessages.ImportExportPage_chooseImportWizard); + super.updateMessage(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/MarkerImportWizard.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/MarkerImportWizard.java index 7d1bd4945..44e803d28 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/MarkerImportWizard.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/MarkerImportWizard.java @@ -40,9 +40,7 @@ import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.IImportWizard; import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.widgets.FormText; @@ -50,7 +48,9 @@ import org.xmind.ui.browser.BrowserSupport; import org.xmind.ui.internal.MarkerImpExpUtils; import org.xmind.ui.internal.dialogs.DialogMessages; +import org.xmind.ui.internal.e4models.IModelConstants; import org.xmind.ui.internal.prefs.MarkerManagerPrefPage; +import org.xmind.ui.internal.utils.E4Utils; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.util.PrefUtils; @@ -97,8 +97,8 @@ protected MarkerImportWizardPage() { public void createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); - composite - .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + composite.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout gridLayout = new GridLayout(1, false); gridLayout.marginWidth = 5; gridLayout.marginHeight = 5; @@ -120,12 +120,12 @@ public void widgetDisposed(DisposeEvent e) { hookWidget(fromFileButton, SWT.Selection); Control fileGroup = createFileControls(composite); - fileGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); + fileGroup.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, false)); Label blank = new Label(composite, SWT.NONE); - blank.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, - false)); + blank.setLayoutData( + new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); blank.setText(" "); //$NON-NLS-1$ fromDirectoryButton = new Button(composite, SWT.RADIO); @@ -134,8 +134,8 @@ public void widgetDisposed(DisposeEvent e) { hookWidget(fromDirectoryButton, SWT.Selection); Control directoryGroup = createFolderGroup(composite); - directoryGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - false)); + directoryGroup.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, false)); setFileOrFolder(true); } @@ -156,14 +156,15 @@ protected Control createFileControls(Composite parent) { if (getSourcePath() != null) { fileInput.setText(getSourcePath()); } - fileInput.setLayoutData(new GridData(GridData.FILL, GridData.FILL, - true, false)); + fileInput.setLayoutData( + new GridData(GridData.FILL, GridData.FILL, true, false)); hookWidget(fileInput, SWT.Modify); hookWidget(fileInput, SWT.FocusIn); fileBrowseButton = new Button(group, SWT.PUSH); fileBrowseButton.setText(WizardMessages.ImportPage_Browse_text); - int width = fileBrowseButton.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; + int width = fileBrowseButton.computeSize(SWT.DEFAULT, + SWT.DEFAULT).x; GridData layoutData = new GridData(GridData.END, GridData.CENTER, false, false); layoutData.widthHint = Math.max(93, width); @@ -193,8 +194,8 @@ public void run() throws Exception { } } }); - descriptionText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, - true, false)); + descriptionText.setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, false)); ((GridData) descriptionText.getLayoutData()).horizontalSpan = 3; ((GridData) descriptionText.getLayoutData()).widthHint = 400; return descriptionText; @@ -216,15 +217,15 @@ private Control createFolderGroup(Composite parent) { if (getSourcePath() != null) { folderInput.setText(getSourcePath()); } - folderInput.setLayoutData(new GridData(GridData.FILL, - GridData.FILL, true, false)); + folderInput.setLayoutData( + new GridData(GridData.FILL, GridData.FILL, true, false)); hookWidget(folderInput, SWT.Modify); hookWidget(folderInput, SWT.FocusIn); folderBrowseButton = new Button(group, SWT.PUSH); folderBrowseButton.setText(WizardMessages.ImportPage_Browse_text); - int width = folderBrowseButton - .computeSize(SWT.DEFAULT, SWT.DEFAULT).x; + int width = folderBrowseButton.computeSize(SWT.DEFAULT, + SWT.DEFAULT).x; GridData layoutData = new GridData(GridData.END, GridData.CENTER, false, false); layoutData.widthHint = Math.max(93, width); @@ -257,8 +258,8 @@ protected void handleWidgetEvent(Event event) { } updateStatus(); } else if (event.type == SWT.FocusIn) { - fileInput.setSelection(new Point(0, fileInput.getText() - .length())); + fileInput.setSelection( + new Point(0, fileInput.getText().length())); } } else if (event.widget == fileBrowseButton) { openFileDialog(); @@ -273,8 +274,8 @@ protected void handleWidgetEvent(Event event) { } updateStatus(); } else if (event.type == SWT.FocusIn) { - folderInput.setSelection(new Point(0, folderInput.getText() - .length())); + folderInput.setSelection( + new Point(0, folderInput.getText().length())); } } else if (event.widget == folderBrowseButton) { openDirectoryDialog(); @@ -443,13 +444,9 @@ private void openMarkerView() { if (workbench != null) { IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); if (window != null) { - IWorkbenchPage page = window.getActivePage(); - if (page != null) { - try { - page.showView(MindMapUI.VIEW_MARKER); - } catch (PartInitException e) { - } - } + E4Utils.showPart(IModelConstants.COMMAND_SHOW_MODEL_PART, + window, IModelConstants.PART_ID_MARKERS, null, + IModelConstants.PART_STACK_ID_RIGHT); } } } @@ -466,4 +463,4 @@ public void init(IWorkbench workbench, IStructuredSelection selection) { this.workbench = workbench; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/TextExportWizard.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/TextExportWizard.java index 5096cf7bd..d613690b3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/TextExportWizard.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/TextExportWizard.java @@ -262,7 +262,7 @@ protected void addValidPages() { protected void doExport(IProgressMonitor monitor, Display display, Shell parentShell) - throws InvocationTargetException, InterruptedException { + throws InvocationTargetException, InterruptedException { MindMapUIPlugin.getDefault().getUsageDataCollector() .increase("ExportToTextCount"); //$NON-NLS-1$ @@ -368,4 +368,11 @@ protected String getSuggestedFileName() { return super.getSuggestedFileName() + EXT_TEXT_FILE; } -} \ No newline at end of file + @Override + protected boolean doExport() { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ExportToTxtCount"); //$NON-NLS-1$ + return super.doExport(); + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/WizardHandler.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/WizardHandler.java new file mode 100644 index 000000000..03df34755 --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/WizardHandler.java @@ -0,0 +1,252 @@ +package org.xmind.ui.internal.wizards; + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchCommandConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWizard; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.internal.IWorkbenchHelpContextIds; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.eclipse.ui.internal.WorkbenchPlugin; +import org.eclipse.ui.menus.UIElement; +import org.eclipse.ui.wizards.IWizardDescriptor; +import org.eclipse.ui.wizards.IWizardRegistry; + +/** + * Abstract handler for commands that launch the import, export and new wizards. + *

    + * This class is only intended to be extended by the three inner classes + * (Export, Import and New) defined here. + *

    + * + * @since 3.2 + */ +public abstract class WizardHandler extends AbstractHandler + implements IElementUpdater { + + /** + * Default handler for launching export wizards. + */ + public static final class Export extends WizardHandler { + private static final int SIZING_WIZARD_WIDTH = 470; + private static final int SIZING_WIZARD_HEIGHT = 550; + + @Override + protected String getWizardIdParameterId() { + return IWorkbenchCommandConstants.FILE_EXPORT_PARM_WIZARDID; + } + + @Override + protected IWizardRegistry getWizardRegistry() { + return PlatformUI.getWorkbench().getExportWizardRegistry(); + } + + @Override + protected void executeHandler(ExecutionEvent event) { + IWorkbenchWindow activeWorkbenchWindow = HandlerUtil + .getActiveWorkbenchWindow(event); + if (activeWorkbenchWindow == null) { + // action has been disposed + return; + } + ImportExportWizard wizard = new ImportExportWizard( + ImportExportWizard.EXPORT); + IStructuredSelection selectionToPass = getSelectionToUse(event); + + wizard.init(activeWorkbenchWindow.getWorkbench(), selectionToPass); + IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault() + .getDialogSettings(); + IDialogSettings wizardSettings = workbenchSettings + .getSection("ImportExportAction"); //$NON-NLS-1$ + if (wizardSettings == null) { + wizardSettings = workbenchSettings + .addNewSection("ImportExportAction"); //$NON-NLS-1$ + } + wizard.setDialogSettings(wizardSettings); + wizard.setForcePreviousAndNextButtons(true); + + Shell parent = activeWorkbenchWindow.getShell(); + WizardDialog dialog = new WizardDialog(parent, wizard); + dialog.create(); + dialog.getShell().setSize( + Math.max(SIZING_WIZARD_WIDTH, + dialog.getShell().getSize().x), + SIZING_WIZARD_HEIGHT); + activeWorkbenchWindow.getWorkbench().getHelpSystem().setHelp( + dialog.getShell(), IWorkbenchHelpContextIds.EXPORT_WIZARD); + dialog.open(); + } + + } + + /** + * Default handler for launching import wizards. + */ + public static final class Import extends WizardHandler { + private static final int SIZING_WIZARD_WIDTH = 470; + private static final int SIZING_WIZARD_HEIGHT = 550; + + @Override + protected String getWizardIdParameterId() { + return IWorkbenchCommandConstants.FILE_IMPORT_PARM_WIZARDID; + } + + @Override + protected IWizardRegistry getWizardRegistry() { + return PlatformUI.getWorkbench().getImportWizardRegistry(); + } + + @Override + protected void executeHandler(ExecutionEvent event) { + IWorkbenchWindow activeWorkbenchWindow = HandlerUtil + .getActiveWorkbenchWindow(event); + if (activeWorkbenchWindow == null) { + // action has been disposed + return; + } + ImportExportWizard wizard = new ImportExportWizard( + ImportExportWizard.IMPORT); + IStructuredSelection selectionToPass = getSelectionToUse(event); + + wizard.init(activeWorkbenchWindow.getWorkbench(), selectionToPass); + IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault() + .getDialogSettings(); + IDialogSettings wizardSettings = workbenchSettings + .getSection("ImportExportAction"); //$NON-NLS-1$ + if (wizardSettings == null) { + wizardSettings = workbenchSettings + .addNewSection("ImportExportAction"); //$NON-NLS-1$ + } + wizard.setDialogSettings(wizardSettings); + wizard.setForcePreviousAndNextButtons(true); + + Shell parent = activeWorkbenchWindow.getShell(); + WizardDialog dialog = new WizardDialog(parent, wizard); + dialog.create(); + dialog.getShell().setSize( + Math.max(SIZING_WIZARD_WIDTH, + dialog.getShell().getSize().x), + SIZING_WIZARD_HEIGHT); + activeWorkbenchWindow.getWorkbench().getHelpSystem().setHelp( + dialog.getShell(), IWorkbenchHelpContextIds.IMPORT_WIZARD); + dialog.open(); + } + + } + + /** + * This is the execution of the handler to open a wizard dialog. + * + * @param event + */ + protected abstract void executeHandler(ExecutionEvent event); + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + String wizardId = event.getParameter(getWizardIdParameterId()); + + IWorkbenchWindow activeWindow = HandlerUtil + .getActiveWorkbenchWindowChecked(event); + + if (wizardId == null) { + executeHandler(event); + } else { + + IWizardRegistry wizardRegistry = getWizardRegistry(); + IWizardDescriptor wizardDescriptor = wizardRegistry + .findWizard(wizardId); + if (wizardDescriptor == null) { + throw new ExecutionException("unknown wizard: " + wizardId); //$NON-NLS-1$ + } + + try { + IWorkbenchWizard wizard = wizardDescriptor.createWizard(); + wizard.init(PlatformUI.getWorkbench(), + getSelectionToUse(event)); + + if (wizardDescriptor.canFinishEarly() + && !wizardDescriptor.hasPages()) { + wizard.performFinish(); + return null; + } + + Shell parent = activeWindow.getShell(); + WizardDialog dialog = new WizardDialog(parent, wizard); + dialog.create(); + dialog.open(); + + } catch (CoreException ex) { + throw new ExecutionException("error creating wizard", ex); //$NON-NLS-1$ + } + + } + + return null; + } + + /** + * Returns a structured selection based on the event to initialize the + * wizard with. + * + * @param event + * the event object containing information about the current + * state of the application + * @return the current structured selection of the application + */ + protected IStructuredSelection getSelectionToUse(ExecutionEvent event) { + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (selection instanceof IStructuredSelection) { + return (IStructuredSelection) selection; + } + return StructuredSelection.EMPTY; + } + + @Override + public void updateElement(UIElement element, Map parameters) { + + String wizardId = (String) parameters.get(getWizardIdParameterId()); + if (wizardId == null) + return; + IWizardDescriptor wizard = getWizardRegistry().findWizard(wizardId); + if (wizard != null) { + element.setText(NLS.bind(WorkbenchMessages.WizardHandler_menuLabel, + wizard.getLabel())); + element.setTooltip(wizard.getDescription()); + element.setIcon(wizard.getImageDescriptor()); + } + } + + /** + * Returns the id of the parameter used to indicate which wizard this + * command should launch. + * + * @return The id of the parameter used to indicate which wizard this + * command should launch. + */ + protected abstract String getWizardIdParameterId(); + + /** + * Returns the wizard registry for the concrete WizardHandler + * implementation class. + * + * @return The wizard registry for the concrete WizardHandler + * implementation class. + */ + protected abstract IWizardRegistry getWizardRegistry(); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/WorkbookImporter.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/WorkbookImporter.java index 57590a791..47b8ddce6 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/WorkbookImporter.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/WorkbookImporter.java @@ -35,6 +35,7 @@ public void build() throws InvocationTargetException, InterruptedException { } catch (Exception e) { throw new InvocationTargetException(e); } + postBuilded(); } } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/XMind2008Importer.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/XMind2008Importer.java index 87ae6cdf6..afb7e7637 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/XMind2008Importer.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/XMind2008Importer.java @@ -21,6 +21,7 @@ import org.xmind.core.io.DirectoryStorage; import org.xmind.core.io.IStorage; import org.xmind.core.util.CloneHandler; +import org.xmind.ui.internal.MindMapUIPlugin; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.wizards.MindMapImporter; @@ -31,6 +32,8 @@ public XMind2008Importer(String sourcePath, IWorkbook targetWorkbook) { } public void build() throws InvocationTargetException, InterruptedException { + MindMapUIPlugin.getDefault().getUsageDataCollector() + .increase("ImportFromXMind2008Count"); //$NON-NLS-1$ try { IStorage storage = createStorage(); try { @@ -46,6 +49,7 @@ public void build() throws InvocationTargetException, InterruptedException { } catch (Exception e) { throw new InvocationTargetException(e); } + postBuilded(); } private IStorage createStorage() { diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/wizards_order.xml b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/wizards_order.xml new file mode 100644 index 000000000..7da433a4c --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/wizards/wizards_order.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/workbench/Perspective.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/workbench/Perspective.java index 9ae70ddb8..4a44aa1ae 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/workbench/Perspective.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/internal/workbench/Perspective.java @@ -13,12 +13,15 @@ *******************************************************************************/ package org.xmind.ui.internal.workbench; +import java.lang.reflect.Field; + +import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; import org.eclipse.swt.graphics.Point; import org.eclipse.ui.IFolderLayout; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPerspectiveFactory; -import org.eclipse.ui.IPlaceholderFolderLayout; -import org.xmind.ui.mindmap.MindMapUI; +import org.eclipse.ui.internal.e4.compatibility.ModeledFolderLayout; +import org.xmind.ui.internal.e4models.IModelConstants; /** * Mind Mapping Perspective @@ -27,70 +30,114 @@ */ public class Perspective implements IPerspectiveFactory { - public static final String CONSOLE_VIEW_ID = "org.eclipse.ui.console.ConsoleView"; //$NON-NLS-1$ - public static final String OUTLINE_VIEW_ID = "org.eclipse.ui.views.ContentOutline"; //$NON-NLS-1$ - public static final String PROPERTIES_VIEW_ID = "org.eclipse.ui.views.PropertySheet"; //$NON-NLS-1$ +// public static final String CONSOLE_VIEW_ID = "org.eclipse.ui.console.ConsoleView"; //$NON-NLS-1$ +// public static final String OUTLINE_VIEW_ID = "org.eclipse.ui.views.ContentOutline"; //$NON-NLS-1$ +// public static final String PROPERTIES_VIEW_ID = "org.eclipse.ui.views.PropertySheet"; //$NON-NLS-1$ + +// public static final String STACK_NAVIGATORS = "org.xmind.ui.stack.navigators"; //$NON-NLS-1$ +// public static final String STACK_INSPECTORS = "org.xmind.ui.stack.inspectors"; //$NON-NLS-1$ +// public static final String STACK_ASSISTANTS = "org.xmind.ui.stack.assistants"; //$NON-NLS-1$ +// public static final String STACK_LIBRARIES = "org.xmind.ui.stack.libraries"; //$NON-NLS-1$ - public static final String STACK_NAVIGATORS = "org.xmind.ui.stack.navigators"; //$NON-NLS-1$ - public static final String STACK_INSPECTORS = "org.xmind.ui.stack.inspectors"; //$NON-NLS-1$ - public static final String STACK_ASSISTANTS = "org.xmind.ui.stack.assistants"; //$NON-NLS-1$ - public static final String STACK_LIBRARIES = "org.xmind.ui.stack.libraries"; //$NON-NLS-1$ + public static final String STACK_RIGHT = "org.xmind.ui.stack.right"; //$NON-NLS-1$ protected float getRatio(float width, boolean horizontal) { Point size = Util.getInitialWindowSize(); return width / (horizontal ? size.x : size.y); } - public void createInitialLayout(IPageLayout pageLayout) { - createLibrariesStack(pageLayout); - createNavigatorsStack(pageLayout); - createInspectorsStack(pageLayout); - createAssistantsStack(pageLayout); - - pageLayout.addShowViewShortcut(OUTLINE_VIEW_ID); - pageLayout.addShowViewShortcut(MindMapUI.VIEW_OVERVIEW); - pageLayout.addShowViewShortcut(MindMapUI.VIEW_MARKER); - pageLayout.addShowViewShortcut(MindMapUI.VIEW_NOTES); - pageLayout.addShowViewShortcut(PROPERTIES_VIEW_ID); - pageLayout.addShowViewShortcut(MindMapUI.VIEW_THEMES); - pageLayout.addShowViewShortcut(MindMapUI.VIEW_REVISIONS); - pageLayout.addShowViewShortcut(MindMapUI.VIEW_INSPECTOR); + private Field getField(Class type, String name) { + while (!type.equals(Object.class)) { + try { + return type.getDeclaredField(name); + } catch (Exception exc) { + type = type.getSuperclass(); + } + } + return null; } - private void createNavigatorsStack(IPageLayout pageLayout) { - IFolderLayout layout = pageLayout.createFolder(STACK_NAVIGATORS, - IPageLayout.RIGHT, 1f - getRatio(250, true), - pageLayout.getEditorArea()); - layout.addView(OUTLINE_VIEW_ID); - layout.addView(MindMapUI.VIEW_OVERVIEW); - layout.addPlaceholder(MindMapUI.VIEW_REVISIONS); - layout.addPlaceholder(MindMapUI.VIEW_SPELLING); - } + public void createInitialLayout(IPageLayout pageLayout) { - private void createInspectorsStack(IPageLayout pageLayout) { - IFolderLayout layout = pageLayout.createFolder(STACK_INSPECTORS, - IPageLayout.BOTTOM, 0.5f, STACK_NAVIGATORS); - layout.addView(PROPERTIES_VIEW_ID); - layout.addView(MindMapUI.VIEW_MARKER); - layout.addPlaceholder(MindMapUI.VIEW_INSPECTOR); - } + IFolderLayout rightLayout = pageLayout.createFolder(STACK_RIGHT, + IPageLayout.RIGHT, 1f, pageLayout.getEditorArea()); + if (rightLayout instanceof ModeledFolderLayout) { + try { + Field partStackField = getField(ModeledFolderLayout.class, + "folderModel"); //$NON-NLS-1$ + boolean oldAccessible = partStackField.isAccessible(); + partStackField.setAccessible(true); + Object partStack = partStackField.get(rightLayout); + partStackField.setAccessible(oldAccessible); + if (partStack instanceof MPartStack) { + ((MPartStack) partStack).getTags().add("RightStack"); //$NON-NLS-1$ + } + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + rightLayout.addView(IModelConstants.PART_ID_PROPERTIES); - private void createAssistantsStack(IPageLayout pageLayout) { - IPlaceholderFolderLayout layout = pageLayout.createPlaceholderFolder( - STACK_ASSISTANTS, IPageLayout.BOTTOM, 1f - getRatio(280, false), - pageLayout.getEditorArea()); - layout.addPlaceholder(MindMapUI.VIEW_NOTES); - layout.addPlaceholder(MindMapUI.VIEW_THEMES); - layout.addPlaceholder(MindMapUI.VIEW_COMMENTS); - layout.addPlaceholder(CONSOLE_VIEW_ID); - } +// rightLayout.addPlaceholder(OUTLINE_VIEW_ID); +// rightLayout.addPlaceholder(MindMapUI.VIEW_MARKER); +// rightLayout.addPlaceholder(MindMapUI.VIEW_THEMES); +// rightLayout.addPlaceholder(MindMapUI.VIEW_NOTES); +// rightLayout.addPlaceholder(MindMapUI.VIEW_COMMENTS); - private void createLibrariesStack(IPageLayout pageLayout) { - IPlaceholderFolderLayout layout = pageLayout.createPlaceholderFolder( - STACK_LIBRARIES, IPageLayout.LEFT, getRatio(400, true), - pageLayout.getEditorArea()); - layout.addPlaceholder(MindMapUI.VIEW_BROSWER); - layout.addPlaceholder(MindMapUI.VIEW_BLACKBOX); +// createLibrariesStack(pageLayout); +// createNavigatorsStack(pageLayout); +// createInspectorsStack(pageLayout); +// createAssistantsStack(pageLayout); +// +// pageLayout.addShowViewShortcut(OUTLINE_VIEW_ID); +// pageLayout.addShowViewShortcut(MindMapUI.VIEW_OVERVIEW); +// pageLayout.addShowViewShortcut(MindMapUI.VIEW_MARKER); +// pageLayout.addShowViewShortcut(MindMapUI.VIEW_NOTES); +// pageLayout.addShowViewShortcut(PROPERTIES_VIEW_ID); +// pageLayout.addShowViewShortcut(MindMapUI.VIEW_THEMES); +// pageLayout.addShowViewShortcut(MindMapUI.VIEW_REVISIONS); +// pageLayout.addShowViewShortcut(MindMapUI.VIEW_INSPECTOR); } -} \ No newline at end of file +// private void createNavigatorsStack(IPageLayout pageLayout) { +// IFolderLayout layout = pageLayout.createFolder(STACK_NAVIGATORS, +// IPageLayout.RIGHT, 1f - getRatio(250, false), +// pageLayout.getEditorArea()); +// layout.addView(OUTLINE_VIEW_ID); +// layout.addView(MindMapUI.VIEW_OVERVIEW); +// layout.addPlaceholder(MindMapUI.VIEW_REVISIONS); +// layout.addPlaceholder(MindMapUI.VIEW_SPELLING); +// } +// +// private void createInspectorsStack(IPageLayout pageLayout) { +// IFolderLayout layout = pageLayout.createFolder(STACK_INSPECTORS, +// IPageLayout.RIGHT, 1f - getRatio(250, false), +// pageLayout.getEditorArea()); +// layout.addPlaceholder(PROPERTIES_VIEW_ID); +// layout.addView(MindMapUI.VIEW_MARKER); +// layout.addPlaceholder(MindMapUI.VIEW_INSPECTOR); +// } +// +// private void createAssistantsStack(IPageLayout pageLayout) { +// IPlaceholderFolderLayout layout = pageLayout.createPlaceholderFolder( +// STACK_ASSISTANTS, IPageLayout.RIGHT, 1f - getRatio(250, false), +// pageLayout.getEditorArea()); +// layout.addPlaceholder(MindMapUI.VIEW_NOTES); +// layout.addPlaceholder(MindMapUI.VIEW_THEMES); +// layout.addPlaceholder(MindMapUI.VIEW_COMMENTS); +// layout.addPlaceholder(CONSOLE_VIEW_ID); +// } +// +// private void createLibrariesStack(IPageLayout pageLayout) { +// IPlaceholderFolderLayout layout = pageLayout.createPlaceholderFolder( +// STACK_LIBRARIES, IPageLayout.LEFT, getRatio(400, true), +// pageLayout.getEditorArea()); +// layout.addPlaceholder(MindMapUI.VIEW_BROSWER); +// layout.addPlaceholder(MindMapUI.VIEW_BLACKBOX); +// } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IDrillDownTraceService.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IDrillDownTraceService.java index db9402eab..3c30b10d9 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IDrillDownTraceService.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IDrillDownTraceService.java @@ -20,6 +20,8 @@ public interface IDrillDownTraceService extends IViewerService { + void init(List centralTopics); + List getCentralTopics(); ITopic getCurrentCentralTopic(); @@ -34,4 +36,4 @@ public interface IDrillDownTraceService extends IViewerService { void removeTraceListener(IDrillDownTraceListener listener); -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IMindMapImages.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IMindMapImages.java index 292fd88c6..b2a78eabf 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IMindMapImages.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IMindMapImages.java @@ -1,13 +1,13 @@ /* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. - * + * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), + * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. - * + * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ @@ -45,18 +45,19 @@ public String getId() { String PATH_WIZ = PATH + "wizban/"; //$NON-NLS-1$ String PATH_PROP = PATH + "prop/"; //$NON-NLS-1$ - String XMIND_ICON = PATH + "xmind.16.gif"; //$NON-NLS-1$ + String XMIND_ICON = PATH + "xmind.16.png"; //$NON-NLS-1$ + String XMIND_FILE_ICON = PATH + "xmind_file.16.png"; //$NON-NLS-1$ String ACTUAL_SIZE = "actualsize.png"; //$NON-NLS-1$ String ACTUAL_SIZE_SMALL = "actualsize_small.png"; //$NON-NLS-1$ - String ADD = "add.gif"; //$NON-NLS-1$ + String ADD = "add.png"; //$NON-NLS-1$ String ADD_COLUMN = "add_column.gif"; //$NON-NLS-1$ String ADD_MARKER = "add_marker.gif"; //$NON-NLS-1$ String ADD_THEME = "add_theme.gif"; //$NON-NLS-1$ String ATTACHMENT = "attachment.gif"; //$NON-NLS-1$ String BOUNDARY = "boundary.png"; //$NON-NLS-1$ String CENTRAL = "central.png"; //$NON-NLS-1$ - String DELETE = "delete_edit.gif"; //$NON-NLS-1$ + String DELETE = "remove.png"; //$NON-NLS-1$ String DONE = "step_done.gif"; //$NON-NLS-1$ String DOWN_TRIANGLE = "down_triangle.gif"; //$NON-NLS-1$ String DRILL_UP = "drill_up.png"; //$NON-NLS-1$ @@ -64,7 +65,7 @@ public String getId() { String FILTER = "filter.gif"; //$NON-NLS-1$ String FIT_SELECTION = "fitselection.png"; //$NON-NLS-1$ String FIT_SIZE = "fitsize.png"; //$NON-NLS-1$ - String FLOATING = "floating.gif"; //$NON-NLS-1$ + String FLOATING = "floating.png"; //$NON-NLS-1$ String HELP = "inspector.png"; //$NON-NLS-1$ String HYPERLINK = "hyperlink.png"; //$NON-NLS-1$ String INSERT_AFTER = "insertafter.png"; //$NON-NLS-1$ @@ -74,7 +75,7 @@ public String getId() { String INSERT_IMAGE = "insertimage.png"; //$NON-NLS-1$ String INSERT_PARENT = "insertparent.png"; //$NON-NLS-1$ String INSERT_SUB = "insertsub.png"; //$NON-NLS-1$ - String LABEL = "label.gif"; //$NON-NLS-1$ + String LABEL = "label.png"; //$NON-NLS-1$ String LEGEND = "legend.gif"; //$NON-NLS-1$ String LEGEND_RESET = "legend_reset.gif"; //$NON-NLS-1$ String LINK = "link.gif"; //$NON-NLS-1$ @@ -90,12 +91,12 @@ public String getId() { String NEWMAP = "newmap.gif"; //$NON-NLS-1$ String NEW_SHEET_FROM_TEMPLATE = "new_sheet_from_template.gif"; //$NON-NLS-1$ String NEWMAP_DIALOG = "newmap_dialog.png"; //$NON-NLS-1$ - String NOTES = "notes.gif"; //$NON-NLS-1$ + String NOTES = "notes.png"; //$NON-NLS-1$ String OPEN = "fldr_obj.gif"; //$NON-NLS-1$ // String PROPERTIES = "prop_ps.gif"; //$NON-NLS-1$ // String REGISTER = "prop_ps.gif"; //$NON-NLS-1$ - String REMOVE = "trash.gif"; //$NON-NLS-1$ + String REMOVE = "trash.png"; //$NON-NLS-1$ String RELATIONSHIP = "relationship.gif"; //$NON-NLS-1$ String SHEET = "sheet.png"; //$NON-NLS-1$ String SHOWALL = "showall.png"; //$NON-NLS-1$ @@ -105,7 +106,7 @@ public String getId() { String STRIKETHROUGH = "strikethrough.gif"; //$NON-NLS-1$ String STYLES = "javaassist_co.gif"; //$NON-NLS-1$ String SUMMARY = "summary.gif"; //$NON-NLS-1$ - String SUMMARY_TOPIC = "summary_topic.gif"; //$NON-NLS-1$ + String SUMMARY_TOPIC = "summary_topic.png"; //$NON-NLS-1$ String SYNCED = "synced.gif"; //$NON-NLS-1$ String ZOOMOUT = "zoomout.png"; //$NON-NLS-1$ String ZOOMIN = "zoomin.png"; //$NON-NLS-1$ @@ -122,30 +123,37 @@ public String getId() { String UNLOCK = "unlock.gif"; //$NON-NLS-1$ String NUMBERING_INHERIT = "inherited.gif"; //$NON-NLS-1$ - String ALIGN_CENTER = "align_center.gif"; //$NON-NLS-1$ - String ALIGN_LEFT = "align_left.gif"; //$NON-NLS-1$ - String ALIGN_RIGHT = "align_right.gif"; //$NON-NLS-1$ + String ALIGN_CENTER = "align_center.png"; //$NON-NLS-1$ + String ALIGN_LEFT = "align_left.png"; //$NON-NLS-1$ + String ALIGN_RIGHT = "align_right.png"; //$NON-NLS-1$ - String FONT = "text_font.gif"; //$NON-NLS-1$ + String FONT = "text_font.png"; //$NON-NLS-1$ String TEXT_BACKGROUND = "text_background.gif"; //$NON-NLS-1$ String TEXT_FOREGROUND = "text_foreground.gif"; //$NON-NLS-1$ - String TEXT_BOLD = "text_bold.gif"; //$NON-NLS-1$ - String TEXT_FONT = "text_font.gif"; //$NON-NLS-1$ - String TEXT_ITALIC = "text_italic.gif"; //$NON-NLS-1$ - String TEXT_STRIKEOUT = "text_strikeout.gif"; //$NON-NLS-1$ - String TEXT_UNDERLINE = "text_underline.gif"; //$NON-NLS-1$ - String LINE_INDENT = "text_indent.gif"; //$NON-NLS-1$ - String LINE_OUTDENT = "text_outdent.gif"; //$NON-NLS-1$ + String TEXT_BOLD = "text_bold.png"; //$NON-NLS-1$ + String TEXT_FONT = "text_font.png"; //$NON-NLS-1$ + String TEXT_ITALIC = "text_italic.png"; //$NON-NLS-1$ + String TEXT_STRIKEOUT = "text_strikeout.png"; //$NON-NLS-1$ + String TEXT_UNDERLINE = "text_underline.png"; //$NON-NLS-1$ + String LINE_INDENT = "text_indent.png"; //$NON-NLS-1$ + String LINE_OUTDENT = "text_outdent.png"; //$NON-NLS-1$ + + String TEXT_MANUAL = "text_manual.png"; //$NON-NLS-1$ + String TEXT_LOWERCASE = "text_lowercase.png"; //$NON-NLS-1$ + String TEXT_UPPERCASE = "text_uppercase.png"; //$NON-NLS-1$ + String TEXT_CAPITALIZE = "text_capitalize.png"; //$NON-NLS-1$ String UNDO = "undo.gif"; //$NON-NLS-1$ String REDO = "redo.gif"; //$NON-NLS-1$ String DEFAULT_THEME = "defaultTheme.gif"; //$NON-NLS-1$ - String STAR = "star.gif"; //$NON-NLS-1$ + String STAR = "star.png"; //$NON-NLS-1$ String PIN = "pin.png"; //$NON-NLS-1$ String THUMBNAIL_LOST = "thumbnail.png"; //$NON-NLS-1$ + String SELECT = "select.png"; //$NON-NLS-1$ + // String BRAINY = "brainy.16.gif"; //$NON-NLS-1$ // String BRAINY_FILE = "xmap_file.gif"; //$NON-NLS-1$ // String ABOUT = "about2.png"; //$NON-NLS-1$ @@ -163,36 +171,39 @@ public String getId() { String OPAQUE = PATH_PROP + "opaque.gif"; //$NON-NLS-1$ - String LINE_THINNEST = PATH_PROP + "line_thinnest.gif"; //$NON-NLS-1$ - String LINE_THIN = PATH_PROP + "line_thin.gif"; //$NON-NLS-1$ - String LINE_MEDIUM = PATH_PROP + "line_medium.gif"; //$NON-NLS-1$ - String LINE_FAT = PATH_PROP + "line_fat.gif"; //$NON-NLS-1$ - String LINE_FATTEST = PATH_PROP + "line_fattest.gif"; //$NON-NLS-1$ + String LINE_NONE = PATH_PROP + "ic_none.png";////$NON-NLS-1$ + String LINE_THINNEST = PATH_PROP + "line_thinnest.png"; //$NON-NLS-1$ + String LINE_THIN = PATH_PROP + "line_thin.png"; //$NON-NLS-1$ + String LINE_MEDIUM = PATH_PROP + "line_medium.png"; //$NON-NLS-1$ + String LINE_FAT = PATH_PROP + "line_fat.png"; //$NON-NLS-1$ + String LINE_FATTEST = PATH_PROP + "line_fattest.png"; //$NON-NLS-1$ - String PATTERN_SOLID = PATH_PROP + "pattern_solid.gif"; //$NON-NLS-1$ - String PATTERN_DOT = PATH_PROP + "pattern_dot.gif"; //$NON-NLS-1$ - String PATTERN_DASH = PATH_PROP + "pattern_dash.gif"; //$NON-NLS-1$ - String PATTERN_DASHDOT = PATH_PROP + "pattern_dashdot.gif"; //$NON-NLS-1$ - String PATTERN_DASHDOTDOT = PATH_PROP + "pattern_dashdotdot.gif"; //$NON-NLS-1$ + String PATTERN_SOLID = PATH_PROP + "pattern_solid.png"; //$NON-NLS-1$ + String PATTERN_DOT = PATH_PROP + "pattern_dot.png"; //$NON-NLS-1$ + String PATTERN_DASH = PATH_PROP + "pattern_dash.png"; //$NON-NLS-1$ + String PATTERN_DASHDOT = PATH_PROP + "pattern_dashdot.png"; //$NON-NLS-1$ + String PATTERN_DASHDOTDOT = PATH_PROP + "pattern_dashdotdot.png"; //$NON-NLS-1$ String DIRECTORY = PATH + "misc/directory.gif"; //$NON-NLS-1$ String RIGHT = PATH + "misc/complete_status.gif"; //$NON-NLS-1$ String WRONG = PATH + "misc/close_view.gif"; //$NON-NLS-1$ String BLANK = PATH + "misc/blank.gif"; //$NON-NLS-1$ - String ENCRYPTED_THUMBNAIL = PATH + "misc/encrypted_thumbnail.jpg"; //$NON-NLS-1$ + String ENCRYPTED_THUMBNAIL = PATH + "misc/encrypted_thumbnail.png"; //$NON-NLS-1$ String DEFAULT_THUMBNAIL = PATH + "misc/default_thumbnail.jpg"; //$NON-NLS-1$ String MISSING_IMAGE = PATH + "misc/missing_image.png"; //$NON-NLS-1$ String UNKNOWN_FILE = "unknownfile.gif"; //$NON-NLS-1$ - String TEXT_MANUAL = "text-manual.png"; //$NON-NLS-1$ - String TEXT_LOWERCASE = "text-lowercase.png"; //$NON-NLS-1$ - String TEXT_UPPERCASE = "text-uppercase.png"; //$NON-NLS-1$ - String TEXT_CAPITALIZE = "text-capitalize.png"; //$NON-NLS-1$ - String ITEM = "item.png"; //$NON-NLS-1$ String ITEM_2 = "item_2.png"; //$NON-NLS-1$ + String DUPLICATE = "duplicate.png"; //$NON-NLS-1$ + String INSERT_CALLOUT = "insertcallout.png"; //$NON-NLS-1$ + + String XMIND_WATERMARK = PATH + "xmind_watermark.png"; //$NON-NLS-1$ + + String WARNING_ICON = PATH + "misc/warning.png"; //$NON-NLS-1$ + CursorFactory CURSOR_ADD = new CursorFactory("add") { //$NON-NLS-1$ public Cursor createCursor(IMindMapImages images) { return images.createCursor(getId(), 4, 3); @@ -270,4 +281,4 @@ ImageDescriptor getFileIcon(String adaptedPath, Cursor createCursor(String name, int hotX, int hotY); -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IResourceManager.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IResourceManager.java index 722306943..e469385e0 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IResourceManager.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/IResourceManager.java @@ -56,8 +56,8 @@ public interface IResourceManager { /** * Finds a resource located at the specified URI. *

    - * The URI must be of the specification: - * schema:path : + * The URI must be of the specification: schema:path + * : *

      *
    • marker:system/GROUP_ID/MARKER_ID * returns a {@link IMarker} representing a marker in the system marker @@ -165,10 +165,13 @@ public interface IResourceManager { */ String toResourceURI(Object resource); + @Deprecated List getSystemTemplates(); List getUserTemplates(); + List getSystemTemplateGroups(); + boolean isSystemTemplate(ITemplate template); boolean isUserTemplate(ITemplate template); @@ -186,4 +189,4 @@ ITemplate addUserTemplateFromWorkbookURI(URI sourceWorkbookURI) void removeResourceManagerListener(IResourceManagerListener listener); -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/ITemplateGroup.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/ITemplateGroup.java new file mode 100644 index 000000000..ed9a0c69a --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/ITemplateGroup.java @@ -0,0 +1,15 @@ +package org.xmind.ui.mindmap; + +import java.util.List; + +public interface ITemplateGroup { + + String getName(); + + void setName(String name); + + List getTemplates(); + + void setTemplates(List templates); + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/MindMapUI.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/MindMapUI.java index 44962bab7..ccebdf0a3 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/MindMapUI.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/mindmap/MindMapUI.java @@ -355,6 +355,16 @@ public class MindMapUI { */ public static final String PARAM_NUMBERING_PREPENDING = "numbering.prepending"; //$NON-NLS-1$ + /** + * Request parameter: the numbering depth of the 'modify numbering' request. + * + *
      + *
      Values:
      + *
      String
      + *
      + */ + public static final String PARAM_NUMBERING_DEPTH = "numbering.depth"; //$NON-NLS-1$ + /** * Request parameter: the dragging point's id of a 'move relationship' * request. diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/prefs/PrefConstants.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/prefs/PrefConstants.java index 33bab474e..ecfcfea1f 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/prefs/PrefConstants.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/prefs/PrefConstants.java @@ -1,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ package org.xmind.ui.prefs; @@ -35,6 +32,11 @@ public class PrefConstants { */ public static final String OVERLAPS_ALLOWED = "overlapsAllowed"; //$NON-NLS-1$ + /** + * + */ + public static final String MANUAL_LAYOUT_ALLOWED = "manualLayoutAllowed"; //$NON-NLS-1$ + /** * */ @@ -73,6 +75,11 @@ public class PrefConstants { /** * */ + public static final String SHOW_OVERVIEW = "showOverview"; //$NON-NLS-1$ + + /** + * + */ public static final String HOME_MAP_LOCATION = "homeMapLocation"; //$NON-NLS-1$ public static final String CREATE_ATTACHMENT = "CREATE_ATTACHMENT"; //$NON-NLS-1$ @@ -141,4 +148,4 @@ public class PrefConstants { public static final String SAVE_WIZARDS = "saveWizards"; //$NON-NLS-1$ public static final String DEFAULT_SAVE_WIZARD = "defaultSaveWizardId"; //$NON-NLS-1$ -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/properties/DecorationLabelProvider.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/properties/DecorationLabelProvider.java index 452add982..29ca1f645 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/properties/DecorationLabelProvider.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/properties/DecorationLabelProvider.java @@ -17,9 +17,11 @@ import org.eclipse.swt.graphics.Image; import org.xmind.ui.decorations.IDecorationDescriptor; import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.resources.ImageDescriptorProvider; import org.xmind.ui.viewers.ImageCachedLabelProvider; -public class DecorationLabelProvider extends ImageCachedLabelProvider { +public class DecorationLabelProvider extends ImageCachedLabelProvider + implements ImageDescriptorProvider { public String getText(Object element) { IDecorationDescriptor descriptor; @@ -31,8 +33,8 @@ public String getText(Object element) { } else { descriptor = null; } - return descriptor != null ? descriptor.getName() : super - .getText(element); + return descriptor != null ? descriptor.getName() + : super.getText(element); } protected Image createImage(Object element) { @@ -52,4 +54,21 @@ protected Image createImage(Object element) { } return null; } -} \ No newline at end of file + + @Override + public ImageDescriptor getImageDescriptor(Object element) { + IDecorationDescriptor descriptor; + if (element instanceof IDecorationDescriptor) { + descriptor = (IDecorationDescriptor) element; + } else if (element instanceof String) { + descriptor = MindMapUI.getDecorationManager() + .getDecorationDescriptor((String) element); + } else { + descriptor = null; + } + if (descriptor != null) { + return descriptor.getIcon(); + } + return null; + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/properties/MindMapPropertySectionPartBase.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/properties/MindMapPropertySectionPartBase.java index 73d62a728..f9f1ecc0d 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/properties/MindMapPropertySectionPartBase.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/properties/MindMapPropertySectionPartBase.java @@ -1,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ package org.xmind.ui.properties; @@ -21,6 +18,7 @@ import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.PlatformUI; import org.xmind.core.event.CoreEvent; import org.xmind.core.event.CoreEventRegister; import org.xmind.core.event.ICoreEventListener; @@ -39,8 +37,8 @@ import org.xmind.gef.ui.properties.PropertySectionPart; import org.xmind.ui.style.StyleUtils; -public abstract class MindMapPropertySectionPartBase extends - PropertySectionPart implements ICoreEventListener { +public abstract class MindMapPropertySectionPartBase extends PropertySectionPart + implements ICoreEventListener { protected static final Object[] NO_ELEMENTS = new Object[0]; @@ -193,11 +191,21 @@ protected void unhookSelection(ISelection selection) { } public void handleCoreEvent(final CoreEvent event) { - getContainer().getContainerSite().getWorkbenchWindow().getWorkbench() - .getDisplay().syncExec(new Runnable() { - public void run() { - refresh(); - } - }); - } -} \ No newline at end of file + if (getContainer().getContainerSite() != null) { + getContainer().getContainerSite().getWorkbenchWindow() + .getWorkbench().getDisplay().syncExec(new Runnable() { + public void run() { + refresh(); + } + }); + } else { + PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { + + @Override + public void run() { + refresh(); + } + }); + } + } +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/style/Styles.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/style/Styles.java index b2f33401a..64c6f0c13 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/style/Styles.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/style/Styles.java @@ -60,7 +60,6 @@ public class Styles { * recommended that the {@link #LineColor} property value be used instead. * Typically this property is used on a branch to define colors for * connections from the branch's node to its children nodes. - * *

      * Example: *

      @@ -70,7 +69,6 @@ public class Styles { *
            * <line-properties multi-line-colors="#ff0000 #00ff00 #0000ff" />
            * 
      - * *

      *

      * Lines with default line color: @@ -78,7 +76,6 @@ public class Styles { *

            * <line-properties multi-line-colors="default" />
            * 
      - * *

      *

      * ATTN: Used to use rainbowcolor property and boolean @@ -102,7 +99,6 @@ public class Styles { *

            * <line-properties line-width="1px"/>
            * 
      - * *

      */ public static final String LineWidth = DOMConstants.ATTR_LINE_WIDTH; @@ -115,7 +111,6 @@ public class Styles { *
            * <line-properties line-tapered="tapered"/>
            * 
      - * *

      *

      * ATTN: Used to use the 'spinylines' property and @@ -551,7 +546,7 @@ public class Styles { public static final String LEGEND_LINE_COLOR = "#dddddd"; //$NON-NLS-1$ - public static final String DEF_YELLOWBOX_FILL_COLOR = "#edf9cc"; //$NON-NLS-1$ + public static final String DEF_YELLOWBOX_FILL_COLOR = "#fff8b6"; //$NON-NLS-1$ public static final String YELLOWBOX_TEXT_COLOR = "#333333"; //$NON-NLS-1$ @@ -577,4 +572,4 @@ public class Styles { public static final String YellowBoxFillColor = "yellowBoxFillColor"; //$NON-NLS-1$ public static final String LegendFillColor = "legendFillColor"; //$NON-NLS-1$ -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/tools/GalleryMoveTool.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/tools/GalleryMoveTool.java new file mode 100644 index 000000000..ed347cdea --- /dev/null +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/tools/GalleryMoveTool.java @@ -0,0 +1,295 @@ +package org.xmind.ui.tools; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Layer; +import org.eclipse.draw2d.RectangleFigure; +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.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.resource.ResourceManager; +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.events.MouseEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.xmind.gef.GEF; +import org.xmind.gef.IGraphicalViewer; +import org.xmind.gef.IViewer; +import org.xmind.gef.Request; +import org.xmind.gef.draw2d.ITextFigure; +import org.xmind.gef.draw2d.SimpleRectangleFigure; +import org.xmind.gef.draw2d.SizeableImageFigure; +import org.xmind.gef.event.MouseDragEvent; +import org.xmind.gef.part.IPart; +import org.xmind.gef.util.Properties; +import org.xmind.ui.gallery.FrameFigure; +import org.xmind.ui.gallery.FramePart; +import org.xmind.ui.gallery.GalleryViewer; +import org.xmind.ui.gallery.IDecorationContext; +import org.xmind.ui.gallery.ILabelDecorator; +import org.xmind.ui.gallery.ShadowedLayer; +import org.xmind.ui.resources.ColorUtils; + +public class GalleryMoveTool extends DummyMoveTool { + + public static final String PARAM_INSERT_TARGET = "insertTarget"; //$NON-NLS-1$ + public static final String PARAM_INSERT_POSITION = "insertPosition"; //$NON-NLS-1$ + + private static final int DELTA = 5; + + private Layer layer; + private SimpleRectangleFigure cover; + + private IFigure placeholder; + private boolean horizontalLayout; + + private IPart relativePart; + + /** + * true is for before, false for after. + */ + private boolean beforeOrAfter; + + private ResourceManager resources; + + @Override + protected void start() { + resources = new LocalResourceManager(JFaceResources.getResources(), + getTargetViewer().getControl()); + + super.start(); + horizontalLayout = getTargetViewer().getProperties() + .getBoolean(GalleryViewer.HorizontalLayout, false); + Layer contentCover = getContentCover(); + cover = new SimpleRectangleFigure( + contentCover.getBounds().getShrinked(2, 2)); + cover.setBackgroundColor(ColorConstants.gray); + cover.setSubAlpha(0x33); + contentCover.add(cover); + } + + private Layer getContentCover() { + FramePart framePart = getFramePart(); + FrameFigure frameFigure = framePart.getFigure(); + return frameFigure.getContentCover(); + } + + protected FramePart getFramePart() { + return (FramePart) getSource(); + } + + @Override + protected void end() { + horizontalLayout = false; + getContentCover().remove(cover); + cover = null; + layer.remove(placeholder); + placeholder = null; + super.end(); + } + + private RectangleFigure createPlaceholder() { + RectangleFigure placeholder = new RectangleFigure(); + placeholder.setFill(true); +// placeholder.setOutline(true); + placeholder.setForegroundColor( + (Color) resources.get(ColorUtils.toDescriptor("#a3a3a3"))); //$NON-NLS-1$ + placeholder.setBackgroundColor( + (Color) resources.get(ColorUtils.toDescriptor("#a3a3a3"))); //$NON-NLS-1$ + placeholder.setLineWidth(4); + return placeholder; + } + + @Override + protected IFigure createDummy() { + IGraphicalViewer viewer = getTargetViewer(); + layer = viewer.getLayer(GEF.LAYER_PRESENTATION); + if (layer != null) { + FrameFigure dummyFrameFigure = new FrameFigure() { + + @Override + public void paint(Graphics graphics) { + graphics.setAlpha(0x4c); + super.paint(graphics); + } + }; + decorate(dummyFrameFigure); + dummyFrameFigure.setBounds(getFramePart().getFigure().getBounds()); + layer.add(dummyFrameFigure); + + placeholder = createPlaceholder(); + layer.add(placeholder); + return dummyFrameFigure; + } + return null; + } + + private void decorate(FrameFigure dummyFrameFigure) { + Object model = getFramePart().getModel(); + IViewer viewer = getTargetViewer(); + Properties properties = viewer.getProperties(); + IBaseLabelProvider labelProvider = viewer + .getAdapter(IBaseLabelProvider.class); + + boolean hideTitle = properties.getBoolean(GalleryViewer.HideTitle, + false); + dummyFrameFigure.setHideTitle(hideTitle); + + boolean flat = properties.getBoolean(GalleryViewer.FlatFrames, false); + dummyFrameFigure.setFlat(flat); + dummyFrameFigure.setContentSize( + (Dimension) properties.get(GalleryViewer.FrameContentSize)); + + int titlePlacement = properties.getInteger(GalleryViewer.TitlePlacement, + GalleryViewer.TITLE_TOP.intValue()); + dummyFrameFigure.setTitlePlacement(titlePlacement); + if (!hideTitle) { + decorateTitle(dummyFrameFigure.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( + dummyFrameFigure.getContentPane(), model, context); + } + + ShadowedLayer layer = dummyFrameFigure.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); + } + layer.setLayoutManager( + getFramePart().getFigure().getContentPane().getLayoutManager()); + + Image image = getImage(model, labelProvider); + SizeableImageFigure imageFigure = new SizeableImageFigure(); + decorateImage(imageFigure, image, properties); + dummyFrameFigure.getContentPane().add(imageFigure); + + } + + private Image getImage(Object element, IBaseLabelProvider labelProvider) { + if (labelProvider instanceof ILabelProvider) + return ((ILabelProvider) labelProvider).getImage(element); + return null; + } + + protected void decorateImage(SizeableImageFigure imageFigure, Image image, + Properties properties) { + imageFigure.setImage(image); + boolean stretched = properties.getBoolean(GalleryViewer.ImageStretched, + false); + boolean constained = properties + .getBoolean(GalleryViewer.ImageConstrained, false); + imageFigure.setConstrained(constained); + imageFigure.setStretched(stretched); + Insets margins = (Insets) properties + .get(GalleryViewer.ContentPaneMargins); + imageFigure.setMargins(margins); + } + + 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)); + } + } + + @Override + protected void onMoving(Point currentPos, MouseDragEvent me) { + super.onMoving(currentPos, me); + IGraphicalViewer viewer = getTargetViewer(); + MouseEvent swtEvent = me.getCurrentSWTEvent(); + IPart framePart = viewer.findPart(swtEvent.x, swtEvent.y); + if (framePart instanceof FramePart) { + this.relativePart = framePart; + FrameFigure frameFigure = ((FramePart) framePart).getFigure(); + Rectangle bounds = frameFigure.getBounds(); + int lineWidth = 2; + if (horizontalLayout) { + Rectangle leftRect = bounds.getResized(-bounds.width / 2, 0); + if (leftRect.contains(currentPos)) { + placeholder.setBounds( + new Rectangle(bounds.x - 1, bounds.y - DELTA, + lineWidth, bounds.height + DELTA * 2)); + beforeOrAfter = true; + } else { + placeholder.setBounds(new Rectangle( + bounds.x + bounds.width + 2, bounds.y - DELTA, + lineWidth, bounds.height + DELTA * 2)); + beforeOrAfter = false; + } + + } else { + Rectangle upRect = bounds.getResized(0, -bounds.height / 2); + if (upRect.contains(currentPos)) { + placeholder.setBounds(new Rectangle(bounds.x - DELTA, + bounds.y - 1, bounds.width + DELTA * 2, lineWidth)); + beforeOrAfter = true; + } else { + placeholder.setBounds(new Rectangle(bounds.x - DELTA, + bounds.y + bounds.height + 2, + bounds.width + DELTA * 2, lineWidth)); + beforeOrAfter = false; + } + } + } + + } + + @Override + protected Request createRequest() { + Request request = new Request(GEF.REQ_MOVETO); + request.setDomain(getDomain()); + request.setViewer(getTargetViewer()); + //both target and source are moved parts + List parts = new ArrayList(); + for (IPart p : getSelectedParts(getTargetViewer())) { + if (p.hasRole(GEF.ROLE_MOVABLE)) { + parts.add(p); + } + } + request.setTargets(parts); + request.setPrimaryTarget(getSource()); + request.setParameter(GEF.PARAM_POSITION, getCursorPosition()); + request.setParameter(GEF.PARAM_PARENT, getFramePart().getParent()); + request.setParameter(GalleryMoveTool.PARAM_INSERT_TARGET, relativePart); + request.setParameter(GalleryMoveTool.PARAM_INSERT_POSITION, + beforeOrAfter); + + return request; + } + +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/MarkerImageDescriptor.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/MarkerImageDescriptor.java index a44de8ffe..c2a70f654 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/MarkerImageDescriptor.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/MarkerImageDescriptor.java @@ -19,8 +19,12 @@ import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageDataProvider; import org.eclipse.swt.graphics.RGB; import org.xmind.core.marker.IMarker; import org.xmind.core.marker.IMarkerRef; @@ -67,6 +71,33 @@ protected MarkerImageDescriptor(IMarkerRef markerRef, int maxWidth, this.maxHeigh = maxHeigh; } + @Override + public Image createImage(boolean returnMissingImageOnError, Device device) { + Image image = null; + try { + image = new Image(device, new ImageDataProvider() { + @Override + public ImageData getImageData(int zoom) { + return MarkerImageDescriptor.this.getImageData(zoom); + } + }); + } catch (SWTException e) { + if (e.code != SWT.ERROR_INVALID_IMAGE) { + throw e; + } + } catch (IllegalArgumentException e) { + // fall through + } + if (image == null && returnMissingImageOnError) { + try { + image = new Image(device, DEFAULT_IMAGE_DATA); + } catch (SWTException nextException) { + return null; + } + } + return image; + } + @Override public ImageData getImageData() { @@ -76,22 +107,40 @@ public ImageData getImageData() { || (svgPath == null || "".equals(svgPath)); //$NON-NLS-1$ if (createImageDataByStream) - return createImageDataByStream(); + return createImageDataByStream(100); else { - return createImageDataBySVG(); + return createImageDataBySVG(100); } } - private ImageData createImageDataBySVG() { + private ImageData getImageData(int zoom) { + if (zoom > 100) { + String svgPath = getMarker() == null ? null + : getMarker().getSVGPath(); + + boolean createImageDataByStream = createByStream + || (svgPath == null || "".equals(svgPath)); //$NON-NLS-1$ + if (createImageDataByStream) + return createImageDataByStream(200); + else { + return createImageDataBySVG(200); + } + } else { + return getImageData(); + } + } + + private ImageData createImageDataBySVG(int zoom) { + int width = zoom / 100 * maxWidth; + int height = zoom / 100 * maxHeigh; String filePath = RESOURCE_URL_PREFIX + getMarker().getSVGPath(); SVGImageData data = new SVGReference(filePath).getSVGData(); - - return data.createImage(new Dimension(maxWidth, maxHeigh), background); + return data.createImage(new Dimension(width, height), background); } - private ImageData createImageDataByStream() { - InputStream in = getStream(); + private ImageData createImageDataByStream(int zoom) { + InputStream in = getStream(zoom); ImageData result = null; if (in != null) { try { @@ -154,7 +203,7 @@ private IMarker getMarker() { return marker; } - private InputStream getStream() { + private InputStream getStream(int zoom) { IMarker m = getMarker(); if (m == null) return null; @@ -165,13 +214,17 @@ private InputStream getStream() { IMarkerVariation variation = getMarkerVariation(res); - InputStream in; - if (variation == null) { - in = res.getInputStream(); - } else { - in = res.getInputStream(variation); - if (in == null) - in = res.getInputStream(); + InputStream in = null; + try { + if (variation == null) { + in = res.openInputStream(zoom); + } else { + in = res.openInputStream(variation, zoom); + if (in == null) + in = res.openInputStream(zoom); + } + } catch (IOException e) { + e.printStackTrace(); } if (in == null) return null; @@ -251,9 +304,13 @@ public static ImageDescriptor createFromMarker(IMarker marker, int maxWidth, public static ImageDescriptor createFromMarker(IMarker marker, int maxWidth, int maxHeigh, boolean createByStream) { + if (createByStream) + return createFromMarker(marker, maxWidth, maxHeigh); + MarkerImageDescriptor descriptor = (MarkerImageDescriptor) createFromMarker( marker, maxWidth, maxHeigh); descriptor.setCreateByStream(createByStream); + return descriptor; } @@ -272,4 +329,4 @@ private void setCreateByStream(boolean createByStream) { this.createByStream = createByStream; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/MindMapUtils.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/MindMapUtils.java index 6246208fd..c9f3c9b45 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/MindMapUtils.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/MindMapUtils.java @@ -1,15 +1,12 @@ -/* ****************************************************************************** - * Copyright (c) 2006-2012 XMind Ltd. and others. - * - * This file is a part of XMind 3. XMind releases 3 and - * above are dual-licensed under the Eclipse Public License (EPL), - * which is available at http://www.eclipse.org/legal/epl-v10.html - * and the GNU Lesser General Public License (LGPL), - * which is available at http://www.gnu.org/licenses/lgpl.html - * See http://www.xmind.net/license.html for details. - * - * Contributors: - * XMind Ltd. - initial API and implementation +/* + * ***************************************************************************** + * * Copyright (c) 2006-2012 XMind Ltd. and others. This file is a part of XMind + * 3. XMind releases 3 and above are dual-licensed under the Eclipse Public + * License (EPL), which is available at + * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public + * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html + * See http://www.xmind.net/license.html for details. Contributors: XMind Ltd. - + * initial API and implementation *******************************************************************************/ package org.xmind.ui.util; @@ -218,6 +215,21 @@ public static boolean hasCentralTopic(ISelection selection, return false; } + public static boolean hasSummary(ISelection selection, IViewer viewer) { + if (selection == null || selection.isEmpty() || viewer == null) + return false; + + if (selection instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) selection; + for (Object o : ss.toArray()) { + if (o instanceof ITopic + && ITopic.SUMMARY.equals(((ITopic) o).getType())) + return true; + } + } + return false; + } + public static boolean isPropertyModifiable(ISelection selection, String propName, IViewer viewer) { if (selection == null || propName == null || viewer == null @@ -621,15 +633,21 @@ public static String getNumberingText(ITopic topic, String defaultFormat, if (number == null || "".equals(number)) { //$NON-NLS-1$ return null; } + + if (topic.getNumbering().getNumberFormat() == null + && topic.getNumbering().getDepth() == null + && !topic.getNumbering().isInherited(0)) + return null; + ITopic parent = topic.getParent(); - if (parent != null && parent.getNumbering().prependsParentNumbers()) { - if (defaultFormat != null - && parent.getNumbering().getNumberFormat() != null) { + INumbering numbering = parent.getNumbering(); + if (parent != null && numbering.prependsParentNumbers()) { + if (defaultFormat != null && numbering.getNumberFormat() != null) { defaultFormat = null; } String parentNumber = getNumberingText(parent, defaultFormat, defaultSeparator); - if (parentNumber != null) { + if (parentNumber != null && parent.getNumbering().isInherited(1)) { String separator = getNumberSeparator(topic, defaultSeparator); if (separator == null) separator = NUMBER_SEPARATOR; @@ -1025,4 +1043,4 @@ public static ITopicPart findTopicPart(IViewer viewer, ITopic topic) { return topicPart; } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/NumberUtils.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/NumberUtils.java index e06fcd46c..f6e2b37f5 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/NumberUtils.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/util/NumberUtils.java @@ -133,7 +133,8 @@ public static double newton(double[] coefs, double x0) { * precision controller * @return a solution to the equation near the initial value */ - public static double newton(double[] coefs, double x0, int max, double eps) { + public static double newton(double[] coefs, double x0, int max, + double eps) { if (coefs == null) throw new IllegalArgumentException("coefficient list is null"); //$NON-NLS-1$ if (coefs.length <= 1) @@ -214,9 +215,8 @@ public static String toRoman(long n) { for (i = 0; i < symbols.length; i++) { if (symbols[i].value <= n) { int shift = i + (i % 2); - if (i > 0 - && shift < symbols.length - && (symbols[i - 1].value - symbols[shift].value) <= n) { + if (i > 0 && shift < symbols.length && (symbols[i - 1].value + - symbols[shift].value) <= n) { sb.append(symbols[shift].name()); sb.append(symbols[i - 1].name()); n = n - symbols[i - 1].value + symbols[shift].value; @@ -232,4 +232,46 @@ public static String toRoman(long n) { return sb.toString(); } + @SuppressWarnings("nls") + public static String toSimpleChinese(int n) { + String num[] = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" }; + String xx[] = { "十", "百", "千" }; + StringBuilder sb = new StringBuilder(); + int bs = 0; + while ((int) (n / ((long) Math.pow(10, bs))) != 0) { + bs++; + } + if (bs > 4) + return ""; + for (int i = bs - 1; i >= 0; i--) { + int index = (int) (n / Math.pow(10, i)); + sb.append(num[index]); + if (index != 0 && i > 0) + sb.append(xx[i - 1]); + n -= index * Math.pow(10, i); + } + return sb.toString(); + } + + @SuppressWarnings("nls") + public static String toTraditionalChinese(int n) { + String num[] = { "零", "壹", "貳", "參", "肆", "伍", "陸", "柒", "捌", "玖" }; + String xx[] = { "拾", "佰", "仟" }; + StringBuilder sb = new StringBuilder(); + int bs = 0; + while ((int) (n / ((long) Math.pow(10, bs))) != 0) { + bs++; + } + if (bs > 4) + return ""; + for (int i = bs - 1; i >= 0; i--) { + int index = (int) (n / Math.pow(10, i)); + sb.append(num[index]); + if (index != 0 && i > 0) + sb.append(xx[i - 1]); + n -= index * Math.pow(10, i); + } + return sb.toString(); + } + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/DocumentExportPageBase.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/DocumentExportPageBase.java index 4073326c7..e6b7f2c98 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/DocumentExportPageBase.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/DocumentExportPageBase.java @@ -132,7 +132,8 @@ protected void uninstallModelListeners() { removePropertyListener(ExportContants.INCLUDE_IMAGE, this); removePropertyListener(ExportContants.INCLUDE_NOTES, this); removePropertyListener(ExportContants.INCLUDE_RELATIONSHIPS, this); - removePropertyListener(ExportContants.INCLUDE_FLOATING_TOPICS, this); + removePropertyListener(ExportContants.INCLUDE_FLOATING_TOPICS, + this); removePropertyListener(ExportContants.INCLUDE_SUMMARIES, this); super.uninstallModelListeners(); } @@ -144,7 +145,8 @@ protected Object[] getModelChildren(Object model) { list.add(new ViewerModel(TopicTitlePreviewPart.class, rootTopic)); - boolean includeOverview = getBoolean(ExportContants.INCLUDE_OVERVIEW); + boolean includeOverview = getBoolean( + ExportContants.INCLUDE_OVERVIEW); if (includeOverview) { list.add(new ViewerModel(OverviewPreviewPart.class, rootTopic)); } @@ -157,7 +159,8 @@ protected Object[] getModelChildren(Object model) { list.add(new ViewerModel(TagsPreviewPart.class, mainTopic)); } - if (includeOverview && getBoolean(ExportContants.SEPARATE_OVERVIEW)) { + if (includeOverview + && getBoolean(ExportContants.SEPARATE_OVERVIEW)) { list.add(new ViewerModel(OverviewPreviewPart.class, mainTopic)); } @@ -221,7 +224,8 @@ protected LayoutManager createLayoutManager() { layout.setMajorAlignment(AdvancedToolbarLayout.ALIGN_TOPLEFT); } layout.setMinorAlignment(AdvancedToolbarLayout.ALIGN_BOTTOMRIGHT); - layout.setInnerMinorAlignment(AdvancedToolbarLayout.ALIGN_BOTTOMRIGHT); + layout.setInnerMinorAlignment( + AdvancedToolbarLayout.ALIGN_BOTTOMRIGHT); layout.setSpacing(5); return layout; } @@ -398,7 +402,8 @@ protected IFigure createFigure() { protected LayoutManager createLayoutManager() { AdvancedToolbarLayout layout = new AdvancedToolbarLayout(true); layout.setMinorAlignment(AdvancedToolbarLayout.ALIGN_BOTTOMRIGHT); - layout.setInnerMinorAlignment(AdvancedToolbarLayout.ALIGN_BOTTOMRIGHT); + layout.setInnerMinorAlignment( + AdvancedToolbarLayout.ALIGN_BOTTOMRIGHT); layout.setMajorAlignment(AdvancedToolbarLayout.ALIGN_TOPLEFT); layout.setSpacing(2); return layout; @@ -477,8 +482,8 @@ public ITopic getTopic() { protected void initFigure(IFigure figure) { super.initFigure(figure); RotatableWrapLabel label = (RotatableWrapLabel) figure; - label.setFont(FontUtils - .getNewHeight(JFaceResources.DEFAULT_FONT, 6)); + label.setFont( + FontUtils.getNewHeight(JFaceResources.DEFAULT_FONT, 6)); label.setForegroundColor(ColorConstants.darkGray); String text = MindMapUtils.getLabelText(getTopic().getLabels()); @@ -510,8 +515,8 @@ protected void initFigure(IFigure figure) { super.initFigure(figure); SizeableImageFigure imgFigure = new SizeableImageFigure(); figure.add(imgFigure); - Image image = ImageUtils.getImage(MindMapUI.getImages().get( - IMindMapImages.INSERT_IMAGE, true)); + Image image = ImageUtils.getImage(MindMapUI.getImages() + .get(IMindMapImages.INSERT_IMAGE, true)); imgFigure.setImage(image); imgFigure.setPreferredSize(imgFigure.getImageSize()); } @@ -531,8 +536,8 @@ protected void initFigure(IFigure figure) { super.initFigure(figure); RotatableWrapLabel label = (RotatableWrapLabel) figure; label.setTextAlignment(PositionConstants.LEFT); - label.setFont(FontUtils - .getNewHeight(JFaceResources.DEFAULT_FONT, 4)); + label.setFont( + FontUtils.getNewHeight(JFaceResources.DEFAULT_FONT, 4)); label.setForegroundColor(ColorConstants.darkGray); label.setText(getSampleNotes()); } @@ -561,19 +566,19 @@ protected void initFigure(IFigure figure) { RotatableWrapLabel seeAlsoLabel = new RotatableWrapLabel( RotatableWrapLabel.NORMAL); seeAlsoLabel.setPrefWidth(300); - seeAlsoLabel.setFont(FontUtils.getBold(JFaceResources.DEFAULT_FONT, - 6)); + seeAlsoLabel + .setFont(FontUtils.getBold(JFaceResources.DEFAULT_FONT, 6)); seeAlsoLabel.setForegroundColor(ColorConstants.darkGray); seeAlsoLabel.setText(WizardMessages.Export_SeeAlso); RotatableWrapLabel relationshipsLabel = new RotatableWrapLabel( RotatableWrapLabel.NORMAL); relationshipsLabel.setPrefWidth(250); - relationshipsLabel.setFont(FontUtils.getNewHeight( - JFaceResources.DEFAULT_FONT, 6)); + relationshipsLabel.setFont( + FontUtils.getNewHeight(JFaceResources.DEFAULT_FONT, 6)); relationshipsLabel.setForegroundColor(ColorConstants.darkGray); - relationshipsLabel - .setText(WizardMessages.DocumentExportPage_Sample_Relationships); + relationshipsLabel.setText( + WizardMessages.DocumentExportPage_Sample_Relationships); figure.add(seeAlsoLabel); figure.add(relationshipsLabel); @@ -667,8 +672,8 @@ protected Control createSettingsGroup(Composite parent) { group.setLayout(layout); Composite widgetContainer = new Composite(group, SWT.NONE); - widgetContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, - true)); + widgetContainer + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); GridLayout containerLayout = new GridLayout(1, false); containerLayout.marginHeight = 0; containerLayout.marginWidth = 0; @@ -716,8 +721,8 @@ protected Object getPreviewViewerInput() { } protected void initPreviewViewer(IGraphicalViewer previewViewer) { - previewViewer.setPartFactory(new PreviewPartFactory(previewViewer - .getPartFactory())); + previewViewer.setPartFactory( + new PreviewPartFactory(previewViewer.getPartFactory())); Properties properties = previewViewer.getProperties(); properties.set(GalleryViewer.Horizontal, Boolean.FALSE); properties.set(GalleryViewer.SolidFrames, Boolean.TRUE); @@ -752,7 +757,8 @@ protected void createAdditionalWidgets(Composite parent) { endAllCheckCreation(); } - protected Widget createBooleanWidget(Composite parent, String propertyName) { + protected Widget createBooleanWidget(Composite parent, + String propertyName) { return createBooleanWidget(parent, propertyName, getDefaultLabel(propertyName)); } @@ -1012,18 +1018,18 @@ protected ISheet createSampleSheet() { IWorkbook workbook = Core.getWorkbookBuilder().createWorkbook(); ISheet sheet = workbook.getPrimarySheet(); ITopic rootTopic = sheet.getRootTopic(); - rootTopic - .setTitleText(WizardMessages.DocumentExportPage_Sample_CentralTopic); + rootTopic.setTitleText( + WizardMessages.DocumentExportPage_Sample_CentralTopic); ITopic mainTopic = workbook.createTopic(); rootTopic.add(mainTopic); - mainTopic - .setTitleText(WizardMessages.DocumentExportPage_Sample_MainTopic1); + mainTopic.setTitleText( + WizardMessages.DocumentExportPage_Sample_MainTopic1); mainTopic.addMarker("priority-1"); //$NON-NLS-1$ mainTopic.addMarker("smiley-smile"); //$NON-NLS-1$ - mainTopic.setLabels(Arrays.asList( - WizardMessages.DocumentExportPage_Sample_Label1, - WizardMessages.DocumentExportPage_Sample_Label2)); + mainTopic.setLabels( + Arrays.asList(WizardMessages.DocumentExportPage_Sample_Label1, + WizardMessages.DocumentExportPage_Sample_Label2)); mainTopic.setHyperlink("http://www.xmind.net"); //$NON-NLS-1$ mainTopic.getImage().setSource("temp.png"); //$NON-NLS-1$ INotesContent notesContent = workbook.createNotesContent(INotes.PLAIN); @@ -1040,21 +1046,23 @@ protected ISheet createSampleSheet() { mainTopic.add(sub2); ITopic summary1 = workbook.createTopic(); - summary1.setTitleText(WizardMessages.DocumentExportPage_Sample_Summary1); + summary1.setTitleText( + WizardMessages.DocumentExportPage_Sample_Summary1); mainTopic.add(summary1, ITopic.SUMMARY); ITopic summary2 = workbook.createTopic(); - summary2.setTitleText(WizardMessages.DocumentExportPage_Sample_Summary2); + summary2.setTitleText( + WizardMessages.DocumentExportPage_Sample_Summary2); mainTopic.add(summary2, ITopic.SUMMARY); ITopic floating1 = workbook.createTopic(); - floating1 - .setTitleText(WizardMessages.DocumentExportPage_Sample_FloatingTopic1); + floating1.setTitleText( + WizardMessages.DocumentExportPage_Sample_FloatingTopic1); rootTopic.add(floating1, ITopic.DETACHED); ITopic floating2 = workbook.createTopic(); - floating2 - .setTitleText(WizardMessages.DocumentExportPage_Sample_FloatingTopic2); + floating2.setTitleText( + WizardMessages.DocumentExportPage_Sample_FloatingTopic2); rootTopic.add(floating2, ITopic.DETACHED); return sheet; } diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/ExportContants.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/ExportContants.java index aa79ece4b..bd20f5875 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/ExportContants.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/ExportContants.java @@ -47,4 +47,6 @@ public class ExportContants { public static final boolean DEFAULT_MINUS_VISIBLE = true; + public static final String NO_WATERMARK = "noWatermark"; //$NON-NLS-1$ + } \ No newline at end of file diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/MindMapImporter.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/MindMapImporter.java index 82637f581..60a6ca61b 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/MindMapImporter.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/MindMapImporter.java @@ -22,8 +22,13 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.xmind.core.Core; 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; import org.xmind.ui.internal.editor.MME; +import org.xmind.ui.mindmap.MindMapUI; +import org.xmind.ui.util.MindMapUtils; public abstract class MindMapImporter { @@ -80,6 +85,27 @@ public IWorkbook getTargetWorkbook() { public abstract void build() throws InvocationTargetException, InterruptedException; + protected void postBuilded() { + initStyles(); + } + + private void initStyles() { + for (ISheet sheet : getTargetWorkbook().getSheets()) { + sheet.setThemeId(createAppliedTheme(getTargetWorkbook(), + MindMapUI.getResourceManager().getDefaultTheme()).getId()); + + List topics = MindMapUtils.getAllTopics(sheet, true, true); + for (ITopic topic : topics) { + topic.setStyleId(null); + } + } + } + + private IStyle createAppliedTheme(IWorkbook workbook, IStyle sourceTheme) { + IStyleSheet ss = workbook.getStyleSheet(); + return ss.importStyle(sourceTheme); + } + public List getTargetSheets() { return targetSheets; } @@ -119,4 +145,4 @@ public Throwable getKey() { public void dispose() { } -} \ No newline at end of file +} diff --git a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/SaveOptions.java b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/SaveOptions.java index b64679cba..7f954a80a 100644 --- a/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/SaveOptions.java +++ b/bundles/org.xmind.ui.mindmap/src/org/xmind/ui/wizards/SaveOptions.java @@ -3,7 +3,6 @@ import java.net.URI; /** - * * @author Frank Shaka * @since 3.6.50 */ @@ -25,10 +24,15 @@ private SaveOptions copy() { public SaveOptions proposalName(String proposalName) { SaveOptions that = copy(); - that.proposalName = proposalName; + that.proposalName = trimName(proposalName); return that; } + private String trimName(String name) { + return name.replaceAll("\\r\\n|\\n|\\r", // $NON-NLS-1$ //$NON-NLS-1$ + " "); //$NON-NLS-1$ + } + public String proposalName() { return proposalName; } diff --git a/bundles/org.xmind.ui.resources/META-INF/MANIFEST.MF b/bundles/org.xmind.ui.resources/META-INF/MANIFEST.MF index 5ae722bb0..c196fd8f2 100644 --- a/bundles/org.xmind.ui.resources/META-INF/MANIFEST.MF +++ b/bundles/org.xmind.ui.resources/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.xmind.ui.resources;singleton:=true -Bundle-Version: 3.6.51.qualifier +Bundle-Version: 3.7.0.qualifier Bundle-Vendor: %providerName Fragment-Host: org.xmind.ui Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/bundles/org.xmind.ui.resources/markers/arrow_down@16@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_down@16@2x.png new file mode 100644 index 000000000..fa878fe45 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_down@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_down@24@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_down@24@2x.png new file mode 100644 index 000000000..359ba1aca Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_down@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_down@32@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_down@32@2x.png new file mode 100644 index 000000000..b49f06ad8 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_down@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_down_left@16@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_down_left@16@2x.png new file mode 100644 index 000000000..87e1dedb3 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_down_left@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_down_left@24@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_down_left@24@2x.png new file mode 100644 index 000000000..4aaba0416 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_down_left@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_down_left@32@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_down_left@32@2x.png new file mode 100644 index 000000000..523412be5 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_down_left@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_down_right@16@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_down_right@16@2x.png new file mode 100644 index 000000000..fbc319c3d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_down_right@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_down_right@24@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_down_right@24@2x.png new file mode 100644 index 000000000..f4e2b681e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_down_right@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_down_right@32@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_down_right@32@2x.png new file mode 100644 index 000000000..8adc38eb1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_down_right@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_left@16@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_left@16@2x.png new file mode 100644 index 000000000..90944256f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_left@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_left@24@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_left@24@2x.png new file mode 100644 index 000000000..2191fca67 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_left@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_left@32@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_left@32@2x.png new file mode 100644 index 000000000..0a5ddcc6c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_left@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_refresh@16@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_refresh@16@2x.png new file mode 100644 index 000000000..84bc5dd1d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_refresh@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_refresh@24@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_refresh@24@2x.png new file mode 100644 index 000000000..1e937608a Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_refresh@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_refresh@32@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_refresh@32@2x.png new file mode 100644 index 000000000..b7fadfb77 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_refresh@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_right@16@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_right@16@2x.png new file mode 100644 index 000000000..969b8fbb4 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_right@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_right@24@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_right@24@2x.png new file mode 100644 index 000000000..dcc79464b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_right@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_right@32@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_right@32@2x.png new file mode 100644 index 000000000..853b34f27 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_right@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_up@16@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_up@16@2x.png new file mode 100644 index 000000000..97efb7036 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_up@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_up@24@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_up@24@2x.png new file mode 100644 index 000000000..23b596b3d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_up@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_up@32@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_up@32@2x.png new file mode 100644 index 000000000..82cfc8e86 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_up@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_up_left@16@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_up_left@16@2x.png new file mode 100644 index 000000000..560097d7b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_up_left@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_up_left@24@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_up_left@24@2x.png new file mode 100644 index 000000000..dd6c8dd5d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_up_left@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_up_left@32@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_up_left@32@2x.png new file mode 100644 index 000000000..9368193d1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_up_left@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_up_right@16@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_up_right@16@2x.png new file mode 100644 index 000000000..86ed5282f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_up_right@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_up_right@24@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_up_right@24@2x.png new file mode 100644 index 000000000..4789b7656 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_up_right@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/arrow_up_right@32@2x.png b/bundles/org.xmind.ui.resources/markers/arrow_up_right@32@2x.png new file mode 100644 index 000000000..2a33ea239 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/arrow_up_right@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_angry@16.svg b/bundles/org.xmind.ui.resources/markers/emotion_angry@16.svg index d2a3fe873..485a73d0d 100644 --- a/bundles/org.xmind.ui.resources/markers/emotion_angry@16.svg +++ b/bundles/org.xmind.ui.resources/markers/emotion_angry@16.svg @@ -1,6 +1,6 @@ - + face_ang Created with Sketch. @@ -9,17 +9,13 @@ - - - + + + - - - - - - + + diff --git a/bundles/org.xmind.ui.resources/markers/emotion_angry@16@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_angry@16@2x.png new file mode 100644 index 000000000..4cd97eeb4 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_angry@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_angry@24@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_angry@24@2x.png new file mode 100644 index 000000000..d14f790a4 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_angry@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_angry@32@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_angry@32@2x.png new file mode 100644 index 000000000..873bcc730 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_angry@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_boring@16.svg b/bundles/org.xmind.ui.resources/markers/emotion_boring@16.svg index 24f810247..753163f02 100644 --- a/bundles/org.xmind.ui.resources/markers/emotion_boring@16.svg +++ b/bundles/org.xmind.ui.resources/markers/emotion_boring@16.svg @@ -15,8 +15,8 @@ - - + + diff --git a/bundles/org.xmind.ui.resources/markers/emotion_boring@16@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_boring@16@2x.png new file mode 100644 index 000000000..7125af885 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_boring@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_boring@24@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_boring@24@2x.png new file mode 100644 index 000000000..88d2e8c21 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_boring@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_boring@32@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_boring@32@2x.png new file mode 100644 index 000000000..37279637f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_boring@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_cry@16.svg b/bundles/org.xmind.ui.resources/markers/emotion_cry@16.svg index c033bc362..05d1025f2 100644 --- a/bundles/org.xmind.ui.resources/markers/emotion_cry@16.svg +++ b/bundles/org.xmind.ui.resources/markers/emotion_cry@16.svg @@ -1,6 +1,6 @@ - + face_cry Created with Sketch. @@ -15,14 +15,12 @@ - - - + + + - - - + diff --git a/bundles/org.xmind.ui.resources/markers/emotion_cry@16@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_cry@16@2x.png new file mode 100644 index 000000000..b588f1ad7 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_cry@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_cry@24@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_cry@24@2x.png new file mode 100644 index 000000000..c77307141 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_cry@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_cry@32@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_cry@32@2x.png new file mode 100644 index 000000000..78a437715 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_cry@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_embarrass.svg b/bundles/org.xmind.ui.resources/markers/emotion_embarrass.svg index b9b60161b..ae03463fd 100644 --- a/bundles/org.xmind.ui.resources/markers/emotion_embarrass.svg +++ b/bundles/org.xmind.ui.resources/markers/emotion_embarrass.svg @@ -10,8 +10,8 @@ - - + + diff --git a/bundles/org.xmind.ui.resources/markers/emotion_embarrass@16@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_embarrass@16@2x.png new file mode 100644 index 000000000..c153b0fd1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_embarrass@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_embarrass@24@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_embarrass@24@2x.png new file mode 100644 index 000000000..f9f7b38ae Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_embarrass@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_embarrass@32@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_embarrass@32@2x.png new file mode 100644 index 000000000..fc47a05b9 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_embarrass@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_laugh@16.svg b/bundles/org.xmind.ui.resources/markers/emotion_laugh@16.svg index 011bcf872..59893f3bf 100644 --- a/bundles/org.xmind.ui.resources/markers/emotion_laugh@16.svg +++ b/bundles/org.xmind.ui.resources/markers/emotion_laugh@16.svg @@ -10,8 +10,8 @@ - - + + diff --git a/bundles/org.xmind.ui.resources/markers/emotion_laugh@16@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_laugh@16@2x.png new file mode 100644 index 000000000..bf62f645f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_laugh@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_laugh@24@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_laugh@24@2x.png new file mode 100644 index 000000000..82a264c53 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_laugh@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_laugh@32@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_laugh@32@2x.png new file mode 100644 index 000000000..68733bd7c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_laugh@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_smile@16.svg b/bundles/org.xmind.ui.resources/markers/emotion_smile@16.svg index 511583406..be27289a2 100644 --- a/bundles/org.xmind.ui.resources/markers/emotion_smile@16.svg +++ b/bundles/org.xmind.ui.resources/markers/emotion_smile@16.svg @@ -10,8 +10,8 @@ - - + + diff --git a/bundles/org.xmind.ui.resources/markers/emotion_smile@16@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_smile@16@2x.png new file mode 100644 index 000000000..417352dc4 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_smile@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_smile@24@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_smile@24@2x.png new file mode 100644 index 000000000..2162d2fbf Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_smile@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_smile@32@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_smile@32@2x.png new file mode 100644 index 000000000..f082315eb Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_smile@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_surprise@16@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_surprise@16@2x.png new file mode 100644 index 000000000..bdbe314f5 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_surprise@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_surprise@24@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_surprise@24@2x.png new file mode 100644 index 000000000..571b29ae1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_surprise@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/emotion_surprise@32@2x.png b/bundles/org.xmind.ui.resources/markers/emotion_surprise@32@2x.png new file mode 100644 index 000000000..dfad699db Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/emotion_surprise@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_blue@16@2x.png b/bundles/org.xmind.ui.resources/markers/flag_blue@16@2x.png new file mode 100644 index 000000000..003b07aba Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_blue@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_blue@24@2x.png b/bundles/org.xmind.ui.resources/markers/flag_blue@24@2x.png new file mode 100644 index 000000000..053dcb7e4 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_blue@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_blue@32@2x.png b/bundles/org.xmind.ui.resources/markers/flag_blue@32@2x.png new file mode 100644 index 000000000..6b10663d7 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_blue@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_dark_gray@16@2x.png b/bundles/org.xmind.ui.resources/markers/flag_dark_gray@16@2x.png new file mode 100644 index 000000000..2a959e3ff Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_dark_gray@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_dark_gray@24@2x.png b/bundles/org.xmind.ui.resources/markers/flag_dark_gray@24@2x.png new file mode 100644 index 000000000..1218dd3d0 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_dark_gray@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_dark_gray@32@2x.png b/bundles/org.xmind.ui.resources/markers/flag_dark_gray@32@2x.png new file mode 100644 index 000000000..7e2b49ddf Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_dark_gray@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_dark_green@16@2x.png b/bundles/org.xmind.ui.resources/markers/flag_dark_green@16@2x.png new file mode 100644 index 000000000..153f81712 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_dark_green@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_dark_green@24@2x.png b/bundles/org.xmind.ui.resources/markers/flag_dark_green@24@2x.png new file mode 100644 index 000000000..6bf85e3eb Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_dark_green@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_dark_green@32@2x.png b/bundles/org.xmind.ui.resources/markers/flag_dark_green@32@2x.png new file mode 100644 index 000000000..1e5ab527c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_dark_green@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_green@16@2x.png b/bundles/org.xmind.ui.resources/markers/flag_green@16@2x.png new file mode 100644 index 000000000..e9140134c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_green@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_green@24@2x.png b/bundles/org.xmind.ui.resources/markers/flag_green@24@2x.png new file mode 100644 index 000000000..54cf30ecb Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_green@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_green@32@2x.png b/bundles/org.xmind.ui.resources/markers/flag_green@32@2x.png new file mode 100644 index 000000000..1c0678c6c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_green@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_orange@16@2x.png b/bundles/org.xmind.ui.resources/markers/flag_orange@16@2x.png new file mode 100644 index 000000000..508754468 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_orange@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_orange@24@2x.png b/bundles/org.xmind.ui.resources/markers/flag_orange@24@2x.png new file mode 100644 index 000000000..fdf870351 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_orange@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_orange@32@2x.png b/bundles/org.xmind.ui.resources/markers/flag_orange@32@2x.png new file mode 100644 index 000000000..833f58fde Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_orange@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_purple@16@2x.png b/bundles/org.xmind.ui.resources/markers/flag_purple@16@2x.png new file mode 100644 index 000000000..bc6e7dd15 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_purple@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_purple@24@2x.png b/bundles/org.xmind.ui.resources/markers/flag_purple@24@2x.png new file mode 100644 index 000000000..6487131cd Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_purple@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_purple@32@2x.png b/bundles/org.xmind.ui.resources/markers/flag_purple@32@2x.png new file mode 100644 index 000000000..1b50056d2 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_purple@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_red@16@2x.png b/bundles/org.xmind.ui.resources/markers/flag_red@16@2x.png new file mode 100644 index 000000000..a031edd56 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_red@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_red@24@2x.png b/bundles/org.xmind.ui.resources/markers/flag_red@24@2x.png new file mode 100644 index 000000000..2fadfb3d0 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_red@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/flag_red@32@2x.png b/bundles/org.xmind.ui.resources/markers/flag_red@32@2x.png new file mode 100644 index 000000000..678ddbc7a Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/flag_red@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_apr@16.png b/bundles/org.xmind.ui.resources/markers/month_apr@16.png index ed1c58905..16573af1f 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_apr@16.png and b/bundles/org.xmind.ui.resources/markers/month_apr@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_apr@16.svg b/bundles/org.xmind.ui.resources/markers/month_apr@16.svg index 82f1ebced..533c28f9c 100644 --- a/bundles/org.xmind.ui.resources/markers/month_apr@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_apr@16.svg @@ -1,30 +1,33 @@ - - - Rectangle 76 Copy 33 + + + month_apr copy Created with Sketch. - - - - - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_apr@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_apr@16@2x.png new file mode 100644 index 000000000..16573af1f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_apr@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_apr@24.png b/bundles/org.xmind.ui.resources/markers/month_apr@24.png index ebb786d9f..9a7d0ea69 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_apr@24.png and b/bundles/org.xmind.ui.resources/markers/month_apr@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_apr@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_apr@24@2x.png new file mode 100644 index 000000000..77da52911 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_apr@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_apr@32.png b/bundles/org.xmind.ui.resources/markers/month_apr@32.png index 7d0a1c1ff..77da52911 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_apr@32.png and b/bundles/org.xmind.ui.resources/markers/month_apr@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_apr@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_apr@32@2x.png new file mode 100644 index 000000000..2f471de01 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_apr@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_aug@16.png b/bundles/org.xmind.ui.resources/markers/month_aug@16.png index 9a9a8cacc..90b026e98 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_aug@16.png and b/bundles/org.xmind.ui.resources/markers/month_aug@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_aug@16.svg b/bundles/org.xmind.ui.resources/markers/month_aug@16.svg index 1a9377d9d..153a014fb 100644 --- a/bundles/org.xmind.ui.resources/markers/month_aug@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_aug@16.svg @@ -1,30 +1,33 @@ - - - Rectangle 76 Copy 37 + + + month_aug copy Created with Sketch. - - - - - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_aug@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_aug@16@2x.png new file mode 100644 index 000000000..90b026e98 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_aug@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_aug@24.png b/bundles/org.xmind.ui.resources/markers/month_aug@24.png index 825ce9ca9..3e2a0190d 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_aug@24.png and b/bundles/org.xmind.ui.resources/markers/month_aug@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_aug@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_aug@24@2x.png new file mode 100644 index 000000000..7cf882b6e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_aug@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_aug@32.png b/bundles/org.xmind.ui.resources/markers/month_aug@32.png index 55bd34622..7cf882b6e 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_aug@32.png and b/bundles/org.xmind.ui.resources/markers/month_aug@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_aug@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_aug@32@2x.png new file mode 100644 index 000000000..c61de2cce Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_aug@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_dec@16.png b/bundles/org.xmind.ui.resources/markers/month_dec@16.png index e91baa858..9ad06c8a0 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_dec@16.png and b/bundles/org.xmind.ui.resources/markers/month_dec@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_dec@16.svg b/bundles/org.xmind.ui.resources/markers/month_dec@16.svg index dc3db0cf9..15db65462 100644 --- a/bundles/org.xmind.ui.resources/markers/month_dec@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_dec@16.svg @@ -1,30 +1,33 @@ - - - Rectangle 76 Copy 41 + + + month_dec copy Created with Sketch. - - - - - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_dec@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_dec@16@2x.png new file mode 100644 index 000000000..9ad06c8a0 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_dec@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_dec@24.png b/bundles/org.xmind.ui.resources/markers/month_dec@24.png index 3fa22d433..103eb6c23 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_dec@24.png and b/bundles/org.xmind.ui.resources/markers/month_dec@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_dec@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_dec@24@2x.png new file mode 100644 index 000000000..e6b9f81c6 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_dec@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_dec@32.png b/bundles/org.xmind.ui.resources/markers/month_dec@32.png index 7dfdc2463..e6b9f81c6 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_dec@32.png and b/bundles/org.xmind.ui.resources/markers/month_dec@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_dec@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_dec@32@2x.png new file mode 100644 index 000000000..bf4c7d8e7 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_dec@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_feb@16.png b/bundles/org.xmind.ui.resources/markers/month_feb@16.png index 2bb92776c..11b8dcb0d 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_feb@16.png and b/bundles/org.xmind.ui.resources/markers/month_feb@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_feb@16.svg b/bundles/org.xmind.ui.resources/markers/month_feb@16.svg index 2a211ece0..d0ecdcc84 100644 --- a/bundles/org.xmind.ui.resources/markers/month_feb@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_feb@16.svg @@ -1,30 +1,33 @@ - - - Rectangle 76 Copy 31 + + + month_feb copy Created with Sketch. - - - - - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_feb@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_feb@16@2x.png new file mode 100644 index 000000000..11b8dcb0d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_feb@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_feb@24.png b/bundles/org.xmind.ui.resources/markers/month_feb@24.png index 8d4abe962..d84dac6bb 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_feb@24.png and b/bundles/org.xmind.ui.resources/markers/month_feb@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_feb@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_feb@24@2x.png new file mode 100644 index 000000000..54d80c914 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_feb@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_feb@32.png b/bundles/org.xmind.ui.resources/markers/month_feb@32.png index 1c357a809..54d80c914 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_feb@32.png and b/bundles/org.xmind.ui.resources/markers/month_feb@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_feb@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_feb@32@2x.png new file mode 100644 index 000000000..ad93d6b65 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_feb@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jan@16.png b/bundles/org.xmind.ui.resources/markers/month_jan@16.png index 64b99cd9e..9a480fdd2 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_jan@16.png and b/bundles/org.xmind.ui.resources/markers/month_jan@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jan@16.svg b/bundles/org.xmind.ui.resources/markers/month_jan@16.svg index b6f17e814..d23309899 100644 --- a/bundles/org.xmind.ui.resources/markers/month_jan@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_jan@16.svg @@ -1,30 +1,33 @@ - - - Rectangle 76 Copy 30 + + + month_jan copy Created with Sketch. - - - - - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_jan@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_jan@16@2x.png new file mode 100644 index 000000000..9a480fdd2 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_jan@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jan@24.png b/bundles/org.xmind.ui.resources/markers/month_jan@24.png index 70477d773..a610117be 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_jan@24.png and b/bundles/org.xmind.ui.resources/markers/month_jan@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jan@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_jan@24@2x.png new file mode 100644 index 000000000..72ef5c282 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_jan@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jan@32.png b/bundles/org.xmind.ui.resources/markers/month_jan@32.png index 263886649..72ef5c282 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_jan@32.png and b/bundles/org.xmind.ui.resources/markers/month_jan@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jan@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_jan@32@2x.png new file mode 100644 index 000000000..a0948ce60 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_jan@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jul@16.png b/bundles/org.xmind.ui.resources/markers/month_jul@16.png index 95e591f37..3a2d0087e 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_jul@16.png and b/bundles/org.xmind.ui.resources/markers/month_jul@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jul@16.svg b/bundles/org.xmind.ui.resources/markers/month_jul@16.svg index 50872bbda..1bad7cf07 100644 --- a/bundles/org.xmind.ui.resources/markers/month_jul@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_jul@16.svg @@ -1,30 +1,25 @@ - - - Rectangle 76 Copy 36 + + + month_jul copy Created with Sketch. - - - - - + + + + - - + + - - - - - - + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_jul@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_jul@16@2x.png new file mode 100644 index 000000000..3a2d0087e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_jul@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jul@24.png b/bundles/org.xmind.ui.resources/markers/month_jul@24.png index 0771fe151..9df481d80 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_jul@24.png and b/bundles/org.xmind.ui.resources/markers/month_jul@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jul@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_jul@24@2x.png new file mode 100644 index 000000000..046f58f38 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_jul@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jul@32.png b/bundles/org.xmind.ui.resources/markers/month_jul@32.png index 8e6c44742..046f58f38 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_jul@32.png and b/bundles/org.xmind.ui.resources/markers/month_jul@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jul@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_jul@32@2x.png new file mode 100644 index 000000000..fcde71176 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_jul@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jun@16.png b/bundles/org.xmind.ui.resources/markers/month_jun@16.png index d1a55eefe..d16670c0e 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_jun@16.png and b/bundles/org.xmind.ui.resources/markers/month_jun@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jun@16.svg b/bundles/org.xmind.ui.resources/markers/month_jun@16.svg index a399bfe13..3a352213a 100644 --- a/bundles/org.xmind.ui.resources/markers/month_jun@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_jun@16.svg @@ -1,30 +1,33 @@ - - - Rectangle 76 Copy 35 + + + month_jun copy Created with Sketch. - - - - - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_jun@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_jun@16@2x.png new file mode 100644 index 000000000..d16670c0e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_jun@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jun@24.png b/bundles/org.xmind.ui.resources/markers/month_jun@24.png index 73bf886c5..cabbb820f 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_jun@24.png and b/bundles/org.xmind.ui.resources/markers/month_jun@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jun@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_jun@24@2x.png new file mode 100644 index 000000000..4f4f3f4ae Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_jun@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jun@32.png b/bundles/org.xmind.ui.resources/markers/month_jun@32.png index af3ab6778..4f4f3f4ae 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_jun@32.png and b/bundles/org.xmind.ui.resources/markers/month_jun@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_jun@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_jun@32@2x.png new file mode 100644 index 000000000..e7fcc70be Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_jun@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_mar@16.png b/bundles/org.xmind.ui.resources/markers/month_mar@16.png index 7776519bc..2e5bc998c 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_mar@16.png and b/bundles/org.xmind.ui.resources/markers/month_mar@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_mar@16.svg b/bundles/org.xmind.ui.resources/markers/month_mar@16.svg index 1c80ce324..4dd6c5cc3 100644 --- a/bundles/org.xmind.ui.resources/markers/month_mar@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_mar@16.svg @@ -1,30 +1,33 @@ - - - Rectangle 76 Copy 32 + + + month_mar copy Created with Sketch. - - - - - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_mar@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_mar@16@2x.png new file mode 100644 index 000000000..2e5bc998c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_mar@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_mar@24.png b/bundles/org.xmind.ui.resources/markers/month_mar@24.png index 7c3e8d481..7efe5c0c4 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_mar@24.png and b/bundles/org.xmind.ui.resources/markers/month_mar@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_mar@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_mar@24@2x.png new file mode 100644 index 000000000..588a86b51 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_mar@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_mar@32.png b/bundles/org.xmind.ui.resources/markers/month_mar@32.png index d78fee5b9..588a86b51 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_mar@32.png and b/bundles/org.xmind.ui.resources/markers/month_mar@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_mar@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_mar@32@2x.png new file mode 100644 index 000000000..54138b092 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_mar@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_may@16.png b/bundles/org.xmind.ui.resources/markers/month_may@16.png index dc7451bb8..9cdb88126 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_may@16.png and b/bundles/org.xmind.ui.resources/markers/month_may@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_may@16.svg b/bundles/org.xmind.ui.resources/markers/month_may@16.svg index 5a0951a8f..b657ac0ba 100644 --- a/bundles/org.xmind.ui.resources/markers/month_may@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_may@16.svg @@ -1,30 +1,33 @@ - - - Rectangle 76 Copy 34 + + + month_may copy Created with Sketch. - - - - - - - - + + + + + + + + + + - - - - - - + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_may@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_may@16@2x.png new file mode 100644 index 000000000..9cdb88126 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_may@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_may@24.png b/bundles/org.xmind.ui.resources/markers/month_may@24.png index 8c20c66e6..b27c319fd 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_may@24.png and b/bundles/org.xmind.ui.resources/markers/month_may@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_may@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_may@24@2x.png new file mode 100644 index 000000000..3fcaebd03 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_may@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_may@32.png b/bundles/org.xmind.ui.resources/markers/month_may@32.png index 24814d842..3fcaebd03 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_may@32.png and b/bundles/org.xmind.ui.resources/markers/month_may@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_may@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_may@32@2x.png new file mode 100644 index 000000000..6f62f0ffc Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_may@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_nov@16.png b/bundles/org.xmind.ui.resources/markers/month_nov@16.png index 6ae841999..16776ca29 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_nov@16.png and b/bundles/org.xmind.ui.resources/markers/month_nov@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_nov@16.svg b/bundles/org.xmind.ui.resources/markers/month_nov@16.svg index dba862362..a4ea1ad50 100644 --- a/bundles/org.xmind.ui.resources/markers/month_nov@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_nov@16.svg @@ -1,30 +1,37 @@ - - - Rectangle 76 Copy 40 + + + month_nov copy Created with Sketch. - - - - - - - - + + + + + + + + + + - + - - - - - + + + + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_nov@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_nov@16@2x.png new file mode 100644 index 000000000..16776ca29 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_nov@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_nov@24.png b/bundles/org.xmind.ui.resources/markers/month_nov@24.png index 497dc1d6c..87ea58d4d 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_nov@24.png and b/bundles/org.xmind.ui.resources/markers/month_nov@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_nov@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_nov@24@2x.png new file mode 100644 index 000000000..7e72e27d8 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_nov@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_nov@32.png b/bundles/org.xmind.ui.resources/markers/month_nov@32.png index bc3a425b1..7e72e27d8 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_nov@32.png and b/bundles/org.xmind.ui.resources/markers/month_nov@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_nov@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_nov@32@2x.png new file mode 100644 index 000000000..370aa0270 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_nov@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_oct@16.png b/bundles/org.xmind.ui.resources/markers/month_oct@16.png index e765199a9..32f886dbb 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_oct@16.png and b/bundles/org.xmind.ui.resources/markers/month_oct@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_oct@16.svg b/bundles/org.xmind.ui.resources/markers/month_oct@16.svg index b93808401..d4539319d 100644 --- a/bundles/org.xmind.ui.resources/markers/month_oct@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_oct@16.svg @@ -1,30 +1,37 @@ - - - Rectangle 76 Copy 39 + + + month_oct copy Created with Sketch. - - - - - - - - + + + + + + + + + + - + - - - - - + + + + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_oct@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_oct@16@2x.png new file mode 100644 index 000000000..32f886dbb Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_oct@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_oct@24.png b/bundles/org.xmind.ui.resources/markers/month_oct@24.png index 3c1d8d389..4a1c8e0bc 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_oct@24.png and b/bundles/org.xmind.ui.resources/markers/month_oct@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_oct@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_oct@24@2x.png new file mode 100644 index 000000000..5aa76dd15 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_oct@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_oct@32.png b/bundles/org.xmind.ui.resources/markers/month_oct@32.png index 6a45d145f..5aa76dd15 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_oct@32.png and b/bundles/org.xmind.ui.resources/markers/month_oct@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_oct@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_oct@32@2x.png new file mode 100644 index 000000000..ec6441e14 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_oct@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_sep@16.png b/bundles/org.xmind.ui.resources/markers/month_sep@16.png index d110beaa9..5c0eab954 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_sep@16.png and b/bundles/org.xmind.ui.resources/markers/month_sep@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_sep@16.svg b/bundles/org.xmind.ui.resources/markers/month_sep@16.svg index 9320919e9..2e6f8dac8 100644 --- a/bundles/org.xmind.ui.resources/markers/month_sep@16.svg +++ b/bundles/org.xmind.ui.resources/markers/month_sep@16.svg @@ -1,30 +1,37 @@ - - - Rectangle 76 Copy 38 + + + month_sep copy Created with Sketch. - - - - - - - - + + + + + + + + + + - + - - - - - + + + + + + + + + + + + + + + - - - - - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/month_sep@16@2x.png b/bundles/org.xmind.ui.resources/markers/month_sep@16@2x.png new file mode 100644 index 000000000..5c0eab954 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_sep@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_sep@24.png b/bundles/org.xmind.ui.resources/markers/month_sep@24.png index f13e14148..5db7c1cf0 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_sep@24.png and b/bundles/org.xmind.ui.resources/markers/month_sep@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_sep@24@2x.png b/bundles/org.xmind.ui.resources/markers/month_sep@24@2x.png new file mode 100644 index 000000000..f0daa29eb Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_sep@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_sep@32.png b/bundles/org.xmind.ui.resources/markers/month_sep@32.png index 6729c3112..f0daa29eb 100644 Binary files a/bundles/org.xmind.ui.resources/markers/month_sep@32.png and b/bundles/org.xmind.ui.resources/markers/month_sep@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/month_sep@32@2x.png b/bundles/org.xmind.ui.resources/markers/month_sep@32@2x.png new file mode 100644 index 000000000..2579538ac Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/month_sep@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_blue@16@2x.png b/bundles/org.xmind.ui.resources/markers/people_blue@16@2x.png new file mode 100644 index 000000000..259fe5935 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_blue@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_blue@24@2x.png b/bundles/org.xmind.ui.resources/markers/people_blue@24@2x.png new file mode 100644 index 000000000..aad81a032 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_blue@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_blue@32@2x.png b/bundles/org.xmind.ui.resources/markers/people_blue@32@2x.png new file mode 100644 index 000000000..bb979d0e5 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_blue@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_dark_gray@16@2x.png b/bundles/org.xmind.ui.resources/markers/people_dark_gray@16@2x.png new file mode 100644 index 000000000..fbfdd394b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_dark_gray@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_dark_gray@24@2x.png b/bundles/org.xmind.ui.resources/markers/people_dark_gray@24@2x.png new file mode 100644 index 000000000..3147d6384 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_dark_gray@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_dark_gray@32@2x.png b/bundles/org.xmind.ui.resources/markers/people_dark_gray@32@2x.png new file mode 100644 index 000000000..e39cf0c75 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_dark_gray@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_dark_green@16@2x.png b/bundles/org.xmind.ui.resources/markers/people_dark_green@16@2x.png new file mode 100644 index 000000000..c4ee1bd6b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_dark_green@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_dark_green@24@2x.png b/bundles/org.xmind.ui.resources/markers/people_dark_green@24@2x.png new file mode 100644 index 000000000..61d8f0e2b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_dark_green@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_dark_green@32@2x.png b/bundles/org.xmind.ui.resources/markers/people_dark_green@32@2x.png new file mode 100644 index 000000000..2d23ade66 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_dark_green@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_green@16@2x.png b/bundles/org.xmind.ui.resources/markers/people_green@16@2x.png new file mode 100644 index 000000000..ba45b3c19 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_green@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_green@24@2x.png b/bundles/org.xmind.ui.resources/markers/people_green@24@2x.png new file mode 100644 index 000000000..f0c29e35e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_green@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_green@32@2x.png b/bundles/org.xmind.ui.resources/markers/people_green@32@2x.png new file mode 100644 index 000000000..1cdf4a672 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_green@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_orange@16@2x.png b/bundles/org.xmind.ui.resources/markers/people_orange@16@2x.png new file mode 100644 index 000000000..d8b8703c4 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_orange@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_orange@24@2x.png b/bundles/org.xmind.ui.resources/markers/people_orange@24@2x.png new file mode 100644 index 000000000..269fab924 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_orange@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_orange@32@2x.png b/bundles/org.xmind.ui.resources/markers/people_orange@32@2x.png new file mode 100644 index 000000000..1a54f003d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_orange@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_purple@16@2x.png b/bundles/org.xmind.ui.resources/markers/people_purple@16@2x.png new file mode 100644 index 000000000..3e01e12cd Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_purple@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_purple@24@2x.png b/bundles/org.xmind.ui.resources/markers/people_purple@24@2x.png new file mode 100644 index 000000000..4c4a27c01 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_purple@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_purple@32@2x.png b/bundles/org.xmind.ui.resources/markers/people_purple@32@2x.png new file mode 100644 index 000000000..58ae315f8 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_purple@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_red@16@2x.png b/bundles/org.xmind.ui.resources/markers/people_red@16@2x.png new file mode 100644 index 000000000..b865a3f3c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_red@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_red@24@2x.png b/bundles/org.xmind.ui.resources/markers/people_red@24@2x.png new file mode 100644 index 000000000..c637ed888 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_red@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/people_red@32@2x.png b/bundles/org.xmind.ui.resources/markers/people_red@32@2x.png new file mode 100644 index 000000000..3a82edd00 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/people_red@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_1@16@2x.png b/bundles/org.xmind.ui.resources/markers/priority_1@16@2x.png new file mode 100644 index 000000000..a93dc6c80 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_1@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_1@24@2x.png b/bundles/org.xmind.ui.resources/markers/priority_1@24@2x.png new file mode 100644 index 000000000..71236429f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_1@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_1@32@2x.png b/bundles/org.xmind.ui.resources/markers/priority_1@32@2x.png new file mode 100644 index 000000000..8e5f74f30 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_1@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_2@16@2x.png b/bundles/org.xmind.ui.resources/markers/priority_2@16@2x.png new file mode 100644 index 000000000..dc9d10cf5 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_2@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_2@24@2x.png b/bundles/org.xmind.ui.resources/markers/priority_2@24@2x.png new file mode 100644 index 000000000..bffb9cc6c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_2@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_2@32@2x.png b/bundles/org.xmind.ui.resources/markers/priority_2@32@2x.png new file mode 100644 index 000000000..c10b413ab Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_2@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_3@16@2x.png b/bundles/org.xmind.ui.resources/markers/priority_3@16@2x.png new file mode 100644 index 000000000..f37019c6b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_3@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_3@24@2x.png b/bundles/org.xmind.ui.resources/markers/priority_3@24@2x.png new file mode 100644 index 000000000..b428ad20f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_3@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_3@32@2x.png b/bundles/org.xmind.ui.resources/markers/priority_3@32@2x.png new file mode 100644 index 000000000..5fb867bb6 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_3@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_4@16@2x.png b/bundles/org.xmind.ui.resources/markers/priority_4@16@2x.png new file mode 100644 index 000000000..bc48a5c53 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_4@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_4@24@2x.png b/bundles/org.xmind.ui.resources/markers/priority_4@24@2x.png new file mode 100644 index 000000000..a0a3e0120 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_4@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_4@32@2x.png b/bundles/org.xmind.ui.resources/markers/priority_4@32@2x.png new file mode 100644 index 000000000..1a72a1ca0 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_4@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_5@16@2x.png b/bundles/org.xmind.ui.resources/markers/priority_5@16@2x.png new file mode 100644 index 000000000..743a5bbec Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_5@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_5@24@2x.png b/bundles/org.xmind.ui.resources/markers/priority_5@24@2x.png new file mode 100644 index 000000000..3e351f6c8 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_5@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_5@32@2x.png b/bundles/org.xmind.ui.resources/markers/priority_5@32@2x.png new file mode 100644 index 000000000..dd3acabab Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_5@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_6@16@2x.png b/bundles/org.xmind.ui.resources/markers/priority_6@16@2x.png new file mode 100644 index 000000000..ad0eb40ff Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_6@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_6@24@2x.png b/bundles/org.xmind.ui.resources/markers/priority_6@24@2x.png new file mode 100644 index 000000000..69606a50f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_6@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_6@32@2x.png b/bundles/org.xmind.ui.resources/markers/priority_6@32@2x.png new file mode 100644 index 000000000..26919fa50 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_6@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_7@16@2x.png b/bundles/org.xmind.ui.resources/markers/priority_7@16@2x.png new file mode 100644 index 000000000..5c3131f63 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_7@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_7@24@2x.png b/bundles/org.xmind.ui.resources/markers/priority_7@24@2x.png new file mode 100644 index 000000000..9487655cd Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_7@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_7@32@2x.png b/bundles/org.xmind.ui.resources/markers/priority_7@32@2x.png new file mode 100644 index 000000000..2f52e9edd Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_7@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_8@16@2x.png b/bundles/org.xmind.ui.resources/markers/priority_8@16@2x.png new file mode 100644 index 000000000..62954489d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_8@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_8@24@2x.png b/bundles/org.xmind.ui.resources/markers/priority_8@24@2x.png new file mode 100644 index 000000000..42332fa8a Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_8@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_8@32@2x.png b/bundles/org.xmind.ui.resources/markers/priority_8@32@2x.png new file mode 100644 index 000000000..a98b45583 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_8@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_9@16@2x.png b/bundles/org.xmind.ui.resources/markers/priority_9@16@2x.png new file mode 100644 index 000000000..a434f8ab8 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_9@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_9@24@2x.png b/bundles/org.xmind.ui.resources/markers/priority_9@24@2x.png new file mode 100644 index 000000000..c9cc67b17 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_9@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/priority_9@32@2x.png b/bundles/org.xmind.ui.resources/markers/priority_9@32@2x.png new file mode 100644 index 000000000..f8fe949ae Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/priority_9@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_1o@16.svg b/bundles/org.xmind.ui.resources/markers/progress_1o@16.svg index 93068c5c1..a8141bd33 100644 --- a/bundles/org.xmind.ui.resources/markers/progress_1o@16.svg +++ b/bundles/org.xmind.ui.resources/markers/progress_1o@16.svg @@ -11,7 +11,17 @@ - + - \ No newline at end of file + diff --git a/bundles/org.xmind.ui.resources/markers/progress_1o@16@2x.png b/bundles/org.xmind.ui.resources/markers/progress_1o@16@2x.png new file mode 100644 index 000000000..f4940496c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_1o@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_1o@24@2x.png b/bundles/org.xmind.ui.resources/markers/progress_1o@24@2x.png new file mode 100644 index 000000000..769447823 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_1o@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_1o@32@2x.png b/bundles/org.xmind.ui.resources/markers/progress_1o@32@2x.png new file mode 100644 index 000000000..567fa75ea Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_1o@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_1q@16.svg b/bundles/org.xmind.ui.resources/markers/progress_1q@16.svg index 744f65686..276a3c1f4 100644 --- a/bundles/org.xmind.ui.resources/markers/progress_1q@16.svg +++ b/bundles/org.xmind.ui.resources/markers/progress_1q@16.svg @@ -11,7 +11,12 @@ - + - \ No newline at end of file + diff --git a/bundles/org.xmind.ui.resources/markers/progress_1q@16@2x.png b/bundles/org.xmind.ui.resources/markers/progress_1q@16@2x.png new file mode 100644 index 000000000..38c0b114a Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_1q@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_1q@24@2x.png b/bundles/org.xmind.ui.resources/markers/progress_1q@24@2x.png new file mode 100644 index 000000000..d7c33eb17 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_1q@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_1q@32@2x.png b/bundles/org.xmind.ui.resources/markers/progress_1q@32@2x.png new file mode 100644 index 000000000..82e07ff6f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_1q@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_3o@16.svg b/bundles/org.xmind.ui.resources/markers/progress_3o@16.svg index dee295419..a7bd81d82 100644 --- a/bundles/org.xmind.ui.resources/markers/progress_3o@16.svg +++ b/bundles/org.xmind.ui.resources/markers/progress_3o@16.svg @@ -11,7 +11,16 @@ - + - \ No newline at end of file + diff --git a/bundles/org.xmind.ui.resources/markers/progress_3o@16@2x.png b/bundles/org.xmind.ui.resources/markers/progress_3o@16@2x.png new file mode 100644 index 000000000..db64118fa Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_3o@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_3o@24@2x.png b/bundles/org.xmind.ui.resources/markers/progress_3o@24@2x.png new file mode 100644 index 000000000..2b5d04974 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_3o@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_3o@32@2x.png b/bundles/org.xmind.ui.resources/markers/progress_3o@32@2x.png new file mode 100644 index 000000000..e7c034902 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_3o@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_3q@16.svg b/bundles/org.xmind.ui.resources/markers/progress_3q@16.svg index cd21237fe..671b1ddd3 100644 --- a/bundles/org.xmind.ui.resources/markers/progress_3q@16.svg +++ b/bundles/org.xmind.ui.resources/markers/progress_3q@16.svg @@ -11,7 +11,11 @@ - + - \ No newline at end of file + diff --git a/bundles/org.xmind.ui.resources/markers/progress_3q@16@2x.png b/bundles/org.xmind.ui.resources/markers/progress_3q@16@2x.png new file mode 100644 index 000000000..6e97dbbac Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_3q@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_3q@24@2x.png b/bundles/org.xmind.ui.resources/markers/progress_3q@24@2x.png new file mode 100644 index 000000000..1108769b7 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_3q@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_3q@32@2x.png b/bundles/org.xmind.ui.resources/markers/progress_3q@32@2x.png new file mode 100644 index 000000000..0fe5f98a7 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_3q@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_5o@16.svg b/bundles/org.xmind.ui.resources/markers/progress_5o@16.svg index 3396178cd..57279108c 100644 --- a/bundles/org.xmind.ui.resources/markers/progress_5o@16.svg +++ b/bundles/org.xmind.ui.resources/markers/progress_5o@16.svg @@ -11,7 +11,13 @@ - + - \ No newline at end of file + diff --git a/bundles/org.xmind.ui.resources/markers/progress_5o@16@2x.png b/bundles/org.xmind.ui.resources/markers/progress_5o@16@2x.png new file mode 100644 index 000000000..f3165cdb6 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_5o@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_5o@24@2x.png b/bundles/org.xmind.ui.resources/markers/progress_5o@24@2x.png new file mode 100644 index 000000000..1aabe73c4 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_5o@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_5o@32@2x.png b/bundles/org.xmind.ui.resources/markers/progress_5o@32@2x.png new file mode 100644 index 000000000..db9b55a81 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_5o@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_7o@16.svg b/bundles/org.xmind.ui.resources/markers/progress_7o@16.svg index 97a77e2d2..b26d43165 100644 --- a/bundles/org.xmind.ui.resources/markers/progress_7o@16.svg +++ b/bundles/org.xmind.ui.resources/markers/progress_7o@16.svg @@ -11,7 +11,14 @@ - + - \ No newline at end of file + diff --git a/bundles/org.xmind.ui.resources/markers/progress_7o@16@2x.png b/bundles/org.xmind.ui.resources/markers/progress_7o@16@2x.png new file mode 100644 index 000000000..b28118d0b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_7o@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_7o@24@2x.png b/bundles/org.xmind.ui.resources/markers/progress_7o@24@2x.png new file mode 100644 index 000000000..f9529b0a7 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_7o@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_7o@32@2x.png b/bundles/org.xmind.ui.resources/markers/progress_7o@32@2x.png new file mode 100644 index 000000000..4eee88022 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_7o@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_done@16.svg b/bundles/org.xmind.ui.resources/markers/progress_done@16.svg index 2d14c3239..a7701b4ba 100644 --- a/bundles/org.xmind.ui.resources/markers/progress_done@16.svg +++ b/bundles/org.xmind.ui.resources/markers/progress_done@16.svg @@ -11,7 +11,20 @@ - + - \ No newline at end of file + diff --git a/bundles/org.xmind.ui.resources/markers/progress_done@16@2x.png b/bundles/org.xmind.ui.resources/markers/progress_done@16@2x.png new file mode 100644 index 000000000..8c05c3020 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_done@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_done@24@2x.png b/bundles/org.xmind.ui.resources/markers/progress_done@24@2x.png new file mode 100644 index 000000000..960359319 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_done@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_done@32@2x.png b/bundles/org.xmind.ui.resources/markers/progress_done@32@2x.png new file mode 100644 index 000000000..4e9f08316 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_done@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_half@16.svg b/bundles/org.xmind.ui.resources/markers/progress_half@16.svg index bf0a32059..0d6c90204 100644 --- a/bundles/org.xmind.ui.resources/markers/progress_half@16.svg +++ b/bundles/org.xmind.ui.resources/markers/progress_half@16.svg @@ -11,7 +11,15 @@ - + - \ No newline at end of file + diff --git a/bundles/org.xmind.ui.resources/markers/progress_half@16@2x.png b/bundles/org.xmind.ui.resources/markers/progress_half@16@2x.png new file mode 100644 index 000000000..726364d4b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_half@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_half@24@2x.png b/bundles/org.xmind.ui.resources/markers/progress_half@24@2x.png new file mode 100644 index 000000000..ed83a291c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_half@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_half@32@2x.png b/bundles/org.xmind.ui.resources/markers/progress_half@32@2x.png new file mode 100644 index 000000000..bc11b122b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_half@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_start@16.svg b/bundles/org.xmind.ui.resources/markers/progress_start@16.svg index 7ee64bc8f..ba3c6ae5a 100644 --- a/bundles/org.xmind.ui.resources/markers/progress_start@16.svg +++ b/bundles/org.xmind.ui.resources/markers/progress_start@16.svg @@ -11,7 +11,19 @@ - + - \ No newline at end of file + diff --git a/bundles/org.xmind.ui.resources/markers/progress_start@16@2x.png b/bundles/org.xmind.ui.resources/markers/progress_start@16@2x.png new file mode 100644 index 000000000..146b6e729 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_start@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_start@24@2x.png b/bundles/org.xmind.ui.resources/markers/progress_start@24@2x.png new file mode 100644 index 000000000..4ab63452c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_start@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/progress_start@32@2x.png b/bundles/org.xmind.ui.resources/markers/progress_start@32@2x.png new file mode 100644 index 000000000..0b41a4c17 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/progress_start@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_blue@16@2x.png b/bundles/org.xmind.ui.resources/markers/star_blue@16@2x.png new file mode 100644 index 000000000..c709a5d37 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_blue@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_blue@24@2x.png b/bundles/org.xmind.ui.resources/markers/star_blue@24@2x.png new file mode 100644 index 000000000..8ab753b1c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_blue@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_blue@32@2x.png b/bundles/org.xmind.ui.resources/markers/star_blue@32@2x.png new file mode 100644 index 000000000..bc7a529c1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_blue@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_dark_gray@16@2x.png b/bundles/org.xmind.ui.resources/markers/star_dark_gray@16@2x.png new file mode 100644 index 000000000..fe085ed13 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_dark_gray@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_dark_gray@24@2x.png b/bundles/org.xmind.ui.resources/markers/star_dark_gray@24@2x.png new file mode 100644 index 000000000..ae3e643c1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_dark_gray@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_dark_gray@32@2x.png b/bundles/org.xmind.ui.resources/markers/star_dark_gray@32@2x.png new file mode 100644 index 000000000..a449c7eff Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_dark_gray@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_dark_green@16@2x.png b/bundles/org.xmind.ui.resources/markers/star_dark_green@16@2x.png new file mode 100644 index 000000000..8ecc22528 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_dark_green@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_dark_green@24@2x.png b/bundles/org.xmind.ui.resources/markers/star_dark_green@24@2x.png new file mode 100644 index 000000000..15158f09e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_dark_green@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_dark_green@32@2x.png b/bundles/org.xmind.ui.resources/markers/star_dark_green@32@2x.png new file mode 100644 index 000000000..dd0951bbd Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_dark_green@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_green@16@2x.png b/bundles/org.xmind.ui.resources/markers/star_green@16@2x.png new file mode 100644 index 000000000..81488316a Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_green@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_green@24@2x.png b/bundles/org.xmind.ui.resources/markers/star_green@24@2x.png new file mode 100644 index 000000000..dc7ffce25 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_green@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_green@32@2x.png b/bundles/org.xmind.ui.resources/markers/star_green@32@2x.png new file mode 100644 index 000000000..0d201d41e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_green@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_orange@16@2x.png b/bundles/org.xmind.ui.resources/markers/star_orange@16@2x.png new file mode 100644 index 000000000..d64b8d058 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_orange@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_orange@24@2x.png b/bundles/org.xmind.ui.resources/markers/star_orange@24@2x.png new file mode 100644 index 000000000..3af62baab Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_orange@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_orange@32@2x.png b/bundles/org.xmind.ui.resources/markers/star_orange@32@2x.png new file mode 100644 index 000000000..8836cf440 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_orange@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_purple@16@2x.png b/bundles/org.xmind.ui.resources/markers/star_purple@16@2x.png new file mode 100644 index 000000000..31225079b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_purple@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_purple@24@2x.png b/bundles/org.xmind.ui.resources/markers/star_purple@24@2x.png new file mode 100644 index 000000000..8fc0d61c3 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_purple@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_purple@32@2x.png b/bundles/org.xmind.ui.resources/markers/star_purple@32@2x.png new file mode 100644 index 000000000..4eabe1081 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_purple@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_red@16@2x.png b/bundles/org.xmind.ui.resources/markers/star_red@16@2x.png new file mode 100644 index 000000000..06168d18c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_red@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_red@24@2x.png b/bundles/org.xmind.ui.resources/markers/star_red@24@2x.png new file mode 100644 index 000000000..5a73337eb Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_red@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/star_red@32@2x.png b/bundles/org.xmind.ui.resources/markers/star_red@32@2x.png new file mode 100644 index 000000000..5a6fc3ef9 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/star_red@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/sym_attention@16@2x.png b/bundles/org.xmind.ui.resources/markers/sym_attention@16@2x.png new file mode 100644 index 000000000..dd05e3993 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/sym_attention@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/sym_attention@24@2x.png b/bundles/org.xmind.ui.resources/markers/sym_attention@24@2x.png new file mode 100644 index 000000000..fe9d6570a Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/sym_attention@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/sym_attention@32@2x.png b/bundles/org.xmind.ui.resources/markers/sym_attention@32@2x.png new file mode 100644 index 000000000..219dcb408 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/sym_attention@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_bar_chart@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_bar_chart@16@2x.png new file mode 100644 index 000000000..23c83292f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_bar_chart@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_bar_chart@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_bar_chart@24@2x.png new file mode 100644 index 000000000..5f1d3c8f1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_bar_chart@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_bar_chart@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_bar_chart@32@2x.png new file mode 100644 index 000000000..b0959cc00 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_bar_chart@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_contact@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_contact@16@2x.png new file mode 100644 index 000000000..b62a1bdb1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_contact@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_contact@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_contact@24@2x.png new file mode 100644 index 000000000..85bb61af1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_contact@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_contact@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_contact@32@2x.png new file mode 100644 index 000000000..3f1570bd7 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_contact@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_dislike@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_dislike@16@2x.png new file mode 100644 index 000000000..d650cf3a1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_dislike@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_dislike@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_dislike@24@2x.png new file mode 100644 index 000000000..b35e69380 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_dislike@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_dislike@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_dislike@32@2x.png new file mode 100644 index 000000000..043dfe963 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_dislike@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_drink@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_drink@16@2x.png new file mode 100644 index 000000000..05180e067 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_drink@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_drink@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_drink@24@2x.png new file mode 100644 index 000000000..53d9ba545 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_drink@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_drink@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_drink@32@2x.png new file mode 100644 index 000000000..72aa8370c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_drink@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_exercise@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_exercise@16@2x.png new file mode 100644 index 000000000..aa8ca54e6 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_exercise@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_exercise@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_exercise@24@2x.png new file mode 100644 index 000000000..ea8297585 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_exercise@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_exercise@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_exercise@32@2x.png new file mode 100644 index 000000000..7b1b25f8a Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_exercise@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_flight@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_flight@16@2x.png new file mode 100644 index 000000000..7ea2de942 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_flight@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_flight@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_flight@24@2x.png new file mode 100644 index 000000000..d9fba1119 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_flight@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_flight@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_flight@32@2x.png new file mode 100644 index 000000000..30940d76d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_flight@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_heart@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_heart@16@2x.png new file mode 100644 index 000000000..58090e880 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_heart@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_heart@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_heart@24@2x.png new file mode 100644 index 000000000..0cc73e5ed Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_heart@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_heart@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_heart@32@2x.png new file mode 100644 index 000000000..0dbc3a54f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_heart@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_information@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_information@16@2x.png new file mode 100644 index 000000000..cbe10d1b6 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_information@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_information@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_information@24@2x.png new file mode 100644 index 000000000..c97480805 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_information@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_information@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_information@32@2x.png new file mode 100644 index 000000000..b47e6d95e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_information@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_like@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_like@16@2x.png new file mode 100644 index 000000000..092884de1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_like@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_like@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_like@24@2x.png new file mode 100644 index 000000000..ac1483659 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_like@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_like@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_like@32@2x.png new file mode 100644 index 000000000..912e52e91 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_like@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_line_graph@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_line_graph@16@2x.png new file mode 100644 index 000000000..fbb094437 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_line_graph@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_line_graph@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_line_graph@24@2x.png new file mode 100644 index 000000000..5dbceddb3 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_line_graph@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_line_graph@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_line_graph@32@2x.png new file mode 100644 index 000000000..d9c62c6b5 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_line_graph@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_medals@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_medals@16@2x.png new file mode 100644 index 000000000..354e8b12b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_medals@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_medals@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_medals@24@2x.png new file mode 100644 index 000000000..c41b1bb26 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_medals@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_medals@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_medals@32@2x.png new file mode 100644 index 000000000..85bebc6f3 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_medals@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_minus@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_minus@16@2x.png new file mode 100644 index 000000000..f1b09e9f7 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_minus@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_minus@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_minus@24@2x.png new file mode 100644 index 000000000..f3bb77efc Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_minus@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_minus@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_minus@32@2x.png new file mode 100644 index 000000000..cb97d60b9 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_minus@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_money@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_money@16@2x.png new file mode 100644 index 000000000..dfaa2edac Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_money@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_money@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_money@24@2x.png new file mode 100644 index 000000000..9fba018fa Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_money@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_money@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_money@32@2x.png new file mode 100644 index 000000000..e94ee2b36 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_money@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_music@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_music@16@2x.png new file mode 100644 index 000000000..604bf8b62 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_music@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_music@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_music@24@2x.png new file mode 100644 index 000000000..5553adada Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_music@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_music@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_music@32@2x.png new file mode 100644 index 000000000..afd1f1be7 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_music@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_pause@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_pause@16@2x.png new file mode 100644 index 000000000..6019250ca Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_pause@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_pause@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_pause@24@2x.png new file mode 100644 index 000000000..ee0e473bd Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_pause@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_pause@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_pause@32@2x.png new file mode 100644 index 000000000..b1a49ae80 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_pause@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_pen@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_pen@16@2x.png new file mode 100644 index 000000000..dac006b5f Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_pen@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_pen@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_pen@24@2x.png new file mode 100644 index 000000000..f146fa87b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_pen@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_pen@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_pen@32@2x.png new file mode 100644 index 000000000..ba992330e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_pen@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_pie_chart@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_pie_chart@16@2x.png new file mode 100644 index 000000000..5ed9da8f6 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_pie_chart@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_pie_chart@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_pie_chart@24@2x.png new file mode 100644 index 000000000..30aec79ad Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_pie_chart@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_pie_chart@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_pie_chart@32@2x.png new file mode 100644 index 000000000..affbf7eae Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_pie_chart@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_plus@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_plus@16@2x.png new file mode 100644 index 000000000..b0248a5c0 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_plus@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_plus@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_plus@24@2x.png new file mode 100644 index 000000000..bab381924 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_plus@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_plus@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_plus@32@2x.png new file mode 100644 index 000000000..41e59b954 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_plus@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_question@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_question@16@2x.png new file mode 100644 index 000000000..44fe3d777 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_question@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_question@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_question@24@2x.png new file mode 100644 index 000000000..47b2eb9fb Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_question@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_question@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_question@32@2x.png new file mode 100644 index 000000000..5ccd44de4 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_question@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_right@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_right@16@2x.png new file mode 100644 index 000000000..be719eeea Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_right@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_right@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_right@24@2x.png new file mode 100644 index 000000000..62bd7d49d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_right@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_right@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_right@32@2x.png new file mode 100644 index 000000000..28b38018e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_right@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_shopping_cart@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_shopping_cart@16@2x.png new file mode 100644 index 000000000..3985ff5c1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_shopping_cart@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_shopping_cart@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_shopping_cart@24@2x.png new file mode 100644 index 000000000..b31595ec6 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_shopping_cart@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_shopping_cart@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_shopping_cart@32@2x.png new file mode 100644 index 000000000..80bb7252e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_shopping_cart@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_telephone@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_telephone@16@2x.png new file mode 100644 index 000000000..7ae0f028d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_telephone@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_telephone@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_telephone@24@2x.png new file mode 100644 index 000000000..ee513762c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_telephone@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_telephone@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_telephone@32@2x.png new file mode 100644 index 000000000..05a5efd1b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_telephone@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_thermometer@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_thermometer@16@2x.png new file mode 100644 index 000000000..7a8a0446d Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_thermometer@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_thermometer@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_thermometer@24@2x.png new file mode 100644 index 000000000..20b52e3aa Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_thermometer@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_thermometer@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_thermometer@32@2x.png new file mode 100644 index 000000000..9da8e4e93 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_thermometer@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_trophy@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_trophy@16@2x.png new file mode 100644 index 000000000..c88b925c0 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_trophy@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_trophy@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_trophy@24@2x.png new file mode 100644 index 000000000..09825533c Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_trophy@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_trophy@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_trophy@32@2x.png new file mode 100644 index 000000000..a8823972e Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_trophy@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_wrong@16@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_wrong@16@2x.png new file mode 100644 index 000000000..d058be727 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_wrong@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_wrong@24@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_wrong@24@2x.png new file mode 100644 index 000000000..a16d6e340 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_wrong@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/symbol_wrong@32@2x.png b/bundles/org.xmind.ui.resources/markers/symbol_wrong@32@2x.png new file mode 100644 index 000000000..5e1b4c818 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/symbol_wrong@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_fri@16.png b/bundles/org.xmind.ui.resources/markers/week_fri@16.png index b429a4873..350a6ab0a 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_fri@16.png and b/bundles/org.xmind.ui.resources/markers/week_fri@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_fri@16.svg b/bundles/org.xmind.ui.resources/markers/week_fri@16.svg index 09290da6f..0ffeaaf46 100644 --- a/bundles/org.xmind.ui.resources/markers/week_fri@16.svg +++ b/bundles/org.xmind.ui.resources/markers/week_fri@16.svg @@ -1,21 +1,20 @@ - - - Rectangle 76 Copy 28 + + + week_fri copy Created with Sketch. - - - - - + + + + - - - - - + + + + + + - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/week_fri@16@2x.png b/bundles/org.xmind.ui.resources/markers/week_fri@16@2x.png new file mode 100644 index 000000000..350a6ab0a Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_fri@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_fri@24.png b/bundles/org.xmind.ui.resources/markers/week_fri@24.png index 4dc278451..eb8675d82 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_fri@24.png and b/bundles/org.xmind.ui.resources/markers/week_fri@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_fri@24@2x.png b/bundles/org.xmind.ui.resources/markers/week_fri@24@2x.png new file mode 100644 index 000000000..4950d1b00 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_fri@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_fri@32.png b/bundles/org.xmind.ui.resources/markers/week_fri@32.png index dbe1fb640..4950d1b00 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_fri@32.png and b/bundles/org.xmind.ui.resources/markers/week_fri@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_fri@32@2x.png b/bundles/org.xmind.ui.resources/markers/week_fri@32@2x.png new file mode 100644 index 000000000..71705f882 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_fri@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_mon@16.png b/bundles/org.xmind.ui.resources/markers/week_mon@16.png index 32301b977..dd9c25942 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_mon@16.png and b/bundles/org.xmind.ui.resources/markers/week_mon@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_mon@16.svg b/bundles/org.xmind.ui.resources/markers/week_mon@16.svg index 311bae19e..84166d1e7 100644 --- a/bundles/org.xmind.ui.resources/markers/week_mon@16.svg +++ b/bundles/org.xmind.ui.resources/markers/week_mon@16.svg @@ -1,21 +1,20 @@ - - - Rectangle 76 Copy 5 + + + week_mon copy Created with Sketch. - - - - - + + + + - - - - - + + + + + + - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/week_mon@16@2x.png b/bundles/org.xmind.ui.resources/markers/week_mon@16@2x.png new file mode 100644 index 000000000..dd9c25942 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_mon@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_mon@24.png b/bundles/org.xmind.ui.resources/markers/week_mon@24.png index 8d1fa8305..255d792b8 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_mon@24.png and b/bundles/org.xmind.ui.resources/markers/week_mon@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_mon@24@2x.png b/bundles/org.xmind.ui.resources/markers/week_mon@24@2x.png new file mode 100644 index 000000000..5f4c57147 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_mon@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_mon@32.png b/bundles/org.xmind.ui.resources/markers/week_mon@32.png index f282d52eb..5f4c57147 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_mon@32.png and b/bundles/org.xmind.ui.resources/markers/week_mon@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_mon@32@2x.png b/bundles/org.xmind.ui.resources/markers/week_mon@32@2x.png new file mode 100644 index 000000000..7af68b567 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_mon@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sat@16.png b/bundles/org.xmind.ui.resources/markers/week_sat@16.png index 20609b85b..9e02fa5f2 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_sat@16.png and b/bundles/org.xmind.ui.resources/markers/week_sat@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sat@16.svg b/bundles/org.xmind.ui.resources/markers/week_sat@16.svg index 969166b80..d329b9785 100644 --- a/bundles/org.xmind.ui.resources/markers/week_sat@16.svg +++ b/bundles/org.xmind.ui.resources/markers/week_sat@16.svg @@ -1,21 +1,20 @@ - - - Rectangle 76 Copy 29 + + + week_sat copy Created with Sketch. - - - - - + + + + - - - - - + + + + + + - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/week_sat@16@2x.png b/bundles/org.xmind.ui.resources/markers/week_sat@16@2x.png new file mode 100644 index 000000000..9e02fa5f2 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_sat@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sat@24.png b/bundles/org.xmind.ui.resources/markers/week_sat@24.png index 00610a306..07c9b5b8e 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_sat@24.png and b/bundles/org.xmind.ui.resources/markers/week_sat@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sat@24@2x.png b/bundles/org.xmind.ui.resources/markers/week_sat@24@2x.png new file mode 100644 index 000000000..c59765f60 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_sat@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sat@32.png b/bundles/org.xmind.ui.resources/markers/week_sat@32.png index c4dd544c5..c59765f60 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_sat@32.png and b/bundles/org.xmind.ui.resources/markers/week_sat@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sat@32@2x.png b/bundles/org.xmind.ui.resources/markers/week_sat@32@2x.png new file mode 100644 index 000000000..58706670b Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_sat@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sun@16.png b/bundles/org.xmind.ui.resources/markers/week_sun@16.png index 939ebae83..ac71e3f71 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_sun@16.png and b/bundles/org.xmind.ui.resources/markers/week_sun@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sun@16.svg b/bundles/org.xmind.ui.resources/markers/week_sun@16.svg index e4327ec71..59f3a3fb3 100644 --- a/bundles/org.xmind.ui.resources/markers/week_sun@16.svg +++ b/bundles/org.xmind.ui.resources/markers/week_sun@16.svg @@ -1,21 +1,20 @@ - - - Rectangle 76 Copy 2 + + + week_sun copy Created with Sketch. - - - - - + + + + - - - - - + + + + + + - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/week_sun@16@2x.png b/bundles/org.xmind.ui.resources/markers/week_sun@16@2x.png new file mode 100644 index 000000000..ac71e3f71 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_sun@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sun@24.png b/bundles/org.xmind.ui.resources/markers/week_sun@24.png index d2e4cd8c4..8d4f57da9 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_sun@24.png and b/bundles/org.xmind.ui.resources/markers/week_sun@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sun@24@2x.png b/bundles/org.xmind.ui.resources/markers/week_sun@24@2x.png new file mode 100644 index 000000000..107549a88 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_sun@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sun@32.png b/bundles/org.xmind.ui.resources/markers/week_sun@32.png index f9f2e3b89..107549a88 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_sun@32.png and b/bundles/org.xmind.ui.resources/markers/week_sun@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_sun@32@2x.png b/bundles/org.xmind.ui.resources/markers/week_sun@32@2x.png new file mode 100644 index 000000000..4c7137f26 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_sun@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_thu@16.png b/bundles/org.xmind.ui.resources/markers/week_thu@16.png index 3af104cb8..49ac5b0d0 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_thu@16.png and b/bundles/org.xmind.ui.resources/markers/week_thu@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_thu@16.svg b/bundles/org.xmind.ui.resources/markers/week_thu@16.svg index edf6203ac..41d2f7e5b 100644 --- a/bundles/org.xmind.ui.resources/markers/week_thu@16.svg +++ b/bundles/org.xmind.ui.resources/markers/week_thu@16.svg @@ -1,21 +1,20 @@ - - - Rectangle 76 Copy 27 + + + week_thu copy Created with Sketch. - - - - - + + + + - - - - - + + + + + + - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/week_thu@16@2x.png b/bundles/org.xmind.ui.resources/markers/week_thu@16@2x.png new file mode 100644 index 000000000..49ac5b0d0 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_thu@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_thu@24.png b/bundles/org.xmind.ui.resources/markers/week_thu@24.png index 44c9d485b..a3f0a192c 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_thu@24.png and b/bundles/org.xmind.ui.resources/markers/week_thu@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_thu@24@2x.png b/bundles/org.xmind.ui.resources/markers/week_thu@24@2x.png new file mode 100644 index 000000000..6486948a3 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_thu@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_thu@32.png b/bundles/org.xmind.ui.resources/markers/week_thu@32.png index f329fa6d3..6486948a3 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_thu@32.png and b/bundles/org.xmind.ui.resources/markers/week_thu@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_thu@32@2x.png b/bundles/org.xmind.ui.resources/markers/week_thu@32@2x.png new file mode 100644 index 000000000..5cacf0f45 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_thu@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_tue@16.png b/bundles/org.xmind.ui.resources/markers/week_tue@16.png index d4b3cc110..ee35fc9d3 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_tue@16.png and b/bundles/org.xmind.ui.resources/markers/week_tue@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_tue@16.svg b/bundles/org.xmind.ui.resources/markers/week_tue@16.svg index 95155d0e9..7a63ba3c8 100644 --- a/bundles/org.xmind.ui.resources/markers/week_tue@16.svg +++ b/bundles/org.xmind.ui.resources/markers/week_tue@16.svg @@ -1,21 +1,20 @@ - - - Rectangle 76 Copy 8 + + + week_tue copy Created with Sketch. - - - - - + + + + - - - - - + + + + + + - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/week_tue@16@2x.png b/bundles/org.xmind.ui.resources/markers/week_tue@16@2x.png new file mode 100644 index 000000000..ee35fc9d3 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_tue@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_tue@24.png b/bundles/org.xmind.ui.resources/markers/week_tue@24.png index 632299fdf..5795d2817 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_tue@24.png and b/bundles/org.xmind.ui.resources/markers/week_tue@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_tue@24@2x.png b/bundles/org.xmind.ui.resources/markers/week_tue@24@2x.png new file mode 100644 index 000000000..62111d6f1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_tue@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_tue@32.png b/bundles/org.xmind.ui.resources/markers/week_tue@32.png index 7d78b7ef0..62111d6f1 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_tue@32.png and b/bundles/org.xmind.ui.resources/markers/week_tue@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_tue@32@2x.png b/bundles/org.xmind.ui.resources/markers/week_tue@32@2x.png new file mode 100644 index 000000000..98ac569f0 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_tue@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_wed@16.png b/bundles/org.xmind.ui.resources/markers/week_wed@16.png index 23afb6f23..cfb4e9b70 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_wed@16.png and b/bundles/org.xmind.ui.resources/markers/week_wed@16.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_wed@16.svg b/bundles/org.xmind.ui.resources/markers/week_wed@16.svg index 138fe4880..53d6dbd63 100644 --- a/bundles/org.xmind.ui.resources/markers/week_wed@16.svg +++ b/bundles/org.xmind.ui.resources/markers/week_wed@16.svg @@ -1,21 +1,20 @@ - - - Rectangle 76 Copy 11 + + + week_wed copy Created with Sketch. - - - - - + + + + - - - - - + + + + + + - \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/markers/week_wed@16@2x.png b/bundles/org.xmind.ui.resources/markers/week_wed@16@2x.png new file mode 100644 index 000000000..cfb4e9b70 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_wed@16@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_wed@24.png b/bundles/org.xmind.ui.resources/markers/week_wed@24.png index 6017d73b9..853633010 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_wed@24.png and b/bundles/org.xmind.ui.resources/markers/week_wed@24.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_wed@24@2x.png b/bundles/org.xmind.ui.resources/markers/week_wed@24@2x.png new file mode 100644 index 000000000..97d3d1f24 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_wed@24@2x.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_wed@32.png b/bundles/org.xmind.ui.resources/markers/week_wed@32.png index e9b91df3b..97d3d1f24 100644 Binary files a/bundles/org.xmind.ui.resources/markers/week_wed@32.png and b/bundles/org.xmind.ui.resources/markers/week_wed@32.png differ diff --git a/bundles/org.xmind.ui.resources/markers/week_wed@32@2x.png b/bundles/org.xmind.ui.resources/markers/week_wed@32@2x.png new file mode 100644 index 000000000..23ec0ec27 Binary files /dev/null and b/bundles/org.xmind.ui.resources/markers/week_wed@32@2x.png differ diff --git a/bundles/org.xmind.ui.resources/pom.xml b/bundles/org.xmind.ui.resources/pom.xml index c6bdc468d..7111b6f75 100644 --- a/bundles/org.xmind.ui.resources/pom.xml +++ b/bundles/org.xmind.ui.resources/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.xmind.cathy.plugins org.xmind.ui.resources - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT eclipse-plugin org.xmind.releng org.xmind.cathy.releng - 3.6.51-SNAPSHOT + 3.7.0-SNAPSHOT ../../ diff --git a/bundles/org.xmind.ui.resources/styles/styles_zh_CN.xml b/bundles/org.xmind.ui.resources/styles/styles_zh_CN.xml new file mode 100644 index 000000000..07e45afce --- /dev/null +++ b/bundles/org.xmind.ui.resources/styles/styles_zh_CN.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/styles/styles_zh_TW.xml b/bundles/org.xmind.ui.resources/styles/styles_zh_TW.xml new file mode 100644 index 000000000..07e45afce --- /dev/null +++ b/bundles/org.xmind.ui.resources/styles/styles_zh_TW.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/styles/themeGroups.xml b/bundles/org.xmind.ui.resources/styles/themeGroups.xml index c8c3b9b44..8e3abb57b 100644 --- a/bundles/org.xmind.ui.resources/styles/themeGroups.xml +++ b/bundles/org.xmind.ui.resources/styles/themeGroups.xml @@ -33,6 +33,7 @@ + diff --git a/bundles/org.xmind.ui.resources/styles/themePopover.xml b/bundles/org.xmind.ui.resources/styles/themePopover.xml new file mode 100644 index 000000000..45c2f213e --- /dev/null +++ b/bundles/org.xmind.ui.resources/styles/themePopover.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/styles/themes.properties b/bundles/org.xmind.ui.resources/styles/themes.properties index ae340a54e..8afb6ecc3 100644 --- a/bundles/org.xmind.ui.resources/styles/themes.properties +++ b/bundles/org.xmind.ui.resources/styles/themes.properties @@ -23,6 +23,7 @@ InkPainting=Ink Painting Light=Light ClassicI=Classic I ClassicII=Classic II +ClassicIII=Classic III Academies=Academies Vintage=Vintage Simple=Simple diff --git a/bundles/org.xmind.ui.resources/styles/themes.xml b/bundles/org.xmind.ui.resources/styles/themes.xml index 0aad67e22..dd5adc289 100644 --- a/bundles/org.xmind.ui.resources/styles/themes.xml +++ b/bundles/org.xmind.ui.resources/styles/themes.xml @@ -1,6 +1,66 @@ + + + + + + + + + + + + + + + + + + + + @@ -31,36 +91,12 @@ - - - - - - - - @@ -310,36 +346,6 @@ - - - - - - - - - - @@ -400,541 +406,623 @@ - - - - - + lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Annual Report.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Annual Report.xmt/styles.xml new file mode 100644 index 000000000..8d18628eb --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Annual Report.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..008d1e6b5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..0824d2670 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/content.xml new file mode 100644 index 000000000..6595c357e --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/content.xml @@ -0,0 +1,21 @@ +Balance SheetAssetsCurrent AssetsCash:50,000Accounts + Receivable:100,000Prepaid + Rent: 50,000Inventory: 100,000Current + Assets:Total Current + Assets: 300,000

      Long-term +AssetsLeasehold +Improvements: 300,000Accumulates + Depreciation:-100,000Total Long-term +Assets: 200,000Total +Assets: 500,000LiabilitiesCurrent +LiabilitiesAccounts +Payable:100,000Accrued +Expenses:100,000Unearned +Revenue:100,000Total Current +Liabilities:300,000Long-term +Liabilities: 100,000Total +Liabilities: 400,000Owner's EquityTotal Owner's + Equity: 100,000Retained +Earnings:50,000Common +Stock:50,000Basic InfoCompany Name:ABC.LtdDate:2016/01/01Total Liabilities +and Owner's Equity:500,000-1Balance SheetEqual \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/meta.xml new file mode 100644 index 000000000..df24fd432 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/styles.xml new file mode 100644 index 000000000..cc40bb72b --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Balance Sheet.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..914f25df2 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..b5563ccb1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/0g8l7cvoups5f0nvgmnfigkf3n.png b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/0g8l7cvoups5f0nvgmnfigkf3n.png new file mode 100644 index 000000000..18fb9e1b0 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/0g8l7cvoups5f0nvgmnfigkf3n.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/2lsqjob5t5f7nicql89sp0ivm7.png b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/2lsqjob5t5f7nicql89sp0ivm7.png new file mode 100644 index 000000000..fe0a41ccf Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/2lsqjob5t5f7nicql89sp0ivm7.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/3ked8un4k3ojsbr9e3ukid36v4.png b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/3ked8un4k3ojsbr9e3ukid36v4.png new file mode 100644 index 000000000..a4285fdce Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/3ked8un4k3ojsbr9e3ukid36v4.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/60ci5487efmnp6u2rvuin2ljhg.png b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/60ci5487efmnp6u2rvuin2ljhg.png new file mode 100644 index 000000000..51534f7d9 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/60ci5487efmnp6u2rvuin2ljhg.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/68p9ne0tgt0gitr19hq8glifqd.png b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/68p9ne0tgt0gitr19hq8glifqd.png new file mode 100644 index 000000000..b2d634c64 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/attachments/68p9ne0tgt0gitr19hq8glifqd.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/content.xml new file mode 100644 index 000000000..8ed6f8dde --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/content.xml @@ -0,0 +1 @@ +Business PlanBefore Writing Your PlanHow Long Should Your Plan Be?Executive SummaryOverviewLastContinuouslyVenture CapitalistsCompanyEmployeeOfficeUniqueTarget MarketCustomersWhoAgesGenderIncomeCompetitorsWhoWhy differentUSPUniqueSellingProposition</boundary></boundaries></topic><topic id="3s0e7nr776fn904q65gqddob5m" modified-by="lyn" timestamp="1477643079390"><title>ProductBenefitsWhen used?How used?Management TeamTrack recordExperienceOthersPartnersYoursSkillsPartnersOthersYoursPartnersStrategyAchievementsWhenWhatPlansShort TeamLong TeamFinancialCash FlowProfit & LossBreak EvenCapital NeededPredictionsSummary3Business PlanImportant \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/meta.xml new file mode 100644 index 000000000..a39f75b88 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/styles.xml new file mode 100644 index 000000000..6ac0c6f21 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Business Plan.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..d1409ed0d --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..b88e676e3 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/107353nik7a2pds8o2g1a1kq9v.png b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/107353nik7a2pds8o2g1a1kq9v.png new file mode 100644 index 000000000..f63d057f7 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/107353nik7a2pds8o2g1a1kq9v.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/4kpjb5vmn5lmah45vj2eu3pai9.png b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/4kpjb5vmn5lmah45vj2eu3pai9.png new file mode 100644 index 000000000..c8f501fdd Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/4kpjb5vmn5lmah45vj2eu3pai9.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/54ll5u6b5641dmhigmfju522qd.png b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/54ll5u6b5641dmhigmfju522qd.png new file mode 100644 index 000000000..f1c9647ad Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/54ll5u6b5641dmhigmfju522qd.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/6vrrjptqml4os90797medc73k3.png b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/6vrrjptqml4os90797medc73k3.png new file mode 100644 index 000000000..18470b5d1 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/6vrrjptqml4os90797medc73k3.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/7herg1h8t3ih0khop1ou8llc3p.png b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/7herg1h8t3ih0khop1ou8llc3p.png new file mode 100644 index 000000000..c4b05dbb6 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/7herg1h8t3ih0khop1ou8llc3p.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/7k8l426lh9i3frngeee8l1rj72.png b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/7k8l426lh9i3frngeee8l1rj72.png new file mode 100644 index 000000000..e6fa0c169 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/attachments/7k8l426lh9i3frngeee8l1rj72.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/content.xml new file mode 100644 index 000000000..c9a7f0e10 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/content.xml @@ -0,0 +1 @@ +s2011Build ConceptIt is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.2012Working in Progress [1]It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.2013Working in Progress [2]It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.2014Working in Progress [3]It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.2015Working in Progress [4]It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.2016Working in Progress [5]It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.-1Business Timeline \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/meta.xml new file mode 100644 index 000000000..7c4d1b781 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/styles.xml new file mode 100644 index 000000000..6f28aabec --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Business Timeline.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..008d1e6b5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..7f19f3976 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/content.xml new file mode 100644 index 000000000..5ab2c2be0 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/content.xml @@ -0,0 +1,3 @@ +Missed + DeadlineBasic InfoProject NameMissed DeadlineDate2016/09/19Prepared ByMollyPeopleMicro-managing + bossAbsent secretarySick children.MachineCoffee machine brokenBroken TruckPoor internet connection.MethodBureaucraticPoor prioritizationLack of planning.EnvironmentFluorescent lightsSmall cubicleOffice cold.MeasurementNo progress trackingNo short term goalsNo timesheet.MaterialsUnstable deskNo printer paperSqueaky desk chair.Sheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/meta.xml new file mode 100644 index 000000000..3cb9718c9 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/styles.xml new file mode 100644 index 000000000..a0cf283e6 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Cause and Effect.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..94bc34ab4 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..0e18babbe Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/0oo0v3r6b7pq8pugr9u4df1l59.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/0oo0v3r6b7pq8pugr9u4df1l59.png new file mode 100644 index 000000000..a1f5ef251 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/0oo0v3r6b7pq8pugr9u4df1l59.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/10bg5224jgb8utll0nrifk664k.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/10bg5224jgb8utll0nrifk664k.png new file mode 100644 index 000000000..a1f5ef251 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/10bg5224jgb8utll0nrifk664k.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/1utv746dmfvfkb86huoiq8t7vn.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/1utv746dmfvfkb86huoiq8t7vn.png new file mode 100644 index 000000000..e0b873777 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/1utv746dmfvfkb86huoiq8t7vn.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/2bnkm0kfadqs6eb53n34qqevp5.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/2bnkm0kfadqs6eb53n34qqevp5.png new file mode 100644 index 000000000..bfcb3e4a8 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/2bnkm0kfadqs6eb53n34qqevp5.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/2uv3ki53i7ogcpl3gs0b1792tp.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/2uv3ki53i7ogcpl3gs0b1792tp.png new file mode 100644 index 000000000..081d53884 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/2uv3ki53i7ogcpl3gs0b1792tp.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/34ej00jou6tn7vqdqi789au57b.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/34ej00jou6tn7vqdqi789au57b.png new file mode 100644 index 000000000..e5697b937 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/34ej00jou6tn7vqdqi789au57b.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/4id6b48ajd6lofmeui1fini45v.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/4id6b48ajd6lofmeui1fini45v.png new file mode 100644 index 000000000..a1f5ef251 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/4id6b48ajd6lofmeui1fini45v.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/5iaap7ivfm9ufqqamu0fqmka93.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/5iaap7ivfm9ufqqamu0fqmka93.png new file mode 100644 index 000000000..081d53884 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/5iaap7ivfm9ufqqamu0fqmka93.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/5od2es36lvrdunr0in0qjeoaio.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/5od2es36lvrdunr0in0qjeoaio.png new file mode 100644 index 000000000..e0b873777 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/5od2es36lvrdunr0in0qjeoaio.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/5u5o6i9v0miv4tpj7hiumg54mi.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/5u5o6i9v0miv4tpj7hiumg54mi.png new file mode 100644 index 000000000..bfcb3e4a8 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/5u5o6i9v0miv4tpj7hiumg54mi.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/6m2qfin74b4r03f972lbb3078b.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/6m2qfin74b4r03f972lbb3078b.png new file mode 100644 index 000000000..e0b873777 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/6m2qfin74b4r03f972lbb3078b.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/6qhp2t572ah1iesjm73kdi48hn.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/6qhp2t572ah1iesjm73kdi48hn.png new file mode 100644 index 000000000..081d53884 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/6qhp2t572ah1iesjm73kdi48hn.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/6ts81nqh8upsl7m82gtuf54m6h.png b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/6ts81nqh8upsl7m82gtuf54m6h.png new file mode 100644 index 000000000..bfcb3e4a8 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/attachments/6ts81nqh8upsl7m82gtuf54m6h.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/content.xml new file mode 100644 index 000000000..ecf3af3fc --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/content.xml @@ -0,0 +1,80 @@ +John DOE +PresidentMarketingJaneTeam LeaderPersonal InfoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: jane@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: jane@abc.comAddress: ***Subtopic 3WilliamsSample textPersonal infoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: name@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: name@abc.comAddress: ***LisaSample textPersonal infoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: name@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: name@abc.comAddress: ***JacobSample textPersonal infoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: name@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: name@abc.comAddress: ***SalesSpencerTeam LeaderPersonal InfoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: jane@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: jane@abc.comAddress: ***Subtopic 3RustySample textPersonal infoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: name@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: name@abc.comAddress: ***DaisySample textPersonal infoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: name@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: name@abc.comAddress: ***AccountingStanleyTeam LeaderPersonal InfoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: jane@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: jane@abc.comAddress: ***Subtopic 3Eric TATLARSample textPersonal infoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: name@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: name@abc.comAddress: ***ElizabethSample textPersonal infoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: name@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: name@abc.comAddress: ***BillSample textPersonal infoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: name@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: name@abc.comAddress: ***HREmilyTeam LeaderPersonal InfoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: jane@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: jane@abc.comAddress: ***Subtopic 3HarveySample textPersonal infoBirthday: Dec. 12, 1990 + +Tel: 000-000-0000 + +Email: name@abc.com + +Address: ***Birthday: Dec. 12, 1990Tel: 000-000-0000Email: name@abc.comAddress: ***Company Hierarchy \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/meta.xml new file mode 100644 index 000000000..37fc97b7c --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/styles.xml new file mode 100644 index 000000000..e3c402d3f --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Company Hierarchy.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..008d1e6b5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..71eec4c89 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/content.xml new file mode 100644 index 000000000..e2e259fe5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/content.xml @@ -0,0 +1 @@ +Manufactory FlowCrushing Raw MaterialsGrinding Raw MaterialsQuarrying Raw MaterialsDry Mixing & BlendingPreheaterRotary KilnClinker CoolerFinish GrindingProduct StoragePackagingShippingGypsumCoal Fly Ash Slag or Pozzolans0Sheet 1<control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="101" svg:y="1"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7oeom17r7vv9vj697plemirn46" end2="3fehltfuj83nmoac735lnqgfr4" id="5bh481t37tuocu96670b052ecg" modified-by="lyn" timestamp="1477643073204"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="3fehltfuj83nmoac735lnqgfr4" end2="2cv0rnjpp477m3a7pem5roph84" id="421jn1in03a0elnldmaniaa76a" modified-by="lyn" timestamp="1477643073204"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="2cv0rnjpp477m3a7pem5roph84" end2="2arrkd89r73flj14016ts0a6cg" id="73mauo5lmlh0rd7uc41md2fpa7" modified-by="lyn" timestamp="1477643073204"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="15" svg:y="69"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"><position svg:x="-18" svg:y="-58"/></control-point></control-points></relationship><relationship end1="2arrkd89r73flj14016ts0a6cg" end2="2m2u1hukrqsfup8d42ub4l021s" id="0k9ldfudjfp883rembn9qkoi86" modified-by="lyn" timestamp="1477643073204"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="2m2u1hukrqsfup8d42ub4l021s" end2="00o1jp5jl9bv79kmlmfs7soipv" id="1qg0cgkqhj80bsffeerdpuvd9r" modified-by="lyn" timestamp="1477643073204"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="00o1jp5jl9bv79kmlmfs7soipv" end2="671r2d1k3m00bocf9asemr2t00" id="7a5oveo73f6c7p4ivunmj922oi" modified-by="lyn" timestamp="1477643073204"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="-30" svg:y="56"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"><position svg:x="16" svg:y="-62"/></control-point></control-points></relationship><relationship end1="3jqt0msclt2755a2sapbdu7nua" end2="6u8p59549vejcmafvulqq7hmqt" id="7var8als22m4saf3lba0b82n4f" modified-by="lyn" timestamp="1477643073204"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7s5qju03n8j12b18r5gv640snk" end2="671r2d1k3m00bocf9asemr2t00" id="5df2q8g2jvhkbil9984bigib26" modified-by="lyn" timestamp="1477643073204"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="38rff6k01v02mi7nce90fd5o4b" end2="2cv0rnjpp477m3a7pem5roph84" id="6mrbklpkhin7pd1rjtrmq1a3db" modified-by="lyn" style-id="4s81s35uvk1ct8sjk1ad2tr042" timestamp="1477643073205"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="-2" svg:y="-79"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"><position svg:x="135" svg:y="1"/></control-point></control-points></relationship><relationship end1="671r2d1k3m00bocf9asemr2t00" end2="6a8p4kdk16nn4cc6ikncd6b598" id="1msg51vg171crp4ktjllgp1n4k" modified-by="lyn" timestamp="1477643073205"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="6a8p4kdk16nn4cc6ikncd6b598" end2="3jqt0msclt2755a2sapbdu7nua" id="07pevqss5t58a7cv8havu1e1th" modified-by="lyn" timestamp="1477643073205"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship></relationships><legend visibility="visible"><position svg:x="498" svg:y="-57"/><marker-descriptions><marker-description description="Requires Heat Input" marker-id="flag-red"/><marker-description description="Requires Energy Input" marker-id="flag-orange"/><marker-description description="Optional Input" marker-id="flag-green"/><marker-description description="Particulate Emissions" marker-id="star-blue"/><marker-description description="Gaseous Emissions" marker-id="arrow-up"/></marker-descriptions></legend></sheet></xmap-content> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/meta.xml new file mode 100644 index 000000000..fc326c41a --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/meta.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><meta xmlns="urn:xmind:xmap:xmlns:meta:2.0" version="2.0"><Author><Name>lyn</Name><Email/><Org/></Author><Create><Time>Oct 28, 2016 4:24:33 PM</Time></Create><Creator><Name>XMind</Name><Version>3.7.0.qualifier</Version></Creator></meta> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/styles.xml new file mode 100644 index 000000000..45c096e9f --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Manufactory Flow.xmt/styles.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><xmap-styles xmlns="urn:xmind:xmap:xmlns:style:2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" version="2.0"><styles><style id="1r13opooivffn0or89pn7l8cm7" name="" type="map"><map-properties legendFillColor="#FFFFFF"/></style><style id="4gf6gje85rtbrn8et9qc2g24lo" name="" type="topic"><topic-properties fo:font-weight="bold" fo:text-transform="uppercase"/></style><style id="2q833277fr540lcdmlnibcsgjo" name="" type="topic"><topic-properties fo:font-size="11pt"/></style><style id="4s81s35uvk1ct8sjk1ad2tr042" name="" type="relationship"><relationship-properties shape-class="org.xmind.relationshipShape.angled"/></style></styles><automatic-styles><style id="2jlca2b12ujdmdpni6h1e6rmj7" name="" type="summary"><summary-properties line-color="#646466" line-width="4pt" shape-class="org.xmind.summaryShape.square"/></style><style id="21e8uhn7f1u7nnr2j2nsahespn" name="" type="topic"><topic-properties fo:color="#535353" fo:font-family="Open Sans" fo:font-size="10pt" svg:fill="none"/></style><style id="1auhhu5edtoub71d5i344g0fue" name="" type="boundary"><boundary-properties fo:color="#FFFFFF" fo:font-family="Open Sans" fo:font-size="10pt" fo:font-style="italic" line-color="#2D8787" line-pattern="dash" line-width="2pt" shape-class="org.xmind.boundaryShape.roundedRect" svg:fill="#2D8787" svg:opacity=".2"/></style><style id="0e605rjvpqhptr6npv3onc3hok" name="" type="topic"><topic-properties border-line-color="#646466" border-line-width="1pt" callout-shape-class="org.xmind.calloutTopicShape.balloon.roundedRect" fo:color="#606060" fo:font-family="Open Sans" fo:font-size="10pt" fo:font-style="italic" line-class="org.xmind.branchConnection.roundedElbow" line-color="#2C2C2C" line-width="2pt" svg:fill="#F8F3E9"/></style><style id="1nppuqruguhjhn614a4sakp9au" name="" type="topic"><topic-properties border-line-color="#646466" border-line-width="1pt" fo:color="#646466" fo:font-family="Open Sans" fo:font-size="14pt" fo:font-style="normal" fo:font-weight="normal" fo:text-align="center" fo:text-transform="manual" line-class="org.xmind.branchConnection.roundedElbow" line-color="#646466" line-width="1pt" shape-class="org.xmind.topicShape.roundedRect" svg:fill="none"/></style><style id="6hbshn97dmn06c4qs0h2a2sefp" name="" type="topic"><topic-properties border-line-color="#646466" border-line-width="1pt" fo:color="#22AC39" fo:font-family="Open Sans" fo:font-size="13pt" fo:font-style="normal" fo:font-weight="normal" fo:text-transform="uppercase" line-class="org.xmind.branchConnection.roundedElbow" line-color="#646466" line-width="1pt" shape-class="org.xmind.topicShape.roundedRect" svg:fill="none"/></style><style id="5vgcovv1vslqr8c4glhuieopo0" name="" type="topic"><topic-properties border-line-color="#646466" border-line-width="1pt" fo:color="#646466" fo:font-family="Open Sans" fo:font-size="10pt" fo:font-style="normal" fo:font-weight="normal" fo:text-decoration="none" fo:text-transform="manual" line-class="org.xmind.branchConnection.curve" line-width="1pt" shape-class="org.xmind.topicShape.roundedRect" svg:fill="#F6F0E3"/></style><style id="5b0i52t2avmqiraho6le6p8stm" name="" type="relationship"><relationship-properties arrow-begin-class="org.xmind.arrowShape.none" arrow-end-class="org.xmind.arrowShape.triangle" fo:color="#2C2C2C" fo:font-family="Open Sans" fo:font-size="11pt" fo:font-style="italic" line-color="#595959" line-pattern="solid" line-width="2pt" shape-class="org.xmind.relationshipShape.straight"/></style><style id="2v8ga64p7dm89bsu9s890f3a58" name="" type="topic"><topic-properties border-line-width="1pt" fo:color="#646466" fo:font-family="Open Sans" fo:font-size="14pt" fo:font-style="normal" fo:font-weight="normal" fo:text-align="center" fo:text-transform="manual" line-class="org.xmind.branchConnection.roundedElbow" line-color="#646466" line-width="1pt" shape-class="org.xmind.topicShape.roundedRect" svg:fill="none"/></style><style id="2jh3ottln5kqnkkptr0k1vvgk9" name="" type="map"><map-properties background="" color-gradient="none" line-tapered="tapered" multi-line-colors="none" svg:fill="#FFFFFF" svg:opacity="1.0"/></style></automatic-styles><master-styles><style id="2r3e6ifq9nf334lmr5m8jb2gvo" name="Theme 2" type="theme"><theme-properties><default-style style-family="summary" style-id="2jlca2b12ujdmdpni6h1e6rmj7"/><default-style style-family="subTopic" style-id="21e8uhn7f1u7nnr2j2nsahespn"/><default-style style-family="boundary" style-id="1auhhu5edtoub71d5i344g0fue"/><default-style style-family="calloutTopic" style-id="0e605rjvpqhptr6npv3onc3hok"/><default-style style-family="centralTopic" style-id="1nppuqruguhjhn614a4sakp9au"/><default-style style-family="mainTopic" style-id="6hbshn97dmn06c4qs0h2a2sefp"/><default-style style-family="summaryTopic" style-id="5vgcovv1vslqr8c4glhuieopo0"/><default-style style-family="relationship" style-id="5b0i52t2avmqiraho6le6p8stm"/><default-style style-family="floatingTopic" style-id="2v8ga64p7dm89bsu9s890f3a58"/><default-style style-family="map" style-id="2jh3ottln5kqnkkptr0k1vvgk9"/></theme-properties></style></master-styles></xmap-styles> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..0ee6410a5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><manifest xmlns="urn:xmind:xmap:xmlns:manifest:1.0" password-hint=""><file-entry full-path="attachments/" media-type=""/><file-entry full-path="attachments/14p69ufe483apondkufcjh3t57.pdf" media-type=""/><file-entry full-path="content.xml" media-type="text/xml"/><file-entry full-path="META-INF/" media-type=""/><file-entry full-path="META-INF/manifest.xml" media-type="text/xml"/><file-entry full-path="meta.xml" media-type="text/xml"/><file-entry full-path="styles.xml" media-type="text/xml"/><file-entry full-path="Thumbnails/" media-type=""/><file-entry full-path="Thumbnails/thumbnail.png" media-type=""/></manifest> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..b128fc021 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/attachments/14p69ufe483apondkufcjh3t57.pdf b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/attachments/14p69ufe483apondkufcjh3t57.pdf new file mode 100644 index 000000000..416077f38 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/attachments/14p69ufe483apondkufcjh3t57.pdf differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/content.xml new file mode 100644 index 000000000..53f9121f0 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/content.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><xmap-content xmlns="urn:xmind:xmap:xmlns:content:2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" modified-by="lyn" timestamp="1477480862206" version="2.0"><sheet id="5oefn0g0isjrs4c6jq7e4tmdr3" modified-by="lyn" style-id="2s51e9c5mjs6mi4tu8sa7f2n25" theme="2br96v98a0rnb7po508v3pqm06" timestamp="1477480862206"><topic id="05and3psga0kcg5fvv0v3rslr7" modified-by="lyn" structure-class="org.xmind.ui.spreadsheet.column" style-id="1407ld96abvt79ieul5dr3uagj" timestamp="1477480862206"><title>Meeting ManagementTopicRelease meeting<labels><label>05</label></labels></topic><topic id="38ctmkea118eh07ojber2g4cic" modified-by="lyn" style-id="714ina2r453hiuoijgtj3l38o6" timestamp="1477480862203"><labels><label>06</label></labels></topic><topic id="4ngc856fo36s8qtfnqtq8tcuiu" modified-by="lyn" style-id="714ina2r453hiuoijgtj3l38o6" timestamp="1477480862203"><title>Determine marketing budget +for Quarter 4Approved the $100,000 budgetMarketing analysis for Quarter 3Data AnalysisDate & TimeSep. 16, 2016Sep. 30, 2016Oct. 30, 20169:00 am3:30 pm10:00 am ParticipantsOwen/Molly/AnnaOwen/StephenAll StaffsDocs & Notessample document.pdfMeeting Minutes[AGENDA TOPIC HERE] + +Time Allocated: 5 min +Presented By: Anna + +Discussion: Remarks + +Conclusion: Remarks + + +ACTIONS + +[Action Topic 1 Here] +Anna +Friday, September 16, 2016; 3:30 PM + +[Action Topic 2 Here] +Anna +Friday, September 16, 2016; 3:50 PM +[AGENDA TOPIC HERE]Time Allocated: 5 minPresented By: AnnaDiscussion: RemarksConclusion: RemarksACTIONS[Action Topic 1 Here]AnnaFriday, September 16, 2016; 3:30 PM[Action Topic 2 Here]AnnaFriday, September 16, 2016; 3:50 PMDocsMeeting Minutes[AGENDA TOPIC HERE] + +Time Allocated: 5 min +Presented By: Anna + +Discussion: Remarks + +Conclusion: Remarks + + +ACTIONS + +[Action Topic 1 Here] +Anna +Friday, September 16, 2016; 3:30 PM + +[Action Topic 2 Here] +Anna +Friday, September 16, 2016; 3:50 PM +[AGENDA TOPIC HERE]Time Allocated: 5 minPresented By: AnnaDiscussion: RemarksConclusion: RemarksACTIONS[Action Topic 1 Here]AnnaFriday, September 16, 2016; 3:30 PM[Action Topic 2 Here]AnnaFriday, September 16, 2016; 3:50 PMDocsMeeting Minutes[AGENDA TOPIC HERE] + +Time Allocated: 5 min +Presented By: Anna + +Discussion: Remarks + +Conclusion: Remarks + + +ACTIONS + +[Action Topic 1 Here] +Anna +Friday, September 16, 2016; 3:30 PM + +[Action Topic 2 Here] +Anna +Friday, September 16, 2016; 3:50 PM +[AGENDA TOPIC HERE]Time Allocated: 5 minPresented By: AnnaDiscussion: RemarksConclusion: RemarksACTIONS[Action Topic 1 Here]AnnaFriday, September 16, 2016; 3:30 PM[Action Topic 2 Here]AnnaFriday, September 16, 2016; 3:50 PM-1010203040506Sheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/meta.xml new file mode 100644 index 000000000..bf9f8d52f --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/styles.xml new file mode 100644 index 000000000..22e45490f --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Meeting Management.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..008d1e6b5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..9373aeea3 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/content.xml new file mode 100644 index 000000000..348495f47 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/content.xml @@ -0,0 +1 @@ +Problem SolvingWhat's the ProblemThink about the real purposeIdeal conditionFind out the gapAnalysis of Current SituationVague conceptQuantificationDetailsSet GoalsDiscussSub GoalsQuantifiable targetsFind out the ReasonsWhy?use tools to analyzeFind out the reason from the phenomenonSolutionsWhoPerson 1Person 2WhereWhenHowMake detailed plansMake detailed plansImplementGo with plansCheck effect of ImplementationStop useless solutions-1Sheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/meta.xml new file mode 100644 index 000000000..4e1f5177e --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/styles.xml new file mode 100644 index 000000000..4673c2e12 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Problem Solving.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..17be28c7d --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..966d7135d Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/attachments/6qgqinhhftphehs1rtcpk5hh6g.pdf b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/attachments/6qgqinhhftphehs1rtcpk5hh6g.pdf new file mode 100644 index 000000000..f9fa78702 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/attachments/6qgqinhhftphehs1rtcpk5hh6g.pdf differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/content.xml new file mode 100644 index 000000000..bf3c2ebbb --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/content.xml @@ -0,0 +1 @@ +Projects DashboardProject 1Idea 1Idea 2......FrankNew WebsiteAccomplishmentsCompleted Actions 1Completed Actions 2Completed Actions 3Action 1Action 1aAction 1bAction 2Action 3Aug 20Action 4Action 5Action 6project sample document.pdfProject 2New product ABrianIdea 1Idea 2Idea 2aIdea 2bAccomplishmentsCompleted Actions 1Completed Actions 2Completed Actions 3Next MonthAction 1Action 1aAction 1bAction 2Action 3Action 4Action 5Action 6drag files & drop hereProject 3New Product BVivianIdea 1Idea 2Idea 2aIdea 2bAccomplishmentsCompleted Actions 1Completed Actions 2Completed Actions 3I don't knowAction 1Action 1aAction 1bAction 2Action 3Action 4Action 5Action 6drag files & drop hereObjectivesProject ManagerBrainstormingProgress/ECTNext Actions (High Priority)Next Actions (Low Priority)DocumentsProject Dashboard \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/meta.xml new file mode 100644 index 000000000..00886b9b9 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/styles.xml new file mode 100644 index 000000000..751a3d055 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Projects Dashboard.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..008d1e6b5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..d1bafce56 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/content.xml new file mode 100644 index 000000000..df8143c0e --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/content.xml @@ -0,0 +1 @@ +Business SWOT AnalysisSWhat do you do well?What internal resources do you have? What advantages do you have over your competition?Do you have strong research and development capabilities? Manufacturing facilities?What other positive aspects, internal to your business, add value or offer you a competitive advantage?.WWhat factors that are within your control detract from your ability to obtain or maintain a competitive edge?What areas need improvement to compete with your strongest competitor?What does your business lack (for example, expertise or access to skills or technology)?Does your business have limited resources?Is your business in a poor location?.OWhat opportunities exist in your market or the environment that you can benefit from?Is the perception of your business positive?Has there been recent market growth or have there been other changes in the market the create an opportunity?Is the opportunity ongoing, or is there just a window for it? In other words, how critical is your timing?.TWho are your existing or potential competitors?What factors beyond your control could place your business at risk?What situations might threaten your marketing efforts?Has there been a significant change in supplier prices or the availability of raw materials?What about shifts in consumer behavior, the economy, or government regulations that could reduce your sales?.Helpful0Business SWOT Analysis<control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="047v7a2s7dgk54mm93ro2sh8ke" end2="0etura6b1rjsp3afl3vr53oh97" id="55s9agt103kp91mv01mbqnue04" modified-by="lyn" style-id="2h0bp35832uf40tbkro19e8cm5" timestamp="1477643066431"><title>1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/meta.xml new file mode 100644 index 000000000..322e7d654 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/styles.xml new file mode 100644 index 000000000..e7a0505a2 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/SWOT Analysis.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..c849f98f9 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..310d73d35 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/attachments/7qm4j10obb7b3i4tgkp4n6npp7.png b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/attachments/7qm4j10obb7b3i4tgkp4n6npp7.png new file mode 100644 index 000000000..1d4621ee4 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/attachments/7qm4j10obb7b3i4tgkp4n6npp7.png differ diff --git a/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/content.xml new file mode 100644 index 000000000..72ef7c7d4 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/content.xml @@ -0,0 +1,2 @@ +Sales +ManagementProductsProduct 1Product 2Product 3ResourceSalesmanSales ManagerMarketing MaterialsAdvertisingTargetsQ1Quantity500,000 Revenue$50,000,000Q2QuantityRevenueQ3QuantityRevenueQ4QuantityRevenueAnalysisCost AnalysisProfit AnalysisMarketing AnalysisInventory AnalysisCRMTop 10 customersCalls & VisitsExpense Logs3Sales Management \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/meta.xml new file mode 100644 index 000000000..0c5d88320 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/styles.xml new file mode 100644 index 000000000..f1d42d3a1 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/business/Sales Management.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..bd8b53204 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..8532d9a06 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/attachments/3i8t9b4f4ma6fqdlnpob1d4hng.png b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/attachments/3i8t9b4f4ma6fqdlnpob1d4hng.png new file mode 100644 index 000000000..35d0a333f Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/attachments/3i8t9b4f4ma6fqdlnpob1d4hng.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/content.xml new file mode 100644 index 000000000..229667ab5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/content.xml @@ -0,0 +1,2 @@ +The Great GatsbyMain CharacterNick CarrawayJay GatsbyDaisy Fay BuchananThomas "Tom" Buchanan....Plot AnalysisExpositionEast or West, Home is BestOur narrator Nick Carraway is back from World War I and renting a house in West Egg, a small but fancy town on Long Island. Cousin Daisy and her ex-football player husband Tom live across the bay in fancier East Egg. Jay Gatsby, Nick's next door neighbor, is a wealthy newcomer who throws large parties weekly, during which his guests are happy to drink his (illegal) booze while snubbing him for being (1) nouveau riche and (2) possibly involved in some shady activities.Our narrator Nick Carraway is back from World War I and renting a house in West Egg, a small but fancy town on Long Island. Cousin Daisy and her ex-football player husband Tom live across the bay in fancier East Egg. Jay Gatsby, Nick's next door neighbor, is a wealthy newcomer who throws large parties weekly, during which his guests are happy to drink his (illegal) booze while snubbing him for being (1) nouveau riche and (2) possibly involved in some shady activities.ConflictCall Me, Maybe?Gatsby wants something he can't have: Daisy, and a shot at being in the American upper class. Tom wants something he can't have: a mistress and a wife who know nothing about each other. Nick wants something that he definitely can't have: all these crazy people to stop being crazy. Oh, and the hot young golf pro, Jordan. He'll have her, too.Gatsby wants something he can't have: Daisy, and a shot at being in the American upper class. Tom wants something he can't have: a mistress and a wife who know nothing about each other. Nick wants something that he definitely can't have: all these crazy people to stop being crazy. Oh, and the hot young golf pro, Jordan. He'll have her, too.ComplicationJay Gatsby, Meet James GatzTom Buchanan takes an instant disliking to Gatsby, even before he knows that Daisy is weeping over Gatsby's beautiful shirts. His investigation complicates matters considerably. Turns out, Jay Gatsby is really James Gatz, a poor kid who earned all his wealth from organized crime (gambling, bootlegging liquor). Uh-oh. No wonder Gatsby has so much trouble fitting in.Tom Buchanan takes an instant disliking to Gatsby, even before he knows that Daisy is weeping over Gatsby's beautiful shirts. His investigation complicates matters considerably. Turns out, Jay Gatsby is really James Gatz, a poor kid who earned all his wealth from organized crime (gambling, bootlegging liquor). Uh-oh. No wonder Gatsby has so much trouble fitting in.ClimaxThe Love TrainTom and Gatsby have a tense but understated showdown around who gets to control Daisy, and (surprise) Tom wins. He seals his victory by letting them drive home together, just to rub it in Gatsby's face. But when the others follow behind, they discover that Myrtle was killed by a speeding yellow car that failed to stop. Apparently, a meteoric rise to the top sometimes comes with casualties.Tom and Gatsby have a tense but understated showdown around who gets to control Daisy, and (surprise) Tom wins. He seals his victory by letting them drive home together, just to rub it in Gatsby's face. But when the others follow behind, they discover that Myrtle was killed by a speeding yellow car that failed to stop. Apparently, a meteoric rise to the top sometimes comes with casualties.SuspenseWrong DirectionGatsby watches Daisy's house all night, worried that Tom will do something to her now that her infidelity has been revealed. We don't blame him: he broke his mistress's nose just for saying Daisy's name. What's going to happen to our intrepid anti-hero?Gatsby watches Daisy's house all night, worried that Tom will do something to her now that her infidelity has been revealed. We don't blame him: he broke his mistress's nose just for saying Daisy's name. What's going to happen to our intrepid anti-hero?DenouementPool BoyNick starts digesting last night's events and comes to the understandable conclusion that "They're a rotten crowd" (8.45). We're with you on that one, Nick. It's too bad Gatsby didn't have the same revelation: George Wilson finds him in the pool and then kills both Gatsby and himself in retaliation for mowing down his wife.Nick starts digesting last night's events and comes to the understandable conclusion that "They're a rotten crowd" (8.45). We're with you on that one, Nick. It's too bad Gatsby didn't have the same revelation: George Wilson finds him in the pool and then kills both Gatsby and himself in retaliation for mowing down his wife..SummaryThe main events of the novel take place in the summer of 1922. Nick Carraway, a Yale graduate and World War I veteran from the Midwest—who serves as the novel's narrator—works in New York as a bond salesman...The main events of the novel take place in the summer of 1922. Nick Carraway, a Yale graduate and World War I veteran from the Midwest—who serves as the novel's narrator—works in New York as a bond salesman...ConclusionDon't Follow the LightDaisy and Tom have fled, Nick and Jordan have broken up, and Gatsby is dead. We end with Gatsby's dismal funeral, of course, sparsely attended by Nick, Gatsby's father, and the owl-eyed man who once marveled at all of Gatsby's books. And Nick sends us off with this enigmatic conclusion: the future is always out of reach. Instead, "we beat on, boats against he current, borne back ceaselessly into the past" (9.151).Daisy and Tom have fled, Nick and Jordan have broken up, and Gatsby is dead. We end with Gatsby's dismal funeral, of course, sparsely attended by Nick, Gatsby's father, and the owl-eyed man who once marveled at all of Gatsby's books. And Nick sends us off with this enigmatic conclusion: the future is always out of reach. Instead, "we beat on, boats against he current, borne back ceaselessly into the past" (9.151)..Favorite PartMy favorite part was when Gatsby ran out of the house as Daisy Showed up to have tea with Nick . He came back after moment even paler than he was when he first showed and this time he was soaking wet. He was acting like complete child which made the scene funny and enjoyable . The way he was acting in this passage is the complete opposite of what he really acts like . He normally act all polite but leaves mysterious aura around him as he speaks and walks. In this passage he looked like he had just seen ghost...My favorite part was when Gatsby ran out of the house as Daisy Showed up to have tea with Nick . He came back after moment even paler than he was when he first showed and this time he was soaking wet. He was acting like complete child which made the scene funny and enjoyable . The way he was acting in this passage is the complete opposite of what he really acts like . He normally act all polite but leaves mysterious aura around him as he speaks and walks. In this passage he looked like he had just seen ghost...Recommendation Reason5 reasons why you should +read The Great Gatsby1. It gives a timeless insight into human natureGatsby is a fantastic example of how human nature doesn’t change; the decadence and excess of Fitzgerald’s revellers – the flappers, the gangsters, the bankers and strivers – don’t look much different to the financiers and property-boomers of the late 90s and early 2000s. If Gatsby were alive now, his parties would be televised and sponsored and featured on E! online, and he’d work the City; he’d have sold dodgy mortgages and tried to whisk Daisy off to Dubai for the weekend.Gatsby is a fantastic example of how human nature doesn’t change; the decadence and excess of Fitzgerald’s revellers – the flappers, the gangsters, the bankers and strivers – don’t look much different to the financiers and property-boomers of the late 90s and early 2000s. If Gatsby were alive now, his parties would be televised and sponsored and featured on E! online, and he’d work the City; he’d have sold dodgy mortgages and tried to whisk Daisy off to Dubai for the weekend.2. It showcases an epic time in historyIt’s partly based on real life. Scott and Zelda Fitzgerald moved to Long Island in the early 1920s, where they were surrounded, like Nick Carraway, by enormous estates and mansions. Gatsby’s vulgar ‘new money’ found its real-life counterpart in the denizens of Great Neck, where the Fitzgeralds settled, while the inherited wealth of the Buchanans was more at home over on Cow Neck – or, in Gatsby’s world, East Egg. Some of the possible inspirations for the house still stand today, like Oheka Castle in Huntington. So if you’ve ever wondered about the lives of the great and the glorious…It’s partly based on real life. Scott and Zelda Fitzgerald moved to Long Island in the early 1920s, where they were surrounded, like Nick Carraway, by enormous estates and mansions. Gatsby’s vulgar ‘new money’ found its real-life counterpart in the denizens of Great Neck, where the Fitzgeralds settled, while the inherited wealth of the Buchanans was more at home over on Cow Neck – or, in Gatsby’s world, East Egg. Some of the possible inspirations for the house still stand today, like Oheka Castle in Huntington. So if you’ve ever wondered about the lives of the great and the glorious…3. It’s infinitely better than any filmWe’re staunch advocates of reading the book, no matter how much you enjoyed the film; in the case of The Great Gatsby, we’re joined in this by Zelda Fitzgerald, the author’s wife, who said of the 1926 adaptation (directed by Herbert Brenon) that it was ‘ROTTEN and awful and terrible’; the couple walked out of the screening. It was filmed again in 1949 (dir. Eliot Nugent) and 1974 (dir. Jack Clayton), the latter version from a screenplay by Francis Ford Coppola. Coppola, disappointed by the result, said, ‘The script that I wrote did not get made.’ Of Luhrmann’s production, the New York Times advised that it was best enjoyed if the viewer ‘put aside whatever literary agenda you are tempted to bring with you’. We say, then, put aside the movies and read the book – the original and the best!We’re staunch advocates of reading the book, no matter how much you enjoyed the film; in the case of The Great Gatsby, we’re joined in this by Zelda Fitzgerald, the author’s wife, who said of the 1926 adaptation (directed by Herbert Brenon) that it was ‘ROTTEN and awful and terrible’; the couple walked out of the screening. It was filmed again in 1949 (dir. Eliot Nugent) and 1974 (dir. Jack Clayton), the latter version from a screenplay by Francis Ford Coppola. Coppola, disappointed by the result, said, ‘The script that I wrote did not get made.’ Of Luhrmann’s production, the New York Times advised that it was best enjoyed if the viewer ‘put aside whatever literary agenda you are tempted to bring with you’. We say, then, put aside the movies and read the book – the original and the best!4. It’s a great example of how failure can breed successJay Gatsby is a case-study on the American Dream – the self-made man, the giddy height of success, the idea of financial independence bringing security, freedom and happiness – and how that ideal can implode. This novel wasn’t Fitzgerald’s first foray into that territory, though; before he wrote it, he spent eighteen months on a satirical screenplay called ‘The Vegetable: or From President to Postman’. The play was a disaster – but it helped the gestation process for The Great Gatsby, which Fitzgerald begun as he was redrafting the doomed ‘Vegetable’. If you’ve ever felt downbeat because a project isn’t working out, read Gatsby and see what can arise from the ashes!Jay Gatsby is a case-study on the American Dream – the self-made man, the giddy height of success, the idea of financial independence bringing security, freedom and happiness – and how that ideal can implode. This novel wasn’t Fitzgerald’s first foray into that territory, though; before he wrote it, he spent eighteen months on a satirical screenplay called ‘The Vegetable: or From President to Postman’. The play was a disaster – but it helped the gestation process for The Great Gatsby, which Fitzgerald begun as he was redrafting the doomed ‘Vegetable’. If you’ve ever felt downbeat because a project isn’t working out, read Gatsby and see what can arise from the ashes!5. Its cover is a retro design classicIf hyperbole and retro trivia float your boat, then check out Ernest Hemingway’s appraisal of the original cover for The Great Gatsby: Despite loving the novel itself, he called the jacket “the ugliest he’d ever seen”. Curious? Sure you are! We don’t think it’s ugly, though, and we’re also mad about the various other imagery associated with Gatsby – in particular, Doctor TJ Eckleberg’s ‘enormous yellow spectacles’. In fact, we’d go so far as to call the book one of the most stylish novels we’ve read – and we hope you’ll agree!If hyperbole and retro trivia float your boat, then check out Ernest Hemingway’s appraisal of the original cover for The Great Gatsby: Despite loving the novel itself, he called the jacket “the ugliest he’d ever seen”. Curious? Sure you are! We don’t think it’s ugly, though, and we’re also mad about the various other imagery associated with Gatsby – in particular, Doctor TJ Eckleberg’s ‘enormous yellow spectacles’. In fact, we’d go so far as to call the book one of the most stylish novels we’ve read – and we hope you’ll agree!2Sheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/meta.xml new file mode 100644 index 000000000..f95073f40 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/styles.xml new file mode 100644 index 000000000..86bfe36d1 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Book Report.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..55275ba7e --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..2aa62c828 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/attachments/2ummt617pu1lt2evu57078kfcq.png b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/attachments/2ummt617pu1lt2evu57078kfcq.png new file mode 100644 index 000000000..c03ca95bb Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/attachments/2ummt617pu1lt2evu57078kfcq.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/content.xml new file mode 100644 index 000000000..40ebc6969 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/content.xml @@ -0,0 +1 @@ + Class ScheduleMONIntro to Ecology and Evolution LectureCalculus IIGeneral Chemistry I LectureGender and DevelopmentTUECalculus IIGeneral Chemistry I LectureGender and DevelopmentIntro to Ecology and Evolution LectureWEDPrinciples of MacroeconomicsIntro to Evolution LabTHUIntro to Ecology and Evolution LectureCalculus IIGeneral Chemistry I LectureFRIGeneral Chemistry I LecturePrinciples of Macroeconomics-108:30 AM10:00 AM02:00 PM04:00 PM08:30 AM10:00 AM02:00 PM04:00 PMClass Schedule \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/extensions/org.xmind.ui.presentation.stories.xml b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/extensions/org.xmind.ui.presentation.stories.xml new file mode 100644 index 000000000..c3cf5b562 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/extensions/org.xmind.ui.presentation.stories.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/meta.xml new file mode 100644 index 000000000..7de777166 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/styles.xml new file mode 100644 index 000000000..980d4d6fb --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Class Schedule.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..ff62d6837 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..4758362a9 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/attachments/2gen34l6gbgq7kfagu8gpo2hgt.png b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/attachments/2gen34l6gbgq7kfagu8gpo2hgt.png new file mode 100644 index 000000000..3c109b2db Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/attachments/2gen34l6gbgq7kfagu8gpo2hgt.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/attachments/4b59vj6up124blfo4hm8iadgt1.png b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/attachments/4b59vj6up124blfo4hm8iadgt1.png new file mode 100644 index 000000000..c474f1701 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/attachments/4b59vj6up124blfo4hm8iadgt1.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/content.xml new file mode 100644 index 000000000..ddbd585b6 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/content.xml @@ -0,0 +1 @@ +Getting a cat or dogGetting a cat.Getting a dog.Funny to watchSheds hairHave to feed itVet billsFleasWill catch miceMight scratch peopleWill ignore me IndependentAloofWill go to places with meWill obey meWill do tricksA fence neededPotty train needed0Sheet 1<control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="-172" svg:y="-199"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"><position svg:x="162" svg:y="186"/></control-point></control-points></relationship><relationship end1="1dulst851jpvj83fn5or9op1ou" end2="484229llph85uvtcq1iukfkmd7" id="5vksuftvmelvuhspmjscq6our0" modified-by="lyn" style-id="4h3hg9qmg7tsdfrnctp53d1i1q" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="-119" svg:y="-33"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"><position svg:x="118" svg:y="60"/></control-point></control-points></relationship><relationship end1="1dulst851jpvj83fn5or9op1ou" end2="1qovda1goe0it9sau6n666vbch" id="7hfkh7u43r9me1lkvprdvpkdqe" modified-by="lyn" style-id="4h3hg9qmg7tsdfrnctp53d1i1q" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="1dulst851jpvj83fn5or9op1ou" end2="2kemkaadkcavhlv9t57oa8q42h" id="2qehfaghp6f50qo590uu9vmj8v" modified-by="lyn" style-id="4h3hg9qmg7tsdfrnctp53d1i1q" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="1dulst851jpvj83fn5or9op1ou" end2="68pkdt4tpuiu54irq8240g59sq" id="6a2sucjjr0oqmot4nies6ue7va" modified-by="lyn" style-id="4h3hg9qmg7tsdfrnctp53d1i1q" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7ss7st5c4kctqem2l5njgjq4q9" end2="4muv6is7fkfrg1l1scdbrlqaru" id="23g7dlaj5b4dsis6pt7lcghm30" modified-by="lyn" style-id="6dburt27ou651a2fe7tqeq3v97" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7ss7st5c4kctqem2l5njgjq4q9" end2="6rehopi99hl4ji6pj4rt1724rp" id="469eglppu0odbde7shsfapgfln" modified-by="lyn" style-id="6dburt27ou651a2fe7tqeq3v97" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7ss7st5c4kctqem2l5njgjq4q9" end2="1457kmdgm9itbehl4ujod4959u" id="7smn3kaiimp0410mh6r8vb7qhv" modified-by="lyn" style-id="6dburt27ou651a2fe7tqeq3v97" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7ss7st5c4kctqem2l5njgjq4q9" end2="1jfqbg0kahast9i6q2vuk6e97r" id="5v1et5rt4vk2e8v10vdnsa4n37" modified-by="lyn" style-id="6dburt27ou651a2fe7tqeq3v97" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7ss7st5c4kctqem2l5njgjq4q9" end2="6f85b0uqrp2p1u4avpf6e63fs3" id="1grea85nqu8938or22tbjckcpo" modified-by="lyn" style-id="6dburt27ou651a2fe7tqeq3v97" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="1dulst851jpvj83fn5or9op1ou" end2="55790c7l3b1b60f76mbd2req4v" id="4v2j4ojlcj1sgms91s2ncdo2pu" modified-by="lyn" style-id="4h3hg9qmg7tsdfrnctp53d1i1q" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="1dulst851jpvj83fn5or9op1ou" end2="2fhpp2duvvmin2vk6hpp3e0538" id="4lmu70ccm4qdbjiovf2rmbb3ba" modified-by="lyn" style-id="4h3hg9qmg7tsdfrnctp53d1i1q" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="1dulst851jpvj83fn5or9op1ou" end2="5vuvjtscdj8805ccafrqamstgv" id="3dg52dpri6par4bpo4pco1r1va" modified-by="lyn" style-id="4h3hg9qmg7tsdfrnctp53d1i1q" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="1dulst851jpvj83fn5or9op1ou" end2="7v49h1p4blce3ru8kltqaauekc" id="19e41kdmut9n6j1k0i3q64gr8s" modified-by="lyn" style-id="4h3hg9qmg7tsdfrnctp53d1i1q" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="1dulst851jpvj83fn5or9op1ou" end2="755qmpfv8eundd8e2fi0t4fk9b" id="426j34iagv2941a94bpbfkn21h" modified-by="lyn" style-id="4h3hg9qmg7tsdfrnctp53d1i1q" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7ss7st5c4kctqem2l5njgjq4q9" end2="55790c7l3b1b60f76mbd2req4v" id="20qbogkcrjpetvrsvgf1jtcgum" modified-by="lyn" style-id="6dburt27ou651a2fe7tqeq3v97" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7ss7st5c4kctqem2l5njgjq4q9" end2="2fhpp2duvvmin2vk6hpp3e0538" id="6c4k74ut5a68lpbkumpdiu40qv" modified-by="lyn" style-id="6dburt27ou651a2fe7tqeq3v97" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7ss7st5c4kctqem2l5njgjq4q9" end2="5vuvjtscdj8805ccafrqamstgv" id="03019crmjfjnj23610r403n8gr" modified-by="lyn" style-id="6dburt27ou651a2fe7tqeq3v97" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7ss7st5c4kctqem2l5njgjq4q9" end2="7v49h1p4blce3ru8kltqaauekc" id="2c068aefor6krr14hdrdkvp8rm" modified-by="lyn" style-id="6dburt27ou651a2fe7tqeq3v97" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="7ss7st5c4kctqem2l5njgjq4q9" end2="755qmpfv8eundd8e2fi0t4fk9b" id="7cg171sd58d6g93e9fpkvn5154" modified-by="lyn" style-id="6dburt27ou651a2fe7tqeq3v97" timestamp="1477643105153"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship></relationships></sheet></xmap-content> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/meta.xml new file mode 100644 index 000000000..6b7921845 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/meta.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><meta xmlns="urn:xmind:xmap:xmlns:meta:2.0" version="2.0"><Author><Name>lyn</Name><Email/><Org/></Author><Create><Time>Oct 28, 2016 4:25:05 PM</Time></Create><Creator><Name>XMind</Name><Version>3.7.0.qualifier</Version></Creator></meta> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/styles.xml new file mode 100644 index 000000000..4905ffd62 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Compare and Contrast.xmt/styles.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><xmap-styles xmlns="urn:xmind:xmap:xmlns:style:2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" version="2.0"><automatic-styles><style id="6r9347lqtbvj44jciu3lgq7709" name="" type="summary"><summary-properties line-color="#5C99D4"/></style><style id="7c9dfmeviqqgble3j6b2o71mdm" name="" type="topic"><topic-properties fo:color="#7F7F7F" fo:font-family="Arial" fo:font-size="10pt" svg:fill="none"/></style><style id="6faouim0c0pqbjmj6560toef4u" name="" type="boundary"><boundary-properties fo:color="#FFFFFF" fo:font-family="Verdana" fo:font-size="10pt" fo:font-style="italic" line-color="#82BAE1" line-pattern="dash" line-width="2pt" shape-class="org.xmind.boundaryShape.scallops" svg:fill="#82BAE1" svg:opacity=".5"/></style><style id="0ciaculgums26v5mdgrhddb7qi" name="" type="topic"><topic-properties border-line-color="#0A5CB9" border-line-width="0pt" callout-shape-class="org.xmind.calloutTopicShape.balloon.roundedRect" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-style="italic" line-class="org.xmind.branchConnection.roundedElbow" svg:fill="#6EAADC"/></style><style id="2kgo63o80qccdecck7ba85mcg9" name="" type="topic"><topic-properties border-line-color="#0A5CB9" border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Arial" fo:font-size="24pt" fo:font-weight="bold" fo:text-align="center" fo:text-transform="capitalize" line-class="org.xmind.branchConnection.straight" line-color="#0A5CB9" line-width="1pt" shape-class="org.xmind.topicShape.circle" svg:fill="#BDBDBD"/></style><style id="6ldkmeaiov3v55v0srevnfp2ej" name="" type="topic"><topic-properties border-line-color="#0D46AA" border-line-width="1pt" fo:color="#0A5CB9" fo:font-family="Georgia" fo:font-size="14pt" fo:text-transform="uppercase" line-width="1pt" svg:fill="#FFFFFF"/></style><style id="6goq66ij9m8e7jj3q2fasn2lr4" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#2B5966" fo:font-family="Arial" fo:font-size="12pt" fo:font-style="italic" line-class="org.xmind.branchConnection.none" shape-class="org.xmind.topicShape.ellipse" svg:fill="none"/></style><style id="37ve5lsj0n5f2dfjpqh554156m" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Arial" fo:font-size="10pt" fo:font-style="normal" fo:font-weight="bold" fo:text-align="center" line-class="org.xmind.branchConnection.curve" line-color="#0D46AA" line-width="1pt" shape-class="org.xmind.topicShape.circle" svg:fill="#66BB69"/></style><style id="5r6apr2470ed75fvd3noqu075q" name="" type="relationship"><relationship-properties arrow-begin-class="org.xmind.arrowShape.none" arrow-end-class="org.xmind.arrowShape.triangle" fo:color="#0A5CB9" fo:font-family="Verdana" fo:font-size="11pt" fo:font-style="italic" line-color="#B0BEC5" line-pattern="dash" line-width="2pt" shape-class="org.xmind.relationshipShape.straight"/></style><style id="1mjschvgv52d6gctq90ummm9v3" name="" type="map"><map-properties background="" color-gradient="none" line-tapered="none" multi-line-colors="none" svg:fill="#FFFFFF" svg:opacity="1.0"/></style></automatic-styles><master-styles><style id="19s51hn2f6hmvklgva93tf1bq8" name="Theme 7" type="theme"><theme-properties><default-style style-family="summary" style-id="6r9347lqtbvj44jciu3lgq7709"/><default-style style-family="subTopic" style-id="7c9dfmeviqqgble3j6b2o71mdm"/><default-style style-family="boundary" style-id="6faouim0c0pqbjmj6560toef4u"/><default-style style-family="calloutTopic" style-id="0ciaculgums26v5mdgrhddb7qi"/><default-style style-family="centralTopic" style-id="2kgo63o80qccdecck7ba85mcg9"/><default-style style-family="mainTopic" style-id="6ldkmeaiov3v55v0srevnfp2ej"/><default-style style-family="summaryTopic" style-id="6goq66ij9m8e7jj3q2fasn2lr4"/><default-style style-family="floatingTopic" style-id="37ve5lsj0n5f2dfjpqh554156m"/><default-style style-family="relationship" style-id="5r6apr2470ed75fvd3noqu075q"/><default-style style-family="map" style-id="1mjschvgv52d6gctq90ummm9v3"/></theme-properties></style></master-styles><styles><style id="487jesrr995te8sva0b8u4fhmt" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-size="18pt" fo:font-weight="bold" fo:text-transform="capitalize" shape-class="org.xmind.topicShape.circle" svg:fill="#BDBDBD"/></style><style id="7rnev2tjpvdot84npgi9vavcui" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-size="16pt" fo:font-style="italic" fo:font-weight="bold" line-class="org.xmind.branchConnection.curve" line-color="#0D46AA" line-width="1pt" shape-class="org.xmind.topicShape.circle" svg:fill="#78909C"/></style><style id="07erte1higs6coi9m6qkkpv7vg" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-size="16pt" fo:font-style="italic" fo:font-weight="bold" line-class="org.xmind.branchConnection.curve" line-color="#0D46AA" line-width="1pt" shape-class="org.xmind.topicShape.circle" svg:fill="#8D6E63"/></style><style id="4fmln0pn3h23dgafv910ksd21n" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-size="13pt" fo:text-align="center" shape-class="org.xmind.topicShape.circle" svg:fill="#66BB69"/></style><style id="54457d52g3vdcgk32tabdmu2qi" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-size="13pt" shape-class="org.xmind.topicShape.circle" svg:fill="#66BB69"/></style><style id="27c8he75923khls0h4am5bpp09" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-size="10pt" fo:font-style="normal" line-class="org.xmind.branchConnection.curve" shape-class="org.xmind.topicShape.circle" svg:fill="#90A3AE"/></style><style id="354l14590te690fqhc076375tb" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-size="10pt" fo:font-style="normal" fo:text-align="center" line-class="org.xmind.branchConnection.curve" shape-class="org.xmind.topicShape.circle" svg:fill="#90A3AE"/></style><style id="40ngg121134t3vjvq0na827n49" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-size="12pt" fo:font-style="normal" line-class="org.xmind.branchConnection.curve" shape-class="org.xmind.topicShape.circle" svg:fill="#90A3AE"/></style><style id="74difl9j68tk6hn7ahbs9fs71o" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-size="10pt" fo:font-style="normal" fo:text-align="center" shape-class="org.xmind.topicShape.circle" svg:fill="#A1887F"/></style><style id="4jrpth3jqivftk2jhn5u91vkm1" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-size="10pt" fo:font-style="normal" shape-class="org.xmind.topicShape.circle" svg:fill="#A1887F"/></style><style id="4h3hg9qmg7tsdfrnctp53d1i1q" name="" type="relationship"><relationship-properties line-color="#B0BEC5" shape-class="org.xmind.relationshipShape.straight"/></style><style id="6dburt27ou651a2fe7tqeq3v97" name="" type="relationship"><relationship-properties line-color="#BCAAA3" shape-class="org.xmind.relationshipShape.straight"/></style></styles></xmap-styles> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..008d1e6b5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><manifest xmlns="urn:xmind:xmap:xmlns:manifest:1.0" password-hint=""><file-entry full-path="content.xml" media-type="text/xml"/><file-entry full-path="META-INF/" media-type=""/><file-entry full-path="META-INF/manifest.xml" media-type="text/xml"/><file-entry full-path="meta.xml" media-type="text/xml"/><file-entry full-path="styles.xml" media-type="text/xml"/><file-entry full-path="Thumbnails/" media-type=""/><file-entry full-path="Thumbnails/thumbnail.png" media-type=""/></manifest> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..e1900054f Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/content.xml new file mode 100644 index 000000000..9d2416713 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/content.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><xmap-content xmlns="urn:xmind:xmap:xmlns:content:2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" modified-by="lyn" timestamp="1477481104230" version="2.0"><sheet id="0hd8fah1cm7sscbe6cbupbc440" modified-by="lyn" theme="3rgsi3ko6m2ptrn4e24h2h7j2l" timestamp="1477481104230"><topic id="23krq67pp14m652treu8ishh77" modified-by="lyn" structure-class="org.xmind.ui.logic.right" timestamp="1477481104230"><title>Exam Review PlanCalculus IIGoal: AEssayLecture NoteQuestion BankQ&A SessionTime:Location:Began to Review2016-11-142016-12-1810Me2Ecology and Evolution Began to ReviewGoal: A+EssayLecture NoteQuestion BankQ&A SessionTime:Location:2016-11-052016-11-2020Me-1General Chemistry I Goal: A+EssayLecture NoteQuestion BankQ&A SessionTime:Location:Began to Review2016-12-192016-12-231Me2Gender and DevelopmentGoal: AEssayLecture NoteQuestion BankQ&A SessionTime:Location:Began to Review2016-11-262016-11-30Me2Principles of MacroeconomicsGoal: AEssayLecture NoteQuestion BankQ&A SessionTime:Location:Began to Review2016-12-012016-12-061Me2-117dSheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/meta.xml new file mode 100644 index 000000000..c86610f7d --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/styles.xml new file mode 100644 index 000000000..6dd08688b --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Exam Review Plan.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..008d1e6b5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..462a69912 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/content.xml new file mode 100644 index 000000000..9c6e32a44 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/content.xml @@ -0,0 +1 @@ +startReceive DataVerify Data Valid TransformReport ErrorsLoadStopYN0Example of Workflow<control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="188o8m43vfrgkc14urt9q18j7t" end2="333vgnl1getec9sf1auavh5ltj" id="6p2v79k96im13bed1v45c62sf7" modified-by="lyn" style-id="7irg4pltc0ellv1e0l11e6j0na" timestamp="1477643095314"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="2krstkoect5osbclf5o0bs8j0a" end2="0j4r12f8tkaeal0ohl675vrgkt" id="0o891p8ksqb8m8nhupu734juc7" modified-by="lyn" style-id="7irg4pltc0ellv1e0l11e6j0na" timestamp="1477643095314"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="3t576cos6pk8lj307mldtidpsb" end2="2krstkoect5osbclf5o0bs8j0a" id="2dihnrhgiac5a0cik87jc86v6c" modified-by="lyn" style-id="4cecvudjhju32vv3kaj9t3e93f" timestamp="1477643095314"><title/></relationship><relationship end1="0j4r12f8tkaeal0ohl675vrgkt" end2="5nbnbqi5m4qr9429roo3cek0mo" id="5r6s0a9ereansvk0qoeerdpjlv" modified-by="lyn" style-id="0sge877covmopu4p2v9tc7e4ut" timestamp="1477643095314"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="-1" svg:y="122"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"><position svg:x="187" svg:y="-7"/></control-point></control-points></relationship><relationship end1="333vgnl1getec9sf1auavh5ltj" end2="3t576cos6pk8lj307mldtidpsb" id="1avu2j63ik6qrvatj117amhihc" modified-by="lyn" style-id="59i8op9l00pa8ftvm79pkfodhi" timestamp="1477643095314"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="1gpn167bq3vjc1vm3s4ql3982n" end2="6fsd5oh7ud77dok6rb7gbu8n6m" id="7ochk08vv573mckplpstuh3uo3" modified-by="lyn" style-id="7irg4pltc0ellv1e0l11e6j0na" timestamp="1477643095314"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="333vgnl1getec9sf1auavh5ltj" end2="377cildk17q9rcnp6clfa6dn4v" id="598a4q212n6snt9hds4p98hc2i" modified-by="lyn" style-id="59i8op9l00pa8ftvm79pkfodhi" timestamp="1477643095315"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship><relationship end1="377cildk17q9rcnp6clfa6dn4v" end2="131toe2ne0plg3jp7lhhsi4ucl" id="2j6udjq51n2at44ge9bje596lg" modified-by="lyn" style-id="56e3dht7srhifh9tum5jjln6a5" timestamp="1477643095315"><title/></relationship><relationship end1="6fsd5oh7ud77dok6rb7gbu8n6m" end2="188o8m43vfrgkc14urt9q18j7t" id="5vnrer56fae519lq5mf207tbqu" modified-by="lyn" style-id="7irg4pltc0ellv1e0l11e6j0na" timestamp="1477643095315"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"/><control-point amount="0.3" angle="0.2617993877991494" index="1"/></control-points></relationship></relationships></sheet></xmap-content> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/meta.xml new file mode 100644 index 000000000..cfe9bd85b --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/meta.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><meta xmlns="urn:xmind:xmap:xmlns:meta:2.0" version="2.0"><Author><Name>lyn</Name><Email/><Org/></Author><Create><Time>Oct 28, 2016 4:24:55 PM</Time></Create><Creator><Name>XMind</Name><Version>3.7.0.qualifier</Version></Creator></meta> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/styles.xml new file mode 100644 index 000000000..82c56b28b --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Example of Workflow.xmt/styles.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><xmap-styles xmlns="urn:xmind:xmap:xmlns:style:2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" version="2.0"><automatic-styles><style id="23h18tja9mscl8j2nl03u9ssn8" name="" type="topic"><topic-properties border-line-color="#558ED5" border-line-width="3pt" fo:font-family="Open Sans" line-class="org.xmind.branchConnection.roundedElbow" line-color="#558ED5" line-width="1pt"/></style><style id="083ljpo9sg5rqjqusva9pu5jbc" name="" type="summary"><summary-properties line-color="#C3D69B" line-width="5pt" shape-class="org.xmind.summaryShape.square"/></style><style id="3ukb1vdq8lsk955vb4uh98q481" name="" type="boundary"><boundary-properties fo:color="#FFFFFF" fo:font-family="Georgia" fo:font-size="10pt" fo:font-style="italic" line-color="#77933C" line-pattern="dot" line-width="3pt" shape-class="org.xmind.boundaryShape.roundedRect" svg:fill="#C3D69B" svg:opacity=".2"/></style><style id="408n2kbkju3pkgh5be9bg003ht" name="" type="topic"><topic-properties border-line-color="#F1BD51" border-line-width="2pt" fo:font-family="Open Sans" svg:fill="#FBF09C"/></style><style id="509c4cksmu5ienfvab1u45nell" name="" type="topic"><topic-properties border-line-color="#558ED5" border-line-width="5pt" fo:color="#376092" fo:font-family="Open Sans" line-class="org.xmind.branchConnection.curve" line-color="#558ED5" line-width="1pt" shape-class="org.xmind.topicShape.roundedRect" svg:fill="#DCE6F2"/></style><style id="1qs5d2d1qr060c4tk08funo91q" name="" type="topic"><topic-properties border-line-color="#558ED5" border-line-width="2pt" fo:color="#17375E" fo:font-family="Open Sans" line-class="org.xmind.branchConnection.curve" line-color="#558ED5" line-width="1pt" shape-class="org.xmind.topicShape.roundedRect" svg:fill="#DCE6F2"/></style><style id="676jbvthaa8t58ogu9oeiqg6j3" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Georgia" fo:font-size="10pt" fo:font-style="italic" shape-class="org.xmind.topicShape.roundedRect" svg:fill="#77933C"/></style><style id="3eecpvhmdhptfak2aat0pmlojl" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#FFFFFF" fo:font-family="Open Sans" fo:font-weight="bold" line-color="#558ED5" svg:fill="#558ED5"/></style><style id="70f8u91arm0dt1k2iir6ba0pmp" name="" type="relationship"><relationship-properties arrow-end-class="org.xmind.arrowShape.triangle" fo:color="#595959" fo:font-family="Georgia" fo:font-size="10pt" fo:font-style="italic" fo:font-weight="normal" fo:text-decoration="none" line-color="#77933C" line-pattern="dash" line-width="3pt"/></style><style id="34ahki5otumbpj8p18d88t706f" name="" type="map"><map-properties color-gradient="none" line-tapered="none" multi-line-colors="none" svg:fill="#FFFFFF"/></style></automatic-styles><master-styles><style id="1jveb5bt4omnpdgihr4fn59vh4" name="" type="theme"><theme-properties><default-style style-family="subTopic" style-id="23h18tja9mscl8j2nl03u9ssn8"/><default-style style-family="summary" style-id="083ljpo9sg5rqjqusva9pu5jbc"/><default-style style-family="boundary" style-id="3ukb1vdq8lsk955vb4uh98q481"/><default-style style-family="calloutTopic" style-id="408n2kbkju3pkgh5be9bg003ht"/><default-style style-family="centralTopic" style-id="509c4cksmu5ienfvab1u45nell"/><default-style style-family="mainTopic" style-id="1qs5d2d1qr060c4tk08funo91q"/><default-style style-family="summaryTopic" style-id="676jbvthaa8t58ogu9oeiqg6j3"/><default-style style-family="floatingTopic" style-id="3eecpvhmdhptfak2aat0pmlojl"/><default-style style-family="relationship" style-id="70f8u91arm0dt1k2iir6ba0pmp"/><default-style style-family="map" style-id="34ahki5otumbpj8p18d88t706f"/></theme-properties></style></master-styles><styles><style id="7rnstsjgktdvv8bf7tcr4fiki7" name="" type="topic"><topic-properties border-line-color="#2096F3" fo:color="#757575" fo:font-family="Roboto" fo:font-size="16pt" shape-class="org.xmind.topicShape.circle" svg:fill="none"/></style><style id="136hk2o5k4beiviakah6nigk2h" name="" type="topic"><topic-properties border-line-color="#9E9E9E" border-line-width="4pt" fo:color="#757575" fo:font-family="Roboto" fo:font-weight="normal" shape-class="org.xmind.topicShape.roundedRect" svg:fill="none"/></style><style id="3rc63g5lel0r71l31fjcuvlvs4" name="" type="topic"><topic-properties fo:font-family="Roboto" fo:font-weight="normal" shape-class="org.xmind.topicShape.diamond" svg:fill="#616161"/></style><style id="2stse4h3l7dopm9pnc7t9h3etk" name="" type="topic"><topic-properties border-line-color="#43A047" border-line-width="4pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-weight="normal" shape-class="org.xmind.topicShape.roundedRect" svg:fill="#43A047"/></style><style id="1hlg82e61matgm1tc6vlsiah12" name="" type="topic"><topic-properties border-line-color="#FF0303" border-line-width="4pt" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-weight="normal" shape-class="org.xmind.topicShape.roundedRect" svg:fill="#FF0303"/></style><style id="7pcnpjjgffrrmdma0m32cb1bad" name="" type="topic"><topic-properties border-line-color="#009688" border-line-width="3pt" fo:font-family="Roboto" shape-class="org.xmind.topicShape.circle" svg:fill="#009688"/></style><style id="5u348sbrtsgn7uq48l3m6l0ekl" name="" type="topic"><topic-properties fo:font-family="Roboto" fo:font-size="8pt" shape-class="org.xmind.topicShape.circle" svg:fill="#43A047"/></style><style id="714dukeqv907dklquc5ju6s3ip" name="" type="topic"><topic-properties fo:font-family="Roboto" fo:font-size="8pt" shape-class="org.xmind.topicShape.circle" svg:fill="#FF0303"/></style><style id="7irg4pltc0ellv1e0l11e6j0na" name="" type="relationship"><relationship-properties line-color="#9E9E9E" line-pattern="solid" shape-class="org.xmind.relationshipShape.straight"/></style><style id="4cecvudjhju32vv3kaj9t3e93f" name="" type="relationship"><relationship-properties line-color="#43A047" line-pattern="solid" shape-class="org.xmind.relationshipShape.straight"/></style><style id="0sge877covmopu4p2v9tc7e4ut" name="" type="relationship"><relationship-properties line-color="#9E9E9E" line-pattern="solid" shape-class="org.xmind.relationshipShape.zigzag"/></style><style id="59i8op9l00pa8ftvm79pkfodhi" name="" type="relationship"><relationship-properties arrow-end-class="org.xmind.arrowShape.none" line-color="#9E9E9E" line-pattern="solid" shape-class="org.xmind.relationshipShape.straight"/></style><style id="56e3dht7srhifh9tum5jjln6a5" name="" type="relationship"><relationship-properties line-color="#FF0303" line-pattern="solid" shape-class="org.xmind.relationshipShape.straight"/></style></styles></xmap-styles> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..008d1e6b5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><manifest xmlns="urn:xmind:xmap:xmlns:manifest:1.0" password-hint=""><file-entry full-path="content.xml" media-type="text/xml"/><file-entry full-path="META-INF/" media-type=""/><file-entry full-path="META-INF/manifest.xml" media-type="text/xml"/><file-entry full-path="meta.xml" media-type="text/xml"/><file-entry full-path="styles.xml" media-type="text/xml"/><file-entry full-path="Thumbnails/" media-type=""/><file-entry full-path="Thumbnails/thumbnail.png" media-type=""/></manifest> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..9d9e6024f Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/content.xml new file mode 100644 index 000000000..728fa1ef7 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/content.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><xmap-content xmlns="urn:xmind:xmap:xmlns:content:2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" modified-by="lyn" timestamp="1477481091196" version="2.0"><sheet id="5ruo0gilloe4t8aig0tcoekuma" modified-by="lyn" style-id="3dssiul1id5ev3kov2u9gbja2i" theme="0576uodv1c92530tsr5sjpov90" timestamp="1477481091196"><topic id="4pr1bj1gqpooqjg94nodcj2qte" modified-by="lyn" structure-class="org.xmind.ui.tree.right" style-id="1htq6qjcrmkoe0ecsee8u32qjg" timestamp="1477481091196"><title svg:width="500">Writing a Paper: OutliningIntroductionCurrent Problem: Educational attainment rates are decreasing in the United States while healthcare costs are increasing.Population/Area of Focus: Unskilled or low-skilled adult workersKey Terms: healthy, well-educated.The following outline is for a 5-7 page paper discussing the link between educational attainment and health. Review the other sections of this page for more detailed information about each component of this outline!The following outline is for a 5-7 page paper discussing the link between educational attainment and health. Review the other sections of this page for more detailed information about each component of this outline!BackgroundHistorical Employment Overview: Unskilled laborers in the past were frequently unionized and adequately compensated for their work (cite sources).Historical Healthcare Overview: Unskilled laborers in the past were often provided adequate healthcare and benefits (cite sources).Current Link between Education and Employment Type: Increasingly, uneducated workers work in unskilled or low-skilled jobs (cite sources).Gaps in the Research: Little information exists exploring the health implications of the current conditions in low-skilled jobs.Major Point 1: Conditions of employment affect workers' physical health. Unskilled work environments are correlated highly with worker injury (cite sources).Unskilled work environments rarely provide healthcare or adequate injury recovery time (cite sources)..Major Point 2: Conditions of employment affect workers' mental healthEmployment in a low-skilled position is highly correlated with dangerous levels of stress (cite sources).Stress is highly correlated with mental health issues (cite sources)..Major Point 3: Physical health and mental health correlate directly with one another.Mental health problems and physical health problems are highly correlated (cite sources).Stress manifests itself in physical form (cite sources)..Major Point 4: People with more financial worries have more stress and worse physical health.Many high-school dropouts face financial problems (cite sources).Financial problems are often correlated with unhealthy lifestyle choices such unhealthy food choices, overconsumption/abuse of alcohol, chain smoking, abusive relationships, etc. (cite sources)..ConclusionRestatement of ThesisStudents who drop out of high school are at a higher risk for both mental and physical health problems throughout their lives.Next StepsSociety needs educational advocates; educators need to be aware of this situation and strive for student retention in order to promote healthy lifestyles and warn students of the risks associated with dropping out of school..Resource fromWALDEN UNIVERSITY-1.Outlining your first draft by listing each paragraph's topic sentence can be an easy way to ensure that each of your paragraphs is serving a specific purpose in your paper. You may find opportunities to combine or eliminate potential paragraphs when outlining—first drafts often contain repetitive ideas or sections that stall, rather than advance, the paper's central argument. + +Additionally, if you are having trouble revising a paper, making an outline of each paragraph and its topic sentence after you have written your paper can be an effective way of identifying a paper's strengths and weaknesses.Outlining your first draft by listing each paragraph's topic sentence can be an easy way to ensure that each of your paragraphs is serving a specific purpose in your paper. You may find opportunities to combine or eliminate potential paragraphs when outlining—first drafts often contain repetitive ideas or sections that stall, rather than advance, the paper's central argument.Additionally, if you are having trouble revising a paper, making an outline of each paragraph and its topic sentence after you have written your paper can be an effective way of identifying a paper's strengths and weaknesses.Sheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/meta.xml new file mode 100644 index 000000000..4e38ad417 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/styles.xml new file mode 100644 index 000000000..c27532e84 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Paper Outline.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..63e1e45c0 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..0b14aa801 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/attachments/35ufq58mbh3sjntbad2gbpsih5.png b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/attachments/35ufq58mbh3sjntbad2gbpsih5.png new file mode 100644 index 000000000..c151437da Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/attachments/35ufq58mbh3sjntbad2gbpsih5.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/content.xml new file mode 100644 index 000000000..cbe138691 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/content.xml @@ -0,0 +1,7 @@ +English III SyllabusCourse DescriptionEnglish III is worth one credit and is a yearlong course. English III exposes students to some of the significant works and ideas of American writers...English III is worth one credit and is a yearlong course. English III exposes students to some of the significant works and ideas of American writers...Instructional GoalsTo develop students' competence as writers, +readers, speakers, listeners, and viewers of many texts.To read and analyse a variety of American +literature, from classis to contemporary.To prepare students for higher-level reading +and writing skills and heighten their overall +communication skills so they may become + successful in life.. Course MethodsClass, small groups, and partner discussions.Group and individual projects.In-class and homework practice activities.Peer writing workshops..Instructional PhilosophyIn order to be successful in this course, students are expected to be active participants...In order to be successful in this course, students are expected to be active participants...ExpectationsBe respectfulTreat everyone with proper consideration, regardless of whether he/she is in the classroom at the time...Treat everyone with proper consideration, regardless of whether he/she is in the classroom at the time...Be responsibleArrive at class on time and with all necessary materials... +Arrive at class on time and with all necessary materials...Be appropriateConduct yourself as a mature, well-mannered young adult...Conduct yourself as a mature, well-mannered young adult...Be involvedParticipate to the fullest extent that you can...Participate to the fullest extent that you can...Be honestDo your own work. Do not cheat, and do not plagiarize...Do your own work. Do not cheat, and do not plagiarize....Classroom ManagementIn order for each student to feel safe and comfortable in my classroom, a positive and respectful attitude is expected, which includes respecting others' thoughts, work, feelings, and individuality...In order for each student to feel safe and comfortable in my classroom, a positive and respectful attitude is expected, which includes respecting others' thoughts, work, feelings, and individuality...Grading Policy.Per the student handbook, all work may be retrieved from the course website as early as the evening of the missed school day...Per the student handbook, all work may be retrieved from the course website as early as the evening of the missed school day...Resources & MaterialsRequired..........Suggested..........4Sheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/meta.xml new file mode 100644 index 000000000..24484c739 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/styles.xml new file mode 100644 index 000000000..4720f2b39 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/Syllabus.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..008d1e6b5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..93e2bfd1f Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/content.xml new file mode 100644 index 000000000..e1bc467dd --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/content.xml @@ -0,0 +1 @@ +20162015NOVXMind 7 (v3.6.0) releasedJUNXMind 6 (v3.5.3) releasedAPRXMind 6 (v3.5.2) released2014NOVXMind 6 (v3.5.1) releasedOCTXMind 6 (v3.5.0) releasedJULXMind is rated as the best brainstorming and mind-mapping tech tools on LifehackJANXMind 2013 SE (v3.4.1) released2013NOVNew brandingXMind 2013 (v3.4.0) releasedSEPWe become 2013 Red Herring Asia Top 100 Winner. It's a huge honer for our work these yearsAPRLiferhacker.com highlights XMind as the most popular mind mapping tool2012DECXMind 2012 SE (v3.3.1) released. XMind Share becomes XMind LibraryAUGFree private sharing service released. Now, the entire XMind Share online service is free.New packages for team business are available.We start new life-time license of XMind Plus 2012, XMind Pro 2012.XMind 2012 (v3.3) released. The biggest release of past years.2010NOVXMind v3.2.1 and XMind Pro v3.2.1 releasedOCTXMind was picked as one of PCWorld Best 100 of 2010, and ranked #50 among all hardware, software, services, sites, and apps, and also the #6 among all best productivity softwareSEPWe offer the special group subscription code for business.XMind v3.2 and XMind Pro v3.2 released2009DECXMind v3.1.1 and XMind Pro v3.1.1 releasedOCTXMind v3.1.0 and XMind Pro v3.1.0 releasedJULXMind wins The Best Project for Academia at Sourceforge.net Community Choice AwardsAPRXMind v3.0.3 and XMind Pro v3.0.3 releasedMARXMind v3.0.2 and XMind Pro v3.0.2 released2008DECXMind v3.0.1 and XMind Pro v3.0.1 releasedNOVXMind 3 become an open source project.XMind Pro 3 released, available for a subscription feeMARXMind 2008 v2.3 released.XMind wins the "Best Commercial RCP Application" award at EclipseCon 2008JANXMind 2008 v2.2 released2007NOVXMind 2008 v2.1 released.XMind garners award as one of "The 100 Best Products of 2007" from PC World ChinaXMind gets ready for Leopard.SEPXMind 2008 is released, with Chinese, English, and Germany language editionsAPRXMind 2007 released. It's our first productJANXMind released the first beta2006 GETTING STARTXMIND TEN YEARS-1XMind 10 Years \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/meta.xml new file mode 100644 index 000000000..ea61bc7cc --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/styles.xml new file mode 100644 index 000000000..715029cb7 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/education/XMind 10 Years.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..f68ea4d5d --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..aaec49c7d Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/03o9cj9od7cqinmkkj62016257.png b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/03o9cj9od7cqinmkkj62016257.png new file mode 100644 index 000000000..facf5b8cf Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/03o9cj9od7cqinmkkj62016257.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/24e6s3j2s2qs24rcisk8nkl3km.png b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/24e6s3j2s2qs24rcisk8nkl3km.png new file mode 100644 index 000000000..bee3b8836 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/24e6s3j2s2qs24rcisk8nkl3km.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/32479v10cob410hsc1imgnfhpp.png b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/32479v10cob410hsc1imgnfhpp.png new file mode 100644 index 000000000..761662f37 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/32479v10cob410hsc1imgnfhpp.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/4j0tpssp1b457tb0839a344dqp.png b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/4j0tpssp1b457tb0839a344dqp.png new file mode 100644 index 000000000..de6cecd54 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/4j0tpssp1b457tb0839a344dqp.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/77onbe7b8lb1ad8php1n38aj90.png b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/77onbe7b8lb1ad8php1n38aj90.png new file mode 100644 index 000000000..b33417bb5 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/attachments/77onbe7b8lb1ad8php1n38aj90.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/content.xml new file mode 100644 index 000000000..822532c1a --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/content.xml @@ -0,0 +1 @@ +Diet PlanBreakfastScrambled Egg WhitesStrawberries Crust-less QuicheFried Egg & SteakFaker's Egg BenedictAvocado over Rice Scrambled Egg Whites & GrapefruitLunchTuna Salad on Sourdough ToastSpinach Salad with StrawberriesAngelo's Chicken Salad om SpinachMelissa's Chef SaladMeatbal SubLeft-over FajitasSnackAlmonds & Dried CranberriesCelery SticksYogurt & BerriesTrail MixString Chinese & GF CrackersApple SticksDinnerTurkey Burgers & Spinach SaladCoconut Chicken with Bok Choy SaladChicken Vegetable Stir FrySteak Fajitas with Black Bean SaladItalian Herb Salmon with BroccoliniCajun Shrimp with RiceKaleDessertCocoa-Banana SmoothieDark ChocolateFrozen Chocolate-Covered BananaStrawberries Fresh Whipped CreamRice Pudding with CinnamonDark ChocolateBlueberries-1Sheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/meta.xml new file mode 100644 index 000000000..e971e3ac1 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/styles.xml new file mode 100644 index 000000000..317369780 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Diet Plan.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..cff157da2 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..711c6696c Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/attachments/71r77d0lamrppvupov6u0n656c.png b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/attachments/71r77d0lamrppvupov6u0n656c.png new file mode 100644 index 000000000..63690b2f9 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/attachments/71r77d0lamrppvupov6u0n656c.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/content.xml new file mode 100644 index 000000000..18ff8e139 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/content.xml @@ -0,0 +1 @@ +Let's Party!EntertainmentSingingDancingGames.Party InformationThemeCelebration of Molly's BirthdayLocationCat CafeDate2016/10/01Time6:15 PMGuestsFamilyJohnHarryPeter.FriendsSandyAnnaLindy.FoodDrinkOrange juiceColaBeers. SnacksChipsCandies. DessertCupcakeBrownieMacaron.FruitApplesGrapesOranges.DecorationBalloonCandlesFloral ArrangementWreathsCeiling DecorationsDecoration.0Sheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/extensions/org.xmind.ui.presentation.stories.xml b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/extensions/org.xmind.ui.presentation.stories.xml new file mode 100644 index 000000000..c3cf5b562 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/extensions/org.xmind.ui.presentation.stories.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/meta.xml new file mode 100644 index 000000000..cec996742 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/styles.xml new file mode 100644 index 000000000..3434c9530 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Party Preparation.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/META-INF/manifest.xml new file mode 100644 index 000000000..e34fc8e21 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..1272d7fac Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/attachments/7qbck2jeve4eg7cll1foia07rs.png b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/attachments/7qbck2jeve4eg7cll1foia07rs.png new file mode 100644 index 000000000..bd7cd2b32 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/attachments/7qbck2jeve4eg7cll1foia07rs.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/content.xml b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/content.xml new file mode 100644 index 000000000..a9effdfbb --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/content.xml @@ -0,0 +1 @@ + John LeePersonal Information AddressHong KongTel12345678Emailjohn@email.netWork ExperienceJan 2015 ~ Dec 2015PMABC Ltd.Hong KongJob DescriptionCollect design requirementsWrite design book.Jan 2016 ~ Dec 2016Senior PMABC Ltd.HongKongJob DescriptionOrganizational needs review meetingMarket Research & Data Analysis.OtherSummaryAwardsThe fifth campus design competition - Champion.Education2009 ~ 2013UndergraduateHong Kong University2013 ~ 2016MasterHong Kong UniversityAdditional SkillsComputer ProgrammingPhotoshop / Coraldraw.</boundary></boundaries><extensions><extension provider="org.xmind.ui.map.unbalanced"><content><right-number>3</right-number></content></extension></extensions></topic><title>Sheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/meta.xml new file mode 100644 index 000000000..b546c0c8b --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/styles.xml new file mode 100644 index 000000000..4033e3234 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Resume (CV).xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..2330893da --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..21bb44ecb Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/attachments/54q8sonlhji0nf1fs8365om1t2.png b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/attachments/54q8sonlhji0nf1fs8365om1t2.png new file mode 100644 index 000000000..69b82e5be Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/attachments/54q8sonlhji0nf1fs8365om1t2.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/content.xml new file mode 100644 index 000000000..46922a4e1 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/content.xml @@ -0,0 +1 @@ +Shopping ListFoodBakeryToastCroissant.BeverageColaBeers.DairyYogurtCheese.MeatFishChicken.Personal CareHair careShampooHair conditionerSkin care productsBody lotion.HouseholdPanOven.BabyInfant dietMilk powderDaily suppliesDiaper care.PetsCat foodPet house1d.OthersMagazineglasses1d.2Sheet 1 \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/extensions/org.xmind.ui.presentation.stories.xml b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/extensions/org.xmind.ui.presentation.stories.xml new file mode 100644 index 000000000..5bdcaafad --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/extensions/org.xmind.ui.presentation.stories.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/meta.xml new file mode 100644 index 000000000..08a3442b5 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/styles.xml new file mode 100644 index 000000000..a0c69f6d9 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Shopping List.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..de2eb7ee8 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..b73b65698 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/0ijh81ov3pbcd814tf2t9o7u6u.png b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/0ijh81ov3pbcd814tf2t9o7u6u.png new file mode 100644 index 000000000..46615caeb Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/0ijh81ov3pbcd814tf2t9o7u6u.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/1udvg9gbghq5c1lskffsaechs7.png b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/1udvg9gbghq5c1lskffsaechs7.png new file mode 100644 index 000000000..2c29495eb Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/1udvg9gbghq5c1lskffsaechs7.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/1usdl8vt041arbff2e6i3d785h.png b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/1usdl8vt041arbff2e6i3d785h.png new file mode 100644 index 000000000..46615caeb Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/1usdl8vt041arbff2e6i3d785h.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/2ljnq3pohq7t8jludvucjetaom.png b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/2ljnq3pohq7t8jludvucjetaom.png new file mode 100644 index 000000000..44e87d35f Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/2ljnq3pohq7t8jludvucjetaom.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/5i4u72j50jeu46gfktkdub8rtp.png b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/5i4u72j50jeu46gfktkdub8rtp.png new file mode 100644 index 000000000..46615caeb Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/5i4u72j50jeu46gfktkdub8rtp.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/6qnukvd1u8jt7o3r73gqksa63s.png b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/6qnukvd1u8jt7o3r73gqksa63s.png new file mode 100644 index 000000000..dca59132a Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/attachments/6qnukvd1u8jt7o3r73gqksa63s.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/content.xml new file mode 100644 index 000000000..9f35cd48f --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/content.xml @@ -0,0 +1 @@ +Travel PlanDAY 1VehiclePlane9:30 AM - 11:30 AMNo.AB123456HotelNameHotel MuseLocation55/555 Langsuan Road, Lumpini, PathumwanTel/ Email+666 2-630-4000Scenic spotsErawan ShrineChao Phraya RiverCentral World.BudgetMeal$ 20Ticket$ 0Transport Fees$ 20Others$ 200DAY 3VehiclePlane09:00 AM- 10:00 AMBangkok - Chiangmai No. AB123456HotelNameDhara DheviLocation51/4Chiang Mai - Sankampaeng RoadTel/ Email66053-888888Scenic spotsDoi SythepWat Phra SinghTha Pae Gate.BudgetMeal$ 100Ticket$ 20Transport Fees$ 20Others$ 100DAY 4Vehicle08:30 AM - unknowHotel - Chiang RaiBusHotelSame as last nightScenic spotsWhite templeBlack temple.BudgetMeal$ 15Ticket$ 0Transport Fees$ 20Others$ 50DAY 5VehiclePlane10:00 AM - 12:00 AMNo.123456Chiang Rai - Hong KongBudgetMeal$ 15Ticket$ 0Transport Fees$ 200Others$ 100DAY 2Vehicle08:30 AM - unknowHotel- Grand PalaceTaxiHotelSame as last nightScenic spotsWat poWat ArunThe bar of hotel's top.BudgetMeal$ 20Ticket$ 100Transport Fees$ 30Others$ 1000Travel Plan<control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="184" svg:y="313"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"><position svg:x="-266" svg:y="-330"/></control-point></control-points></relationship><relationship end1="3v72roq6f7tulgjmipcbg3fnou" end2="27v64nqaeul1qi9ni1d9sclst7" id="4tjadl4dqukhg8oljlcfdp2nef" modified-by="lyn" style-id="2ofo7q2pf0beh8me5ld9im9idv" timestamp="1477913556852"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="25" svg:y="304"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"><position svg:x="52" svg:y="-295"/></control-point></control-points></relationship><relationship end1="27v64nqaeul1qi9ni1d9sclst7" end2="626g9jndvuupb9ie8dnj52lolq" id="011dsnpt2oeemmj7tnrvnjg66p" modified-by="lyn" style-id="2ofo7q2pf0beh8me5ld9im9idv" timestamp="1477913556852"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="-259" svg:y="-261"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"><position svg:x="249" svg:y="250"/></control-point></control-points></relationship><relationship end1="626g9jndvuupb9ie8dnj52lolq" end2="0p1vv21ssbitn0bb8h92inoki3" id="25srm0ib9f80eo4s0llt2lkihq" modified-by="lyn" style-id="2ofo7q2pf0beh8me5ld9im9idv" timestamp="1477913556852"><title/><control-points><control-point amount="0.3" angle="0.2617993877991494" index="0"><position svg:x="75" svg:y="-154"/></control-point><control-point amount="0.3" angle="0.2617993877991494" index="1"><position svg:x="-141" svg:y="192"/></control-point></control-points></relationship></relationships><sheet-settings><info-items><info-item mode="icon" type="org.xmind.ui.infoItem.label"/></info-items></sheet-settings></sheet></xmap-content> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/meta.xml new file mode 100644 index 000000000..6342b48af --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/meta.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><meta xmlns="urn:xmind:xmap:xmlns:meta:2.0" version="2.0"><Author><Name>lyn</Name><Email/><Org/></Author><Create><Time>Oct 31, 2016 7:32:36 PM</Time></Create><Creator><Name>XMind</Name><Version>3.7.0.qualifier</Version></Creator></meta> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/styles.xml new file mode 100644 index 000000000..f6b1037d6 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Travel Plan.xmt/styles.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><xmap-styles xmlns="urn:xmind:xmap:xmlns:style:2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" version="2.0"><styles><style id="5cb0tiqtu5s9cic5fudakug2j0" name="" type="map"><map-properties color-gradient="none" line-tapered="none" multi-line-colors="none" svg:fill="#F2F2F2"/></style><style id="462qhdodpg4nfu5o8j3g2hlpeg" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#00695C" fo:font-family="Microsoft YaHei UI" fo:font-size="36pt" fo:font-weight="bold" line-width="5pt" shape-class="org.xmind.topicShape.rect" svg:fill="none"/></style><style id="5dcaentlbvubl34u7ult7dr6s1" name="" type="topic"><topic-properties border-line-width="1pt" fo:color="#FFFFFF" fo:font-family="Microsoft YaHei UI" fo:font-size="22pt" fo:font-style="italic" fo:font-weight="bold" line-class="org.xmind.branchConnection.curve" line-color="#53AF80" line-width="2pt" shape-class="org.xmind.topicShape.circle" svg:fill="#53AE7F"/></style><style id="4cg4armjo1t0f68nv57q6ftleb" name="" type="topic"><topic-properties border-line-color="#53AE7F" fo:color="#53AF80" fo:font-family="Microsoft YaHei UI" fo:font-size="13pt" fo:font-style="italic" fo:font-weight="bold" shape-class="org.xmind.topicShape.circle" svg:fill="#FFFFFF"/></style><style id="2v16lesc2gct83hmep6t3prlth" name="" type="topic"><topic-properties border-line-width="2pt" fo:color="#00695C" fo:font-family="Microsoft YaHei UI" fo:font-size="10pt" fo:font-weight="normal" shape-class="org.xmind.topicShape.underline" svg:fill="none"/></style><style id="1dfduka7figfm9i25h4ghqkrgu" name="" type="topic"><topic-properties border-line-color="#53AE7F" fo:color="#53AF80" fo:font-family="Microsoft YaHei UI" fo:font-size="13pt" fo:font-style="italic" fo:font-weight="bold" line-color="#53AF80" shape-class="org.xmind.topicShape.circle" svg:fill="#FFFFFF"/></style><style id="2ofo7q2pf0beh8me5ld9im9idv" name="" type="relationship"><relationship-properties line-color="#BFBFBF" line-pattern="dash-dot" line-width="5pt"/></style></styles><automatic-styles><style id="2e66fot3dkl40330mpo3g3v631" name="" type="summary"><summary-properties line-color="#0095a4"/></style><style id="4ohgf3gvbldafrr97ok7nh8std" name="" type="topic"><topic-properties fo:color="#1f5279" fo:font-family="Arial" fo:font-size="10pt" svg:fill="none"/></style><style id="779fj1kh0s6g57osueg0sbiinn" name="" type="boundary"><boundary-properties fo:color="#FFFFFF" fo:font-family="Verdana" fo:font-size="10pt" fo:font-style="italic" line-color="#0095a4" line-pattern="dash" line-width="2pt" shape-class="org.xmind.boundaryShape.scallops" svg:fill="#0095a4" svg:opacity=".5"/></style><style id="2qrod8cln8fiuioio3g512jgsc" name="" type="topic"><topic-properties border-line-color="#1f5279" border-line-width="0pt" callout-shape-class="org.xmind.calloutTopicShape.balloon.roundedRect" fo:color="#FFFFFF" fo:font-family="Roboto" fo:font-style="italic" line-class="org.xmind.branchConnection.roundedElbow" svg:fill="#ed7f00"/></style><style id="6e8eajh197t97gg8be5e6gitb0" name="" type="topic"><topic-properties border-line-color="#1f5279" border-line-width="2pt" fo:color="#1f5279" fo:font-family="Georgia" fo:font-size="20pt" fo:font-weight="normal" fo:text-align="center" fo:text-transform="uppercase" line-class="org.xmind.branchConnection.roundedElbow" line-color="#1f5279" line-width="1pt" shape-class="org.xmind.topicShape.roundedRect" svg:fill="#FFFFFF"/></style><style id="18qtrhli6js60jlhs29fs06k8m" name="" type="topic"><topic-properties border-line-color="#1f5279" border-line-width="2pt" fo:color="#1f5279" fo:font-family="Georgia" fo:font-size="14pt" fo:text-transform="uppercase" line-width="1pt" svg:fill="#FFFFFF"/></style><style id="7it6a9ife9e64or17r7phhe49v" name="" type="topic"><topic-properties border-line-width="0pt" fo:color="#0095a4" fo:font-family="Arial" fo:font-size="12pt" fo:font-style="italic" line-class="org.xmind.branchConnection.none" shape-class="org.xmind.topicShape.ellipse" svg:fill="none"/></style><style id="190llmis6ock76dsqntqabqv23" name="" type="relationship"><relationship-properties arrow-begin-class="org.xmind.arrowShape.none" arrow-end-class="org.xmind.arrowShape.triangle" fo:color="#1f5279" fo:font-family="Verdana" fo:font-size="11pt" fo:font-style="italic" line-color="#ed7f00" line-pattern="dash" line-width="2pt" shape-class="org.xmind.relationshipShape.curved"/></style><style id="2ksdhovn9o6rcf8mvm3tf0mbud" name="" type="topic"><topic-properties border-line-width="1pt" fo:color="#0095a4" fo:font-family="Georgia" fo:font-style="italic" fo:font-weight="normal" line-class="org.xmind.branchConnection.elbow" line-color="#0095a4" line-width="1pt" shape-class="org.xmind.topicShape.rect"/></style><style id="6oet0djcov1jhadv9b2bvitn43" name="" type="map"><map-properties background="" color-gradient="none" line-tapered="none" multi-line-colors="none" svg:fill="#f3ffe1" svg:opacity="1.0"/></style></automatic-styles><master-styles><style id="4epp3evo4us7om18h1h1fdddmr" name="Business VI" type="theme"><theme-properties><default-style style-family="summary" style-id="2e66fot3dkl40330mpo3g3v631"/><default-style style-family="subTopic" style-id="4ohgf3gvbldafrr97ok7nh8std"/><default-style style-family="boundary" style-id="779fj1kh0s6g57osueg0sbiinn"/><default-style style-family="calloutTopic" style-id="2qrod8cln8fiuioio3g512jgsc"/><default-style style-family="centralTopic" style-id="6e8eajh197t97gg8be5e6gitb0"/><default-style style-family="mainTopic" style-id="18qtrhli6js60jlhs29fs06k8m"/><default-style style-family="summaryTopic" style-id="7it6a9ife9e64or17r7phhe49v"/><default-style style-family="relationship" style-id="190llmis6ock76dsqntqabqv23"/><default-style style-family="floatingTopic" style-id="2ksdhovn9o6rcf8mvm3tf0mbud"/><default-style style-family="map" style-id="6oet0djcov1jhadv9b2bvitn43"/></theme-properties></style></master-styles></xmap-styles> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/META-INF/manifest.xml b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/META-INF/manifest.xml new file mode 100644 index 000000000..740c07192 --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/META-INF/manifest.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><manifest xmlns="urn:xmind:xmap:xmlns:manifest:1.0" password-hint=""><file-entry full-path="attachments/" media-type=""/><file-entry full-path="attachments/1hgbv6vb24hepddnakq48hl257.png" media-type="image/png"/><file-entry full-path="content.xml" media-type="text/xml"/><file-entry full-path="META-INF/" media-type=""/><file-entry full-path="META-INF/manifest.xml" media-type="text/xml"/><file-entry full-path="meta.xml" media-type="text/xml"/><file-entry full-path="styles.xml" media-type="text/xml"/><file-entry full-path="Thumbnails/" media-type=""/><file-entry full-path="Thumbnails/thumbnail.png" media-type=""/></manifest> \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/Thumbnails/thumbnail.png b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/Thumbnails/thumbnail.png new file mode 100644 index 000000000..f35c658f9 Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/Thumbnails/thumbnail.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/attachments/1hgbv6vb24hepddnakq48hl257.png b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/attachments/1hgbv6vb24hepddnakq48hl257.png new file mode 100644 index 000000000..3f10ea80f Binary files /dev/null and b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/attachments/1hgbv6vb24hepddnakq48hl257.png differ diff --git a/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/content.xml b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/content.xml new file mode 100644 index 000000000..d3a6ace7b --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/content.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><xmap-content xmlns="urn:xmind:xmap:xmlns:content:2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" modified-by="lyn" timestamp="1477481275413" version="2.0"><sheet id="2la50aecfa9het10rdgt60ttft" modified-by="lyn" theme="0vscso3i5fpsv1olmgal8fbl02" timestamp="1477481275412"><topic id="4ss080c8fgv8mlgutkrmo6g51a" modified-by="lyn" structure-class="org.xmind.ui.logic.right" timestamp="1477481275412"><title>Weekly PlanMondayWorking ItemsMeetingReply Emails.SwimmingSpanish ClassTuesdayWorking Items.ReadingWednesdayWorking ItemsWrite A ReportPresentation.BoxingDateThursdayWorking ItemsMeetingReply Emails.DateReadingFridayWorking ItemsCommunicate with supervisorReply Emails.Jogging DateSaturdayVolunteerFamily ReunionSundayYogaReadingWatch a Movie-1Weekly Plan \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/meta.xml b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/meta.xml new file mode 100644 index 000000000..90987c4fa --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/meta.xml @@ -0,0 +1 @@ +lynXMind3.7.0.qualifier \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/styles.xml b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/styles.xml new file mode 100644 index 000000000..aa22586bb --- /dev/null +++ b/bundles/org.xmind.ui.resources/templates/personal/Weekly Plan.xmt/styles.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/bundles/org.xmind.ui.resources/templates/templates.properties b/bundles/org.xmind.ui.resources/templates/templates.properties index f4d6b3eae..1999d2fe8 100644 --- a/bundles/org.xmind.ui.resources/templates/templates.properties +++ b/bundles/org.xmind.ui.resources/templates/templates.properties @@ -1,20 +1,3 @@ -template.causeAndEffect.name=Cause & Effect -template.makeADecision.name=Make a Decision -template.meetingManagement.name=Meeting Management -template.orgChart.name=Org Chart -template.projectPlan.name=Project Plan -template.projectStatusReport.name=Project Status Report -template.projectsDashboard.name=Projects Dashboard -template.shortMeeting.name=Short Meeting -template.swotAnalysis.name=SWOT Analysis -template.timeline.name=Timeline -template.weeklyPlan.name=Weekly Plan -template.toDoList.name=To Do List -template.flowChart.name= Flow Chart -template.travelPlan.name=Travel Plan -template.weightLossProgram.name=Weight-loss Program -template.personalManagement.name=Personal Management -template.negotiationOfSale.name=Negotiation of Sale -template.preparationForAConversation.name=Preparation for a Conversation -template.marketing.name=Marketing -template.orgEmployees.name=Org Employees +category.business.name=Business +category.education.name=Education +category.personal.name=Personal diff --git a/bundles/org.xmind.ui.resources/templates/templates.xml b/bundles/org.xmind.ui.resources/templates/templates.xml index 271947b76..3962af5e1 100644 --- a/bundles/org.xmind.ui.resources/templates/templates.xml +++ b/bundles/org.xmind.ui.resources/templates/templates.xml @@ -1,23 +1,37 @@ -