Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Aeschlimann2006-01-29 22:11:47 +0000
committerMartin Aeschlimann2006-01-29 22:11:47 +0000
commite1b034b769699f23e8dc54b36123c2d6d85c9fd9 (patch)
treeb8bd0055685d1eef7300d7685ed09ce054849a2a /org.eclipse.search
parent5f4eb5798f495065281cd1291605621f3d7f6cdf (diff)
downloadeclipse.platform.text-e1b034b769699f23e8dc54b36123c2d6d85c9fd9.tar.gz
eclipse.platform.text-e1b034b769699f23e8dc54b36123c2d6d85c9fd9.tar.xz
eclipse.platform.text-e1b034b769699f23e8dc54b36123c2d6d85c9fd9.zip
118200 Proposal for a new TextSearch UI
Diffstat (limited to 'org.eclipse.search')
-rw-r--r--org.eclipse.search/.settings/org.eclipse.jdt.core.prefs246
-rw-r--r--org.eclipse.search/.settings/org.eclipse.jdt.ui.prefs6
-rw-r--r--org.eclipse.search/META-INF/MANIFEST.MF7
-rw-r--r--org.eclipse.search/icons/full/dlcl16/filter_ps.gifbin0 -> 112 bytes
-rw-r--r--org.eclipse.search/icons/full/elcl16/filter_ps.gifbin0 -> 219 bytes
-rw-r--r--org.eclipse.search/icons/full/obj16/line_match.gifbin0 -> 372 bytes
-rw-r--r--org.eclipse.search/new search/org/eclipse/search/core/text/AbstractTextFileScanner.java213
-rw-r--r--org.eclipse.search/new search/org/eclipse/search/core/text/TextSearchEngine.java35
-rw-r--r--org.eclipse.search/new search/org/eclipse/search/ui/actions/TextSearchGroup.java90
-rw-r--r--org.eclipse.search/new search/org/eclipse/search/ui/text/AbstractTextSearchViewPage.java38
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/SearchMessages.java94
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/SearchMessages.properties84
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/CurrentFileScopeDescription.java59
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/CurrentProjectScopeDescription.java68
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/EditorDescriptorLabelProvider.java71
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FilePatternSelectionDialog.java333
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FilterMatchEvent.java30
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInFileActionDelegate.java30
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInProjectActionDelegate.java29
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInRecentScopeActionDelegate.java88
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInWorkingSetActionDelegate.java37
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInWorkspaceActionDelegate.java29
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/IRetrieverKeys.java66
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/IScopeDescription.java39
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/JavaScanner.java219
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/LineNumberScanner.java48
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/ReplaceAction.java553
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverAction.java195
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverContentProvider.java302
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFilter.java80
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFilterTab.java428
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFindTab.java429
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverLabelProvider.java88
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverLine.java282
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverMatch.java80
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverPage.java1031
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverQuery.java330
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverReplaceTab.java470
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverResult.java292
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverSearchScope.java155
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverTreeViewer.java37
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverViewerSorter.java90
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/TextFileScannerRegistry.java303
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WindowWorkingSetScopeDescription.java45
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WorkingSetScopeDescription.java173
-rw-r--r--org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WorkspaceScopeDescription.java50
-rw-r--r--org.eclipse.search/plugin.properties29
-rw-r--r--org.eclipse.search/plugin.xml123
-rw-r--r--org.eclipse.search/schema/textFileScanner.exsd162
-rw-r--r--org.eclipse.search/schema/textSearchEngine.exsd134
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/core/text/FileNamePatternSearchScope.java2
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/core/text/FilesOfScopeCalculator.java (renamed from org.eclipse.search/search/org/eclipse/search/internal/core/text/AmountOfWorkCalculator.java)49
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/core/text/PatternConstructor.java191
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchEngineRegistry.java111
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchVisitor.java103
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.java2
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.properties2
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPlugin.java14
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPluginImages.java6
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPreferencePage.java16
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/text/EditorOpener.java21
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchPage.java2
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchQuery.java2
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/text/NewTextSearchActionGroup.java2
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceDialog2.java2
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/text/SearchResultUpdater.java10
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchPage.java217
-rw-r--r--org.eclipse.search/search/org/eclipse/search/internal/ui/util/ComboFieldEditor.java3
68 files changed, 8329 insertions, 246 deletions
diff --git a/org.eclipse.search/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.search/.settings/org.eclipse.jdt.core.prefs
index 9c05f6773d2..7bb8267ac19 100644
--- a/org.eclipse.search/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.search/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,4 @@
-#Sun Oct 09 00:33:35 CEST 2005
+#Sun Jan 29 20:07:41 CET 2006
eclipse.preferences.version=1
org.eclipse.jdt.core.builder.cleanOutputFolder=clean
org.eclipse.jdt.core.builder.duplicateResourceTask=warning
@@ -66,5 +66,249 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.3
+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_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=20
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16
+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_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=18
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=66
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=0
+org.eclipse.jdt.core.formatter.blank_lines_after_package=0
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=0
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=0
+org.eclipse.jdt.core.formatter.blank_lines_before_method=0
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=0
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=0
+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=false
+org.eclipse.jdt.core.formatter.comment.format_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_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=999
+org.eclipse.jdt.core.formatter.compact_else_if=false
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+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=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_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_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=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=do not 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=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_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=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=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.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=999
+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=2
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.incompatibleJDKLevel=ignore
org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/org.eclipse.search/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.search/.settings/org.eclipse.jdt.ui.prefs
index be033ab315d..06084349bb2 100644
--- a/org.eclipse.search/.settings/org.eclipse.jdt.ui.prefs
+++ b/org.eclipse.search/.settings/org.eclipse.jdt.ui.prefs
@@ -1,5 +1,7 @@
-#Tue Dec 21 12:50:24 CET 2004
+#Sun Jan 29 19:31:13 CET 2006
eclipse.preferences.version=1
-org.eclipse.jdt.ui.ondemandthreshold=99
+formatter_profile=_Search Code Style Conventions
+formatter_settings_version=9
org.eclipse.jdt.ui.ignorelowercasenames=true
org.eclipse.jdt.ui.importorder=java;javax;org.eclipse.core;org.eclipse.core.runtime;org.eclipse.core.resources;org.eclipse.swt;org.eclipse.jface;org.eclipse.jface.text;org.eclipse.ui;org.eclipse.ui.editors;org.eclipse.ui.workbench;org.eclipse.ui.workbench.texteditor;org.eclipseui.ide;org.eclipse.search.ui;org.eclipse.search.internal;org.eclipse.search2.internal;
+org.eclipse.jdt.ui.ondemandthreshold=99
diff --git a/org.eclipse.search/META-INF/MANIFEST.MF b/org.eclipse.search/META-INF/MANIFEST.MF
index 52c51c684ba..3d0c433807d 100644
--- a/org.eclipse.search/META-INF/MANIFEST.MF
+++ b/org.eclipse.search/META-INF/MANIFEST.MF
@@ -12,15 +12,18 @@ Export-Package: org.eclipse.search.core.text,
org.eclipse.search.internal.ui.text;x-internal:=true,
org.eclipse.search.internal.ui.util;x-internal:=true,
org.eclipse.search.ui,
+ org.eclipse.search.ui.actions,
org.eclipse.search.ui.text,
org.eclipse.search2.internal.ui;x-internal:=true,
org.eclipse.search2.internal.ui.basic.views;x-internal:=true,
- org.eclipse.search2.internal.ui.text;x-internal:=true
+ org.eclipse.search2.internal.ui.text;x-internal:=true,
+ org.eclipse.search2.internal.ui.text2;x-internal:=true
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.ui,
org.eclipse.ui.ide,
org.eclipse.ui.workbench.texteditor,
org.eclipse.jface.text,
- org.eclipse.ui.editors
+ org.eclipse.ui.editors,
+ org.eclipse.ui.forms
Eclipse-LazyStart: true
diff --git a/org.eclipse.search/icons/full/dlcl16/filter_ps.gif b/org.eclipse.search/icons/full/dlcl16/filter_ps.gif
new file mode 100644
index 00000000000..ba6d891495f
--- /dev/null
+++ b/org.eclipse.search/icons/full/dlcl16/filter_ps.gif
Binary files differ
diff --git a/org.eclipse.search/icons/full/elcl16/filter_ps.gif b/org.eclipse.search/icons/full/elcl16/filter_ps.gif
new file mode 100644
index 00000000000..6fe6f0e10a1
--- /dev/null
+++ b/org.eclipse.search/icons/full/elcl16/filter_ps.gif
Binary files differ
diff --git a/org.eclipse.search/icons/full/obj16/line_match.gif b/org.eclipse.search/icons/full/obj16/line_match.gif
new file mode 100644
index 00000000000..cf62b63ae3e
--- /dev/null
+++ b/org.eclipse.search/icons/full/obj16/line_match.gif
Binary files differ
diff --git a/org.eclipse.search/new search/org/eclipse/search/core/text/AbstractTextFileScanner.java b/org.eclipse.search/new search/org/eclipse/search/core/text/AbstractTextFileScanner.java
new file mode 100644
index 00000000000..24b82f3ca7c
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search/core/text/AbstractTextFileScanner.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search.core.text;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * Abstract base class for scanners supplied via the
+ * org.eclipse.search.textFileScanner extension point.
+ * It suffices to implement the scanFile() method.
+ */
+public abstract class AbstractTextFileScanner {
+ public final static int LOCATION_OTHER= 0;
+ public final static int LOCATION_STRING_LITERAL= 1;
+ public final static int LOCATION_COMMENT= 2;
+ public final static int LOCATION_IMPORT_OR_INCLUDE_STATEMENT= 3;
+ public final static int LOCATION_PREPROCESSOR_DIRECTIVE= 4;
+ public final static int LOCATION_FUNCTION= 5;
+
+ /**
+ * LocationInfo objects are used to report information about matches.
+ */
+ public final static class LineInformation {
+ private int fLineNumber;
+ private int fLineOffset;
+ private int fLineLength;
+
+ public LineInformation(int lineNumber, int lineOffset, int lineLength) {
+ fLineNumber= lineNumber;
+ fLineOffset= lineOffset;
+ fLineLength= lineLength;
+ }
+
+ /**
+ * @return the line number where the match starts in.
+ */
+ public int getLineNumber() {
+ return fLineNumber;
+ }
+
+ /**
+ * Returns the total length of the lines containing the match. This also includes
+ * the characters of the line terminator.
+ * @return the length of the lines containing the match.
+ * */
+ public int getLineLength() {
+ return fLineLength;
+ }
+
+ /**
+ * The character offset of the beginning of the line where the match starts.
+ * */
+ public int getLineOffset() {
+ return fLineOffset;
+ }
+ }
+
+ private static class Location {
+ public Location(int offset, int length, int kind) {
+ fOffset= offset;
+ fLength= length;
+ fKind= kind;
+ }
+ private int fOffset;
+ private int fLength;
+ private int fKind;
+ }
+
+ private ArrayList fLocations= new ArrayList();
+ private int[] fLineOffsets= null;
+ private int fLineCount;
+ private IFile fFile;
+ private int fFileLength;
+
+ /**
+ * Clears any data cached by the scanner.
+ * Implementors may override this method but must call super.reset();
+ */
+ public void reset() {
+ fFile= null;
+ fLocations.clear();
+ fLineOffsets= null;
+ fLineCount= 0;
+ }
+
+ /**
+ * Called whenever information about a new file is requested. Implementors must
+ * scan the file and report lines and locations with addLineOffset() and addLocation().
+ * @param matchAccess provides access to the file to be scanned.
+ */
+ abstract protected void scanFile(TextSearchMatchAccess matchAccess);
+
+ private void checkScanFile(TextSearchMatchAccess match) {
+ if (!match.getFile().equals(fFile)) {
+ reset();
+ scanFile(match);
+
+ // trim line count
+ if (fLineCount != 0) {
+ int[] offsets= new int[fLineCount];
+ System.arraycopy(fLineOffsets, 0, offsets, 0, fLineCount);
+ fLineOffsets= offsets;
+ }
+ fFile= match.getFile();
+ fFileLength= match.getFileContentLength();
+ }
+ }
+
+ /**
+ * Adds the offset of another line to the list of offsets.
+ * Call this method for every line when scanning a file. The first offset that has to
+ * be reported is always 0.
+ */
+ final protected void addLineOffset(int offset) {
+ if (fLineCount == 0) {
+ fLineOffsets= new int[1024];
+ } else
+ if (fLineCount == fLineOffsets.length) {
+ int[] newOffsets= new int[fLineOffsets.length * 2];
+ System.arraycopy(fLineOffsets, 0, newOffsets, 0, fLineCount);
+ fLineOffsets= newOffsets;
+ }
+ fLineOffsets[fLineCount++]= offset;
+ }
+
+ /**
+ * Adds the location to the list of offsets.
+ * Call this method for every location when scanning a file.
+ */
+ final protected void addLocation(int offset, int length, int kind) {
+ fLocations.add(new Location(offset, length, kind));
+ }
+
+ /**
+ * Returns information about the lines containing the match provided.
+ * @param match access to the match.
+ * @return information about the provided match.
+ */
+ public LineInformation getLineInformation(TextSearchMatchAccess match) {
+ // check if we need to scan another file
+ checkScanFile(match);
+ return getLineInformation(match.getMatchOffset(), match.getMatchLength());
+ }
+
+ private LineInformation getLineInformation(int offset, int length) {
+ if (fLineOffsets != null) {
+ final int lineIdx= getLineIndexForOffset(offset);
+ final int lineOffset= fLineOffsets[lineIdx];
+
+ int endLineIdx= getLineIndexForOffset(offset + length - 1);
+ int lineLength;
+ if (endLineIdx < fLineOffsets.length - 1) {
+ lineLength= fLineOffsets[endLineIdx + 1] - lineOffset;
+ } else {
+ lineLength= fFileLength - lineOffset;
+ }
+ return new LineInformation(lineIdx + 1, lineOffset, lineLength);
+ }
+ return new LineInformation(0, 0, 0);
+ }
+
+ private int getLineIndexForOffset(int offset) {
+ int lineIdx= Arrays.binarySearch(fLineOffsets, offset);
+ if (lineIdx < 0) {
+ lineIdx= Math.max(0, -lineIdx - 2);
+ }
+ return lineIdx;
+ }
+
+ /**
+ * Returns the kind of location the given match starts in.
+ * @param match access to the match.
+ * @return one of LOCATION_...
+ */
+ public int getLocationKind(TextSearchMatchAccess match) {
+ checkScanFile(match);
+ return getLocationKind(match.getMatchOffset());
+ }
+
+ private int getLocationKind(int offset) {
+ int low= 0;
+ int high= fLocations.size() - 1;
+
+ while (low <= high) {
+ int mid= (low + high) / 2;
+ Location loc= (Location) fLocations.get(mid);
+ int locOffset= loc.fOffset;
+ if (offset >= locOffset) {
+ if (offset < locOffset + loc.fLength) {
+ return loc.fKind;
+ }
+ // offset is larger
+ low= mid + 1;
+ } else {
+ // offset is smaller
+ high= mid - 1;
+ }
+ }
+ return 0;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search/core/text/TextSearchEngine.java b/org.eclipse.search/new search/org/eclipse/search/core/text/TextSearchEngine.java
index 66ecd561062..4c10b7890b5 100644
--- a/org.eclipse.search/new search/org/eclipse/search/core/text/TextSearchEngine.java
+++ b/org.eclipse.search/new search/org/eclipse/search/core/text/TextSearchEngine.java
@@ -11,13 +11,14 @@
package org.eclipse.search.core.text;
+import java.util.Comparator;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
-
import org.eclipse.search.internal.core.text.TextSearchVisitor;
+import org.eclipse.search.internal.ui.SearchPlugin;
/**
* A {@link TextSearchEngine} searches the content of a workspace file resources
@@ -37,8 +38,7 @@ public abstract class TextSearchEngine {
* @return the created {@link TextSearchEngine}.
*/
public static TextSearchEngine create() {
- // TODO: An future extension point will allow to contribute a new text search engine
- return createDefault();
+ return SearchPlugin.getDefault().getTextSearchEngineRegistry().getPreferred();
}
/**
@@ -50,10 +50,12 @@ public abstract class TextSearchEngine {
public static TextSearchEngine createDefault() {
return new TextSearchEngine() {
public IStatus search(TextSearchScope scope, TextSearchRequestor requestor, Pattern searchPattern, IProgressMonitor monitor) {
- return TextSearchVisitor.search(scope, requestor, searchPattern, monitor);
+ return new TextSearchVisitor(requestor, searchPattern, monitor).search(scope, getSearchOrderHint());
}
};
}
+
+ private Comparator fSearchOrderHint;
/**
* Uses a given search pattern to find matches in the content of a workspace file resource. If the file is open in an editor, the
@@ -66,5 +68,28 @@ public abstract class TextSearchEngine {
* @return the status containing information about problems in resources searched.
*/
public abstract IStatus search(TextSearchScope scope, TextSearchRequestor requestor, Pattern searchPattern, IProgressMonitor monitor);
-
+
+ /**
+ * Sets a comparator to be used by the search engine to order the files before searching them.
+ * The passed comparator will be used with instances of type {@link org.eclipse.core.resources.IFile}.
+ * The comparator on serves as a hint: The search engine is free to ignore the comparator and
+ * search the files in any order.
+ *
+ * @param comparator a comparator that is capable of comparing instances of type {@link org.eclipse.core.resources.IFile}
+ * or <code>null</code> not not provide a hint for the search order.
+ */
+ public void setSearchOrderHint(Comparator comparator) {
+ fSearchOrderHint= comparator;
+ }
+
+ /**
+ * Returns the comparator provided to give a hint of the order the search result should be provided. <code>null</code>
+ * is returned if no such order has been configured with {@link #setSearchOrderHint(Comparator)}.
+ *
+ * @return the comparator that can be used to order the files before searching, or
+ * <code>null</code> if no order hint has been configured.
+ */
+ protected Comparator getSearchOrderHint() {
+ return fSearchOrderHint;
+ }
}
diff --git a/org.eclipse.search/new search/org/eclipse/search/ui/actions/TextSearchGroup.java b/org.eclipse.search/new search/org/eclipse/search/ui/actions/TextSearchGroup.java
new file mode 100644
index 00000000000..79bec523702
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search/ui/actions/TextSearchGroup.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search.ui.actions;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+
+import org.eclipse.search.ui.IContextMenuConstants;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+import org.eclipse.search2.internal.ui.text2.FindInFileActionDelegate;
+import org.eclipse.search2.internal.ui.text2.FindInProjectActionDelegate;
+import org.eclipse.search2.internal.ui.text2.FindInRecentScopeActionDelegate;
+import org.eclipse.search2.internal.ui.text2.FindInWorkingSetActionDelegate;
+import org.eclipse.search2.internal.ui.text2.FindInWorkspaceActionDelegate;
+
+/**
+ * Action group that adds a sub-menu with text search actions to a context menu.
+ * to a context menu.
+ *
+ * @since 3.2
+ */
+public class TextSearchGroup extends ActionGroup {
+ private String fAppendToGroup= ITextEditorActionConstants.GROUP_FIND;
+ private String fMenuText= SearchMessages.TextSearchGroup_submenu_text;
+
+ private FindInRecentScopeActionDelegate[] fActions;
+
+ /**
+ * Constructs a TextSearchGroup for adding actions to the context menu
+ * of the editor provided. The editor will be accessed for the purpose of
+ * determining the search string.
+ */
+ public TextSearchGroup(IEditorPart editor) {
+ createActions(editor);
+ }
+
+ /**
+ * Changes the text that is used for the submenu. The default is
+ * "Find Text".
+ */
+ public void setMenuText(String text) {
+ fMenuText= text;
+ }
+
+ /**
+ * Changes the group where the submenu is appended to. The default is
+ * ITextEditorActionConstants.GROUP_FIND.
+ */
+ public void setAppendToGroup(String groupID) {
+ fAppendToGroup= groupID;
+ }
+
+ private void createActions(IEditorPart editor) {
+ fActions= new FindInRecentScopeActionDelegate[] {new FindInRecentScopeActionDelegate(), new FindInWorkspaceActionDelegate(), new FindInProjectActionDelegate(), new FindInFileActionDelegate(), new FindInWorkingSetActionDelegate()};
+ for (int i= 0; i < fActions.length; i++) {
+ FindInRecentScopeActionDelegate action= fActions[i];
+ action.setActiveEditor(action, editor);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.actions.ActionGroup#fillContextMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ public void fillContextMenu(IMenuManager menu) {
+ MenuManager textSearchMM= new MenuManager(fMenuText, IContextMenuConstants.GROUP_SEARCH);
+ textSearchMM.add(fActions[0]);
+ textSearchMM.add(new Separator());
+ for (int i= 1; i < fActions.length; i++) {
+ textSearchMM.add(fActions[i]);
+ }
+
+ menu.appendToGroup(fAppendToGroup, textSearchMM);
+ }
+
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search/ui/text/AbstractTextSearchViewPage.java b/org.eclipse.search/new search/org/eclipse/search/ui/text/AbstractTextSearchViewPage.java
index e14796a4141..2b5831259b7 100644
--- a/org.eclipse.search/new search/org/eclipse/search/ui/text/AbstractTextSearchViewPage.java
+++ b/org.eclipse.search/new search/org/eclipse/search/ui/text/AbstractTextSearchViewPage.java
@@ -135,6 +135,14 @@ public abstract class AbstractTextSearchViewPage extends Page implements ISearch
} else {
fIsUIUpdateScheduled= false;
turnOnDecoration();
+ updateBusyLabel();
+ if (fScheduleEnsureSelection) {
+ fScheduleEnsureSelection= false;
+ AbstractTextSearchResult result = getInput();
+ if (result != null && fViewer.getSelection().isEmpty()) {
+ navigateNext(true);
+ }
+ }
}
fViewPart.updateLabel();
return Status.OK_STATUS;
@@ -179,7 +187,8 @@ public abstract class AbstractTextSearchViewPage extends Page implements ISearch
}
- private transient boolean fIsUIUpdateScheduled= false;
+ private volatile boolean fIsUIUpdateScheduled= false;
+ private volatile boolean fScheduleEnsureSelection= false;
private static final String KEY_LAYOUT = "org.eclipse.search.resultpage.layout"; //$NON-NLS-1$
/**
@@ -516,25 +525,19 @@ public abstract class AbstractTextSearchViewPage extends Page implements ISearch
}
public void queryFinished(final ISearchQuery query) {
- final Runnable runnable2 = new Runnable() {
- public void run() {
- updateBusyLabel();
- AbstractTextSearchResult result = getInput();
-
- if (result == null || !result.getQuery().equals(query)) {
- return;
- }
-
- if (fViewer.getSelection().isEmpty()) {
- navigateNext(true);
- }
- }
- };
- asyncExec(runnable2);
+ // handle the end of the query in the UIUpdateJob, as ui updates
+ // may not be finished here.
+ postEnsureSelection();
}
};
}
+ protected void postEnsureSelection() {
+ fScheduleEnsureSelection= true;
+ scheduleUIUpdate();
+ }
+
+
private void updateBusyLabel() {
AbstractTextSearchResult result = getInput();
boolean shouldShowBusy = result != null && NewSearchUI.isQueryRunning(result.getQuery()) && result.getMatchCount() == 0;
@@ -812,10 +815,11 @@ public abstract class AbstractTextSearchViewPage extends Page implements ISearch
Match nextMatch = getCurrentMatch();
if (nextMatch == null) {
navigateNext(false);
- fCurrentMatchIndex = getInput().getMatchCount(getFirstSelectedElement()) - 1;
+ fCurrentMatchIndex = getDisplayedMatchCount(getFirstSelectedElement()) - 1;
}
showCurrentMatch(activateEditor);
}
+
private void navigateNext(boolean forward) {
INavigate navigator = null;
if (fViewer instanceof TableViewer) {
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/SearchMessages.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/SearchMessages.java
index 6b6ca8e4e25..5dde62d0c44 100644
--- a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/SearchMessages.java
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/SearchMessages.java
@@ -19,6 +19,10 @@ public final class SearchMessages extends NLS {
private SearchMessages() {
// Do not instantiate
}
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, SearchMessages.class);
+ }
public static String AbstractTextSearchViewPage_update_job_name;
public static String RemoveSelectedMatchesAction_label;
@@ -79,14 +83,94 @@ public final class SearchMessages extends NLS {
public static String AnnotationHighlighter_error_badLocation;
public static String AnnotationHighlighter_error_noDocument;
public static String EditorAccessHighlighter_error_badLocation;
-
- static {
- NLS.initializeMessages(BUNDLE_NAME, SearchMessages.class);
- }
-
public static String SearchHistoryDropDownAction_showemptyview_title;
public static String SearchHistoryDropDownAction_showemptyview_tooltip;
public static String PinSearchViewAction_label;
public static String PinSearchViewAction_tooltip;
public static String SearchPageRegistry_error_creating_extensionpoint;
+ public static String RetrieverFindTab_search;
+ public static String RetrieverFindTab_caseSensitive;
+ public static String RetrieverFindTab_regularExpression;
+ public static String RetrieverFindTab_wholeWord;
+ public static String RetrieverFindTab_searchScope;
+ public static String RetrieverFindTab_choose;
+ public static String RetrieverFindTab_filePatterns;
+ public static String RetrieverFindTab_Error_emptySearchString;
+ public static String RetrieverFindTab_Error_invalidRegex;
+ public static String RetrieverFindTab_Question_regexMatchesEmptyString;
+ public static String RetrieverQuery_label;
+ public static String RetrieverResult_label;
+ public static String RetrieverResult_noInput_label;
+ public static String FilePatternSelectionDialog_title;
+ public static String FilePatternSelectionDialog_message;
+ public static String FilePatternSelectionDialog_selectAll;
+ public static String FilePatternSelectionDialog_deselectAll;
+ public static String WorkspaceScopeDescription_label;
+ public static String RetrieverFilterTab_LocationFilter_text;
+ public static String RetrieverFilterTab_Comment_text;
+ public static String RetrieverFilterTab_Import_text;
+ public static String RetrieverFilterTab_Preprocessor_text;
+ public static String RetrieverFilterTab_String_text;
+ public static String RetrieverFilterTab_OtherLocation_text;
+ public static String RetrieverFilterTab_TextFilter_text;
+ public static String RetrieverFilterTab_HideMatching_text;
+ public static String WindowWorkingSetScopeDescription_label;
+ public static String RetrieverReplaceTab_ReplaceWith_label;
+ public static String RetrieverReplaceTab_Find_text;
+ public static String RetrieverReplaceTab_ReplaceFind_text;
+ public static String RetrieverReplaceTab_RestoreFind_text;
+ public static String RetrieverReplaceTab_Replace_text;
+ public static String RetrieverReplaceTab_ReplaceAll_text;
+ public static String RetrieverReplaceTab_RestoreAll_text;
+ public static String RetrieverReplaceTab_Preview_label;
+ public static String RetrieverReplaceTab_Restore_text;
+ public static String RetrieverReplaceTab_ReplaceWith_text;
+ public static String RetrieverLabelProvider_FilterHidesMatches_label;
+ public static String RetrieverFilterTab_FunctionBody_text;
+ public static String RetrieverPage_FindTab_text;
+ public static String RetrieverPage_FilterTab_text;
+ public static String RetrieverPage_ReplaceTab_text;
+ public static String RetrieverPage_EnableFilter_text;
+ public static String RetrieverPage_EnableFilter_tooltip;
+ public static String RetrieverPage_LoadQuery_text;
+ public static String RetrieverPage_LoadQuery_tooltip;
+ public static String RetrieverPage_SaveQuery_text;
+ public static String RetrieverPage_SaveQuery_tooltip;
+ public static String RetrieverPage_CreateWorkingSet_text;
+ public static String RetrieverPage_CreateWorkingSet_tooltip;
+ public static String RetrieverPage_CaseSensitiveFilePatterns_text;
+ public static String RetrieverPage_error_noResourcesForWorkingSet;
+ public static String RetrieverPage_CreateWorkingsetDialog_title;
+ public static String RetrieverPage_CreateWorkingSetDialog_description;
+ public static String RetrieverPage_question_overwriteWorkingSet;
+ public static String RetrieverPage_error_cannotLoadQuery;
+ public static String RetrieverPage_error_cannotStoreQuery;
+ public static String RetrieverPage_ErrorDialog_title;
+ public static String RetrieverPage_QuestionDialog_title;
+ public static String RetrieverPage_InformationDialog_title;
+ public static String RetrieverPage_ConsiderDerived_text;
+ public static String ReplaceOperation_error_cannotLocateMatch;
+ public static String ReplaceOperation_error_operationFailed;
+ public static String ReplaceOperation_task_performChanges;
+ public static String ReplaceOperation_error_didNotSucceedForAllMatches;
+ public static String ReplaceOperation_error_multipleErrors;
+ public static String ReplaceOperation_error_whileRefreshing;
+ public static String ReplaceOperation_error_whileValidateEdit;
+ public static String ReplaceOperation_error_allFilesReadOnly;
+ public static String ReplaceOperation_question_continueWithReadOnly_singular;
+ public static String ReplaceOperation_question_continueWithReadOnly_plural;
+ public static String ReplaceOperation_error_cannotComputeReplacement;
+ public static String ReplaceOperation_error_cannotLocateMatchAt;
+ public static String RetrieverReplaceTab_ReplaceSelected_text;
+ public static String RetrieverReplaceTab_RestoreSelected_text;
+ public static String TextFileScannerRegistry_error_instanciateScanner;
+ public static String CurrentFileScopeDescription_label;
+ public static String CurrentProjectScopeDescription_label;
+ public static String TextSearchGroup_submenu_text;
+ public static String FindInWorkspaceActionDelegate_text;
+ public static String FindInRecentScopeActionDelegate_text;
+ public static String FindInProjectActionDelegate_text;
+ public static String FindInWorkingSetActionDelegate_text;
+ public static String FindInFileActionDelegate_text;
+
} \ No newline at end of file
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/SearchMessages.properties b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/SearchMessages.properties
index 94564d08dc3..a71f940061d 100644
--- a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/SearchMessages.properties
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/SearchMessages.properties
@@ -72,3 +72,87 @@ SearchHistoryDropDownAction_showemptyview_tooltip=Shows new {0} result
SearchPageRegistry_error_creating_extensionpoint=Search result page creation failed
PinSearchViewAction_label=Pi&n Search View
PinSearchViewAction_tooltip=Pi&n the Search View
+FilePatternSelectionDialog_deselectAll=Deselect All
+FilePatternSelectionDialog_message=Select patterns for the files to be searched:
+FindInWorkspaceActionDelegate_text=Workspace
+FindInWorkingSetActionDelegate_text=Working Set...
+FindInProjectActionDelegate_text=Project
+FindInFileActionDelegate_text=File
+FindInRecentScopeActionDelegate_text=Recent Scope
+FilePatternSelectionDialog_selectAll=Select All
+FilePatternSelectionDialog_title=Select File Patterns
+RetrieverFilterTab_Comment_text=Comment
+RetrieverFilterTab_FunctionBody_text=Function
+RetrieverFilterTab_HideMatching_text=Hide matching
+RetrieverFilterTab_Import_text=Import/Include
+RetrieverFilterTab_LocationFilter_text=Restrict by location:
+RetrieverFilterTab_OtherLocation_text=Any other
+RetrieverFilterTab_Preprocessor_text=Preprocessor
+RetrieverFilterTab_String_text=String
+RetrieverFilterTab_TextFilter_text=Text filter:
+RetrieverFindTab_caseSensitive=Case sensitive
+RetrieverFindTab_choose=Choose...
+RetrieverFindTab_Error_emptySearchString=Search string must not be empty.
+ReplaceOperation_error_cannotLocateMatch=The match cannot be located
+ReplaceOperation_error_whileValidateEdit=An error occurred while ensuring that files are writable
+RetrieverFindTab_Error_invalidRegex=Invalid regular expression:
+RetrieverFindTab_filePatterns=File patterns:
+RetrieverFindTab_Question_regexMatchesEmptyString=The regular expression matches even an empty string, do you want to proceed?
+ReplaceOperation_error_didNotSucceedForAllMatches=The operation did not succeed for all of the matches
+RetrieverFindTab_regularExpression=Regular expression
+RetrieverFindTab_search=Search
+RetrieverFindTab_searchScope=Search scope:
+RetrieverFindTab_wholeWord=Whole word
+RetrieverLabelProvider_FilterHidesMatches_label=Filter hides {0} matches
+ReplaceOperation_error_cannotComputeReplacement=Cannot compute replacement for match in {0} at line {1}
+RetrieverPage_CaseSensitiveFilePatterns_text=Case Sensitive File Patterns
+RetrieverPage_ConsiderDerived_text=Consider Derived Resources
+RetrieverPage_CreateWorkingSet_text=Create Working Set...
+RetrieverPage_CreateWorkingSet_tooltip=Create a working set off the search result
+ReplaceOperation_error_operationFailed=The operation failed
+ReplaceOperation_error_whileRefreshing=An error occurred while refreshing resources
+RetrieverPage_CreateWorkingSetDialog_description=Specify a name for the working set:
+RetrieverPage_CreateWorkingsetDialog_title=Create Working Set
+RetrieverPage_EnableFilter_text=Enable Filter
+RetrieverPage_EnableFilter_tooltip=Enables the filter for the current search result.
+RetrieverPage_error_cannotLoadQuery=Cannot load query\!
+RetrieverPage_error_cannotStoreQuery=Cannot store query\!
+RetrieverPage_error_noResourcesForWorkingSet=There is no search result for creating a working set\!
+RetrieverPage_ErrorDialog_title=Input Error
+RetrieverPage_FilterTab_text=Filter
+RetrieverPage_FindTab_text=Find
+RetrieverPage_InformationDialog_title=Information
+RetrieverPage_LoadQuery_text=Load Query...
+RetrieverPage_LoadQuery_tooltip=Load a query
+RetrieverPage_question_overwriteWorkingSet=Working set exists, do you want to overwrite it?
+ReplaceOperation_error_cannotLocateMatchAt=Cannot locate match in {0} at line {1}
+RetrieverPage_QuestionDialog_title=Question
+RetrieverPage_ReplaceTab_text=Replace
+RetrieverPage_SaveQuery_text=Save Query...
+RetrieverPage_SaveQuery_tooltip=Save a query
+RetrieverQuery_label=Retriever Query
+RetrieverReplaceTab_Find_text=Find
+RetrieverReplaceTab_Preview_label=Preview of replacement:
+RetrieverReplaceTab_Replace_text=Replace
+RetrieverReplaceTab_ReplaceAll_text=Replace All
+RetrieverReplaceTab_ReplaceFind_text=Replace/Find
+RetrieverReplaceTab_ReplaceWith_label=Replace with:
+RetrieverReplaceTab_ReplaceSelected_text=Replace Selected
+ReplaceOperation_error_multipleErrors=Multiple errors have occurred
+RetrieverReplaceTab_ReplaceWith_text=Replace with ''{0}''
+RetrieverReplaceTab_Restore_text=Restore
+RetrieverReplaceTab_RestoreAll_text=Restore All
+RetrieverReplaceTab_RestoreFind_text=Restore/Find
+RetrieverReplaceTab_RestoreSelected_text=Restore Selected
+ReplaceOperation_task_performChanges=Performing changes
+RetrieverResult_label=''{0}'' - {1} match(es) in {2}
+RetrieverResult_noInput_label=Empty Text Search
+WindowWorkingSetScopeDescription_label=Window working set
+WorkspaceScopeDescription_label=Workspace
+ReplaceOperation_error_allFilesReadOnly=Cannot apply changes, all files are read-only.
+ReplaceOperation_question_continueWithReadOnly_singular=There is {0} read-only file, do you want to perform the rest of the changes?
+ReplaceOperation_question_continueWithReadOnly_plural=There are {0} read-only files, do you want to perform the rest of the changes?
+TextFileScannerRegistry_error_instanciateScanner=Cannot instantiate text file scanner
+CurrentFileScopeDescription_label=Current file
+CurrentProjectScopeDescription_label=Current project
+TextSearchGroup_submenu_text=Find Text
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/CurrentFileScopeDescription.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/CurrentFileScopeDescription.java
new file mode 100644
index 00000000000..c33da45da4a
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/CurrentFileScopeDescription.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.Properties;
+
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class CurrentFileScopeDescription implements IScopeDescription {
+
+ private static final IResource[] EMPTY_ARRAY= new IResource[0];
+
+ public CurrentFileScopeDescription() {
+ }
+
+ public IResource[] getRoots(IWorkbenchPage page) {
+ IEditorPart editor= page.getActiveEditor();
+ if (editor != null) {
+ IEditorInput ei= editor.getEditorInput();
+ if (ei instanceof IFileEditorInput) {
+ IFileEditorInput fi= (IFileEditorInput) ei;
+ return new IResource[] {fi.getFile()};
+ }
+ }
+ return EMPTY_ARRAY;
+ }
+
+ public void store(IDialogSettings section) {
+ }
+ public void restore(IDialogSettings section) {
+ }
+
+ public void store(Properties props, String prefix) {
+ }
+ public void restore(Properties props, String prefix) {
+ }
+
+ public String getLabel() {
+ return SearchMessages.CurrentFileScopeDescription_label;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/CurrentProjectScopeDescription.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/CurrentProjectScopeDescription.java
new file mode 100644
index 00000000000..673822171c9
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/CurrentProjectScopeDescription.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.Properties;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class CurrentProjectScopeDescription implements IScopeDescription {
+
+ private static final IResource[] EMPTY_ARRAY= new IResource[0];
+
+ public static IProject getCurrentProject(IWorkbenchPage page) {
+ IEditorPart editor= page.getActiveEditor();
+ if (editor != null) {
+ IEditorInput ei= editor.getEditorInput();
+ if (ei instanceof IFileEditorInput) {
+ IFileEditorInput fi= (IFileEditorInput) ei;
+ return fi.getFile().getProject();
+ }
+ }
+ return null;
+ }
+
+ public CurrentProjectScopeDescription() {
+ }
+
+ public IResource[] getRoots(IWorkbenchPage page) {
+ IProject prj= getCurrentProject(page);
+ if (prj != null) {
+ return new IResource[] {prj};
+ }
+ return EMPTY_ARRAY;
+ }
+
+ public void store(IDialogSettings section) {
+ }
+ public void restore(IDialogSettings section) {
+ }
+
+ public void store(Properties props, String prefix) {
+ }
+ public void restore(Properties props, String prefix) {
+ }
+
+ public String getLabel() {
+ return SearchMessages.CurrentProjectScopeDescription_label;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/EditorDescriptorLabelProvider.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/EditorDescriptorLabelProvider.java
new file mode 100644
index 00000000000..cfc38f0b833
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/EditorDescriptorLabelProvider.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IEditorDescriptor;
+
+/**
+ * @author markus.schorn@windriver.com
+ */
+public class EditorDescriptorLabelProvider extends LabelProvider {
+ public final static EditorDescriptorLabelProvider INSTANCE= new EditorDescriptorLabelProvider();
+
+ private List imagesToDispose= new ArrayList();
+
+ private EditorDescriptorLabelProvider() {
+ super();
+ }
+
+ public void dispose() {
+ super.dispose();
+ for (Iterator e= imagesToDispose.iterator(); e.hasNext();) {
+ ((Image) e.next()).dispose();
+ }
+ imagesToDispose.clear();
+ }
+
+ public Image getColumnImage(Object element, int row) {
+ return getImage(element);
+ }
+
+ public String getColumnText(Object element, int row) {
+ return getText(element);
+ }
+
+ public Image getImage(Object element) {
+ if (element instanceof Map.Entry) {
+ Entry e= (Entry) element;
+ if (e.getValue() instanceof IEditorDescriptor) {
+ Image image= ((IEditorDescriptor) e.getValue()).getImageDescriptor().createImage();
+ imagesToDispose.add(image);
+ return image;
+ }
+ }
+ return null;
+ }
+
+ public String getText(Object element) {
+ if (element instanceof Map.Entry) {
+ Entry e= (Entry) element;
+ return e.getKey().toString();
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FilePatternSelectionDialog.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FilePatternSelectionDialog.java
new file mode 100644
index 00000000000..da5dcaf2dd7
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FilePatternSelectionDialog.java
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.content.IContentTypeManager;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+
+/**
+ * @author markus.schorn@windriver.com
+ */
+public class FilePatternSelectionDialog extends SelectionDialog {
+ static final String FILE_PATTERN_SEPERATOR= ","; //$NON-NLS-1$
+ private final static int SIZING_SELECTION_WIDGET_HEIGHT= 250;
+ private final static int SIZING_SELECTION_WIDGET_WIDTH= 300;
+
+ private String fInitialSelection;
+ private CheckboxTableViewer fListViewer;
+ private String fResult;
+ private Object[] fInput;
+
+
+ /**
+ * Creates a type selection dialog using the supplied entries. Set the
+ * initial selections to those whose extensions match the preselections.
+ */
+ public FilePatternSelectionDialog(Shell parentShell, String string) {
+ super(parentShell);
+ setTitle(SearchMessages.FilePatternSelectionDialog_title);
+ fInitialSelection= string;
+ setMessage(SearchMessages.FilePatternSelectionDialog_message);
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ }
+
+ /*
+ * (non-Javadoc) Method declared on Dialog.
+ */
+ protected Control createDialogArea(Composite parent) {
+ // page group
+ Composite composite= (Composite) super.createDialogArea(parent);
+ createMessageArea(composite);
+
+ fListViewer= CheckboxTableViewer.newCheckList(composite, SWT.BORDER);
+ GridData data= new GridData(GridData.FILL_BOTH);
+ data.heightHint= SIZING_SELECTION_WIDGET_HEIGHT;
+ data.widthHint= SIZING_SELECTION_WIDGET_WIDTH;
+ fListViewer.getTable().setLayoutData(data);
+
+ fListViewer.setLabelProvider(EditorDescriptorLabelProvider.INSTANCE);
+ fListViewer.setContentProvider(new ArrayContentProvider());
+
+ addSelectionButtons(composite);
+ initializeViewer(fInitialSelection);
+
+ applyDialogFont(composite);
+ return composite;
+ }
+
+ /**
+ * Add the selection and deselection buttons to the dialog.
+ */
+ private void addSelectionButtons(Composite composite) {
+ Composite buttonComposite= new Composite(composite, SWT.RIGHT);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ buttonComposite.setLayout(layout);
+ GridData data= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.GRAB_HORIZONTAL);
+ data.grabExcessHorizontalSpace= true;
+ composite.setData(data);
+
+ Button selectButton= createButton(buttonComposite, IDialogConstants.SELECT_ALL_ID, SearchMessages.FilePatternSelectionDialog_selectAll, false);
+
+ SelectionListener listener= new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ getListViewer().setAllChecked(true);
+ }
+ };
+ selectButton.addSelectionListener(listener);
+
+ Button deselectButton= createButton(buttonComposite, IDialogConstants.DESELECT_ALL_ID, SearchMessages.FilePatternSelectionDialog_deselectAll, false);
+
+ listener= new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ getListViewer().setAllChecked(false);
+
+ }
+ };
+ deselectButton.addSelectionListener(listener);
+ }
+
+ /*
+ * (non-Javadoc) Method declared in Window.
+ */
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ // IWorkbenchHelpSystem help= PlatformUI.getWorkbench().getHelpSystem();
+ // help.setHelp(shell, IContextIDs.DIALOG_selectSymbol);
+ }
+
+ /**
+ * Initializes this dialog's viewer after it has been laid out.
+ */
+ private void initializeViewer(String initialSelection) {
+ IContentTypeManager ctm= Platform.getContentTypeManager();
+ IContentType[] cts= ctm.getAllContentTypes();
+ IContentType txtCt= ctm.getContentType(IContentTypeManager.CT_TEXT);
+
+ HashMap editorToExtensions= new HashMap();
+ for (int i= 0; i < cts.length; i++) {
+ IContentType ct= cts[i];
+ if (ct.isKindOf(txtCt)) {
+ String[] exts= ct.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
+ String[] files= ct.getFileSpecs(IContentType.FILE_NAME_SPEC);
+ if (files.length > 30) { // ignore the c++ headers
+ files= new String[0];
+ }
+ if (exts.length > 0 || files.length > 0) {
+ IEditorDescriptor editorDescriptor= searchForEditor(exts, files, ct);
+ HashSet patterns= (HashSet) editorToExtensions.get(editorDescriptor);
+ if (patterns == null) {
+ patterns= new HashSet();
+ editorToExtensions.put(editorDescriptor, patterns);
+ }
+
+ if (exts.length > 0) {
+ for (int j= 0; j < exts.length; j++) {
+ patterns.add("*." + exts[j]); //$NON-NLS-1$
+ }
+ }
+ if (files.length > 0) {
+ for (int j= 0; j < files.length; j++) {
+ String file= files[j];
+ int idx= file.lastIndexOf('.');
+ if (idx >= 0) {
+ patterns.add("*" + file.substring(idx)); //$NON-NLS-1$
+ } else {
+ patterns.add(file);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // remove all subsets
+ HashMap oldMap= editorToExtensions;
+ editorToExtensions= new HashMap();
+ for (Iterator iter= oldMap.entrySet().iterator(); iter.hasNext();) {
+ boolean ignore= false;
+ Entry entry= (Entry) iter.next();
+ HashSet patterns= (HashSet) entry.getValue();
+ for (Iterator iter2= editorToExtensions.values().iterator(); iter2.hasNext();) {
+ HashSet patterns2= (HashSet) iter2.next();
+ if (patterns.size() <= patterns2.size()) {
+ if (patterns2.containsAll(patterns)) {
+ ignore= true;
+ }
+ } else {
+ if (patterns.containsAll(patterns2)) {
+ iter2.remove();
+ }
+ }
+ }
+ if (!ignore) {
+ editorToExtensions.put(entry.getKey(), patterns);
+ }
+ }
+
+ HashSet initialPatterns= new HashSet();
+ HashSet remainingPatterns= new HashSet();
+ if (initialPatterns != null) {
+ List helper= Arrays.asList(initialSelection.split(FILE_PATTERN_SEPERATOR));
+ for (Iterator iter= helper.iterator(); iter.hasNext();) {
+ String element= (String) iter.next();
+ element= element.trim();
+ if (element.length() > 0) {
+ initialPatterns.add(element);
+ remainingPatterns.add(element);
+ }
+ }
+ }
+ final Comparator stringComparator= new Comparator() {
+ public int compare(Object arg0, Object arg1) {
+ String s1= (String) arg0;
+ String s2= (String) arg1;
+ int cmp= s1.compareToIgnoreCase(s2);
+ if (cmp == 0) {
+ cmp= -s1.compareTo(s2);
+ }
+ return cmp;
+ }
+ };
+ TreeMap filePatterns= new TreeMap(stringComparator);
+ List checkmark= new ArrayList();
+ for (Iterator iter= editorToExtensions.entrySet().iterator(); iter.hasNext();) {
+ Entry entry= (Entry) iter.next();
+ Collection extensions= (Collection) entry.getValue();
+ Object editor= entry.getKey();
+ filePatterns.put(combineExtensions(extensions, stringComparator), editor);
+ if (initialPatterns.containsAll(extensions)) {
+ checkmark.add(editor);
+ remainingPatterns.removeAll(extensions);
+ }
+ }
+
+ if (!remainingPatterns.isEmpty()) {
+ filePatterns.put(combineExtensions(remainingPatterns, stringComparator), null);
+ checkmark.add(null);
+ }
+
+ fInput= filePatterns.entrySet().toArray();
+ fListViewer.setInput(fInput);
+ for (int i= 0; i < fInput.length; i++) {
+ Entry element= (Entry) fInput[i];
+ if (checkmark.contains(element.getValue())) {
+ fListViewer.setChecked(element, true);
+ }
+ }
+ }
+
+ private IEditorDescriptor searchForEditor(String[] exts, String[] files, IContentType ct) {
+ IEditorRegistry reg= PlatformUI.getWorkbench().getEditorRegistry();
+
+ // try the extensions first
+ for (int i= 0; i < exts.length; i++) {
+ String ext= exts[i];
+ String sample= "file." + ext; //$NON-NLS-1$
+ IEditorDescriptor ed= reg.getDefaultEditor(sample, ct);
+ if (ed != null) {
+ return ed;
+ }
+ }
+ // next try files
+ for (int i= 0; i < files.length; i++) {
+ String file= files[i];
+ IEditorDescriptor ed= reg.getDefaultEditor(file, ct);
+ if (ed != null) {
+ return ed;
+ }
+ }
+
+ // give up
+ return null;
+ }
+
+ private String combineExtensions(Collection input, Comparator comp) {
+ ArrayList extensions= new ArrayList();
+ extensions.addAll(input);
+ Collections.sort(extensions, comp);
+ String last= null;
+ boolean needSep= false;
+ StringBuffer pattern= new StringBuffer();
+ for (Iterator iterator= extensions.iterator(); iterator.hasNext();) {
+ String extension= (String) iterator.next();
+ if (!extension.equals(last)) {
+ if (needSep) {
+ pattern.append(FILE_PATTERN_SEPERATOR);
+ }
+ needSep= true;
+ pattern.append(extension);
+ last= extension;
+ }
+ }
+ return pattern.toString();
+ }
+
+ protected void okPressed() {
+ // Get the input children.
+ List list= new ArrayList();
+ for (int i= 0; i < fInput.length; ++i) {
+ Entry element= (Entry) fInput[i];
+ if (fListViewer.getChecked(element)) {
+ String pattern= (String) element.getKey();
+ list.addAll(Arrays.asList(pattern.split(FILE_PATTERN_SEPERATOR)));
+ }
+ }
+ setResult(list);
+ fResult= combineExtensions(list, String.CASE_INSENSITIVE_ORDER);
+ super.okPressed();
+ }
+
+ protected CheckboxTableViewer getListViewer() {
+ return fListViewer;
+ }
+
+ public String getFilePatterns() {
+ return fResult;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FilterMatchEvent.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FilterMatchEvent.java
new file mode 100644
index 00000000000..be0aac709bd
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FilterMatchEvent.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.search.ui.ISearchResult;
+import org.eclipse.search.ui.text.Match;
+import org.eclipse.search.ui.text.MatchEvent;
+
+public class FilterMatchEvent extends MatchEvent {
+ private static final long serialVersionUID= -4394594389515651137L;
+ public static final int FILTER_CHANGED= 3;
+
+ public FilterMatchEvent(ISearchResult searchResult) {
+ super(searchResult);
+ setKind(FILTER_CHANGED);
+ }
+
+ public void setMatches(Match[] matches) {
+ super.setMatches(matches);
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInFileActionDelegate.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInFileActionDelegate.java
new file mode 100644
index 00000000000..318b2ae163c
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInFileActionDelegate.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+
+public class FindInFileActionDelegate extends FindInRecentScopeActionDelegate {
+
+ public FindInFileActionDelegate() {
+ super(SearchMessages.FindInFileActionDelegate_text);
+ }
+
+ protected boolean modifyQuery(RetrieverQuery query) {
+ if (super.modifyQuery(query)) {
+ query.setSearchScope(new CurrentFileScopeDescription());
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInProjectActionDelegate.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInProjectActionDelegate.java
new file mode 100644
index 00000000000..2c4f7d0a2b2
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInProjectActionDelegate.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class FindInProjectActionDelegate extends FindInRecentScopeActionDelegate {
+
+ public FindInProjectActionDelegate() {
+ super(SearchMessages.FindInProjectActionDelegate_text);
+ }
+
+ protected boolean modifyQuery(RetrieverQuery query) {
+ if (super.modifyQuery(query)) {
+ query.setSearchScope(new CurrentProjectScopeDescription());
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInRecentScopeActionDelegate.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInRecentScopeActionDelegate.java
new file mode 100644
index 00000000000..b468fcb2de6
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInRecentScopeActionDelegate.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+
+/**
+ * @author markus.schorn@windriver.com
+ */
+public class FindInRecentScopeActionDelegate extends RetrieverAction implements IWorkbenchWindowActionDelegate, IEditorActionDelegate {
+ private IWorkbenchWindow fWindow;
+
+ public FindInRecentScopeActionDelegate() {
+ this(SearchMessages.FindInRecentScopeActionDelegate_text);
+ }
+
+ public FindInRecentScopeActionDelegate(String text) {
+ setText(text);
+ }
+
+ // IWorkbenchWindowActionDelegate
+ public void dispose() {
+ fWindow= null;
+ }
+
+ // IWorkbenchWindowActionDelegate
+ public void init(IWorkbenchWindow window) {
+ fWindow= window;
+ }
+
+ // IEditorActionDelegate
+ public void setActiveEditor(IAction action, IEditorPart targetEditor) {
+ if (targetEditor instanceof ITextEditor) {
+ fWindow= targetEditor.getSite().getWorkbenchWindow();
+ } else {
+ fWindow= null;
+ }
+ }
+
+ // IActionDelegate
+ public void selectionChanged(IAction action, ISelection selection) {
+ }
+
+ // IActionDelegate
+ final public void run(IAction action) {
+ run();
+ }
+
+ // RetrieverAction
+ protected IWorkbenchPage getWorkbenchPage() {
+ if (fWindow != null) {
+ return fWindow.getActivePage();
+ }
+ return null;
+ }
+
+ protected boolean modifyQuery(RetrieverQuery query) {
+ IWorkbenchPage page= getWorkbenchPage();
+ String searchFor= null;
+ if (page != null) {
+ searchFor= extractSearchTextFromSelection(page.getSelection());
+ }
+ if (searchFor == null || searchFor.length() == 0) {
+ searchFor= extractSearchTextFromEditor(page.getActiveEditor());
+ }
+ query.setSearchString(searchFor);
+ return true;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInWorkingSetActionDelegate.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInWorkingSetActionDelegate.java
new file mode 100644
index 00000000000..bcf711d37a2
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInWorkingSetActionDelegate.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.ui.IWorkbenchPage;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class FindInWorkingSetActionDelegate extends FindInRecentScopeActionDelegate {
+
+ public FindInWorkingSetActionDelegate() {
+ super(SearchMessages.FindInWorkingSetActionDelegate_text);
+ }
+
+ protected boolean modifyQuery(RetrieverQuery query) {
+ if (super.modifyQuery(query)) {
+ IWorkbenchPage page= getWorkbenchPage();
+ if (page != null) {
+ IScopeDescription scope= WorkingSetScopeDescription.createWithDialog(page, query.getScopeDescription());
+ if (scope != null) {
+ query.setSearchScope(scope);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInWorkspaceActionDelegate.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInWorkspaceActionDelegate.java
new file mode 100644
index 00000000000..1744de33db7
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/FindInWorkspaceActionDelegate.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class FindInWorkspaceActionDelegate extends FindInRecentScopeActionDelegate {
+
+ public FindInWorkspaceActionDelegate() {
+ super(SearchMessages.FindInWorkspaceActionDelegate_text);
+ }
+
+ protected boolean modifyQuery(RetrieverQuery query) {
+ if (super.modifyQuery(query)) {
+ query.setSearchScope(new WorkspaceScopeDescription());
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/IRetrieverKeys.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/IRetrieverKeys.java
new file mode 100644
index 00000000000..5f9b449f4ba
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/IRetrieverKeys.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.search.core.text.AbstractTextFileScanner;
+
+interface IRetrieverKeys {
+ final String KEY_EXT_COMBO_CONTENT= ".combo"; //$NON-NLS-1$
+
+ final String KEY_SPLITTER_W1= "splitter.w1"; //$NON-NLS-1$
+ final String KEY_SPLITTER_W2= "splitter.w2"; //$NON-NLS-1$
+
+ final String KEY_USE_FLAT_LAYOUT= "flat-layout"; //$NON-NLS-1$
+
+ final String KEY_CASE_SENSITIVE_SEARCH= "case-sensitive"; //$NON-NLS-1$
+ final String KEY_REGULAR_EXPRESSION_SEARCH= "regular-expression"; //$NON-NLS-1$
+ final String KEY_WHOLE_WORD= "whole-word"; //$NON-NLS-1$
+ final String KEY_SEARCH_STRINGS= "search-string"; //$NON-NLS-1$
+
+ final String KEY_SEARCH_SCOPE= "search-scope"; //$NON-NLS-1$
+ final String KEY_SCOPE_HISTORY= "scope-history"; //$NON-NLS-1$
+ final String KEY_SCOPE_DESCRIPTOR_CLASS= "scope-descriptor-class"; //$NON-NLS-1$
+ final String KEY_FILE_PATTERNS= "file-patterns"; //$NON-NLS-1$
+ final String KEY_CONSIDER_DERIVED_RESOURCES= "consider-derived"; //$NON-NLS-1$
+ final String KEY_USE_CASE_SENSITIVE_FILE_PATTERNS= "case-sensitive-file-patterns"; //$NON-NLS-1$
+
+ final String KEY_ENABLE_FILTER= "filter-action"; //$NON-NLS-1$
+ final String KEY_ENABLE_LOCATION_FILTER= "use-location-filter"; //$NON-NLS-1$
+ final String KEY_COMMENT_FILTER= "filter-comment"; //$NON-NLS-1$
+ final String KEY_STRING_FILTER= "filter-string"; //$NON-NLS-1$
+ final String KEY_INCLUDE_FILTER= "filter-include"; //$NON-NLS-1$
+ final String KEY_PREP_FILTER= "filter-prep"; //$NON-NLS-1$
+ final String KEY_FUNCTION_FILTER= "filter-function"; //$NON-NLS-1$
+ final String KEY_ELSEWHERE_FILTER= "filter-elsewhere"; //$NON-NLS-1$
+
+ final String KEY_ENABLE_TEXT_FILTER= "use-filter-pattern"; //$NON-NLS-1$
+ final String KEY_FILTER_PATTERNS= "filter-pattern"; //$NON-NLS-1$
+ final String KEY_REGULAR_EXPRESSION_FILTER= "filter-regexp"; //$NON-NLS-1$
+ final String KEY_INVERT_FILTER= "filter-invert"; //$NON-NLS-1$
+
+ final String KEY_REPLACEMENT_STRING= "replacement-string"; //$NON-NLS-1$
+
+ final int VISIBLE_ITEMS_IN_COMBO= 8;
+
+ final int MAX_FILTER_PATTERNS= 8;
+ final int MAX_SEARCH_STRINGS= 8;
+ final int MAX_FILE_PATTERNS= 8;
+ final int MAX_SCOPES= 8;
+ final int MAX_REPLACEMENT_STRINGS= 8;
+
+ final int MAX_COMBINED_LINE_LENGTH= 1024 * 8;
+
+ final String SECTION_SCOPE= "scope"; //$NON-NLS-1$
+
+ final int ALL_LOCATIONS= (1 << AbstractTextFileScanner.LOCATION_OTHER) | (1 << AbstractTextFileScanner.LOCATION_COMMENT) | (1 << AbstractTextFileScanner.LOCATION_FUNCTION) | (1 << AbstractTextFileScanner.LOCATION_IMPORT_OR_INCLUDE_STATEMENT) | (1 << AbstractTextFileScanner.LOCATION_PREPROCESSOR_DIRECTIVE) | (1 << AbstractTextFileScanner.LOCATION_STRING_LITERAL);
+
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/IScopeDescription.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/IScopeDescription.java
new file mode 100644
index 00000000000..7fda6263c3a
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/IScopeDescription.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.Properties;
+
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+
+import org.eclipse.ui.IWorkbenchPage;
+
+/**
+ * Interface to handle various search scopes in the UI.
+ */
+public interface IScopeDescription {
+
+ public String getLabel();
+
+ public IResource[] getRoots(IWorkbenchPage page);
+
+ public void restore(IDialogSettings section);
+
+ public void restore(Properties props, String keyPrefix);
+
+ public void store(IDialogSettings section);
+
+ public void store(Properties props, String keyPrefix);
+
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/JavaScanner.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/JavaScanner.java
new file mode 100644
index 00000000000..25abd4dc7d7
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/JavaScanner.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.search.core.text.AbstractTextFileScanner;
+import org.eclipse.search.core.text.TextSearchMatchAccess;
+
+/**
+ * Scanner for java files, contributed via the org.eclipse.search.textFileScanner
+ * extension-point.
+ * Detects comments, string literals and import statements.
+ */
+public class JavaScanner extends AbstractTextFileScanner {
+
+ private static final char[] IMPORT_CHARS= "import".toCharArray(); //$NON-NLS-1$
+ private TextSearchMatchAccess fMatchAccess;
+ private int fOffset;
+ private int fLength;
+
+ public JavaScanner() {
+ }
+
+ protected void scanFile(TextSearchMatchAccess matchAccess) {
+ fMatchAccess= matchAccess;
+ fOffset= -1;
+ fLength= matchAccess.getFileContentLength();
+ doScanFile();
+ fMatchAccess= null;
+ }
+
+ private void doScanFile() {
+ addLineOffset(0);
+ int c= nextChar();
+ int offset;
+ while (c != -1) {
+ switch (c) {
+ case '"':
+ offset= fOffset;
+ c= matchStringLiteral();
+ addLocation(offset, fOffset - offset, LOCATION_STRING_LITERAL);
+ break;
+
+ case 'L':
+ if (peekChar() == '"') {
+ offset= fOffset;
+ nextChar();
+ c= matchStringLiteral();
+ addLocation(offset, fOffset - offset, LOCATION_STRING_LITERAL);
+ } else {
+ c= matchKeywordOrIdentifier((char) c);
+ }
+ break;
+
+ case '\'':
+ c= matchCharacterLiteral();
+ break;
+
+ case '/':
+ offset= fOffset;
+ c= nextChar();
+ switch (c) {
+ case '/':
+ c= matchSinglelineComment();
+ addLocation(offset, fOffset - offset, LOCATION_COMMENT);
+ break;
+
+ case '*':
+ c= matchMultilineComment();
+ addLocation(offset, fOffset - offset, LOCATION_COMMENT);
+ break;
+ }
+ break;
+
+ default:
+ if (Character.isJavaIdentifierStart((char) c)) {
+ c= matchKeywordOrIdentifier((char) c);
+ } else {
+ c= nextChar();
+ }
+ break;
+ }
+ }
+ }
+
+ private int matchMultilineComment() {
+ int c= nextChar();
+ while (c != -1) {
+ if (c == '*') {
+ c= nextChar();
+ if (c == '/') {
+ return nextChar();
+ }
+ } else {
+ c= nextChar();
+ }
+ }
+ return c;
+ }
+
+ private int matchSinglelineComment() {
+ int c;
+ do {
+ c= nextChar();
+ } while (c != '\n' && c != '\r' && c != -1);
+ if (c == '\r' && peekChar() == '\n') {
+ nextChar();
+ }
+ return nextChar();
+ }
+
+ private int matchKeywordOrIdentifier(int c) {
+ int start= fOffset;
+ int importIdx= 0;
+ boolean isImport= c == IMPORT_CHARS[importIdx++];
+ while (true) {
+ c= nextChar();
+ if (c != -1 && Character.isJavaIdentifierPart((char) c)) {
+ if (isImport) {
+ if (importIdx == IMPORT_CHARS.length) {
+ isImport= false;
+ } else {
+ isImport= IMPORT_CHARS[importIdx++] == c;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ if (isImport) {
+ c= matchEndOfImport(c);
+ addLocation(start, fOffset - start, LOCATION_IMPORT_OR_INCLUDE_STATEMENT);
+ return c;
+ }
+ return c;
+ }
+
+ private int matchEndOfImport(int c) {
+ while (c != ';' && c != -1) {
+ c= nextChar();
+ }
+ return nextChar();
+ }
+
+ private int matchCharacterLiteral() {
+ boolean escaped= false;
+ while (true) {
+ switch (nextChar()) {
+ case -1:
+ return -1;
+ case '\\':
+ escaped= !escaped;
+ break;
+ case '\'':
+ case '\n':
+ case '\r':
+ if (!escaped) {
+ return nextChar();
+ }
+ escaped= false;
+ break;
+ }
+ }
+ }
+
+ private int matchStringLiteral() {
+ boolean escaped= false;
+ while (true) {
+ switch (nextChar()) {
+ case -1:
+ return -1;
+ case '\\':
+ escaped= !escaped;
+ break;
+ case '"':
+ case '\n':
+ case '\r':
+ if (!escaped) {
+ return nextChar();
+ }
+ escaped= false;
+ break;
+ }
+ }
+ }
+
+ private int peekChar() {
+ int offset= fOffset + 1;
+ if (offset >= fLength) {
+ return -1;
+ }
+ return fMatchAccess.getFileContentChar(offset);
+ }
+
+ private int nextChar() {
+ if (++fOffset >= fLength) {
+ fOffset= fLength;
+ return -1;
+ }
+ char c= fMatchAccess.getFileContentChar(fOffset);
+ if (c == '\n') {
+ addLineOffset(fOffset + 1);
+ } else
+ if (c == '\r') {
+ if (peekChar() != '\n') {
+ addLineOffset(fOffset + 1);
+ }
+ }
+ return c;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/LineNumberScanner.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/LineNumberScanner.java
new file mode 100644
index 00000000000..e47809356fb
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/LineNumberScanner.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.search.core.text.AbstractTextFileScanner;
+import org.eclipse.search.core.text.TextSearchMatchAccess;
+
+/**
+ * The minimal scanner that figures out the line-numbers only.
+ */
+public class LineNumberScanner extends AbstractTextFileScanner {
+ public void scanFile(TextSearchMatchAccess matchAccess) {
+ int length= matchAccess.getFileContentLength();
+ addLineOffset(0);
+
+ boolean r= false;
+ for (int i= 0; i < length; i++) {
+ switch (matchAccess.getFileContentChar(i)) {
+ case '\r':
+ if (r) {
+ addLineOffset(i);
+ }
+ r= true;
+ break;
+
+ case '\n':
+ addLineOffset(i + 1);
+ r= false;
+ break;
+
+ default:
+ if (r) {
+ addLineOffset(i);
+ r= false;
+ }
+ }
+ }
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/ReplaceAction.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/ReplaceAction.java
new file mode 100644
index 00000000000..49b97faef33
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/ReplaceAction.java
@@ -0,0 +1,553 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+
+import org.eclipse.ui.PlatformUI;
+
+import org.eclipse.search.internal.ui.SearchPlugin;
+import org.eclipse.search.internal.ui.text.SearchAgainConfirmationDialog;
+
+import org.eclipse.search2.internal.ui.InternalSearchUI;
+import org.eclipse.search2.internal.ui.Messages;
+import org.eclipse.search2.internal.ui.SearchMessages;
+import org.eclipse.search2.internal.ui.text.PositionTracker;
+
+/**
+ * Class to carry out replacement opertions. An instance may only be used once.
+ */
+public class ReplaceAction extends Action {
+ private RetrieverPage fView;
+ private Shell fShell;
+ private RetrieverResult fSearchResult;
+ private String fDialogTitle;
+ private boolean fSuccess;
+ private Pattern fPattern;
+ private String fReplacement;
+ private boolean fReplace;
+ private RetrieverMatch fMatch;
+ private HashSet fFileSet;
+ private Map fLineMap;
+
+ /**
+ * Constructor to replace all matches
+ */
+ public ReplaceAction(RetrieverPage retriever, String action, boolean replace) {
+ init(retriever, action, replace);
+ setupReplaceAll();
+ }
+
+ /**
+ * Constructor to replace a selection of matches
+ */
+ public ReplaceAction(RetrieverPage retriever, String action, boolean replace, IStructuredSelection sel) {
+ init(retriever, action, replace);
+ setupReplaceSelection(sel);
+ }
+
+ /**
+ * Constructor to replace a single match
+ */
+ public ReplaceAction(RetrieverPage retriever, String action, boolean replace, RetrieverMatch match) {
+ init(retriever, action, replace);
+ fMatch= match;
+ }
+
+ private void init(RetrieverPage retriever, String action, boolean replace) {
+ fView= retriever;
+ fSearchResult= (RetrieverResult) fView.getInput();
+ fShell= fView.getSite().getShell();
+ fDialogTitle= action;
+ fReplace= replace;
+ setText(action);
+ }
+
+ private void setupReplaceAll() {
+ fFileSet= new HashSet();
+ fLineMap= Collections.EMPTY_MAP;
+ Object[] lines= fSearchResult.getElements();
+ for (int i= 0; i < lines.length; i++) {
+ RetrieverLine line= (RetrieverLine) lines[i];
+ if (needsReplacement(line)) {
+ fFileSet.add(line.getParent());
+ }
+ }
+ setEnabled(!fFileSet.isEmpty());
+ }
+
+ private boolean needsReplacement(RetrieverLine line) {
+ if (!line.isFiltered()) {
+ RetrieverMatch[] matches= line.getMatches(false);
+ for (int j= 0; j < matches.length; j++) {
+ RetrieverMatch match= matches[j];
+ if (!match.isFiltered() && match.isReplaced() != fReplace) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private void setupReplaceSelection(IStructuredSelection sel) {
+ // collect resources and lines of selection
+ HashMap selectedResources= new HashMap();
+ HashSet selectedLines= new HashSet();
+ fFileSet= new HashSet();
+ fLineMap= new HashMap();
+ for (Iterator iter= sel.iterator(); iter.hasNext();) {
+ Object element= iter.next();
+ if (element instanceof IResource) {
+ selectedResources.put(element, Boolean.TRUE);
+ } else
+ if (element instanceof RetrieverLine) {
+ selectedLines.add(element);
+ }
+ }
+
+ Object[] allLines= fSearchResult.getElements();
+ for (int i= 0; i < allLines.length; i++) {
+ RetrieverLine line= (RetrieverLine) allLines[i];
+ if (needsReplacement(line)) {
+ IFile file= line.getParent();
+ if (containsFile(selectedResources, file)) {
+ fFileSet.add(file);
+ } else
+ if (selectedLines.contains(line)) {
+ fFileSet.add(file);
+ addToLineMap(file, line);
+ }
+ }
+ }
+ setEnabled(!fFileSet.isEmpty());
+ }
+
+ private void addToLineMap(IFile file, RetrieverLine line) {
+ ArrayList lines= (ArrayList) fLineMap.get(file);
+ if (lines == null) {
+ lines= new ArrayList();
+ fLineMap.put(file, lines);
+ }
+ lines.add(line);
+ }
+
+ private boolean containsFile(HashMap resources, IFile file) {
+ return containsResource(resources, file).booleanValue();
+ }
+
+ private Boolean containsResource(HashMap resources, IResource res) {
+ Boolean result= (Boolean) resources.get(res);
+ if (result == null) {
+ IResource parent= res.getParent();
+ result= parent == null ? Boolean.FALSE : containsResource(resources, parent);
+ resources.put(res, result);
+ }
+ return result;
+ }
+
+ public void setReplacement(Pattern pattern, String replacement) {
+ fPattern= pattern;
+ fReplacement= replacement;
+ }
+
+ public void run() {
+ fSuccess= false;
+ if (fSearchResult == null) {
+ return;
+ }
+ if (fReplace && (fPattern == null || fReplacement == null)) {
+ return;
+ }
+
+ IWorkspace workspace= ResourcesPlugin.getWorkspace();
+ ISchedulingRule rule= workspace.getRuleFactory().modifyRule(workspace.getRoot());
+
+ IRunnableWithProgress runnable= new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ fSuccess= doPerformReplace(monitor);
+ }
+ };
+
+ try {
+ PlatformUI.getWorkbench().getProgressService().runInUI(fView.getSite().getWorkbenchWindow(), runnable, rule);
+ } catch (InvocationTargetException e) {
+ SearchPlugin.log(e);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ protected boolean doPerformReplace(IProgressMonitor monitor) {
+ if (fMatch != null) {
+ return doPerformSingleReplace(monitor);
+ } else
+ if (fFileSet != null && fLineMap != null) {
+ return doPerformMultiReplace(monitor);
+ }
+ return false;
+ }
+
+ private boolean doPerformSingleReplace(IProgressMonitor monitor) {
+ RetrieverMatch match= fMatch;
+ RetrieverLine line= match.getLine();
+ IFile file= line.getParent();
+ HashSet searchedAgain= new HashSet();
+ if (!makeCommitable(Collections.singleton(file), searchedAgain)) {
+ return false;
+ }
+ if (searchedAgain.contains(file)) {
+ match= mapMatch(match);
+ }
+ if (match == null) {
+ MessageDialog.openError(fShell, fDialogTitle, SearchMessages.ReplaceOperation_error_cannotLocateMatch);
+ return false;
+ }
+
+ ArrayList failures= new ArrayList();
+ line= match.getLine();
+ replaceInFile(monitor, line.getParent(), new RetrieverMatch[] {match}, failures);
+ if (!failures.isEmpty()) {
+ ErrorDialog.openError(fShell, fDialogTitle, SearchMessages.ReplaceOperation_error_operationFailed, (IStatus) failures.get(0));
+ return false;
+ }
+ fView.getTreeViewer().refresh(line);
+ return true;
+ }
+
+ private boolean doPerformMultiReplace(IProgressMonitor monitor) {
+ HashSet searchedAgain= new HashSet();
+ if (!makeCommitable(fFileSet, searchedAgain)) {
+ return false;
+ }
+
+ for (Iterator iter= searchedAgain.iterator(); iter.hasNext();) {
+ IFile file= (IFile) iter.next();
+ ArrayList lines= (ArrayList) fLineMap.get(file);
+ if (lines != null) {
+ mapLines(file, lines);
+ }
+ }
+
+ ArrayList failures= new ArrayList();
+ monitor.beginTask(SearchMessages.ReplaceOperation_task_performChanges, fFileSet.size());
+ try {
+ for (Iterator iter= fFileSet.iterator(); iter.hasNext();) {
+ IFile file= (IFile) iter.next();
+ List lines= (List) fLineMap.get(file);
+ if (lines == null) {
+ lines= Arrays.asList(fSearchResult.getLinesForFile(file, false));
+ }
+ ArrayList matches= new ArrayList(lines.size());
+ for (Iterator iterator= lines.iterator(); iterator.hasNext();) {
+ RetrieverLine line= (RetrieverLine) iterator.next();
+ if (line != null) {
+ matches.addAll(Arrays.asList(line.getDisplayedMatches()));
+ }
+ }
+
+ replaceInFile(new SubProgressMonitor(monitor, 1), file, (RetrieverMatch[]) matches.toArray(new RetrieverMatch[matches.size()]), failures);
+ if (monitor.isCanceled()) {
+ return false;
+ }
+ }
+ } finally {
+ monitor.done();
+ }
+ if (!failures.isEmpty()) {
+ handleFailures((IStatus[]) failures.toArray(new IStatus[failures.size()]));
+ return false;
+ }
+
+ fView.getTreeViewer().refresh();
+ return true;
+ }
+
+ private void mapLines(IFile file, ArrayList lines) {
+ RetrieverLine[] newLines= fSearchResult.getLinesForFile(file, false);
+ for (int i= 0; i < lines.size(); i++) {
+ RetrieverLine line= (RetrieverLine) lines.get(i);
+ lines.set(i, findBestLine(line, newLines));
+ }
+ }
+
+ private RetrieverMatch mapMatch(RetrieverMatch match) {
+ RetrieverLine line= match.getLine();
+ RetrieverLine[] newLines= fSearchResult.getLinesForFile(line.getParent(), false);
+
+ RetrieverMatch bestMatch= null;
+ RetrieverLine bestLine= findBestLine(line, newLines);
+ if (bestLine != null) {
+ int col= match.getLineOffset();
+ int nearest= Integer.MAX_VALUE;
+ RetrieverMatch[] candidates= bestLine.getDisplayedMatches();
+ for (int i= 0; i < candidates.length; i++) {
+ RetrieverMatch candidate= candidates[i];
+ if (!candidate.isFiltered() && candidate.getOriginal().equals(match.getOriginal())) {
+ int dist= Math.abs(candidate.getLineOffset() - col);
+ if (dist < nearest) {
+ dist= nearest;
+ bestMatch= candidate;
+ }
+ }
+ }
+ }
+ return bestMatch;
+ }
+
+ private RetrieverLine findBestLine(RetrieverLine line, RetrieverLine[] newLines) {
+ // find the best line
+ String lineData= line.getLine().trim();
+ int lineNumber= line.getLineNumber();
+ int nearest= Integer.MAX_VALUE;
+ RetrieverLine best= null;
+ for (int i= 0; i < newLines.length; i++) {
+ RetrieverLine test= newLines[i];
+ if (lineData.equals(test.getLine().trim())) {
+ int dist= Math.abs(test.getLineNumber() - lineNumber);
+ if (dist < nearest) {
+ dist= nearest;
+ best= test;
+ }
+ }
+ }
+ return best;
+ }
+
+ private boolean handleFailures(IStatus[] stati) {
+ if (stati.length == 0) {
+ return true;
+ }
+
+ String message= Messages.format(SearchMessages.ReplaceOperation_error_didNotSucceedForAllMatches, fDialogTitle);
+ if (stati.length == 1) {
+ ErrorDialog.openError(fShell, fDialogTitle, message, stati[0]);
+ } else {
+ MultiStatus mstatus= new MultiStatus(SearchPlugin.getID(), SearchPlugin.INTERNAL_ERROR, stati, SearchMessages.ReplaceOperation_error_multipleErrors, null);
+ ErrorDialog.openError(fShell, fDialogTitle, message, mstatus);
+ }
+ return false;
+ }
+
+ private boolean makeCommitable(Collection files, HashSet searchedAgain) {
+ if (files.isEmpty()) {
+ return true;
+ }
+
+ HashSet readOnly= new HashSet();
+ for (Iterator iter= files.iterator(); iter.hasNext();) {
+ IFile file= (IFile) iter.next();
+ if (!file.isSynchronized(IResource.DEPTH_ZERO)) {
+ if (!refreshFile(file)) {
+ return false;
+ }
+ searchedAgain.add(file);
+ }
+ if (file.isReadOnly()) {
+ readOnly.add(file);
+ }
+ }
+
+ // try to make files writable
+ if (!validateEdit(readOnly)) {
+ return false;
+ }
+
+ // check files if they are still read-only
+ int readOnlyCount= 0;
+ for (Iterator iter= readOnly.iterator(); iter.hasNext();) {
+ IFile rf= (IFile) iter.next();
+ if (rf.isReadOnly()) {
+ searchedAgain.remove(rf);
+ readOnlyCount++;
+ } else {
+ searchedAgain.add(rf);
+ }
+ }
+
+ // continue with all writable files?
+ if (!confirmParialReplacement(files.size(), readOnlyCount)) {
+ return false;
+ }
+
+ if (!searchAgain(searchedAgain)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean searchAgain(HashSet outdated) {
+ // don't attempt to research on a restore operation!
+ if (outdated.isEmpty() || !fReplace) {
+ return true;
+ }
+ SearchAgainConfirmationDialog dialog= new SearchAgainConfirmationDialog(fShell, (ILabelProvider) fView.getTreeViewer().getLabelProvider(), Collections.EMPTY_LIST, new ArrayList(outdated));
+ if (dialog.open() != IDialogConstants.OK_ID) {
+ return false;
+ }
+
+ fSearchResult.searchAgain(outdated);
+ return true;
+ }
+
+ private boolean refreshFile(IFile file) {
+ try {
+ file.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
+ } catch (CoreException e) {
+ ErrorDialog.openError(fShell, fDialogTitle, SearchMessages.ReplaceOperation_error_whileRefreshing, e.getStatus());
+ return false;
+ }
+ return true;
+ }
+
+ private boolean validateEdit(HashSet readOnly) {
+ if (!readOnly.isEmpty()) {
+ IStatus s= ResourcesPlugin.getWorkspace().validateEdit((IFile[]) readOnly.toArray(new IFile[readOnly.size()]), fShell);
+ if (s.getSeverity() != IStatus.OK) {
+ if (s.getSeverity() != IStatus.CANCEL && s.getCode() != IResourceStatus.READ_ONLY_LOCAL) {
+ ErrorDialog.openError(fShell, fDialogTitle, SearchMessages.ReplaceOperation_error_whileValidateEdit, s);
+ }
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean confirmParialReplacement(int writableFiles, int readOnlyFiles) {
+ if (readOnlyFiles == 0) {
+ return true;
+ }
+ if (writableFiles == 0) {
+ MessageDialog.openError(fShell, fDialogTitle, SearchMessages.ReplaceOperation_error_allFilesReadOnly);
+ return false;
+ }
+
+ String key= readOnlyFiles == 1 ? SearchMessages.ReplaceOperation_question_continueWithReadOnly_singular : SearchMessages.ReplaceOperation_question_continueWithReadOnly_plural;
+
+ return MessageDialog.openQuestion(fShell, fDialogTitle, MessageFormat.format(key, new Object[] {new Integer(readOnlyFiles)}));
+ }
+
+ private void replaceInFile(IProgressMonitor monitor, IFile file, RetrieverMatch[] matches, Collection failures) {
+ try {
+ if (file.isReadOnly()) {
+ return;
+ }
+ int ticks= 3;
+ monitor.beginTask(SearchMessages.ReplaceOperation_task_performChanges, ticks);
+ ITextFileBufferManager bm= FileBuffers.getTextFileBufferManager();
+ try {
+ ticks--;
+ bm.connect(file.getFullPath(), new SubProgressMonitor(monitor, 1));
+ if (monitor.isCanceled()) {
+ return;
+ }
+ ITextFileBuffer fb= bm.getTextFileBuffer(file.getFullPath());
+ boolean wasDirty= fb.isDirty();
+ IDocument doc= fb.getDocument();
+ PositionTracker tracker= InternalSearchUI.getInstance().getPositionTracker();
+ for (int i= 0; i < matches.length; i++) {
+ RetrieverMatch match= matches[i];
+ if (!match.isFiltered() && (match.isReplaced() != fReplace)) {
+ int offset= match.getOffset();
+ int length= match.getLength();
+ Position currentPosition= tracker.getCurrentPosition(match);
+ if (currentPosition != null) {
+ offset= currentPosition.offset;
+ length= currentPosition.length;
+ }
+ String currentText= null;
+ try {
+ currentText= doc.get(offset, length);
+ } catch (BadLocationException e) {
+ }
+ if (currentText == null || !currentText.equals(match.getCurrentText())) {
+ failures.add(createErrorStatus(Messages.format(SearchMessages.ReplaceOperation_error_cannotLocateMatchAt, new Object[] {file.getFullPath(), new Integer(match.getLine().getLineNumber())})));
+ } else {
+ String newText= fReplace ? match.computeReplacement(fPattern, fReplacement) : match.getOriginal();
+ if (newText == null) {
+ failures.add(createErrorStatus(Messages.format(SearchMessages.ReplaceOperation_error_cannotComputeReplacement, new Object[] {file.getFullPath(), new Integer(match.getLine().getLineNumber())})));
+ } else {
+ try {
+ doc.replace(offset, length, newText);
+ match.setReplacement(fReplace ? newText : null);
+ } catch (BadLocationException e) {
+ failures.add(createErrorStatus(Messages.format(SearchMessages.ReplaceOperation_error_cannotLocateMatchAt, new Object[] {file, new Integer(match.getLine().getLineNumber())})));
+ }
+ }
+ }
+ }
+ }
+ if (!wasDirty) {
+ ticks--;
+ fb.commit(new SubProgressMonitor(monitor, 1), true);
+ }
+ } finally {
+ bm.disconnect(file.getFullPath(), new SubProgressMonitor(monitor, ticks));
+ }
+ } catch (CoreException e) {
+ failures.add(e.getStatus());
+ } finally {
+ monitor.done();
+ }
+ }
+
+ private Status createErrorStatus(String message) {
+ return new Status(IStatus.ERROR, SearchPlugin.getID(), SearchPlugin.INTERNAL_ERROR, message, null);
+ }
+
+ public boolean wasSuccessful() {
+ return fSuccess;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverAction.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverAction.java
new file mode 100644
index 00000000000..27e237b15c4
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverAction.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.TextSelection;
+
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+import org.eclipse.search.ui.NewSearchUI;
+
+import org.eclipse.search2.internal.ui.InternalSearchUI;
+import org.eclipse.search2.internal.ui.SearchView;
+
+abstract public class RetrieverAction extends Action {
+ public RetrieverAction() {
+ }
+
+ public void run() {
+ IWorkbenchPage page= getWorkbenchPage();
+ if (page == null) {
+ return;
+ }
+
+ RetrieverQuery query= new RetrieverQuery(page);
+ RetrieverPage.initializeQuery(query);
+ if (modifyQuery(query)) {
+ String searchPattern= query.getSearchText();
+ if (searchPattern == null || searchPattern.length() == 0) {
+ SearchView view= (SearchView) InternalSearchUI.getInstance().getSearchViewManager().activateSearchView(true);
+ view.showEmptySearchPage(RetrieverPage.ID);
+ } else {
+ NewSearchUI.runQueryInBackground(query);
+ }
+ }
+ }
+
+ abstract protected boolean modifyQuery(RetrieverQuery query);
+ abstract protected IWorkbenchPage getWorkbenchPage();
+
+ final protected String extractSearchTextFromEditor(IEditorPart editor) {
+ if (editor != null) {
+ ITextSelection selection= null;
+ ISelectionProvider provider= editor.getEditorSite().getSelectionProvider();
+ if (provider != null) {
+ ISelection s= provider.getSelection();
+ if (s instanceof ITextSelection) {
+ selection= (ITextSelection) s;
+ }
+ }
+
+ if (selection != null) {
+ if (selection.getLength() == 0) {
+ ITextEditor txtEditor= getTextEditor(editor);
+ if (txtEditor != null) {
+ IDocument document= txtEditor.getDocumentProvider().getDocument(txtEditor.getEditorInput());
+ selection= expandSelection(selection, document, null);
+ }
+ }
+
+ if (selection.getLength() > 0) {
+ return trimSearchString(selection.getText());
+ }
+ }
+ }
+ return null;
+ }
+
+ final protected String extractSearchTextFromSelection(ISelection sel) {
+ if (sel instanceof ITextSelection) {
+ return trimSearchString(((ITextSelection) sel).getText());
+ }
+ return null;
+ }
+
+ private String trimSearchString(String text) {
+ int idx= text.indexOf('\n');
+ int idx2= text.indexOf('\r');
+ if (idx2 >= 0 && idx2 < idx) {
+ idx= idx2;
+ }
+ if (idx >= 0) {
+ text= text.substring(0, idx);
+ }
+ return text.trim();
+ }
+
+ private ITextEditor getTextEditor(IEditorPart editor) {
+ if (editor instanceof ITextEditor) {
+ return (ITextEditor) editor;
+ } else
+ if (editor instanceof FormEditor) {
+ FormEditor me= (FormEditor) editor;
+ editor= me.getActiveEditor();
+ if (editor instanceof ITextEditor) {
+ return (ITextEditor) editor;
+ }
+ }
+ return null;
+ }
+
+ private ITextSelection expandSelection(ITextSelection sel, IDocument document, String stopChars) {
+ int offset= sel.getOffset();
+ int length= sel.getLength();
+
+ // in case the length is zero we have to decide whether to go
+ // left or right.
+ if (length == 0) {
+ // try right
+ char chr= 0;
+ char chl= 0;
+ try {
+ chr= document.getChar(offset);
+ } catch (BadLocationException e2) {
+ }
+ try {
+ chl= document.getChar(offset - 1);
+ } catch (BadLocationException e2) {
+ }
+
+ if (isPartOfIdentifier(chr)) {
+ length= 1;
+ } else
+ if (isPartOfIdentifier(chl)) {
+ offset--;
+ length= 1;
+ } else
+ if (stopChars != null && stopChars.indexOf(chr) == -1) {
+ length= 1;
+ } else
+ if (stopChars != null && stopChars.indexOf(chl) == -1) {
+ offset--;
+ length= 1;
+ } else {
+ return sel;
+ }
+ }
+
+ int a= offset + length - 1;
+ int z= a;
+
+ // move z one behind last character.
+ try {
+ char ch= document.getChar(z);
+ while (isValidChar(stopChars, ch)) {
+ ch= document.getChar(++z);
+ }
+ } catch (BadLocationException e2) {
+ }
+ // move a one before the first character
+ try {
+ char ch= document.getChar(a);
+ while (isValidChar(stopChars, ch)) {
+ ch= document.getChar(--a);
+ }
+ } catch (BadLocationException e2) {
+ }
+
+ if (a == z) {
+ offset= a;
+ length= 0;
+ } else {
+ offset= a + 1;
+ length= z - a - 1;
+ }
+ return new TextSelection(document, offset, length);
+ }
+
+ private boolean isValidChar(String stopChars, char ch) {
+ return stopChars == null ? isPartOfIdentifier(ch) : stopChars.indexOf(ch) == -1;
+ }
+
+ private boolean isPartOfIdentifier(char ch) {
+ return Character.isLetterOrDigit(ch) || ch == '_';
+ }
+
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverContentProvider.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverContentProvider.java
new file mode 100644
index 00000000000..889e2ee5148
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverContentProvider.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.Viewer;
+
+import org.eclipse.search.ui.text.AbstractTextSearchResult;
+
+import org.eclipse.search.internal.ui.text.IFileSearchContentProvider;
+
+public class RetrieverContentProvider implements ITreeContentProvider, IFileSearchContentProvider {
+ private static final Object[] EMPTY_ARR= new Object[0];
+ private RetrieverResult fResult;
+ private RetrieverTreeViewer fTreeViewer;
+ private Map fChildrenMap;
+ private int[] fMatchCount;
+ private HashSet fAutoExpand= new HashSet();
+ private boolean fFlatLayout;
+
+ public RetrieverContentProvider(RetrieverTreeViewer viewer, boolean flatLayout) {
+ fTreeViewer= viewer;
+ fFlatLayout= flatLayout;
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof RetrieverLine) {
+ return ((RetrieverLine) element).getParent();
+ }
+ if (element instanceof IProject) {
+ return null;
+ }
+ if (element instanceof IResource) {
+ IResource resource= (IResource) element;
+ return fFlatLayout ? null : resource.getParent();
+ }
+ return null;
+ }
+
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ public void dispose() {
+ // nothing to do
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ if (newInput instanceof AbstractTextSearchResult) {
+ initialize((AbstractTextSearchResult) newInput);
+ }
+ }
+
+
+ protected synchronized void initialize(AbstractTextSearchResult result) {
+ fResult= (RetrieverResult) result;
+ fChildrenMap= new HashMap();
+ fAutoExpand.clear();
+ fMatchCount= null;
+ if (result != null) {
+ Object[] elements= result.getElements();
+ for (int i= 0; i < elements.length; i++) {
+ Object element= elements[i];
+ if (fResult.getDisplayedMatchCount(element) > 0) {
+ insert(element, false, null, null);
+ }
+ }
+ updateFilterItem(false, null, null);
+ }
+ }
+
+ protected void insert(Object child, boolean refreshViewer, HashSet refreshElems, HashMap insertElems) {
+ Object parent= getParent(child);
+ Object dummyParent= parent;
+ if (parent == null) {
+ dummyParent= fResult;
+ }
+
+ // add child to our childmap
+ if (insertInMap(dummyParent, child, fChildrenMap)) {
+ if (refreshViewer) {
+ insertInMap(dummyParent, child, insertElems);
+ }
+ if (parent != null) {
+ insert(parent, refreshViewer, refreshElems, insertElems);
+ }
+ }
+ }
+
+ /**
+ * returns true if the child was added.
+ */
+ private boolean insertInMap(Object parent, Object child, Map map) {
+ Set children= (Set) map.get(parent);
+ if (children == null) {
+ children= new HashSet();
+ map.put(parent, children);
+ }
+ return children.add(child);
+ }
+
+ protected void remove(Object element, boolean refreshViewer, HashSet refreshElems) {
+ // precondition here: fResult.getMatchCount(child) <= 0
+
+ if (hasChildren(element)) {
+ if (refreshViewer) {
+ refreshElems.add(element);
+ }
+ } else {
+ fChildrenMap.remove(element);
+ Object parent= getParent(element);
+ if (parent != null) {
+ if (removeFromSiblings(element, parent)) {
+ remove(parent, refreshViewer, refreshElems);
+ }
+ } else {
+ if (removeFromSiblings(element, fResult)) {
+ if (refreshViewer) {
+ refreshElems.add(fResult);
+ }
+ }
+ }
+ }
+ }
+
+ private boolean removeFromSiblings(Object element, Object parent) {
+ Set siblings= (Set) fChildrenMap.get(parent);
+ if (siblings != null) {
+ return siblings.remove(element);
+ }
+ return false;
+ }
+
+ public Object[] getChildren(Object parentElement) {
+ Set children= (Set) fChildrenMap.get(parentElement);
+ if (children == null)
+ return EMPTY_ARR;
+ return children.toArray();
+ }
+
+ public boolean hasChildren(Object element) {
+ return getChildren(element).length > 0;
+ }
+
+ public synchronized void elementsChanged(final Object[] updatedElements) {
+ if (updatedElements.length == 0) {
+ return;
+ }
+ Runnable r= new Runnable() {
+ public void run() {
+ handeElementsChanged(updatedElements);
+ }
+ };
+ fTreeViewer.preservingSelection(r);
+ }
+
+ private void handeElementsChanged(final Object[] updatedElements) {
+ final HashSet refreshElems= new HashSet();
+ final HashMap insertElems= new HashMap();
+ updateFilterItem(true, refreshElems, insertElems);
+ for (int i= 0; i < updatedElements.length; i++) {
+ Object updatedElem= updatedElements[i];
+ if (fResult.getDisplayedMatchCount(updatedElem) > 0) {
+ insert(updatedElem, true, refreshElems, insertElems);
+ } else {
+ remove(updatedElem, true, refreshElems);
+ }
+ }
+ if (refreshElems.contains(fResult)) {
+ fTreeViewer.refresh();
+ } else {
+ for (Iterator iter= refreshElems.iterator(); iter.hasNext();) {
+ Object elem= iter.next();
+ Object parent= getParent(elem);
+ if (!containsElemOrAParent(refreshElems, parent)) {
+ fTreeViewer.refresh(elem);
+ }
+ }
+ }
+
+ Object[] insertParents= insertElems.keySet().toArray();
+ for (int i= 0; i < insertParents.length; i++) {
+ Object element= insertParents[i];
+ insertInView(element, refreshElems, insertElems);
+ }
+ }
+
+ private void updateFilterItem(boolean updateViewer, final HashSet refreshElems, final HashMap insertElems) {
+ if (fResult != null) {
+ int[] matchCount= fResult.getDetailedMatchCount();
+ if (matchCount[0] == matchCount[1]) {
+ if (fMatchCount != null) {
+ remove(fMatchCount, updateViewer, refreshElems);
+ fMatchCount= null;
+ }
+ } else {
+ if (fMatchCount != null) {
+ fMatchCount[0]= matchCount[0];
+ fMatchCount[1]= matchCount[1];
+ refreshElems.add(fMatchCount);
+ } else {
+ fMatchCount= matchCount;
+ insert(fMatchCount, updateViewer, refreshElems, insertElems);
+ }
+ }
+ }
+ }
+
+ private boolean insertInView(Object element, HashSet refreshElems, HashMap insertElems) {
+ Object parent= getParent(element);
+ if (parent == null) {
+ parent= fResult;
+ }
+ Collection children= (Collection) insertElems.remove(element);
+ if (children == null) {
+ return !containsElemOrAParent(refreshElems, element);
+ }
+
+ boolean needToInsert= true;
+ if (element != fResult) {
+ needToInsert= insertInView(parent, refreshElems, insertElems);
+ }
+ if (needToInsert) {
+ needToInsert= !refreshElems.contains(element);
+ }
+ if (needToInsert) {
+ fTreeViewer.add(element, children.toArray());
+ }
+ if (fAutoExpand.contains(element)) {
+ fTreeViewer.setExpandedState(element, true);
+ }
+ return needToInsert;
+ }
+
+ private boolean containsElemOrAParent(final HashSet set, Object elem) {
+ while (elem != null) {
+ if (set.contains(elem)) {
+ return true;
+ }
+ elem= getParent(elem);
+ }
+ return set.contains(fResult);
+ }
+
+ public void clear() {
+ initialize(fResult);
+ fTreeViewer.refresh();
+ }
+
+ public AbstractTextSearchResult getResult() {
+ return fResult;
+ }
+
+ public void onExpansionStateChange(Object element, boolean expanded) {
+ if (!expanded) {
+ fAutoExpand.remove(element);
+ } else {
+ fAutoExpand.add(element);
+ }
+ }
+
+ public void setLayout(boolean flat) {
+ if (flat != fFlatLayout) {
+ fFlatLayout= flat;
+ initialize(fResult);
+ }
+ }
+
+ // this works around the fact that expansion change is not reported when
+ // the selection is set via next/previous.
+ public void onSelectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection sel= (IStructuredSelection) event.getSelection();
+ Object element= sel.getFirstElement();
+ if (element != null) {
+ element= getParent(element);
+ while (element != null && fAutoExpand.add(element)) {
+ element= getParent(element);
+ }
+ }
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFilter.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFilter.java
new file mode 100644
index 00000000000..b34fab5ec63
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFilter.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.search.internal.core.text.PatternConstructor;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class RetrieverFilter {
+ private static String sLastCauseForError;
+ private Pattern fFilterPattern;
+ private String fFilterText;
+ private int fAcceptedLocations;
+ private boolean fIsRegex;
+ private boolean fHideMatching;
+ private int fOriginatorsHash;
+
+ public RetrieverFilter(RetrieverPage page, int acceptedLocations, String filterText, boolean isRegex, boolean hideMatching, int originatorsHash) {
+
+ fOriginatorsHash= originatorsHash;
+ fFilterPattern= null;
+ fFilterText= null;
+ if (filterText != null) {
+ if (filterText.length() != 0) {
+ try {
+ fFilterPattern= PatternConstructor.createPattern(filterText, isRegex, false, false, false);
+ fFilterText= filterText;
+ } catch (Exception e) {
+ if (page != null && !filterText.equals(sLastCauseForError)) {
+ page.showError(SearchMessages.RetrieverFindTab_Error_invalidRegex + e.getMessage());
+ }
+ }
+ sLastCauseForError= filterText;
+ }
+ }
+ fAcceptedLocations= acceptedLocations;
+ fIsRegex= isRegex;
+ fHideMatching= hideMatching;
+ }
+
+ public RetrieverFilter() {
+ fAcceptedLocations= IRetrieverKeys.ALL_LOCATIONS;
+ }
+
+ public int getOriginatorsHash() {
+ return fOriginatorsHash;
+ }
+
+ public boolean getHideMatching() {
+ return fHideMatching;
+ }
+
+ public int getAcceptedLocations() {
+ return fAcceptedLocations;
+ }
+
+ public Pattern getPattern() {
+ return fFilterPattern;
+ }
+
+ public boolean getIsRegex() {
+ return fIsRegex;
+ }
+
+ public String getFilterString() {
+ return fFilterText;
+ }
+
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFilterTab.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFilterTab.java
new file mode 100644
index 00000000000..b801e12f19e
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFilterTab.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+import org.eclipse.search.core.text.AbstractTextFileScanner;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+/**
+ * @author markus.schorn@windriver.com
+ */
+public class RetrieverFilterTab implements IRetrieverKeys {
+ private RetrieverPage fView;
+
+ private boolean fEnable;
+ private boolean fEnableLocation;
+ private boolean fEnableString;
+
+ private Button fUseLocationFilter;
+ private Button fCommentFilter;
+ private Button fStringFilter;
+ private Button fIncludeFilter;
+ private Button fPrepFilter;
+ private Button fFunctionFilter;
+ private Button fOtherFilter;
+
+ private Button fUseStringFilter;
+ private Combo fFilterString;
+ private Button fHideMatching;
+ private Button fRegularExpressionFilter;
+
+ private Control[][] fEnableDisable;
+
+
+ RetrieverFilterTab(RetrieverPage view) {
+ fView= view;
+ }
+
+ public void createControl(Composite parent) {
+ int indent= 15;
+ GridData gd;
+ GridLayout gl;
+
+ Composite outer= new Composite(parent, SWT.NONE);
+ outer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ outer.setLayout(gl= new GridLayout(1, false));
+ gl.marginHeight= gl.marginWidth= 0;
+ gl.verticalSpacing= 2;
+
+ fUseLocationFilter= new Button(outer, SWT.CHECK);
+ fUseLocationFilter.setText(SearchMessages.RetrieverFilterTab_LocationFilter_text);
+ fUseLocationFilter.setLayoutData(new GridData());
+
+ // location group
+ Composite locationGroup= new Composite(outer, SWT.NONE);
+ locationGroup.setLayoutData(gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ gd.horizontalIndent= indent;
+
+ locationGroup.setLayout(gl= new GridLayout(3, false));
+ gl.marginWidth= 0;
+ gl.marginHeight= 0;
+ gl.verticalSpacing= 0;
+
+ // line 3, 4
+ fCommentFilter= new Button(locationGroup, SWT.CHECK);
+ fCommentFilter.setText(SearchMessages.RetrieverFilterTab_Comment_text);
+
+ fIncludeFilter= new Button(locationGroup, SWT.CHECK);
+ fIncludeFilter.setText(SearchMessages.RetrieverFilterTab_Import_text);
+
+ if (TextFileScannerRegistry.getInstance().hasPreprocessorSupport()) {
+ fPrepFilter= new Button(locationGroup, SWT.CHECK);
+ fPrepFilter.setText(SearchMessages.RetrieverFilterTab_Preprocessor_text);
+ } else {
+ new Label(locationGroup, SWT.NONE);
+ }
+
+ fStringFilter= new Button(locationGroup, SWT.CHECK);
+ fStringFilter.setText(SearchMessages.RetrieverFilterTab_String_text);
+
+ if (TextFileScannerRegistry.getInstance().hasFunctionSupport()) {
+ fFunctionFilter= new Button(locationGroup, SWT.CHECK);
+ fFunctionFilter.setText(SearchMessages.RetrieverFilterTab_FunctionBody_text);
+ }
+
+ fOtherFilter= new Button(locationGroup, SWT.CHECK);
+ fOtherFilter.setText(SearchMessages.RetrieverFilterTab_OtherLocation_text);
+
+ // a bit of space before next line
+ Label separator2= new Label(outer, SWT.SEPARATOR | SWT.HORIZONTAL);
+ separator2.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ new Label(outer, SWT.NONE).setLayoutData(gd= new GridData());
+ gd.heightHint= 5;
+
+ // text filter
+ Composite indepAlign= new Composite(outer, SWT.NONE);
+ indepAlign.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ indepAlign.setLayout(gl= new GridLayout(2, false));
+ gl.marginHeight= gl.marginWidth= 0;
+
+ fUseStringFilter= new Button(indepAlign, SWT.CHECK);
+ fUseStringFilter.setLayoutData(new GridData());
+ fUseStringFilter.setText(SearchMessages.RetrieverFilterTab_TextFilter_text);
+
+ fFilterString= new Combo(indepAlign, SWT.NONE);
+ fFilterString.setVisibleItemCount(VISIBLE_ITEMS_IN_COMBO);
+ fFilterString.setLayoutData(gd= new GridData(GridData.FILL_HORIZONTAL));
+ gd.widthHint= 20;
+
+ indepAlign= new Composite(outer, SWT.NONE);
+ indepAlign.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+ indepAlign.setLayout(gl= new GridLayout(2, false));
+ gl.marginHeight= gl.marginWidth= 0;
+
+ fRegularExpressionFilter= new Button(indepAlign, SWT.CHECK);
+ fRegularExpressionFilter.setText(SearchMessages.RetrieverFindTab_regularExpression);
+
+ fHideMatching= new Button(indepAlign, SWT.CHECK);
+ fHideMatching.setText(SearchMessages.RetrieverFilterTab_HideMatching_text);
+
+ fEnableDisable= new Control[][] { {fCommentFilter, fStringFilter, fIncludeFilter, fPrepFilter, fFunctionFilter, fOtherFilter}, {fFilterString, fHideMatching, fRegularExpressionFilter}};
+ }
+
+ void createListeners() {
+ SelectionListener s= new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onEnableFilter();
+ }
+ };
+ fUseLocationFilter.addSelectionListener(s);
+ fUseStringFilter.addSelectionListener(s);
+ fFilterString.addKeyListener(new KeyListener() {
+ public void keyPressed(KeyEvent e) {
+ }
+
+ public void keyReleased(KeyEvent e) {
+ if ((e.character == SWT.LF || e.character == SWT.CR)) {
+ onFilter();
+ selectStringFilter();
+ }
+ }
+ });
+ fFilterString.addFocusListener(new FocusListener() {
+ public void focusGained(FocusEvent e) {
+ }
+
+ public void focusLost(FocusEvent e) {
+ onFilter();
+ }
+ });
+
+ SelectionListener onFilter= new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onFilter();
+ }
+ };
+ fHideMatching.addSelectionListener(onFilter);
+ fRegularExpressionFilter.addSelectionListener(onFilter);
+ fStringFilter.addSelectionListener(onFilter);
+ fCommentFilter.addSelectionListener(onFilter);
+ fIncludeFilter.addSelectionListener(onFilter);
+ if (fPrepFilter != null) {
+ fPrepFilter.addSelectionListener(onFilter);
+ }
+ if (fFunctionFilter != null) {
+ fFunctionFilter.addSelectionListener(onFilter);
+ }
+ fOtherFilter.addSelectionListener(onFilter);
+ }
+
+ protected void onEnableFilter() {
+ boolean el= fUseLocationFilter.getSelection();
+ boolean es= fUseStringFilter.getSelection();
+ fEnable= el || es;
+ if (fEnable) {
+ fEnableLocation= el;
+ fEnableString= es;
+ }
+ // reroute through the enable filter on the view
+ fView.onEnableToolbarFilter(fEnable);
+ }
+
+ protected void onFilter() {
+ storeValues();
+ fView.onFilterTabChanged();
+ }
+
+ public RetrieverFilter getFilter() {
+ if (fEnable) {
+ return new RetrieverFilter(fView, getAcceptedLocations(), getFilterText(), fRegularExpressionFilter.getSelection(), fHideMatching.getSelection(), hashCode());
+ }
+ return new RetrieverFilter();
+ }
+
+ private int getAcceptedLocations() {
+ int acceptLocations= ALL_LOCATIONS;
+ if (fUseLocationFilter.getSelection()) {
+ acceptLocations= 0;
+ if (fStringFilter.getSelection()) {
+ acceptLocations|= (1 << AbstractTextFileScanner.LOCATION_STRING_LITERAL);
+ }
+ if (fCommentFilter.getSelection()) {
+ acceptLocations|= (1 << AbstractTextFileScanner.LOCATION_COMMENT);
+ }
+ if (fIncludeFilter.getSelection()) {
+ acceptLocations|= (1 << AbstractTextFileScanner.LOCATION_IMPORT_OR_INCLUDE_STATEMENT);
+ }
+ if (fPrepFilter == null || fPrepFilter.getSelection()) {
+ acceptLocations|= (1 << AbstractTextFileScanner.LOCATION_PREPROCESSOR_DIRECTIVE);
+ }
+ if (fFunctionFilter == null || fFunctionFilter.getSelection()) {
+ acceptLocations|= (1 << AbstractTextFileScanner.LOCATION_FUNCTION);
+ }
+ if (fOtherFilter.getSelection()) {
+ acceptLocations|= (1 << AbstractTextFileScanner.LOCATION_OTHER);
+ }
+ }
+ return acceptLocations;
+ }
+
+ private String getFilterText() {
+ return fUseStringFilter.getSelection() ? fFilterString.getText() : null;
+ }
+
+
+ void storeValues() {
+ fView.storeValue(fEnableString, KEY_ENABLE_TEXT_FILTER);
+ fView.storeValue(fEnableLocation, KEY_ENABLE_LOCATION_FILTER);
+ fView.storeComboContent(fFilterString, KEY_FILTER_PATTERNS, MAX_FILTER_PATTERNS);
+ fView.storeButton(fHideMatching, KEY_INVERT_FILTER);
+ fView.storeButton(fRegularExpressionFilter, KEY_REGULAR_EXPRESSION_FILTER);
+ fView.storeButton(fCommentFilter, KEY_COMMENT_FILTER);
+ fView.storeButton(fStringFilter, KEY_STRING_FILTER);
+ fView.storeButton(fIncludeFilter, KEY_INCLUDE_FILTER);
+ fView.storeButton(fPrepFilter, KEY_PREP_FILTER);
+ fView.storeButton(fFunctionFilter, KEY_FUNCTION_FILTER);
+ fView.storeButton(fOtherFilter, KEY_ELSEWHERE_FILTER);
+ }
+
+ /**
+ * called when the view is created
+ */
+ void restoreValues(boolean filterEnabled) {
+ fEnable= filterEnabled;
+ fEnableLocation= fView.restoreValue(KEY_ENABLE_LOCATION_FILTER, true);
+ fEnableString= fView.restoreValue(KEY_ENABLE_TEXT_FILTER, false);
+ fUseLocationFilter.setSelection(fEnable && fEnableLocation);
+ fUseStringFilter.setSelection(fEnable && fEnableString);
+ fView.restoreCombo(fFilterString, KEY_FILTER_PATTERNS, ""); //$NON-NLS-1$
+ fView.restoreButton(fHideMatching, KEY_INVERT_FILTER, false);
+ fView.restoreButton(fRegularExpressionFilter, KEY_REGULAR_EXPRESSION_FILTER, false);
+ fView.restoreButton(fCommentFilter, KEY_COMMENT_FILTER, true);
+ fView.restoreButton(fStringFilter, KEY_STRING_FILTER, true);
+ fView.restoreButton(fIncludeFilter, KEY_INCLUDE_FILTER, true);
+ fView.restoreButton(fPrepFilter, KEY_PREP_FILTER, true);
+ fView.restoreButton(fFunctionFilter, KEY_FUNCTION_FILTER, true);
+ fView.restoreButton(fOtherFilter, KEY_ELSEWHERE_FILTER, true);
+ updateEnablement();
+ }
+
+ private void updateEnablement() {
+ enableAll(fEnableDisable[0], fEnable && fEnableLocation);
+ enableAll(fEnableDisable[1], fEnable && fEnableString);
+ }
+
+ private void enableAll(Control[] controls, boolean enable) {
+ for (int i= 0; i < controls.length; i++) {
+ Control control= controls[i];
+ if (control != null) {
+ control.setEnabled(enable);
+ }
+ }
+ }
+
+ public void onEnableToolbarFilter(boolean enable) {
+ fEnable= enable;
+ fUseLocationFilter.setSelection(fEnable && fEnableLocation);
+ fUseStringFilter.setSelection(fEnable && fEnableString);
+ updateEnablement();
+ selectStringFilter();
+ }
+
+ public void onSelected() {
+ selectStringFilter();
+ }
+
+ private void selectStringFilter() {
+ if (fFilterString.isEnabled()) {
+ fFilterString.setFocus();
+ fFilterString.setSelection(new Point(0, fFilterString.getText().length()));
+ }
+ }
+
+ public void getProperties(Properties props) {
+ if (fEnable) {
+ props.setProperty(KEY_ENABLE_FILTER, String.valueOf(true));
+ getProperty(props, KEY_COMMENT_FILTER, fCommentFilter);
+ getProperty(props, KEY_ELSEWHERE_FILTER, fOtherFilter);
+ getProperty(props, KEY_FILTER_PATTERNS, fFilterString);
+ getProperty(props, KEY_FUNCTION_FILTER, fFunctionFilter);
+ getProperty(props, KEY_INCLUDE_FILTER, fIncludeFilter);
+ getProperty(props, KEY_INVERT_FILTER, fHideMatching);
+ getProperty(props, KEY_PREP_FILTER, fPrepFilter);
+ getProperty(props, KEY_REGULAR_EXPRESSION_FILTER, fRegularExpressionFilter);
+ getProperty(props, KEY_STRING_FILTER, fStringFilter);
+ }
+ }
+
+ private void getProperty(Properties props, String key, Button button) {
+ if (button != null) {
+ props.setProperty(key, String.valueOf(button.getSelection()));
+ }
+ }
+
+ private void getProperty(Properties props, String key, Combo text) {
+ props.setProperty(key, text.getText());
+ }
+
+ public void setProperties(Properties props) {
+ if (Boolean.valueOf(props.getProperty(KEY_ENABLE_FILTER)).booleanValue()) {
+ fEnable= true;
+ setProperty(props, KEY_COMMENT_FILTER, fCommentFilter);
+ setProperty(props, KEY_INCLUDE_FILTER, fIncludeFilter);
+ setProperty(props, KEY_PREP_FILTER, fPrepFilter);
+ setProperty(props, KEY_STRING_FILTER, fStringFilter);
+ setProperty(props, KEY_FUNCTION_FILTER, fFunctionFilter);
+ setProperty(props, KEY_ELSEWHERE_FILTER, fOtherFilter);
+ setProperty(props, KEY_FILTER_PATTERNS, fFilterString);
+ setProperty(props, KEY_INVERT_FILTER, fHideMatching);
+ setProperty(props, KEY_REGULAR_EXPRESSION_FILTER, fRegularExpressionFilter);
+ } else {
+ fEnable= false;
+ }
+
+ updateEnablement();
+ }
+
+ private void setProperty(Properties props, String key, Combo combo) {
+ String property= props.getProperty(key);
+ if (property != null) {
+ combo.setText(property);
+ }
+ }
+
+ private void setProperty(Properties props, String key, Button button) {
+ if (button != null) {
+ String property= props.getProperty(key);
+ if (property != null) {
+ button.setSelection(Boolean.valueOf(property).booleanValue());
+ }
+ }
+ }
+
+ public boolean restoreFromResult(RetrieverFilter filter) {
+ // this came right back to me, so ignore it.
+ if (filter.getOriginatorsHash() == hashCode()) {
+ return fEnable;
+ }
+ int loc= filter.getAcceptedLocations();
+ Pattern pattern= filter.getPattern();
+ boolean el= (loc != ALL_LOCATIONS);
+ boolean es= (pattern != null);
+
+ fEnable= el || es;
+ if (fEnable) {
+ fEnableLocation= el;
+ fEnableString= es;
+ } else {
+ el= es= false;
+ }
+
+ fUseLocationFilter.setSelection(el);
+ fUseStringFilter.setSelection(es);
+
+ if (el) {
+ setButton(fCommentFilter, loc, AbstractTextFileScanner.LOCATION_COMMENT);
+ setButton(fStringFilter, loc, AbstractTextFileScanner.LOCATION_STRING_LITERAL);
+ setButton(fIncludeFilter, loc, AbstractTextFileScanner.LOCATION_IMPORT_OR_INCLUDE_STATEMENT);
+ setButton(fPrepFilter, loc, AbstractTextFileScanner.LOCATION_PREPROCESSOR_DIRECTIVE);
+ setButton(fFunctionFilter, loc, AbstractTextFileScanner.LOCATION_FUNCTION);
+ setButton(fOtherFilter, loc, AbstractTextFileScanner.LOCATION_OTHER);
+ }
+ if (es) {
+ fEnableString= true;
+ fUseStringFilter.setSelection(true);
+ fFilterString.setText(filter.getFilterString());
+ fRegularExpressionFilter.setSelection(filter.getIsRegex());
+ fHideMatching.setSelection(filter.getHideMatching());
+ }
+ updateEnablement();
+ return fEnable;
+ }
+
+ private void setButton(Button button, int allowedLoc, int loc) {
+ if (button != null) {
+ button.setSelection((allowedLoc & (1 << loc)) != 0);
+ }
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFindTab.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFindTab.java
new file mode 100644
index 00000000000..c4ca3405eab
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverFindTab.java
@@ -0,0 +1,429 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+import org.eclipse.jface.window.Window;
+
+import org.eclipse.search.ui.NewSearchUI;
+
+import org.eclipse.search.internal.ui.util.SWTUtil;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+/**
+ * @author markus.schorn@windriver.com
+ */
+public class RetrieverFindTab implements IRetrieverKeys {
+ private RetrieverPage fView;
+ private Combo fWorkingSetCombo;
+ private Button fChooseWorkingSetButton;
+ private Combo fSearchString;
+ private Button fCaseSensitive;
+ private Button fRegularExpression;
+ private Button fWholeWord;
+ private Button fSearchButton;
+ private Combo fFilePatterns;
+ private Button fFilePatternButton;
+ private Control[] fEnableDisable;
+ private Map fScopeMap= new HashMap();
+ private int fPermanentScopeCount;
+
+ RetrieverFindTab(RetrieverPage view) {
+ fView= view;
+ }
+
+ public void createControl(Composite group) {
+ GridData gd;
+ GridLayout gl;
+ group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ group.setLayout(new GridLayout(3, false));
+
+ fSearchString= new Combo(group, SWT.NONE);
+ fSearchString.setLayoutData(gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ fSearchString.setVisibleItemCount(VISIBLE_ITEMS_IN_COMBO);
+ gd.horizontalSpan= 2;
+ gd.widthHint= 20; // spr 112201
+
+ fSearchButton= new Button(group, SWT.PUSH);
+ fSearchButton.setText(SearchMessages.RetrieverFindTab_search);
+ fSearchButton.setLayoutData(gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ gd.horizontalSpan= 1;
+ SWTUtil.setButtonDimensionHint(fSearchButton);
+
+ Composite comp= new Composite(group, SWT.NONE);
+ comp.setLayoutData(gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ gd.horizontalSpan= 3;
+ comp.setLayout(gl= new GridLayout(3, false));
+ gl.marginHeight= gl.marginWidth= 0;
+
+ fCaseSensitive= new Button(comp, SWT.CHECK);
+ fCaseSensitive.setText(SearchMessages.RetrieverFindTab_caseSensitive);
+
+ fRegularExpression= new Button(comp, SWT.CHECK);
+ fRegularExpression.setText(SearchMessages.RetrieverFindTab_regularExpression);
+
+ fWholeWord= new Button(comp, SWT.CHECK);
+ fWholeWord.setText(SearchMessages.RetrieverFindTab_wholeWord);
+
+ Label separator= new Label(group, SWT.SEPARATOR | SWT.HORIZONTAL);
+ separator.setLayoutData(gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ gd.horizontalSpan= 3;
+ new Label(group, SWT.NONE).setLayoutData(gd= new GridData());
+ gd.horizontalSpan= 3;
+ gd.heightHint= 0;
+
+ Label scopeLabel= new Label(group, SWT.NONE);
+ scopeLabel.setText(SearchMessages.RetrieverFindTab_searchScope);
+
+ fWorkingSetCombo= new Combo(group, SWT.BORDER | SWT.READ_ONLY);
+ fWorkingSetCombo.setVisibleItemCount(VISIBLE_ITEMS_IN_COMBO);
+ fWorkingSetCombo.setLayoutData(gd= new GridData(GridData.FILL_HORIZONTAL));
+ gd.widthHint= 20;
+
+ fChooseWorkingSetButton= new Button(group, SWT.PUSH);
+ fChooseWorkingSetButton.setText(SearchMessages.RetrieverFindTab_choose);
+ fChooseWorkingSetButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ SWTUtil.setButtonDimensionHint(fChooseWorkingSetButton);
+
+ Label filePatternLabel= new Label(group, SWT.NONE);
+ filePatternLabel.setText(SearchMessages.RetrieverFindTab_filePatterns);
+
+ fFilePatterns= new Combo(group, SWT.NONE);
+ fFilePatterns.setVisibleItemCount(VISIBLE_ITEMS_IN_COMBO);
+ fFilePatterns.setLayoutData(gd= new GridData(GridData.FILL_HORIZONTAL));
+ gd.widthHint= 20;
+
+ fFilePatternButton= new Button(group, SWT.PUSH);
+ fFilePatternButton.setText(SearchMessages.RetrieverFindTab_choose);
+ fFilePatternButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ SWTUtil.setButtonDimensionHint(fFilePatternButton);
+
+ fEnableDisable= new Control[] {fSearchString, fSearchButton, fCaseSensitive, fRegularExpression, fWholeWord, scopeLabel, fWorkingSetCombo, fChooseWorkingSetButton, filePatternLabel, fFilePatterns, fFilePatternButton};
+
+ setupScopeCombo();
+ }
+
+ // overrider
+ public void setFocus() {
+ fSearchString.setSelection(new Point(0, fSearchString.getText().length()));
+ fSearchString.setFocus();
+ }
+
+ public void dispose() {
+ }
+
+ void storeValues() {
+ IScopeDescription scope= getSearchScope();
+ fView.storeComboContent(fFilePatterns, KEY_FILE_PATTERNS, MAX_FILE_PATTERNS);
+ fView.storeComboContent(fSearchString, KEY_SEARCH_STRINGS, MAX_SEARCH_STRINGS);
+ fView.storeButton(fCaseSensitive, KEY_CASE_SENSITIVE_SEARCH);
+ fView.storeButton(fRegularExpression, KEY_REGULAR_EXPRESSION_SEARCH);
+ fView.storeButton(fWholeWord, KEY_WHOLE_WORD);
+ storeScopeCombo();
+
+ RetrieverPage.sLastFilePatterns= fFilePatterns.getText();
+ RetrieverPage.sLastSearchPattern= fSearchString.getText();
+ RetrieverPage.sLastIsCaseSensitive= fCaseSensitive.getSelection();
+ RetrieverPage.sLastIsRegularExpression= fRegularExpression.getSelection();
+ RetrieverPage.sLastIsWholeWord= fWholeWord.getSelection();
+ RetrieverPage.sLastScope= scope;
+ }
+
+ private void storeScopeCombo() {
+ String[] names= fWorkingSetCombo.getItems();
+ fView.storeValue(names, KEY_SCOPE_HISTORY);
+ for (int i= fPermanentScopeCount; i < names.length; i++) {
+ String name= names[i];
+ IScopeDescription scope= (IScopeDescription) fScopeMap.get(name);
+ if (scope != null) {
+ fView.storeScope(scope, KEY_SCOPE_HISTORY + "-" + name); //$NON-NLS-1$
+ }
+ }
+ IScopeDescription scope= getSearchScope();
+ fView.storeScope(scope, KEY_SEARCH_SCOPE);
+ }
+
+ void restoreValues() {
+ fView.restoreCombo(fFilePatterns, KEY_FILE_PATTERNS, "*.c,*.ci,*.h,*.java"); //$NON-NLS-1$
+ fView.restoreCombo(fSearchString, KEY_SEARCH_STRINGS, null);
+ fView.restoreButton(fCaseSensitive, KEY_CASE_SENSITIVE_SEARCH, true);
+ fView.restoreButton(fRegularExpression, KEY_REGULAR_EXPRESSION_SEARCH, false);
+ fView.restoreButton(fWholeWord, KEY_WHOLE_WORD, true);
+ fFilePatterns.clearSelection();
+ setupScopeCombo();
+ }
+
+ private void setupScopeCombo() {
+ fWorkingSetCombo.removeAll();
+ fPermanentScopeCount= 4;
+ addScopeToCombo(new WorkspaceScopeDescription(), false);
+ addScopeToCombo(new CurrentProjectScopeDescription(), false);
+ addScopeToCombo(new CurrentFileScopeDescription(), false);
+ addScopeToCombo(new WindowWorkingSetScopeDescription(), false);
+
+ String[] names= fView.restoreValue(KEY_SCOPE_HISTORY, null);
+ if (names != null) {
+ for (int i= names.length - 1; i >= 0; i--) {
+ String name= names[i];
+ IScopeDescription scope= fView.restoreScope(KEY_SCOPE_HISTORY + "-" + name); //$NON-NLS-1$
+ if (scope != null) {
+ addScopeToCombo(scope, false);
+ }
+ }
+ }
+ IScopeDescription scope= fView.restoreScope(KEY_SEARCH_SCOPE);
+ addScopeToCombo(scope, false);
+ }
+
+ void createListeners() {
+ fSearchButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onSearch();
+ }
+ });
+ fSearchString.addKeyListener(new KeyListener() {
+ public void keyPressed(KeyEvent e) {
+ }
+
+ public void keyReleased(KeyEvent e) {
+ String text= fSearchString.getText();
+ if ((e.character == SWT.LF || e.character == SWT.CR) && text.length() > 0) {
+ onSearch();
+ }
+ RetrieverPage.sLastSearchPattern= text;
+ }
+ });
+ fChooseWorkingSetButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onChooseButtonSelectWorkingSet();
+ }
+ });
+ fFilePatternButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onChooseButtonSelectFilePatterns();
+ }
+ });
+ fSearchString.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ RetrieverPage.sLastSearchPattern= fSearchString.getText();
+ }
+ });
+ fCaseSensitive.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ RetrieverPage.sLastIsCaseSensitive= fCaseSensitive.getSelection();
+ }
+ });
+ fRegularExpression.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ RetrieverPage.sLastIsRegularExpression= fRegularExpression.getSelection();
+ }
+ });
+ fWholeWord.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ RetrieverPage.sLastIsWholeWord= fWholeWord.getSelection();
+ }
+ });
+ fFilePatterns.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ RetrieverPage.sLastFilePatterns= fFilePatterns.getText();
+ }
+ });
+ fWorkingSetCombo.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ RetrieverPage.sLastScope= getSearchScope();
+ }
+ });
+ }
+
+ protected void onSearch() {
+ // first do a few checks!
+ String searchText= fSearchString.getText();
+ if (searchText.length() == 0) {
+ fView.showError(SearchMessages.RetrieverFindTab_Error_emptySearchString);
+ return;
+ }
+ if (fRegularExpression.getSelection()) {
+ Pattern pattern= null;
+ try {
+ pattern= Pattern.compile(searchText);
+ } catch (Exception e) {
+ fView.showError(SearchMessages.RetrieverFindTab_Error_invalidRegex + e.getMessage());
+ return;
+ }
+
+ if (pattern.matcher("").find()) { //$NON-NLS-1$
+ boolean cont= fView.showQuestion(SearchMessages.RetrieverFindTab_Question_regexMatchesEmptyString);
+ if (!cont) {
+ return;
+ }
+ }
+ }
+
+ fView.storeValues();
+ RetrieverQuery query= new RetrieverQuery(fView.getSite().getPage());
+ query.setSearchString(RetrieverPage.sLastSearchPattern);
+ query.setIsCaseSensitive(RetrieverPage.sLastIsCaseSensitive);
+ query.setIsRegularExpression(RetrieverPage.sLastIsRegularExpression);
+ query.setIsWholeWord(RetrieverPage.sLastIsWholeWord);
+ query.setSearchScope(RetrieverPage.sLastScope, RetrieverPage.sLastConsiderDerivedResources);
+ query.setFilePatterns(RetrieverPage.sLastFilePatterns, RetrieverPage.sLastUseCaseSensitiveFilePatterns);
+ query.setSearchOrder(fView.getPreferredSearchOrder());
+
+ RetrieverResult result= (RetrieverResult) query.getSearchResult();
+ fView.initFilter(result);
+ fView.storeValues();
+ NewSearchUI.runQueryInBackground(query, fView.getViewPart());
+ }
+
+ private IScopeDescription getSearchScope() {
+ String scopeLabel= fWorkingSetCombo.getText();
+ IScopeDescription result= (IScopeDescription) fScopeMap.get(scopeLabel);
+ return result == null ? new WorkspaceScopeDescription() : result;
+ }
+
+ protected void onChooseButtonSelectWorkingSet() {
+ IScopeDescription scope= getSearchScope();
+ IScopeDescription use= WorkingSetScopeDescription.createWithDialog(fView.getSite().getPage(), scope);
+ if (use != null) {
+ addScopeToCombo(use, false);
+ }
+ }
+
+ protected void onChooseButtonSelectFilePatterns() {
+ FilePatternSelectionDialog dlg= new FilePatternSelectionDialog(fView.getSite().getShell(), fFilePatterns.getText());
+ if (dlg.open() == Window.OK) {
+ setCombo(fFilePatterns, dlg.getFilePatterns(), 0, MAX_FILE_PATTERNS, false);
+ }
+ }
+
+ void updateEnablement(boolean searchInProgress) {
+ for (int i= 0; i < fEnableDisable.length; i++) {
+ fEnableDisable[i].setEnabled(!searchInProgress);
+ }
+ }
+
+ public void onSelected() {
+ setFocus();
+ }
+
+ public void storeValues(Properties props) {
+ props.setProperty(KEY_FILE_PATTERNS, fFilePatterns.getText());
+ props.setProperty(KEY_SEARCH_STRINGS, fSearchString.getText());
+ storeButton(props, KEY_CASE_SENSITIVE_SEARCH, fCaseSensitive);
+ storeButton(props, KEY_REGULAR_EXPRESSION_SEARCH, fRegularExpression);
+ storeButton(props, KEY_WHOLE_WORD, fWholeWord);
+ storeScope(props, getSearchScope());
+ }
+
+ private void storeScope(Properties props, IScopeDescription searchScope) {
+ props.setProperty(KEY_SCOPE_DESCRIPTOR_CLASS, searchScope.getClass().getName());
+ searchScope.store(props, KEY_SEARCH_SCOPE);
+ }
+
+ private void storeButton(Properties props, String key, Button button) {
+ props.setProperty(key, String.valueOf(button.getSelection()));
+ }
+
+ public void restoreValues(Properties props) {
+ restoreComboText(props, KEY_FILE_PATTERNS, fFilePatterns);
+ restoreComboText(props, KEY_SEARCH_STRINGS, fSearchString);
+ restoreButton(props, KEY_CASE_SENSITIVE_SEARCH, fCaseSensitive);
+ restoreButton(props, KEY_REGULAR_EXPRESSION_SEARCH, fRegularExpression);
+ restoreButton(props, KEY_WHOLE_WORD, fWholeWord);
+
+ IScopeDescription scope= restoreScope(props);
+ addScopeToCombo(scope, false);
+ }
+
+ private IScopeDescription restoreScope(Properties props) {
+ IScopeDescription scope= null;
+ try {
+ String scopeDescClass= props.getProperty(KEY_SCOPE_DESCRIPTOR_CLASS);
+ scope= (IScopeDescription) Class.forName(scopeDescClass).newInstance();
+ scope.restore(props, KEY_SEARCH_SCOPE);
+ } catch (Exception e) {
+ scope= new WorkspaceScopeDescription();
+ }
+ return scope;
+ }
+
+ private void restoreComboText(Properties props, String key, Combo combo) {
+ String property= props.getProperty(key);
+ if (property != null) {
+ combo.setText(property);
+ }
+ }
+
+ private void restoreButton(Properties props, String key, Button button) {
+ String property= props.getProperty(key);
+ if (property != null) {
+ button.setSelection(Boolean.valueOf(property).booleanValue());
+ }
+ }
+
+ public void restoreFromQuery(RetrieverQuery rq) {
+ fCaseSensitive.setSelection(rq.isCaseSensitive());
+ fRegularExpression.setSelection(rq.isRegularExpression());
+ fWholeWord.setSelection(rq.isWholeWord());
+
+ String searchFor= rq.getSearchText();
+ if (searchFor != null && searchFor.length() > 0) {
+ setCombo(fSearchString, rq.getSearchText(), 0, MAX_SEARCH_STRINGS, true);
+ }
+ setCombo(fFilePatterns, rq.getFilePatterns(), 0, MAX_FILE_PATTERNS, true);
+ addScopeToCombo(rq.getScopeDescription(), true);
+ }
+
+ private void addScopeToCombo(IScopeDescription scope, boolean moveExisting) {
+ String scopeLabel= scope.getLabel();
+ fScopeMap.put(scopeLabel, scope);
+ setCombo(fWorkingSetCombo, scope.getLabel(), fPermanentScopeCount, MAX_SCOPES, moveExisting);
+ RetrieverPage.sLastScope= scope;
+ }
+
+ private void setCombo(Combo combo, String value, int insertPos, int maxItems, boolean moveExisting) {
+ int idx= combo.indexOf(value);
+ if (idx < 0) {
+ insertPos= Math.min(combo.getItemCount(), insertPos);
+ combo.add(value, insertPos);
+ int itemCount= combo.getItemCount();
+ if (itemCount > maxItems) {
+ combo.remove(maxItems, itemCount - 1);
+ }
+ idx= insertPos;
+ } else
+ if (moveExisting && idx > insertPos) {
+ combo.remove(idx);
+ combo.add(value, insertPos);
+ }
+ combo.setText(value);
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverLabelProvider.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverLabelProvider.java
new file mode 100644
index 00000000000..008d80531ea
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverLabelProvider.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.text.MessageFormat;
+
+import org.eclipse.core.resources.IFile;
+
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.search.ui.text.AbstractTextSearchViewPage;
+
+import org.eclipse.search.internal.ui.SearchPluginImages;
+import org.eclipse.search.internal.ui.text.FileLabelProvider;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class RetrieverLabelProvider extends FileLabelProvider {
+ private boolean fAppendContainer= false;
+
+ public RetrieverLabelProvider(AbstractTextSearchViewPage page, int orderFlag) {
+ super(page, orderFlag);
+ }
+
+ public void setAppendFileContainer(boolean val) {
+ fAppendContainer= val;
+ }
+
+ public Image getImage(Object element) {
+ if (element instanceof RetrieverLine) {
+ return SearchPluginImages.get(SearchPluginImages.IMG_OBJ_TEXT_SEARCH_LINE);
+ }
+ return super.getImage(element);
+ }
+
+ public String getText(Object element) {
+ if (element instanceof RetrieverLine) {
+ RetrieverLine line= (RetrieverLine) element;
+ StringBuffer buf= new StringBuffer();
+ buf.append(String.valueOf(line.getLineNumber()));
+ buf.append(": "); //$NON-NLS-1$
+ buf.append(convertChars(line.getString()));
+ return buf.toString();
+ }
+ if (element instanceof int[]) {
+ int[] matchCount= (int[]) element;
+ Integer hidden= new Integer(matchCount[0] - matchCount[1]);
+ return MessageFormat.format(SearchMessages.RetrieverLabelProvider_FilterHidesMatches_label, new Object[] {hidden});
+ }
+ if (fAppendContainer && element instanceof IFile) {
+ IFile file= (IFile) element;
+ StringBuffer buf= new StringBuffer();
+ buf.append(file.getName());
+ buf.append(" - "); //$NON-NLS-1$
+ buf.append(file.getParent().getFullPath().toString());
+ return buf.toString();
+ }
+ return super.getText(element);
+ }
+
+ static String convertChars(CharSequence input) {
+ StringBuffer result= new StringBuffer();
+ for (int i= 0; i < input.length(); i++) {
+ char c= input.charAt(i);
+ switch (c) {
+ case '\r':
+ result.append("\\r");break; //$NON-NLS-1$
+ case '\n':
+ result.append("\\n");break; //$NON-NLS-1$
+ case '\t':
+ result.append(" ");break; //$NON-NLS-1$
+ default:
+ result.append(c);
+ break;
+ }
+ }
+ return result.toString();
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverLine.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverLine.java
new file mode 100644
index 00000000000..c04eb10878b
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverLine.java
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+import org.eclipse.core.resources.IFile;
+
+
+/**
+ * @author markus.schorn@windriver.com
+ */
+public class RetrieverLine implements IAdaptable {
+ private static final RetrieverMatch[] EMPTY_ARRAY= new RetrieverMatch[0];
+ private static final int HIGH_BIT= 1 << 31;
+
+ private IFile fParent;
+ private int fLineNumber;
+ private String fLineData;
+ private RetrieverMatch[] fMatches;
+
+ public RetrieverLine(IFile parent, int lineNumber) {
+ fParent= parent;
+ fLineNumber= lineNumber;
+ fMatches= null;
+ setIsFiltered(false);
+ }
+ public int getLineNumber() {
+ return fLineNumber & ~HIGH_BIT;
+ }
+ public void setData(String line) {
+ fLineData= line;
+ }
+
+ synchronized public void addMatch(RetrieverMatch match) {
+ if (fMatches == null) {
+ fMatches= new RetrieverMatch[] {match};
+ } else {
+ RetrieverMatch[] newMatches= new RetrieverMatch[fMatches.length + 1];
+ System.arraycopy(fMatches, 0, newMatches, 0, fMatches.length);
+ newMatches[fMatches.length]= match;
+ fMatches= newMatches;
+ }
+ }
+
+ synchronized public void filter(Pattern regex, boolean hideMatching, int acceptLocations, Collection changedMatches) {
+ boolean lineWasFiltered= isFiltered();
+ boolean lineIsFiltered= regex != null && regex.matcher(fLineData).find() == hideMatching;
+ for (int i= 0; i < fMatches.length; i++) {
+ RetrieverMatch match= fMatches[i];
+ boolean wasFiltered= lineWasFiltered || match.isFiltered();
+ boolean doFilter= lineIsFiltered || ((match.getKind() & acceptLocations) == 0);
+ if (wasFiltered != doFilter) {
+ if (changedMatches != null) {
+ changedMatches.add(match);
+ }
+ match.setFiltered(doFilter);
+ }
+ }
+ setIsFiltered(lineIsFiltered);
+ }
+
+ private void setIsFiltered(boolean value) {
+ if (value) {
+ fLineNumber|= HIGH_BIT;
+ } else {
+ fLineNumber&= ~HIGH_BIT;
+ }
+ }
+ public String getLine() {
+ return fLineData;
+ }
+
+ public RetrieverMatch[] getMatches(boolean copy) {
+ return copy ? (RetrieverMatch[]) fMatches.clone() : fMatches;
+ }
+
+ public IFile getParent() {
+ return fParent;
+ }
+
+ synchronized public void addMatchCount(int[] count) {
+ count[0]+= fMatches.length;
+ if (!isFiltered()) {
+ for (int i= 0; i < fMatches.length; i++) {
+ if (!fMatches[i].isFiltered()) {
+ count[1]++;
+ }
+ }
+ }
+ }
+
+ public int getLength() {
+ return fLineData.length();
+ }
+
+ public String getString() {
+ return getPreString(null);
+ }
+
+ synchronized public String getPreString(RetrieverMatch match) {
+ StringBuffer pre= new StringBuffer();
+ int offset= 0;
+ int lineLength= fLineData.length();
+ for (int i= 0; i < fMatches.length; i++) {
+ RetrieverMatch m= fMatches[i];
+ if (m == match) {
+ break;
+ }
+ if (m.isReplaced()) {
+ int start= m.getLineOffset();
+ if (start >= lineLength) {
+ break;
+ }
+ pre.append(fLineData.substring(offset, start));
+ pre.append(m.getReplacement());
+ offset= start + m.getOriginalLength();
+ if (offset >= lineLength) {
+ break;
+ }
+ }
+ if (m == match) {
+ break;
+ }
+ }
+ if (offset < lineLength) {
+ int end= match == null ? lineLength : Math.min(match.getLineOffset(), lineLength);
+ pre.append(fLineData.substring(offset, end));
+ }
+ return pre.toString();
+ }
+
+ synchronized public String computeReplacement(RetrieverMatch match, Pattern p, String replacement) {
+ if (match.getLineOffset() + match.getOriginalLength() > fLineData.length()) {
+ return null;
+ }
+ RetrieverMatch prev= null;
+ for (int i= 0; i < fMatches.length; i++) {
+ RetrieverMatch m= fMatches[i];
+ if (m == match) {
+ break;
+ }
+ prev= m;
+ }
+ // find a good point to start the find
+ int offsetInLine= prev == null ? 0 : prev.getLineOffset() + prev.getOriginalLength();
+ Matcher matcher= p.matcher(fLineData);
+ if (matcher.find(offsetInLine)) {
+ int shouldStart= match.getLineOffset();
+ if (shouldStart == matcher.start()) {
+ StringBuffer help= new StringBuffer();
+ try {
+ matcher.appendReplacement(help, replacement);
+ } catch (Exception e) {
+ return replacement.replaceAll("\\\\\\\\", "\\\\"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ return help.substring(shouldStart);
+ }
+ }
+ return null;
+ }
+
+ synchronized public String getPostString(RetrieverMatch match) {
+ StringBuffer post= new StringBuffer();
+ int offset= 0;
+ int lineLength= fLineData.length();
+ for (int i= 0; i < fMatches.length; i++) {
+ RetrieverMatch m= fMatches[i];
+ if (m == match) {
+ offset= match.getLineOffset() + match.getOriginalLength();
+ } else
+ if (offset > 0) {
+ if (m.isReplaced()) {
+ int start= m.getLineOffset();
+ if (start >= lineLength) {
+ break;
+ }
+ post.append(fLineData.substring(offset, start));
+ post.append(m.getReplacement());
+ offset= start + m.getOriginalLength();
+ if (offset >= lineLength) {
+ break;
+ }
+ }
+ }
+ }
+ if (offset < lineLength) {
+ post.append(fLineData.substring(offset, lineLength));
+ }
+ return post.toString();
+ }
+
+ public void setParent(IFile file) {
+ fParent= file;
+ }
+
+ synchronized public boolean checkState(boolean replace) {
+ for (int i= 0; i < fMatches.length; i++) {
+ RetrieverMatch match= fMatches[i];
+ if (!match.isFiltered() && replace != match.isReplaced()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ synchronized public void remove(Set matchset) {
+ ArrayList matches= new ArrayList();
+ for (int i= 0; i < fMatches.length; i++) {
+ Object m= fMatches[i];
+ if (!matchset.contains(m)) {
+ matches.add(m);
+ }
+ }
+ fMatches= (RetrieverMatch[]) matches.toArray(new RetrieverMatch[matches.size()]);
+ }
+
+ synchronized public int getDisplayedMatchCount() {
+ int result= 0;
+ if (!isFiltered()) {
+ for (int i= 0; i < fMatches.length; i++) {
+ if (!fMatches[i].isFiltered()) {
+ result++;
+ }
+ }
+ }
+ return result;
+ }
+
+ synchronized public RetrieverMatch[] getDisplayedMatches() {
+ int count= getDisplayedMatchCount();
+ if (count == 0) {
+ return EMPTY_ARRAY;
+ }
+ if (count == fMatches.length) {
+ return fMatches;
+ }
+ RetrieverMatch[] result= new RetrieverMatch[count];
+ int j= 0;
+ for (int i= 0; i < fMatches.length; i++) {
+ RetrieverMatch match= fMatches[i];
+ if (!match.isFiltered()) {
+ result[j++]= match;
+ }
+ }
+ return result;
+ }
+
+ public boolean isFiltered() {
+ return (fLineNumber & HIGH_BIT) != 0;
+ }
+
+ public int getMatchCount() {
+ return 0;
+ }
+
+ public String substring(int begin, int end) {
+ return fLineData.substring(begin, end);
+ }
+
+ public Object getAdapter(Class adapter) {
+ /* if (adapter.isAssignableFrom(IFile.class)) {
+ return getParent();
+ }*/
+ return null;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverMatch.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverMatch.java
new file mode 100644
index 00000000000..e7c4201b748
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverMatch.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.search.ui.text.Match;
+
+public class RetrieverMatch extends Match {
+ private int fKind;
+ private int fLineOffset;
+ private String fReplacement;
+ private String fOriginal;
+
+ public RetrieverMatch(RetrieverLine line, String original, int offset, int length, int lineOffset, int kind) {
+ super(line, offset, length);
+ fOriginal= original;
+ fReplacement= null;
+ fLineOffset= lineOffset;
+ fKind= kind;
+ }
+
+ public int getKind() {
+ return fKind;
+ }
+
+ public void setReplacement(String replacement) {
+ fReplacement= replacement;
+ }
+
+ public boolean isReplaced() {
+ return fReplacement != null;
+ }
+
+ public String getReplacement() {
+ return fReplacement;
+ }
+
+ public String getOriginal() {
+ return fOriginal;
+ }
+
+ public boolean filter(Pattern filterExpr, boolean hideMatching, int filterOptions, boolean invertOptions) {
+ boolean filtered= false;
+ if (((fKind & filterOptions) == 0) == invertOptions) {
+ filtered= true;
+ }
+ setFiltered(filtered);
+ return filtered;
+ }
+
+ public int getLineOffset() {
+ return fLineOffset;
+ }
+
+ public String getCurrentText() {
+ return fReplacement != null ? fReplacement : fOriginal;
+ }
+
+ public String computeReplacement(Pattern pattern, String replacement) {
+ return getLine().computeReplacement(this, pattern, replacement);
+ }
+
+ public RetrieverLine getLine() {
+ return (RetrieverLine) getElement();
+ }
+
+ public int getOriginalLength() {
+ return fOriginal.length();
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverPage.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverPage.java
new file mode 100644
index 00000000000..e4a6dd74f9f
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverPage.java
@@ -0,0 +1,1031 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Properties;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.custom.ViewForm;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.util.DelegatingDragAdapter;
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.Window;
+
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.IPageSite;
+import org.eclipse.ui.part.ResourceTransfer;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+import org.eclipse.search.ui.IContextMenuConstants;
+import org.eclipse.search.ui.IQueryListener;
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.ISearchResult;
+import org.eclipse.search.ui.ISearchResultViewPart;
+import org.eclipse.search.ui.NewSearchUI;
+import org.eclipse.search.ui.SearchResultEvent;
+import org.eclipse.search.ui.text.AbstractTextSearchResult;
+import org.eclipse.search.ui.text.AbstractTextSearchViewPage;
+import org.eclipse.search.ui.text.Match;
+
+import org.eclipse.search.internal.ui.SearchPlugin;
+import org.eclipse.search.internal.ui.SearchPluginImages;
+import org.eclipse.search.internal.ui.text.EditorOpener;
+import org.eclipse.search.internal.ui.text.FileLabelProvider;
+import org.eclipse.search.internal.ui.text.NewTextSearchActionGroup;
+import org.eclipse.search.internal.ui.text.ResourceTransferDragAdapter;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+import org.eclipse.search2.internal.ui.basic.views.SetLayoutAction;
+
+/**
+ * @author markus.schorn@windriver.com
+ */
+public class RetrieverPage extends AbstractTextSearchViewPage implements IQueryListener, IRetrieverKeys {
+
+ public static final String ID= "org.eclipse.search.text.RetrieverPage"; //$NON-NLS-1$
+ private static final String QUERY_EXTENSION= ".query"; //$NON-NLS-1$
+
+ private static final Collator COLLATOR= Collator.getInstance();
+ private static final Comparator FLAT_SORTER= new Comparator() {
+ public int compare(Object o1, Object o2) {
+ return compareResources((IResource) o1, (IResource) o2);
+ }
+ private int compareResources(IResource r1, IResource r2) {
+ if (r1 == r2)
+ return 0;
+ if (r1 == null)
+ return -1;
+ if (r2 == null)
+ return 1;
+
+ int cmp= COLLATOR.compare(r1.getName(), r2.getName());
+ if (cmp == 0) {
+ cmp= compare(r1.getParent(), r2.getParent());
+ }
+ return cmp;
+ }
+ };
+ private static final Comparator HIERARCHICAL_SORTER= new Comparator() {
+ public int compare(Object o1, Object o2) {
+ return compareFiles((IFile) o1, (IFile) o2);
+ }
+ private int compareFiles(IFile r1, IFile r2) {
+ if (r1 == r2)
+ return 0;
+ if (r1 == null)
+ return -1;
+ if (r2 == null)
+ return 1;
+
+ int cmp= compareParentPaths(r1.getParent().getFullPath(), r2.getParent().getFullPath());
+ if (cmp == 0) { // in same folder
+ cmp= COLLATOR.compare(r1.getName(), r2.getName());
+ }
+ return cmp;
+ }
+ private int compareParentPaths(IPath p1, IPath p2) {
+ // compare fragment by fragment to avoid new string creation
+ int p1len= p1.segmentCount();
+ int p2len= p2.segmentCount();
+ for (int i= 0; i < p1len; i++) {
+ if (i >= p2len) {
+ return 1; // second is shorter, sort it first
+ }
+ int cmp= COLLATOR.compare(p1.segment(i), p2.segment(i));
+ if (cmp != 0) {
+ return cmp;
+ }
+ }
+ if (p1len == p2len) {
+ return 0;
+ }
+ return -1; // first is shorter, sort it first
+ }
+ };
+
+ static String sLastSearchPattern;
+ static boolean sLastIsCaseSensitive;
+ static boolean sLastIsRegularExpression;
+ static boolean sLastIsWholeWord;
+ static boolean sLastConsiderDerivedResources;
+ static boolean sLastUseCaseSensitiveFilePatterns;
+ static boolean sLastUseFlatLayout;
+ static IScopeDescription sLastScope;
+ static String sLastFilePatterns;
+
+ private RetrieverFindTab fSearchControl= new RetrieverFindTab(this);
+ private RetrieverFilterTab fFilterControl= new RetrieverFilterTab(this);
+ private RetrieverReplaceTab fReplaceControl= new RetrieverReplaceTab(this);
+
+ private IDialogSettings fDialogSettings;
+ private boolean fSearchInProgress= false;
+
+ private SashForm fSplitter;
+ private ViewForm fResultForm;
+ private ViewForm fInputForm;
+ private TabFolder fTabFolder;
+
+ private SetLayoutAction fFlatAction;
+ private SetLayoutAction fHierarchicalAction;
+
+ private Action fEnableFilter;
+ private Action fUseCaseSensitiveFilePatterns;
+ private Action fConsiderDerivedResources;
+ private RetrieverContentProvider fContentProvider;
+ private EditorOpener fEditorOpener= new EditorOpener();
+ private Action fLoadAction;
+ private Action fStoreAction;
+ private Action fCreateWSAction;
+ private ActionGroup fActionGroup;
+
+ private RetrieverViewerSorter fSorter;
+
+ private boolean fUseFlatLayout;
+
+ private RetrieverLabelProvider fLabelProvider;
+ private ISearchResultViewPart fViewPart;
+ private RetrieverFilter fRecentFilter;
+
+ public RetrieverPage() {
+ super(FLAG_LAYOUT_TREE);
+ }
+
+ // overrider
+ public void createControl(Composite parent) {
+ IDialogSettings ds= SearchPlugin.getDefault().getDialogSettings();
+ fDialogSettings= ds.getSection(getClass().getName());
+ if (fDialogSettings == null) {
+ fDialogSettings= ds.addNewSection(getClass().getName());
+ }
+ restoreCurrentLayout();
+
+ fSplitter= new SashForm(parent, SWT.HORIZONTAL);
+ fSplitter.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ fResultForm= new ViewForm(fSplitter, SWT.NONE);
+ super.createControl(fResultForm);
+ fResultForm.setContent(super.getControl());
+
+ fInputForm= new ViewForm(fSplitter, SWT.NONE);
+ fInputForm.setContent(createInputControl(fInputForm));
+
+ fSplitter.setWeights(new int[] {60, 40});
+
+
+ createListeners();
+
+ // IWorkbenchHelpSystem help= PlatformUI.getWorkbench().getHelpSystem();
+ // help.setHelp(fSplitter, ISYContextIDs.VIEW_textSearch);
+
+ restoreValues();
+ }
+
+ public Control getControl() {
+ return fSplitter;
+ }
+
+ public void init(IPageSite pageSite) {
+ super.init(pageSite);
+
+ createActions();
+ IActionBars actionBars= pageSite.getActionBars();
+ IMenuManager mm= actionBars.getMenuManager();
+ mm.appendToGroup(IContextMenuConstants.GROUP_NEW, fLoadAction);
+ mm.appendToGroup(IContextMenuConstants.GROUP_NEW, fStoreAction);
+ mm.appendToGroup(IContextMenuConstants.GROUP_SHOW, fEnableFilter);
+ mm.appendToGroup(IContextMenuConstants.GROUP_SHOW, fCreateWSAction);
+ mm.appendToGroup(IContextMenuConstants.GROUP_SEARCH, fUseCaseSensitiveFilePatterns);
+ mm.appendToGroup(IContextMenuConstants.GROUP_SEARCH, fConsiderDerivedResources);
+ mm.appendToGroup(IContextMenuConstants.GROUP_VIEWER_SETUP, fFlatAction);
+ mm.appendToGroup(IContextMenuConstants.GROUP_VIEWER_SETUP, fHierarchicalAction);
+
+ actionBars.updateActionBars();
+ }
+
+ protected void fillToolbar(IToolBarManager tbm) {
+ super.fillToolbar(tbm);
+ tbm.appendToGroup(IContextMenuConstants.GROUP_SHOW, fEnableFilter);
+ }
+
+ public void setViewPart(ISearchResultViewPart part) {
+ super.setViewPart(part);
+ fViewPart= part;
+ fActionGroup= new NewTextSearchActionGroup(part);
+ }
+
+ public void dispose() {
+ fActionGroup.dispose();
+ NewSearchUI.removeQueryListener(this);
+ fSearchControl.dispose();
+ fFilterControl= null;
+ super.dispose();
+ }
+
+ public void setLayout(int layout) {
+ boolean flat= ((layout & FLAG_LAYOUT_FLAT) != 0);
+ if (fUseFlatLayout != flat) {
+ onChangeLayout(flat);
+ }
+ }
+
+ protected void fillContextMenu(IMenuManager mgr) {
+ super.fillContextMenu(mgr);
+ IStructuredSelection sel= (IStructuredSelection) getTreeViewer().getSelection();
+ if (sel.getFirstElement() instanceof IFile) {
+ fActionGroup.setContext(new ActionContext(sel));
+ fActionGroup.fillContextMenu(mgr);
+ }
+ if (!fSearchInProgress) {
+ fReplaceControl.fillContextMenu(mgr);
+ }
+ }
+
+ // overrider
+ public void setFocus() {
+ fSearchControl.setFocus();
+ }
+
+ public int getDisplayedMatchCount(Object element) {
+ if (element instanceof RetrieverLine) {
+ return ((RetrieverLine) element).getDisplayedMatchCount();
+ }
+ return 0;
+ }
+
+ public Match[] getDisplayedMatches(Object element) {
+ if (element instanceof RetrieverLine) {
+ return ((RetrieverLine) element).getDisplayedMatches();
+ }
+ return EMPTY_MATCH_ARRAY;
+ }
+
+
+ private Control createInputControl(Composite parent) {
+ fTabFolder= new TabFolder(parent, SWT.NONE);
+ fTabFolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fTabFolder.setLayout(new GridLayout(1, false));
+
+ // search tab
+ ScrolledComposite sc= createScrolledComposite(fTabFolder);
+ fSearchControl.createControl((Composite) sc.getContent());
+ setMinSize(sc);
+ createTabItem(fTabFolder, sc, SearchMessages.RetrieverPage_FindTab_text);
+
+ // filter tab
+ sc= createScrolledComposite(fTabFolder);
+ fFilterControl.createControl((Composite) sc.getContent());
+ setMinSize(sc);
+ createTabItem(fTabFolder, sc, SearchMessages.RetrieverPage_FilterTab_text);
+
+ // replace tab
+ sc= createScrolledComposite(fTabFolder);
+ fReplaceControl.createControl((Composite) sc.getContent());
+ setMinSize(sc);
+ createTabItem(fTabFolder, sc, SearchMessages.RetrieverPage_ReplaceTab_text);
+
+ return fTabFolder;
+ }
+
+ private void setMinSize(ScrolledComposite sc) {
+ sc.setMinSize(sc.getContent().computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ }
+
+ private void createTabItem(TabFolder folder, Control content, String text) {
+ TabItem tabItem= new TabItem(folder, SWT.NONE);
+ tabItem.setText(text);
+ tabItem.setControl(content);
+ }
+
+ private ScrolledComposite createScrolledComposite(Composite parent) {
+ ScrolledComposite sc= new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
+ sc.setLayoutData(new GridData(GridData.FILL_BOTH));
+ sc.setLayout(new GridLayout(1, true));
+ sc.setExpandHorizontal(true);
+ sc.setExpandVertical(true);
+
+ Composite comp= new Composite(sc, SWT.NONE);
+ sc.setContent(comp);
+ comp.setLayoutData(new GridData(GridData.FILL_BOTH));
+ comp.setLayout(new GridLayout(1, true));
+ return sc;
+ }
+
+ private void createListeners() {
+ fTabFolder.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onTabChanged();
+ }
+ });
+
+ fSearchControl.createListeners();
+ fFilterControl.createListeners();
+ fReplaceControl.createListeners(getViewer());
+
+ NewSearchUI.addQueryListener(this);
+ }
+
+ private void createActions() {
+ fReplaceControl.createActions();
+
+ fFlatAction= new SetLayoutAction(this, SearchMessages.AbstractTextSearchViewPage_flat_layout_label, SearchMessages.AbstractTextSearchViewPage_flat_layout_tooltip, FLAG_LAYOUT_FLAT);
+ fHierarchicalAction= new SetLayoutAction(this, SearchMessages.AbstractTextSearchViewPage_hierarchical_layout_label, SearchMessages.AbstractTextSearchViewPage_hierarchical_layout_tooltip, FLAG_LAYOUT_TREE);
+ SearchPluginImages.setImageDescriptors(fFlatAction, SearchPluginImages.T_LCL, SearchPluginImages.IMG_LCL_SEARCH_FLAT_LAYOUT);
+ SearchPluginImages.setImageDescriptors(fHierarchicalAction, SearchPluginImages.T_LCL, SearchPluginImages.IMG_LCL_SEARCH_HIERARCHICAL_LAYOUT);
+
+ fEnableFilter= new Action(SearchMessages.RetrieverPage_EnableFilter_text, IAction.AS_CHECK_BOX) {
+ public void run() {
+ onEnableToolbarFilter(fEnableFilter.isChecked());
+ }
+ };
+ fEnableFilter.setToolTipText(SearchMessages.RetrieverPage_EnableFilter_tooltip);
+ SearchPluginImages.setImageDescriptors(fEnableFilter, SearchPluginImages.T_LCL, SearchPluginImages.IMG_LCL_SEARCH_FILTER);
+
+ fLoadAction= new Action() {
+ public void run() {
+ onLoad();
+ }
+ };
+ fLoadAction.setText(SearchMessages.RetrieverPage_LoadQuery_text);
+ fLoadAction.setToolTipText(SearchMessages.RetrieverPage_LoadQuery_tooltip);
+
+ fStoreAction= new Action() {
+ public void run() {
+ onStore();
+ }
+ };
+ fStoreAction.setText(SearchMessages.RetrieverPage_SaveQuery_text);
+ fStoreAction.setToolTipText(SearchMessages.RetrieverPage_SaveQuery_tooltip);
+
+ fCreateWSAction= new Action() {
+ public void run() {
+ onCreateWorkingSet();
+ }
+ };
+ fCreateWSAction.setText(SearchMessages.RetrieverPage_CreateWorkingSet_text);
+ fCreateWSAction.setToolTipText(SearchMessages.RetrieverPage_CreateWorkingSet_tooltip);
+
+
+ fUseCaseSensitiveFilePatterns= new Action() {
+ public void run() {
+ onUseCaseSensitiveFilePatterns();
+ }
+ };
+ fUseCaseSensitiveFilePatterns.setText(SearchMessages.RetrieverPage_CaseSensitiveFilePatterns_text);
+
+ fConsiderDerivedResources= new Action() {
+ public void run() {
+ onConsiderDerivedResources();
+ }
+ };
+ fConsiderDerivedResources.setText(SearchMessages.RetrieverPage_ConsiderDerived_text);
+ }
+
+ protected void onConsiderDerivedResources() {
+ sLastConsiderDerivedResources= fConsiderDerivedResources.isChecked();
+ }
+
+ protected void onUseCaseSensitiveFilePatterns() {
+ sLastUseCaseSensitiveFilePatterns= fUseCaseSensitiveFilePatterns.isChecked();
+ }
+
+ private void onChangeLayout(boolean flat) {
+ fUseFlatLayout= flat;
+ fLabelProvider.setAppendFileContainer(flat);
+ fContentProvider.setLayout(flat);
+ getViewer().refresh();
+ storeValues();
+ }
+
+
+ protected void onCreateWorkingSet() {
+ Object[] lines= null;
+ String searchString= null;
+ AbstractTextSearchResult input= getInput();
+ if (input != null) {
+ lines= input.getElements();
+ RetrieverQuery q= (RetrieverQuery) input.getQuery();
+ if (q != null) {
+ searchString= q.getSearchText();
+ }
+ }
+ if (lines == null || searchString == null || lines.length < 1) {
+ showError(SearchMessages.RetrieverPage_error_noResourcesForWorkingSet);
+ return;
+ }
+ InputDialog dlg= new InputDialog(getSite().getShell(), SearchMessages.RetrieverPage_CreateWorkingsetDialog_title, SearchMessages.RetrieverPage_CreateWorkingSetDialog_description, "contains-" + searchString, null); //$NON-NLS-1$
+ if (dlg.open() == Window.OK) {
+ String name= dlg.getValue();
+ IWorkingSetManager wsm= PlatformUI.getWorkbench().getWorkingSetManager();
+ IWorkingSet ws= wsm.getWorkingSet(name);
+ if (ws != null) {
+ if (!showQuestion(SearchMessages.RetrieverPage_question_overwriteWorkingSet)) {
+ onCreateWorkingSet();
+ return;
+ }
+ }
+ HashSet fileset= new HashSet();
+ for (int i= 0; i < lines.length; i++) {
+ RetrieverLine line= (RetrieverLine) lines[i];
+ fileset.add(line.getParent());
+ }
+ IFile[] files= (IFile[]) fileset.toArray(new IFile[fileset.size()]);
+ if (ws == null) {
+ ws= wsm.createWorkingSet(name, files);
+ ws.setId("org.eclipse.ui.resourceWorkingSetPage"); //$NON-NLS-1$
+ wsm.addWorkingSet(ws);
+ } else {
+ ws.setElements(files);
+ }
+ wsm.addRecentWorkingSet(ws);
+ }
+ }
+
+ protected void onLoad() {
+ FileDialog dlg= new FileDialog(getSite().getShell(), SWT.OPEN);
+ dlg.setFilterPath(SearchPlugin.getDefault().getStateLocation().toOSString());
+ dlg.setFilterExtensions(new String[] {"*" + QUERY_EXTENSION}); //$NON-NLS-1$
+ String path= dlg.open();
+ if (path != null) {
+ InputStream in;
+ Properties props= new Properties();
+ try {
+ in= new FileInputStream(path);
+ props.load(in);
+ fSearchControl.restoreValues(props);
+ fFilterControl.setProperties(props);
+ fReplaceControl.setProperties(props);
+ } catch (IOException e) {
+ handleError(SearchMessages.RetrieverPage_error_cannotLoadQuery, e, true);
+ }
+ storeValues();
+ onFilterTabChanged();
+ }
+ }
+
+ protected void onStore() {
+ Properties props= new Properties();
+ fSearchControl.storeValues(props);
+ fFilterControl.getProperties(props);
+ fReplaceControl.getProperties(props);
+
+ FileDialog dlg= new FileDialog(getSite().getShell(), SWT.SAVE);
+ dlg.setFilterPath(SearchPlugin.getDefault().getStateLocation().toOSString());
+ dlg.setFilterExtensions(new String[] {"*" + QUERY_EXTENSION}); //$NON-NLS-1$
+ String path= dlg.open();
+ if (path != null) {
+ if (!path.endsWith(QUERY_EXTENSION)) {
+ path+= QUERY_EXTENSION;
+ }
+ OutputStream out;
+ try {
+ out= new FileOutputStream(path);
+ props.store(out, "Query for retriever"); //$NON-NLS-1$
+ } catch (IOException e) {
+ handleError(SearchMessages.RetrieverPage_error_cannotStoreQuery, e, true);
+ }
+ }
+ }
+
+
+ protected void onTabChanged() {
+ int idx= fTabFolder.getSelectionIndex();
+ switch (idx) {
+ case 0:
+ fSearchControl.onSelected();
+ break;
+ case 1:
+ fFilterControl.onSelected();
+ break;
+ case 2:
+ fReplaceControl.onSelected();
+ break;
+ }
+ }
+
+ // called by the filter tab
+ public void onFilterTabChanged() {
+ RetrieverResult r= (RetrieverResult) getInput();
+ if (r != null) {
+ r.filter(fFilterControl.getFilter());
+ }
+ postEnsureSelection();
+ }
+
+ public void onEnableToolbarFilter(boolean enable) {
+ fEnableFilter.setChecked(enable);
+ fFilterControl.onEnableToolbarFilter(enable);
+ onFilterTabChanged();
+ storeValues();
+ if (enable) {
+ fTabFolder.setSelection(1);
+ fFilterControl.onSelected();
+ }
+ }
+
+ void showError(String errorTxt) {
+ MessageDialog.openError(getSite().getShell(), SearchMessages.RetrieverPage_ErrorDialog_title, errorTxt);
+ }
+
+ boolean showQuestion(String qtext) {
+ return MessageDialog.openQuestion(getSite().getShell(), SearchMessages.RetrieverPage_QuestionDialog_title, qtext);
+ }
+
+ void showInformation(String itext) {
+ MessageDialog.openInformation(getSite().getShell(), SearchMessages.RetrieverPage_InformationDialog_title, itext);
+ }
+
+ void storeValues() {
+ int[] weights= fSplitter.getWeights();
+ fDialogSettings.put(KEY_SPLITTER_W1, weights[0]);
+ fDialogSettings.put(KEY_SPLITTER_W2, weights[1]);
+ fDialogSettings.put(KEY_ENABLE_FILTER, fEnableFilter.isChecked());
+ fDialogSettings.put(KEY_CONSIDER_DERIVED_RESOURCES, fConsiderDerivedResources.isChecked());
+ fDialogSettings.put(KEY_USE_CASE_SENSITIVE_FILE_PATTERNS, fUseCaseSensitiveFilePatterns.isChecked());
+ fDialogSettings.put(KEY_USE_FLAT_LAYOUT, fUseFlatLayout);
+ sLastUseFlatLayout= fUseFlatLayout;
+ sLastConsiderDerivedResources= fConsiderDerivedResources.isChecked();
+ sLastUseCaseSensitiveFilePatterns= fUseCaseSensitiveFilePatterns.isChecked();
+
+ fSearchControl.storeValues();
+ fFilterControl.storeValues();
+ fReplaceControl.storeValues();
+ }
+
+ private void restoreCurrentLayout() {
+ if (fDialogSettings.get(KEY_USE_FLAT_LAYOUT) == null) {
+ fUseFlatLayout= true;
+ } else {
+ fUseFlatLayout= fDialogSettings.getBoolean(KEY_USE_FLAT_LAYOUT);
+ }
+ }
+
+ private void restoreValues() {
+ int[] weights= new int[] {0, 0};
+ try {
+ weights[0]= fDialogSettings.getInt(KEY_SPLITTER_W1);
+ weights[1]= fDialogSettings.getInt(KEY_SPLITTER_W2);
+ fSplitter.setWeights(weights);
+ } catch (Exception e) {
+ }
+ restoreAction(fEnableFilter, KEY_ENABLE_FILTER, false);
+ restoreAction(fUseCaseSensitiveFilePatterns, KEY_USE_CASE_SENSITIVE_FILE_PATTERNS, false);
+ restoreAction(fConsiderDerivedResources, KEY_CONSIDER_DERIVED_RESOURCES, false);
+ fSearchControl.restoreValues();
+ fFilterControl.restoreValues(fEnableFilter.isChecked());
+ fReplaceControl.restoreValues();
+ fFlatAction.setChecked(fUseFlatLayout);
+ fHierarchicalAction.setChecked(!fUseFlatLayout);
+ }
+
+
+ void storeButton(Button button, String key) {
+ if (button != null) {
+ fDialogSettings.put(key, button.getSelection());
+ }
+ }
+
+ void storeValue(boolean val, String key) {
+ fDialogSettings.put(key, val);
+ }
+
+ public void storeValue(String[] val, String key) {
+ fDialogSettings.put(key, val);
+ }
+
+ void storeComboContent(Combo combo, String key, int maxItems) {
+ String ckey= key + KEY_EXT_COMBO_CONTENT;
+ String[] stored= fDialogSettings.getArray(ckey);
+ if (stored == null) {
+ stored= new String[0];
+ }
+
+ // copy elements
+ String text= combo.getText();
+ ArrayList newElems= new ArrayList();
+ if (text.length() > 0) {
+ newElems.add(text);
+ }
+
+ for (int i= 0; i < stored.length && newElems.size() < maxItems; i++) {
+ String elem= stored[i];
+ if (!text.equals(elem)) {
+ newElems.add(elem);
+ }
+ }
+
+ String[] save= (String[]) newElems.toArray(new String[newElems.size()]);
+ fDialogSettings.put(ckey, save);
+ fDialogSettings.put(key, text);
+
+ // redo the combo
+ combo.removeAll();
+ combo.setItems(save);
+ combo.setText(text);
+ }
+
+ void storeScope(IScopeDescription scope, String key) {
+ IDialogSettings ds= fDialogSettings.addNewSection(key);
+ ds.put(KEY_SCOPE_DESCRIPTOR_CLASS, scope.getClass().getName());
+ scope.store(ds);
+ }
+
+ boolean restoreValue(String key, boolean defaultValue) {
+ if (fDialogSettings.get(key) != null) {
+ defaultValue= fDialogSettings.getBoolean(key);
+ }
+ return defaultValue;
+ }
+
+ public String[] restoreValue(String key, String[] defaultValue) {
+ String[] result= fDialogSettings.getArray(key);
+ return result == null ? defaultValue : result;
+ }
+
+
+ void restoreButton(Button button, String key, boolean defaultValue) {
+ if (button != null) {
+ if (fDialogSettings.get(key) != null) {
+ defaultValue= fDialogSettings.getBoolean(key);
+ }
+ button.setSelection(defaultValue);
+ }
+ }
+
+ void restoreAction(Action button, String key, boolean defaultValue) {
+ if (fDialogSettings.get(key) != null) {
+ defaultValue= fDialogSettings.getBoolean(key);
+ }
+ button.setChecked(defaultValue);
+ }
+
+ void restoreCombo(Combo combo, String key, String def) {
+ String ckey= key + KEY_EXT_COMBO_CONTENT;
+ String[] stored= fDialogSettings.getArray(ckey);
+ if (stored != null && stored.length > 0) {
+ combo.setItems(stored);
+ }
+ String text= fDialogSettings.get(key);
+ if (text == null) {
+ text= def;
+ }
+ if (text != null && text.length() > 0) {
+ combo.setText(text);
+ }
+ }
+
+ public IScopeDescription restoreScope(String key) {
+ return getScope(fDialogSettings, key);
+ }
+
+ IStructuredSelection getSelection() {
+ return (IStructuredSelection) getViewer().getSelection();
+ }
+
+ void handleError(String emsg, Exception e, boolean show) {
+ if (show) {
+ showError(emsg);
+ } else {
+ SearchPlugin.log(new Status(IStatus.ERROR, NewSearchUI.PLUGIN_ID, SearchPlugin.INTERNAL_ERROR, emsg, e));
+ }
+ }
+
+ protected void elementsChanged(Object[] objects) {
+ if (fContentProvider != null)
+ fContentProvider.elementsChanged(objects);
+ }
+
+ protected void clear() {
+ if (fContentProvider != null)
+ fContentProvider.clear();
+ }
+
+ protected void configureTableViewer(TableViewer viewer) {
+ }
+
+ protected TreeViewer createTreeViewer(Composite parent) {
+ return new RetrieverTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+ }
+
+ protected void configureTreeViewer(TreeViewer viewer) {
+ viewer.setUseHashlookup(true);
+ fLabelProvider= new RetrieverLabelProvider(this, FileLabelProvider.SHOW_LABEL);
+ fLabelProvider.setAppendFileContainer(fUseFlatLayout);
+ viewer.setLabelProvider(new DecoratingLabelProvider(fLabelProvider, PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator()));
+ fContentProvider= new RetrieverContentProvider((RetrieverTreeViewer) viewer, fUseFlatLayout);
+ viewer.setContentProvider(fContentProvider);
+ fSorter= new RetrieverViewerSorter(fLabelProvider);
+ viewer.setSorter(fSorter);
+ viewer.addTreeListener(new ITreeViewerListener() {
+ public void treeCollapsed(TreeExpansionEvent event) {
+ fContentProvider.onExpansionStateChange(event.getElement(), false);
+ }
+ public void treeExpanded(TreeExpansionEvent event) {
+ fContentProvider.onExpansionStateChange(event.getElement(), true);
+ }
+ });
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ fContentProvider.onSelectionChanged(event);
+ }
+ });
+
+ addDragAdapters(viewer);
+ }
+
+ public TreeViewer getTreeViewer() {
+ return (TreeViewer) getViewer();
+ }
+
+ public ISearchResultViewPart getViewPart() {
+ return fViewPart;
+ }
+
+ synchronized public void setInput(ISearchResult result, Object viewState) {
+ fSearchInProgress= false;
+ if (result != null) {
+ ISearchQuery query= result.getQuery();
+ if (query instanceof RetrieverQuery) {
+ RetrieverQuery rq= (RetrieverQuery) query;
+ restoreFromQuery(rq);
+ fSearchInProgress= NewSearchUI.isQueryRunning(query);
+ }
+ }
+ super.setInput(result, viewState);
+ updateEnablementOnTabs();
+ setFocus();
+ }
+
+ private void restoreFromQuery(RetrieverQuery rq) {
+ fConsiderDerivedResources.setChecked(rq.getConsiderDerivedResources());
+ fUseCaseSensitiveFilePatterns.setChecked(rq.getUseCaseSensitiveFilePatterns());
+ fSearchControl.restoreFromQuery(rq);
+ initFilter((RetrieverResult) rq.getSearchResult());
+ fReplaceControl.setPattern(rq.createSearchPattern());
+ String searchText= rq.getSearchText();
+ if (searchText == null || searchText.length() == 0) {
+ fTabFolder.setSelection(0);
+ }
+ }
+
+ private void updateEnablementOnTabs() {
+ fSearchControl.updateEnablement(fSearchInProgress);
+ fReplaceControl.updateEnablement(fSearchInProgress);
+ }
+
+ private void addDragAdapters(StructuredViewer viewer) {
+ Transfer[] transfers= new Transfer[] {ResourceTransfer.getInstance()};
+ int ops= DND.DROP_COPY | DND.DROP_LINK;
+
+ DelegatingDragAdapter adapter= new DelegatingDragAdapter();
+ adapter.addDragSourceListener(new ResourceTransferDragAdapter(viewer));
+
+ viewer.addDragSupport(ops, transfers, adapter);
+ }
+
+ protected void showMatch(Match match, int offset, int length, boolean activate) throws PartInitException {
+ AbstractTextSearchResult result= getInput();
+ if (result != null) {
+ IFile file= result.getFileMatchAdapter().getFile(match.getElement());
+ IEditorPart editor= fEditorOpener.open(file, activate);
+ if (offset != 0 && length != 0) {
+ if (editor instanceof ITextEditor) {
+ ITextEditor textEditor= (ITextEditor) editor;
+ textEditor.selectAndReveal(offset, length);
+ } else
+ if (editor != null) {
+ showWithMarker(editor, file, offset, length);
+ }
+ }
+ }
+ fReplaceControl.updatePreview(null);
+ }
+
+ private void showWithMarker(IEditorPart editor, IFile file, int offset, int length) throws PartInitException {
+ IMarker marker= null;
+ try {
+ marker= file.createMarker(NewSearchUI.SEARCH_MARKER);
+ HashMap attributes= new HashMap(4);
+ attributes.put(IMarker.CHAR_START, new Integer(offset));
+ attributes.put(IMarker.CHAR_END, new Integer(offset + length));
+ marker.setAttributes(attributes);
+ IDE.gotoMarker(editor, marker);
+ } catch (CoreException e) {
+ throw new PartInitException(org.eclipse.search.internal.ui.SearchMessages.FileSearchPage_error_marker, e);
+ } finally {
+ if (marker != null)
+ try {
+ marker.delete();
+ } catch (CoreException e) {
+ // ignore
+ }
+ }
+ }
+
+ public void queryAdded(ISearchQuery query) {
+ }
+
+ public void queryRemoved(ISearchQuery query) {
+ }
+
+ synchronized public void queryStarting(ISearchQuery query) {
+ AbstractTextSearchResult result= getInput();
+ if (result != null && result.getQuery() == query) {
+ fSearchInProgress= true;
+ asyncUpdateEnablement();
+ }
+ }
+
+ synchronized public void queryFinished(ISearchQuery query) {
+ AbstractTextSearchResult result= getInput();
+ if (result != null && result.getQuery() == query) {
+ fSearchInProgress= false;
+ asyncUpdateEnablement();
+ }
+ }
+
+ private void asyncUpdateEnablement() {
+ asyncExec(new Runnable() {
+ public void run() {
+ if (fFilterControl != null) {
+ updateEnablementOnTabs();
+ }
+ }
+ });
+ }
+
+ private void asyncExec(Runnable runnable) {
+ Display display= getSite().getShell().getDisplay();
+ if (display != null) {
+ display.asyncExec(runnable);
+ }
+ }
+
+ public static IDialogSettings createSection(IDialogSettings ds, String name) {
+ IDialogSettings result= ds.getSection(name);
+ if (result == null) {
+ result= ds.addNewSection(name);
+ }
+ return result;
+ }
+
+ public static void initializeQuery(RetrieverQuery query) {
+ if (sLastSearchPattern == null) {
+ initializeLastQuery();
+ }
+ query.setSearchString(sLastSearchPattern);
+ query.setIsCaseSensitive(sLastIsCaseSensitive);
+ query.setIsRegularExpression(sLastIsRegularExpression);
+ query.setIsWholeWord(sLastIsWholeWord);
+ query.setSearchScope(sLastScope, sLastConsiderDerivedResources);
+ query.setFilePatterns(sLastFilePatterns, sLastUseCaseSensitiveFilePatterns);
+ query.setSearchOrder(sLastUseFlatLayout ? FLAT_SORTER : HIERARCHICAL_SORTER);
+ }
+
+
+ private static void initializeLastQuery() {
+ IDialogSettings ds= SearchPlugin.getDefault().getDialogSettings();
+ ds= createSection(ds, RetrieverPage.class.getName());
+
+ sLastSearchPattern= getValue(ds, KEY_SEARCH_STRINGS, null);
+ sLastIsCaseSensitive= getValue(ds, KEY_CASE_SENSITIVE_SEARCH, false);
+ sLastIsRegularExpression= getValue(ds, KEY_REGULAR_EXPRESSION_SEARCH, false);
+ sLastIsWholeWord= getValue(ds, KEY_WHOLE_WORD, true);
+ sLastConsiderDerivedResources= getValue(ds, KEY_CONSIDER_DERIVED_RESOURCES, false);
+ sLastFilePatterns= getValue(ds, KEY_FILE_PATTERNS, "*.c,*.cpp,*.h,*.java"); //$NON-NLS-1$
+ sLastUseCaseSensitiveFilePatterns= getValue(ds, KEY_USE_CASE_SENSITIVE_FILE_PATTERNS, false);
+ sLastUseFlatLayout= getValue(ds, KEY_USE_FLAT_LAYOUT, false);
+ sLastScope= getScope(ds, KEY_SEARCH_SCOPE);
+ }
+
+ private static String getValue(IDialogSettings ds, String key, String def) {
+ String result= ds.get(key);
+ return result == null ? def : result;
+ }
+
+ private static boolean getValue(IDialogSettings ds, String key, boolean def) {
+ String result= ds.get(key);
+ return result == null ? def : ds.getBoolean(key);
+ }
+
+ private static IScopeDescription getScope(IDialogSettings ds, String key) {
+ ds= ds.getSection(key);
+ if (ds != null) {
+ String scopeDescClass= getValue(ds, KEY_SCOPE_DESCRIPTOR_CLASS, WorkspaceScopeDescription.class.getName());
+ try {
+ IScopeDescription result= (IScopeDescription) Class.forName(scopeDescClass).newInstance();
+ result.restore(ds);
+ return result;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return new WorkspaceScopeDescription();
+ }
+
+ public void initFilter(RetrieverResult result) {
+ RetrieverFilter filter= result.getFilter();
+ if (filter == null) {
+ result.filter(fFilterControl.getFilter());
+ } else {
+ fRecentFilter= filter;
+ handleNewFilterFromResult();
+ }
+
+ }
+
+ private void handleNewFilterFromResult() {
+ fEnableFilter.setChecked(fFilterControl.restoreFromResult(fRecentFilter));
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.search.ui.text.AbstractTextSearchViewPage#handleSearchResultChanged(org.eclipse.search.ui.SearchResultEvent)
+ */
+ protected void handleSearchResultChanged(SearchResultEvent e) {
+ super.handleSearchResultChanged(e);
+ if (e instanceof FilterMatchEvent) {
+ RetrieverFilter filter= ((RetrieverResult) e.getSearchResult()).getFilter();
+ if (filter != fRecentFilter) {
+ fRecentFilter= filter;
+ asyncExec(new Runnable() {
+ public void run() {
+ // make sure we are not disposed
+ if (fFilterControl != null) {
+ handleNewFilterFromResult();
+ }
+ }
+ });
+ }
+ }
+ }
+
+ public Comparator getPreferredSearchOrder() {
+ return fUseFlatLayout ? FLAT_SORTER : HIERARCHICAL_SORTER;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverQuery.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverQuery.java
new file mode 100644
index 00000000000..7c40e82b194
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverQuery.java
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.ui.IWorkbenchPage;
+
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.ISearchResult;
+
+import org.eclipse.search.core.text.AbstractTextFileScanner;
+import org.eclipse.search.core.text.TextSearchEngine;
+import org.eclipse.search.core.text.TextSearchMatchAccess;
+import org.eclipse.search.core.text.TextSearchRequestor;
+import org.eclipse.search.core.text.TextSearchScope;
+import org.eclipse.search.core.text.AbstractTextFileScanner.LineInformation;
+
+import org.eclipse.search.internal.core.text.PatternConstructor;
+import org.eclipse.search.internal.ui.text.SearchResultUpdater;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class RetrieverQuery implements ISearchQuery, IRetrieverKeys {
+ private String fSearchPattern= ""; //$NON-NLS-1$
+ private boolean fIsCaseSensitive;
+ private boolean fIsRegularExpression;
+ private boolean fIsWholeWord;
+ private boolean fConsiderDerivedResources;
+ private boolean fUseCaseSensitiveFilePatterns;
+ private IScopeDescription fScope;
+ private String[] fFilePatterns;
+ private RetrieverLine fCurrentLine;
+ private int fCurrentLineOffset;
+ private RetrieverResult fResult;
+ private ArrayList fLinesOfCurrentFile;
+ private IWorkbenchPage fWorkbenchPage;
+ private AbstractTextFileScanner fScanner;
+ private Comparator fSearchOrder;
+
+
+ public RetrieverQuery(IWorkbenchPage page) {
+ fWorkbenchPage= page;
+ }
+
+ public void setSearchString(String searchFor) {
+ fSearchPattern= searchFor == null ? "" : searchFor; //$NON-NLS-1$
+ }
+ public void setIsCaseSensitive(boolean isCaseSensitive) {
+ fIsCaseSensitive= isCaseSensitive;
+ }
+ public void setIsRegularExpression(boolean isRegularExpression) {
+ fIsRegularExpression= isRegularExpression;
+ }
+ public void setIsWholeWord(boolean isWholeWord) {
+ fIsWholeWord= isWholeWord;
+ }
+
+ public void setSearchScope(IScopeDescription scope) {
+ fScope= scope;
+ }
+
+ public void setSearchScope(IScopeDescription scope, boolean considerDerived) {
+ fScope= scope;
+ fConsiderDerivedResources= considerDerived;
+ }
+
+ public void setFilePatterns(String filePatterns, boolean caseSensitive) {
+ fFilePatterns= filePatterns.split(FilePatternSelectionDialog.FILE_PATTERN_SEPERATOR);
+ fUseCaseSensitiveFilePatterns= caseSensitive;
+ }
+
+ public void setFilePatterns(String[] fileNamePatterns) {
+ fFilePatterns= (String[]) fileNamePatterns.clone();
+ }
+
+ public String getLabel() {
+ return SearchMessages.RetrieverQuery_label;
+ }
+
+ public boolean canRerun() {
+ return true;
+ }
+
+ public boolean canRunInBackground() {
+ return true;
+ }
+
+ public ISearchResult getSearchResult() {
+ if (fResult == null) {
+ fResult= new RetrieverResult(this);
+ new SearchResultUpdater(fResult);
+ }
+ return fResult;
+ }
+
+ public IStatus run(IProgressMonitor monitor) throws OperationCanceledException {
+ if (fSearchPattern.length() == 0) {
+ return Status.OK_STATUS;
+ }
+ if (fResult != null) {
+ fResult.removeAll();
+ fResult.setComplete(false);
+ }
+
+ TextSearchScope scope= createSearchScope(fWorkbenchPage);
+ return performSearch(monitor, scope);
+ }
+
+ private IStatus performSearch(IProgressMonitor monitor, TextSearchScope scope) {
+ TextSearchEngine engine= TextSearchEngine.create();
+ engine.setSearchOrderHint(fSearchOrder);
+ TextSearchRequestor requestor= createRequestor();
+ Pattern searchPattern= createSearchPattern();
+
+ if (fResult != null) {
+ fResult.setComplete(false);
+ }
+
+ IStatus status= engine.search(scope, requestor, searchPattern, monitor);
+ return status;
+ }
+
+ Pattern createSearchPattern() {
+ return PatternConstructor.createPattern(fSearchPattern, fIsRegularExpression, false, fIsCaseSensitive, fIsWholeWord);
+ }
+
+ private TextSearchScope createSearchScope(IWorkbenchPage page) {
+ RetrieverSearchScope scope= new RetrieverSearchScope(fScope.getRoots(page), fFilePatterns, fUseCaseSensitiveFilePatterns);
+ scope.setVisitDerived(fConsiderDerivedResources);
+ return scope;
+ }
+
+ private TextSearchRequestor createRequestor() {
+ return new TextSearchRequestor() {
+ public boolean acceptFile(IFile file) throws CoreException {
+ onAcceptFile(file);
+ return true;
+ }
+ public boolean acceptPatternMatch(TextSearchMatchAccess matchAccess) throws CoreException {
+ onAcceptPatternMatch(matchAccess);
+ return true;
+ }
+ public void beginReporting() {
+ onBeginReporting();
+ }
+ public void endReporting() {
+ onEndReporting();
+ }
+ };
+ }
+
+ protected void onBeginReporting() {
+ fLinesOfCurrentFile= new ArrayList();
+ getSearchResult();
+ fScanner= null;
+ fCurrentLine= null;
+ }
+
+ protected void onAcceptFile(IFile file) {
+ flushMatches();
+ if (fScanner != null) {
+ fScanner.reset();
+ }
+ fScanner= null;
+ fCurrentLine= null;
+ }
+
+ protected void onAcceptPatternMatch(TextSearchMatchAccess matchAccess) {
+ if (fScanner == null) {
+ fScanner= selectScanner(matchAccess);
+ }
+ int offset= matchAccess.getMatchOffset();
+ int length= matchAccess.getMatchLength();
+ int kind= fScanner.getLocationKind(matchAccess);
+ int shiftedkind= 1;
+ if (kind >= 0 && kind < 32) {
+ shiftedkind= 1 << kind;
+ }
+ setupCurrentLine(matchAccess);
+ int column= offset - fCurrentLineOffset;
+ int endcolumn= column + length;
+ String original= null;
+ if (fCurrentLine.getLength() >= endcolumn) {
+ original= fCurrentLine.substring(column, endcolumn);
+ } else {
+ StringBuffer match= new StringBuffer(length);
+ int end= offset + length;
+ for (int i= offset; i < end; i++) {
+ match.append(matchAccess.getFileContentChar(i));
+ }
+ original= match.toString();
+ }
+ RetrieverMatch match= new RetrieverMatch(fCurrentLine, original, offset, length, column, shiftedkind);
+ fCurrentLine.addMatch(match);
+ }
+
+ protected void onEndReporting() {
+ fResult.setComplete(true);
+ flushMatches();
+ if (fScanner != null) {
+ fScanner.reset();
+ }
+ fScanner= null;
+ fCurrentLine= null;
+ fLinesOfCurrentFile= null;
+ }
+
+ private void setupCurrentLine(TextSearchMatchAccess match) {
+ LineInformation info= fScanner.getLineInformation(match);
+ int lineNumber= info.getLineNumber();
+ if (fCurrentLine == null || fCurrentLine.getLineNumber() != lineNumber) {
+ fCurrentLineOffset= info.getLineOffset();
+ final int lineLength= Math.min(info.getLineLength(), MAX_COMBINED_LINE_LENGTH);
+ final int lineEndOffset= fCurrentLineOffset + lineLength;
+ final int matchEndOffset= match.getMatchOffset() + match.getMatchLength();
+
+ StringBuffer lineData= new StringBuffer(lineLength);
+ for (int i= fCurrentLineOffset; i < lineEndOffset; i++) {
+ lineData.append(match.getFileContentChar(i));
+ }
+
+ // check the last two characters separately
+ if (lineEndOffset > matchEndOffset && lineLength > 0) {
+ char last= lineData.charAt(lineLength - 1);
+ if (last == '\n') {
+ if (lineEndOffset > matchEndOffset + 1 && lineLength > 1 && lineData.charAt(lineLength - 2) == '\r') {
+ lineData.setLength(lineLength - 2);
+ } else {
+ lineData.setLength(lineLength - 1);
+ }
+ } else
+ if (last == '\r') {
+ lineData.setLength(lineLength - 1);
+ }
+ }
+
+ fCurrentLine= new RetrieverLine(match.getFile(), lineNumber);
+ fCurrentLine.setData(lineData.toString());
+ fLinesOfCurrentFile.add(fCurrentLine);
+ }
+ }
+
+ private void flushMatches() {
+ if (!fLinesOfCurrentFile.isEmpty()) {
+ fResult.setLinesForFile(fCurrentLine.getParent(), fLinesOfCurrentFile);
+ fLinesOfCurrentFile.clear();
+ fCurrentLine= null;
+ }
+ }
+
+ private AbstractTextFileScanner selectScanner(TextSearchMatchAccess matchAccess) {
+ AbstractTextFileScanner scanner= TextFileScannerRegistry.getInstance().findScanner(matchAccess.getFile());
+ if (scanner == null) {
+ scanner= TextFileScannerRegistry.getInstance().getLineNumberScanner();
+ }
+ return scanner;
+ }
+
+
+ public IScopeDescription getScopeDescription() {
+ return fScope;
+ }
+
+ public boolean isCaseSensitive() {
+ return fIsCaseSensitive;
+ }
+
+ public boolean isRegularExpression() {
+ return fIsRegularExpression;
+ }
+
+ public boolean isWholeWord() {
+ return fIsWholeWord;
+ }
+
+ public String getSearchText() {
+ return fSearchPattern;
+ }
+
+ public boolean getUseCaseSensitiveFilePatterns() {
+ return fUseCaseSensitiveFilePatterns;
+ }
+
+ public String getFilePatterns() {
+ StringBuffer buffer= new StringBuffer();
+ for (int i= 0; i < fFilePatterns.length; i++) {
+ if (i > 0) {
+ buffer.append(FilePatternSelectionDialog.FILE_PATTERN_SEPERATOR);
+ }
+ buffer.append(fFilePatterns[i]);
+ }
+
+ return buffer.toString();
+ }
+
+ public boolean getConsiderDerivedResources() {
+ return fConsiderDerivedResources;
+ }
+
+ public void searchAgain(Collection outdated, IProgressMonitor monitor) {
+ TextSearchScope scope= new RetrieverSearchScope((IResource[]) outdated.toArray(new IResource[outdated.size()]), new String[] {"*"}, true); //$NON-NLS-1$
+ performSearch(monitor, scope);
+ }
+
+ public void setSearchOrder(Comparator searchOrder) {
+ fSearchOrder= searchOrder;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverReplaceTab.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverReplaceTab.java
new file mode 100644
index 00000000000..8e06c9ce7de
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverReplaceTab.java
@@ -0,0 +1,470 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+
+import org.eclipse.core.runtime.IPath;
+
+import org.eclipse.core.resources.IFile;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.Viewer;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+
+import org.eclipse.search.ui.IContextMenuConstants;
+
+import org.eclipse.search.internal.ui.util.SWTUtil;
+
+import org.eclipse.search2.internal.ui.InternalSearchUI;
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+/**
+ * @author markus.schorn@windriver.com
+ */
+public class RetrieverReplaceTab implements IRetrieverKeys {
+ private RetrieverPage fView;
+
+ private Combo fReplacementCombo;
+ private Button fNextButton;
+ private Button fReplaceNextButton;
+ private Button fRestoreNextButton;
+ private Button fReplaceRestoreButton;
+ private Button fReplaceAllButton;
+ private Button fRestoreAllButton;
+ private Text fPreviewLine;
+ private Pattern fSearchPattern;
+ private boolean fSearchInProgress;
+
+ private RetrieverMatch fMatchOfPreview;
+
+
+ public RetrieverReplaceTab(RetrieverPage view) {
+ fView= view;
+ }
+
+ public void createControl(Composite parent) {
+ GridLayout gl;
+ GridData gd;
+
+ Composite group= new Composite(parent, SWT.NONE);
+ group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ group.setLayout(gl= new GridLayout(2, false));
+ gl.marginHeight= gl.marginWidth= 0;
+
+ // line 1
+ Label l= new Label(group, SWT.NONE);
+ l.setText(SearchMessages.RetrieverReplaceTab_ReplaceWith_label);
+
+ fReplacementCombo= new Combo(group, SWT.NONE);
+ fReplacementCombo.setVisibleItemCount(VISIBLE_ITEMS_IN_COMBO);
+ fReplacementCombo.setLayoutData(gd= new GridData(GridData.FILL_HORIZONTAL));
+ gd.widthHint= 20;
+
+ // line 2
+ group= new Composite(parent, SWT.NONE);
+ group.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+ group.setLayout(gl= new GridLayout(1, true));
+ gl.marginHeight= gl.marginWidth= 0;
+
+ Composite lg= new Composite(group, SWT.NONE);
+ lg.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ lg.setLayout(gl= new GridLayout(3, true));
+ gl.marginHeight= gl.marginWidth= 0;
+ gl.verticalSpacing= gl.horizontalSpacing= 2;
+
+ fNextButton= new Button(lg, SWT.NONE);
+ fNextButton.setText(SearchMessages.RetrieverReplaceTab_Find_text);
+ fNextButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ SWTUtil.setButtonDimensionHint(fNextButton);
+
+ fReplaceNextButton= new Button(lg, SWT.NONE);
+ fReplaceNextButton.setText(SearchMessages.RetrieverReplaceTab_ReplaceFind_text);
+ fReplaceNextButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ SWTUtil.setButtonDimensionHint(fReplaceNextButton);
+
+ fRestoreNextButton= new Button(lg, SWT.NONE);
+ fRestoreNextButton.setText(SearchMessages.RetrieverReplaceTab_RestoreFind_text);
+ fRestoreNextButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ SWTUtil.setButtonDimensionHint(fRestoreNextButton);
+
+ fReplaceRestoreButton= new Button(lg, SWT.NONE);
+ fReplaceRestoreButton.setText(SearchMessages.RetrieverReplaceTab_Replace_text);
+ fReplaceRestoreButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ SWTUtil.setButtonDimensionHint(fReplaceRestoreButton);
+
+ fReplaceAllButton= new Button(lg, SWT.NONE);
+ fReplaceAllButton.setText(SearchMessages.RetrieverReplaceTab_ReplaceAll_text);
+ fReplaceAllButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ SWTUtil.setButtonDimensionHint(fReplaceAllButton);
+
+ fRestoreAllButton= new Button(lg, SWT.NONE);
+ fRestoreAllButton.setText(SearchMessages.RetrieverReplaceTab_RestoreAll_text);
+ fRestoreAllButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ SWTUtil.setButtonDimensionHint(fRestoreAllButton);
+
+ // line 4
+ group= new Composite(parent, SWT.NONE);
+ group.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ group.setLayout(gl= new GridLayout(1, true));
+ gl.marginHeight= gl.marginWidth= 0;
+ gl.verticalSpacing= 2;
+
+ l= new Label(group, SWT.NONE);
+ l.setText(SearchMessages.RetrieverReplaceTab_Preview_label);
+
+ fPreviewLine= new Text(group, SWT.READ_ONLY | SWT.BORDER);
+ fPreviewLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ }
+
+ void createListeners(Viewer resultViewer) {
+ resultViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ onSelectionChanged((IStructuredSelection) event.getSelection());
+ }
+ });
+
+ fReplacementCombo.addKeyListener(new KeyListener() {
+ public void keyPressed(KeyEvent e) {
+ }
+ public void keyReleased(KeyEvent e) {
+ onReplacementChange();
+ }
+ });
+ fReplacementCombo.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onReplacementChange();
+ }
+ });
+ fNextButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ fView.gotoNextMatch();
+ }
+ });
+ fReplaceRestoreButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ if (fMatchOfPreview != null) {
+ onReplace(!fMatchOfPreview.isReplaced(), false, fReplaceRestoreButton.getText());
+ }
+ }
+ });
+ fReplaceNextButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onReplace(true, true, fReplaceNextButton.getText());
+ }
+ });
+ fRestoreNextButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onReplace(false, true, fRestoreNextButton.getText());
+ }
+ });
+ fReplaceAllButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onReplaceAll(true, fReplaceAllButton.getText());
+ }
+ });
+ fRestoreAllButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ onReplaceAll(false, fRestoreAllButton.getText());
+ }
+ });
+ }
+
+ void createActions() {
+ }
+
+ protected void onReplacementChange() {
+ updatePreview(fView.getSelection());
+ }
+
+ protected void updatePreview(ISelection sel) {
+ fMatchOfPreview= (RetrieverMatch) fView.getCurrentMatch();
+ if (fMatchOfPreview == null) {
+ fMatchOfPreview= getMatchOfSelection(sel);
+ }
+ String preview= null;
+ if (fMatchOfPreview != null) {
+ preview= computePreview(fMatchOfPreview);
+ }
+ if (preview == null) {
+ preview= ""; //$NON-NLS-1$
+ }
+ fPreviewLine.setText(preview);
+ }
+
+ private RetrieverMatch getMatchOfSelection(ISelection sel) {
+ if (sel instanceof IStructuredSelection) {
+ Object element= ((IStructuredSelection) sel).getFirstElement();
+ if (element instanceof RetrieverLine) {
+ RetrieverMatch[] matches= ((RetrieverLine) element).getDisplayedMatches();
+ if (matches.length > 0) {
+ return matches[0];
+ }
+ }
+ }
+ return null;
+ }
+
+ protected void onSelectionChanged(IStructuredSelection sel) {
+ // compute preview
+ updatePreview(sel);
+
+ if (fSearchInProgress) {
+ fReplaceRestoreButton.setEnabled(false);
+ fReplaceNextButton.setEnabled(false);
+ fRestoreNextButton.setEnabled(false);
+ fReplaceAllButton.setEnabled(false);
+ fRestoreAllButton.setEnabled(false);
+ return;
+ }
+
+ if (fMatchOfPreview != null) {
+ boolean replaced= fMatchOfPreview.isReplaced();
+ fReplaceRestoreButton.setEnabled(true);
+ fReplaceRestoreButton.setText(replaced ? SearchMessages.RetrieverReplaceTab_Restore_text : SearchMessages.RetrieverReplaceTab_Replace_text);
+ fReplaceNextButton.setEnabled(!replaced);
+ fRestoreNextButton.setEnabled(replaced);
+ }
+ fReplaceAllButton.setEnabled(true);
+ fRestoreAllButton.setEnabled(true);
+
+ }
+
+ private String computePreview(RetrieverMatch match) {
+ RetrieverLine line= match.getLine();
+ IFile file= line.getParent();
+ IDocument doc= null;
+ if (file != null) {
+ IPath path= file.getFullPath();
+ ITextFileBuffer txfbuf= FileBuffers.getTextFileBufferManager().getTextFileBuffer(path);
+ if (txfbuf != null) {
+ doc= txfbuf.getDocument();
+ }
+ }
+
+ String pre, post;
+ if (doc != null) {
+ int offset1= match.getOffset();
+ int offset2= offset1 + match.getLength();
+ Position pos= InternalSearchUI.getInstance().getPositionTracker().getCurrentPosition(match);
+ if (pos != null) {
+ offset1= pos.offset;
+ offset2= offset1 + pos.length;
+ }
+ if (0 > offset1 || offset1 > offset2 || offset2 > doc.getLength()) {
+ return null;
+ }
+ String matchstr;
+ try {
+ int offset0= offset1;
+ int min= Math.max(0, offset1 - 1024);
+ while (offset0 > min) {
+ char c= doc.getChar(offset0 - 1);
+ if (c == '\n' || c == '\r') {
+ break;
+ }
+ offset0--;
+ }
+ int offset3= offset2;
+ int max= Math.min(doc.getLength(), offset2 + 1024);
+ while (offset3 < max) {
+ char c= doc.getChar(offset3);
+ if (c == '\n' || c == '\r') {
+ break;
+ }
+ offset3++;
+ }
+ // don't accept trailing \r
+ if (offset3 > offset2 && doc.getChar(offset3 - 1) == '\r') {
+ offset3--;
+ }
+ pre= doc.get(offset0, offset1 - offset0);
+ matchstr= doc.get(offset1, offset2 - offset1);
+ post= doc.get(offset2, offset3 - offset2);
+ } catch (BadLocationException e) {
+ return null;
+ }
+ if (!matchstr.equals(match.getCurrentText())) {
+ return null;
+ }
+ } else {
+ pre= line.getPreString(match);
+ post= line.getPostString(match);
+ }
+
+ StringBuffer result= new StringBuffer();
+ result.append(pre);
+ if (match.isReplaced()) {
+ result.append(match.getOriginal());
+ } else {
+ String unescapedReplacement= getUnescapedReplacementString();
+ String replacement= match.computeReplacement(fSearchPattern, unescapedReplacement);
+ if (replacement == null) {
+ return null;
+ }
+ result.append(replacement);
+ }
+ result.append(post);
+ return RetrieverLabelProvider.convertChars(result);
+ }
+
+ private String getUnescapedReplacementString() {
+ return unescapeWhitespace(fReplacementCombo.getText());
+ }
+
+ private String unescapeWhitespace(String input) {
+ StringBuffer result= new StringBuffer(input.length());
+ int i= 0;
+ while (i < input.length() - 1) {
+ char c= input.charAt(i);
+ i++;
+ if (c == '\\') {
+ c= input.charAt(i);
+ i++;
+ switch (c) {
+ case 't':
+ result.append('\t');
+ break;
+ case 'r':
+ result.append('\r');
+ break;
+ case 'n':
+ result.append('\n');
+ break;
+ case '\\':
+ result.append('\\');
+ result.append('\\');
+ break;
+ default:
+ result.append('\\');
+ result.append(c);
+ break;
+ }
+ } else {
+ result.append(c);
+ }
+ }
+ if (i < input.length()) {
+ result.append(input.charAt(i));
+ }
+
+ return result.toString();
+ }
+
+ protected void onReplace(boolean replace, boolean moveOn, String actionLabel) {
+ storeValues();
+ if (fMatchOfPreview != null) {
+ ReplaceAction op= new ReplaceAction(fView, actionLabel, replace, fMatchOfPreview);
+ op.setReplacement(fSearchPattern, getUnescapedReplacementString());
+ op.run();
+ if (fView.getCurrentMatch() == null) {
+ fView.gotoNextMatch();
+ }
+ if (moveOn && op.wasSuccessful()) {
+ fView.gotoNextMatch();
+ } else {
+ onSelectionChanged(fView.getSelection());
+ }
+ }
+ }
+
+ protected void onReplaceAll(boolean replace, String actionLabel) {
+ storeValues();
+ ReplaceAction op= new ReplaceAction(fView, actionLabel, replace);
+ op.setReplacement(fSearchPattern, getUnescapedReplacementString());
+ op.run();
+ }
+
+ void storeValues() {
+ fView.storeComboContent(fReplacementCombo, KEY_REPLACEMENT_STRING, MAX_REPLACEMENT_STRINGS);
+ }
+
+ void restoreValues() {
+ fView.restoreCombo(fReplacementCombo, KEY_REPLACEMENT_STRING, ""); //$NON-NLS-1$
+ updateEnablement(true);
+ }
+
+ public void setPattern(Pattern pattern) {
+ fSearchPattern= pattern;
+ }
+
+ public void updateEnablement(boolean searchInProgress) {
+ if (fSearchInProgress != searchInProgress) {
+ fSearchInProgress= searchInProgress;
+ onSelectionChanged(fView.getSelection());
+ }
+ }
+
+ public void onSelected() {
+ fReplacementCombo.setFocus();
+ }
+
+ public void getProperties(Properties props) {
+ props.setProperty(KEY_REPLACEMENT_STRING, fReplacementCombo.getText());
+ }
+
+ public void setProperties(Properties props) {
+ String property= props.getProperty(KEY_REPLACEMENT_STRING);
+ if (property != null) {
+ fReplacementCombo.setText(property);
+ onReplacementChange();
+ }
+ }
+
+ public void fillContextMenu(IMenuManager mgr) {
+ IStructuredSelection sel= (IStructuredSelection) fView.getTreeViewer().getSelection();
+ String replacement= getUnescapedReplacementString();
+ if (sel != null && !sel.isEmpty()) {
+ ReplaceAction replaceAction= new ReplaceAction(fView, SearchMessages.RetrieverReplaceTab_ReplaceSelected_text, true, sel);
+ if (replaceAction.isEnabled()) {
+ replaceAction.setReplacement(fSearchPattern, replacement);
+ mgr.appendToGroup(IContextMenuConstants.GROUP_REORGANIZE, replaceAction);
+ }
+ ReplaceAction restoreAction= new ReplaceAction(fView, SearchMessages.RetrieverReplaceTab_RestoreSelected_text, false, sel);
+ if (restoreAction.isEnabled()) {
+ mgr.appendToGroup(IContextMenuConstants.GROUP_REORGANIZE, restoreAction);
+ }
+ }
+ ReplaceAction replaceAction= new ReplaceAction(fView, SearchMessages.RetrieverReplaceTab_ReplaceAll_text, true);
+ if (replaceAction.isEnabled()) {
+ replaceAction.setReplacement(fSearchPattern, replacement);
+ mgr.appendToGroup(IContextMenuConstants.GROUP_REORGANIZE, replaceAction);
+ }
+ ReplaceAction restoreAction= new ReplaceAction(fView, SearchMessages.RetrieverReplaceTab_RestoreAll_text, false);
+ if (restoreAction.isEnabled()) {
+ mgr.appendToGroup(IContextMenuConstants.GROUP_REORGANIZE, restoreAction);
+ }
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverResult.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverResult.java
new file mode 100644
index 00000000000..8ad2adfa6f0
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverResult.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+import org.eclipse.core.resources.IFile;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.ISearchResult;
+import org.eclipse.search.ui.SearchResultEvent;
+import org.eclipse.search.ui.text.AbstractTextSearchResult;
+import org.eclipse.search.ui.text.IEditorMatchAdapter;
+import org.eclipse.search.ui.text.IFileMatchAdapter;
+import org.eclipse.search.ui.text.Match;
+
+import org.eclipse.search.internal.ui.SearchPluginImages;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+/**
+ * @author markus.schorn@windriver.com
+ */
+class RetrieverResult extends AbstractTextSearchResult implements ISearchResult, IEditorMatchAdapter, IFileMatchAdapter, IRetrieverKeys {
+ private static final RetrieverMatch[] EMPTY_ARRAY= new RetrieverMatch[0];
+
+ private Pattern fFilterExpr;
+ private boolean fFilterHideMatching;
+ private int fAcceptLocations= 0;
+ private RetrieverQuery fQuery;
+ private boolean fIsComplete;
+
+ private HashMap fFilesToLines= new HashMap();
+ private FilterMatchEvent fFilterEvent= new FilterMatchEvent(this);
+
+ private RetrieverFilter fFilter;
+
+ public RetrieverResult(RetrieverQuery query) {
+ fQuery= query;
+ }
+
+ public void filter(RetrieverFilter filter) {
+ fFilter= filter;
+ boolean hideMatches= filter.getHideMatching();
+ int acceptLocations= filter.getAcceptedLocations();
+ Pattern filterPattern= filter.getPattern();
+ // check if filter has changed at all
+ if (fFilterHideMatching == hideMatches && acceptLocations == fAcceptLocations) {
+ if (filterPattern == fFilterExpr || (filterPattern != null && filterPattern.equals(fFilterExpr))) {
+ return;
+ }
+ }
+
+ fFilterExpr= filterPattern;
+ fFilterHideMatching= hideMatches;
+ fAcceptLocations= acceptLocations;
+
+ ArrayList changedMatches= new ArrayList();
+ Object[] lines= getElements();
+ for (int i= 0; i < lines.length; i++) {
+ RetrieverLine line= (RetrieverLine) lines[i];
+ line.filter(fFilterExpr, fFilterHideMatching, fAcceptLocations, changedMatches);
+ }
+ synchronized (fFilterEvent) {
+ if (!changedMatches.isEmpty()) {
+ fireChange(getFilterSearchResultEvent(changedMatches));
+ }
+ }
+ }
+
+ private SearchResultEvent getFilterSearchResultEvent(ArrayList matches) {
+ Match[] matchArray= (Match[]) matches.toArray(new Match[matches.size()]);
+ fFilterEvent.setMatches(matchArray);
+ return fFilterEvent;
+ }
+
+ public boolean hasFilter() {
+ return fFilterExpr != null || fAcceptLocations == ALL_LOCATIONS;
+ }
+
+ public IEditorMatchAdapter getEditorMatchAdapter() {
+ return this;
+ }
+
+ public IFileMatchAdapter getFileMatchAdapter() {
+ return this;
+ }
+
+ public String getLabel() {
+ String pattern= fQuery.getSearchText();
+ String scope= fQuery.getScopeDescription().getLabel();
+ int matchCount= getMatchCount();
+
+ if (pattern.length() == 0) {
+ return SearchMessages.RetrieverResult_noInput_label;
+ }
+ return MessageFormat.format(SearchMessages.RetrieverResult_label, new Object[] {pattern, new Integer(matchCount), scope});
+ }
+
+ public String getTooltip() {
+ return getLabel();
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ return SearchPluginImages.DESC_OBJ_TSEARCH_DPDN;
+ }
+
+ public ISearchQuery getQuery() {
+ return fQuery;
+ }
+
+ public Match[] computeContainedMatches(AbstractTextSearchResult result, IFile file) {
+ return collectMatches(getLinesForFile(file, false));
+ }
+
+ public RetrieverLine[] getLinesForFile(IFile file, boolean copy) {
+ RetrieverLine[] lines= null;
+ synchronized (fFilesToLines) {
+ lines= (RetrieverLine[]) fFilesToLines.get(file);
+ }
+ return (copy && lines != null) ? (RetrieverLine[]) lines.clone() : lines;
+ }
+
+ public IFile getFile(Object element) {
+ if (element instanceof IFile) {
+ return (IFile) element;
+ } else
+ if (element instanceof RetrieverLine) {
+ RetrieverLine line= (RetrieverLine) element;
+ return line.getParent();
+ }
+ return null;
+ }
+
+ public boolean isShownInEditor(Match match, IEditorPart editor) {
+ IEditorInput ei= editor.getEditorInput();
+ if (ei instanceof IFileEditorInput) {
+ IFileEditorInput fi= (IFileEditorInput) ei;
+ Object line= match.getElement();
+ if (line instanceof RetrieverLine) {
+ return ((RetrieverLine) line).getParent().equals(fi.getFile());
+ }
+ }
+ return false;
+ }
+
+ public Match[] computeContainedMatches(AbstractTextSearchResult result, IEditorPart editor) {
+ IEditorInput ei= editor.getEditorInput();
+ if (ei instanceof IFileEditorInput) {
+ IFileEditorInput fi= (IFileEditorInput) ei;
+ return computeContainedMatches(result, fi.getFile());
+ }
+ return EMPTY_ARRAY;
+ }
+
+ public void setLinesForFile(IFile file, List lines) {
+ RetrieverLine[] newLines= (RetrieverLine[]) lines.toArray(new RetrieverLine[lines.size()]);
+ RetrieverMatch[] oldMatches= collectMatches(getLinesForFile(file, false));
+ synchronized (fFilesToLines) {
+ fFilesToLines.remove(file);
+ }
+ if (oldMatches.length > 0) {
+ removeMatches(oldMatches);
+ }
+ if (newLines.length > 0) {
+ ArrayList matches= new ArrayList(newLines.length);
+ for (Iterator iter= lines.iterator(); iter.hasNext();) {
+ RetrieverLine line= (RetrieverLine) iter.next();
+ line.filter(fFilterExpr, fFilterHideMatching, fAcceptLocations, null);
+ RetrieverMatch[] m= line.getMatches(false);
+ matches.addAll(Arrays.asList(m));
+ }
+ if (!matches.isEmpty()) {
+ synchronized (fFilesToLines) {
+ fFilesToLines.put(file, newLines);
+ }
+ addMatches((Match[]) matches.toArray(new Match[matches.size()]));
+ }
+ }
+ }
+
+ private RetrieverMatch[] collectMatches(RetrieverLine[] lines) {
+ if (lines == null || lines.length == 0) {
+ return EMPTY_ARRAY;
+ }
+ ArrayList matches= new ArrayList(lines.length);
+ for (int i= 0; i < lines.length; i++) {
+ RetrieverLine line= lines[i];
+ matches.addAll(Arrays.asList(line.getMatches(false)));
+ }
+ return (RetrieverMatch[]) matches.toArray(new RetrieverMatch[matches.size()]);
+ }
+
+ public void removeAll() {
+ synchronized (fFilesToLines) {
+ fFilesToLines.clear();
+ }
+ super.removeAll();
+ }
+
+ public void removeMatch(Match match) {
+ ((RetrieverLine) match.getElement()).remove(Collections.singleton(match));
+ super.removeMatch(match);
+ }
+
+ public void removeMatches(Match[] matches) {
+ HashSet matchset= new HashSet();
+ matchset.addAll(Arrays.asList(matches));
+ HashSet lines= new HashSet();
+ for (int i= 0; i < matches.length; i++) {
+ RetrieverMatch match= (RetrieverMatch) matches[i];
+ lines.add(match.getElement());
+ }
+ for (Iterator iter= lines.iterator(); iter.hasNext();) {
+ RetrieverLine line= (RetrieverLine) iter.next();
+ line.remove(matchset);
+ }
+ super.removeMatches(matches);
+ }
+
+ public int getMatchCount(Object element) {
+ if (element instanceof RetrieverLine) {
+ return ((RetrieverLine) element).getMatchCount();
+ }
+ return 0;
+ }
+
+ public int getDisplayedMatchCount(Object element) {
+ if (element instanceof RetrieverLine) {
+ return ((RetrieverLine) element).getDisplayedMatchCount();
+ }
+ return 0;
+ }
+
+ public boolean isComplete() {
+ return fIsComplete;
+ }
+
+ public void setComplete(boolean isComplete) {
+ fIsComplete= isComplete;
+ }
+
+ public int[] getDetailedMatchCount() {
+ int[] result= new int[] {0, 0};
+ synchronized (fFilesToLines) {
+ for (Iterator iter= fFilesToLines.values().iterator(); iter.hasNext();) {
+ RetrieverLine[] lines= (RetrieverLine[]) iter.next();
+ for (int i= 0; i < lines.length; i++) {
+ RetrieverLine line= lines[i];
+ line.addMatchCount(result);
+ }
+ }
+ }
+ return result;
+ }
+
+ public void searchAgain(Collection outdated) {
+ if (fQuery != null) {
+ fQuery.searchAgain(outdated, new NullProgressMonitor());
+ }
+ }
+
+ public RetrieverFilter getFilter() {
+ return fFilter;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverSearchScope.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverSearchScope.java
new file mode 100644
index 00000000000..cc6e6d836ec
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverSearchScope.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+
+import org.eclipse.search.internal.core.text.PatternConstructor;
+
+import org.eclipse.search.core.text.TextSearchScope;
+
+public class RetrieverSearchScope extends TextSearchScope {
+ private boolean fIsCaseSensitive= false;
+ private boolean fVisitDerived= false;
+
+ private IResource[] fRoots;
+ private HashSet fFileExtensions= new HashSet();
+ private ArrayList fFileMatchers= new ArrayList();
+
+
+ /**
+ * Creates a search scope for resources below a root matching one of the
+ * given file patterns.
+ *
+ * @param root
+ * the subtree of resources to be considered
+ * @param filePatterns
+ * an array of eclipse style patterns
+ * @param isCaseSensitive
+ * flag that indicates whether the file patterns are case
+ * sensitive or not.
+ */
+ public RetrieverSearchScope(IResource root, String[] filePatterns, boolean isCaseSensitive) {
+ this(new IResource[] {root}, filePatterns, isCaseSensitive);
+ }
+
+ /**
+ * Creates a search scope for resources below several roots matching one of
+ * the given file patterns.
+ *
+ * @param roots
+ * the subtree of resources to be considered
+ * @param filePatterns
+ * an array of eclipse style patterns
+ * @param isCaseSensitive
+ * flag that indicates whether the file patterns are case
+ * sensitive or not.
+ */
+ public RetrieverSearchScope(IResource[] roots, String[] filePatterns, boolean isCaseSensitive) {
+ fIsCaseSensitive= isCaseSensitive; // do this before compiling the patterns!
+ compileFilePatterns(filePatterns);
+
+ ArrayList openRoots= new ArrayList();
+ for (int i= 0; i < roots.length; i++) {
+ IResource root= roots[i];
+ if (root.getProject().isOpen()) {
+ openRoots.add(root);
+ }
+ }
+ fRoots= (IResource[]) openRoots.toArray(new IResource[openRoots.size()]);
+ }
+
+ private void compileFilePatterns(String[] filePatterns) {
+ fFileMatchers.clear();
+ fFileExtensions.clear();
+ if (filePatterns != null) {
+ for (int i= 0; i < filePatterns.length; i++) {
+ compileFilePattern(filePatterns[i], fFileExtensions, fFileMatchers);
+ }
+ }
+ }
+
+ private void compileFilePattern(String pattern, HashSet extensions, ArrayList matchers) {
+ pattern= pattern.trim();
+ int pos= pattern.lastIndexOf('*');
+ if (pos == 0) {
+ pos= pattern.lastIndexOf('.');
+ if (pos == 1) {
+ String suffix= pattern.substring(2);
+ String literal= PatternConstructor.appendAsRegEx(false, suffix, new StringBuffer()).toString();
+ String strMatcher= PatternConstructor.appendAsRegEx(true, suffix, new StringBuffer()).toString();
+ if (literal.equals(strMatcher)) {
+ if (!fIsCaseSensitive) {
+ suffix= suffix.toUpperCase();
+ }
+ extensions.add(suffix);
+ return;
+ }
+ }
+ }
+ Pattern regex= PatternConstructor.createPattern(pattern, false, true, fIsCaseSensitive, false);
+ matchers.add(regex.matcher("")); //$NON-NLS-1$
+ }
+
+ public boolean contains(IResourceProxy proxy) {
+ if (!fVisitDerived && proxy.isDerived()) {
+ return false; // all resources in a derived folder are considered to be derived, see bug 103576
+ }
+
+ switch (proxy.getType()) {
+ case IResource.PROJECT:
+ return ((IProject) proxy.requestResource()).isOpen();
+
+ case IResource.FILE:
+ return containsFile(proxy);
+ }
+ return true;
+ }
+
+ private boolean containsFile(IResourceProxy proxy) {
+ String name= proxy.getName();
+ int iDot= name.lastIndexOf('.');
+ String ext= null;
+ if (iDot >= 0) {
+ ext= name.substring(iDot + 1);
+ if (!fIsCaseSensitive) {
+ ext= ext.toUpperCase();
+ }
+ if (fFileExtensions.contains(ext)) {
+ return true;
+ }
+ }
+ for (int i= 0; i < fFileMatchers.size(); i++) {
+ Matcher m= (Matcher) fFileMatchers.get(i);
+ m.reset(name);
+ if (m.matches()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setVisitDerived(boolean visitDerived) {
+ fVisitDerived= visitDerived;
+ }
+
+ public IResource[] getRoots() {
+ return fRoots;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverTreeViewer.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverTreeViewer.java
new file mode 100644
index 00000000000..334258251a9
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverTreeViewer.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import org.eclipse.swt.widgets.Composite;
+
+import org.eclipse.jface.viewers.TreeViewer;
+
+class RetrieverTreeViewer extends TreeViewer {
+ private boolean fPreservingSelection= false;
+
+ public RetrieverTreeViewer(Composite parent, int options) {
+ super(parent, options);
+ }
+
+ public void preservingSelection(Runnable updateCode) {
+ if (!fPreservingSelection) {
+ fPreservingSelection= true;
+ try {
+ super.preservingSelection(updateCode);
+ } finally {
+ fPreservingSelection= false;
+ }
+ } else {
+ updateCode.run();
+ }
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverViewerSorter.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverViewerSorter.java
new file mode 100644
index 00000000000..d1399babfb5
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/RetrieverViewerSorter.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.text.Collator;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+
+public class RetrieverViewerSorter extends ViewerSorter {
+ private final ILabelProvider fLabelProvider;
+
+ public RetrieverViewerSorter(ILabelProvider labelProvider) {
+ super(null); // lazy initialization
+ fLabelProvider= labelProvider;
+ }
+
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ if (e1 instanceof RetrieverLine && e2 instanceof RetrieverLine) {
+ return ((RetrieverLine) e1).getLineNumber() - ((RetrieverLine) e2).getLineNumber();
+ }
+
+ int diff= category(e1) - category(e2);
+ if (diff != 0) {
+ return diff;
+ }
+
+ String name1= fLabelProvider.getText(e1);
+ String name2= fLabelProvider.getText(e2);
+ if (name1 == null)
+ name1= "";//$NON-NLS-1$
+ if (name2 == null)
+ name2= "";//$NON-NLS-1$
+ return getCollator().compare(name1, name2);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerSorter#getCollator()
+ */
+ public final Collator getCollator() {
+ if (collator == null) {
+ collator= Collator.getInstance();
+ }
+ return collator;
+ }
+
+ public int category(Object element) {
+ if (element instanceof IResource) {
+ return -((IResource) element).getType();
+ }
+ return 0;
+ }
+
+ public void sort(Viewer viewer, Object[] elements) {
+ if (elements.length > 0) {
+ Object o= elements[0];
+ if (o instanceof RetrieverLine) {
+ sortLines(viewer, elements);
+ return;
+ }
+ super.sort(viewer, elements);
+ }
+ }
+
+ private void sortLines(Viewer viewer, Object[] elements) {
+ Arrays.sort(elements, new Comparator() {
+ public int compare(Object a, Object b) {
+ RetrieverLine l1= (RetrieverLine) a;
+ RetrieverLine l2= (RetrieverLine) b;
+ return l1.getLineNumber() - l2.getLineNumber();
+ }
+ });
+ }
+
+
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/TextFileScannerRegistry.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/TextFileScannerRegistry.java
new file mode 100644
index 00000000000..84d844c8f90
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/TextFileScannerRegistry.java
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+
+import org.eclipse.jface.util.SafeRunnable;
+
+import org.eclipse.search.core.text.AbstractTextFileScanner;
+
+import org.eclipse.search.internal.ui.SearchPlugin;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class TextFileScannerRegistry {
+ private static final String ID_TEXT_FILE_SCANNER= "org.eclipse.search.textFileScanner"; //$NON-NLS-1$
+
+ private static final String ATTRIBUTE_SEPARATOR= ","; //$NON-NLS-1$
+ private static final String ATTRIBUTE_FILE_EXTENSIONS= "fileExtensions"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_CONTENT_TYPE_IDS= "contentTypeIDs"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_COMMENT_SUPPORT= "supportsComments"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_STRING_SUPPORT= "supportsStrings"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_INCLUDE_SUPPORT= "supportsIncludes"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_PREPROCESSOR_SUPPORT= "supportsPreprocessor"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_FUNCTION_SUPPORT= "supportsFunctions"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_CLASS= "class"; //$NON-NLS-1$
+ private static final String SCANNER_NODE_NAME= "textFileScanner"; //$NON-NLS-1$
+ private static final ScannerProxyChain NULL_CHAIN= new ScannerProxyChain();
+
+ private static TextFileScannerRegistry sInstance= null;
+
+ public static TextFileScannerRegistry getInstance() {
+ if (sInstance == null) {
+ sInstance= new TextFileScannerRegistry();
+ }
+ return sInstance;
+ }
+
+ private static class ScannerProxyChain {
+ private ArrayList fProxies= new ArrayList();
+ private AbstractTextFileScanner fScanner= null;
+ public void sort() {
+ Collections.sort(fProxies);
+ }
+ public void add(ScannerProxy proxy) {
+ fProxies.add(proxy);
+ }
+ public AbstractTextFileScanner getScanner() {
+ return fScanner;
+ }
+ public AbstractTextFileScanner computeScanner() {
+ if (fScanner == null) {
+ for (Iterator iter= fProxies.iterator(); fScanner == null && iter.hasNext();) {
+ ScannerProxy proxy= (ScannerProxy) iter.next();
+ if (proxy.isDisabled()) {
+ iter.remove();
+ } else {
+ fScanner= proxy.createScanner();
+ }
+ }
+ }
+ return fScanner;
+ }
+ }
+
+ private static class ScannerProxy implements Comparable {
+ public static final ScannerProxy NULL_PROXY= new ScannerProxy(null, 0);
+ private IConfigurationElement fConfigElem;
+ private int fPriority;
+ private boolean fIsDisabled= false;
+
+ public ScannerProxy(IConfigurationElement elem, int locationSupport) {
+ fConfigElem= elem;
+ fPriority= getPriority(locationSupport);
+
+ }
+
+ public AbstractTextFileScanner createScanner() {
+ final AbstractTextFileScanner[] holder= {null};
+ ISafeRunnable code= new SafeRunnable(SearchMessages.TextFileScannerRegistry_error_instanciateScanner) {
+ public void run() throws Exception {
+ holder[0]= (AbstractTextFileScanner) fConfigElem.createExecutableExtension(ATTRIBUTE_CLASS);
+ }
+ public void handleException(Throwable e) {
+ disable();
+ }
+ };
+ Platform.run(code);
+ return holder[0];
+ }
+
+ public int getPriority(int locations) {
+ int priority= 0;
+ if (supportsLocation(locations, AbstractTextFileScanner.LOCATION_COMMENT)) {
+ priority+= 3;
+ }
+ if (supportsLocation(locations, AbstractTextFileScanner.LOCATION_STRING_LITERAL)) {
+ priority+= 3;
+ }
+ if (supportsLocation(locations, AbstractTextFileScanner.LOCATION_PREPROCESSOR_DIRECTIVE)) {
+ priority+= 1;
+ }
+ if (supportsLocation(locations, AbstractTextFileScanner.LOCATION_IMPORT_OR_INCLUDE_STATEMENT)) {
+ priority+= 2;
+ }
+ if (supportsLocation(locations, AbstractTextFileScanner.LOCATION_FUNCTION)) {
+ priority+= 1;
+ }
+ return priority;
+ }
+
+ public int compareTo(Object o) {
+ return -(fPriority - ((ScannerProxy) o).fPriority);
+ }
+
+ public boolean isDisabled() {
+ return fIsDisabled;
+ }
+
+ public void disable() {
+ fIsDisabled= true;
+ }
+ }
+
+ private HashMap fContentTypeMap= new HashMap();
+ private HashMap fExtensionsMap= new HashMap();
+ private AbstractTextFileScanner fLineNumberScanner= new LineNumberScanner();
+ private int fAvailableLocations;
+
+ private TextFileScannerRegistry() {
+ registerExtensions();
+ }
+
+ private void registerExtensions() {
+ fAvailableLocations= 0;
+ IExtensionPoint ep= Platform.getExtensionRegistry().getExtensionPoint(ID_TEXT_FILE_SCANNER);
+ if (ep != null) {
+ IExtension[] extensions= ep.getExtensions();
+ if (extensions != null) {
+ for (int i= 0; i < extensions.length; i++) {
+ IConfigurationElement[] elems= extensions[i].getConfigurationElements();
+ if (elems != null) {
+ for (int j= 0; j < elems.length; j++) {
+ IConfigurationElement elem= elems[j];
+ if (SCANNER_NODE_NAME.equals(elem.getName())) {
+ String contentTypeIDs= elem.getAttribute(ATTRIBUTE_CONTENT_TYPE_IDS);
+ String fileExtensions= elem.getAttribute(ATTRIBUTE_FILE_EXTENSIONS);
+ int locationSupport= getLocationSupport(elem);
+ fAvailableLocations|= locationSupport;
+ ScannerProxy proxy= new ScannerProxy(elem, locationSupport);
+ registerProxy(contentTypeIDs, proxy, fContentTypeMap);
+ registerProxy(fileExtensions, proxy, fExtensionsMap);
+ }
+ }
+ }
+ }
+ }
+ }
+ sortProxyChains(fContentTypeMap.values());
+ sortProxyChains(fExtensionsMap.values());
+ }
+
+ private void sortProxyChains(Collection chains) {
+ for (Iterator iter= chains.iterator(); iter.hasNext();) {
+ ScannerProxyChain chain= (ScannerProxyChain) iter.next();
+ chain.sort();
+ }
+ }
+
+ private int getLocationSupport(IConfigurationElement elem) {
+ int result= 0;
+ result|= hasSupport(elem, ATTRIBUTE_COMMENT_SUPPORT, 1 << AbstractTextFileScanner.LOCATION_COMMENT);
+ result|= hasSupport(elem, ATTRIBUTE_STRING_SUPPORT, 1 << AbstractTextFileScanner.LOCATION_STRING_LITERAL);
+ result|= hasSupport(elem, ATTRIBUTE_INCLUDE_SUPPORT, 1 << AbstractTextFileScanner.LOCATION_IMPORT_OR_INCLUDE_STATEMENT);
+ result|= hasSupport(elem, ATTRIBUTE_PREPROCESSOR_SUPPORT, 1 << AbstractTextFileScanner.LOCATION_PREPROCESSOR_DIRECTIVE);
+ result|= hasSupport(elem, ATTRIBUTE_FUNCTION_SUPPORT, 1 << AbstractTextFileScanner.LOCATION_FUNCTION);
+ return result;
+ }
+
+ private int hasSupport(IConfigurationElement elem, String attrib, int value) {
+ String aval= elem.getAttribute(attrib);
+ if (aval != null && Boolean.valueOf(aval).booleanValue()) {
+ return value;
+ }
+ return 0;
+ }
+
+ private void registerProxy(String idList, ScannerProxy proxy, HashMap map) {
+ if (idList != null) {
+ String[] ids= idList.split(ATTRIBUTE_SEPARATOR);
+ for (int k= 0; k < ids.length; k++) {
+ String id= ids[k].trim();
+ if (id.length() > 0) {
+ ScannerProxyChain chain= (ScannerProxyChain) map.get(id);
+ if (chain == null) {
+ chain= new ScannerProxyChain();
+ map.put(id, chain);
+ }
+ chain.add(proxy);
+ }
+ }
+ }
+ }
+
+ public AbstractTextFileScanner findScanner(IFile file) {
+ ScannerProxyChain chain= NULL_CHAIN;
+ if (file != null) {
+ // first try to find a scanner with the content type
+ IProject prj= file.getProject();
+ IContentType ct;
+ try {
+ ct= prj.getContentTypeMatcher().findContentTypeFor(file.getName());
+ if (ct != null) {
+ chain= findScanner(ct);
+ }
+ } catch (CoreException e) {
+ SearchPlugin.log(e.getStatus());
+ }
+
+ // try to find scanner by file extension
+ if (chain == NULL_CHAIN) {
+ chain= findScanner(file.getName());
+ }
+ }
+ return chain.getScanner();
+ }
+
+ private ScannerProxyChain findScanner(IContentType ct) {
+ String id= ct.getId();
+ ScannerProxyChain chain= (ScannerProxyChain) fContentTypeMap.get(id);
+ if (chain != null) {
+ if (chain == NULL_CHAIN || chain.computeScanner() != null) {
+ return chain;
+ }
+ }
+
+ // no cached element
+ ct= ct.getBaseType();
+ chain= ct == null ? NULL_CHAIN : findScanner(ct);
+
+ fContentTypeMap.put(id, chain);
+ return chain;
+ }
+
+ private ScannerProxyChain findScanner(String name) {
+ int idx= 0;
+ while (true) {
+ ScannerProxyChain chain= (ScannerProxyChain) fExtensionsMap.get(name);
+ if (chain != null) {
+ if (chain.computeScanner() != null) {
+ return chain;
+ }
+ fExtensionsMap.remove(name);
+ }
+
+ idx= name.indexOf('.', 1);
+ if (idx < 0) {
+ return NULL_CHAIN;
+ }
+ name= name.substring(idx);
+ }
+ }
+
+ public AbstractTextFileScanner getLineNumberScanner() {
+ return fLineNumberScanner;
+ }
+
+ private static boolean supportsLocation(int locations, int location) {
+ return (locations & (1 << location)) != 0;
+ }
+
+ public boolean hasPreprocessorSupport() {
+ return supportsLocation(fAvailableLocations, AbstractTextFileScanner.LOCATION_PREPROCESSOR_DIRECTIVE);
+ }
+
+ public boolean hasFunctionSupport() {
+ return supportsLocation(fAvailableLocations, AbstractTextFileScanner.LOCATION_FUNCTION);
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WindowWorkingSetScopeDescription.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WindowWorkingSetScopeDescription.java
new file mode 100644
index 00000000000..d93a6779d23
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WindowWorkingSetScopeDescription.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.Properties;
+
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkingSet;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class WindowWorkingSetScopeDescription extends WorkingSetScopeDescription {
+
+ public WindowWorkingSetScopeDescription() {
+ setLabel(SearchMessages.WindowWorkingSetScopeDescription_label);
+ }
+
+ public IResource[] getRoots(IWorkbenchPage page) {
+ IWorkingSet ws= page.getAggregateWorkingSet();
+ return getRootsFromWorkingSet(ws);
+ }
+
+ public void store(IDialogSettings section) {
+ }
+ public void restore(IDialogSettings section) {
+ }
+
+ public void store(Properties props, String prefix) {
+ }
+ public void restore(Properties props, String prefix) {
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WorkingSetScopeDescription.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WorkingSetScopeDescription.java
new file mode 100644
index 00000000000..c1d3c43b0cb
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WorkingSetScopeDescription.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.window.Window;
+
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog;
+
+public class WorkingSetScopeDescription implements IScopeDescription {
+ private static final String KEY_WORKING_SET_NAME= "workingset-name"; //$NON-NLS-1$
+ private static final String KEY_LABEL= "workingset-label"; //$NON-NLS-1$
+ private static final IResource[] EMPTY_ARRAY= new IResource[0];
+ private String fWorkingSetName;
+ private String fLabel;
+
+ public WorkingSetScopeDescription() {
+ }
+
+ public WorkingSetScopeDescription(IWorkingSet set) {
+ fWorkingSetName= set.getName();
+ fLabel= set.getLabel();
+ // try to change the label
+ if (set.isAggregateWorkingSet()) {
+ computeLabel();
+ }
+ }
+
+ private void computeLabel() {
+ if (fWorkingSetName.startsWith("Aggregate:") && //$NON-NLS-1$
+ fWorkingSetName.charAt(fWorkingSetName.length() - 1) == ':') {
+ fLabel= fWorkingSetName.substring(10, fWorkingSetName.length() - 1).replace(':', '+');
+ }
+ }
+
+ public String getLabel() {
+ return fLabel;
+ }
+
+ protected void setLabel(String label) {
+ fLabel= label;
+ }
+
+ public IResource[] getRoots(IWorkbenchPage page) {
+ IWorkingSetManager workingSetManager= PlatformUI.getWorkbench().getWorkingSetManager();
+ IWorkingSet ws= workingSetManager.getWorkingSet(fWorkingSetName);
+
+ return getRootsFromWorkingSet(ws);
+ }
+
+ protected IResource[] getRootsFromWorkingSet(IWorkingSet ws) {
+ if (ws == null) {
+ return EMPTY_ARRAY;
+ }
+
+ HashSet resources= new HashSet();
+ getResources(ws.getElements(), resources);
+
+ // remove duplicates
+ for (Iterator iter= resources.iterator(); iter.hasNext();) {
+ IResource r= (IResource) iter.next();
+ IResource parent= r.getParent();
+ while (parent != null) {
+ if (resources.contains(parent)) {
+ iter.remove();
+ parent= null;
+ } else {
+ parent= parent.getParent();
+ }
+ }
+ }
+ return (IResource[]) resources.toArray(new IResource[resources.size()]);
+ }
+
+ public String getWorkingSetName() {
+ return fWorkingSetName;
+ }
+
+ private void getResources(IAdaptable[] elements, Collection target) {
+ for (int i= 0; i < elements.length; i++) {
+ IAdaptable adaptable= elements[i];
+ IResource r= (IResource) adaptable.getAdapter(IResource.class);
+ if (r != null) {
+ target.add(r);
+ }
+ }
+ }
+
+ public void restore(IDialogSettings section) {
+ fWorkingSetName= section.get(KEY_WORKING_SET_NAME);
+ fLabel= section.get(KEY_LABEL);
+ if (fLabel == null) {
+ fLabel= fWorkingSetName;
+ }
+ }
+
+ public void store(IDialogSettings section) {
+ section.put(KEY_WORKING_SET_NAME, fWorkingSetName);
+ section.put(KEY_LABEL, fLabel);
+ }
+
+ public void store(Properties props, String prefix) {
+ props.put(prefix + KEY_WORKING_SET_NAME, fWorkingSetName);
+ props.put(prefix + KEY_LABEL, fLabel);
+ }
+
+ public void restore(Properties props, String prefix) {
+ fWorkingSetName= (String) props.get(prefix + KEY_WORKING_SET_NAME);
+ fLabel= (String) props.get(prefix + KEY_LABEL);
+ if (fLabel == null) {
+ fLabel= fWorkingSetName;
+ }
+ }
+
+ public static IScopeDescription createWithDialog(IWorkbenchPage page, IScopeDescription scope) {
+ if (page == null) {
+ return null;
+ }
+ IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager();
+ IWorkingSetSelectionDialog dialog= manager.createWorkingSetSelectionDialog(page.getWorkbenchWindow().getShell(), false);
+
+ IScopeDescription result= null;
+ if (scope instanceof WindowWorkingSetScopeDescription) {
+ dialog.setSelection(new IWorkingSet[] {page.getAggregateWorkingSet()});
+ } else
+ if (scope instanceof WorkingSetScopeDescription) {
+ WorkingSetScopeDescription wsetscope= (WorkingSetScopeDescription) scope;
+ String name= wsetscope.getWorkingSetName();
+ IWorkingSet ws= manager.getWorkingSet(name);
+ if (ws != null) {
+ dialog.setSelection(new IWorkingSet[] {ws});
+ }
+ }
+
+ if (dialog.open() == Window.OK) {
+ IWorkingSet[] wsarray= dialog.getSelection();
+ if (wsarray != null && wsarray.length > 0) {
+ IWorkingSet ws= wsarray[0];
+ if (ws == page.getAggregateWorkingSet()) {
+ result= new WindowWorkingSetScopeDescription();
+ } else {
+ result= new WorkingSetScopeDescription(ws);
+ manager.addRecentWorkingSet(ws);
+ }
+ } else {
+ result= new WorkspaceScopeDescription();
+ }
+ }
+ return result;
+ }
+}
diff --git a/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WorkspaceScopeDescription.java b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WorkspaceScopeDescription.java
new file mode 100644
index 00000000000..0d54867acd5
--- /dev/null
+++ b/org.eclipse.search/new search/org/eclipse/search2/internal/ui/text2/WorkspaceScopeDescription.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search2.internal.ui.text2;
+
+import java.util.Properties;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+
+import org.eclipse.ui.IWorkbenchPage;
+
+import org.eclipse.search2.internal.ui.SearchMessages;
+
+public class WorkspaceScopeDescription implements IScopeDescription {
+ public static final String LABEL= SearchMessages.WorkspaceScopeDescription_label;
+
+ public WorkspaceScopeDescription() {
+ }
+
+ public String getLabel() {
+ return LABEL;
+ }
+
+ public IResource[] getRoots(IWorkbenchPage page) {
+ return ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ }
+
+ public void restore(IDialogSettings section) {
+ }
+
+ public void store(IDialogSettings section) {
+ }
+
+ public void store(Properties props, String prefix) {
+ }
+
+ public void restore(Properties props, String prefix) {
+ }
+}
diff --git a/org.eclipse.search/plugin.properties b/org.eclipse.search/plugin.properties
index a653d7b4b21..523348c7ad1 100644
--- a/org.eclipse.search/plugin.properties
+++ b/org.eclipse.search/plugin.properties
@@ -27,6 +27,35 @@ openFileSearchPageAction.label= &File...
openSearchDialogAction.label= Se&arch...
openSearchDialogAction.tooltip= Search
+textSearchSubMenu.label= Te&xt
+
+action.performTextSearch.label= &Recent Scope
+action.performTextSearch.tooltip= Search for Text in Recent Search Scope
+command.performTextSearch.name= Find Text in Recent Scope
+command.performTextSearch.description= Searches the files in the recent search scope for specific text.
+
+action.performTextSearchWorkspace.label= &Workspace
+action.performTextSearchWorkspace.tooltip= Search for Text in Workspace
+command.performTextSearchWorkspace.name= Find Text in Workspace
+command.performTextSearchWorkspace.description= Searches the files in the workspace for specific text.
+
+action.performTextSearchProject.label= &Project
+action.performTextSearchProject.tooltip= Search for Text in Project
+command.performTextSearchProject.name= Find Text in Project
+command.performTextSearchProject.description= Searches the files in the project for specific text.
+
+action.performTextSearchFile.label= &File
+action.performTextSearchFile.tooltip= Search for Text in File
+command.performTextSearchFile.name= Find Text in File
+command.performTextSearchFile.description= Searches the files in the file for specific text.
+
+action.performTextSearchWorkingSet.label= Working &Set...
+action.performTextSearchWorkingSet.tooltip= Search for Text in a Working Set
+command.performTextSearchWorkingSet.name= Find Text in Working Set
+command.performTextSearchWorkingSet.description= Searches the files in the working set for specific text.
+
+RetrieverPage.label= Text Search
+
fileSearch= File Search
searchResultViewName= Classic Search
newSearchResultViewName= Search
diff --git a/org.eclipse.search/plugin.xml b/org.eclipse.search/plugin.xml
index ac66fdd349f..560138fe097 100644
--- a/org.eclipse.search/plugin.xml
+++ b/org.eclipse.search/plugin.xml
@@ -11,6 +11,8 @@
<extension-point name="%searchPages" id="searchPages" schema="schema/searchPages.exsd"/>
<extension-point name="%searchResultSorters" id="searchResultSorters" schema="schema/searchResultSorters.exsd"/>
<extension-point name="%searchResultViewPages" id="searchResultViewPages" schema="schema/searchResultViewPages.exsd"/>
+ <extension-point name="%textFileScanner" id="textFileScanner" schema="schema/textFileScanner.exsd"/>
+ <extension-point id="textSearchEngine" name="%textSearchEngine" schema="schema/textSearchEngine.exsd"/>
<!-- Extensions -->
@@ -93,6 +95,37 @@
name="%ViewCommand.searchView.name"
description="%ViewCommand.searchView.description"
/>
+
+ <command
+ categoryId="org.eclipse.search.ui.category.search"
+ description="%command.performTextSearch.description"
+ id="org.eclipse.search.ui.performTextSearch"
+ name="%command.performTextSearch.name"/>
+ <command
+ categoryId="org.eclipse.search.ui.category.search"
+ id="org.eclipse.search.ui.performTextSearchWorkingSet"
+ name="%command.performTextSearchWorkingSet.name"
+ description="%command.performTextSearchWorkingSet.description"
+ />
+ <command
+ categoryId="org.eclipse.search.ui.category.search"
+ id="org.eclipse.search.ui.performTextSearchWorkspace"
+ name="%command.performTextSearchWorkspace.name"
+ description="%command.performTextSearchWorkspace.description"
+ />
+ <command
+ categoryId="org.eclipse.search.ui.category.search"
+ id="org.eclipse.search.ui.performTextSearchProject"
+ name="%command.performTextSearchProject.name"
+ description="%command.performTextSearchProject.description"
+ />
+ <command
+ categoryId="org.eclipse.search.ui.category.search"
+ id="org.eclipse.search.ui.performTextSearchFile"
+ name="%command.performTextSearchFile.name"
+ description="%command.performTextSearchFile.description"
+ />
+
</extension>
<extension point="org.eclipse.ui.bindings">
@@ -119,6 +152,18 @@
commandId="org.eclipse.search.ui.views.SearchView"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
/>
+ <key
+ contextId="org.eclipse.ui.globalScope"
+ sequence="Ctrl+2"
+ commandId="org.eclipse.search.ui.performTextSearch"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ />
+ <key
+ contextId="org.eclipse.jdt.ui.javaEditorScope"
+ sequence="Ctrl+2 2"
+ commandId="org.eclipse.search.ui.performTextSearch"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ />
</extension>
<!-- action sets -->
@@ -160,9 +205,57 @@
icon="$nl$/icons/full/etool16/search.gif"
helpContextId="open_search_dialog_action_context"
class="org.eclipse.search.internal.ui.OpenSearchDialogAction"/>
+
+ <action id="org.eclipse.search.TextSearchWorkingSet"
+ definitionId="org.eclipse.search.ui.performTextSearchWorkingSet"
+ menubarPath="org.eclipse.search.menu/textSearchSubMenu/group1"
+ style="push"
+ label="%action.performTextSearchWorkingSet.label"
+ tooltip= "%action.performTextSearchWorkingSet.tooltip"
+ class="org.eclipse.search2.internal.ui.text2.FindInWorkingSetActionDelegate"/>
+
+ <!-- Various actions for the text search in a sub menu -->
+ <menu id="textSearchSubMenu"
+ label="%textSearchSubMenu.label"
+ path="org.eclipse.search.menu/contextMenuActionsGroup">
+ <separator name="group0"/>
+ <separator name="group1"/>
+ </menu>
+ <action id="org.eclipse.search.TextSearchFile"
+ definitionId="org.eclipse.search.ui.performTextSearchFile"
+ menubarPath="org.eclipse.search.menu/textSearchSubMenu/group1"
+ style="push"
+ label="%action.performTextSearchFile.label"
+ tooltip= "%action.performTextSearchFile.tooltip"
+ class="org.eclipse.search2.internal.ui.text2.FindInFileActionDelegate"/>
+
+ <action id="org.eclipse.search.TextSearchProject"
+ definitionId="org.eclipse.search.ui.performTextSearchProject"
+ menubarPath="org.eclipse.search.menu/textSearchSubMenu/group1"
+ style="push"
+ label="%action.performTextSearchProject.label"
+ tooltip= "%action.performTextSearchProject.tooltip"
+ class="org.eclipse.search2.internal.ui.text2.FindInProjectActionDelegate"/>
+
+ <action id="org.eclipse.search.TextSearchWorkspace"
+ definitionId="org.eclipse.search.ui.performTextSearchWorkspace"
+ menubarPath="org.eclipse.search.menu/textSearchSubMenu/group1"
+ style="push"
+ label="%action.performTextSearchWorkspace.label"
+ tooltip= "%action.performTextSearchWorkspace.tooltip"
+ class="org.eclipse.search2.internal.ui.text2.FindInWorkspaceActionDelegate"/>
+
+ <action
+ class="org.eclipse.search2.internal.ui.text2.FindInRecentScopeActionDelegate"
+ definitionId="org.eclipse.search.ui.performTextSearch"
+ id="org.eclipse.search.TextSearch"
+ label="%action.performTextSearch.label"
+ menubarPath="org.eclipse.search.menu/textSearchSubMenu/group0"
+ style="push"
+ tooltip="%action.performTextSearch.tooltip"/>
</actionSet>
</extension>
-
+
<extension point="org.eclipse.ui.views">
<view
id="org.eclipse.search.SearchResultView"
@@ -190,6 +283,14 @@
searchResultClass="org.eclipse.search.internal.ui.text.FileSearchResult"
class="org.eclipse.search.internal.ui.text.FileSearchPage">
</viewPage>
+ <viewPage
+ class="org.eclipse.search2.internal.ui.text2.RetrieverPage"
+ emptyPageUseful="true"
+ icon="icons/full/obj16/tsearch_dpdn_obj.gif"
+ id="org.eclipse.search.text.RetrieverPage"
+ label="%RetrieverPage.label"
+ searchResultClass="org.eclipse.search2.internal.ui.text2.RetrieverResult">
+ </viewPage>
</extension>
<extension point="org.eclipse.search.searchPages">
@@ -283,9 +384,21 @@
<factory
class="org.eclipse.search.internal.ui.SearchResultViewEntryAdapterFactory"
adaptableType="org.eclipse.search.ui.ISearchResultViewEntry">
- <adapter type="org.eclipse.core.resources.IResource"/>
- <adapter type="org.eclipse.core.resources.IMarker"/>
+ <adapter type="org.eclipse.core.resources.IResource"/>
+ <adapter type="org.eclipse.core.resources.IMarker"/>
</factory>
- </extension>
-
+ </extension>
+ <extension
+ id="java-scanner"
+ point="org.eclipse.search.textFileScanner">
+ <textFileScanner
+ class="org.eclipse.search2.internal.ui.text2.JavaScanner"
+ contentTypeIDs="org.eclipse.jdt.core.javaSource"
+ fileExtensions=".java"
+ supportsComments="true"
+ supportsFunctions="false"
+ supportsIncludes="true"
+ supportsPreprocessor="false"
+ supportsStrings="true"/>
+ </extension>
</plugin> \ No newline at end of file
diff --git a/org.eclipse.search/schema/textFileScanner.exsd b/org.eclipse.search/schema/textFileScanner.exsd
new file mode 100644
index 00000000000..a870008d5c0
--- /dev/null
+++ b/org.eclipse.search/schema/textFileScanner.exsd
@@ -0,0 +1,162 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.search">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.search" id="textFileScanner" name="Text File Scanner"/>
+ </appInfo>
+ <documentation>
+ The extension point allows to register a scanner that categorizes text-matches.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="textFileScanner" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="textFileScanner">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ Class of the scanner that will be created, must extend org.eclipse.search.core.text.AbstractTextFileScanner.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.search.core.text.AbstractTextFileScanner"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="fileExtensions" type="string">
+ <annotation>
+ <documentation>
+ Comma separated list of file-extensions for which the scanner shall be applied. E.g. &apos;.c,.h,.cpp&apos;. In case an extension does not start with a dot, a match against the complete file-name will be attempted. E.g. &apos;Makefile,.mk&apos;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="contentTypeIDs" type="string">
+ <annotation>
+ <documentation>
+ A comma-separated list of content type ids for which the supplied scanner shall be used. E.g.: &apos;org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cppSource&apos;
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="supportsComments" type="boolean">
+ <annotation>
+ <documentation>
+ True, if the scanner can detect comments. False, otherwise.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="supportsStrings" type="boolean">
+ <annotation>
+ <documentation>
+ True, if the scanner can detect string literals False, otherwise.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="supportsIncludes" type="boolean">
+ <annotation>
+ <documentation>
+ True, if the scanner can detect include or import statements. False, otherwise.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="supportsPreprocessor" type="boolean">
+ <annotation>
+ <documentation>
+ True, if the scanner can detect preprocessor directives. False, otherwise.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="supportsFunctions" type="boolean">
+ <annotation>
+ <documentation>
+ True, if the scanner can detect function bodies. False, otherwise.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 3.2
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ As an example, here is the markup for the java scanner.
+
+&lt;p&gt;
+&lt;pre&gt;
+&lt;extension id=&quot;JavaScanner&quot;
+ point=&quot;org.eclipse.search.textFileScanner&quot;&gt;
+ &lt;textFileScanner
+ class=&quot;org.eclipse.search2.internal.ui.text2.JavaScanner&quot;
+ contentTypeIDs=&quot;org.eclipse.jdt.core.javaSource&quot;
+ fileExtensions=&quot;.java&quot;
+ supportsComments=&quot;true&quot;
+ supportsStrings=&quot;true&quot;
+ supportsIncludes=&quot;true&quot;/&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ The contributed class must implement &lt;code&gt;org.eclipse.search.core.text.AbstractTextFileScanner&lt;/code&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ The search plugin provides both a scanner for java-files and for c/c++-files.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2006 Wind River Systems 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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/org.eclipse.search/schema/textSearchEngine.exsd b/org.eclipse.search/schema/textSearchEngine.exsd
new file mode 100644
index 00000000000..00a8f984e70
--- /dev/null
+++ b/org.eclipse.search/schema/textSearchEngine.exsd
@@ -0,0 +1,134 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.search">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.search" id="textSearchEngine" name="Text Search Engine"/>
+ </appInfo>
+ <documentation>
+ The extension point allows to register a text search engine that is used to search for text in files of the workspace.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="textSearchEngine" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <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="textSearchEngine">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ Used to distinguish different search engines.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ Used when search engine is presented in UI.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The class implementing org.eclipse.search.core.text.TextSearchEngine.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.search.core.text.TextSearchEngine"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 3.2
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ As an example, here is the markup for suppling a search engine
+
+&lt;p&gt;
+&lt;pre&gt;
+&lt;extension id=&quot;MyEngine&quot;
+ point=&quot;org.eclipse.search.textSearchEngine&quot;&gt;
+ &lt;textFileScanner
+ id=&quot;com.windriver.textSearchEngine&quot;
+ label=&quot;Wind River Search&quot;
+ class=&quot;com.windriver.text.SearchEngine&quot; /&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ The contributed class must implement &lt;code&gt;org.eclipse.search.core.text.TextSearchEngine&lt;/code&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2006 Wind River Systems 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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/core/text/FileNamePatternSearchScope.java b/org.eclipse.search/search/org/eclipse/search/internal/core/text/FileNamePatternSearchScope.java
index d03a728e658..95889e06ccd 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/core/text/FileNamePatternSearchScope.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/core/text/FileNamePatternSearchScope.java
@@ -147,7 +147,7 @@ public class FileNamePatternSearchScope extends TextSearchScope {
pattern= Pattern.compile(".*"); //$NON-NLS-1$
} else {
String[] patternStrings= (String[]) fFileNamePatterns.toArray(new String[fFileNamePatterns.size()]);
- pattern= PatternConstructor.createPattern(patternStrings, IS_CASE_SENSITIVE_FILESYSTEM, false);
+ pattern= PatternConstructor.createPattern(patternStrings, IS_CASE_SENSITIVE_FILESYSTEM);
}
fFileNameMatcher= pattern.matcher(""); //$NON-NLS-1$
}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/core/text/AmountOfWorkCalculator.java b/org.eclipse.search/search/org/eclipse/search/internal/core/text/FilesOfScopeCalculator.java
index 4edc3687261..b07fb5e4651 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/core/text/AmountOfWorkCalculator.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/core/text/FilesOfScopeCalculator.java
@@ -10,46 +10,53 @@
*******************************************************************************/
package org.eclipse.search.internal.core.text;
+import java.util.ArrayList;
+
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.search.core.text.TextSearchScope;
-/**
- * The visitor that does the actual work.
- */
-public class AmountOfWorkCalculator implements IResourceProxyVisitor {
-
+public class FilesOfScopeCalculator implements IResourceProxyVisitor {
+
private final TextSearchScope fScope;
-
- private int fFileCount;
+ private final MultiStatus fStatus;
+ private ArrayList fFiles;
- public AmountOfWorkCalculator(TextSearchScope scope) {
+ public FilesOfScopeCalculator(TextSearchScope scope, MultiStatus status) {
fScope= scope;
+ fStatus= status;
}
-
+
public boolean visit(IResourceProxy proxy) {
boolean inScope= fScope.contains(proxy);
-
+
if (inScope && proxy.getType() == IResource.FILE) {
- fFileCount++;
+ fFiles.add(proxy.requestResource());
}
return inScope;
}
-
- public int process() {
- fFileCount= 0;
- IResource[] roots= fScope.getRoots();
- for (int i= 0; i < roots.length; i++) {
- try {
- roots[i].accept(this, 0);
- } catch (CoreException ex) {
- // ignore
+
+ public IFile[] process() {
+ fFiles= new ArrayList();
+ try {
+ IResource[] roots= fScope.getRoots();
+ for (int i= 0; i < roots.length; i++) {
+ try {
+ roots[i].accept(this, 0);
+ } catch (CoreException ex) {
+ // report and ignore
+ fStatus.add(ex.getStatus());
+ }
}
+ return (IFile[]) fFiles.toArray(new IFile[fFiles.size()]);
+ } finally {
+ fFiles= null;
}
- return fFileCount;
}
}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/core/text/PatternConstructor.java b/org.eclipse.search/search/org/eclipse/search/internal/core/text/PatternConstructor.java
index 7d4a2f8f036..e5d176fe690 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/core/text/PatternConstructor.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/core/text/PatternConstructor.java
@@ -22,108 +22,145 @@ public class PatternConstructor {
private PatternConstructor() {
// don't instantiate
}
+
+ public static Pattern createPattern(String pattern, boolean isCaseSensitive, boolean isRegex) throws PatternSyntaxException {
+ return createPattern(pattern, isRegex, true, isCaseSensitive, false);
+ }
/**
* Creates a pattern element from the pattern string which is either a reg-ex expression or in our old
* 'StringMatcher' format.
* @param pattern The search pattern
+ * @param isRegex <code>true</code> if the passed string already is a reg-ex pattern
+ * @param isStringMatcher <code>true</code> if the passed string is in the StringMatcher format.
* @param isCaseSensitive Set to <code>true</code> to create a case insensitive pattern
- * @param isRegexSearch <code>true</code> if the passed string already is a reg-ex pattern
+ * @param isWholeWord <code>true</code> to create a pattern that requires a word boundary at the beginning and the end.
* @return The created pattern
* @throws PatternSyntaxException
*/
- public static Pattern createPattern(String pattern, boolean isCaseSensitive, boolean isRegexSearch) throws PatternSyntaxException {
- if (!isRegexSearch) {
- pattern= asRegEx(pattern, new StringBuffer()).toString();
+ public static Pattern createPattern(String pattern, boolean isRegex, boolean isStringMatcher, boolean isCaseSensitive, boolean isWholeWord) throws PatternSyntaxException {
+ if (isRegex) {
+ if (isWholeWord) {
+ StringBuffer buffer= new StringBuffer(pattern.length() + 10);
+ buffer.append("\\b(?:").append(pattern).append(")\\b"); //$NON-NLS-1$ //$NON-NLS-2$
+ pattern= buffer.toString();
+ }
+ } else {
+ int len= pattern.length();
+ StringBuffer buffer= new StringBuffer(len + 10);
+ // don't add a word boundary if the search text does not start with
+ // a word char. (this works around a user input error).
+ if (isWholeWord && len > 0 && isWordChar(pattern.charAt(0))) {
+ buffer.append("\\b"); //$NON-NLS-1$
+ }
+ appendAsRegEx(isStringMatcher, pattern, buffer);
+ if (isWholeWord && len > 0 && isWordChar(pattern.charAt(len - 1))) {
+ buffer.append("\\b"); //$NON-NLS-1$
+ }
+ pattern= buffer.toString();
}
-
- if (!isCaseSensitive)
- return Pattern.compile(pattern, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.MULTILINE);
-
- return Pattern.compile(pattern, Pattern.MULTILINE);
+
+ int regexOptions= Pattern.MULTILINE;
+ if (!isCaseSensitive) {
+ regexOptions|= Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
+ }
+ return Pattern.compile(pattern, regexOptions);
}
- /**
- * Creates a pattern element from the pattern string which is either a reg-ex expression or in our old
+ private static boolean isWordChar(char c) {
+ return Character.isLetterOrDigit(c);
+ }
+
+ /**
+ * Creates a pattern element from an array of patterns in the old
* 'StringMatcher' format.
* @param patterns The search patterns
* @param isCaseSensitive Set to <code>true</code> to create a case insensitive pattern
- * @param isRegexSearch <code>true</code> if the passed string already is a reg-ex pattern
* @return The created pattern
* @throws PatternSyntaxException
*/
- public static Pattern createPattern(String[] patterns, boolean isCaseSensitive, boolean isRegexSearch) throws PatternSyntaxException {
+ public static Pattern createPattern(String[] patterns, boolean isCaseSensitive) throws PatternSyntaxException {
StringBuffer pattern= new StringBuffer();
for (int i= 0; i < patterns.length; i++) {
if (i > 0) {
+ // note that this works only as we know that the operands of the
+ // or expression will be simple and need no brackets.
pattern.append('|');
}
- if (isRegexSearch) {
- pattern.append(patterns[i]);
- } else {
- asRegEx(patterns[i], pattern);
- }
+ appendAsRegEx(true, patterns[i], pattern);
}
- return createPattern(pattern.toString(), isCaseSensitive, true);
+ return createPattern(pattern.toString(), true, true, isCaseSensitive, false);
}
- /**
- * Translates a StringMatcher pattern (using '*' and '?') to a regex pattern string
- * @param stringMatcherPattern a pattern using '*' and '?'
- */
- private static StringBuffer asRegEx(String stringMatcherPattern, StringBuffer out) {
- boolean escaped= false;
- boolean quoting= false;
-
- int i= 0;
- while (i < stringMatcherPattern.length()) {
- char ch= stringMatcherPattern.charAt(i++);
-
- if (ch == '*' && !escaped) {
- if (quoting) {
- out.append("\\E"); //$NON-NLS-1$
- quoting= false;
- }
- out.append(".*"); //$NON-NLS-1$
- escaped= false;
- continue;
- } else if (ch == '?' && !escaped) {
- if (quoting) {
- out.append("\\E"); //$NON-NLS-1$
- quoting= false;
- }
- out.append("."); //$NON-NLS-1$
- escaped= false;
- continue;
- } else if (ch == '\\' && !escaped) {
- escaped= true;
- continue;
-
- } else if (ch == '\\' && escaped) {
- escaped= false;
- if (quoting) {
- out.append("\\E"); //$NON-NLS-1$
- quoting= false;
- }
- out.append("\\\\"); //$NON-NLS-1$
- continue;
- }
-
- if (!quoting) {
- out.append("\\Q"); //$NON-NLS-1$
- quoting= true;
- }
- if (escaped && ch != '*' && ch != '?' && ch != '\\')
- out.append('\\');
- out.append(ch);
- escaped= ch == '\\';
-
- }
- if (quoting)
- out.append("\\E"); //$NON-NLS-1$
-
- return out;
- }
-
+ public static StringBuffer appendAsRegEx(boolean isStringMatcher, String pattern, StringBuffer buffer) {
+ boolean isEscaped= false;
+ for (int i = 0; i < pattern.length(); i++) {
+ char c = pattern.charAt(i);
+ switch(c) {
+ // the backslash
+ case '\\':
+ // the backslash is escape char in string matcher
+ if (isStringMatcher && !isEscaped) {
+ isEscaped= true;
+ }
+ else {
+ buffer.append("\\\\"); //$NON-NLS-1$
+ isEscaped= false;
+ }
+ break;
+ // characters that need to be escaped in the regex.
+ case '(':
+ case ')':
+ case '{':
+ case '}':
+ case '.':
+ case '[':
+ case ']':
+ case '$':
+ case '^':
+ case '+':
+ case '|':
+ if (isEscaped) {
+ buffer.append("\\\\"); //$NON-NLS-1$
+ isEscaped= false;
+ }
+ buffer.append('\\');
+ buffer.append(c);
+ break;
+ case '?':
+ if (isStringMatcher && !isEscaped) {
+ buffer.append('.');
+ }
+ else {
+ buffer.append('\\');
+ buffer.append(c);
+ isEscaped= false;
+ }
+ break;
+ case '*':
+ if (isStringMatcher && !isEscaped) {
+ buffer.append(".*"); //$NON-NLS-1$
+ }
+ else {
+ buffer.append('\\');
+ buffer.append(c);
+ isEscaped= false;
+ }
+ break;
+ default:
+ if (isEscaped) {
+ buffer.append("\\\\"); //$NON-NLS-1$
+ isEscaped= false;
+ }
+ buffer.append(c);
+ break;
+ }
+ }
+ if (isEscaped) {
+ buffer.append("\\\\"); //$NON-NLS-1$
+ isEscaped= false;
+ }
+ return buffer;
+ }
}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchEngineRegistry.java b/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchEngineRegistry.java
new file mode 100644
index 00000000000..c5a6606e632
--- /dev/null
+++ b/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchEngineRegistry.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems 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:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.search.internal.core.text;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Preferences;
+
+import org.eclipse.jface.util.SafeRunnable;
+
+import org.eclipse.search.core.text.TextSearchEngine;
+
+import org.eclipse.search.internal.ui.SearchMessages;
+import org.eclipse.search.internal.ui.SearchPlugin;
+import org.eclipse.search.internal.ui.SearchPreferencePage;
+
+
+public class TextSearchEngineRegistry {
+
+ private static final String ENGINE_NODE_NAME= "textSearchEngine"; //$NON-NLS-1$
+ private static final String ATTRIB_ID= "id"; //$NON-NLS-1$
+ private static final String ATTRIB_LABEL= "label"; //$NON-NLS-1$
+ private static final String ATTRIB_CLASS= "class"; //$NON-NLS-1$
+
+ private TextSearchEngine fPreferredEngine;
+ private String fPreferredEngineId;
+
+ public TextSearchEngineRegistry() {
+ fPreferredEngineId= null; // only null when not initialized
+ fPreferredEngine= null;
+ }
+
+ public TextSearchEngine getPreferred() {
+ String preferredId= getPreferredEngineID();
+ if (!preferredId.equals(fPreferredEngineId)) {
+ updateEngine(preferredId);
+ }
+ return fPreferredEngine;
+ }
+
+ private void updateEngine(String preferredId) {
+ if (preferredId.length() != 0) { // empty string: default engine
+ TextSearchEngine engine= createFromExtension(preferredId);
+ if (engine != null) {
+ fPreferredEngineId= preferredId;
+ fPreferredEngine= engine;
+ return;
+ }
+ // creation failed, clear preference
+ setPreferredEngineID(""); // set to default //$NON-NLS-1$
+ }
+ fPreferredEngineId= ""; //$NON-NLS-1$
+ fPreferredEngine= TextSearchEngine.createDefault();
+ }
+
+ private String getPreferredEngineID() {
+ Preferences prefs= SearchPlugin.getDefault().getPluginPreferences();
+ String preferedEngine= prefs.getString(SearchPreferencePage.TEXT_SEARCH_ENGINE);
+ return preferedEngine;
+ }
+
+ private void setPreferredEngineID(String id) {
+ Preferences prefs= SearchPlugin.getDefault().getPluginPreferences();
+ prefs.setValue(SearchPreferencePage.TEXT_SEARCH_ENGINE, id);
+ }
+
+ private TextSearchEngine createFromExtension(final String id) {
+ final TextSearchEngine[] res= new TextSearchEngine[] { null };
+
+ SafeRunnable safe= new SafeRunnable() {
+ public void run() throws Exception {
+ IConfigurationElement[] extensions= Platform.getExtensionRegistry().getConfigurationElementsFor(ENGINE_NODE_NAME);
+ for (int i= 0; i < extensions.length; i++) {
+ IConfigurationElement curr= extensions[i];
+ if (id.equals(curr.getAttribute(ATTRIB_ID))) {
+ res[0]= (TextSearchEngine) curr.createExecutableExtension(ATTRIB_CLASS);
+ return;
+ }
+ }
+ }
+ public void handleException(Throwable e) {
+ SearchPlugin.log(e);
+ }
+ };
+ Platform.run(safe);
+ return res[0];
+ }
+
+ public String[][] getAvailableEngines() {
+ ArrayList res= new ArrayList();
+ res.add(new String[] { SearchMessages.TextSearchEngineRegistry_defaulttextsearch_label, "" }); //$NON-NLS-1$
+
+ IConfigurationElement[] extensions= Platform.getExtensionRegistry().getConfigurationElementsFor(ENGINE_NODE_NAME);
+ for (int i= 0; i < extensions.length; i++) {
+ IConfigurationElement elem= extensions[i];
+ res.add(new String[] { elem.getAttribute(ATTRIB_LABEL), elem.getAttribute(ATTRIB_ID) });
+ }
+ return (String[][]) res.toArray(new String[res.size()][]);
+ }
+}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchVisitor.java b/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchVisitor.java
index cbc237ec383..079311e68da 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchVisitor.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchVisitor.java
@@ -13,6 +13,8 @@ package org.eclipse.search.internal.core.text;
import java.io.IOException;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
@@ -32,9 +34,6 @@ import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceProxy;
-import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.jface.text.IDocument;
@@ -60,7 +59,7 @@ import org.eclipse.search.internal.ui.SearchPlugin;
/**
* The visitor that does the actual work.
*/
-public class TextSearchVisitor implements IResourceProxyVisitor {
+public class TextSearchVisitor {
public static class ReusableMatchAccess extends TextSearchMatchAccess {
@@ -102,7 +101,6 @@ public class TextSearchVisitor implements IResourceProxyVisitor {
}
- private final TextSearchScope fScope;
private final TextSearchRequestor fCollector;
private final Matcher fMatcher;
@@ -120,33 +118,45 @@ public class TextSearchVisitor implements IResourceProxyVisitor {
private final ReusableMatchAccess fMatchAccess;
- public TextSearchVisitor(TextSearchScope scope, TextSearchRequestor collector, Pattern searchPattern, int fileCount, IProgressMonitor monitor) {
- fScope= scope;
+ public TextSearchVisitor(TextSearchRequestor collector, Pattern searchPattern, IProgressMonitor monitor) {
fCollector= collector;
- fProgressMonitor= monitor;
+ fProgressMonitor= monitor == null ? new NullProgressMonitor() : monitor;
fStatus= new MultiStatus(NewSearchUI.PLUGIN_ID, IStatus.OK, SearchMessages.TextSearchEngine_statusMessage, null);
fMatcher= searchPattern.pattern().length() == 0 ? null : searchPattern.matcher(new String());
- fNumberOfScannedFiles= 0;
- fNumberOfFilesToScan= fileCount;
-
fFileCharSequenceProvider= new FileCharSequenceProvider();
fMatchAccess= new ReusableMatchAccess();
}
- public void process() {
+ public IStatus search(TextSearchScope scope, Comparator searchOrder) {
+ IFile[] files= new FilesOfScopeCalculator(scope, fStatus).process();
+ fNumberOfScannedFiles= 0;
+ fNumberOfFilesToScan= files.length;
+ try {
+ fProgressMonitor.beginTask("", fNumberOfFilesToScan); //$NON-NLS-1$
+ if (fNumberOfFilesToScan > 0) {
+ Integer[] args= new Integer[] {new Integer(1), new Integer(fNumberOfFilesToScan)};
+ fProgressMonitor.setTaskName(Messages.format(SearchMessages.TextSearchEngine_scanning, args));
+ }
+ fCollector.beginReporting();
+ processFiles(files, searchOrder);
+ return fStatus;
+ } finally {
+ fProgressMonitor.done();
+ fCollector.endReporting();
+ }
+
+ }
+
+ private void processFiles(IFile[] files, Comparator searchOrder) {
fDocumentsInEditors= evalNonFileBufferDocuments();
-
- IResource[] roots= fScope.getRoots();
- for (int i= 0; i < roots.length; i++) {
- try {
- roots[i].accept(this, 0);
- } catch (CoreException ex) {
- fStatus.add(ex.getStatus());
- }
+ if (searchOrder != null) {
+ Arrays.sort(files, searchOrder);
+ }
+ for (int i= 0; i < files.length; i++) {
+ processFile(files[i]);
}
-
fDocumentsInEditors= null;
}
@@ -197,23 +207,12 @@ public class TextSearchVisitor implements IResourceProxyVisitor {
}
}
- public boolean visit(IResourceProxy proxy) {
- if (!fScope.contains(proxy)) {
- return false;
- }
- if (proxy.getType() != IResource.FILE) {
- return true;
- }
+ public void processFile(IFile file) {
try {
- IFile file= (IFile) proxy.requestResource();
-
- boolean res= fCollector.acceptFile(file);
- res= res || fCollector.acceptFile(proxy); //call for compatibility, remove before M5
- if (!res || fMatcher == null) {
- return false;
- }
-
-
+ if (!fCollector.acceptFile(file) || fMatcher == null) {
+ return;
+ }
+
IDocument document= getOpenDocument(file);
if (document != null) {
@@ -236,29 +235,24 @@ public class TextSearchVisitor implements IResourceProxyVisitor {
}
}
} catch (UnsupportedCharsetException e) {
- IFile file= (IFile) proxy.requestResource();
String[] args= { getCharSetName(file), file.getFullPath().makeRelative().toString()};
String message= Messages.format(SearchMessages.TextSearchVisitor_unsupportedcharset, args);
fStatus.add(new Status(IStatus.ERROR, NewSearchUI.PLUGIN_ID, Platform.PLUGIN_ERROR, message, e));
} catch (IllegalCharsetNameException e) {
- IFile file= (IFile) proxy.requestResource();
String[] args= { getCharSetName(file), file.getFullPath().makeRelative().toString()};
String message= Messages.format(SearchMessages.TextSearchVisitor_illegalcharset, args);
fStatus.add(new Status(IStatus.ERROR, NewSearchUI.PLUGIN_ID, Platform.PLUGIN_ERROR, message, e));
} catch (IOException e) {
- IFile file= (IFile) proxy.requestResource();
String[] args= { getExceptionMessage(e), file.getFullPath().makeRelative().toString()};
String message= Messages.format(SearchMessages.TextSearchVisitor_error, args);
fStatus.add(new Status(IStatus.ERROR, NewSearchUI.PLUGIN_ID, Platform.PLUGIN_ERROR, message, e));
} catch (CoreException e) {
- IFile file= (IFile) proxy.requestResource();
String[] args= { getExceptionMessage(e), file.getFullPath().makeRelative().toString()};
String message= Messages.format(SearchMessages.TextSearchVisitor_error, args);
fStatus.add(new Status(IStatus.ERROR, NewSearchUI.PLUGIN_ID, Platform.PLUGIN_ERROR, message, e));
} finally {
updateProgressMonitor();
}
- return false; // finish, files don't have children
}
private void locateMatches(IFile file, CharSequence searchInput) throws CoreException {
@@ -327,30 +321,5 @@ public class TextSearchVisitor implements IResourceProxyVisitor {
if (fProgressMonitor.isCanceled())
throw new OperationCanceledException(SearchMessages.TextSearchVisitor_canceled);
}
-
-
- public static IStatus search(TextSearchScope scope, TextSearchRequestor collector, Pattern searchPattern, IProgressMonitor monitor) {
- if (monitor == null) {
- monitor= new NullProgressMonitor();
- }
-
- int amountOfWork= new AmountOfWorkCalculator(scope).process();
- try {
- monitor.beginTask("", amountOfWork); //$NON-NLS-1$
- if (amountOfWork > 0) {
- Integer[] args= new Integer[] {new Integer(1), new Integer(amountOfWork)};
- monitor.setTaskName(Messages.format(SearchMessages.TextSearchEngine_scanning, args));
- }
- collector.beginReporting();
- TextSearchVisitor visitor= new TextSearchVisitor(scope, collector, searchPattern, amountOfWork, monitor);
- visitor.process();
- return visitor.getStatus();
- } finally {
- monitor.done();
- collector.endReporting();
- }
-
- }
-
}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.java
index 1bee616e20e..bd874b0726c 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.java
@@ -198,4 +198,6 @@ public final class SearchMessages extends NLS {
}
public static String ReplaceDialog2_nomatches_error;
+ public static String SearchPreferencePage_textSearchEngine;
+ public static String TextSearchEngineRegistry_defaulttextsearch_label;
} \ No newline at end of file
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.properties b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.properties
index 5de161b9e5b..74c0c2b126e 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.properties
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.properties
@@ -113,6 +113,7 @@ PreviousSearchesDialog_message= &Select one of the previous searches
TextSearchPage_replace_searchproblems_title=Replace
TextSearchPage_replace_searchproblems_message=Problems occurred while searching. The affected files will be skipped.
+TextSearchEngineRegistry_defaulttextsearch_label=Default Text Search
FileSearchQuery_label=File Search
@@ -178,6 +179,7 @@ SearchPreferencePage_limit_label=&Limit table size for file search results to:
SearchPreferencePage_limit_error=Table size must be an integer greater than 0
SearchPreferencePage_bringToFront= &Bring Search view to front after search
SearchPreferencePage_defaultPerspective= Default &perspective for the Search view:
+SearchPreferencePage_textSearchEngine=Text Search Engine to be used:
SearchPreferencePage_defaultPerspective_none= None
SearchPreferencePage_ignorePotentialMatches= &Ignore potential matches
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPlugin.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPlugin.java
index eacd17035ec..9499dcf5c40 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPlugin.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPlugin.java
@@ -43,6 +43,7 @@ import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.search.ui.IContextMenuConstants;
import org.eclipse.search.ui.NewSearchUI;
+import org.eclipse.search.internal.core.text.TextSearchEngineRegistry;
import org.eclipse.search.internal.ui.util.ExceptionHandler;
import org.eclipse.search2.internal.ui.InternalSearchUI;
@@ -68,15 +69,18 @@ public class SearchPlugin extends AbstractUIPlugin {
public static final int INTERNAL_ERROR= 1;
private static SearchPlugin fgSearchPlugin;
+
private List fPageDescriptors;
private List fSorterDescriptors;
+ private TextSearchEngineRegistry fTextSearchEngineRegistry;
public SearchPlugin() {
super();
Assert.isTrue(fgSearchPlugin == null);
fgSearchPlugin= this;
+ fTextSearchEngineRegistry= null;
}
/**
@@ -287,7 +291,15 @@ public class SearchPlugin extends AbstractUIPlugin {
fSorterDescriptors= createSorterDescriptors(elements);
}
return fSorterDescriptors;
- }
+ }
+
+
+ public TextSearchEngineRegistry getTextSearchEngineRegistry() {
+ if (fTextSearchEngineRegistry == null) {
+ fTextSearchEngineRegistry= new TextSearchEngineRegistry();
+ }
+ return fTextSearchEngineRegistry;
+ }
/**
* Creates all necessary sorter description nodes.
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPluginImages.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPluginImages.java
index 69aafd6d6a2..3f19118fae6 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPluginImages.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPluginImages.java
@@ -61,15 +61,17 @@ public class SearchPluginImages {
public static final String IMG_LCL_SEARCH_CANCEL= NAME_PREFIX + "stop.gif"; //$NON-NLS-1$
public static final String IMG_LCL_SEARCH_COLLAPSE_ALL= NAME_PREFIX + "collapseall.gif"; //$NON-NLS-1$
public static final String IMG_LCL_SEARCH_EXPAND_ALL= NAME_PREFIX + "expandall.gif"; //$NON-NLS-1$
-
+ public static final String IMG_LCL_SEARCH_FILTER= NAME_PREFIX + "filter_ps.gif"; //$NON-NLS-1$
public static final String IMG_VIEW_SEARCHRES= NAME_PREFIX + "searchres.gif"; //$NON-NLS-1$
public static final String IMG_OBJ_TSEARCH_DPDN= NAME_PREFIX + "tsearch_dpdn_obj.gif"; //$NON-NLS-1$
public static final String IMG_OBJ_SEARCHMARKER= NAME_PREFIX + "searchm_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJ_TEXT_SEARCH_LINE= NAME_PREFIX + "line_match.gif"; //$NON-NLS-1$
// Define images
public static final ImageDescriptor DESC_OBJ_TSEARCH_DPDN= createManaged(T_OBJ, IMG_OBJ_TSEARCH_DPDN);
public static final ImageDescriptor DESC_OBJ_SEARCHMARKER= createManaged(T_OBJ, IMG_OBJ_SEARCHMARKER);
+ public static final ImageDescriptor DESC_OBJ_TEXT_SEARCH_LINE= createManaged(T_OBJ, IMG_OBJ_TEXT_SEARCH_LINE);
public static final ImageDescriptor DESC_VIEW_SEARCHRES= createManaged(T_EVIEW, IMG_VIEW_SEARCHRES);
public static Image get(String key) {
@@ -81,7 +83,7 @@ public class SearchPluginImages {
PLUGIN_REGISTRY.put(name, result);
return result;
}
-
+
/*
* Creates an image descriptor for the given prefix and name in the Search plugin bundle. The path can
* contain variables like $NL$.
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPreferencePage.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPreferencePage.java
index 432016ca6df..3e973cea09a 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPreferencePage.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchPreferencePage.java
@@ -20,6 +20,8 @@ import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.util.PropertyChangeEvent;
+
+import org.eclipse.search.internal.core.text.TextSearchEngineRegistry;
import org.eclipse.search.internal.ui.util.ComboFieldEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
@@ -52,6 +54,7 @@ public class SearchPreferencePage extends FieldEditorPreferencePage implements I
public static final String BRING_VIEW_TO_FRONT= "org.eclipse.search.bringToFront"; //$NON-NLS-1$
public static final String LIMIT_TABLE_TO= "org.eclipse.search.limitTableTo"; //$NON-NLS-1$
public static final String LIMIT_TABLE= "org.eclipse.search.limitTable"; //$NON-NLS-1$
+ public static final String TEXT_SEARCH_ENGINE = "org.eclipse.search.textSearchEngine"; //$NON-NLS-1$
private ColorFieldEditor fColorEditor;
private BooleanFieldEditor fEmphasizedCheckbox;
@@ -91,6 +94,7 @@ public class SearchPreferencePage extends FieldEditorPreferencePage implements I
store.setDefault(DEFAULT_PERSPECTIVE, NO_DEFAULT_PERSPECTIVE);
store.setDefault(LIMIT_TABLE_TO, 200);
store.setDefault(LIMIT_TABLE, false);
+ store.setDefault(TEXT_SEARCH_ENGINE, ""); //default search engine is empty string //$NON-NLS-1$
}
@@ -146,6 +150,18 @@ public class SearchPreferencePage extends FieldEditorPreferencePage implements I
perspectiveNamesAndIds,
getFieldEditorParent());
addField(comboEditor);
+
+ // in case we have a contributed engine, let the user choose.
+ TextSearchEngineRegistry reg= SearchPlugin.getDefault().getTextSearchEngineRegistry();
+ String[][] engineNamesAndIds= reg.getAvailableEngines();
+ if (engineNamesAndIds.length > 1) {
+ comboEditor= new ComboFieldEditor(
+ TEXT_SEARCH_ENGINE,
+ SearchMessages.SearchPreferencePage_textSearchEngine,
+ engineNamesAndIds,
+ getFieldEditorParent());
+ addField(comboEditor);
+ }
}
private void createTableLimit() {
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/EditorOpener.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/EditorOpener.java
index 216a9e8d254..b8e5e3b7fa9 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/EditorOpener.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/EditorOpener.java
@@ -11,9 +11,7 @@
package org.eclipse.search.internal.ui.text;
import org.eclipse.core.resources.IFile;
-import org.eclipse.search.internal.ui.SearchPlugin;
-import org.eclipse.search.ui.NewSearchUI;
-import org.eclipse.search.ui.text.Match;
+
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
@@ -25,23 +23,26 @@ import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.search.ui.NewSearchUI;
+
+import org.eclipse.search.internal.ui.SearchPlugin;
+
public class EditorOpener {
private IEditorPart fEditor;
- IEditorPart open(Match match, boolean activate) throws PartInitException {
+ public IEditorPart open(IFile file, boolean activate) throws PartInitException {
IWorkbenchPage wbPage= SearchPlugin.getActivePage();
if (NewSearchUI.reuseEditor())
- return showWithReuse(match, wbPage, activate);
- return showWithoutReuse(match, wbPage, activate);
+ return showWithReuse(file, wbPage, activate);
+ return showWithoutReuse(file, wbPage, activate);
}
- private IEditorPart showWithoutReuse(Match match, IWorkbenchPage wbPage, boolean activate) throws PartInitException {
- return IDE.openEditor(wbPage, (IFile) match.getElement(), activate);
+ private IEditorPart showWithoutReuse(IFile file, IWorkbenchPage wbPage, boolean activate) throws PartInitException {
+ return IDE.openEditor(wbPage, file, activate);
}
- private IEditorPart showWithReuse(Match match, IWorkbenchPage wbPage, boolean activate) throws PartInitException {
- IFile file= (IFile) match.getElement();
+ private IEditorPart showWithReuse(IFile file, IWorkbenchPage wbPage, boolean activate) throws PartInitException {
String editorID= getEditorID(file);
return showInEditor(wbPage, file, editorID, activate);
}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchPage.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchPage.java
index f0f5aef62cf..003a6483835 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchPage.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchPage.java
@@ -165,7 +165,7 @@ public class FileSearchPage extends AbstractTextSearchViewPage implements IAdapt
protected void showMatch(Match match, int offset, int length, boolean activate) throws PartInitException {
IFile file= (IFile) match.getElement();
- IEditorPart editor= fEditorOpener.open(match, activate);
+ IEditorPart editor= fEditorOpener.open(file, activate);
if (offset != 0 && length != 0) {
if (editor instanceof ITextEditor) {
ITextEditor textEditor= (ITextEditor) editor;
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchQuery.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchQuery.java
index 1123460410d..19a14044703 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchQuery.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchQuery.java
@@ -135,7 +135,7 @@ public class FileSearchQuery implements ISearchQuery {
if (searchString.trim().equals(String.valueOf('*'))) {
searchString= new String();
}
- return PatternConstructor.createPattern(searchString, isCaseSensitive(), isRegexSearch());
+ return PatternConstructor.createPattern(searchString, isRegexSearch(), true, isCaseSensitive(), false);
}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/NewTextSearchActionGroup.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/NewTextSearchActionGroup.java
index d3f9381dfe7..b50c7b14f5e 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/NewTextSearchActionGroup.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/NewTextSearchActionGroup.java
@@ -42,7 +42,7 @@ import org.eclipse.search.ui.IContextMenuConstants;
*
* @since 2.1
*/
-class NewTextSearchActionGroup extends ActionGroup {
+public class NewTextSearchActionGroup extends ActionGroup {
private ISelectionProvider fSelectionProvider;
private IWorkbenchPage fPage;
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceDialog2.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceDialog2.java
index 1a45f3310aa..bad36bc50fe 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceDialog2.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceDialog2.java
@@ -510,7 +510,7 @@ class ReplaceDialog2 extends ExtendedDialogWindow {
}
private Pattern createReplacePattern(FileSearchQuery query) {
- return PatternConstructor.createPattern(query.getSearchString(), query.isCaseSensitive(), true);
+ return PatternConstructor.createPattern(query.getSearchString(), true, true, query.isCaseSensitive(), false);
}
private String computeReplacementString(Pattern pattern, String originalText, String replacementText) {
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/SearchResultUpdater.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/SearchResultUpdater.java
index 669793adc7e..9eea60e8347 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/SearchResultUpdater.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/SearchResultUpdater.java
@@ -20,16 +20,18 @@ import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.search.internal.ui.SearchPlugin;
import org.eclipse.search.ui.IQueryListener;
import org.eclipse.search.ui.ISearchQuery;
import org.eclipse.search.ui.NewSearchUI;
+import org.eclipse.search.ui.text.AbstractTextSearchResult;
import org.eclipse.search.ui.text.Match;
+import org.eclipse.search.internal.ui.SearchPlugin;
+
public class SearchResultUpdater implements IResourceChangeListener, IQueryListener {
- FileSearchResult fResult;
+ private AbstractTextSearchResult fResult;
- public SearchResultUpdater(FileSearchResult result) {
+ public SearchResultUpdater(AbstractTextSearchResult result) {
fResult= result;
NewSearchUI.addQueryListener(this);
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
@@ -63,7 +65,7 @@ public class SearchResultUpdater implements IResourceChangeListener, IQueryListe
}
});
} catch (CoreException e) {
- SearchPlugin.getDefault().getLog().log(e.getStatus());
+ SearchPlugin.log(e);
}
}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchPage.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchPage.java
index 996e8b98e63..2b076688bd5 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchPage.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchPage.java
@@ -56,6 +56,7 @@ import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
@@ -70,6 +71,7 @@ import org.eclipse.search.ui.ISearchResultViewPart;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.search.internal.core.text.FileNamePatternSearchScope;
+import org.eclipse.search.internal.core.text.PatternConstructor;
import org.eclipse.search.internal.ui.ISearchHelpContextIds;
import org.eclipse.search.internal.ui.Messages;
import org.eclipse.search.internal.ui.ScopePart;
@@ -78,9 +80,17 @@ import org.eclipse.search.internal.ui.SearchPlugin;
import org.eclipse.search.internal.ui.util.FileTypeEditor;
import org.eclipse.search.internal.ui.util.SWTUtil;
+import org.eclipse.search2.internal.ui.text2.CurrentProjectScopeDescription;
+import org.eclipse.search2.internal.ui.text2.IScopeDescription;
+import org.eclipse.search2.internal.ui.text2.RetrieverQuery;
+import org.eclipse.search2.internal.ui.text2.WindowWorkingSetScopeDescription;
+import org.eclipse.search2.internal.ui.text2.WorkingSetScopeDescription;
+import org.eclipse.search2.internal.ui.text2.WorkspaceScopeDescription;
+
public class TextSearchPage extends DialogPage implements ISearchPage, IReplacePage {
- private static final int HISTORY_SIZE= 12;
+ private static final String TMP_WORKING_SET_NAME = "tmp_for_search";
+ private static final int HISTORY_SIZE= 12;
public static final String EXTENSION_POINT_ID= "org.eclipse.search.internal.ui.text.TextSearchPage"; //$NON-NLS-1$
// Dialog store id constants
@@ -99,7 +109,7 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
private boolean fSearchDerived;
private Combo fPattern;
- private Button fIgnoreCase;
+ private Button fIsCaseSensitiveCheckbox;
private Combo fExtensions;
private Button fIsRegExCheckbox;
private CLabel fStatusLabel;
@@ -109,18 +119,23 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
private FileTypeEditor fFileTypeEditor;
private ContentAssistHandler fReplaceContentAssistHandler;
+
+ // mstodo remove before release
+ private Button fUseNewTextUICheckbox;
+ private boolean fUseNewTextUI;
+ private static final String STORE_USE_NEW_TEXT_UI = "use-new-text-ui";
private static class SearchPatternData {
- public final boolean ignoreCase;
+ public final boolean isCaseSensitive;
public final boolean isRegExSearch;
public final String textPattern;
public final String[] fileNamePatterns;
public final int scope;
public final IWorkingSet[] workingSets;
- public SearchPatternData(String textPattern, boolean ignoreCase, boolean isRegExSearch, String[] fileNamePatterns, int scope, IWorkingSet[] workingSets) {
+ public SearchPatternData(String textPattern, boolean isCaseSensitive, boolean isRegExSearch, String[] fileNamePatterns, int scope, IWorkingSet[] workingSets) {
Assert.isNotNull(fileNamePatterns);
- this.ignoreCase= ignoreCase;
+ this.isCaseSensitive= isCaseSensitive;
this.isRegExSearch= isRegExSearch;
this.textPattern= textPattern;
this.fileNamePatterns= fileNamePatterns;
@@ -129,7 +144,7 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
}
public void store(IDialogSettings settings) {
- settings.put("ignoreCase", ignoreCase); //$NON-NLS-1$
+ settings.put("ignoreCase", !isCaseSensitive); //$NON-NLS-1$
settings.put("isRegExSearch", isRegExSearch); //$NON-NLS-1$
settings.put("textPattern", textPattern); //$NON-NLS-1$
settings.put("fileNamePatterns", fileNamePatterns); //$NON-NLS-1$
@@ -169,7 +184,7 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
boolean isRegExSearch= settings.getBoolean("isRegExSearch"); //$NON-NLS-1$
boolean ignoreCase= settings.getBoolean("ignoreCase"); //$NON-NLS-1$
- return new SearchPatternData(textPattern, ignoreCase, isRegExSearch, fileNamePatterns, scope, workingSets);
+ return new SearchPatternData(textPattern, !ignoreCase, isRegExSearch, fileNamePatterns, scope, workingSets);
} catch (NumberFormatException e) {
return null;
}
@@ -179,7 +194,12 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
//---- Action Handling ------------------------------------------------
public boolean performAction() {
- NewSearchUI.runQueryInBackground(getSearchQuery());
+ if (fUseNewTextUI) {
+ NewSearchUI.runQueryInBackground(getNewSearchQuery());
+ }
+ else {
+ NewSearchUI.runQueryInBackground(getSearchQuery());
+ }
return true;
}
@@ -246,6 +266,56 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
return new FileSearchQuery(scope, getSearchOptions(), patternData.textPattern);
}
+ private ISearchQuery getNewSearchQuery() {
+ // create query
+ RetrieverQuery query= new RetrieverQuery(getActivePage());
+
+ // extract data
+ SearchPatternData patternData= getPatternData();
+
+ // check if we have a string matcher pattern.
+ String pattern= patternData.textPattern;
+ boolean isRegex= patternData.isRegExSearch;
+ if (!isRegex) {
+ String literal= PatternConstructor.appendAsRegEx(false, pattern, new StringBuffer()).toString();
+ String strMatcher= PatternConstructor.appendAsRegEx(true, pattern, new StringBuffer()).toString();
+ if (!literal.equals(strMatcher)) {
+ isRegex= true;
+ pattern= strMatcher;
+ }
+ }
+
+ // Setup search scope
+ IScopeDescription scope= null;
+ switch (getContainer().getSelectedScope()) {
+ case ISearchPageContainer.SELECTION_SCOPE:
+ scope= getSelectedResourcesScopeDescription();
+ break;
+ case ISearchPageContainer.SELECTED_PROJECTS_SCOPE:
+ scope= getEnclosingProjectScopeDescription();
+ break;
+ case ISearchPageContainer.WORKING_SET_SCOPE:
+ scope= getWorkingSetScopeDescription();
+ break;
+ case ISearchPageContainer.WORKSPACE_SCOPE:
+ default:
+ scope= new WorkspaceScopeDescription();
+ break;
+ }
+
+ query.setSearchString(pattern);
+ query.setIsCaseSensitive(patternData.isCaseSensitive);
+ query.setIsRegularExpression(isRegex);
+
+ query.setFilePatterns(patternData.fileNamePatterns);
+ query.setSearchScope(scope, fSearchDerived);
+ return query;
+ }
+
+ private IWorkbenchPage getActivePage() {
+ return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ }
+
private String getPattern() {
return fPattern.getText();
}
@@ -272,7 +342,7 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
}
match= new SearchPatternData(
getPattern(),
- ignoreCase(),
+ isCaseSensitive(),
fIsRegExCheckbox.getSelection(),
getExtensions(),
getContainer().getSelectedScope(),
@@ -303,7 +373,7 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
private String getSearchOptions() {
StringBuffer result= new StringBuffer();
- if (!ignoreCase())
+ if (!isCaseSensitive())
result.append('i');
if (fIsRegExSearch)
@@ -316,8 +386,8 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
return fFileTypeEditor.getFileTypes();
}
- private boolean ignoreCase() {
- return fIgnoreCase.getSelection();
+ private boolean isCaseSensitive() {
+ return fIsCaseSensitiveCheckbox.getSelection();
}
/*
@@ -424,16 +494,16 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
data.widthHint= convertWidthInCharsToPixels(50);
fPattern.setLayoutData(data);
- fIgnoreCase= new Button(group, SWT.CHECK);
- fIgnoreCase.setText(SearchMessages.SearchPage_caseSensitive);
- fIgnoreCase.setSelection(!fIsCaseSensitive);
- fIgnoreCase.addSelectionListener(new SelectionAdapter() {
+ fIsCaseSensitiveCheckbox= new Button(group, SWT.CHECK);
+ fIsCaseSensitiveCheckbox.setText(SearchMessages.SearchPage_caseSensitive);
+ fIsCaseSensitiveCheckbox.setSelection(!fIsCaseSensitive);
+ fIsCaseSensitiveCheckbox.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
- fIsCaseSensitive= !fIgnoreCase.getSelection();
+ fIsCaseSensitive= fIsCaseSensitiveCheckbox.getSelection();
}
});
- fIgnoreCase.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
- fIgnoreCase.setFont(group.getFont());
+ fIsCaseSensitiveCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ fIsCaseSensitiveCheckbox.setFont(group.getFont());
// Text line which explains the special characters
fStatusLabel= new CLabel(group, SWT.LEAD);
@@ -468,7 +538,7 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
SearchPatternData patternData= (SearchPatternData) fPreviousSearchPatterns.get(selectionIndex);
if (!fPattern.getText().equals(patternData.textPattern))
return;
- fIgnoreCase.setSelection(patternData.ignoreCase);
+ fIsCaseSensitiveCheckbox.setSelection(patternData.isCaseSensitive);
fIsRegExCheckbox.setSelection(patternData.isRegExSearch);
fPattern.setText(patternData.textPattern);
fFileTypeEditor.setFileTypes(patternData.fileNamePatterns);
@@ -583,6 +653,18 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
});
fSearchDerivedCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1));
fSearchDerivedCheckbox.setFont(group.getFont());
+
+ fUseNewTextUICheckbox= new Button(group, SWT.CHECK);
+ fUseNewTextUICheckbox.setText("Work in progress: show search results in new Text Search UI");
+ fUseNewTextUICheckbox.setSelection(fUseNewTextUI);
+ fUseNewTextUICheckbox.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ fUseNewTextUI= fUseNewTextUICheckbox.getSelection();
+ writeConfiguration();
+ }
+ });
+ fUseNewTextUICheckbox.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+ fUseNewTextUICheckbox.setFont(group.getFont());
}
/**
@@ -624,6 +706,52 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
return FileNamePatternSearchScope.newSearchScope(name, res, fSearchDerived);
}
+ private IScopeDescription getEnclosingProjectScopeDescription() {
+ String[] enclosingProjectName= getContainer().getSelectedProjectNames();
+ if (enclosingProjectName == null) {
+ return new WorkspaceScopeDescription();
+ }
+
+ IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
+ IResource[] res= new IResource[enclosingProjectName.length];
+ for (int i= 0; i < res.length; i++) {
+ res[i]= root.getProject(enclosingProjectName[i]);
+ }
+ if (res.length == 0) {
+ return new CurrentProjectScopeDescription();
+ }
+ return getScopeDescription(res);
+ }
+
+ private IScopeDescription getScopeDescription(IResource[] res) {
+ if (res.length == 1) {
+ if (res[0].equals(CurrentProjectScopeDescription.getCurrentProject(getActivePage()))) {
+ return new CurrentProjectScopeDescription();
+ }
+ }
+ return new WorkingSetScopeDescription(createWorkingSet(res));
+ }
+
+ private IScopeDescription getWorkingSetScopeDescription() {
+ IWorkingSet[] wss= getContainer().getSelectedWorkingSets();
+ if (wss.length == 0) {
+ return new WorkspaceScopeDescription();
+ }
+ if (wss.length == 1) {
+ if (wss[0].equals(getActivePage().getAggregateWorkingSet())) {
+ return new WindowWorkingSetScopeDescription();
+ }
+ return new WorkingSetScopeDescription(wss[0]);
+ }
+ IWorkingSetManager wm= PlatformUI.getWorkbench().getWorkingSetManager();
+ StringBuffer id = new StringBuffer();
+ id.append("Aggregate:"); //$NON-NLS-1$
+ for (int i = 0; i < wss.length; i++) {
+ id.append(wss[i].getName()).append(':');
+ }
+ return new WorkingSetScopeDescription(wm.createAggregateWorkingSet(
+ id.toString(), "Multiple Working Sets", wss)); //$NON-NLS-1$
+ }
private FileNamePatternSearchScope getSelectedResourcesScope() {
HashSet resources= new HashSet();
@@ -656,9 +784,54 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
return FileNamePatternSearchScope.newSearchScope(SearchMessages.SelectionScope, arr, fSearchDerived);
}
+ private IScopeDescription getSelectedResourcesScopeDescription() {
+ HashSet resources= new HashSet();
+ ISelection selection= getSelection();
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ Iterator iter= ((IStructuredSelection) selection).iterator();
+ while (iter.hasNext()) {
+ Object curr= iter.next();
+ if (curr instanceof IWorkingSet) {
+ IWorkingSet workingSet= (IWorkingSet) curr;
+ if (workingSet.isAggregateWorkingSet() && workingSet.isEmpty()) {
+ return new WorkspaceScopeDescription();
+ }
+ IAdaptable[] elements= workingSet.getElements();
+ for (int i= 0; i < elements.length; i++) {
+ IResource resource= (IResource)elements[i].getAdapter(IResource.class);
+ if (resource != null && resource.isAccessible()) {
+ resources.add(resource);
+ }
+ }
+ } else if (curr instanceof IAdaptable) {
+ IResource resource= (IResource) ((IAdaptable)curr).getAdapter(IResource.class);
+ if (resource != null && resource.isAccessible()) {
+ resources.add(resource);
+ }
+ }
+ }
+ }
+ return getScopeDescription((IResource[]) resources.toArray(new IResource[resources.size()]));
+ }
+
+ private IWorkingSet createWorkingSet(IResource[] arr) {
+ IWorkingSetManager wsm= PlatformUI.getWorkbench().getWorkingSetManager();
+ IWorkingSet ws= wsm.getWorkingSet(TMP_WORKING_SET_NAME);
+ if (ws == null) {
+ ws= wsm.createWorkingSet(TMP_WORKING_SET_NAME, arr);
+ ws.setId("org.eclipse.ui.resourceWorkingSetPage"); //$NON-NLS-1$
+ wsm.addWorkingSet(ws);
+ }
+ else {
+ ws.setElements(arr);
+ }
+ return ws;
+ }
+
+
//--------------- Configuration handling --------------
- /* (non-Javadoc)
+ /* (non-Javadoc)
* @see org.eclipse.jface.dialogs.DialogPage#dispose()
*/
public void dispose() {
@@ -684,6 +857,7 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
fIsCaseSensitive= s.getBoolean(STORE_CASE_SENSITIVE);
fIsRegExSearch= s.getBoolean(STORE_IS_REG_EX_SEARCH);
fSearchDerived= s.getBoolean(STORE_SEARCH_DERIVED);
+ fUseNewTextUI= s.getBoolean(STORE_USE_NEW_TEXT_UI);
try {
int historySize= s.getInt(STORE_HISTORY_SIZE);
@@ -709,6 +883,7 @@ public class TextSearchPage extends DialogPage implements ISearchPage, IReplaceP
s.put(STORE_CASE_SENSITIVE, fIsCaseSensitive);
s.put(STORE_IS_REG_EX_SEARCH, fIsRegExSearch);
s.put(STORE_SEARCH_DERIVED, fSearchDerived);
+ s.put(STORE_USE_NEW_TEXT_UI, fUseNewTextUI);
int historySize= Math.min(fPreviousSearchPatterns.size(), HISTORY_SIZE);
s.put(STORE_HISTORY_SIZE, historySize);
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/util/ComboFieldEditor.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/util/ComboFieldEditor.java
index 6353789b13c..e5d1e03ddd2 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/util/ComboFieldEditor.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/util/ComboFieldEditor.java
@@ -79,7 +79,8 @@ public class ComboFieldEditor extends FieldEditor {
protected void adjustForNumColumns(int numColumns) {
Control control= getLabelControl();
if (control != null) {
- ((GridData)control.getLayoutData()).horizontalSpan= numColumns;
+ ((GridData)control.getLayoutData()).horizontalSpan= numColumns-1;
+ numColumns=1;
}
((GridData)fCombo.getLayoutData()).horizontalSpan= numColumns;
}

Back to the top