Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Pingel2011-12-05 16:26:52 +0000
committerSteffen Pingel2011-12-05 16:26:52 +0000
commit8684a2d007c949b05bea03dd72bf000b1a26651a (patch)
tree3cbaea659f6a3450c2c8459a4806c2245b6ce961 /org.eclipse.mylyn.commons.notifications.ui
parenteb9ab5220521f233cc209ffedaeaf30db9da4902 (diff)
downloadorg.eclipse.mylyn.commons-8684a2d007c949b05bea03dd72bf000b1a26651a.tar.gz
org.eclipse.mylyn.commons-8684a2d007c949b05bea03dd72bf000b1a26651a.tar.xz
org.eclipse.mylyn.commons-8684a2d007c949b05bea03dd72bf000b1a26651a.zip
NEW - bug 361048: [api] move service message implementation to
notifications component https://bugs.eclipse.org/bugs/show_bug.cgi?id=361048 Change-Id: Ib98a6a431b23ed9c92fc3029fc9da308dd4c9c97
Diffstat (limited to 'org.eclipse.mylyn.commons.notifications.ui')
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/.classpath11
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/.cvsignore2
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/.project34
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.core.runtime.prefs2
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.jdt.core.prefs354
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.jdt.ui.prefs63
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.ltk.core.refactoring.prefs3
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.mylyn.tasks.ui.prefs4
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.pde.prefs18
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/META-INF/MANIFEST.MF24
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/about.html27
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/build.properties17
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/plugin.properties13
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/plugin.xml47
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/pom.xml29
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/schema/notifications.exsd319
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/AbstractUiNotification.java37
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/NotificationControl.java89
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/NotificationsUi.java30
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/Messages.java33
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationAction.java51
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationCategory.java45
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationElement.java80
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationEvent.java127
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationHandler.java40
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationModel.java172
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationService.java91
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationSinkDescriptor.java58
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsExtensionReader.java143
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPlugin.java131
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPreferencesInitializer.java32
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPreferencesPage.java406
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/messages.properties4
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/Messages.java27
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/NotificationPopup.java183
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/PopupNotificationSink.java163
-rw-r--r--org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/messages.properties1
37 files changed, 2910 insertions, 0 deletions
diff --git a/org.eclipse.mylyn.commons.notifications.ui/.classpath b/org.eclipse.mylyn.commons.notifications.ui/.classpath
new file mode 100644
index 00000000..fcedc478
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/.classpath
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+ <accessrules>
+ <accessrule kind="accessible" pattern="org/eclipse/core/internal/runtime/*"/>
+ </accessrules>
+ </classpathentry>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.mylyn.commons.notifications.ui/.cvsignore b/org.eclipse.mylyn.commons.notifications.ui/.cvsignore
new file mode 100644
index 00000000..d567ba01
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/.cvsignore
@@ -0,0 +1,2 @@
+bin
+target
diff --git a/org.eclipse.mylyn.commons.notifications.ui/.project b/org.eclipse.mylyn.commons.notifications.ui/.project
new file mode 100644
index 00000000..420819d9
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.mylyn.commons.notifications.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 00000000..5a0ad22d
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..38a554ff
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,354 @@
+#Wed Mar 02 16:00:06 PST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
+org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL
+org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=48
+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_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+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_selector_in_method_invocation=80
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=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
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=false
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=false
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_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=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true
+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.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+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_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000..d92dfc1c
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,63 @@
+#Wed Mar 02 16:00:08 PST 2011
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Mylyn based on Eclipse
+formatter_settings_version=12
+internal.default.compliance=default
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=false
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * @author ${user}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="false" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment"/><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">/*******************************************************************************\r\n * Copyright (c) ${year} Tasktop Technologies and others.\r\n * All rights reserved. This program and the accompanying materials\r\n * are made available under the terms of the Eclipse Public License v1.0\r\n * which accompanies this distribution, and is available at\r\n * http\://www.eclipse.org/legal/epl-v10.html\r\n *\r\n * Contributors\:\r\n * Tasktop Technologies - initial API and implementation\r\n *******************************************************************************/\r\n\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="false" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="false" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ignore\r\n${body_statement}</template><template autoinsert\="false" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ignore</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created JavaScript files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n * @author ${user}\r\n *\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for vars" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Jsdoc)\r\n * ${see_to_overridden}\r\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\r\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created function stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated function stub\r\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=true
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.ltk.core.refactoring.prefs b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 00000000..5e7f2bd4
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,3 @@
+#Tue Aug 18 22:42:26 PDT 2009
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 00000000..d8c6d26a
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Mon Jun 25 03:02:37 GMT 2007
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.pde.prefs b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.pde.prefs
new file mode 100644
index 00000000..e8f2d562
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,18 @@
+#Tue Apr 15 11:07:59 PDT 2008
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=2
+compilers.p.missing-bundle-classpath-entries=1
+compilers.p.missing-packages=1
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/org.eclipse.mylyn.commons.notifications.ui/META-INF/MANIFEST.MF b/org.eclipse.mylyn.commons.notifications.ui/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..9164a49b
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.mylyn.commons.notifications.ui;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-Vendor: %Bundle-Vendor
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.mylyn.commons.notifications.ui;x-internal:=true,
+ org.eclipse.mylyn.internal.commons.notifications.ui;x-internal:=true,
+ org.eclipse.mylyn.internal.commons.notifications.ui.popup;x-internal:=true
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.jface,
+ org.eclipse.ui,
+ org.eclipse.ui.forms,
+ org.eclipse.ui.workbench,
+ org.eclipse.mylyn.commons.core;bundle-version="3.5.0",
+ org.eclipse.mylyn.commons.notifications.core,
+ org.eclipse.mylyn.commons.ui;bundle-version="3.5.0",
+ org.eclipse.mylyn.commons.workbench;bundle-version="3.5.0",
+ org.eclipse.ui.forms
+Bundle-ClassPath: .
+Bundle-Localization: plugin
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.eclipse.mylyn.internal.commons.notifications.ui.NotificationsPlugin
diff --git a/org.eclipse.mylyn.commons.notifications.ui/about.html b/org.eclipse.mylyn.commons.notifications.ui/about.html
new file mode 100644
index 00000000..d774b07c
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/about.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 25, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/org.eclipse.mylyn.commons.notifications.ui/build.properties b/org.eclipse.mylyn.commons.notifications.ui/build.properties
new file mode 100644
index 00000000..e5e8ab81
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/build.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2004, 2009 Tasktop Technologies and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+bin.includes = about.html,\
+ META-INF/,\
+ .,\
+ plugin.xml,\
+ plugin.properties
+src.includes = about.html,\
+ schema/
+jre.compilation.profile = J2SE-1.5
+source.. = src/
diff --git a/org.eclipse.mylyn.commons.notifications.ui/plugin.properties b/org.eclipse.mylyn.commons.notifications.ui/plugin.properties
new file mode 100644
index 00000000..9d7af387
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2010 Tasktop Technologies and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Tasktop Technologies - initial API and implementation
+###############################################################################
+
+Bundle-Vendor = Eclipse Mylyn
+Bundle-Name = Mylyn Commons
diff --git a/org.eclipse.mylyn.commons.notifications.ui/plugin.xml b/org.eclipse.mylyn.commons.notifications.ui/plugin.xml
new file mode 100644
index 00000000..406cfced
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/plugin.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<!--
+ Copyright (c) 2010 Tasktop Technologies and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+
+ Contributors:
+ Tasktop Technologies - initial API and implementation
+ -->
+<plugin>
+ <extension-point id="notifications" name="Noification Provider" schema="schema/notifications.exsd"/>
+ <extension
+ point="org.eclipse.mylyn.commons.notifications.ui.notifications">
+ <sink
+ class="org.eclipse.mylyn.internal.commons.notifications.ui.popup.PopupNotificationSink"
+ id="org.eclipse.mylyn.commons.notifications.sink.Popup"
+ label="Desktop Popup">
+ </sink>
+ </extension>
+ <extension
+ point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="org.eclipse.mylyn.internal.commons.notifications.ui.NotificationsPreferencesInitializer">
+ </initializer>
+ </extension>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <!--
+ <page
+ category="org.eclipse.ui.preferencePages.Workbench"
+ class="org.eclipse.mylyn.internal.commons.ui.notifications.NotificationsPreferencesPage"
+ id="org.eclipse.mylyn.commons.notifications.preferencePages.Notifications"
+ name="Notifications">
+ </page>
+ -->
+ <page
+ category="org.eclipse.mylyn.preferencePages.Mylyn"
+ class="org.eclipse.mylyn.internal.commons.notifications.ui.NotificationsPreferencesPage"
+ id="org.eclipse.mylyn.commons.notifications.preferencePages.Notifications"
+ name="Notifications">
+ </page>
+ </extension>
+
+</plugin>
diff --git a/org.eclipse.mylyn.commons.notifications.ui/pom.xml b/org.eclipse.mylyn.commons.notifications.ui/pom.xml
new file mode 100644
index 00000000..bd224d1d
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.mylyn.commons-parent</artifactId>
+ <groupId>org.eclipse.mylyn.commons</groupId>
+ <version>3.7.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.mylyn.commons.notifications.ui</artifactId>
+ <version>0.9.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/org.eclipse.mylyn.commons.notifications.ui/schema/notifications.exsd b/org.eclipse.mylyn.commons.notifications.ui/schema/notifications.exsd
new file mode 100644
index 00000000..cff69b43
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/schema/notifications.exsd
@@ -0,0 +1,319 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.mylyn.commons.notifications" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.mylyn.commons.notifications" id="notifications" name="Notifications"/>
+ </appinfo>
+ <documentation>
+ Provides support for event categories, types and sinks.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <choice minOccurs="1" maxOccurs="unbounded">
+ <element ref="category"/>
+ <element ref="event"/>
+ <element ref="sink"/>
+ <element ref="eventMapping"/>
+ </choice>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="event">
+ <annotation>
+ <documentation>
+ Event types has an unique identifier, a label and optionally an icon and a category. Whenever a notification is triggered the identifier is used to determine how to present the notification to the user.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="0" maxOccurs="1">
+ <element ref="description"/>
+ <element ref="defaultHandler" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ a unique event identifier.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ a 16x16 icon.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ a label describing the event type.
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="categoryId" type="string">
+ <annotation>
+ <documentation>
+ parent category identifier.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.mylyn.commons.notifications.notifications/category/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="category">
+ <annotation>
+ <documentation>
+ Events can (and should) be organised into categories making them easy to locate in the user interface.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ a unique event category identifier.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ a 16x16 icon.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ a label describing the category.
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="sink">
+ <annotation>
+ <documentation>
+ Notification sinks are used to handle events.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ a unique event sink identifier.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ the event sink implementation.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.mylyn.commons.notifications.NotificationSink:"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ a label describing the event sink.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="description" type="string">
+ <annotation>
+ <appinfo>
+ <meta.element translatable="true"/>
+ </appinfo>
+ <documentation>
+ A description of the event type.
+ </documentation>
+ </annotation>
+ </element>
+
+ <element name="defaultHandler">
+ <annotation>
+ <documentation>
+ One or more &lt;i&gt;defaultHandler&lt;/i&gt; elements may be added to an event for specifying which sink should handle the event. If none are specified all sinks will be used. Note that this element specifies a default setting that may be changed in user preferences.
+
+A similar effect is achieved by the &lt;i&gt;eventMapping&lt;/i&gt; extension.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="sinkId" type="string" use="required">
+ <annotation>
+ <documentation>
+ Identifier of the sink that should handle the event.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.mylyn.commons.notifications.notifications/sink/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="eventMapping">
+ <annotation>
+ <documentation>
+ Event mappings are used to map one ore more events to a sink. Note that this element specifies a default setting that may be changed in user preferences.
+
+Also see the &lt;i&gt;defaultHandler&lt;/i&gt; element of &lt;i&gt;event&lt;/i&gt; declarations.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="sinkId" type="string" use="required">
+ <annotation>
+ <documentation>
+ Identifier of the sink that should handle the event.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.mylyn.commons.notifications.notifications/sink/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="eventIds" type="string" use="required">
+ <annotation>
+ <documentation>
+ a comma separated list of event identifiers that will be mapped to the notification sink. The &quot;*&quot; wildcard can be used so that multiple events can be mapped to one sink.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 3.5
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ Following is an example of use:
+&lt;pre&gt;
+ &lt;extension
+ point=&quot;org.eclipse.mylyn.commons.notifications.notifications&quot;&gt;
+ &lt;event
+ categoryId=&quot;org.eclipse.mylyn.builds.ui.category.Builds&quot;
+ id=&quot;org.eclipse.mylyn.builds.ui.events.BuildServiceChanged&quot;
+ label=&quot;Build Service Changed&quot;&gt;
+ &lt;description&gt;
+ This event is triggered when the status of a build service is changed. For instance a new server is discovered or is no longer available.
+ &lt;/description&gt;
+ &lt;defaultHandler
+ sinkId=&quot;org.eclipse.mylyn.internal.builds.ui.view.NotificationSinkProxy&quot;/&gt;
+ &lt;/category&gt;
+ &lt;/event&gt;
+ &lt;category
+ icon=&quot;icons/eview16/build-view.png&quot;
+ id=&quot;org.eclipse.mylyn.builds.ui.category.Builds&quot;
+ label=&quot;Builds&quot;&gt;
+ &lt;/category&gt;
+ &lt;sink
+ class=&quot;org.eclipse.mylyn.internal.builds.ui.view.NotificationSinkProxy&quot;
+ id=&quot;org.eclipse.mylyn.builds.ui.sink.View&quot;
+ label=&quot;Builds View&quot;&gt;
+ &lt;/sink&gt;
+ &lt;eventMapping
+ eventIds=&quot;org.eclipse.mylyn.builds.ui.events.*&quot;
+ sinkId=&quot;org.eclipse.mylyn.commons.notifications.sink.Popup&quot;&gt;
+ &lt;/eventMapping&gt;
+ &lt;/extension&gt;
+&lt;/pre&gt;
+
+This example will declare a new event and assign it to the builds view notification sink. The category for the event is also declared in addition to the builds view notification sink. The last configuration element declares a mapping between all build event types and the popup notification sink.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ The value of the class attribute in sink must represent a class
+that implements &lt;samp&gt;org.eclipse.mylyn.commons.notifications.NotificationSink&lt;/samp&gt;.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ Mylyn Builds comes with two event types and two different sinks for handling these notifications.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ Copyright (c) 2010 Tasktop Technologies and others.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/AbstractUiNotification.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/AbstractUiNotification.java
new file mode 100644
index 00000000..4e59f0f4
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/AbstractUiNotification.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.commons.notifications.ui;
+
+import org.eclipse.mylyn.commons.notifications.core.AbstractNotification;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A notification with UI specific extensions.
+ *
+ * @author Steffen Pingel
+ */
+public abstract class AbstractUiNotification extends AbstractNotification {
+
+ public AbstractUiNotification(String eventId) {
+ super(eventId);
+ }
+
+ public abstract Image getNotificationImage();
+
+ public abstract Image getNotificationKindImage();
+
+ /**
+ * Executes the default action for opening the notification.
+ */
+ public abstract void open();
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/NotificationControl.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/NotificationControl.java
new file mode 100644
index 00000000..af5251e1
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/NotificationControl.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.commons.notifications.ui;
+
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.mylyn.commons.ui.CommonImages;
+import org.eclipse.mylyn.commons.workbench.forms.MessageControl;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+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.ImageHyperlink;
+
+/**
+ * @author Steffen Pingel
+ * @since 3.7
+ */
+public abstract class NotificationControl extends MessageControl {
+
+ private static final String NOTIFICATIONS_PREF_PAGE = "org.eclipse.mylyn.commons.notifications.preferencePages.Notifications"; //$NON-NLS-1$
+
+ private ImageHyperlink configureLink;
+
+ private String preferencesPageId;
+
+ public NotificationControl(Composite parent) {
+ super(parent);
+ setPreferencesPageId(NOTIFICATIONS_PREF_PAGE);
+ }
+
+ public String getPreferencesPageId() {
+ return preferencesPageId;
+ }
+
+ public void setPreferencesPageId(String preferencesPageId) {
+ this.preferencesPageId = preferencesPageId;
+ }
+
+ @Override
+ protected void createLinkControls(Composite buttonsComp) {
+ if (getPreferencesPageId() != null) {
+ configureLink = new ImageHyperlink(buttonsComp, SWT.NONE);
+ configureLink.setImage(CommonImages.getImage(CommonImages.NOTIFICATION_CONFIGURE));
+ configureLink.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(HyperlinkEvent e) {
+ PreferenceDialog pd = PreferencesUtil.createPreferenceDialogOn(getShell(), getPreferencesPageId(),
+ new String[0], getEventId());
+ // Only close the message if the did not cancel the operation
+ if (pd != null) {
+ pd.open();
+ }
+ }
+
+ @Override
+ public void linkEntered(HyperlinkEvent e) {
+ configureLink.setImage(CommonImages.getImage(CommonImages.NOTIFICATION_CONFIGURE_HOVER));
+ }
+
+ @Override
+ public void linkExited(HyperlinkEvent e) {
+ configureLink.setImage(CommonImages.getImage(CommonImages.NOTIFICATION_CONFIGURE));
+ }
+ });
+ // Initially invisible, must have eventId for this to be of any use.
+ configureLink.setVisible(getEventId() != null);
+ }
+ super.createLinkControls(buttonsComp);
+ }
+
+ @Override
+ protected void setEventId(String eventId) {
+ super.setEventId(eventId);
+ if (configureLink != null) {
+ configureLink.setVisible(eventId != null);
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/NotificationsUi.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/NotificationsUi.java
new file mode 100644
index 00000000..7886dd51
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/commons/notifications/ui/NotificationsUi.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.commons.notifications.ui;
+
+import org.eclipse.mylyn.commons.notifications.core.INotificationService;
+import org.eclipse.mylyn.internal.commons.notifications.ui.NotificationsPlugin;
+
+/**
+ * @author Steffen Pingel
+ */
+public final class NotificationsUi {
+
+ private NotificationsUi() {
+ // do not instantiate
+ }
+
+ public static INotificationService getService() {
+ return NotificationsPlugin.getDefault().getService();
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/Messages.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/Messages.java
new file mode 100644
index 00000000..b4e8798f
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/Messages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.mylyn.internal.commons.ui.notifications.messages"; //$NON-NLS-1$
+
+ public static String NotificationsPreferencesPage_Descriptions_Label;
+
+ public static String NotificationsPreferencesPage_Enable_Notifications_Text;
+
+ public static String NotificationsPreferencesPage_Events_Label;
+
+ public static String NotificationsPreferencesPage_Notifiers_Label;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationAction.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationAction.java
new file mode 100644
index 00000000..0ae1fd48
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationAction.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.mylyn.commons.notifications.core.NotificationSink;
+
+/**
+ * Describes how a {@link NotificationEvent} is handled. {@link NotificationAction}s store enablement and parameters
+ * that determine how the {@link NotificationSink} executes the action.
+ *
+ * @author Steffen Pingel
+ */
+public class NotificationAction {
+
+ private boolean selected;
+
+ private final NotificationSinkDescriptor sinkDescriptor;
+
+ public NotificationAction(NotificationSinkDescriptor sinkDescriptor) {
+ Assert.isNotNull(sinkDescriptor);
+ this.sinkDescriptor = sinkDescriptor;
+ }
+
+ public NotificationSinkDescriptor getSinkDescriptor() {
+ return sinkDescriptor;
+ }
+
+ public boolean isSelected() {
+ return selected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ @Override
+ public String toString() {
+ return sinkDescriptor.getLabel();
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationCategory.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationCategory.java
new file mode 100644
index 00000000..b18ab676
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationCategory.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+
+/**
+ * @author Steffen Pingel
+ */
+public class NotificationCategory extends NotificationElement {
+
+ private final List<NotificationEvent> events;
+
+ public NotificationCategory(IConfigurationElement element) {
+ super(element);
+ this.events = new ArrayList<NotificationEvent>();
+ }
+
+ public void addEvent(NotificationEvent event) {
+ event.setCategory(this);
+ events.add(event);
+ }
+
+ public List<NotificationEvent> getEvents() {
+ return events;
+ }
+
+ public void removeEvent(NotificationEvent event) {
+ event.setCategory(null);
+ events.remove(event);
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationElement.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationElement.java
new file mode 100644
index 00000000..f8e013ba
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationElement.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @author Steffen Pingel
+ */
+public class NotificationElement {
+
+ protected final IConfigurationElement element;
+
+ private ImageDescriptor iconDescriptor;
+
+ private final String id;
+
+ private final String label;
+
+ public NotificationElement(IConfigurationElement element) {
+ Assert.isNotNull(element);
+ this.element = element;
+ this.id = element.getAttribute("id"); //$NON-NLS-1$
+ this.label = element.getAttribute("label"); //$NON-NLS-1$
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ if (iconDescriptor == null) {
+ if (element != null) {
+ String iconPath = element.getAttribute("icon"); //$NON-NLS-1$
+ if (iconPath != null) {
+ iconDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin(element.getContributor().getName(),
+ iconPath);
+ }
+ }
+ }
+ return iconDescriptor;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getPluginId() {
+ return element.getContributor().getName();
+ }
+
+ public IStatus validate() {
+ if (id == null) {
+ return new Status(IStatus.ERROR, NotificationsPlugin.ID_PLUGIN, NLS.bind(
+ "Extension {0} contributed by {1} does not specify id attribute", element.getNamespaceIdentifier(), //$NON-NLS-1$
+ getPluginId())); //NON-NLS-1$
+ } else if (label == null) {
+ return new Status(IStatus.ERROR, NotificationsPlugin.ID_PLUGIN, NLS.bind(
+ "Extension {0} contributed by {1} does not specify label attribute", //$NON-NLS-1$
+ element.getNamespaceIdentifier(), getPluginId())); //NON-NLS-1$
+ }
+ return Status.OK_STATUS;
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationEvent.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationEvent.java
new file mode 100644
index 00000000..845e0309
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationEvent.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Itema AS - bug 331424 handle default event-sink action associations
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.mylyn.commons.notifications.core.NotificationSink;
+
+/**
+ * Describes an event that is handled through a notification. The handling of event is stored in
+ * {@link NotificationAction} objects that delegate to {@link NotificationSink} objects for the handling of actual
+ * events.
+ *
+ * @author Steffen Pingel
+ * @author Torkild U. Resheim
+ */
+public class NotificationEvent extends NotificationElement {
+
+ private static final String EXTENSION_POINT_ID = "org.eclipse.mylyn.commons.notifications.notifications"; //$NON-NLS-1$
+
+ private NotificationCategory category;
+
+ private boolean selected;
+
+ private final ArrayList<String> defaultSinks;
+
+ /**
+ * Tests whether or not the event should per default be handled by the sink with the specified identifier.
+ *
+ * @param sinkId
+ * the sink identifier
+ * @return <code>true</code> if the
+ */
+ public boolean defaultHandledBySink(String sinkId) {
+ if (defaultSinks.isEmpty() || defaultSinks.contains(sinkId)) {
+ return true;
+ }
+ return false;
+ }
+
+ public NotificationEvent(IConfigurationElement element) {
+ super(element);
+ defaultSinks = new ArrayList<String>();
+ IConfigurationElement[] children = element.getChildren("defaultHandler"); //$NON-NLS-1$
+ for (IConfigurationElement child : children) {
+ defaultSinks.add(child.getAttribute("sinkId")); //$NON-NLS-1$
+ }
+ doEventMappings();
+ }
+
+ private void doEventMappings() {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint point = registry.getExtensionPoint(EXTENSION_POINT_ID);
+ if (point != null) {
+ IConfigurationElement[] elements = point.getConfigurationElements();
+ for (IConfigurationElement mapping : elements) {
+ if (mapping.getName().equals("eventMapping")) { //$NON-NLS-1$
+ String eventIds = mapping.getAttribute("eventIds"); //$NON-NLS-1$
+ String[] list = eventIds.split(","); //$NON-NLS-1$
+ for (String item : list) {
+ if (wildCardMatch(getId(), item)) {
+ defaultSinks.add(mapping.getAttribute("sinkId")); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private boolean wildCardMatch(String text, String pattern) {
+ String[] cards = pattern.split("\\*"); //$NON-NLS-1$
+ for (String card : cards) {
+ int idx = text.indexOf(card);
+ if (idx == -1) {
+ return false;
+ }
+ text = text.substring(idx + card.length());
+ }
+
+ return true;
+ }
+
+ public NotificationCategory getCategory() {
+ return category;
+ }
+
+ public String getCategoryId() {
+ return element.getAttribute("categoryId"); //$NON-NLS-1$
+ }
+
+ public String getDescription() {
+ IConfigurationElement[] children = element.getChildren("description"); //$NON-NLS-1$
+ if (children.length > 0) {
+ return children[0].getValue();
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ public void setCategory(NotificationCategory category) {
+ this.category = category;
+ }
+
+ @Deprecated
+ public boolean isSelected() {
+ return selected;
+ }
+
+ @Deprecated
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationHandler.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationHandler.java
new file mode 100644
index 00000000..95b4437a
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationHandler.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import java.util.List;
+
+/**
+ * Manages actions that are triggered when a {@link NotificationEvent} occurs.
+ *
+ * @author Steffen Pingel
+ */
+public class NotificationHandler {
+
+ private final List<NotificationAction> actions;
+
+ private final NotificationEvent event;
+
+ public NotificationHandler(NotificationEvent event, List<NotificationAction> actions) {
+ this.event = event;
+ this.actions = actions;
+ }
+
+ public List<NotificationAction> getActions() {
+ return actions;
+ }
+
+ public NotificationEvent getEvent() {
+ return event;
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationModel.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationModel.java
new file mode 100644
index 00000000..2de1e41d
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationModel.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Itema AS - bug 330064 notification filtering and model persistence
+ * Itema AS - bug 331424 handle default event-sink action associations
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.ui.IMemento;
+
+/**
+ * @author Steffen Pingel
+ * @author Torkild U. Resheim
+ */
+public class NotificationModel {
+
+ private boolean dirty;
+
+ private Map<String, NotificationHandler> handlerByEventId;
+
+ public NotificationModel(IMemento memento) {
+ initialize(memento);
+ }
+
+ void initialize(IMemento memento) {
+ this.handlerByEventId = new HashMap<String, NotificationHandler>();
+ // We need the handlerByEventId map to be populated early
+ for (NotificationCategory category : getCategories()) {
+ for (NotificationEvent event : category.getEvents()) {
+ getOrCreateNotificationHandler(event);
+ }
+ }
+ if (memento != null) {
+ load(memento);
+ }
+ }
+
+ public Collection<NotificationCategory> getCategories() {
+ return NotificationsExtensionReader.getCategories();
+ }
+
+ public NotificationHandler getNotificationHandler(String eventId) {
+ return handlerByEventId.get(eventId);
+ }
+
+ public NotificationHandler getOrCreateNotificationHandler(NotificationEvent event) {
+ NotificationHandler handler = getNotificationHandler(event.getId());
+ if (handler == null) {
+ handler = new NotificationHandler(event, getActions(event));
+ handlerByEventId.put(event.getId(), handler);
+ }
+ return handler;
+ }
+
+ private List<NotificationAction> getActions(NotificationEvent event) {
+ List<NotificationSinkDescriptor> descriptors = NotificationsExtensionReader.getSinks();
+ List<NotificationAction> actions = new ArrayList<NotificationAction>(descriptors.size());
+ for (NotificationSinkDescriptor descriptor : descriptors) {
+ NotificationAction action = new NotificationAction(descriptor);
+ if (event.defaultHandledBySink(descriptor.getId())) {
+ action.setSelected(true);
+ }
+ actions.add(action);
+ }
+ return actions;
+ }
+
+ public boolean isDirty() {
+ return dirty;
+ }
+
+ public boolean isSelected(NotificationEvent event) {
+ NotificationHandler handler = getOrCreateNotificationHandler(event);
+ for (NotificationAction action : handler.getActions()) {
+ if (action.isSelected()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Stores the selected state of events and sinks.
+ *
+ * @param memento
+ * the memento to store in.
+ */
+ public void save(IMemento memento) {
+ for (Entry<String, NotificationHandler> entry : handlerByEventId.entrySet()) {
+ IMemento event = memento.createChild("event"); //$NON-NLS-1$
+ event.putString("id", entry.getKey()); //$NON-NLS-1$
+ List<NotificationAction> actions = entry.getValue().getActions();
+ for (NotificationAction notificationAction : actions) {
+ IMemento action = event.createChild("action"); //$NON-NLS-1$
+ action.putBoolean("selected", notificationAction.isSelected()); //$NON-NLS-1$
+ action.putString("sink", notificationAction.getSinkDescriptor().getId()); //$NON-NLS-1$
+ }
+ }
+ setDirty(false);
+ }
+
+ /**
+ * Updates the notification model with selected states from the memento instance.
+ *
+ * @param memento
+ */
+ private void load(IMemento memento) {
+ Assert.isNotNull(memento);
+ for (IMemento mEvent : memento.getChildren("event")) { //$NON-NLS-1$
+ for (NotificationCategory category : getCategories()) {
+ for (NotificationEvent event : category.getEvents()) {
+ if (event.getId().equals(mEvent.getString("id"))) { //$NON-NLS-1$
+ NotificationHandler handler = getOrCreateNotificationHandler(event);
+ List<NotificationAction> actions = handler.getActions();
+ for (NotificationAction notificationAction : actions) {
+ IMemento[] mActions = mEvent.getChildren("action"); //$NON-NLS-1$
+ for (IMemento mAction : mActions) {
+ if (notificationAction.getSinkDescriptor().getId().equals(mAction.getString("sink"))) { //$NON-NLS-1$
+ notificationAction.setSelected(mAction.getBoolean("selected")); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+
+ /**
+ * Updates the state of the notification handlers depending on their child notification action states.
+ */
+ @Deprecated
+ public void updateStates() {
+ Collection<NotificationHandler> handlers = handlerByEventId.values();
+ for (NotificationHandler notificationHandler : handlers) {
+ List<NotificationAction> actions = notificationHandler.getActions();
+ boolean selected = false;
+ for (NotificationAction notificationAction : actions) {
+ if (notificationAction.isSelected()) {
+ selected = true;
+ break;
+ }
+ }
+ notificationHandler.getEvent().setSelected(selected);
+ }
+ }
+
+ public void setNotificationHandler(String eventId, NotificationHandler handler) {
+ handlerByEventId.put(eventId, handler);
+ setDirty(true);
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationService.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationService.java
new file mode 100644
index 00000000..2ad3f2b0
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationService.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Itema AS - bug 330064 notification filtering and model persistence
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.commons.core.StatusHandler;
+import org.eclipse.mylyn.commons.notifications.core.AbstractNotification;
+import org.eclipse.mylyn.commons.notifications.core.INotificationService;
+import org.eclipse.mylyn.commons.notifications.core.NotificationSink;
+import org.eclipse.mylyn.commons.notifications.core.NotificationSinkEvent;
+
+/**
+ * @author Steffen Pingel
+ * @author Torkild U. Resheim
+ */
+public class NotificationService implements INotificationService {
+
+ public NotificationService() {
+ }
+
+ /**
+ * Notify sinks about the.
+ */
+ public void notify(List<? extends AbstractNotification> notifications) {
+ // Return if notifications are not globally enabled.
+ if (!NotificationsPlugin.getDefault()
+ .getPreferenceStore()
+ .getBoolean(NotificationsPlugin.PREF_NOTICATIONS_ENABLED)) {
+ return;
+ }
+ // For each sink assemble a list of notifications that are not blocked
+ // and pass these along.
+ HashMap<NotificationSink, ArrayList<AbstractNotification>> filtered = new HashMap<NotificationSink, ArrayList<AbstractNotification>>();
+ for (AbstractNotification notification : notifications) {
+ String id = notification.getEventId();
+ NotificationHandler handler = NotificationsPlugin.getDefault().getModel().getNotificationHandler(id);
+ if (handler != null) {
+ List<NotificationAction> actions = handler.getActions();
+ for (NotificationAction action : actions) {
+ if (action.isSelected()) {
+ NotificationSink sink = action.getSinkDescriptor().getSink();
+ if (sink != null) {
+ ArrayList<AbstractNotification> list = filtered.get(sink);
+ if (list == null) {
+ list = new ArrayList<AbstractNotification>();
+ filtered.put(sink, list);
+ }
+ list.add(notification);
+ }
+ }
+ }
+ }
+ }
+ // Go through all the sinks that have notifications to display and let
+ // them do their job.
+ for (Entry<NotificationSink, ArrayList<AbstractNotification>> entry : filtered.entrySet()) {
+ final NotificationSink sink = entry.getKey();
+ final NotificationSinkEvent event = new NotificationSinkEvent(new ArrayList<AbstractNotification>(
+ entry.getValue()));
+ SafeRunner.run(new ISafeRunnable() {
+ public void handleException(Throwable e) {
+ StatusHandler.log(new Status(IStatus.WARNING, NotificationsPlugin.ID_PLUGIN, "Sink failed: " //$NON-NLS-1$
+ + sink.getClass(), e));
+ }
+
+ public void run() throws Exception {
+ sink.notify(event);
+ }
+ });
+ }
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationSinkDescriptor.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationSinkDescriptor.java
new file mode 100644
index 00000000..d7b1a7da
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationSinkDescriptor.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.mylyn.commons.notifications.core.NotificationSink;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+/**
+ * @author Steffen Pingel
+ */
+public class NotificationSinkDescriptor extends NotificationElement {
+
+ private NotificationSink sink;
+
+ private Status status;
+
+ public NotificationSinkDescriptor(IConfigurationElement element) {
+ super(element);
+ }
+
+ public NotificationSink getSink() {
+ if (sink != null || status != null) {
+ return sink;
+ }
+
+ try {
+ Object object = element.createExecutableExtension("class"); //$NON-NLS-1$
+ if (object instanceof NotificationSink) {
+ sink = (NotificationSink) object;
+ return sink;
+ } else {
+ status = new Status(IStatus.ERROR, NotificationsPlugin.ID_PLUGIN, NLS.bind(
+ "Sink ''{0}'' does not extend expected class for extension contributed by {1}", //$NON-NLS-1$
+ object.getClass().getCanonicalName(), getPluginId()));
+ }
+ } catch (Throwable e) {
+ status = new Status(IStatus.ERROR, NotificationsPlugin.ID_PLUGIN, NLS.bind(
+ "Sink failed to load for extension contributed by {0}", getPluginId()), e); //$NON-NLS-1$
+ }
+
+ StatusManager.getManager().handle(status);
+ return null;
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsExtensionReader.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsExtensionReader.java
new file mode 100644
index 00000000..4f9f2ca3
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsExtensionReader.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Itema AS - bug 330064 notification filtering and model persistence
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+/**
+ * @author Steffen Pingel
+ * @author Torkild U. Resheim
+ */
+public class NotificationsExtensionReader {
+
+ private static boolean errorLogged = false;
+
+ static List<NotificationSinkDescriptor> sinks;
+
+ private static Collection<NotificationCategory> categories;
+
+ /**
+ * Returns a list of notification categories, each containing their belonging notification events. Once initialised
+ * the same list will be returned upon subsequent calls of this method.
+ *
+ * @return a list of notification categories.
+ * @see NotificationModel#save(org.eclipse.ui.IMemento)
+ * @see NotificationModel#load(org.eclipse.ui.IMemento)
+ */
+ public static Collection<NotificationCategory> getCategories() {
+ if (categories != null) {
+ return categories;
+ }
+ HashMap<String, NotificationCategory> categoryById = new HashMap<String, NotificationCategory>();
+
+ MultiStatus result = new MultiStatus(NotificationsPlugin.ID_PLUGIN, 0,
+ "Notifcation extensions failed to load", null); //$NON-NLS-1$
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint repositoriesExtensionPoint = registry.getExtensionPoint(NotificationsPlugin.ID_PLUGIN
+ + ".notifications"); //$NON-NLS-1$
+ IExtension[] extensions = repositoriesExtensionPoint.getExtensions();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ for (IConfigurationElement element : elements) {
+ if ("category".equals(element.getName())) { //$NON-NLS-1$
+ NotificationCategory category = new NotificationCategory(element);
+ IStatus status = category.validate();
+ if (status.isOK()) {
+ categoryById.put(category.getId(), category);
+ } else {
+ result.add(status);
+ }
+ }
+ }
+ for (IConfigurationElement element : elements) {
+ if ("event".equals(element.getName())) { //$NON-NLS-1$
+ NotificationEvent event = new NotificationEvent(element);
+ IStatus status = event.validate();
+ if (status.isOK()) {
+ NotificationCategory category = categoryById.get(event.getCategoryId());
+ if (category != null) {
+ category.addEvent(event);
+ } else {
+ result.add(new Status(
+ IStatus.ERROR,
+ NotificationsPlugin.ID_PLUGIN,
+ NLS.bind(
+ "Extension {0} contributed by {1} specify unknown category ''{2}''", new String[] { element.getNamespaceIdentifier(), element.getContributor().getName(), event.getCategoryId() }))); //NON-NLS-1$ //$NON-NLS-1$
+ }
+ } else {
+ result.add(status);
+ }
+ }
+ }
+ }
+
+ if (!result.isOK() && !errorLogged) {
+ StatusManager.getManager().handle(result);
+ errorLogged = true;
+ }
+
+ categories = categoryById.values();
+ return categories;
+ }
+
+ public static List<NotificationSinkDescriptor> getSinks() {
+ if (sinks != null) {
+ return sinks;
+ }
+
+ sinks = new ArrayList<NotificationSinkDescriptor>();
+
+ MultiStatus result = new MultiStatus(NotificationsPlugin.ID_PLUGIN, 0,
+ "Notifcation extensions failed to load", null); //$NON-NLS-1$
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IExtensionPoint repositoriesExtensionPoint = registry.getExtensionPoint(NotificationsPlugin.ID_PLUGIN
+ + ".notifications"); //$NON-NLS-1$
+ IExtension[] extensions = repositoriesExtensionPoint.getExtensions();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ for (IConfigurationElement element : elements) {
+ if ("sink".equals(element.getName())) { //$NON-NLS-1$
+ NotificationSinkDescriptor descriptor = new NotificationSinkDescriptor(element);
+ IStatus status = descriptor.validate();
+ if (status.isOK()) {
+ sinks.add(descriptor);
+ } else {
+ result.add(status);
+ }
+ }
+ }
+ }
+
+ if (!result.isOK()) {
+ StatusManager.getManager().handle(result);
+ }
+
+ return sinks;
+ }
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPlugin.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPlugin.java
new file mode 100644
index 00000000..15aad577
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPlugin.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * @author Steffen Pingel
+ */
+public class NotificationsPlugin extends AbstractUIPlugin {
+
+ public static final String ID_PLUGIN = "org.eclipse.mylyn.commons.notifications"; //$NON-NLS-1$
+
+ public static final String PREF_NOTICATIONS_ENABLED = "notifications.enabled"; //$NON-NLS-1$
+
+ private static NotificationsPlugin instance;
+
+ public static NotificationsPlugin getDefault() {
+ return instance;
+ }
+
+ private NotificationModel model;
+
+ private NotificationService service;
+
+ public NotificationModel createModelWorkingCopy() {
+ IMemento memento = null;
+ File file = getModelFile().toFile();
+ if (file.exists()) {
+ try {
+ FileReader reader = new FileReader(file);
+ try {
+ memento = XMLMemento.createReadRoot(reader);
+ } finally {
+ reader.close();
+ }
+ } catch (IOException e) {
+ getLog().log(new Status(IStatus.ERROR, ID_PLUGIN, "Unexpected error restoring notification state", e)); //$NON-NLS-1$
+ } catch (WorkbenchException e) {
+ getLog().log(new Status(IStatus.ERROR, ID_PLUGIN, "Unexpected error restoring notification state", e)); //$NON-NLS-1$
+ }
+ }
+ return new NotificationModel(memento);
+ }
+
+ public NotificationModel getModel() {
+ if (model == null) {
+ model = createModelWorkingCopy();
+ }
+ return model;
+ }
+
+ public NotificationService getService() {
+ if (service == null) {
+ service = new NotificationService();
+ }
+ return service;
+ }
+
+ public void saveModel() {
+ if (model != null && model.isDirty()) {
+ save(model);
+ }
+ }
+
+ public void saveWorkingCopy(NotificationModel workingCopy) {
+ XMLMemento memento = save(workingCopy);
+ if (this.model != null) {
+ // reload model
+ this.model.initialize(memento);
+ }
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ instance = this;
+ super.start(context);
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ instance = null;
+ }
+
+ private XMLMemento save(NotificationModel model) {
+ XMLMemento memento = XMLMemento.createWriteRoot("notifications"); //$NON-NLS-1$
+ model.save(memento);
+ FileWriter writer;
+ try {
+ writer = new FileWriter(getModelFile().toFile());
+ try {
+ memento.save(writer);
+ } finally {
+ writer.close();
+ }
+ } catch (IOException e) {
+ getLog().log(new Status(IStatus.ERROR, ID_PLUGIN, "Unexpected error saving notification state", e)); //$NON-NLS-1$
+ }
+ return memento;
+ }
+
+ protected IPath getModelFile() {
+ IPath stateLocation = Platform.getStateLocation(getBundle());
+ IPath cacheFile = stateLocation.append("notifications.xml"); //$NON-NLS-1$
+ return cacheFile;
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPreferencesInitializer.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPreferencesInitializer.java
new file mode 100644
index 00000000..22fee0db
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPreferencesInitializer.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * @author Steffen Pingel
+ */
+public class NotificationsPreferencesInitializer extends AbstractPreferenceInitializer {
+
+ public NotificationsPreferencesInitializer() {
+ // ignore
+ }
+
+ @Override
+ public void initializeDefaultPreferences() {
+ IPreferenceStore preferencesStore = NotificationsPlugin.getDefault().getPreferenceStore();
+ preferencesStore.setDefault(NotificationsPlugin.PREF_NOTICATIONS_ENABLED, true);
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPreferencesPage.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPreferencesPage.java
new file mode 100644
index 00000000..9b3f74b0
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/NotificationsPreferencesPage.java
@@ -0,0 +1,406 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * Itema AS - bug 329897 select event type on open if available
+ * Itema AS - bug 330064 notification filtering and model persistence
+ * Itema AS - bug 331424 handle default event-sink action associations
+ *******************************************************************************/
+package org.eclipse.mylyn.internal.commons.notifications.ui;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ICheckStateProvider;
+import org.eclipse.jface.viewers.IElementComparer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+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.mylyn.commons.ui.CommonImages;
+import org.eclipse.mylyn.commons.workbench.SubstringPatternFilter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+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.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.dialogs.FilteredTree;
+
+/**
+ * @author Steffen Pingel
+ * @author Torkild Ulvøy Resheim
+ */
+public class NotificationsPreferencesPage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ /**
+ * We need this in order to make sure that the correct element is selected in the {@link TreeViewer} when the
+ * selection is set.
+ *
+ * @author Torkild Ulvøy Resheim
+ */
+ public class NotificationEventComparer implements IElementComparer {
+
+ public boolean equals(Object a, Object b) {
+ if (a instanceof NotificationEvent && b instanceof NotificationEvent) {
+ String idA = ((NotificationEvent) a).getId();
+ String idB = ((NotificationEvent) b).getId();
+ return (idA.equals(idB));
+ }
+ return a.equals(b);
+ }
+
+ public int hashCode(Object element) {
+ return element.hashCode();
+ }
+
+ }
+
+ private static final Object[] EMPTY = new Object[0];
+
+ private final class EventContentProvider implements ITreeContentProvider {
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // ignore
+ }
+
+ public void dispose() {
+ // ignore
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof NotificationCategory) {
+ return ((NotificationCategory) element).getEvents().size() > 0;
+ }
+ return false;
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof NotificationEvent) {
+ return ((NotificationEvent) element).getCategory();
+ }
+ return null;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof Object[]) {
+ return (Object[]) inputElement;
+ } else {
+ return EMPTY;
+ }
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof NotificationCategory) {
+ return ((NotificationCategory) parentElement).getEvents().toArray();
+ }
+ return EMPTY;
+ }
+
+ }
+
+ private final class NotifiersContentProvider implements IStructuredContentProvider {
+
+ private NotificationHandler handler;
+
+ public void dispose() {
+ // ignore
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (newInput instanceof NotificationHandler) {
+ handler = (NotificationHandler) newInput;
+ } else {
+ handler = null;
+ }
+ }
+
+ public Object[] getElements(Object inputElement) {
+ if (handler != null) {
+ return handler.getActions().toArray();
+ } else {
+ return EMPTY;
+ }
+ }
+
+ }
+
+ public final class EventLabelProvider extends LabelProvider {
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof NotificationElement) {
+ NotificationElement item = (NotificationElement) element;
+ return item.getLabel();
+ }
+ return super.getText(element);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof NotificationEvent) {
+ NotificationEvent item = (NotificationEvent) element;
+ if (model.isSelected(item)) {
+ return CommonImages.getImage(CommonImages.CHECKED);
+ } else {
+ return null;
+ }
+ }
+ if (element instanceof NotificationElement) {
+ NotificationElement item = (NotificationElement) element;
+ ImageDescriptor imageDescriptor = item.getImageDescriptor();
+ if (imageDescriptor != null) {
+ return CommonImages.getImage(imageDescriptor);
+ }
+ }
+ return super.getImage(element);
+ }
+ }
+
+ private TreeViewer eventsViewer;
+
+ private CheckboxTableViewer notifiersViewer;
+
+ private Button enableNotificationsButton;
+
+ private NotificationModel model;
+
+ private Text descriptionText;
+
+ public NotificationsPreferencesPage() {
+ }
+
+ @Override
+ public IPreferenceStore getPreferenceStore() {
+ return NotificationsPlugin.getDefault().getPreferenceStore();
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ model = NotificationsPlugin.getDefault().createModelWorkingCopy();
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+
+ enableNotificationsButton = new Button(composite, SWT.CHECK);
+ GridDataFactory.fillDefaults().span(2, 1).applyTo(enableNotificationsButton);
+ enableNotificationsButton.setText(Messages.NotificationsPreferencesPage_Enable_Notifications_Text);
+ enableNotificationsButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ updateEnablement();
+ }
+ });
+
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(" "); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().span(2, 1).applyTo(label);
+
+ label = new Label(composite, SWT.NONE);
+ label.setText(Messages.NotificationsPreferencesPage_Events_Label);
+
+ label = new Label(composite, SWT.NONE);
+ label.setText(Messages.NotificationsPreferencesPage_Notifiers_Label);
+ // Create the tree showing all the various notification types
+ FilteredTree tree = new FilteredTree(composite, SWT.BORDER, new SubstringPatternFilter(), true);
+ eventsViewer = tree.getViewer();
+ GridDataFactory.fillDefaults().span(1, 2).grab(false, true).applyTo(tree);
+ eventsViewer.setComparer(new NotificationEventComparer());
+ eventsViewer.setContentProvider(new EventContentProvider());
+ eventsViewer.setLabelProvider(new EventLabelProvider());
+ eventsViewer.setInput(model.getCategories().toArray());
+ eventsViewer.expandAll();
+ eventsViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ Object input = getDetailsInput((IStructuredSelection) event.getSelection());
+ notifiersViewer.setInput(input);
+
+ Object item = ((IStructuredSelection) event.getSelection()).getFirstElement();
+ if (item instanceof NotificationEvent) {
+ descriptionText.setText(((NotificationEvent) item).getDescription());
+ notifiersViewer.getControl().setEnabled(true);
+ } else {
+ descriptionText.setText(" "); //$NON-NLS-1$
+ notifiersViewer.getControl().setEnabled(false);
+ }
+ }
+
+ private Object getDetailsInput(IStructuredSelection selection) {
+ Object item = selection.getFirstElement();
+ if (item instanceof NotificationEvent) {
+ return model.getOrCreateNotificationHandler((NotificationEvent) item);
+ }
+ return null;
+ }
+ });
+ // Create the table listing all notification sinks available for the selected event type.
+ notifiersViewer = CheckboxTableViewer.newCheckList(composite, SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(notifiersViewer.getControl());
+ notifiersViewer.setContentProvider(new NotifiersContentProvider());
+ notifiersViewer.setLabelProvider(new EventLabelProvider());
+ notifiersViewer.addCheckStateListener(new ICheckStateListener() {
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ NotificationAction action = (NotificationAction) event.getElement();
+ action.setSelected(event.getChecked());
+ model.setDirty(true);
+ eventsViewer.refresh();
+ }
+ });
+ notifiersViewer.setCheckStateProvider(new ICheckStateProvider() {
+ public boolean isChecked(Object element) {
+ return ((NotificationAction) element).isSelected();
+ }
+
+ public boolean isGrayed(Object element) {
+ return false;
+ }
+ });
+ notifiersViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ Object item = ((IStructuredSelection) event.getSelection()).getFirstElement();
+ if (item instanceof NotificationAction) {
+ // TODO show configuration pane
+ }
+ }
+ });
+
+ Group group = new Group(composite, SWT.NONE);
+ GridDataFactory.fillDefaults().hint(150, SWT.DEFAULT).grab(true, true).applyTo(group);
+ group.setText(Messages.NotificationsPreferencesPage_Descriptions_Label);
+ FillLayout layout = new FillLayout();
+ layout.marginHeight = 5;
+ layout.marginWidth = 5;
+ group.setLayout(layout);
+
+ descriptionText = new Text(group, SWT.WRAP);
+ descriptionText.setBackground(group.getBackground());
+
+// Button testButton = new Button(composite, SWT.NONE);
+// testButton.setText("Test");
+// testButton.addSelectionListener(new SelectionAdapter() {
+// @Override
+// public void widgetSelected(SelectionEvent e) {
+// ISelection selection = eventsViewer.getSelection();
+// if (selection instanceof IStructuredSelection) {
+// Object object = ((IStructuredSelection) selection).getFirstElement();
+// if (object instanceof NotificationEvent) {
+// final NotificationEvent event = (NotificationEvent) object;
+// getControl().getDisplay().asyncExec(new Runnable() {
+// public void run() {
+// Notifications.getService().notify(
+// Collections.singletonList(new TestNotification(event)));
+// }
+// });
+// }
+// }
+// }
+//
+// });
+
+ reset();
+ Dialog.applyDialogFont(composite);
+ return composite;
+ }
+
+ @Override
+ public void applyData(Object data) {
+ // We may or may not have a NotificationEvent supplied when this
+ // preference dialog is opened. If we do have this data we want to
+ // highlight the appropriate instance.
+ if (data instanceof String) {
+ String selectedEventId = (String) data;
+ Collection<NotificationCategory> items = model.getCategories();
+ NotificationEvent selectedEvent = null;
+ for (NotificationCategory notificationCategory : items) {
+ List<NotificationEvent> event = notificationCategory.getEvents();
+ for (NotificationEvent notificationEvent : event) {
+ if (notificationEvent.getId().equals(selectedEventId)) {
+ selectedEvent = notificationEvent;
+ break;
+ }
+ }
+ }
+ if (selectedEvent != null) {
+ eventsViewer.setSelection(new StructuredSelection(selectedEvent), true);
+ }
+ }
+ }
+
+ private void updateEnablement() {
+ boolean enabled = enableNotificationsButton.getSelection();
+ eventsViewer.getControl().setEnabled(enabled);
+ notifiersViewer.getControl().setEnabled(enabled);// FIXME enabled && notifiersViewer.getInput() != null);
+ descriptionText.setEnabled(enabled);
+ if (!enabled) {
+ eventsViewer.setSelection(StructuredSelection.EMPTY);
+ }
+ }
+
+ public void init(IWorkbench workbench) {
+ // ignore
+ }
+
+ public void reset() {
+ enableNotificationsButton.setSelection(getPreferenceStore().getBoolean(
+ NotificationsPlugin.PREF_NOTICATIONS_ENABLED));
+ updateEnablement();
+ }
+
+ @Override
+ public boolean performOk() {
+ getPreferenceStore().setValue(NotificationsPlugin.PREF_NOTICATIONS_ENABLED,
+ enableNotificationsButton.getSelection());
+ if (model.isDirty()) {
+ NotificationsPlugin.getDefault().saveWorkingCopy(model);
+ model.setDirty(false);
+ }
+ return super.performOk();
+ }
+
+ @Override
+ protected void performDefaults() {
+ enableNotificationsButton.setSelection(getPreferenceStore().getDefaultBoolean(
+ NotificationsPlugin.PREF_NOTICATIONS_ENABLED));
+ for (NotificationCategory category : model.getCategories()) {
+ for (NotificationEvent event : category.getEvents()) {
+ NotificationHandler handler = model.getOrCreateNotificationHandler(event);
+ for (NotificationAction action : handler.getActions()) {
+ action.setSelected(event.defaultHandledBySink(action.getSinkDescriptor().getId()));
+ }
+ }
+ }
+ // assume that the model has become dirty
+ model.setDirty(true);
+ // refresh UI
+ eventsViewer.refresh();
+ notifiersViewer.refresh();
+ updateEnablement();
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/messages.properties b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/messages.properties
new file mode 100644
index 00000000..1b85c3c2
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/messages.properties
@@ -0,0 +1,4 @@
+NotificationsPreferencesPage_Descriptions_Label=Description
+NotificationsPreferencesPage_Enable_Notifications_Text=&Enable notifications
+NotificationsPreferencesPage_Events_Label=Events:
+NotificationsPreferencesPage_Notifiers_Label=Notifiers:
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/Messages.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/Messages.java
new file mode 100644
index 00000000..5b8aa47d
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/Messages.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui.popup;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.mylyn.internal.commons.ui.notifications.popup.messages"; //$NON-NLS-1$
+
+ public static String PopupNotificationSink_Popup_Noifier_Job_Label;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/NotificationPopup.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/NotificationPopup.java
new file mode 100644
index 00000000..4c1f6e32
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/NotificationPopup.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui.popup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.action.LegacyActionTools;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.mylyn.commons.notifications.core.AbstractNotification;
+import org.eclipse.mylyn.commons.notifications.ui.AbstractUiNotification;
+import org.eclipse.mylyn.commons.ui.CommonUiUtil;
+import org.eclipse.mylyn.commons.ui.compatibility.CommonColors;
+import org.eclipse.mylyn.commons.workbench.AbstractWorkbenchNotificationPopup;
+import org.eclipse.mylyn.commons.workbench.forms.CommonFormUtil;
+import org.eclipse.mylyn.commons.workbench.forms.ScalingHyperlink;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+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;
+
+/**
+ * @author Rob Elves
+ * @author Mik Kersten
+ */
+public class NotificationPopup extends AbstractWorkbenchNotificationPopup {
+
+ private static final int NUM_NOTIFICATIONS_TO_DISPLAY = 4;
+
+ private List<AbstractNotification> notifications;
+
+ public NotificationPopup(Shell parent) {
+ super(parent.getDisplay());
+ }
+
+ @Override
+ protected void createContentArea(Composite parent) {
+ int count = 0;
+ for (final AbstractNotification notification : notifications) {
+ Composite notificationComposite = new Composite(parent, SWT.NO_FOCUS);
+ GridLayout gridLayout = new GridLayout(2, false);
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(notificationComposite);
+ notificationComposite.setLayout(gridLayout);
+ notificationComposite.setBackground(parent.getBackground());
+
+ if (count < NUM_NOTIFICATIONS_TO_DISPLAY) {
+ final Label notificationLabelIcon = new Label(notificationComposite, SWT.NO_FOCUS);
+ notificationLabelIcon.setBackground(parent.getBackground());
+ if (notification instanceof AbstractUiNotification) {
+ notificationLabelIcon.setImage(((AbstractUiNotification) notification).getNotificationKindImage());
+ }
+ // FIXME
+// if (!(notification instanceof TaskListNotificationReminder)) {
+// final AbstractTask task = (AbstractTask) notification.getAdapter(AbstractTask.class);
+// if (task != null) {
+// notificationLabelIcon.addMouseListener(new MouseAdapter() {
+// @Override
+// public void mouseUp(MouseEvent e) {
+// TasksUiPlugin.getTaskDataManager().setTaskRead(task, true);
+// notificationLabelIcon.setImage(null);
+// notificationLabelIcon.setToolTipText(null);
+// }
+// });
+// notificationLabelIcon.setToolTipText(Messages.TaskListNotificationPopup_Mark_Task_Read);
+// }
+// }
+
+ // FIXME
+// final TaskScalingHyperlink itemLink = new TaskScalingHyperlink(notificationComposite, SWT.BEGINNING
+// | SWT.NO_FOCUS);
+
+ final ScalingHyperlink itemLink = new ScalingHyperlink(notificationComposite, SWT.BEGINNING
+ | SWT.NO_FOCUS);
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.TOP).applyTo(itemLink);
+ itemLink.setForeground(CommonColors.HYPERLINK_WIDGET);
+ itemLink.registerMouseTrackListener();
+ itemLink.setText(CommonUiUtil.toLabel(notification.getLabel()));
+ if (notification instanceof AbstractUiNotification) {
+ itemLink.setImage(((AbstractUiNotification) notification).getNotificationImage());
+ }
+ itemLink.setBackground(parent.getBackground());
+ itemLink.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(HyperlinkEvent e) {
+ if (notification instanceof AbstractUiNotification) {
+ ((AbstractUiNotification) notification).open();
+ }
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) {
+ Shell windowShell = window.getShell();
+ if (windowShell != null) {
+ if (windowShell.getMinimized()) {
+ windowShell.setMinimized(false);
+ }
+
+ windowShell.open();
+ windowShell.forceActive();
+ }
+ }
+ }
+ });
+
+ String descriptionText = null;
+ if (notification.getDescription() != null) {
+ descriptionText = notification.getDescription();
+ }
+ if (descriptionText != null && !descriptionText.trim().equals("")) { //$NON-NLS-1$
+ Label descriptionLabel = new Label(notificationComposite, SWT.NO_FOCUS);
+ descriptionLabel.setText(LegacyActionTools.escapeMnemonics(descriptionText));
+ descriptionLabel.setBackground(parent.getBackground());
+ GridDataFactory.fillDefaults()
+ .span(2, SWT.DEFAULT)
+ .grab(true, false)
+ .align(SWT.FILL, SWT.TOP)
+ .applyTo(descriptionLabel);
+ }
+ } else {
+ int numNotificationsRemain = notifications.size() - count;
+ ScalingHyperlink remainingLink = new ScalingHyperlink(notificationComposite, SWT.NO_FOCUS);
+ remainingLink.setForeground(CommonColors.HYPERLINK_WIDGET);
+ remainingLink.registerMouseTrackListener();
+ remainingLink.setBackground(parent.getBackground());
+
+ remainingLink.setText(NLS.bind("{0} more", numNotificationsRemain)); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(remainingLink);
+ remainingLink.addHyperlinkListener(new HyperlinkAdapter() {
+ @Override
+ public void linkActivated(HyperlinkEvent e) {
+ // FIXME
+ // TasksUiUtil.openTasksViewInActivePerspective().setFocus();
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) {
+ Shell windowShell = window.getShell();
+ if (windowShell != null) {
+ windowShell.setMaximized(true);
+ windowShell.open();
+ }
+ }
+ }
+ });
+ break;
+ }
+ count++;
+ }
+ }
+
+ @Override
+ protected void createTitleArea(Composite parent) {
+ super.createTitleArea(parent);
+ }
+
+ public List<AbstractNotification> getNotifications() {
+ return new ArrayList<AbstractNotification>(notifications);
+ }
+
+ @Override
+ protected Color getTitleForeground() {
+ return CommonFormUtil.getSharedColors().getColor(IFormColors.TITLE);
+
+ }
+
+ public void setContents(List<AbstractNotification> notifications) {
+ this.notifications = notifications;
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/PopupNotificationSink.java b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/PopupNotificationSink.java
new file mode 100644
index 00000000..e1835740
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/PopupNotificationSink.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2010 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.commons.notifications.ui.popup;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.window.Window;
+import org.eclipse.mylyn.commons.notifications.core.AbstractNotification;
+import org.eclipse.mylyn.commons.notifications.core.NotificationSink;
+import org.eclipse.mylyn.commons.notifications.core.NotificationSinkEvent;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPreferenceConstants;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author Rob Elves
+ * @author Steffen Pingel
+ */
+public class PopupNotificationSink extends NotificationSink {
+
+ private static final long DELAY_OPEN = 1 * 1000;
+
+ private static final boolean runSystem = true;
+
+ private final WeakHashMap<Object, Object> cancelledTokens = new WeakHashMap<Object, Object>();
+
+ private final Set<AbstractNotification> notifications = new HashSet<AbstractNotification>();
+
+ private final Set<AbstractNotification> currentlyNotifying = Collections.synchronizedSet(notifications);
+
+ private final Job openJob = new Job(Messages.PopupNotificationSink_Popup_Noifier_Job_Label) {
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ if (Platform.isRunning() && PlatformUI.getWorkbench() != null
+ && PlatformUI.getWorkbench().getDisplay() != null
+ && !PlatformUI.getWorkbench().getDisplay().isDisposed()) {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+
+ public void run() {
+ collectNotifications();
+
+ if (popup != null && popup.getReturnCode() == Window.CANCEL) {
+ List<AbstractNotification> notifications = popup.getNotifications();
+ for (AbstractNotification notification : notifications) {
+ if (notification.getToken() != null) {
+ cancelledTokens.put(notification.getToken(), null);
+ }
+ }
+ }
+
+ for (Iterator<AbstractNotification> it = currentlyNotifying.iterator(); it.hasNext();) {
+ AbstractNotification notification = it.next();
+ if (notification.getToken() != null
+ && cancelledTokens.containsKey(notification.getToken())) {
+ it.remove();
+ }
+ }
+
+ synchronized (PopupNotificationSink.class) {
+ if (currentlyNotifying.size() > 0) {
+// popup.close();
+ showPopup();
+ }
+ }
+ }
+ });
+ }
+ } finally {
+ if (popup != null) {
+ schedule(popup.getDelayClose() / 2);
+ }
+ }
+
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ };
+
+ private NotificationPopup popup;
+
+ public PopupNotificationSink() {
+ }
+
+ private void cleanNotified() {
+ currentlyNotifying.clear();
+ }
+
+ /** public for testing */
+ public void collectNotifications() {
+ }
+
+ /**
+ * public for testing purposes
+ */
+ public Set<AbstractNotification> getNotifications() {
+ synchronized (PopupNotificationSink.class) {
+ return currentlyNotifying;
+ }
+ }
+
+ public boolean isAnimationsEnabled() {
+ IPreferenceStore store = PlatformUI.getPreferenceStore();
+ return store.getBoolean(IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS);
+ }
+
+ @Override
+ public void notify(NotificationSinkEvent event) {
+ currentlyNotifying.addAll(event.getNotifications());
+
+ if (!openJob.cancel()) {
+ try {
+ openJob.join();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ openJob.setSystem(runSystem);
+ openJob.schedule(DELAY_OPEN);
+ }
+
+ public void showPopup() {
+ if (popup != null) {
+ popup.close();
+ }
+
+ Shell shell = new Shell(PlatformUI.getWorkbench().getDisplay());
+ popup = new NotificationPopup(shell);
+ popup.setFadingEnabled(isAnimationsEnabled());
+ List<AbstractNotification> toDisplay = new ArrayList<AbstractNotification>(currentlyNotifying);
+ Collections.sort(toDisplay);
+ popup.setContents(toDisplay);
+ cleanNotified();
+ popup.setBlockOnOpen(false);
+ popup.open();
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/messages.properties b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/messages.properties
new file mode 100644
index 00000000..5ac2c060
--- /dev/null
+++ b/org.eclipse.mylyn.commons.notifications.ui/src/org/eclipse/mylyn/internal/commons/notifications/ui/popup/messages.properties
@@ -0,0 +1 @@
+PopupNotificationSink_Popup_Noifier_Job_Label=Popup Notifier

Back to the top