summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/analysis-api/src/com/intellij/codeInspection/ex/ScopeToolState.java9
-rw-r--r--platform/analysis-api/src/com/intellij/codeInspection/reference/RefManager.java1
-rw-r--r--platform/analysis-api/src/com/intellij/codeInspection/ui/OptionAccessor.java10
-rw-r--r--platform/analysis-api/src/com/intellij/problems/WolfTheProblemSolver.java1
-rw-r--r--platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java8
-rw-r--r--platform/analysis-api/src/com/intellij/util/ui/CheckBox.java40
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java50
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java52
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java5
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/ui/ConventionOptionsPanel.java54
-rw-r--r--platform/core-api/src/com/intellij/ide/caches/FileContent.java2
-rw-r--r--platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java8
-rw-r--r--platform/core-api/src/com/intellij/lexer/DelegateLexer.java2
-rw-r--r--platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java16
-rw-r--r--platform/core-api/src/com/intellij/openapi/roots/FileIndexFacade.java1
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/JarFile.java2
-rw-r--r--platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java14
-rw-r--r--platform/core-api/src/com/intellij/psi/PsiInvalidElementAccessException.java2
-rw-r--r--platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java6
-rw-r--r--platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java79
-rw-r--r--platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java73
-rw-r--r--platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java58
-rw-r--r--platform/core-impl/src/com/intellij/mock/MockFileIndexFacade.java5
-rw-r--r--platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java59
-rw-r--r--platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java2
-rw-r--r--platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java17
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java2
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java8
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java9
-rw-r--r--platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java3
-rw-r--r--platform/core-impl/src/com/intellij/psi/text/BlockSupport.java2
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/repo/Repository.java3
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/repo/RepositoryImpl.java3
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/repo/RepositoryUtil.java10
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/ui/VcsLogAction.java85
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/ui/VcsLogOneCommitPerRepoAction.java69
-rw-r--r--platform/dvcs/src/com/intellij/dvcs/ui/VcsLogSingleCommitAction.java46
-rw-r--r--platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java1
-rw-r--r--platform/editor-ui-ex/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java (renamed from platform/lang-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java)36
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java12
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalFilter.java62
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalPlugin.java (renamed from platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SteppingConfigurable.java)33
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalProject.java243
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalSourceDirectorySet.java124
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalSourceSet.java66
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalTask.java86
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalFilter.java34
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalPlugin.java30
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalProject.java87
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalSourceDirectorySet.java (renamed from platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatePsiInfoBase.java)35
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalSourceSet.java39
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalTask.java36
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalSystemSourceType.java74
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/IExternalSystemSourceType.java32
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java5
-rw-r--r--platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java1
-rw-r--r--platform/external-system-impl/external-system-impl.iml1
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/ProjectStructureServices.java42
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java19
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java1
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataManager.java21
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java5
-rw-r--r--platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java140
-rw-r--r--platform/icons/src/actions/GroupByFile.pngbin0 -> 266 bytes
-rw-r--r--platform/icons/src/actions/GroupByFile@2x.pngbin0 -> 599 bytes
-rw-r--r--platform/icons/src/actions/GroupByFile@2x_dark.pngbin0 -> 599 bytes
-rw-r--r--platform/icons/src/actions/GroupByFile_dark.pngbin0 -> 266 bytes
-rw-r--r--platform/icons/src/general/projectConfigurableBanner.pngbin0 -> 119 bytes
-rw-r--r--platform/icons/src/general/projectConfigurableBanner@2x.pngbin0 -> 1019 bytes
-rw-r--r--platform/icons/src/general/projectConfigurableSelected.pngbin0 -> 122 bytes
-rw-r--r--platform/icons/src/general/projectConfigurableSelected@2x.pngbin0 -> 1098 bytes
-rw-r--r--platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java6
-rw-r--r--platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java4
-rw-r--r--platform/indexing-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java8
-rw-r--r--platform/lang-api/src/com/intellij/codeInsight/completion/CompletionInitializationContext.java22
-rw-r--r--platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java7
-rw-r--r--platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java36
-rw-r--r--platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java9
-rw-r--r--platform/lang-api/src/com/intellij/find/FindManager.java12
-rw-r--r--platform/lang-api/src/com/intellij/find/FindModel.java107
-rw-r--r--platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java10
-rw-r--r--platform/lang-api/src/com/intellij/lexer/LexerUtil.java10
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java22
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java1
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java3
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/codeStyle/RightMarginForm.form44
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/codeStyle/RightMarginForm.java120
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRulesControl.java36
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.form35
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java26
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java11
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java47
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WolfHighlightingPass.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java22
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/CopyHandler.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/IndentingBackspaceHandler.java90
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java9
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java45
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java256
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/problems/MockWolfTheProblemSolver.java5
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java6
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java7
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ChooserExpressionSelector.java (renamed from platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ExpressionPostfixTemplateWithChooser.java)66
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/NotPostfixTemplate.java22
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedPostfixTemplate.java19
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateExpressionSelector.java54
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatePsiInfo.java35
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateWithExpressionSelector.java83
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatesUtils.java18
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementWrapPostfixTemplate.java6
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StringBasedPostfixTemplate.java8
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/SurroundPostfixTemplateBase.java12
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/TopmostExpressionSelector.java58
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/TypedPostfixTemplate.java42
-rw-r--r--platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java2
-rw-r--r--platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java2
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java63
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/DuplexConsoleView.java47
-rw-r--r--platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java6
-rw-r--r--platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java10
-rw-r--r--platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java76
-rw-r--r--platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java9
-rw-r--r--platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java6
-rw-r--r--platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java11
-rw-r--r--platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java6
-rw-r--r--platform/lang-impl/src/com/intellij/find/FindSettings.java9
-rw-r--r--platform/lang-impl/src/com/intellij/find/FindUtil.java4
-rw-r--r--platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptCommentsAction.java38
-rw-r--r--platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptCommentsAndLiteralsAction.java38
-rw-r--r--platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptLiteralsAction.java38
-rw-r--r--platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleInCommentsAction.java4
-rw-r--r--platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleInLiteralsOnlyAction.java4
-rw-r--r--platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java11
-rw-r--r--platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java11
-rw-r--r--platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java5
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindDialog.java91
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java58
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java11
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java204
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java10
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java47
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/RegExHelpPopup.java39
-rw-r--r--platform/lang-impl/src/com/intellij/formatting/FormatterEx.java11
-rw-r--r--platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java53
-rw-r--r--platform/lang-impl/src/com/intellij/framework/detection/impl/exclude/DetectionExcludesConfigurable.java33
-rw-r--r--platform/lang-impl/src/com/intellij/framework/detection/impl/exclude/InvalidExcludeListItem.java4
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedFileAction.java14
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java279
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java5
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java5
-rw-r--r--platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java10
-rw-r--r--platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java23
-rw-r--r--platform/lang-impl/src/com/intellij/ide/todo/ChangeListTodosPanel.java7
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java25
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java144
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java2
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java1
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionItemProvider.java7
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java27
-rw-r--r--platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java8
-rw-r--r--platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java22
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java7
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectNextOccurrenceAction.java9
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectOccurrencesActionHandler.java21
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectPreviousOccurrenceAction.java10
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/richcopy/FontMapper.java8
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/editor/richcopy/TextWithMarkupProcessor.java14
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java150
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java6
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/DetectedRootsChooserDialog.java41
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/SuggestedChildRootInfo.java7
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java41
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java21
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/AddScopeUtil.java117
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/AdvancedSettingsAction.java209
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java4
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooserAction.java6
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/MultiScopeSeverityIcon.java58
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopeOrderComparator.java62
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesChooser.java60
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesOrderDialog.java121
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java109
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/filter/InspectionFilterAction.java18
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/filter/InspectionsFilter.java19
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java70
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/MultiScopeSeverityIcon.java19
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/ScopesAndSeveritiesHintTable.java32
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java94
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityRenderer.java31
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityState.java40
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java22
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java4
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java71
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/KeyboardComboSwitcher.java2
-rw-r--r--platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java1
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/ContentHashesSupport.java2
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/DebugAssertions.java2
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java51
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java2
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java6
-rw-r--r--platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java18
-rw-r--r--platform/lang-impl/src/com/intellij/webcore/packaging/PackagesNotificationPanel.java58
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/beforeBrace-after.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/beforeBrace.java5
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/spacingInsert-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/spacingInsert.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart.java4
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart2-after.java3
-rw-r--r--platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart2.java4
-rw-r--r--platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerUncommittedDocumentTest.java52
-rw-r--r--platform/lvcs-impl/src/com/intellij/history/core/Paths.java15
-rw-r--r--platform/platform-api/src/com/intellij/ide/BrowserUtil.java8
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/BrowserFamily.java6
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java36
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/BrowserSpecificSettings.java6
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/chrome/ChromeSettings.java25
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/firefox/FirefoxSettingsConfigurable.java16
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java4
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java11
-rw-r--r--platform/platform-api/src/com/intellij/openapi/diff/DiffRequestFactory.java9
-rw-r--r--platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java14
-rw-r--r--platform/platform-api/src/com/intellij/openapi/diff/MergeRequest.java2
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/EditorCopyPasteHelper.java53
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java97
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java263
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/actionSystem/DialogAwareDataContext.java54
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java8
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java46
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java27
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java2
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java15
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/Banner.java20
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java7
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java17
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/FixedComboBoxEditor.java16
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java14
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/NamedConfigurable.java9
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java233
-rw-r--r--platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java2
-rw-r--r--platform/platform-api/src/com/intellij/ui/AnActionButton.java19
-rw-r--r--platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java35
-rw-r--r--platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java266
-rw-r--r--platform/platform-api/src/com/intellij/ui/CheckboxTreeHelper.java (renamed from platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/CheckboxTreeTable.java)223
-rw-r--r--platform/platform-api/src/com/intellij/ui/CheckboxTreeListener.java31
-rw-r--r--platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java5
-rw-r--r--platform/platform-api/src/com/intellij/ui/JBSplitter.java8
-rw-r--r--platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java59
-rw-r--r--platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java11
-rw-r--r--platform/platform-api/src/com/intellij/ui/table/BaseTableView.java8
-rw-r--r--platform/platform-api/src/com/intellij/ui/table/JBTable.java8
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java9
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java2
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java12
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java22
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java13
-rw-r--r--platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java4
-rw-r--r--platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java33
-rw-r--r--platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java4
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java6
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/FormBuilder.java5
-rw-r--r--platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java2
-rw-r--r--platform/platform-impl/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java (renamed from platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java)0
-rw-r--r--platform/platform-impl/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java (renamed from platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java)0
-rw-r--r--platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java4
-rw-r--r--platform/platform-impl/src/com/intellij/help/impl/MacHelpUtil.java2
-rw-r--r--platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java20
-rw-r--r--platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java22
-rw-r--r--platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java6
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java14
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java40
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java14
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java9
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/SplitterActionBase.java25
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/Switcher.java2
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/TabsAlphabeticalModeSwitcher.java5
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/UnsplitAllAction.java6
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java11
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java62
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java37
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java21
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java28
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java13
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java23
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java2
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java2
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java2
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties7
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxMenuItemUI.java81
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaMenuItemUIBase.java208
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonMenuItemUI.java85
-rw-r--r--platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java611
-rw-r--r--platform/platform-impl/src/com/intellij/ide/util/MultiStateElementsChooser.java692
-rw-r--r--platform/platform-impl/src/com/intellij/internal/statistic/ideSettings/IdeSettingsStatisticsUtils.java29
-rw-r--r--platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java20
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java10
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java10
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/actions/CompareClipboardWithSelection.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java15
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java36
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSplitter.java7
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java61
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/DiffRequestFactoryImpl.java31
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java58
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/CaretStateTransferableData.java (renamed from platform/platform-api/src/com/intellij/openapi/editor/CaretStateTransferableData.java)0
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java (renamed from platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java)0
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretAbove.java23
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretActionHandler.java113
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretBelow.java27
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java76
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorCopyPasteHelperImpl.java (renamed from platform/platform-api/src/com/intellij/openapi/editor/CopyPasteSupport.java)114
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java11
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHighlighterCache.java33
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java132
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java67
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/LazyRangeMarkerFactoryImpl.java323
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/TrailingSpacesStripper.java (renamed from platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java)19
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java19
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java1
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java8
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java27
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java18
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java46
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java15
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/SimpleConfigurable.java52
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/TabbedConfigurable.java1
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java62
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java17
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java18
-rwxr-xr-xplatform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java19
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpFileSystemBase.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpVirtualFileImpl.java (renamed from platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java)9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileManagerImpl.java22
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java20
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java16
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java18
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java408
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java36
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java13
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java9
-rw-r--r--platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java21
-rw-r--r--platform/platform-impl/src/com/intellij/remote/VagrantSupport.java5
-rw-r--r--platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java1
-rw-r--r--platform/platform-impl/src/com/intellij/ui/AppUIUtil.java6
-rw-r--r--platform/platform-impl/src/com/intellij/ui/BalloonImpl.java5
-rw-r--r--platform/platform-impl/src/com/intellij/ui/CheckboxTree.java9
-rw-r--r--platform/platform-impl/src/com/intellij/ui/CheckboxTreeTable.java47
-rw-r--r--platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java45
-rw-r--r--platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java7
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java68
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java35
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java9
-rw-r--r--platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java92
-rw-r--r--platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java2
-rw-r--r--platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java2
-rw-r--r--platform/platform-resources-en/src/messages/ActionsBundle.properties6
-rw-r--r--platform/platform-resources-en/src/messages/ApplicationBundle.properties1
-rw-r--r--platform/platform-resources-en/src/messages/CommonBundle.properties1
-rw-r--r--platform/platform-resources-en/src/messages/DiffBundle.properties2
-rw-r--r--platform/platform-resources-en/src/messages/FindBundle.properties9
-rw-r--r--platform/platform-resources-en/src/messages/VcsBundle.properties2
-rw-r--r--platform/platform-resources-en/src/messages/XDebuggerBundle.properties2
-rw-r--r--platform/platform-resources-en/src/messages/XmlBundle.properties3
-rw-r--r--platform/platform-resources/src/META-INF/PlatformExtensions.xml6
-rw-r--r--platform/platform-resources/src/META-INF/XmlPlugin.xml17
-rw-r--r--platform/platform-resources/src/META-INF/xdebugger.xml4
-rw-r--r--platform/platform-resources/src/brokenPlugins.txt11
-rw-r--r--platform/platform-resources/src/idea/Keymap_Default.xml3
-rw-r--r--platform/platform-resources/src/idea/Keymap_EclipseMac.xml4
-rw-r--r--platform/platform-resources/src/idea/PlatformActions.xml1
-rw-r--r--platform/platform-resources/src/idea/VcsActions.xml2
-rw-r--r--platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java24
-rw-r--r--platform/platform-tests/testSrc/com/intellij/history/core/PathsTest.java5
-rw-r--r--platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java211
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorCloneCaretAboveBelowTest.java106
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/AbstractEditorTest.java15
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java24
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/RangeMarkerTest.java44
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/StripTrailingSpacesTest.java (renamed from platform/platform-tests/testSrc/com/intellij/openapi/editor/StripTrailingSpacesTest.java)4
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/NonProjectFileAccessTest.java2
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java40
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java10
-rw-r--r--platform/projectModel-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java12
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/OrderEnumerationHandler.java9
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java17
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexExcludePolicy.java4
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java17
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java149
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java4
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/NonProjectDirectoryInfo.java24
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEnumeratorBase.java32
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderRootsEnumeratorImpl.java1
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexFacade.java5
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java7
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java5
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java117
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java11
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java6
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java21
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java24
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java58
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudRunConfigurationUtil.java93
-rwxr-xr-xplatform/script-debugger/backend/src/org/jetbrains/debugger/Breakpoint.java5
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/DebugEventAdapter.java2
-rwxr-xr-xplatform/script-debugger/backend/src/org/jetbrains/debugger/DebugEventListener.java2
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/VmBase.java1
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java4
-rw-r--r--platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LazyVariablesGroup.java33
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/BoxableType.java1
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ClassScope.java4
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/DomainGenerator.java21
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/Generator.java83
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/InputClassScope.java63
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/MemberScope.java2
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/MyCreateStandaloneTypeBindingVisitorBase.java4
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/OutputClassScope.java19
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ParserRootInterfaceItem.java2
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ResolveAndGenerateScope.java2
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/TypeData.java47
-rw-r--r--platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/TypeDescriptor.java (renamed from platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/QualifiedTypeData.java)25
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonField.java (renamed from platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonField.java)3
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonNullable.java (renamed from platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonNullable.java)2
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonOptionalField.java (renamed from platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonOptionalField.java)2
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonParseMethod.java (renamed from platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonParseMethod.java)2
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonReaders.java2
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonSubtype.java (renamed from platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonSubtype.java)2
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonSubtypeCasting.java (renamed from platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonSubtypeCasting.java)2
-rw-r--r--platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonType.java (renamed from platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonType.java)2
-rw-r--r--platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java5
-rw-r--r--platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java6
-rw-r--r--platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java2
-rw-r--r--platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TextOutput.java10
-rw-r--r--platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ValueReader.java6
-rw-r--r--platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ItemDescriptor.java2
-rw-r--r--platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ProtocolMetaModel.java4
-rw-r--r--platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ProtocolSchemaReader.java1
-rw-r--r--platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java6
-rw-r--r--platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/SuiteInProgressState.java3
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/CompiledPattern.java2
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/PatternCompiler.java8
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java27
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SubstitutionShortInfoHandler.java13
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java43
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java13
-rw-r--r--platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java29
-rw-r--r--platform/testFramework/src/com/intellij/FileSetTestCase.java7
-rw-r--r--platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java9
-rw-r--r--platform/testFramework/src/com/intellij/TestCaseLoader.java36
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java2
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java27
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java4
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java8
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java2
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/fixtures/HeavyIdeaTestFixture.java5
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java56
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java2
-rw-r--r--platform/testFramework/src/com/intellij/util/io/TestFileSystemBuilder.java8
-rw-r--r--platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java3
-rw-r--r--platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java5
-rw-r--r--platform/usageView/src/com/intellij/usages/ChunkExtractor.java84
-rw-r--r--platform/usageView/src/com/intellij/usages/FindUsagesProcessPresentation.java11
-rw-r--r--platform/usageView/src/com/intellij/usages/TextChunk.java12
-rw-r--r--platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java51
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java64
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java108
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java42
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/rules/UsageTypeGroupingRule.java9
-rw-r--r--platform/usageView/usageView.iml1
-rw-r--r--platform/util/resources/misc/registry.properties (renamed from platform/platform-resources-en/src/misc/registry.properties)17
-rw-r--r--platform/util/src/com/intellij/icons/AllIcons.java3
-rw-r--r--platform/util/src/com/intellij/openapi/ui/Divider.java34
-rw-r--r--platform/util/src/com/intellij/openapi/ui/Splitter.java10
-rw-r--r--platform/util/src/com/intellij/openapi/util/io/FileUtil.java9
-rw-r--r--platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java2
-rw-r--r--platform/util/src/com/intellij/openapi/util/text/StringUtil.java73
-rw-r--r--platform/util/src/com/intellij/ui/JBColor.java120
-rw-r--r--platform/util/src/com/intellij/util/EventDispatcher.java8
-rw-r--r--platform/util/src/com/intellij/util/PatternUtil.java46
-rw-r--r--platform/util/src/com/intellij/util/ReflectionUtil.java20
-rw-r--r--platform/util/src/com/intellij/util/Restarter.java11
-rw-r--r--platform/util/src/com/intellij/util/containers/ContainerUtil.java1
-rw-r--r--platform/util/src/com/intellij/util/containers/LongStack.java75
-rw-r--r--platform/util/src/com/intellij/util/diff/DiffTree.java8
-rw-r--r--platform/util/src/com/intellij/util/io/LongInlineKeyDescriptor.java (renamed from platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurable.java)41
-rw-r--r--platform/util/src/com/intellij/util/text/StringSearcher.java3
-rw-r--r--platform/util/src/com/intellij/util/ui/UIUtil.java8
-rw-r--r--platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java13
-rw-r--r--platform/util/testSrc/com/intellij/util/text/StringUtilTest.java19
-rw-r--r--platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java16
-rw-r--r--platform/util/util.iml1
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java1
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManager.java1
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/changes/IgnoredFileBean.java16
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeModifier.java4
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java183
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerSerialization.java57
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedContent.java59
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java46
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LocalChangeListImpl.java19
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java58
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java19
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java11
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsGuess.java2
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ConflictedDiffRequestPresentable.java7
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java2
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java9
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/IgnoredSettingsPanel.java42
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java13
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusAction.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/history/BaseDiffFromHistoryHandler.java197
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultFileIndexFacade.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java16
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java28
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java11
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootErrorsFinder.java12
-rw-r--r--platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java8
-rw-r--r--platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/ConvertExcludedToIgnoredTest.java94
-rw-r--r--platform/vcs-impl/vcs-impl.iml1
-rw-r--r--platform/vcs-log/api/src/com/intellij/vcs/log/TimedVcsCommit.java10
-rw-r--r--platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java4
-rw-r--r--platform/vcs-log/api/src/com/intellij/vcs/log/VcsShortCommitDetails.java11
-rw-r--r--platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/GraphCommit.java6
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java13
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java26
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefreshNotEnoughDataException.java25
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java89
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/graph/GraphColorManagerImpl.java4
-rw-r--r--platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogJoinerTest.java141
-rw-r--r--platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogJoinerTest.kt468
-rw-r--r--platform/vcs-log/impl/test/com/intellij/vcs/log/impl/TestVcsLogProvider.java8
-rw-r--r--platform/vcs-log/impl/vcs-log-impl.iml1
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java2
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/settings/DebuggerConfigurableProvider.java42
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/settings/DebuggerSettingsCategory.java6
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java23
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java6
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java31
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java12
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ForceStepIntoAction.java3
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java4
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java8
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java13
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java9
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java4
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java35
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java6
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java173
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java86
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerSettingsPanelProvider.java23
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/MergedCompositeConfigurable.java78
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java20
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerConfigurableProvider.java74
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsPanelProviderImpl.java70
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java22
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java15
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java11
-rw-r--r--platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerSettingsTest.java8
577 files changed, 12512 insertions, 5968 deletions
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/ex/ScopeToolState.java b/platform/analysis-api/src/com/intellij/codeInspection/ex/ScopeToolState.java
index 3a75f1738ead..81e340679a50 100644
--- a/platform/analysis-api/src/com/intellij/codeInspection/ex/ScopeToolState.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/ex/ScopeToolState.java
@@ -42,6 +42,7 @@ public class ScopeToolState {
private boolean myEnabled;
private HighlightDisplayLevel myLevel;
+ private boolean myAdditionalConfigPanelCreated = false;
private JComponent myAdditionalConfigPanel;
private static final Logger LOG = Logger.getInstance("#" + ScopeToolState.class.getName());
@@ -98,13 +99,11 @@ public class ScopeToolState {
myLevel = level;
}
- @NotNull
+ @Nullable
public JComponent getAdditionalConfigPanel() {
- if (myAdditionalConfigPanel == null) {
+ if (!myAdditionalConfigPanelCreated) {
myAdditionalConfigPanel = myToolWrapper.getTool().createOptionsPanel();
- if (myAdditionalConfigPanel == null){
- myAdditionalConfigPanel = new JPanel();
- }
+ myAdditionalConfigPanelCreated = true;
}
return myAdditionalConfigPanel;
}
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/reference/RefManager.java b/platform/analysis-api/src/com/intellij/codeInspection/reference/RefManager.java
index 6f0a3c24e523..b46352670030 100644
--- a/platform/analysis-api/src/com/intellij/codeInspection/reference/RefManager.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/reference/RefManager.java
@@ -47,6 +47,7 @@ public abstract class RefManager {
*
* @return the analysis scope.
*/
+ @Nullable
public abstract AnalysisScope getScope();
/**
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/ui/OptionAccessor.java b/platform/analysis-api/src/com/intellij/codeInspection/ui/OptionAccessor.java
index 0c32f60dadd0..5e23b224920f 100644
--- a/platform/analysis-api/src/com/intellij/codeInspection/ui/OptionAccessor.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/ui/OptionAccessor.java
@@ -43,15 +43,7 @@ public interface OptionAccessor {
@Override
public void setOption(final String optionName, boolean optionValue) {
- try {
- ReflectionUtil.findField(myInspection.getClass(), boolean.class, optionName).setBoolean(myInspection, optionValue);
- }
- catch (IllegalAccessException e) {
- LOG.warn(e);
- }
- catch (NoSuchFieldException e) {
- LOG.warn(e);
- }
+ ReflectionUtil.setField(myInspection.getClass(), myInspection, boolean.class, optionName, optionValue);
}
}
}
diff --git a/platform/analysis-api/src/com/intellij/problems/WolfTheProblemSolver.java b/platform/analysis-api/src/com/intellij/problems/WolfTheProblemSolver.java
index c4580e082fb4..cc72d479daec 100644
--- a/platform/analysis-api/src/com/intellij/problems/WolfTheProblemSolver.java
+++ b/platform/analysis-api/src/com/intellij/problems/WolfTheProblemSolver.java
@@ -40,6 +40,7 @@ public abstract class WolfTheProblemSolver {
public abstract boolean isProblemFile(VirtualFile virtualFile);
public abstract void weHaveGotProblems(@NotNull VirtualFile virtualFile, @NotNull List<Problem> problems);
+ public abstract void weHaveGotNonIgnorableProblems(@NotNull VirtualFile virtualFile, @NotNull List<Problem> problems);
public abstract void clearProblems(@NotNull VirtualFile virtualFile);
public abstract boolean hasProblemFilesBeneath(@NotNull Condition<VirtualFile> condition);
diff --git a/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java b/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java
index 647cd728c6ac..76db4a7cc765 100644
--- a/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java
+++ b/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java
@@ -189,10 +189,10 @@ public class GlobalSearchScopesCore {
private final VirtualFile myDirectory;
private final boolean myWithSubdirectories;
- private DirectoryScope(@NotNull PsiDirectory directory, final boolean withSubdirectories) {
- super(directory.getProject());
+ private DirectoryScope(@NotNull PsiDirectory psiDirectory, final boolean withSubdirectories) {
+ super(psiDirectory.getProject());
myWithSubdirectories = withSubdirectories;
- myDirectory = directory.getVirtualFile();
+ myDirectory = psiDirectory.getVirtualFile();
}
private DirectoryScope(@NotNull Project project, @NotNull VirtualFile directory, final boolean withSubdirectories) {
@@ -221,6 +221,7 @@ public class GlobalSearchScopesCore {
return false;
}
+ @Override
public String toString() {
//noinspection HardCodedStringLiteral
return "directory scope: " + myDirectory + "; withSubdirs:"+myWithSubdirectories;
@@ -296,6 +297,7 @@ public class GlobalSearchScopesCore {
return false;
}
+ @Override
public String toString() {
//noinspection HardCodedStringLiteral
return "Directories scope: " + Arrays.asList(myDirectories);
diff --git a/platform/analysis-api/src/com/intellij/util/ui/CheckBox.java b/platform/analysis-api/src/com/intellij/util/ui/CheckBox.java
index d6e4101c6086..d00655a66768 100644
--- a/platform/analysis-api/src/com/intellij/util/ui/CheckBox.java
+++ b/platform/analysis-api/src/com/intellij/util/ui/CheckBox.java
@@ -16,14 +16,13 @@
package com.intellij.util.ui;
import com.intellij.codeInspection.InspectionProfileEntry;
+import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import javax.swing.ButtonModel;
-import javax.swing.JCheckBox;
+import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import java.lang.reflect.Field;
public class CheckBox extends JCheckBox {
@@ -39,30 +38,8 @@ public class CheckBox extends JCheckBox {
private static boolean getPropertyValue(InspectionProfileEntry owner,
String property) {
- try {
- final Class<? extends InspectionProfileEntry> aClass = owner.getClass();
- final Field field = getField(aClass, property);
- field.setAccessible(true);
- return field.getBoolean(owner);
- } catch (IllegalAccessException ignore) {
- return false;
- } catch (NoSuchFieldException ignore) {
- return false;
- }
- }
-
- static Field getField(Class clazz, String fieldName) throws NoSuchFieldException {
- try {
- return clazz.getDeclaredField(fieldName);
- } catch (NoSuchFieldException e) {
- final Class superClass = clazz.getSuperclass();
- if (superClass == null) {
- throw e;
- } else {
- return getField(superClass, fieldName);
- }
+ return ReflectionUtil.getField(owner.getClass(), owner, boolean.class, property);
}
- }
private static class SingleCheckboxChangeListener
implements ChangeListener {
@@ -85,16 +62,7 @@ public class CheckBox extends JCheckBox {
private static void setPropertyValue(InspectionProfileEntry owner,
String property,
boolean selected) {
- try {
- final Class<? extends InspectionProfileEntry> aClass = owner.getClass();
- final Field field = getField(aClass, property);
- field.setAccessible(true);
- field.setBoolean(owner, selected);
- } catch (IllegalAccessException ignore) {
- // do nothing
- } catch (NoSuchFieldException ignore) {
- // do nothing
- }
+ ReflectionUtil.setField(owner.getClass(), owner, boolean.class, property, selected);
}
}
} \ No newline at end of file
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java
index d8dc5d00656a..0a1861e8000e 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java
@@ -39,9 +39,13 @@ import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.SeverityProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.scope.packageSet.NamedScope;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.graph.CachingSemiGraph;
+import com.intellij.util.graph.DFSTBuilder;
+import com.intellij.util.graph.GraphGenerator;
import gnu.trove.THashMap;
import org.jdom.Document;
import org.jdom.Element;
@@ -85,7 +89,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
private final ExternalInfo myExternalInfo = new ExternalInfo();
@TestOnly
public static boolean INIT_INSPECTIONS = false;
- private List<NamedScope> myScopes = Collections.emptyList();
+ private String[] myScopesOrder = null;
@Override
public void setModified(final boolean modified) {
@@ -509,6 +513,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
catch (ProcessCanceledException e) {
return false;
}
+ final Map<String, List<String>> dependencies = new HashMap<String, List<String>>();
for (InspectionToolWrapper toolWrapper : tools) {
final String shortName = toolWrapper.getShortName();
HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
@@ -536,7 +541,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
final Element element = myDeinstalledInspectionsSettings.remove(toolWrapper.getShortName());
if (element != null) {
try {
- toolsList.readExternal(element, this);
+ toolsList.readExternal(element, this, dependencies);
}
catch (InvalidDataException e) {
LOG.error("Can't read settings for " + toolWrapper, e);
@@ -544,12 +549,39 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
}
myTools.put(toolWrapper.getShortName(), toolsList);
}
+ final GraphGenerator<String> graphGenerator = GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<String>() {
+ @Override
+ public Collection<String> getNodes() {
+ return dependencies.keySet();
+ }
+
+ @Override
+ public Iterator<String> getIn(String n) {
+ return dependencies.get(n).iterator();
+ }
+ }));
+
+ DFSTBuilder<String> builder = new DFSTBuilder<String>(graphGenerator);
+ if (builder.isAcyclic()) {
+ final List<String> scopes = builder.getSortedNodes();
+ myScopesOrder = ArrayUtil.toStringArray(scopes);
+ }
+
if (mySource != null) {
copyToolsConfigurations(mySource, project);
}
return true;
}
+ @Nullable
+ public String[] getScopesOrder() {
+ return myScopesOrder;
+ }
+
+ public void setScopesOrder(String[] scopesOrder) {
+ myScopesOrder = scopesOrder;
+ }
+
@NotNull
private List<InspectionToolWrapper> createTools(Project project) {
if (mySource != null) {
@@ -907,13 +939,13 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
return getTools(toolWrapper.getShortName(), project).prependTool(scope, toolWrapper, enabled, level);
}
- public void setErrorLevel(@NotNull HighlightDisplayKey key, @NotNull HighlightDisplayLevel level, int scopeIdx, Project project) {
- getTools(key.toString(), project).setLevel(level, scopeIdx, project);
+ public void setErrorLevel(@NotNull HighlightDisplayKey key, @NotNull HighlightDisplayLevel level, String scopeName, Project project) {
+ getTools(key.toString(), project).setLevel(level, scopeName, project);
}
- public void setErrorLevel(@NotNull List<HighlightDisplayKey> keys, @NotNull HighlightDisplayLevel level, int scopeIdx, Project project) {
+ public void setErrorLevel(@NotNull List<HighlightDisplayKey> keys, @NotNull HighlightDisplayLevel level, String scopeName, Project project) {
for (HighlightDisplayKey key : keys) {
- getTools(key.toString(), project).setLevel(level, scopeIdx, project);
+ setErrorLevel(key, level, scopeName, project);
}
}
@@ -944,10 +976,4 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
return super.equals(o) && ((InspectionProfileImpl)o).getProfileManager() == getProfileManager();
}
- /**
- * @return list of used scopes for all inspections
- */
- public List<NamedScope> getUsedScopes() {
- return myScopes;
- }
}
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
index b28dad40f094..267c0ee67fc3 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
@@ -46,6 +46,7 @@ import org.jetbrains.annotations.TestOnly;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
public class ToolsImpl implements Tools {
@NonNls private static final String ENABLED_BY_DEFAULT_ATTRIBUTE = "enabled_by_default";
@@ -170,7 +171,7 @@ public class ToolsImpl implements Tools {
}
}
- void readExternal(@NotNull Element toolElement, @NotNull InspectionProfile profile) throws InvalidDataException {
+ void readExternal(@NotNull Element toolElement, @NotNull InspectionProfile profile, Map<String, List<String>> dependencies) throws InvalidDataException {
final String levelName = toolElement.getAttributeValue(LEVEL_ATTRIBUTE);
final ProfileManager profileManager = profile.getProfileManager();
final SeverityRegistrar registrar = ((SeverityProvider)profileManager).getOwnSeverityRegistrar();
@@ -187,6 +188,7 @@ public class ToolsImpl implements Tools {
final InspectionToolWrapper toolWrapper = myDefaultState.getTool();
final List scopeElements = toolElement.getChildren(ProfileEx.SCOPE);
+ final List<String> scopeNames = new ArrayList<String>();
for (Object sO : scopeElements) {
final Element scopeElement = (Element)sO;
final String scopeName = scopeElement.getAttributeValue(ProfileEx.NAME);
@@ -216,6 +218,20 @@ public class ToolsImpl implements Tools {
else {
addTool(scopeName, copyToolWrapper, enabledInScope != null && Boolean.parseBoolean(enabledInScope), scopeLevel);
}
+
+ scopeNames.add(scopeName);
+ }
+
+ for (int i = 0; i < scopeNames.size(); i++) {
+ String scopeName = scopeNames.get(i);
+ List<String> order = dependencies.get(scopeName);
+ if (order == null) {
+ order = new ArrayList<String>();
+ dependencies.put(scopeName, order);
+ }
+ for (int j = i + 1; j < scopeNames.size(); j++) {
+ order.add(scopeNames.get(j));
+ }
}
// check if unknown children exists
@@ -445,22 +461,36 @@ public class ToolsImpl implements Tools {
}
- public void setLevel(@NotNull HighlightDisplayLevel level, int idx, Project project) {
- if (myTools != null && myTools.size() > idx && idx >= 0) {
- final ScopeToolState scopeToolState = myTools.get(idx);
- myTools.remove(idx);
+ public void setLevel(@NotNull HighlightDisplayLevel level, @Nullable String scopeName, Project project) {
+ if (scopeName == null) {
+ myDefaultState.setLevel(level);
+ } else {
+ if (myTools == null) {
+ return;
+ }
+ ScopeToolState scopeToolState = null;
+ int index = -1;
+ for (int i = 0; i < myTools.size(); i++) {
+ ScopeToolState tool = myTools.get(i);
+ if (scopeName.equals(tool.getScopeName())) {
+ scopeToolState = tool;
+ myTools.remove(tool);
+ index = i;
+ break;
+ }
+ }
+ if (index < 0) {
+ throw new IllegalStateException("Scope " + scopeName + " not found");
+ }
+ final InspectionToolWrapper toolWrapper = scopeToolState.getTool();
final NamedScope scope = scopeToolState.getScope(project);
- InspectionToolWrapper toolWrapper = scopeToolState.getTool();
if (scope != null) {
- myTools.add(idx, new ScopeToolState(scope, toolWrapper, scopeToolState.isEnabled(), level));
+ myTools.add(index, new ScopeToolState(scope, toolWrapper, scopeToolState.isEnabled(), level));
}
else {
- myTools.add(idx, new ScopeToolState(scopeToolState.getScopeName(), toolWrapper, scopeToolState.isEnabled(), level));
+ myTools.add(index, new ScopeToolState(scopeToolState.getScopeName(), toolWrapper, scopeToolState.isEnabled(), level));
}
}
- else if (idx == -1) {
- myDefaultState.setLevel(level);
- }
}
public void setDefaultState(@NotNull InspectionToolWrapper toolWrapper, boolean enabled, @NotNull HighlightDisplayLevel level) {
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
index 0fbd048f4929..f31e44e96e2c 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
@@ -149,6 +149,7 @@ public class RefManagerImpl extends RefManager {
}
}
+ @Nullable
@Override
public AnalysisScope getScope() {
return myScope;
@@ -304,7 +305,9 @@ public class RefManagerImpl extends RefManager {
if (!myDeclarationsFound) {
long before = System.currentTimeMillis();
final AnalysisScope scope = getScope();
- scope.accept(myProjectIterator);
+ if (scope != null) {
+ scope.accept(myProjectIterator);
+ }
myDeclarationsFound = true;
LOG.info("Total duration of processing project usages:" + (System.currentTimeMillis() - before));
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ui/ConventionOptionsPanel.java b/platform/analysis-impl/src/com/intellij/codeInspection/ui/ConventionOptionsPanel.java
index 0afe259bd018..ba9125f3808a 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ui/ConventionOptionsPanel.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ui/ConventionOptionsPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package com.intellij.codeInspection.ui;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.ui.DocumentAdapter;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -28,7 +29,6 @@ import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.text.InternationalFormatter;
import java.awt.*;
-import java.lang.reflect.Field;
import java.text.NumberFormat;
import java.util.regex.Pattern;
@@ -150,58 +150,18 @@ public class ConventionOptionsPanel extends JPanel {
}
private static void setPropertyIntegerValue(InspectionProfileEntry owner, String property, Integer value) {
- try {
- final Field field = getField(owner.getClass(), property);
- field.setAccessible(true);
- field.setInt(owner, value.intValue());
- } catch (Exception e) {
- LOG.error(e);
- }
+ setPropertyValue(owner, property, value);
}
private static Integer getPropertyIntegerValue(InspectionProfileEntry owner, String property) {
- try {
- final Field field = getField(owner.getClass(), property);
- field.setAccessible(true);
- return Integer.valueOf(field.getInt(owner));
- } catch (Exception e) {
- LOG.error(e);
- return 0;
- }
+ return (Integer)getPropertyValue(owner, property);
}
- private static void setPropertyValue(InspectionProfileEntry owner, String property, Object value) {
- try {
- final Field field = getField(owner.getClass(), property);
- field.setAccessible(true);
- field.set(owner, value);
- } catch (Exception e) {
- LOG.error(e);
- }
+ private static void setPropertyValue(@NotNull InspectionProfileEntry owner, String property, Object value) {
+ ReflectionUtil.setField(owner.getClass(), owner, null, property, value);
}
private static Object getPropertyValue(InspectionProfileEntry owner, String property) {
- try {
- final Field field = getField(owner.getClass(), property);
- field.setAccessible(true);
- return field.get(owner);
- }
- catch (Exception e) {
- LOG.error(e);
- return null;
- }
- }
-
- private static Field getField(Class clazz, String fieldName) throws NoSuchFieldException {
- try {
- return clazz.getDeclaredField(fieldName);
- } catch (NoSuchFieldException e) {
- Class superClass = clazz.getSuperclass();
- if (superClass == null) {
- throw e;
- } else {
- return getField(superClass, fieldName);
- }
- }
+ return ReflectionUtil.getField(owner.getClass(), owner, null, property);
}
}
diff --git a/platform/core-api/src/com/intellij/ide/caches/FileContent.java b/platform/core-api/src/com/intellij/ide/caches/FileContent.java
index 0933b7f19005..c4c6d61c4513 100644
--- a/platform/core-api/src/com/intellij/ide/caches/FileContent.java
+++ b/platform/core-api/src/com/intellij/ide/caches/FileContent.java
@@ -47,7 +47,7 @@ public class FileContent extends UserDataHolderBase {
@NotNull
public byte[] getBytes() throws IOException {
if (myCachedBytes == null) {
- myCachedBytes = myVirtualFile.contentsToByteArray(false);
+ myCachedBytes = myVirtualFile.isValid() ? myVirtualFile.contentsToByteArray(false) : ArrayUtil.EMPTY_BYTE_ARRAY;
}
return myCachedBytes;
diff --git a/platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java b/platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java
index f3b883d0b60f..f733cd04f4a6 100644
--- a/platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java
+++ b/platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java
@@ -17,8 +17,10 @@ package com.intellij.ide.util;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
@@ -31,6 +33,7 @@ public abstract class PropertiesComponent {
public abstract boolean isValueSet(String name);
+ @Nullable
public abstract String getValue(@NonNls String name);
public abstract void setValue(@NonNls String name, String value);
@@ -62,7 +65,10 @@ public abstract class PropertiesComponent {
@NotNull
public String getValue(@NonNls String name, @NotNull String defaultValue) {
- return isValueSet(name) ? getValue(name) : defaultValue;
+ if (!isValueSet(name)) {
+ return defaultValue;
+ }
+ return ObjectUtils.notNull(getValue(name), defaultValue);
}
public final int getOrInitInt(@NonNls String name, int defaultValue) {
diff --git a/platform/core-api/src/com/intellij/lexer/DelegateLexer.java b/platform/core-api/src/com/intellij/lexer/DelegateLexer.java
index ce8bbbc18748..102256b60160 100644
--- a/platform/core-api/src/com/intellij/lexer/DelegateLexer.java
+++ b/platform/core-api/src/com/intellij/lexer/DelegateLexer.java
@@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable;
public class DelegateLexer extends LexerBase {
protected final Lexer myDelegate;
- public DelegateLexer(Lexer delegate) {
+ public DelegateLexer(@NotNull Lexer delegate) {
myDelegate = delegate;
}
diff --git a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java
index a319700b4be2..e99b8e6bebf0 100644
--- a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java
+++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java
@@ -79,7 +79,7 @@ public abstract class ProgressManager {
}
}
- public static void progress(final String text) throws ProcessCanceledException {
+ public static void progress(@NotNull String text) throws ProcessCanceledException {
progress(text, "");
}
@@ -91,7 +91,7 @@ public abstract class ProgressManager {
}
}
- public static void progress(final String text, @Nullable String text2) throws ProcessCanceledException {
+ public static void progress(@NotNull String text, @Nullable String text2) throws ProcessCanceledException {
final ProgressIndicator pi = getInstance().getProgressIndicator();
if (pi != null) {
pi.checkCanceled();
@@ -103,6 +103,7 @@ public abstract class ProgressManager {
protected abstract void doCheckCanceled() throws ProcessCanceledException;
public abstract void executeNonCancelableSection(@NotNull Runnable runnable);
+ @NotNull
public abstract NonCancelableSection startNonCancelableSection();
public abstract void setCancelButtonText(String cancelButtonText);
@@ -135,9 +136,9 @@ public abstract class ProgressManager {
* @throws E exception thrown by process
*/
public abstract <T, E extends Exception> T runProcessWithProgressSynchronously(@NotNull ThrowableComputable<T, E> process,
- @NotNull @Nls String progressTitle,
- boolean canBeCanceled,
- @Nullable Project project) throws E;
+ @NotNull @Nls String progressTitle,
+ boolean canBeCanceled,
+ @Nullable Project project) throws E;
/**
* Runs the specified operation in a background thread and shows a modal progress dialog in the
@@ -206,7 +207,10 @@ public abstract class ProgressManager {
public abstract void runProcessWithProgressAsynchronously(@NotNull Task.Backgroundable task, @NotNull ProgressIndicator progressIndicator);
protected static final ThreadLocal<ProgressIndicator> myThreadIndicator = new ThreadLocal<ProgressIndicator>();
- public void executeProcessUnderProgress(@NotNull Runnable process, ProgressIndicator progress) throws ProcessCanceledException {
+
+ public void executeProcessUnderProgress(@NotNull Runnable process,
+ @Nullable("null means reuse current progress") ProgressIndicator progress)
+ throws ProcessCanceledException {
ProgressIndicator oldIndicator = null;
boolean set = progress != null && progress != (oldIndicator = myThreadIndicator.get());
diff --git a/platform/core-api/src/com/intellij/openapi/roots/FileIndexFacade.java b/platform/core-api/src/com/intellij/openapi/roots/FileIndexFacade.java
index cc7dddd3c848..96dde81c6a80 100644
--- a/platform/core-api/src/com/intellij/openapi/roots/FileIndexFacade.java
+++ b/platform/core-api/src/com/intellij/openapi/roots/FileIndexFacade.java
@@ -45,6 +45,7 @@ public abstract class FileIndexFacade {
public abstract boolean isInLibrarySource(@NotNull VirtualFile file);
public abstract boolean isExcludedFile(@NotNull VirtualFile file);
+ public abstract boolean isUnderIgnored(@NotNull VirtualFile file);
@Nullable
public abstract Module getModuleForFile(@NotNull VirtualFile file);
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/JarFile.java b/platform/core-api/src/com/intellij/openapi/vfs/JarFile.java
index c363a815577a..f8ddc7630e23 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/JarFile.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/JarFile.java
@@ -22,7 +22,7 @@ import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipFile;
-/** @deprecated causes ZipFile leaks, do not use (to be removed in IDEA 15) */
+/** @deprecated causes ZipFile leaks, do not use (to be removed in IDEA 15) + can lead to crashes (IDEA-126550) */
public interface JarFile {
interface JarEntry {
String getName();
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java
index cd0f15f3796c..9e8c37880589 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java
@@ -84,6 +84,20 @@ public class VfsUtilCore {
return false;
}
+ /**
+ * @return {@code true} if {@code url} is located under one of {@code rootUrls} or equal to one of them
+ */
+ public static boolean isUnder(@NotNull String url, @Nullable Collection<String> rootUrls) {
+ if (rootUrls == null || rootUrls.isEmpty()) return false;
+
+ for (String excludesUrl : rootUrls) {
+ if (isEqualOrAncestor(excludesUrl, url)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static boolean isEqualOrAncestor(@NotNull String ancestorUrl, @NotNull String fileUrl) {
if (ancestorUrl.equals(fileUrl)) return true;
if (StringUtil.endsWithChar(ancestorUrl, '/')) {
diff --git a/platform/core-api/src/com/intellij/psi/PsiInvalidElementAccessException.java b/platform/core-api/src/com/intellij/psi/PsiInvalidElementAccessException.java
index fb2ae2ce4d21..f24556fe5c25 100644
--- a/platform/core-api/src/com/intellij/psi/PsiInvalidElementAccessException.java
+++ b/platform/core-api/src/com/intellij/psi/PsiInvalidElementAccessException.java
@@ -164,7 +164,7 @@ public class PsiInvalidElementAccessException extends RuntimeException implement
}
public static boolean isTrackingInvalidation() {
- return Registry.is("psi.track.invalidation", true);
+ return Registry.is("psi.track.invalidation");
}
@Nullable
diff --git a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java
index 7f04b192c640..633c25a0145a 100644
--- a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java
+++ b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java
@@ -68,10 +68,8 @@ import org.picocontainer.MutablePicoContainer;
import java.lang.reflect.Modifier;
import java.util.List;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
/**
* @author yole
@@ -210,12 +208,12 @@ public class CoreApplicationEnvironment {
}
@Override
- public Object get() throws InterruptedException, ExecutionException {
+ public Object get() {
return null;
}
@Override
- public Object get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+ public Object get(long timeout, @NotNull TimeUnit unit) {
return null;
}
});
diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java
deleted file mode 100644
index a6b957c0c508..000000000000
--- a/platform/core-impl/src/com/intellij/ide/plugins/PluginDescriptorComparator.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.ide.plugins;
-
-import com.intellij.openapi.extensions.PluginId;
-import com.intellij.util.containers.HashMap;
-import gnu.trove.TObjectIntHashMap;
-
-import java.util.Comparator;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * @author Eugene Zhuravlev
- * Date: Aug 3, 2004
- */
-public class PluginDescriptorComparator implements Comparator<IdeaPluginDescriptor>{
- private final TObjectIntHashMap<PluginId> myIdToNumberMap = new TObjectIntHashMap<PluginId>();
- private int myAvailableNumber = 1;
-
- public PluginDescriptorComparator(IdeaPluginDescriptor[] descriptors){
- final Map<PluginId, IdeaPluginDescriptor> idToDescriptorMap = new HashMap<PluginId, IdeaPluginDescriptor>();
- for (final IdeaPluginDescriptor descriptor : descriptors) {
- idToDescriptorMap.put(descriptor.getPluginId(), descriptor);
- }
- myIdToNumberMap.put(PluginId.getId(PluginManagerCore.CORE_PLUGIN_ID), 0);
-
- final Stack<PluginId> visited = new Stack<PluginId>();
- for (int idx = 0; idx < descriptors.length && myIdToNumberMap.size() != descriptors.length; idx++) {
- assignNumbers(descriptors[idx].getPluginId(), idToDescriptorMap, visited);
- visited.clear();
- }
- }
-
- private void assignNumbers(PluginId id, Map<PluginId, IdeaPluginDescriptor> idToDescriptorMap, Stack<PluginId> visited){
- visited.push(id);
- try {
- final IdeaPluginDescriptor ideaPluginDescriptor = idToDescriptorMap.get(id);
- if (ideaPluginDescriptor == null || !ideaPluginDescriptor.isEnabled()) {
- // missing optional dependency or already disabled due to cycles
- return;
- }
- final PluginId[] parentIds = ideaPluginDescriptor.getDependentPluginIds();
- for (final PluginId parentId : parentIds) {
- if (visited.contains(parentId)) {
- //disable plugins in the cycle
- ideaPluginDescriptor.setEnabled(false);
- break;
- }
- }
- for (PluginId parentId1 : parentIds) {
- assignNumbers(parentId1, idToDescriptorMap, visited);
- }
- if (!myIdToNumberMap.contains(id)) {
- myIdToNumberMap.put(id, myAvailableNumber++);
- }
- }
- finally {
- visited.pop();
- }
- }
-
- public int compare(IdeaPluginDescriptor d1, IdeaPluginDescriptor d2) {
- return myIdToNumberMap.get(d1.getPluginId()) - myIdToNumberMap.get(d2.getPluginId());
- }
-}
diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
index 8f4fd771ebdd..e834e33f0f42 100644
--- a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
+++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java
@@ -30,10 +30,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.openapi.util.io.ZipFileCache;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.Function;
-import com.intellij.util.PlatformUtilsCore;
-import com.intellij.util.ReflectionUtil;
+import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.execution.ParametersListUtil;
@@ -43,6 +40,7 @@ import com.intellij.util.graph.Graph;
import com.intellij.util.graph.GraphGenerator;
import com.intellij.util.xmlb.XmlSerializationException;
import gnu.trove.THashMap;
+import gnu.trove.TIntProcedure;
import org.jdom.Document;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -498,26 +496,38 @@ public class PluginManagerCore {
}
}
- @Deprecated
- static Comparator<IdeaPluginDescriptor> getPluginDescriptorComparator(Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap) {
+ static Comparator<IdeaPluginDescriptor> getPluginDescriptorComparator(final Map<PluginId, ? extends IdeaPluginDescriptor> idToDescriptorMap) {
final Graph<PluginId> graph = createPluginIdGraph(idToDescriptorMap);
final DFSTBuilder<PluginId> builder = new DFSTBuilder<PluginId>(graph);
- /*
if (!builder.isAcyclic()) {
- final Pair<String,String> circularDependency = builder.getCircularDependency();
- throw new Exception("Cyclic dependencies between plugins are not allowed: \"" + circularDependency.getFirst() + "\" and \"" + circularDependency.getSecond() + "");
+ builder.getSCCs().forEach(new TIntProcedure() {
+ int myTNumber = 0;
+ public boolean execute(int size) {
+ if (size > 1) {
+ for (int j = 0; j < size; j++) {
+ idToDescriptorMap.get(builder.getNodeByTNumber(myTNumber + j)).setEnabled(false);
+ }
+ }
+ myTNumber += size;
+ return true;
+ }
+ });
}
- */
+
final Comparator<PluginId> idComparator = builder.comparator();
return new Comparator<IdeaPluginDescriptor>() {
@Override
public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) {
- return idComparator.compare(o1.getPluginId(), o2.getPluginId());
+ final PluginId pluginId1 = o1.getPluginId();
+ final PluginId pluginId2 = o2.getPluginId();
+ if (pluginId1.getIdString().equals(CORE_PLUGIN_ID)) return -1;
+ if (pluginId2.getIdString().equals(CORE_PLUGIN_ID)) return 1;
+ return idComparator.compare(pluginId1, pluginId2);
}
};
}
- private static Graph<PluginId> createPluginIdGraph(final Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap) {
+ private static Graph<PluginId> createPluginIdGraph(final Map<PluginId, ? extends IdeaPluginDescriptor> idToDescriptorMap) {
final List<PluginId> ids = new ArrayList<PluginId>(idToDescriptorMap.keySet());
// this magic ensures that the dependent plugins always follow their dependencies in lexicographic order
// needed to make sure that extensions are always in the same order
@@ -539,7 +549,7 @@ public class PluginManagerCore {
ArrayList<PluginId> plugins = new ArrayList<PluginId>();
for (PluginId dependentPluginId : descriptor.getDependentPluginIds()) {
// check for missing optional dependency
- IdeaPluginDescriptorImpl dep = idToDescriptorMap.get(dependentPluginId);
+ IdeaPluginDescriptor dep = idToDescriptorMap.get(dependentPluginId);
if (dep != null) {
plugins.add(dep.getPluginId());
}
@@ -901,7 +911,12 @@ public class PluginManagerCore {
loadDescriptorsFromClassPath(result, fromSources ? progress : null);
IdeaPluginDescriptorImpl[] pluginDescriptors = result.toArray(new IdeaPluginDescriptorImpl[result.size()]);
- Arrays.sort(pluginDescriptors, new PluginDescriptorComparator(pluginDescriptors));
+ final Map<PluginId, IdeaPluginDescriptorImpl> idToDescriptorMap = new com.intellij.util.containers.HashMap<PluginId, IdeaPluginDescriptorImpl>();
+ for (final IdeaPluginDescriptorImpl descriptor : pluginDescriptors) {
+ idToDescriptorMap.put(descriptor.getPluginId(), descriptor);
+ }
+
+ Arrays.sort(pluginDescriptors, getPluginDescriptorComparator(idToDescriptorMap));
return pluginDescriptors;
}
@@ -1110,13 +1125,35 @@ public class PluginManagerCore {
final Graph<PluginId> graph = createPluginIdGraph(idToDescriptorMap);
final DFSTBuilder<PluginId> builder = new DFSTBuilder<PluginId>(graph);
if (!builder.isAcyclic()) {
- final Couple<PluginId> circularDependency = builder.getCircularDependency();
- final PluginId id = circularDependency.getFirst();
- final PluginId parentId = circularDependency.getSecond();
if (!StringUtil.isEmptyOrSpaces(errorMessage)) {
errorMessage += "<br>";
}
- errorMessage += IdeBundle.message("error.plugins.should.not.have.cyclic.dependencies") + id + "->" + parentId + "->...->" + id;
+
+ final String cyclePresentation;
+ if (ApplicationManager.getApplication().isInternal()) {
+ final List<String> cycles = new ArrayList<String>();
+ builder.getSCCs().forEach(new TIntProcedure() {
+ int myTNumber = 0;
+ public boolean execute(int size) {
+ if (size > 1) {
+ String cycle = "";
+ for (int j = 0; j < size; j++) {
+ cycle += builder.getNodeByTNumber(myTNumber + j).getIdString() + " ";
+ }
+ cycles.add(cycle);
+ }
+ myTNumber += size;
+ return true;
+ }
+ });
+ cyclePresentation = ": " + StringUtil.join(cycles, ";");
+ } else {
+ final Couple<PluginId> circularDependency = builder.getCircularDependency();
+ final PluginId id = circularDependency.getFirst();
+ final PluginId parentId = circularDependency.getSecond();
+ cyclePresentation = id + "->" + parentId + "->...->" + id;
+ }
+ errorMessage += IdeBundle.message("error.plugins.should.not.have.cyclic.dependencies") + cyclePresentation;
}
prepareLoadingPluginsErrorMessage(errorMessage);
diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java
index 3338241e705a..b68fa936af23 100644
--- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java
+++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java
@@ -1152,64 +1152,66 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
private void balanceWhiteSpaces() {
- RelativeTokenTypesView wsTokens = null;
- RelativeTokenTextView tokenTextGetter = null;
+ RelativeTokenTypesView wsTokens = new RelativeTokenTypesView();
+ RelativeTokenTextView tokenTextGetter = new RelativeTokenTextView();
+ int lastIndex = 0;
for (int i = 1, size = myProduction.size() - 1; i < size; i++) {
- final ProductionMarker item = myProduction.get(i);
-
+ ProductionMarker item = myProduction.get(i);
if (item instanceof StartMarker && ((StartMarker)item).myDoneMarker == null) {
LOG.error(UNBALANCED_MESSAGE);
}
- final int prevProductionLexIndex = myProduction.get(i - 1).myLexemeIndex;
- int idx = item.myLexemeIndex;
- while (idx > prevProductionLexIndex && whitespaceOrComment(myLexTypes[idx - 1])) idx--;
- final int wsStartIndex = idx;
-
+ int prevProductionLexIndex = myProduction.get(i - 1).myLexemeIndex;
+ int wsStartIndex = Math.max(item.myLexemeIndex, lastIndex);
+ while (wsStartIndex > prevProductionLexIndex && whitespaceOrComment(myLexTypes[wsStartIndex - 1])) wsStartIndex--;
int wsEndIndex = item.myLexemeIndex;
while (wsEndIndex < myLexemeCount && whitespaceOrComment(myLexTypes[wsEndIndex])) wsEndIndex++;
- if (wsTokens == null) wsTokens = new RelativeTokenTypesView();
- wsTokens.configure(wsStartIndex, wsEndIndex);
- final boolean atEnd = wsStartIndex == 0 || wsEndIndex == myLexemeCount;
- if (tokenTextGetter == null) tokenTextGetter = new RelativeTokenTextView();
- tokenTextGetter.configure(wsStartIndex);
+ if (wsStartIndex != wsEndIndex) {
+ wsTokens.configure(wsStartIndex, wsEndIndex);
+ tokenTextGetter.configure(wsStartIndex);
+ boolean atEnd = wsStartIndex == 0 || wsEndIndex == myLexemeCount;
+ item.myLexemeIndex = wsStartIndex + item.myEdgeTokenBinder.getEdgePosition(wsTokens, atEnd, tokenTextGetter);
+ }
+ else if (item.myLexemeIndex < wsStartIndex) {
+ item.myLexemeIndex = wsStartIndex;
+ }
- item.myLexemeIndex = wsStartIndex + item.myEdgeTokenBinder.getEdgePosition(wsTokens, atEnd, tokenTextGetter);
+ lastIndex = item.myLexemeIndex;
}
}
private final class RelativeTokenTypesView extends AbstractList<IElementType> {
- private int start;
- private int size;
+ private int myStart;
+ private int mySize;
- private void configure(int _start, int _end) {
- size = _end - _start;
- start = _start;
+ private void configure(int start, int end) {
+ myStart = start;
+ mySize = end - start;
}
@Override
- public IElementType get(final int index) {
- return myLexTypes[start + index];
+ public IElementType get(int index) {
+ return myLexTypes[myStart + index];
}
@Override
public int size() {
- return size;
+ return mySize;
}
}
private final class RelativeTokenTextView implements WhitespacesAndCommentsBinder.TokenTextGetter {
- private int start;
+ private int myStart;
- private void configure(int _start) {
- start = _start;
+ private void configure(int start) {
+ myStart = start;
}
@Override
- public CharSequence get(final int i) {
- return myText.subSequence(myLexStarts[start + i], myLexStarts[start + i + 1]);
+ public CharSequence get(int i) {
+ return myText.subSequence(myLexStarts[myStart + i], myLexStarts[myStart + i + 1]);
}
}
diff --git a/platform/core-impl/src/com/intellij/mock/MockFileIndexFacade.java b/platform/core-impl/src/com/intellij/mock/MockFileIndexFacade.java
index dd6d73f11b99..6df23d8edba0 100644
--- a/platform/core-impl/src/com/intellij/mock/MockFileIndexFacade.java
+++ b/platform/core-impl/src/com/intellij/mock/MockFileIndexFacade.java
@@ -74,6 +74,11 @@ public class MockFileIndexFacade extends FileIndexFacade {
}
@Override
+ public boolean isUnderIgnored(@NotNull VirtualFile file) {
+ return false;
+ }
+
+ @Override
public Module getModuleForFile(@NotNull VirtualFile file) {
return myModule;
}
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
index fa234e109d49..918ebaa22425 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
@@ -75,6 +75,9 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
private final List<EditReadOnlyListener> myReadOnlyListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private volatile boolean myMightContainTabs = true; // optimisation flag: when document contains no tabs it is dramatically easier to calculate positions in editor
+ private int myTabTrackingRequestors = 0;
+
private int myCheckGuardedBlocks = 0;
private boolean myGuardsSuppressed = false;
private boolean myEventsHandling = false;
@@ -171,14 +174,14 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
/**
* @return true if stripping was completed successfully, false if the document prevented stripping by e.g. caret being in the way
*
- * @deprecated should be replaced with {@link #stripTrailingSpaces(com.intellij.openapi.project.Project, boolean, boolean, java.util.List)}
+ * @deprecated should be replaced with {@link #stripTrailingSpaces(com.intellij.openapi.project.Project, boolean, boolean, int[])}
* once multicaret logic will become unconditional (not controlled by configuration flag)
*/
- public boolean stripTrailingSpaces(@Nullable final Project project,
- boolean inChangedLinesOnly,
- boolean virtualSpaceEnabled,
- int caretLine,
- int caretOffset) {
+ boolean stripTrailingSpaces(@Nullable final Project project,
+ boolean inChangedLinesOnly,
+ boolean virtualSpaceEnabled,
+ int caretLine,
+ int caretOffset) {
if (!isStripTrailingSpacesEnabled) {
return true;
}
@@ -230,24 +233,24 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
/**
* @return true if stripping was completed successfully, false if the document prevented stripping by e.g. caret(s) being in the way
*/
- public boolean stripTrailingSpaces(@Nullable final Project project,
- boolean inChangedLinesOnly,
- boolean virtualSpaceEnabled,
- @NotNull List<Integer> caretOffsets) {
+ boolean stripTrailingSpaces(@Nullable final Project project,
+ boolean inChangedLinesOnly,
+ boolean virtualSpaceEnabled,
+ @NotNull int[] caretOffsets) {
if (!isStripTrailingSpacesEnabled) {
return true;
}
boolean markAsNeedsStrippingLater = false;
CharSequence text = myText;
- TIntObjectHashMap<List<RangeMarker>> caretMarkers = new TIntObjectHashMap<List<RangeMarker>>(caretOffsets.size());
+ TIntObjectHashMap<List<RangeMarker>> caretMarkers = new TIntObjectHashMap<List<RangeMarker>>(caretOffsets.length);
try {
if (!virtualSpaceEnabled) {
- for (Integer caretOffset : caretOffsets) {
- if (caretOffset == null || caretOffset < 0 || caretOffset > getTextLength()) {
+ for (int caretOffset : caretOffsets) {
+ if (caretOffset < 0 || caretOffset > getTextLength()) {
continue;
}
- Integer line = getLineNumber(caretOffset);
+ int line = getLineNumber(caretOffset);
List<RangeMarker> markers = caretMarkers.get(line);
if (markers == null) {
markers = new ArrayList<RangeMarker>();
@@ -763,6 +766,9 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
if (LOG.isDebugEnabled()) LOG.debug(event.toString());
getLineSet().changedUpdate(event);
+ if (myTabTrackingRequestors > 0) {
+ updateMightContainTabs(event.getNewFragment());
+ }
setModificationStamp(newModificationStamp);
if (!ShutDownTracker.isShutdownHookRunning()) {
@@ -1051,4 +1057,29 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
public String toString() {
return "DocumentImpl[" + FileDocumentManager.getInstance().getFile(this) + "]";
}
+
+ public void requestTabTracking() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ if (myTabTrackingRequestors++ == 0) {
+ myMightContainTabs = false;
+ updateMightContainTabs(myText);
+ }
+ }
+
+ public void giveUpTabTracking() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ if (--myTabTrackingRequestors == 0) {
+ myMightContainTabs = true;
+ }
+ }
+
+ public boolean mightContainTabs() {
+ return myMightContainTabs;
+ }
+
+ private void updateMightContainTabs(CharSequence text) {
+ if (!myMightContainTabs) {
+ myMightContainTabs = StringUtil.contains(text, 0, text.length(), '\t');
+ }
+ }
}
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java
index 975add0847a9..5ce1e2c2167b 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java
@@ -123,7 +123,7 @@ public class RangeMarkerTree<T extends RangeMarkerEx> extends IntervalTreeImpl<T
}
});
if (alive.get() > DUPLICATE_LIMIT) {
- return "Too many range markers (" + alive + ") registered in "+this+"\n";
+ return "Too many range markers (" + alive + ") registered for interval "+node+"\n";
}
return null;
diff --git a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java
index ba5858c52993..2ca35e4227e9 100644
--- a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java
+++ b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java
@@ -301,15 +301,30 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel {
final PsiToDocumentSynchronizer synchronizer = manager.getSynchronizer();
final PsiElement changeScope = transaction.getChangeScope();
LOG.assertTrue(changeScope != null);
- BlockSupportImpl.sendBeforeChildrenChangeEvent((PsiManagerImpl)PsiManager.getInstance(myProject), changeScope, true);
+
final PsiFile containingFileByTree = getContainingFileByTree(changeScope);
+ if (changeScope.isPhysical() && synchronizer.toProcessPsiEvent() && isDocumentUncommitted(containingFileByTree)) {
+ // fail-fast to prevent any psi modifications that would cause psi/document text mismatch
+ // PsiToDocumentSynchronizer assertions happen inside event processing and are logged by PsiManagerImpl.fireEvent instead of being rethrown
+ // so it's important to throw something outside event processing
+ throw new IllegalStateException("Attempt to modify PSI for non-committed Document!");
+ }
+ BlockSupportImpl.sendBeforeChildrenChangeEvent((PsiManagerImpl)PsiManager.getInstance(myProject), changeScope, true);
Document document = containingFileByTree == null ? null : manager.getCachedDocument(containingFileByTree);
if(document != null) {
synchronizer.startTransaction(myProject, document, changeScope);
}
}
+ private boolean isDocumentUncommitted(@Nullable PsiFile file) {
+ if (file == null) return false;
+
+ PsiDocumentManager manager = PsiDocumentManager.getInstance(myProject);
+ Document cachedDocument = manager.getCachedDocument(file);
+ return cachedDocument != null && manager.isUncommited(cachedDocument);
+ }
+
@Nullable
private static PsiFile getContainingFileByTree(@NotNull final PsiElement changeScope) {
// there could be pseudo physical trees (JSPX/JSP/etc.) which must not translate
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java
index 3583af212528..8a8f7221d962 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java
@@ -699,7 +699,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
}
// we can end up outside write action here if the document has forUseInNonAWTThread=true
- ApplicationManager.getApplication().runWriteAction(new Runnable() {
+ ApplicationManager.getApplication().runWriteAction(new ExternalChangeAction() {
@Override
public void run() {
psiFile.getViewProvider().beforeContentsSynchronized();
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java b/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java
index 7611dd11162a..13c43571decb 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java
@@ -74,10 +74,8 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
final PsiFile psiFile = event.getFile();
if (psiFile == null || psiFile.getNode() == null) return;
- final Document document = getCachedDocument(psiFile, force);
- if (document == null) return;
-
- if (myPsiDocumentManager.isUncommited(document)) {
+ final Document document = myPsiDocumentManager.getCachedDocument(psiFile);
+ if (document != null && myPsiDocumentManager.isUncommited(document)) {
throw new IllegalStateException("Attempt to modify PSI for non-committed Document!");
}
}
@@ -207,7 +205,7 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
return myIgnorePsiEvents;
}
- private boolean toProcessPsiEvent() {
+ public boolean toProcessPsiEvent() {
return !myIgnorePsiEvents && !ApplicationManager.getApplication().hasWriteAction(IgnorePsiEventsMarker.class);
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java b/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java
index d41138043e95..386fb2dea0e9 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/text/DiffLog.java
@@ -39,8 +39,7 @@ import java.util.List;
* User: cdr
*/
public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
- public DiffLog() {
- }
+ public DiffLog() { }
private abstract static class LogEntry {
protected LogEntry() {
@@ -58,7 +57,6 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
entry.doActualPsiChange(file, astDiffBuilder);
}
file.subtreeChanged();
-
return astDiffBuilder.getEvent();
}
@@ -83,7 +81,6 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
@Override
public void nodeDeleted(@NotNull ASTNode oldParent, @NotNull ASTNode oldNode) {
myEntries.add(new DeleteEntry(oldParent, oldNode));
-
}
@Override
@@ -126,14 +123,12 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
astDiffBuilder.nodeReplaced(oldNode, newNode);
- /////////////////
((TreeElement)newNode).clearCaches();
if (!(newNode instanceof FileElement)) {
((CompositeElement)newNode.getTreeParent()).subtreeChanged();
}
DebugUtil.checkTreeStructure(parent);
-
}
}
@@ -168,7 +163,6 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
((CompositeElement)parent).subtreeChanged();
DebugUtil.checkTreeStructure(parent);
-
}
}
@@ -222,7 +216,6 @@ public class DiffLog implements DiffTreeChangeBuilder<ASTNode,ASTNode> {
DebugUtil.checkTreeStructure(myOldParent);
}
-
}
private static PsiElement getPsi(ASTNode node, PsiFile file) {
diff --git a/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java b/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java
index 115b91a050fd..f21c241e966a 100644
--- a/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java
@@ -26,7 +26,7 @@ import org.jetbrains.annotations.NotNull;
public class ProjectScopeImpl extends GlobalSearchScope {
private final FileIndexFacade myFileIndex;
- public ProjectScopeImpl(Project project, FileIndexFacade fileIndex) {
+ public ProjectScopeImpl(@NotNull Project project, @NotNull FileIndexFacade fileIndex) {
super(project);
myFileIndex = fileIndex;
}
@@ -61,6 +61,7 @@ public class ProjectScopeImpl extends GlobalSearchScope {
return PsiBundle.message("psi.search.scope.project");
}
+ @Override
public String toString() {
return getDisplayName();
}
diff --git a/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java b/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java
index c94921b7eaeb..581352cea35f 100644
--- a/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java
+++ b/platform/core-impl/src/com/intellij/psi/text/BlockSupport.java
@@ -66,7 +66,7 @@ public abstract class BlockSupport {
// maximal tree depth for which incremental reparse is allowed
// if tree is deeper then it will be replaced completely - to avoid SOEs
- public static final int INCREMENTAL_REPARSE_DEPTH_LIMIT = Registry.intValue("psi.incremental.reparse.depth.limit", 1000);
+ public static final int INCREMENTAL_REPARSE_DEPTH_LIMIT = Registry.intValue("psi.incremental.reparse.depth.limit");
public static final Key<Boolean> TREE_DEPTH_LIMIT_EXCEEDED = Key.create("TREE_IS_TOO_DEEP");
diff --git a/platform/dvcs/src/com/intellij/dvcs/repo/Repository.java b/platform/dvcs/src/com/intellij/dvcs/repo/Repository.java
index 3650b99ce200..c12cf4ff0407 100644
--- a/platform/dvcs/src/com/intellij/dvcs/repo/Repository.java
+++ b/platform/dvcs/src/com/intellij/dvcs/repo/Repository.java
@@ -15,6 +15,7 @@
*/
package com.intellij.dvcs.repo;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -49,7 +50,7 @@ import org.jetbrains.annotations.Nullable;
*
* @author Nadya Zabrodina
*/
-public interface Repository {
+public interface Repository extends Disposable {
/**
diff --git a/platform/dvcs/src/com/intellij/dvcs/repo/RepositoryImpl.java b/platform/dvcs/src/com/intellij/dvcs/repo/RepositoryImpl.java
index a7de8f97cb8a..5a605c566710 100644
--- a/platform/dvcs/src/com/intellij/dvcs/repo/RepositoryImpl.java
+++ b/platform/dvcs/src/com/intellij/dvcs/repo/RepositoryImpl.java
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author Nadya Zabrodina
*/
-public abstract class RepositoryImpl implements Repository, Disposable {
+public abstract class RepositoryImpl implements Repository {
@NotNull private final Project myProject;
@NotNull private final VirtualFile myRootDir;
@@ -82,7 +82,6 @@ public abstract class RepositoryImpl implements Repository, Disposable {
public void dispose() {
}
-
@Override
public boolean equals(Object o) {
if (this == o) return true;
diff --git a/platform/dvcs/src/com/intellij/dvcs/repo/RepositoryUtil.java b/platform/dvcs/src/com/intellij/dvcs/repo/RepositoryUtil.java
index fa2e9a8bebe8..5a5a555768ba 100644
--- a/platform/dvcs/src/com/intellij/dvcs/repo/RepositoryUtil.java
+++ b/platform/dvcs/src/com/intellij/dvcs/repo/RepositoryUtil.java
@@ -17,6 +17,7 @@ package com.intellij.dvcs.repo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
@@ -29,7 +30,10 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
-import java.util.*;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
import java.util.concurrent.Callable;
/**
@@ -117,7 +121,9 @@ public class RepositoryUtil {
@Override
public void consume(Object dummy) {
- myRepository.update();
+ if (!Disposer.isDisposed(myRepository)) {
+ myRepository.update();
+ }
}
}
diff --git a/platform/dvcs/src/com/intellij/dvcs/ui/VcsLogAction.java b/platform/dvcs/src/com/intellij/dvcs/ui/VcsLogAction.java
new file mode 100644
index 000000000000..bb7f64f9b24c
--- /dev/null
+++ b/platform/dvcs/src/com/intellij/dvcs/ui/VcsLogAction.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.dvcs.ui;
+
+import com.intellij.dvcs.repo.Repository;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.vcs.log.VcsFullCommitDetails;
+import com.intellij.vcs.log.VcsLog;
+import com.intellij.vcs.log.VcsLogDataKeys;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public abstract class VcsLogAction<Repo extends Repository> extends DumbAwareAction {
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ Project project = e.getRequiredData(CommonDataKeys.PROJECT);
+ VcsLog log = e.getRequiredData(VcsLogDataKeys.VSC_LOG);
+ List<VcsFullCommitDetails> details = log.getSelectedDetails();
+ MultiMap<Repo, VcsFullCommitDetails> grouped = groupByRootWithCheck(project, details);
+ assert grouped != null;
+ actionPerformed(project, grouped);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ Project project = e.getProject();
+ VcsLog log = e.getData(VcsLogDataKeys.VSC_LOG);
+ if (project == null || log == null) {
+ e.getPresentation().setEnabledAndVisible(false);
+ return;
+ }
+
+ List<VcsFullCommitDetails> details = log.getSelectedDetails();
+ MultiMap<Repo, VcsFullCommitDetails> grouped = groupByRootWithCheck(project, details);
+ if (grouped == null) {
+ e.getPresentation().setEnabledAndVisible(false);
+ }
+ else {
+ e.getPresentation().setVisible(true);
+ e.getPresentation().setEnabled(!grouped.isEmpty() && isEnabled(grouped));
+ }
+ }
+
+ protected abstract void actionPerformed(@NotNull Project project, @NotNull MultiMap<Repo, VcsFullCommitDetails> grouped);
+
+ protected abstract boolean isEnabled(@NotNull MultiMap<Repo, VcsFullCommitDetails> grouped);
+
+ @Nullable
+ protected abstract Repo getRepositoryForRoot(@NotNull Project project, @NotNull VirtualFile root);
+
+ @Nullable
+ private MultiMap<Repo, VcsFullCommitDetails> groupByRootWithCheck(@NotNull Project project, @NotNull List<VcsFullCommitDetails> commits) {
+ MultiMap<Repo, VcsFullCommitDetails> map = MultiMap.create();
+ for (VcsFullCommitDetails commit : commits) {
+ Repo root = getRepositoryForRoot(project, commit.getRoot());
+ if (root == null) { // commit from some other VCS
+ return null;
+ }
+ map.putValue(root, commit);
+ }
+ return map;
+ }
+
+}
diff --git a/platform/dvcs/src/com/intellij/dvcs/ui/VcsLogOneCommitPerRepoAction.java b/platform/dvcs/src/com/intellij/dvcs/ui/VcsLogOneCommitPerRepoAction.java
new file mode 100644
index 000000000000..1b4be918a3e1
--- /dev/null
+++ b/platform/dvcs/src/com/intellij/dvcs/ui/VcsLogOneCommitPerRepoAction.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.dvcs.ui;
+
+import com.intellij.dvcs.repo.Repository;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.vcs.log.VcsFullCommitDetails;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Map;
+
+public abstract class VcsLogOneCommitPerRepoAction<Repo extends Repository> extends VcsLogAction<Repo> {
+
+ @Override
+ protected void actionPerformed(@NotNull Project project, @NotNull MultiMap<Repo, VcsFullCommitDetails> grouped) {
+ Map<Repo, VcsFullCommitDetails> singleElementMap = convertToSingleElementMap(grouped);
+ assert singleElementMap != null;
+ actionPerformed(project, singleElementMap);
+ }
+
+ @Override
+ protected boolean isEnabled(@NotNull MultiMap<Repo, VcsFullCommitDetails> grouped) {
+ return allValuesAreSingletons(grouped);
+ }
+
+ protected abstract void actionPerformed(@NotNull Project project, @NotNull Map<Repo, VcsFullCommitDetails> commits);
+
+ private boolean allValuesAreSingletons(@NotNull MultiMap<Repo, VcsFullCommitDetails> grouped) {
+ return !ContainerUtil.exists(grouped.entrySet(), new Condition<Map.Entry<Repo, Collection<VcsFullCommitDetails>>>() {
+ @Override
+ public boolean value(Map.Entry<Repo, Collection<VcsFullCommitDetails>> entry) {
+ return entry.getValue().size() != 1;
+ }
+ });
+ }
+
+ @Nullable
+ private Map<Repo, VcsFullCommitDetails> convertToSingleElementMap(@NotNull MultiMap<Repo, VcsFullCommitDetails> groupedCommits) {
+ Map<Repo, VcsFullCommitDetails> map = ContainerUtil.newHashMap();
+ for (Map.Entry<Repo, Collection<VcsFullCommitDetails>> entry : groupedCommits.entrySet()) {
+ Collection<VcsFullCommitDetails> commits = entry.getValue();
+ if (commits.size() != 1) {
+ return null;
+ }
+ map.put(entry.getKey(), commits.iterator().next());
+ }
+ return map;
+ }
+
+
+}
diff --git a/platform/dvcs/src/com/intellij/dvcs/ui/VcsLogSingleCommitAction.java b/platform/dvcs/src/com/intellij/dvcs/ui/VcsLogSingleCommitAction.java
new file mode 100644
index 000000000000..4b43380ea9eb
--- /dev/null
+++ b/platform/dvcs/src/com/intellij/dvcs/ui/VcsLogSingleCommitAction.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.dvcs.ui;
+
+import com.intellij.dvcs.repo.Repository;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.vcs.log.VcsFullCommitDetails;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Map;
+
+public abstract class VcsLogSingleCommitAction<Repo extends Repository> extends VcsLogAction<Repo> {
+
+ @Override
+ protected boolean isEnabled(@NotNull MultiMap<Repo, VcsFullCommitDetails> grouped) {
+ return grouped.size() == 1;
+ }
+
+ @Override
+ protected void actionPerformed(@NotNull Project project, @NotNull MultiMap<Repo, VcsFullCommitDetails> grouped) {
+ assert grouped.size() == 1;
+ Map.Entry<Repo, Collection<VcsFullCommitDetails>> entry = grouped.entrySet().iterator().next();
+ Repo repository = entry.getKey();
+ Collection<VcsFullCommitDetails> commits = entry.getValue();
+ assert commits.size() == 1;
+ actionPerformed(repository, commits.iterator().next());
+ }
+
+ protected abstract void actionPerformed(@NotNull Repo repository, @NotNull VcsFullCommitDetails commit);
+
+}
diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java
index cb0e1a298c9c..e6b2553085a8 100644
--- a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java
+++ b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java
@@ -72,6 +72,7 @@ public class UISettings implements PersistentStateComponent<UISettings>, Exporta
public int RECENT_FILES_LIMIT = 50;
public int CONSOLE_COMMAND_HISTORY_LIMIT = 300;
public int EDITOR_TAB_LIMIT = 10;
+ public int EDITOR_TAB_TITLE_LIMIT = 100;
public boolean ANIMATE_WINDOWS = true;
public int ANIMATION_SPEED = 2000; // Pixels per second
public boolean SHOW_TOOL_WINDOW_NUMBERS = true;
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java
index 2add3ed1b3c5..a966d831b71a 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java
+++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java
@@ -15,23 +15,12 @@
*/
package com.intellij.psi.impl.search;
-import com.intellij.lexer.Lexer;
import com.intellij.lexer.LexerBase;
-import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
-import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
-import com.intellij.openapi.editor.impl.EditorHighlighterCache;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiManager;
-import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.text.CharSequenceSubSequence;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* @author Sergey Evdokimov
@@ -49,31 +38,6 @@ public class LexerEditorHighlighterLexer extends LexerBase {
myAlreadyInitializedHighlighter = alreadyInitializedHighlighter;
}
- @Nullable
- public static Lexer getLexerBasedOnLexerHighlighter(CharSequence text, VirtualFile virtualFile, Project project) {
- EditorHighlighter highlighter = null;
-
- PsiFile psiFile = virtualFile != null ? PsiManager.getInstance(project).findFile(virtualFile) : null;
- final Document document = psiFile != null ? PsiDocumentManager.getInstance(project).getDocument(psiFile) : null;
- final EditorHighlighter cachedEditorHighlighter;
- boolean alreadyInitializedHighlighter = false;
-
- if (document != null &&
- (cachedEditorHighlighter = EditorHighlighterCache.getEditorHighlighterForCachesBuilding(document)) != null &&
- PlatformIdTableBuilding.checkCanUseCachedEditorHighlighter(text, cachedEditorHighlighter)) {
- highlighter = cachedEditorHighlighter;
- alreadyInitializedHighlighter = true;
- }
- else if (virtualFile != null) {
- highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(project, virtualFile);
- }
-
- if (highlighter != null) {
- return new LexerEditorHighlighterLexer(highlighter, alreadyInitializedHighlighter);
- }
- return null;
- }
-
@Override
public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int state) {
if (myAlreadyInitializedHighlighter) {
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java
index 4efac184c2ee..10fc11acbf5f 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DataNode.java
@@ -69,6 +69,18 @@ public class DataNode<T> implements Serializable {
}
@NotNull
+ public <T> DataNode<T> createOrReplaceChild(@NotNull Key<T> key, @NotNull T data) {
+ for (Iterator<DataNode<?>> iterator = myChildren.iterator(); iterator.hasNext(); ) {
+ DataNode<?> child = iterator.next();
+ if (child.getKey().equals(key)) {
+ iterator.remove();
+ break;
+ }
+ }
+ return createChild(key, data);
+ }
+
+ @NotNull
public Key<T> getKey() {
return myKey;
}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalFilter.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalFilter.java
new file mode 100644
index 000000000000..6bc9cf9aed94
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalFilter.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/22/2014
+ */
+public class DefaultExternalFilter implements ExternalFilter {
+ private static final long serialVersionUID = 1L;
+
+ @NotNull
+ private String myFilterType;
+ @NotNull
+ private String myPropertiesAsJsonMap;
+
+ public DefaultExternalFilter() {
+ myPropertiesAsJsonMap = "";
+ myFilterType = "";
+ }
+
+
+ public DefaultExternalFilter(ExternalFilter filter) {
+ myPropertiesAsJsonMap = filter.getPropertiesAsJsonMap();
+ myFilterType = filter.getFilterType();
+ }
+
+ @NotNull
+ @Override
+ public String getFilterType() {
+ return myFilterType;
+ }
+
+ public void setFilterType(@NotNull String filterType) {
+ myFilterType = filterType;
+ }
+
+ @Override
+ @NotNull
+ public String getPropertiesAsJsonMap() {
+ return myPropertiesAsJsonMap;
+ }
+
+ public void setPropertiesAsJsonMap(@NotNull String propertiesAsJsonMap) {
+ myPropertiesAsJsonMap = propertiesAsJsonMap;
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SteppingConfigurable.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalPlugin.java
index 5f16424c1790..8b7991b1d88c 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SteppingConfigurable.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalPlugin.java
@@ -13,29 +13,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.xdebugger.impl.settings;
+package com.intellij.openapi.externalSystem.model;
-import com.intellij.openapi.options.Configurable;
-import com.intellij.xdebugger.XDebuggerBundle;
-import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
-import java.util.List;
+/**
+ * @author Vladislav.Soroka
+ * @since 7/16/2014
+ */
+public class DefaultExternalPlugin implements ExternalPlugin {
+ private static final long serialVersionUID = 1L;
+
+ @NotNull
+ private String myId;
-class SteppingConfigurable extends MergedCompositeConfigurable {
- public SteppingConfigurable(@NotNull List<Configurable> configurables) {
- super(configurables.toArray(new Configurable[configurables.size()]));
+ public DefaultExternalPlugin() {
+ }
+
+ public DefaultExternalPlugin(ExternalPlugin plugin) {
+ myId = plugin.getId();
}
@NotNull
@Override
public String getId() {
- return "debugger.stepping";
+ return myId;
}
- @Nls
- @Override
- public String getDisplayName() {
- return XDebuggerBundle.message("debugger.stepping.display.name");
+ public void setId(@NotNull String id) {
+ myId = id;
}
-} \ No newline at end of file
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalProject.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalProject.java
new file mode 100644
index 000000000000..cecb9ad33c12
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalProject.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/14/2014
+ */
+public class DefaultExternalProject implements ExternalProject {
+
+ private static final long serialVersionUID = 1L;
+
+ @NotNull
+ private String myName;
+ @NotNull
+ private String myQName;
+ @Nullable
+ private String myDescription;
+ @NotNull
+ private String myGroup;
+ @NotNull
+ private String myVersion;
+ @NotNull
+ private Map<String, ExternalProject> myChildProjects;
+ @NotNull
+ private File myProjectDir;
+ @NotNull
+ private File myBuildDir;
+ @Nullable
+ private File myBuildFile;
+ @NotNull
+ private Map<String, ExternalTask> myTasks;
+ @NotNull
+ private Map<String, ?> myProperties;
+ @NotNull
+ private Map<String, ExternalSourceSet> mySourceSets;
+ @NotNull
+ private String myExternalSystemId;
+ @NotNull
+ private Map<String, ExternalPlugin> myPlugins;
+
+ public DefaultExternalProject() {
+ myChildProjects = new HashMap<String, ExternalProject>();
+ myTasks = new HashMap<String, ExternalTask>();
+ myProperties = new HashMap<String, Object>();
+ mySourceSets = new HashMap<String, ExternalSourceSet>();
+ myPlugins = new HashMap<String, ExternalPlugin>();
+ }
+
+ public DefaultExternalProject(@NotNull ExternalProject externalProject) {
+ this();
+ myName = externalProject.getName();
+ myQName = externalProject.getQName();
+ myVersion = externalProject.getVersion();
+ myGroup = externalProject.getGroup();
+ myDescription = externalProject.getDescription();
+ myProjectDir = externalProject.getProjectDir();
+ myBuildDir = externalProject.getBuildDir();
+ myBuildFile = externalProject.getBuildFile();
+ myExternalSystemId = externalProject.getExternalSystemId();
+
+ for (Map.Entry<String, ExternalProject> entry : externalProject.getChildProjects().entrySet()) {
+ myChildProjects.put(entry.getKey(), new DefaultExternalProject(entry.getValue()));
+ }
+
+ for (Map.Entry<String, ExternalTask> entry : externalProject.getTasks().entrySet()) {
+ myTasks.put(entry.getKey(), new DefaultExternalTask(entry.getValue()));
+ }
+ for (Map.Entry<String, ExternalSourceSet> entry : externalProject.getSourceSets().entrySet()) {
+ mySourceSets.put(entry.getKey(), new DefaultExternalSourceSet(entry.getValue()));
+ }
+ for (Map.Entry<String, ExternalPlugin> entry : externalProject.getPlugins().entrySet()) {
+ myPlugins.put(entry.getKey(), new DefaultExternalPlugin(entry.getValue()));
+ }
+ }
+
+
+ @NotNull
+ @Override
+ public String getExternalSystemId() {
+ return myExternalSystemId;
+ }
+
+ public void setExternalSystemId(@NotNull String externalSystemId) {
+ myExternalSystemId = externalSystemId;
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return myName;
+ }
+
+ public void setName(@NotNull String name) {
+ myName = name;
+ }
+
+ @NotNull
+ @Override
+ public String getQName() {
+ return myQName;
+ }
+
+ public void setQName(@NotNull String QName) {
+ myQName = QName;
+ }
+
+ @Nullable
+ @Override
+ public String getDescription() {
+ return myDescription;
+ }
+
+ public void setDescription(@Nullable String description) {
+ myDescription = description;
+ }
+
+ @NotNull
+ @Override
+ public String getGroup() {
+ return myGroup;
+ }
+
+ public void setGroup(@NotNull String group) {
+ myGroup = group;
+ }
+
+ @NotNull
+ @Override
+ public String getVersion() {
+ return myVersion;
+ }
+
+ public void setVersion(@NotNull String version) {
+ myVersion = version;
+ }
+
+ @NotNull
+ @Override
+ public Map<String, ExternalProject> getChildProjects() {
+ return myChildProjects;
+ }
+
+ public void setChildProjects(@NotNull Map<String, ExternalProject> childProjects) {
+ myChildProjects = childProjects;
+ }
+
+ @NotNull
+ @Override
+ public File getProjectDir() {
+ return myProjectDir;
+ }
+
+ public void setProjectDir(@NotNull File projectDir) {
+ myProjectDir = projectDir;
+ }
+
+ @NotNull
+ @Override
+ public File getBuildDir() {
+ return myBuildDir;
+ }
+
+ public void setBuildDir(@NotNull File buildDir) {
+ myBuildDir = buildDir;
+ }
+
+ @Nullable
+ @Override
+ public File getBuildFile() {
+ return myBuildFile;
+ }
+
+ public void setBuildFile(@Nullable File buildFile) {
+ myBuildFile = buildFile;
+ }
+
+ @NotNull
+ @Override
+ public Map<String, ExternalTask> getTasks() {
+ return myTasks;
+ }
+
+ public void setTasks(@NotNull Map<String, ExternalTask> tasks) {
+ myTasks = tasks;
+ }
+
+ @NotNull
+ @Override
+ public Map<String, ExternalPlugin> getPlugins() {
+ return myPlugins;
+ }
+
+ public void setPlugins(@NotNull Map<String, ExternalPlugin> plugins) {
+ myPlugins = plugins;
+ }
+
+ @NotNull
+ @Override
+ public Map<String, ?> getProperties() {
+ return myProperties;
+ }
+
+ public void setProperties(@NotNull Map<String, ?> properties) {
+ myProperties = properties;
+ }
+
+ @Nullable
+ @Override
+ public Object getProperty(String name) {
+ return myProperties.get(name);
+ }
+
+ @NotNull
+ @Override
+ public Map<String, ExternalSourceSet> getSourceSets() {
+ return mySourceSets;
+ }
+
+ public void setSourceSets(@NotNull Map<String, ExternalSourceSet> sourceSets) {
+ mySourceSets = sourceSets;
+ }
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalSourceDirectorySet.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalSourceDirectorySet.java
new file mode 100644
index 000000000000..d6a8d7aa6291
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalSourceDirectorySet.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/14/2014
+ */
+public class DefaultExternalSourceDirectorySet implements ExternalSourceDirectorySet {
+ private static final long serialVersionUID = 1L;
+
+ @NotNull
+ private String myName;
+ @NotNull
+ private Set<File> mySrcDirs;
+ @NotNull
+ private File myOutputDir;
+ @NotNull
+ private Set<String> myExcludes;
+ @NotNull
+ private Set<String> myIncludes;
+ @NotNull
+ private List<ExternalFilter> myFilters;
+
+ public DefaultExternalSourceDirectorySet() {
+ mySrcDirs = new HashSet<File>();
+ myExcludes = new HashSet<String>();
+ myIncludes = new HashSet<String>();
+ myFilters = new ArrayList<ExternalFilter>();
+ }
+
+ public DefaultExternalSourceDirectorySet(ExternalSourceDirectorySet sourceDirectorySet) {
+ this();
+ myName = sourceDirectorySet.getName();
+ mySrcDirs = new HashSet<File>(sourceDirectorySet.getSrcDirs());
+ myOutputDir = sourceDirectorySet.getOutputDir();
+ myExcludes = new HashSet<String>(sourceDirectorySet.getExcludes());
+ myIncludes = new HashSet<String>(sourceDirectorySet.getIncludes());
+ for (ExternalFilter filter : sourceDirectorySet.getFilters()) {
+ myFilters.add(new DefaultExternalFilter(filter));
+ }
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return myName;
+ }
+
+ public void setName(@NotNull String name) {
+ myName = name;
+ }
+
+ @NotNull
+ @Override
+ public Set<File> getSrcDirs() {
+ return mySrcDirs;
+ }
+
+ public void setSrcDirs(@NotNull Set<File> srcDirs) {
+ mySrcDirs = srcDirs;
+ }
+
+ @NotNull
+ @Override
+ public File getOutputDir() {
+ return myOutputDir;
+ }
+
+ @NotNull
+ @Override
+ public Set<String> getIncludes() {
+ return myIncludes;
+ }
+
+ public void setIncludes(@NotNull Set<String> includes) {
+ myIncludes = includes;
+ }
+
+ @NotNull
+ @Override
+ public Set<String> getExcludes() {
+ return myExcludes;
+ }
+
+ public void setExcludes(@NotNull Set<String> excludes) {
+ myExcludes = excludes;
+ }
+
+ @NotNull
+ @Override
+ public List<ExternalFilter> getFilters() {
+ return myFilters;
+ }
+
+ public void setFilters(@NotNull List<ExternalFilter> filters) {
+ myFilters = filters;
+ }
+
+ public void setOutputDir(@NotNull File outputDir) {
+ myOutputDir = outputDir;
+ }
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalSourceSet.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalSourceSet.java
new file mode 100644
index 000000000000..19d692dd1985
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalSourceSet.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model;
+
+import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType;
+import com.intellij.openapi.externalSystem.model.project.IExternalSystemSourceType;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/14/2014
+ */
+public class DefaultExternalSourceSet implements ExternalSourceSet {
+ private static final long serialVersionUID = 1L;
+
+ private String myName;
+ private Map<IExternalSystemSourceType, ExternalSourceDirectorySet> mySources;
+
+ public DefaultExternalSourceSet() {
+ mySources = new HashMap<IExternalSystemSourceType, ExternalSourceDirectorySet>();
+ }
+
+ public DefaultExternalSourceSet(ExternalSourceSet sourceSet) {
+ this();
+ myName = sourceSet.getName();
+ for (Map.Entry<IExternalSystemSourceType, ExternalSourceDirectorySet> entry : sourceSet.getSources().entrySet()) {
+ mySources.put(ExternalSystemSourceType.from(entry.getKey()), new DefaultExternalSourceDirectorySet(entry.getValue()));
+ }
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return myName;
+ }
+
+ public void setName(String name) {
+ myName = name;
+ }
+
+ @NotNull
+ @Override
+ public Map<IExternalSystemSourceType, ExternalSourceDirectorySet> getSources() {
+ return mySources;
+ }
+
+ public void setSources(Map<IExternalSystemSourceType, ExternalSourceDirectorySet> sources) {
+ mySources = sources;
+ }
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalTask.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalTask.java
new file mode 100644
index 000000000000..e9392eb52e84
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/DefaultExternalTask.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/14/2014
+ */
+public class DefaultExternalTask implements ExternalTask {
+ private static final long serialVersionUID = 1L;
+
+ @NotNull
+ private String myName;
+ @NotNull
+ private String myQName;
+ @Nullable
+ private String myDescription;
+ @Nullable
+ private String myGroup;
+
+ public DefaultExternalTask() {
+ }
+
+ public DefaultExternalTask(ExternalTask externalTask) {
+ myName = externalTask.getName();
+ myQName = externalTask.getQName();
+ myDescription = externalTask.getDescription();
+ myGroup = externalTask.getGroup();
+ }
+
+ @NotNull
+ @Override
+ public String getName() {
+ return myName;
+ }
+
+ public void setName(@NotNull String name) {
+ myName = name;
+ }
+
+ @NotNull
+ @Override
+ public String getQName() {
+ return myQName;
+ }
+
+ public void setQName(@NotNull String QName) {
+ myQName = QName;
+ }
+
+ @Nullable
+ @Override
+ public String getDescription() {
+ return myDescription;
+ }
+
+ public void setDescription(@Nullable String description) {
+ myDescription = description;
+ }
+
+ @Nullable
+ @Override
+ public String getGroup() {
+ return myGroup;
+ }
+
+ public void setGroup(@Nullable String group) {
+ myGroup = group;
+ }
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalFilter.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalFilter.java
new file mode 100644
index 000000000000..98fc003cb645
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalFilter.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/14/2014
+ */
+public interface ExternalFilter extends Serializable {
+ @NotNull
+ String getFilterType();
+ @NotNull
+ String getPropertiesAsJsonMap();
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalPlugin.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalPlugin.java
new file mode 100644
index 000000000000..edd3db771b3f
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalPlugin.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.Serializable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/14/2014
+ */
+public interface ExternalPlugin extends Serializable {
+ @NotNull
+ String getId();
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalProject.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalProject.java
new file mode 100644
index 000000000000..6df2d413d0fd
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalProject.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/14/2014
+ */
+public interface ExternalProject extends Serializable {
+
+ @NotNull
+ String getExternalSystemId();
+
+ @NotNull
+ String getName();
+
+ @NotNull
+ String getQName();
+
+ @Nullable
+ String getDescription();
+
+ @NotNull
+ String getGroup();
+
+ @NotNull
+ String getVersion();
+
+ @NotNull
+ Map<String, ExternalProject> getChildProjects();
+
+ @NotNull
+ File getProjectDir();
+
+ @NotNull
+ File getBuildDir();
+
+ @Nullable
+ File getBuildFile();
+
+ @NotNull
+ Map<String, ExternalTask> getTasks();
+
+ //@NotNull
+ //Map<String, ExternalConfiguration> getConfigurations();
+
+ //@NotNull
+ //List<ExternalRepository> getRepositories();
+
+ //@NotNull
+ //List<ExternalDependency> getDependencies();
+
+ @NotNull
+ Map<String, ExternalPlugin> getPlugins();
+
+ //@NotNull
+ //ExternalProjectBuild getBuild();
+
+ @NotNull
+ Map<String, ?> getProperties();
+
+ @Nullable
+ Object getProperty(String name);
+
+ @NotNull
+ Map<String, ExternalSourceSet> getSourceSets();
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatePsiInfoBase.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalSourceDirectorySet.java
index 7254e651ce41..70f0bed3d177 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatePsiInfoBase.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalSourceDirectorySet.java
@@ -13,27 +13,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.codeInsight.template.postfix.templates;
+package com.intellij.openapi.externalSystem.model;
-import com.intellij.openapi.editor.Document;
-import com.intellij.psi.PsiElement;
-import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
+import java.io.File;
+import java.io.Serializable;
import java.util.List;
+import java.util.Set;
-public abstract class PostfixTemplatePsiInfoBase implements PostfixTemplatePsiInfo {
+/**
+ * @author Vladislav.Soroka
+ * @since 7/14/2014
+ */
+public interface ExternalSourceDirectorySet extends Serializable {
+ @NotNull
+ String getName();
+
+ @NotNull
+ Set<File> getSrcDirs();
@NotNull
- public abstract List<PsiElement> getExpressions(@NotNull PsiElement context, @NotNull Document document, int newOffset);
+ File getOutputDir();
+
+ @NotNull
+ Set<String> getExcludes();
+ @NotNull
+ Set<String> getIncludes();
@NotNull
- public Function<PsiElement, String> getRenderer() {
- return new Function<PsiElement, String>() {
- @Override
- public String fun(@NotNull PsiElement element) {
- return element.getText();
- }
- };
- }
+ List<ExternalFilter> getFilters();
}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalSourceSet.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalSourceSet.java
new file mode 100644
index 000000000000..b23c07bbafa6
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalSourceSet.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model;
+
+import com.intellij.openapi.externalSystem.model.project.IExternalSystemSourceType;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/14/2014
+ */
+public interface ExternalSourceSet extends Serializable {
+ @NotNull
+ String getName();
+ //@NotNull
+ //ClasspathContainer getCompileClasspath();
+
+ //@NotNull
+ //ClasspathContainer getRuntimeClasspath();
+
+ @NotNull
+ Map<IExternalSystemSourceType, ExternalSourceDirectorySet> getSources();
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalTask.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalTask.java
new file mode 100644
index 000000000000..b4c61c662acc
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalTask.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.Serializable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/14/2014
+ */
+public interface ExternalTask extends Serializable {
+ @NotNull
+ String getName();
+ @NotNull
+ String getQName();
+ @Nullable
+ String getDescription();
+ @Nullable
+ String getGroup();
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalSystemSourceType.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalSystemSourceType.java
index ffe8a52d4a06..0e112b1c2b14 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalSystemSourceType.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalSystemSourceType.java
@@ -1,52 +1,62 @@
package com.intellij.openapi.externalSystem.model.project;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.Serializable;
-
/**
* Enumerates module source types.
*
* @author Denis Zhdanov
* @since 8/10/11 5:21 PM
*/
-public class ExternalSystemSourceType implements Serializable {
-
- @NotNull public static final ExternalSystemSourceType SOURCE = new ExternalSystemSourceType("SOURCE");
- @NotNull public static final ExternalSystemSourceType TEST = new ExternalSystemSourceType("TEST");
- @NotNull public static final ExternalSystemSourceType EXCLUDED = new ExternalSystemSourceType("EXCLUDED");
- @NotNull public static final ExternalSystemSourceType SOURCE_GENERATED = new ExternalSystemSourceType("SOURCE_GENERATED");
- @NotNull public static final ExternalSystemSourceType TEST_GENERATED = new ExternalSystemSourceType("TEST_GENERATED");
- @NotNull public static final ExternalSystemSourceType RESOURCE = new ExternalSystemSourceType("RESOURCE");
- @NotNull public static final ExternalSystemSourceType TEST_RESOURCE = new ExternalSystemSourceType("TEST_RESOURCE");
-
- private static final long serialVersionUID = 1L;
-
- @NotNull private final String myId;
-
- public ExternalSystemSourceType(@NotNull String id) {
- myId = id;
+public enum ExternalSystemSourceType implements IExternalSystemSourceType {
+
+ SOURCE(false, false, false, false),
+ TEST(true, false, false, false),
+ EXCLUDED(false, false, false, true),
+ SOURCE_GENERATED(true, true, false, false),
+ TEST_GENERATED(true, true, false, false),
+ RESOURCE(false, false, true, false),
+ TEST_RESOURCE(true, false, true, false);
+
+ private final boolean isTest;
+ private final boolean isGenerated;
+ private final boolean isResource;
+ private final boolean isExcluded;
+
+ ExternalSystemSourceType(boolean test, boolean generated, boolean resource, boolean excluded) {
+ isTest = test;
+ isGenerated = generated;
+ isResource = resource;
+ isExcluded = excluded;
}
@Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- ExternalSystemSourceType type = (ExternalSystemSourceType)o;
-
- if (!myId.equals(type.myId)) return false;
+ public boolean isTest() {
+ return isTest;
+ }
- return true;
+ @Override
+ public boolean isGenerated() {
+ return isGenerated;
}
@Override
- public int hashCode() {
- return myId.hashCode();
+ public boolean isResource() {
+ return isResource;
}
@Override
- public String toString() {
- return myId;
+ public boolean isExcluded() {
+ return isExcluded;
+ }
+
+ public static ExternalSystemSourceType from(IExternalSystemSourceType sourceType) {
+ for (ExternalSystemSourceType systemSourceType : ExternalSystemSourceType.values()) {
+ if (systemSourceType.isGenerated == sourceType.isGenerated() &&
+ systemSourceType.isResource == sourceType.isResource() &&
+ systemSourceType.isTest == sourceType.isTest() &&
+ systemSourceType.isExcluded == sourceType.isExcluded()) {
+ return systemSourceType;
+ }
+ }
+ throw new IllegalArgumentException("Invalid source type: " + sourceType);
}
}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/IExternalSystemSourceType.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/IExternalSystemSourceType.java
new file mode 100644
index 000000000000..2ad8821b06cd
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/IExternalSystemSourceType.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.externalSystem.model.project;
+
+import java.io.Serializable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 7/17/2014
+ */
+public interface IExternalSystemSourceType extends Serializable {
+ boolean isTest();
+
+ boolean isGenerated();
+
+ boolean isResource();
+
+ boolean isExcluded();
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
index a6cfc65eb759..fd3493447ced 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
@@ -681,4 +681,9 @@ public class ExternalSystemApiUtil {
public static String getExternalProjectPath(@Nullable Module module) {
return module != null ? module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY) : null;
}
+
+ @Nullable
+ public static String getExternalProjectId(@Nullable Module module) {
+ return module != null ? module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_ID_KEY) : null;
+ }
}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java
index 283067810bb0..160c95938378 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemConstants.java
@@ -27,6 +27,7 @@ public class ExternalSystemConstants {
@NonNls @NotNull public static final String EXTERNAL_SYSTEM_ID_KEY = "external.system.id";
@NonNls @NotNull public static final String LINKED_PROJECT_PATH_KEY = "external.linked.project.path";
@NonNls @NotNull public static final String ROOT_PROJECT_PATH_KEY = "external.root.project.path";
+ @NonNls @NotNull public static final String LINKED_PROJECT_ID_KEY = "external.linked.project.id";
@NonNls @NotNull public static final String EXTERNAL_SYSTEM_MODULE_GROUP_KEY = "external.system.module.group";
@NonNls @NotNull public static final String EXTERNAL_SYSTEM_MODULE_VERSION_KEY = "external.system.module.version";
diff --git a/platform/external-system-impl/external-system-impl.iml b/platform/external-system-impl/external-system-impl.iml
index aa68fdc4d7b6..1cbf68f907f9 100644
--- a/platform/external-system-impl/external-system-impl.iml
+++ b/platform/external-system-impl/external-system-impl.iml
@@ -24,6 +24,7 @@
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="module" module-name="testFramework" scope="TEST" />
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
+ <orderEntry type="module" module-name="compiler-impl" scope="TEST" />
</component>
</module>
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/ProjectStructureServices.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/ProjectStructureServices.java
deleted file mode 100644
index 1e6dadd0d3b8..000000000000
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/ProjectStructureServices.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.intellij.openapi.externalSystem.service.project;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Facades all services necessary for the 'sync project changes' processing.
- * <p/>
- * Thread-safe.
- *
- * @author Denis Zhdanov
- * @since 2/14/12 1:26 PM
- */
-public class ProjectStructureServices {
-
- @NotNull private final ProjectStructureHelper myProjectStructureHelper;
- @NotNull private final PlatformFacade myPlatformFacade;
- @NotNull private final ExternalLibraryPathTypeMapper myLibraryPathTypeMapper;
-
- public ProjectStructureServices(@NotNull ProjectStructureHelper projectStructureHelper,
- @NotNull PlatformFacade platformFacade,
- @NotNull ExternalLibraryPathTypeMapper mapper)
- {
- myProjectStructureHelper = projectStructureHelper;
- myPlatformFacade = platformFacade;
- myLibraryPathTypeMapper = mapper;
- }
-
- @NotNull
- public ProjectStructureHelper getProjectStructureHelper() {
- return myProjectStructureHelper;
- }
-
- @NotNull
- public PlatformFacade getPlatformFacade() {
- return myPlatformFacade;
- }
-
- @NotNull
- public ExternalLibraryPathTypeMapper getLibraryPathTypeMapper() {
- return myLibraryPathTypeMapper;
- }
-}
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java
index 7e7483869728..3e1c95ad3766 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java
@@ -33,8 +33,13 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
import com.intellij.openapi.externalSystem.util.Order;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootModificationUtil;
+import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -151,7 +156,7 @@ public class ContentRootDataService implements ProjectDataService<ContentRootDat
createSourceRootIfAbsent(contentEntry, path, module.getName(), JavaSourceRootType.TEST_SOURCE, true, createEmptyContentRootDirectories);
}
for (SourceRoot path : contentRoot.getPaths(ExternalSystemSourceType.EXCLUDED)) {
- createExcludedRootIfAbsent(contentEntry, path, module.getName());
+ createExcludedRootIfAbsent(contentEntry, path, module.getName(), module.getProject());
}
contentEntriesMap.remove(contentEntry.getUrl());
}
@@ -214,14 +219,18 @@ public class ContentRootDataService implements ProjectDataService<ContentRootDat
}
}
- private static void createExcludedRootIfAbsent(@NotNull ContentEntry entry, @NotNull SourceRoot root, @NotNull String moduleName) {
+ private static void createExcludedRootIfAbsent(@NotNull ContentEntry entry, @NotNull SourceRoot root, @NotNull String moduleName, @NotNull Project project) {
+ String rootPath = root.getPath();
for (VirtualFile file : entry.getExcludeFolderFiles()) {
- if (ExternalSystemApiUtil.getLocalFileSystemPath(file).equals(root.getPath())) {
+ if (ExternalSystemApiUtil.getLocalFileSystemPath(file).equals(rootPath)) {
return;
}
}
LOG.info(String.format("Importing excluded root '%s' for content root '%s' of module '%s'", root, entry.getUrl(), moduleName));
- entry.addExcludeFolder(toVfsUrl(root.getPath()));
+ entry.addExcludeFolder(toVfsUrl(rootPath));
+ if (!Registry.is("ide.hide.excluded.files")) {
+ ChangeListManager.getInstance(project).addDirectoryToIgnoreImplicitly(rootPath);
+ }
}
@Override
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java
index 4b1e3b13a22f..32919794eca4 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ModuleDataService.java
@@ -274,6 +274,7 @@ public class ModuleDataService implements ProjectDataService<ModuleData, Module>
module.putUserData(MODULE_DATA_KEY, moduleData);
module.setOption(ExternalSystemConstants.EXTERNAL_SYSTEM_ID_KEY, moduleData.getOwner().toString());
+ module.setOption(ExternalSystemConstants.LINKED_PROJECT_ID_KEY, moduleData.getId());
module.setOption(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY, moduleData.getLinkedExternalProjectPath());
final ProjectData projectData = moduleDataNode.getData(ProjectKeys.PROJECT);
module.setOption(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY, projectData != null ? projectData.getLinkedExternalProjectPath() : "");
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataManager.java
index 6575ffb107f0..c2dcfe57b010 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataManager.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ProjectDataManager.java
@@ -25,6 +25,7 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ContainerUtilRt;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
@@ -40,8 +41,10 @@ public class ProjectDataManager {
private static final Logger LOG = Logger.getInstance("#" + ProjectDataManager.class.getName());
- @NotNull private final NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>> myServices =
- new NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>>() {
+ @NotNull private final NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>> myServices;
+
+ public ProjectDataManager() {
+ myServices = new NotNullLazyValue<Map<Key<?>, List<ProjectDataService<?, ?>>>>() {
@NotNull
@Override
protected Map<Key<?>, List<ProjectDataService<?, ?>>> compute() {
@@ -57,10 +60,22 @@ public class ProjectDataManager {
for (List<ProjectDataService<?, ?>> services : result.values()) {
ExternalSystemApiUtil.orderAwareSort(services);
}
-
return result;
}
};
+ }
+
+ @Nullable
+ public List<ProjectDataService<?, ?>> getDataServices(Key<?> key) {
+ return myServices.getValue().get(key);
+ }
+
+ @Nullable
+ public ProjectDataService<?, ?> getDataService(Key<?> key) {
+ final List<ProjectDataService<?, ?>> dataServices = myServices.getValue().get(key);
+ assert dataServices == null || dataServices.isEmpty() || dataServices.size() == 1;
+ return ContainerUtil.getFirstItem(dataServices);
+ }
@SuppressWarnings("unchecked")
public <T> void importData(@NotNull Collection<DataNode<?>> nodes, @NotNull Project project, boolean synchronous) {
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java
index 5dcb5ef71e3b..deb9a9044ea6 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/settings/AbstractImportFromExternalSystemControl.java
@@ -193,6 +193,11 @@ public abstract class AbstractImportFromExternalSystemControl<
return myProjectSettingsControl;
}
+ @Nullable
+ public ExternalSystemSettingsControl<SystemSettings> getSystemSettingsControl() {
+ return mySystemSettingsControl;
+ }
+
public void setLinkedProjectPath(@NotNull String path) {
myProjectSettings.setExternalProjectPath(path);
myLinkedProjectPathField.setText(path);
diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java
index 22ec927eb30d..449de84f4627 100644
--- a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java
+++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemTestCase.java
@@ -15,24 +15,42 @@
*/
package com.intellij.openapi.externalSystem.test;
+import com.intellij.compiler.CompilerTestUtil;
+import com.intellij.compiler.CompilerWorkspaceConfiguration;
+import com.intellij.compiler.artifacts.ArtifactsTestUtil;
+import com.intellij.compiler.impl.ModuleCompileScope;
+import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompileStatusNotification;
+import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
+import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
import com.intellij.testFramework.IdeaTestCase;
+import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
+import com.intellij.util.concurrency.Semaphore;
+import com.intellij.util.io.TestFileSystemItem;
import com.intellij.util.ui.UIUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
@@ -40,6 +58,7 @@ import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
+import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
@@ -129,11 +148,11 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
@Override
public void tearDown() throws Exception {
try {
- myProject = null;
- UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ edt(new Runnable() {
@Override
public void run() {
try {
+ CompilerTestUtil.disableExternalCompiler(myProject);
tearDownFixtures();
}
catch (Exception e) {
@@ -141,6 +160,7 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
}
}
});
+ myProject = null;
if (!FileUtil.delete(myTestDir) && myTestDir.exists()) {
System.err.println("Cannot delete " + myTestDir);
//printDirectoryContent(myDir);
@@ -319,7 +339,11 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
protected VirtualFile createProjectSubFile(String relativePath) throws IOException {
File f = new File(getProjectPath(), relativePath);
FileUtil.ensureExists(f.getParentFile());
- f.createNewFile();
+ FileUtil.ensureCanCreateFile(f);
+ final boolean created = f.createNewFile();
+ if(!created) {
+ throw new AssertionError("Unable to create the project sub file: " + f.getAbsolutePath());
+ }
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f);
}
@@ -329,6 +353,116 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
return file;
}
+
+ protected void compileModules(final String... moduleNames) {
+ compile(createModulesCompileScope(moduleNames));
+ }
+
+ protected void buildArtifacts(String... artifactNames) {
+ compile(createArtifactsScope(artifactNames));
+ }
+
+ private void compile(final CompileScope scope) {
+ edt(new Runnable() {
+ @Override
+ public void run() {
+ for (Module module : scope.getAffectedModules()) {
+ setupJdkForModule(module.getName());
+ }
+ }
+ });
+
+ CompilerWorkspaceConfiguration.getInstance(myProject).CLEAR_OUTPUT_DIRECTORY = true;
+
+ final Semaphore semaphore = new Semaphore();
+ semaphore.down();
+ edt(new Runnable() {
+ @Override
+ public void run() {
+ CompilerTestUtil.enableExternalCompiler();
+ CompilerManager.getInstance(myProject).make(scope, new CompileStatusNotification() {
+ @Override
+ public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
+ //assertFalse(aborted);
+ //assertEquals(collectMessages(compileContext, CompilerMessageCategory.ERROR), 0, errors);
+ //assertEquals(collectMessages(compileContext, CompilerMessageCategory.WARNING), 0, warnings);
+ semaphore.up();
+ }
+ });
+ }
+ });
+ while (!semaphore.waitFor(100)) {
+ if (SwingUtilities.isEventDispatchThread()) {
+ UIUtil.dispatchAllInvocationEvents();
+ }
+ }
+ if (SwingUtilities.isEventDispatchThread()) {
+ UIUtil.dispatchAllInvocationEvents();
+ }
+ }
+
+ private CompileScope createModulesCompileScope(final String[] moduleNames) {
+ final List<Module> modules = new ArrayList<Module>();
+ for (String name : moduleNames) {
+ modules.add(getModule(name));
+ }
+ return new ModuleCompileScope(myProject, modules.toArray(new Module[modules.size()]), false);
+ }
+
+ private CompileScope createArtifactsScope(String[] artifactNames) {
+ List<Artifact> artifacts = new ArrayList<Artifact>();
+ for (String name : artifactNames) {
+ artifacts.add(ArtifactsTestUtil.findArtifact(myProject, name));
+ }
+ return ArtifactCompileScope.createArtifactsScope(myProject, artifacts);
+ }
+
+ protected Sdk setupJdkForModule(final String moduleName) {
+ final Sdk sdk = true ? JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk() : createJdk("Java 1.5");
+ ModuleRootModificationUtil.setModuleSdk(getModule(moduleName), sdk);
+ return sdk;
+ }
+
+ protected static Sdk createJdk(String versionName) {
+ return IdeaTestUtil.getMockJdk17(versionName);
+ }
+
+ protected Module getModule(final String name) {
+ AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
+ try {
+ Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
+ assertNotNull("Module " + name + " not found", m);
+ return m;
+ }
+ finally {
+ accessToken.finish();
+ }
+ }
+
+ protected void assertExplodedLayout(String artifactName, String expected) {
+ assertJarLayout(artifactName + " exploded", expected);
+ }
+
+ protected void assertJarLayout(String artifactName, String expected) {
+ ArtifactsTestUtil.assertLayout(myProject, artifactName, expected);
+ }
+
+ protected void assertArtifactOutputPath(final String artifactName, final String expected) {
+ ArtifactsTestUtil.assertOutputPath(myProject, artifactName, expected);
+ }
+
+ protected void assertArtifactOutputFileName(final String artifactName, final String expected) {
+ ArtifactsTestUtil.assertOutputFileName(myProject, artifactName, expected);
+ }
+
+ protected void assertArtifactOutput(String artifactName, TestFileSystemItem fs) {
+ final Artifact artifact = ArtifactsTestUtil.findArtifact(myProject, artifactName);
+ final VirtualFile outputFile = artifact.getOutputFile();
+ assert outputFile != null;
+ final File file = VfsUtilCore.virtualToIoFile(outputFile);
+ fs.assertFileEqual(file);
+ }
+
private static void setFileContent(final VirtualFile file, final String content, final boolean advanceStamps) throws IOException {
new WriteAction<VirtualFile>() {
@Override
diff --git a/platform/icons/src/actions/GroupByFile.png b/platform/icons/src/actions/GroupByFile.png
new file mode 100644
index 000000000000..b79988d3f0ed
--- /dev/null
+++ b/platform/icons/src/actions/GroupByFile.png
Binary files differ
diff --git a/platform/icons/src/actions/GroupByFile@2x.png b/platform/icons/src/actions/GroupByFile@2x.png
new file mode 100644
index 000000000000..5342abe8ad2c
--- /dev/null
+++ b/platform/icons/src/actions/GroupByFile@2x.png
Binary files differ
diff --git a/platform/icons/src/actions/GroupByFile@2x_dark.png b/platform/icons/src/actions/GroupByFile@2x_dark.png
new file mode 100644
index 000000000000..809d342a1266
--- /dev/null
+++ b/platform/icons/src/actions/GroupByFile@2x_dark.png
Binary files differ
diff --git a/platform/icons/src/actions/GroupByFile_dark.png b/platform/icons/src/actions/GroupByFile_dark.png
new file mode 100644
index 000000000000..f5db91f950fc
--- /dev/null
+++ b/platform/icons/src/actions/GroupByFile_dark.png
Binary files differ
diff --git a/platform/icons/src/general/projectConfigurableBanner.png b/platform/icons/src/general/projectConfigurableBanner.png
new file mode 100644
index 000000000000..b655f59be352
--- /dev/null
+++ b/platform/icons/src/general/projectConfigurableBanner.png
Binary files differ
diff --git a/platform/icons/src/general/projectConfigurableBanner@2x.png b/platform/icons/src/general/projectConfigurableBanner@2x.png
new file mode 100644
index 000000000000..04495ec5073e
--- /dev/null
+++ b/platform/icons/src/general/projectConfigurableBanner@2x.png
Binary files differ
diff --git a/platform/icons/src/general/projectConfigurableSelected.png b/platform/icons/src/general/projectConfigurableSelected.png
new file mode 100644
index 000000000000..dcbb64a75390
--- /dev/null
+++ b/platform/icons/src/general/projectConfigurableSelected.png
Binary files differ
diff --git a/platform/icons/src/general/projectConfigurableSelected@2x.png b/platform/icons/src/general/projectConfigurableSelected@2x.png
new file mode 100644
index 000000000000..3550d5fbf390
--- /dev/null
+++ b/platform/icons/src/general/projectConfigurableSelected@2x.png
Binary files differ
diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java
index 259ea3936934..c773402b27e3 100644
--- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java
+++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java
@@ -56,6 +56,8 @@ class ModuleWithDependentsScope extends GlobalSearchScope {
private static Set<Module> buildDependents(Module module) {
Set<Module> result = new THashSet<Module>();
result.add(module);
+
+ Set<Module> processedExporting = new THashSet<Module>();
ModuleIndex index = getModuleIndex(module.getProject());
@@ -64,9 +66,11 @@ class ModuleWithDependentsScope extends GlobalSearchScope {
while (!walkingQueue.isEmpty()) {
Module current = walkingQueue.pullFirst();
+ processedExporting.add(current);
result.addAll(index.plainUsages.get(current));
for (Module dependent : index.exportingUsages.get(current)) {
- if (result.add(dependent)) {
+ result.add(dependent);
+ if (processedExporting.add(dependent)) {
walkingQueue.addLast(dependent);
}
}
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java
index 3e6571405a91..8519453e3e6c 100644
--- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdTableBuilding.java
@@ -149,7 +149,9 @@ public class IdTableBuilding {
}
private int convertToMask(final WordOccurrence.Kind kind) {
- if (kind == null) return UsageSearchContext.ANY;
+ if (kind == null) {
+ return UsageSearchContext.ANY;
+ }
if (kind == WordOccurrence.Kind.CODE) return UsageSearchContext.IN_CODE;
if (kind == WordOccurrence.Kind.COMMENTS) return UsageSearchContext.IN_COMMENTS;
if (kind == WordOccurrence.Kind.LITERALS) return UsageSearchContext.IN_STRINGS;
diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java
index 6f904bae5d54..b89042b68257 100644
--- a/platform/indexing-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java
+++ b/platform/indexing-impl/src/com/intellij/psi/impl/file/impl/ResolveScopeManagerImpl.java
@@ -76,7 +76,7 @@ public class ResolveScopeManagerImpl extends ResolveScopeManager {
}
- private GlobalSearchScope getDefaultResolveScope(@NotNull PsiFile psiFile, @NotNull final VirtualFile vFile) {
+ private GlobalSearchScope getResolveScopeFromProviders(@NotNull final VirtualFile vFile) {
return myDefaultResolveScopesCache.get(vFile);
}
@@ -85,8 +85,6 @@ public class ResolveScopeManagerImpl extends ResolveScopeManager {
Module module = projectFileIndex.getModuleForFile(vFile);
if (module != null) {
boolean includeTests = projectFileIndex.isInTestSourceContent(vFile);
- // TODO: dmitrylomov: removed this line to see what fails.
- //!(vFile.getFileType() == StdFileTypes.JAVA && projectFileIndex.isContentSourceFile(vFile));
return GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module, includeTests);
}
else {
@@ -167,7 +165,7 @@ public class ResolveScopeManagerImpl extends ResolveScopeManager {
return GlobalSearchScope.allScope(myProject);
}
- return getDefaultResolveScope(contextFile, vFile);
+ return getResolveScopeFromProviders(vFile);
}
@@ -175,7 +173,7 @@ public class ResolveScopeManagerImpl extends ResolveScopeManager {
public GlobalSearchScope getDefaultResolveScope(final VirtualFile vFile) {
final PsiFile psiFile = myManager.findFile(vFile);
assert psiFile != null;
- return getDefaultResolveScope(psiFile, vFile);
+ return getResolveScopeFromProviders(vFile);
}
diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionInitializationContext.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionInitializationContext.java
index 624d60fd8688..2c152b595421 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionInitializationContext.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionInitializationContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,8 @@
package com.intellij.codeInsight.completion;
import com.intellij.lang.Language;
+import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilBase;
@@ -45,26 +45,24 @@ public class CompletionInitializationContext {
private final OffsetMap myOffsetMap;
private String myDummyIdentifier = DUMMY_IDENTIFIER;
- public CompletionInitializationContext(final Editor editor, final PsiFile file, final CompletionType completionType, int invocationCount) {
+ public CompletionInitializationContext(final Editor editor, final Caret caret, final PsiFile file, final CompletionType completionType, int invocationCount) {
myEditor = editor;
myFile = file;
myCompletionType = completionType;
myInvocationCount = invocationCount;
myOffsetMap = new OffsetMap(editor.getDocument());
- myOffsetMap.addOffset(START_OFFSET, calcStartOffset(editor));
- myOffsetMap.addOffset(SELECTION_END_OFFSET, calcSelectionEnd(editor));
- myOffsetMap.addOffset(IDENTIFIER_END_OFFSET, calcDefaultIdentifierEnd(editor, calcSelectionEnd(editor)));
+ myOffsetMap.addOffset(START_OFFSET, calcStartOffset(caret));
+ myOffsetMap.addOffset(SELECTION_END_OFFSET, calcSelectionEnd(caret));
+ myOffsetMap.addOffset(IDENTIFIER_END_OFFSET, calcDefaultIdentifierEnd(editor, calcSelectionEnd(caret)));
}
- private static int calcSelectionEnd(Editor editor) {
- final SelectionModel selectionModel = editor.getSelectionModel();
- return selectionModel.hasSelection() ? selectionModel.getSelectionEnd() : editor.getCaretModel().getOffset();
+ private static int calcSelectionEnd(Caret caret) {
+ return caret.hasSelection() ? caret.getSelectionEnd() : caret.getOffset();
}
- public static int calcStartOffset(Editor editor) {
- final SelectionModel selectionModel = editor.getSelectionModel();
- return selectionModel.hasSelection() ? selectionModel.getSelectionStart() : editor.getCaretModel().getOffset();
+ public static int calcStartOffset(Caret caret) {
+ return caret.hasSelection() ? caret.getSelectionStart() : caret.getOffset();
}
static int calcDefaultIdentifierEnd(Editor editor, int startFrom) {
diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java
index 8a7feb2109fe..6cccc06dacf2 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionResultSet.java
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.StandardPatterns;
import com.intellij.util.Consumer;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.LinkedHashSet;
@@ -61,7 +62,6 @@ public abstract class CompletionResultSet implements Consumer<LookupElement> {
/**
* If a given element matches the prefix, give it for further processing (which may eventually result in its appearing in the completion list)
- * @param element
*/
public abstract void addElement(@NotNull final LookupElement element);
@@ -75,15 +75,17 @@ public abstract class CompletionResultSet implements Consumer<LookupElement> {
}
}
+ @Contract(value="", pure=true)
@NotNull public abstract CompletionResultSet withPrefixMatcher(@NotNull PrefixMatcher matcher);
/**
* Creates a default camel-hump prefix matcher based on given prefix
- * @param prefix
*/
+ @Contract(value="", pure=true)
@NotNull public abstract CompletionResultSet withPrefixMatcher(@NotNull String prefix);
@NotNull
+ @Contract(value="", pure=true)
public abstract CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter);
public abstract void addLookupAdvertisement(@NotNull String text);
@@ -92,6 +94,7 @@ public abstract class CompletionResultSet implements Consumer<LookupElement> {
* @return A result set with the same prefix, but the lookup strings will be matched case-insensitively. Their lookup strings will
* remain as they are though, so upon insertion the prefix case will be changed.
*/
+ @Contract(value="", pure=true)
@NotNull public abstract CompletionResultSet caseInsensitive();
@NotNull
diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java
index 189e6581d171..771ca526b5fe 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.util.PsiUtilCore;
import gnu.trove.THashSet;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -85,10 +86,12 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withInsertHandler(com.intellij.codeInsight.completion.InsertHandler)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setInsertHandler(@Nullable InsertHandler<LookupElement> insertHandler) {
return withInsertHandler(insertHandler);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withInsertHandler(@Nullable InsertHandler<LookupElement> insertHandler) {
return new LookupElementBuilder(myLookupString, myObject, insertHandler, myRenderer, myHardcodedPresentation,
myAllLookupStrings, myCaseSensitive);
@@ -97,9 +100,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withRenderer(LookupElementRenderer)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setRenderer(@Nullable LookupElementRenderer<LookupElement> renderer) {
return withRenderer(renderer);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withRenderer(@Nullable LookupElementRenderer<LookupElement> renderer) {
return new LookupElementBuilder(myLookupString, myObject, myInsertHandler, renderer, myHardcodedPresentation,
myAllLookupStrings, myCaseSensitive);
@@ -114,10 +119,12 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withIcon(javax.swing.Icon)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setIcon(@Nullable Icon icon) {
return withIcon(icon);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withIcon(@Nullable Icon icon) {
final LookupElementPresentation presentation = copyPresentation();
presentation.setIcon(icon);
@@ -139,9 +146,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withLookupString(String)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder addLookupString(@NotNull String another) {
return withLookupString(another);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withLookupString(@NotNull String another) {
final THashSet<String> set = new THashSet<String>(myAllLookupStrings);
set.add(another);
@@ -157,6 +166,7 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withCaseSensitivity(boolean)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setCaseSensitive(boolean caseSensitive) {
return withCaseSensitivity(caseSensitive);
}
@@ -165,6 +175,7 @@ public final class LookupElementBuilder extends LookupElement {
* @return modified builder
* @see com.intellij.codeInsight.completion.CompletionResultSet#caseInsensitive()
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder withCaseSensitivity(boolean caseSensitive) {
return new LookupElementBuilder(myLookupString, myObject, myInsertHandler, myRenderer, myHardcodedPresentation,
myAllLookupStrings, caseSensitive);
@@ -173,9 +184,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withItemTextForeground(java.awt.Color)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setItemTextForeground(@NotNull Color itemTextForeground) {
return withItemTextForeground(itemTextForeground);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withItemTextForeground(@NotNull Color itemTextForeground) {
final LookupElementPresentation presentation = copyPresentation();
presentation.setItemTextForeground(itemTextForeground);
@@ -185,9 +198,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withItemTextUnderlined(boolean)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setItemTextUnderlined(boolean underlined) {
return withItemTextUnderlined(underlined);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withItemTextUnderlined(boolean underlined) {
final LookupElementPresentation presentation = copyPresentation();
presentation.setItemTextUnderlined(underlined);
@@ -197,9 +212,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withTypeText(String)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setTypeText(@Nullable String typeText) {
return withTypeText(typeText);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withTypeText(@Nullable String typeText) {
return withTypeText(typeText, false);
}
@@ -207,14 +224,17 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withTypeText(String, boolean)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setTypeText(@Nullable String typeText, boolean grayed) {
return withTypeText(typeText, grayed);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withTypeText(@Nullable String typeText, boolean grayed) {
return withTypeText(typeText, null, grayed);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withTypeText(@Nullable String typeText, @Nullable Icon typeIcon, boolean grayed) {
final LookupElementPresentation presentation = copyPresentation();
presentation.setTypeText(typeText, typeIcon);
@@ -226,9 +246,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withPresentableText(String)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setPresentableText(@NotNull String presentableText) {
return withPresentableText(presentableText);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withPresentableText(@NotNull String presentableText) {
final LookupElementPresentation presentation = copyPresentation();
presentation.setItemText(presentableText);
@@ -239,9 +261,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #bold()}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setBold() {
return bold();
}
+ @Contract(value="", pure=true)
public LookupElementBuilder bold() {
return withBoldness(true);
}
@@ -249,9 +273,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withBoldness(boolean)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setBold(boolean bold) {
return withBoldness(bold);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withBoldness(boolean bold) {
final LookupElementPresentation presentation = copyPresentation();
presentation.setItemTextBold(bold);
@@ -262,9 +288,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #strikeout()}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setStrikeout() {
return strikeout();
}
+ @Contract(value="", pure=true)
public LookupElementBuilder strikeout() {
return withStrikeoutness(true);
}
@@ -272,9 +300,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withStrikeoutness(boolean)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setStrikeout(boolean strikeout) {
return withStrikeoutness(strikeout);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withStrikeoutness(boolean strikeout) {
final LookupElementPresentation presentation = copyPresentation();
presentation.setStrikeout(strikeout);
@@ -285,9 +315,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withTailText(String)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setTailText(@Nullable String tailText) {
return withTailText(tailText);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withTailText(@Nullable String tailText) {
return withTailText(tailText, false);
}
@@ -295,9 +327,11 @@ public final class LookupElementBuilder extends LookupElement {
/**
* @deprecated use {@link #withTailText(String, boolean)}
*/
+ @Contract(value="", pure=true)
public LookupElementBuilder setTailText(@Nullable String tailText, boolean grayed) {
return withTailText(tailText, grayed);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder withTailText(@Nullable String tailText, boolean grayed) {
final LookupElementPresentation presentation = copyPresentation();
presentation.setTailText(tailText, grayed);
@@ -305,12 +339,14 @@ public final class LookupElementBuilder extends LookupElement {
myAllLookupStrings, myCaseSensitive);
}
+ @Contract(value="", pure=true)
public LookupElementBuilder appendTailText(@NotNull String tailText, boolean grayed) {
final LookupElementPresentation presentation = copyPresentation();
presentation.appendTailText(tailText, grayed);
return new LookupElementBuilder(myLookupString, myObject, myInsertHandler, null, presentation, myAllLookupStrings, myCaseSensitive);
}
+ @Contract(value="", pure=true)
public LookupElement withAutoCompletionPolicy(AutoCompletionPolicy policy) {
return policy.applyPolicy(this);
}
diff --git a/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java b/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java
index efee74b807da..8d4d3b29b088 100644
--- a/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java
+++ b/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java
@@ -142,14 +142,15 @@ public class RunContentDescriptor implements Disposable {
return myContent;
}
- public void setRestarter(Runnable runnable) {
- myRestarter = runnable;
- }
-
+ @Nullable
public Runnable getRestarter() {
return myRestarter;
}
+ public void setRestarter(@Nullable Runnable runnable) {
+ myRestarter = runnable;
+ }
+
public boolean isActivateToolWindowWhenAdded() {
return myActivateToolWindowWhenAdded;
}
diff --git a/platform/lang-api/src/com/intellij/find/FindManager.java b/platform/lang-api/src/com/intellij/find/FindManager.java
index 56339d116e14..abf90bb4f0b7 100644
--- a/platform/lang-api/src/com/intellij/find/FindManager.java
+++ b/platform/lang-api/src/com/intellij/find/FindManager.java
@@ -172,6 +172,18 @@ public abstract class FindManager {
public abstract void setFindWasPerformed();
/**
+ * Gets the flag indicating that 'Add Selection for Next Occurrence' action was performed recently,
+ * so "Find Next" and "Find Previous" actions should work in its context.
+ */
+ public abstract boolean selectNextOccurrenceWasPerformed();
+
+ /**
+ * Sets the flag indicating that 'Add Selection for Next Occurrence' action was performed recently,
+ * so "Find Next" and "Find Previous" actions should work in its context.
+ */
+ public abstract void setSelectNextOccurrenceWasPerformed();
+
+ /**
* Explicitly tell FindManager that "Find Next" and "Find Previous" actions should not use
* find usages previous results.
*/
diff --git a/platform/lang-api/src/com/intellij/find/FindModel.java b/platform/lang-api/src/com/intellij/find/FindModel.java
index a09070c1ed24..5dafc2db8acf 100644
--- a/platform/lang-api/src/com/intellij/find/FindModel.java
+++ b/platform/lang-api/src/com/intellij/find/FindModel.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.search.SearchScope;
+import com.intellij.util.PatternUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -72,8 +73,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
private boolean isSearchHighlighters = false;
private boolean isReplaceState = false;
private boolean isWholeWordsOnly = false;
- private boolean isInCommentsOnly;
- private boolean isInStringLiteralsOnly;
+ private SearchContext searchContext = SearchContext.ANY;
private boolean isFromCursor = true;
private boolean isForward = true;
private boolean isGlobal = true;
@@ -96,6 +96,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
private SearchScope customScope;
private boolean isCustomScope = false;
private boolean isMultiline = false;
+ private boolean mySearchInProjectFiles;
public boolean isMultiline() {
return isMultiline;
@@ -170,8 +171,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
isCustomScope = model.isCustomScope;
isFindAll = model.isFindAll;
- isInCommentsOnly = model.isInCommentsOnly;
- isInStringLiteralsOnly = model.isInStringLiteralsOnly;
+ searchContext = model.searchContext;
isMultiline = model.isMultiline;
}
@@ -190,8 +190,8 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
if (isForward != findModel.isForward) return false;
if (isFromCursor != findModel.isFromCursor) return false;
if (isGlobal != findModel.isGlobal) return false;
- if (isInCommentsOnly != findModel.isInCommentsOnly) return false;
- if (isInStringLiteralsOnly != findModel.isInStringLiteralsOnly) return false;
+ if (searchContext != findModel.searchContext) return false;
+
if (isMultiline != findModel.isMultiline) return false;
if (isMultipleFiles != findModel.isMultipleFiles) return false;
if (isOpenInNewTabEnabled != findModel.isOpenInNewTabEnabled) return false;
@@ -215,6 +215,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
if (myStringToReplace != null ? !myStringToReplace.equals(findModel.myStringToReplace) : findModel.myStringToReplace != null) {
return false;
}
+ if (mySearchInProjectFiles != findModel.mySearchInProjectFiles) return false;
return true;
}
@@ -227,8 +228,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
result = 31 * result + (isSearchHighlighters ? 1 : 0);
result = 31 * result + (isReplaceState ? 1 : 0);
result = 31 * result + (isWholeWordsOnly ? 1 : 0);
- result = 31 * result + (isInCommentsOnly ? 1 : 0);
- result = 31 * result + (isInStringLiteralsOnly ? 1 : 0);
+ result = 31 * result + (searchContext.ordinal());
result = 31 * result + (isFromCursor ? 1 : 0);
result = 31 * result + (isForward ? 1 : 0);
result = 31 * result + (isGlobal ? 1 : 0);
@@ -252,6 +252,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
result = 31 * result + (isCustomScope ? 1 : 0);
result = 31 * result + (isMultiline ? 1 : 0);
result = 31 * result + (isPreserveCase ? 1 : 0);
+ result = 31 * result + (mySearchInProjectFiles ? 1 : 0);
result = 31 * result + (myPattern != null ? myPattern.hashCode() : 0);
return result;
}
@@ -274,7 +275,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
public void setStringToFind(@NotNull String s) {
boolean changed = !StringUtil.equals(s, myStringToFind);
myStringToFind = s;
- myPattern = NO_PATTERN;
+ myPattern = PatternUtil.NOTHING;
if (changed) {
notifyObservers();
}
@@ -409,7 +410,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
boolean changed = val != isCaseSensitive;
isCaseSensitive = val;
if (changed) {
- myPattern = NO_PATTERN;
+ myPattern = PatternUtil.NOTHING;
notifyObservers();
}
}
@@ -658,8 +659,8 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
}
@Override
- public Object clone() {
- return super.clone();
+ public FindModel clone() {
+ return (FindModel)super.clone();
}
@@ -670,8 +671,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
buffer.append("myStringToReplace =").append(myStringToReplace).append("\n");
buffer.append("isReplaceState =").append(isReplaceState).append("\n");
buffer.append("isWholeWordsOnly =").append(isWholeWordsOnly).append("\n");
- buffer.append("isInStringLiterals =").append(isInStringLiteralsOnly).append("\n");
- buffer.append("isInComments =").append(isInCommentsOnly).append("\n");
+ buffer.append("searchContext =").append(searchContext).append("\n");
buffer.append("isFromCursor =").append(isFromCursor).append("\n");
buffer.append("isForward =").append(isForward).append("\n");
buffer.append("isGlobal =").append(isGlobal).append("\n");
@@ -689,6 +689,7 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
buffer.append("fileFilter =").append(fileFilter).append("\n");
buffer.append("moduleName =").append(moduleName).append("\n");
buffer.append("customScopeName =").append(customScopeName).append("\n");
+ buffer.append("searchInProjectFiles =").append(mySearchInProjectFiles).append("\n");
return buffer.toString();
}
@@ -849,45 +850,95 @@ public class FindModel extends UserDataHolderBase implements Cloneable {
}
}
+ public enum SearchContext {
+ ANY, IN_STRING_LITERALS, IN_COMMENTS, EXCEPT_STRING_LITERALS, EXCEPT_COMMENTS, EXCEPT_COMMENTS_AND_STRING_LITERALS
+ }
+
public boolean isInStringLiteralsOnly() {
- return isInStringLiteralsOnly;
+ return searchContext == SearchContext.IN_STRING_LITERALS;
+ }
+
+ public boolean isExceptComments() {
+ return searchContext == SearchContext.EXCEPT_COMMENTS;
+ }
+
+ public boolean isExceptStringLiterals() {
+ return searchContext == SearchContext.EXCEPT_STRING_LITERALS;
+ }
+
+ public boolean isInCommentsOnly() {
+ return searchContext == SearchContext.IN_COMMENTS;
+ }
+
+ public boolean isExceptCommentsAndStringLiterals() {
+ return searchContext == SearchContext.EXCEPT_COMMENTS_AND_STRING_LITERALS;
+ }
+
+ @Deprecated
+ public void setInCommentsOnly(boolean inCommentsOnly) {
+ doApplyContextChange(inCommentsOnly, SearchContext.IN_COMMENTS);
}
+ @Deprecated
public void setInStringLiteralsOnly(boolean inStringLiteralsOnly) {
- boolean changed = isInStringLiteralsOnly != inStringLiteralsOnly;
- isInStringLiteralsOnly = inStringLiteralsOnly;
+ doApplyContextChange(inStringLiteralsOnly, SearchContext.IN_STRING_LITERALS);
+ }
+
+ private void doApplyContextChange(boolean newOptionValue, SearchContext option) {
+ boolean changed = false;
+ if (newOptionValue) {
+ changed = searchContext != option;
+ searchContext = option;
+ } else if (searchContext == option) { // do not reset unrelated value
+ changed = true;
+ searchContext = SearchContext.ANY;
+ }
+
if (changed) {
notifyObservers();
}
}
- public boolean isInCommentsOnly() {
- return isInCommentsOnly;
+ public @NotNull SearchContext getSearchContext() {
+ return searchContext;
}
- public void setInCommentsOnly(boolean inCommentsOnly) {
- boolean changed = isInCommentsOnly != inCommentsOnly;
- isInCommentsOnly = inCommentsOnly;
+ public void setSearchContext(@NotNull SearchContext _searchContext) {
+ doSetContext(_searchContext);
+ }
+
+ private void doSetContext(SearchContext newSearchContext) {
+ boolean changed = newSearchContext != searchContext;
+ searchContext = newSearchContext;
+ if (changed) {
+ notifyObservers();
+ }
+ }
+
+ public boolean isSearchInProjectFiles() {
+ return mySearchInProjectFiles;
+ }
+
+ public void setSearchInProjectFiles(boolean searchInProjectFiles) {
+ boolean changed = mySearchInProjectFiles != searchInProjectFiles;
+ mySearchInProjectFiles = searchInProjectFiles;
if (changed) {
notifyObservers();
}
}
- private static final Pattern NO_PATTERN = Pattern.compile("");
- private Pattern myPattern = NO_PATTERN;
+ private Pattern myPattern = PatternUtil.NOTHING;
public Pattern compileRegExp() {
String toFind = getStringToFind();
Pattern pattern = myPattern;
- if (pattern == NO_PATTERN) {
+ if (pattern == PatternUtil.NOTHING) {
try {
myPattern = pattern = Pattern.compile(toFind, isCaseSensitive() ? Pattern.MULTILINE : Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
}
catch (PatternSyntaxException e) {
- LOG.error("Regexp:'" + toFind + "'", e);
- myPattern = null;
- return null;
+ myPattern = pattern = null;
}
}
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java
index bb8a60c83479..6f23ac69f745 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/WizardContext.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.platform.ProjectTemplate;
import com.intellij.util.SystemProperties;
@@ -48,6 +49,7 @@ public class WizardContext extends UserDataHolderBase {
private final List<Listener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private StorageScheme myProjectStorageFormat = StorageScheme.DIRECTORY_BASED;
private boolean myNewWizard;
+ private ModulesProvider myModulesProvider;
public void setProjectStorageFormat(StorageScheme format) {
myProjectStorageFormat = format;
@@ -61,6 +63,14 @@ public class WizardContext extends UserDataHolderBase {
myNewWizard = newWizard;
}
+ public ModulesProvider getModulesProvider() {
+ return myModulesProvider;
+ }
+
+ public void setModulesProvider(ModulesProvider modulesProvider) {
+ myModulesProvider = modulesProvider;
+ }
+
public interface Listener {
void buttonsUpdateRequested();
void nextStepRequested();
diff --git a/platform/lang-api/src/com/intellij/lexer/LexerUtil.java b/platform/lang-api/src/com/intellij/lexer/LexerUtil.java
index 7623248e60d1..8abdfa5e79af 100644
--- a/platform/lang-api/src/com/intellij/lexer/LexerUtil.java
+++ b/platform/lang-api/src/com/intellij/lexer/LexerUtil.java
@@ -16,6 +16,8 @@
package com.intellij.lexer;
import com.intellij.util.CharTable;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Nullable;
/**
* @author max
@@ -30,4 +32,12 @@ public class LexerUtil {
public static CharSequence internToken(Lexer lexer, CharTable table) {
return table.intern(getTokenText(lexer));
}
+
+ @Contract("!null->!null")
+ public static Lexer getRootLexer(@Nullable Lexer lexer) {
+ while (lexer instanceof DelegateLexer) {
+ lexer = ((DelegateLexer)lexer).getDelegate();
+ }
+ return lexer;
+ }
}
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java
index 2c44a32d9ace..d858bfc01fcb 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java
@@ -56,7 +56,6 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
public CodeStyleSettings(boolean loadExtensions) {
super(null);
- RIGHT_MARGIN = DEFAULT_RIGHT_MARGIN;
initTypeToName();
initImportsByDefault();
@@ -108,12 +107,16 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
private void addCustomSettings(CustomCodeStyleSettings settings) {
if (settings != null) {
- myCustomSettings.put(settings.getClass(), settings);
+ synchronized (myCustomSettings) {
+ myCustomSettings.put(settings.getClass(), settings);
+ }
}
}
public <T extends CustomCodeStyleSettings> T getCustomSettings(Class<T> aClass) {
- return (T)myCustomSettings.get(aClass);
+ synchronized (myCustomSettings) {
+ return (T)myCustomSettings.get(aClass);
+ }
}
@Override
@@ -125,7 +128,7 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
private void copyCustomSettingsFrom(@NotNull CodeStyleSettings from) {
myCustomSettings.clear();
- for (final CustomCodeStyleSettings settings : from.myCustomSettings.values()) {
+ for (final CustomCodeStyleSettings settings : from.getCustomSettingsValues()) {
addCustomSettings((CustomCodeStyleSettings) settings.clone());
}
@@ -244,6 +247,7 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
public int INNER_CLASSES_ORDER_WEIGHT = 7;
//----------------- WRAPPING ---------------------------
+ public int RIGHT_MARGIN = 120;
public boolean WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN = false;
@@ -431,6 +435,12 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
private CodeStyleSettings myParentSettings;
private boolean myLoadedAdditionalIndentOptions;
+ private Collection<CustomCodeStyleSettings> getCustomSettingsValues() {
+ synchronized (myCustomSettings) {
+ return Collections.unmodifiableCollection(myCustomSettings.values());
+ }
+ }
+
@Override
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
@@ -452,7 +462,7 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
}
}
boolean oldOptionsImported = importOldIndentOptions(element);
- for (final CustomCodeStyleSettings settings : myCustomSettings.values()) {
+ for (final CustomCodeStyleSettings settings : getCustomSettingsValues()) {
settings.readExternal(element);
settings.importLegacySettings();
}
@@ -564,7 +574,7 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea
public void writeExternal(Element element) throws WriteExternalException {
final CodeStyleSettings parentSettings = new CodeStyleSettings();
DefaultJDOMExternalizer.writeExternal(this, element, new DifferenceFilter<CodeStyleSettings>(this, parentSettings));
- List<CustomCodeStyleSettings> customSettings = new ArrayList<CustomCodeStyleSettings>(myCustomSettings.values());
+ List<CustomCodeStyleSettings> customSettings = new ArrayList<CustomCodeStyleSettings>(getCustomSettingsValues());
Collections.sort(customSettings, new Comparator<CustomCodeStyleSettings>(){
@Override
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java
index 20b96cac3920..299d17215fdf 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java
@@ -287,7 +287,6 @@ public class CommonCodeStyleSettings {
//----------------- GENERAL --------------------
public int RIGHT_MARGIN = -1;
- public final static int DEFAULT_RIGHT_MARGIN = 120;
public boolean LINE_COMMENT_AT_FIRST_COLUMN = true;
public boolean BLOCK_COMMENT_AT_FIRST_COLUMN = true;
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java
index f978d5f6dcdb..59736bc0e4b2 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTableWithPreviewPanel.java
@@ -18,6 +18,7 @@ package com.intellij.application.options.codeStyle;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
import com.intellij.ui.SpeedSearchComparator;
import com.intellij.ui.TreeTableSpeedSearch;
@@ -378,7 +379,7 @@ public abstract class OptionTableWithPreviewPanel extends MultilanguageCodeStyle
this.groupName = groupName;
try {
- Class styleSettingsClass = clazz == null ? CodeStyleSettings.class : clazz;
+ Class styleSettingsClass = clazz == null ? CommonCodeStyleSettings.class : clazz;
this.field = styleSettingsClass.getField(fieldName);
}
catch (NoSuchFieldException e) {
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/RightMarginForm.form b/platform/lang-impl/src/com/intellij/application/options/codeStyle/RightMarginForm.form
new file mode 100644
index 000000000000..67f579a77ff5
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/RightMarginForm.form
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.codeStyle.RightMarginForm">
+ <grid id="27dc6" binding="myTopPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <xy x="20" y="20" width="500" height="400"/>
+ </constraints>
+ <properties/>
+ <border type="none"/>
+ <children>
+ <component id="12cf8" class="com.intellij.ui.components.JBLabel">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/ApplicationBundle" key="editbox.right.margin.columns"/>
+ </properties>
+ </component>
+ <vspacer id="1265c">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
+ <component id="78fe" class="javax.swing.JTextField" binding="myRightMarginField">
+ <constraints>
+ <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
+ <preferred-size width="50" height="-1"/>
+ </grid>
+ </constraints>
+ <properties>
+ <horizontalAlignment value="2"/>
+ </properties>
+ </component>
+ <component id="5ef52" class="javax.swing.JCheckBox" binding="myDefaultGeneralCheckBox" default-binding="true">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/ApplicationBundle" key="settings.code.style.default.general"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
+</form>
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/RightMarginForm.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/RightMarginForm.java
new file mode 100644
index 000000000000..70c747dc11ca
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/RightMarginForm.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.application.options.codeStyle;
+
+import com.intellij.lang.Language;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+/**
+ * Can be used for languages which do not use standard "Wrapping and Braces" panel.
+ * <p>
+ * <strong>Note</strong>: besides adding the panel to UI it is necessary to make sure that language's own
+ * <code>LanguageCodeStyleSettingsProvider</code> explicitly supports RIGHT_MARGIN field in <code>customizeSettings()</code>
+ * method as shown below:
+ * <pre>
+ * public void customizeSettings(...) {
+ * if (settingsType == SettingsType.WRAPPING_AND_BRACES_SETTINGS) {
+ * consumer.showStandardOptions("RIGHT_MARGIN");
+ * }
+ * }
+ * </pre>
+ * @author Rustam Vishnyakov
+ */
+public class RightMarginForm {
+ private JTextField myRightMarginField;
+ private JCheckBox myDefaultGeneralCheckBox;
+ private JPanel myTopPanel;
+ private final Language myLanguage;
+ private final int myDefaultRightMargin;
+
+ public RightMarginForm(@NotNull Language language, @NotNull CodeStyleSettings settings) {
+ myLanguage = language;
+ myDefaultRightMargin = settings.RIGHT_MARGIN;
+ myDefaultGeneralCheckBox.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ if (myDefaultGeneralCheckBox.isSelected()) {
+ myRightMarginField.setText(Integer.toString(myDefaultRightMargin));
+ myRightMarginField.setEnabled(false);
+ }
+ else {
+ myRightMarginField.setEnabled(true);
+ }
+ }
+ });
+ }
+
+ public void reset(@NotNull CodeStyleSettings settings) {
+ CommonCodeStyleSettings langSettings = settings.getCommonSettings(myLanguage);
+ if (langSettings != settings && langSettings.RIGHT_MARGIN >= 0) {
+ myDefaultGeneralCheckBox.setSelected(false);
+ myRightMarginField.setText(Integer.toString(langSettings.RIGHT_MARGIN));
+ }
+ else {
+ myDefaultGeneralCheckBox.setSelected(true);
+ myRightMarginField.setText(Integer.toString(settings.RIGHT_MARGIN));
+ if (langSettings == settings) {
+ myDefaultGeneralCheckBox.setEnabled(false);
+ myRightMarginField.setEnabled(false);
+ }
+ }
+ }
+
+ public void apply(@NotNull CodeStyleSettings settings) {
+ CommonCodeStyleSettings langSettings = settings.getCommonSettings(myLanguage);
+ if (langSettings != settings) {
+ if (myDefaultGeneralCheckBox.isSelected()) {
+ langSettings.RIGHT_MARGIN = -1;
+ }
+ else {
+ langSettings.RIGHT_MARGIN = getFieldRightMargin(settings.RIGHT_MARGIN);
+ }
+ }
+ }
+
+ public boolean isModified(@NotNull CodeStyleSettings settings) {
+ CommonCodeStyleSettings langSettings = settings.getCommonSettings(myLanguage);
+ if (myDefaultGeneralCheckBox.isSelected()) {
+ return langSettings.RIGHT_MARGIN >= 0;
+ }
+ else {
+ return langSettings.RIGHT_MARGIN != getFieldRightMargin(settings.RIGHT_MARGIN);
+ }
+ }
+
+ private int getFieldRightMargin(int fallBackValue) {
+ String strValue = myRightMarginField.getText();
+ if (!strValue.trim().isEmpty()) {
+ try {
+ return Integer.parseInt(strValue);
+ }
+ catch (NumberFormatException e) {
+ myRightMarginField.setText(Integer.toString(fallBackValue));
+ }
+ }
+ return fallBackValue;
+ }
+
+ public JPanel getTopPanel() {
+ return myTopPanel;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRulesControl.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRulesControl.java
index fa14958132d0..145ae1094e0b 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRulesControl.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/match/ArrangementMatchingRulesControl.java
@@ -165,7 +165,7 @@ public class ArrangementMatchingRulesControl extends JBTable {
}
final List<ArrangementSectionRule> result = ContainerUtil.newArrayList();
- final List<StdArrangementMatchRule> currentRules = ContainerUtil.newArrayList();
+ final List<StdArrangementMatchRule> buffer = ContainerUtil.newArrayList();
String currentSectionStart = null;
for (int i = 0; i < getModel().getSize(); i++) {
Object element = getModel().getElementAt(i);
@@ -174,15 +174,12 @@ public class ArrangementMatchingRulesControl extends JBTable {
mySectionRuleManager == null ? null : mySectionRuleManager.getSectionRuleData((StdArrangementMatchRule)element);
if (sectionRule != null) {
if (sectionRule.isSectionStart()) {
- if (currentSectionStart != null) {
- result.add(ArrangementSectionRule.create(currentSectionStart, null, currentRules));
- currentRules.clear();
- }
+ appendBufferedSectionRules(result, buffer, currentSectionStart);
currentSectionStart = sectionRule.getText();
}
else {
- result.add(ArrangementSectionRule.create(StringUtil.notNullize(currentSectionStart), sectionRule.getText(), currentRules));
- currentRules.clear();
+ result.add(ArrangementSectionRule.create(StringUtil.notNullize(currentSectionStart), sectionRule.getText(), buffer));
+ buffer.clear();
currentSectionStart = null;
}
}
@@ -190,17 +187,34 @@ public class ArrangementMatchingRulesControl extends JBTable {
result.add(ArrangementSectionRule.create((StdArrangementMatchRule)element));
}
else {
- currentRules.add((StdArrangementMatchRule)element);
+ buffer.add((StdArrangementMatchRule)element);
}
}
}
- if (currentSectionStart != null) {
- result.add(ArrangementSectionRule.create(currentSectionStart, null, currentRules));
- }
+ appendBufferedSectionRules(result, buffer, currentSectionStart);
return result;
}
+ private static void appendBufferedSectionRules(@NotNull List<ArrangementSectionRule> result,
+ @NotNull List<StdArrangementMatchRule> buffer,
+ @Nullable String currentSectionStart) {
+ if (currentSectionStart == null) {
+ return;
+ }
+
+ if (buffer.isEmpty()) {
+ result.add(ArrangementSectionRule.create(currentSectionStart, null));
+ }
+ else {
+ result.add(ArrangementSectionRule.create(currentSectionStart, null, buffer.get(0)));
+ for (int j = 1; j < buffer.size(); j++) {
+ result.add(ArrangementSectionRule.create(buffer.get(j)));
+ }
+ buffer.clear();
+ }
+ }
+
@Override
protected void processMouseEvent(MouseEvent e) {
int id = e.getID();
diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.form
index 9872c7c624aa..db23ce17b2c3 100644
--- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.form
+++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.form
@@ -3,7 +3,7 @@
<grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="20" y="20" width="500" height="527"/>
+ <xy x="20" y="20" width="500" height="585"/>
</constraints>
<properties/>
<border type="none"/>
@@ -108,7 +108,7 @@
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
- <grid id="eb8d0" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="10">
+ <grid id="eb8d0" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="10">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -119,7 +119,7 @@
</clientProperties>
<border type="none" title-resource-bundle="messages/ApplicationBundle" title-key="group.tab.closing.policy"/>
<children>
- <grid id="5a5a7" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="5a5a7" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -129,7 +129,9 @@
<children>
<component id="527a6" class="javax.swing.JLabel">
<constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
+ <preferred-size width="60" height="27"/>
+ </grid>
</constraints>
<properties>
<text resource-bundle="messages/ApplicationBundle" key="editbox.tab.limit"/>
@@ -138,19 +140,38 @@
<component id="16477" class="javax.swing.JTextField" binding="myEditorTabLimitField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="0" indent="0" use-parent-layout="false">
- <preferred-size width="30" height="-1"/>
+ <preferred-size width="30" height="27"/>
</grid>
</constraints>
<properties>
<text value="15"/>
</properties>
</component>
+ <component id="2479d" class="javax.swing.JLabel">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/ApplicationBundle" key="editbox.tab.title.limit"/>
+ </properties>
+ </component>
+ <component id="3499c" class="javax.swing.JTextField" binding="myTabTitleLimitField">
+ <constraints>
+ <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="0" indent="0" use-parent-layout="false">
+ <preferred-size width="30" height="27"/>
+ </grid>
+ </constraints>
+ <properties>
+ <columns value="2"/>
+ <text value="30"/>
+ </properties>
+ </component>
</children>
</grid>
<grid id="9b723" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="2">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -184,7 +205,7 @@
<grid id="611cc" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="2">
<margin top="10" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java
index 4e1de817255a..35a34085d035 100644
--- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java
@@ -45,6 +45,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
private JCheckBox myShowCloseButtonOnCheckBox;
private JCheckBox myShowDirectoryInTabCheckBox;
private JRadioButton myActivateRightNeighbouringTabRadioButton;
+ private JTextField myTabTitleLimitField;
public EditorTabsConfigurable() {
myEditorTabPlacement.setModel(new DefaultComboBoxModel(new Object[]{
@@ -119,6 +120,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
myHideKnownExtensions.setSelected(uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS);
myShowDirectoryInTabCheckBox.setSelected(uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES);
myEditorTabLimitField.setText(Integer.toString(uiSettings.EDITOR_TAB_LIMIT));
+ myTabTitleLimitField.setText(Integer.toString(uiSettings.EDITOR_TAB_TITLE_LIMIT));
myShowCloseButtonOnCheckBox.setSelected(uiSettings.SHOW_CLOSE_BUTTON);
if (uiSettings.CLOSE_NON_MODIFIED_FILES_FIRST) {
@@ -171,14 +173,29 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
uiSettings.ACTIVATE_RIGHT_EDITOR_ON_CLOSE = myActivateRightNeighbouringTabRadioButton.isSelected();
String temp = myEditorTabLimitField.getText();
- if(temp.trim().length() > 0){
+ if (temp.trim().length() > 0) {
try {
int newEditorTabLimit = Integer.parseInt(temp);
- if(newEditorTabLimit>0&&newEditorTabLimit!=uiSettings.EDITOR_TAB_LIMIT){
- uiSettings.EDITOR_TAB_LIMIT=newEditorTabLimit;
+ if (newEditorTabLimit > 0 && newEditorTabLimit != uiSettings.EDITOR_TAB_LIMIT) {
+ uiSettings.EDITOR_TAB_LIMIT = newEditorTabLimit;
uiSettingsChanged = true;
}
- }catch (NumberFormatException ignored){}
+ }
+ catch (NumberFormatException ignored) {
+ }
+ }
+ temp = myTabTitleLimitField.getText();
+ if (temp.trim().length() > 0) {
+ try {
+ int newTabTitleLimit = Integer.parseInt(temp);
+ newTabTitleLimit = Math.max(25, Math.min(100, newTabTitleLimit));
+ if (newTabTitleLimit != uiSettings.EDITOR_TAB_TITLE_LIMIT){
+ uiSettings.EDITOR_TAB_TITLE_LIMIT = newTabTitleLimit;
+ uiSettingsChanged = true;
+ }
+ }
+ catch (NumberFormatException ignored) {
+ }
}
if(uiSettingsChanged){
uiSettings.fireUISettingsChanged();
@@ -191,6 +208,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
boolean isModified = isModified(myCbModifiedTabsMarkedWithAsterisk, uiSettings.MARK_MODIFIED_TABS_WITH_ASTERISK);
isModified |= isModified(myShowTabsTooltipsCheckBox, uiSettings.SHOW_TABS_TOOLTIPS);
isModified |= isModified(myEditorTabLimitField, uiSettings.EDITOR_TAB_LIMIT);
+ isModified |= isModified(myTabTitleLimitField, uiSettings.EDITOR_TAB_TITLE_LIMIT);
int tabPlacement = ((Integer)myEditorTabPlacement.getSelectedItem()).intValue();
isModified |= tabPlacement != uiSettings.EDITOR_TAB_PLACEMENT;
isModified |= myHideKnownExtensions.isSelected() != uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java
index bf77a3022a0e..af6bbdc931ca 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java
@@ -289,7 +289,16 @@ public class FormatChangedTextUtil {
}
try {
- List<Range> changedRanges = new RangesBuilder(document, documentFromVcs).getRanges();
+ List<Range> changedRanges;
+
+ LineStatusTracker tracker = LineStatusTrackerManager.getInstance(project).getLineStatusTracker(document);
+ if (tracker != null) {
+ changedRanges = tracker.getRanges();
+ }
+ else {
+ changedRanges = new RangesBuilder(document, documentFromVcs).getRanges();
+ }
+
return getChangedTextRanges(document, changedRanges);
}
catch (FilesTooBigForDiffException e) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java
index 4966a9466a26..8ec833e8258b 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeAction.java
@@ -79,9 +79,6 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
PsiDocumentManager.getInstance(project).commitAllDocuments();
final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
- if (files == null) {
- return;
- }
PsiFile file = null;
final PsiDirectory dir;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
index e0a3be5f423d..fcb080dcd277 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
@@ -71,6 +71,8 @@ import java.util.concurrent.atomic.AtomicReference;
public class CodeCompletionHandlerBase {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.CodeCompletionHandlerBase");
+ private static final Key<Boolean> CARET_PROCESSED = Key.create("CodeCompletionHandlerBase.caretProcessed");
+
@NotNull private final CompletionType myCompletionType;
final boolean invokedExplicitly;
final boolean synchronous;
@@ -108,6 +110,13 @@ public class CodeCompletionHandlerBase {
}
public final void invokeCompletion(@NotNull final Project project, @NotNull final Editor editor, int time, boolean hasModifiers, boolean restarted) {
+ clearCaretMarkers(editor);
+ invokeCompletion(project, editor, time, hasModifiers, restarted, editor.getCaretModel().getPrimaryCaret());
+ }
+
+ public final void invokeCompletion(@NotNull final Project project, @NotNull final Editor editor, int time, boolean hasModifiers, boolean restarted, @NotNull final Caret caret) {
+ markCaretAsProcessed(caret);
+
if (invokedExplicitly) {
CompletionLookupArranger.applyLastCompletionStatisticsUpdate();
}
@@ -162,12 +171,12 @@ public class CodeCompletionHandlerBase {
PsiDocumentManager.getInstance(project).commitAllDocuments();
CompletionAssertions.checkEditorValid(editor);
- final PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(editor, project);
+ final PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(caret, project);
assert psiFile != null : "no PSI file: " + FileDocumentManager.getInstance().getFile(editor.getDocument());
psiFile.putUserData(PsiFileEx.BATCH_REFERENCE_PROCESSING, Boolean.TRUE);
CompletionAssertions.assertCommitSuccessful(editor, psiFile);
- initializationContext[0] = runContributorsBeforeCompletion(editor, psiFile, invocationCount);
+ initializationContext[0] = runContributorsBeforeCompletion(editor, psiFile, invocationCount, caret);
}
};
ApplicationManager.getApplication().runWriteAction(runnable);
@@ -186,9 +195,9 @@ public class CodeCompletionHandlerBase {
insertDummyIdentifier(initializationContext[0], hasModifiers, invocationCount);
}
- private CompletionInitializationContext runContributorsBeforeCompletion(Editor editor, PsiFile psiFile, int invocationCount) {
+ private CompletionInitializationContext runContributorsBeforeCompletion(Editor editor, PsiFile psiFile, int invocationCount, Caret caret) {
final Ref<CompletionContributor> current = Ref.create(null);
- CompletionInitializationContext context = new CompletionInitializationContext(editor, psiFile, myCompletionType, invocationCount) {
+ CompletionInitializationContext context = new CompletionInitializationContext(editor, caret, psiFile, myCompletionType, invocationCount) {
CompletionContributor dummyIdentifierChanger;
@Override
@@ -400,8 +409,15 @@ public class CodeCompletionHandlerBase {
final LookupElement[] items, boolean hasModifiers) {
if (items.length == 0) {
LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
- indicator.handleEmptyLookup(true);
- checkNotSync(indicator, items);
+
+ Caret nextCaret = getNextCaretToProcess(indicator.getEditor());
+ if (nextCaret != null) {
+ invokeCompletion(indicator.getProject(), indicator.getEditor(), indicator.getParameters().getInvocationCount(), hasModifiers, false, nextCaret);
+ }
+ else {
+ indicator.handleEmptyLookup(true);
+ checkNotSync(indicator, items);
+ }
return;
}
@@ -866,4 +882,23 @@ public class CodeCompletionHandlerBase {
}
};
}
+
+ private static void clearCaretMarkers(@NotNull Editor editor) {
+ for (Caret caret : editor.getCaretModel().getAllCarets()) {
+ caret.putUserData(CARET_PROCESSED, null);
+ }
+ }
+
+ private static void markCaretAsProcessed(@NotNull Caret caret) {
+ caret.putUserData(CARET_PROCESSED, Boolean.TRUE);
+ }
+
+ private static Caret getNextCaretToProcess(@NotNull Editor editor) {
+ for (Caret caret : editor.getCaretModel().getAllCarets()) {
+ if (caret.getUserData(CARET_PROCESSED) == null) {
+ return caret;
+ }
+ }
+ return null;
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java
index 8560129194f1..0321191294c5 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/InjectedGeneralHighlightingPass.java
@@ -73,7 +73,7 @@ public class InjectedGeneralHighlightingPass extends GeneralHighlightingPass imp
@Override
protected void collectInformationWithProgress(@NotNull final ProgressIndicator progress) {
- if (!Registry.is("editor.injected.highlighting.enabled", true)) return;
+ if (!Registry.is("editor.injected.highlighting.enabled")) return;
final Set<HighlightInfo> gotHighlights = new THashSet<HighlightInfo>(100);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WolfHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WolfHighlightingPass.java
index 9211bead784b..6ff242108eed 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WolfHighlightingPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WolfHighlightingPass.java
@@ -38,7 +38,7 @@ class WolfHighlightingPass extends ProgressableTextEditorHighlightingPass implem
@Override
protected void collectInformationWithProgress(@NotNull final ProgressIndicator progress) {
- if (!Registry.is("wolf.the.problem.solver", true)) return;
+ if (!Registry.is("wolf.the.problem.solver")) return;
final WolfTheProblemSolver solver = WolfTheProblemSolver.getInstance(myProject);
if (solver instanceof WolfTheProblemSolverImpl) {
((WolfTheProblemSolverImpl)solver).startCheckingIfVincentSolvedProblemsYet(progress, this);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
index c27ce400049e..05a1e01c6aa1 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
@@ -261,10 +261,20 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
public void showJavaDocInfo(final Editor editor, @Nullable final PsiFile file, boolean requestFocus) {
- showJavaDocInfo(editor, file, requestFocus, true);
+ showJavaDocInfo(editor, file, requestFocus, null);
}
- private void showJavaDocInfo(final Editor editor, @Nullable final PsiFile file, boolean requestFocus, final boolean autoupdate) {
+ public void showJavaDocInfo(final Editor editor,
+ @Nullable final PsiFile file,
+ boolean requestFocus,
+ final Runnable closeCallback) {
+ showJavaDocInfo(editor, file, requestFocus, true, closeCallback);
+ }
+
+ private void showJavaDocInfo(final Editor editor,
+ @Nullable final PsiFile file,
+ boolean requestFocus,
+ final boolean autoupdate, @Nullable final Runnable closeCallback) {
myEditor = editor;
final Project project = getProject(file);
PsiDocumentManager.getInstance(project).commitAllDocuments();
@@ -314,7 +324,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return;
}
if (lookupIteObject instanceof PsiElement) {
- doShowJavaDocInfo((PsiElement)lookupIteObject, false, this, originalElement, autoupdate);
+ doShowJavaDocInfo((PsiElement)lookupIteObject, false, this, originalElement, autoupdate, closeCallback);
return;
}
@@ -337,12 +347,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
}
else {
- doShowJavaDocInfo(element, false, this, originalElement, autoupdate);
+ doShowJavaDocInfo(element, false, this, originalElement, autoupdate, closeCallback);
}
}
};
- doShowJavaDocInfo(element, requestFocus, updateProcessor, originalElement, autoupdate);
+ doShowJavaDocInfo(element, requestFocus, updateProcessor, originalElement, autoupdate, closeCallback);
}
public PsiElement findTargetElement(Editor editor, PsiFile file) {
@@ -969,7 +979,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Override
protected void doUpdateComponent(Editor editor, PsiFile psiFile) {
- showJavaDocInfo(editor, psiFile, false, true);
+ showJavaDocInfo(editor, psiFile, false, true, null);
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CopyHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CopyHandler.java
index 2a46c08fc2dd..b738bafb038a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CopyHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CopyHandler.java
@@ -19,12 +19,12 @@ package com.intellij.codeInsight.editorActions;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.editor.actions.CopyAction;
import com.intellij.openapi.editor.actions.EditorActionUtil;
import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.editor.impl.EditorCopyPasteHelperImpl;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
@@ -92,7 +92,7 @@ public class CopyHandler extends EditorActionHandler {
}
String text = editor.getCaretModel().supportsMultipleCarets()
- ? CopyPasteSupport.getSelectedTextForClipboard(editor, transferableDatas)
+ ? EditorCopyPasteHelperImpl.getSelectedTextForClipboard(editor, transferableDatas)
: selectionModel.getSelectedText();
String rawText = TextBlockTransferable.convertLineSeparators(text, "\n", transferableDatas);
String escapedText = null;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/IndentingBackspaceHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/IndentingBackspaceHandler.java
index 345cb80bae69..17916e008501 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/IndentingBackspaceHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/IndentingBackspaceHandler.java
@@ -17,15 +17,22 @@ package com.intellij.codeInsight.editorActions;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeStyle.CodeStyleFacade;
+import com.intellij.formatting.*;
+import com.intellij.lang.LanguageFormatting;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.codeStyle.CodeStyleSettings;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -36,40 +43,75 @@ import org.jetbrains.annotations.NotNull;
public class IndentingBackspaceHandler extends BackspaceHandlerDelegate {
private static final Logger LOG = Logger.getInstance(IndentingBackspaceHandler.class);
+ private boolean isApplicable;
private boolean caretWasAtLineStart;
+ private String precalculatedSpacing;
@Override
public void beforeCharDeleted(char c, PsiFile file, Editor editor) {
- caretWasAtLineStart = editor.getCaretModel().getLogicalPosition().column == 0;
- }
-
- @Override
- public boolean charDeleted(char c, PsiFile file, Editor editor) {
if (CodeInsightSettings.getInstance().SMART_BACKSPACE != CodeInsightSettings.AUTOINDENT || !StringUtil.isWhiteSpace(c)) {
- return false;
+ isApplicable = false;
+ return;
}
LanguageCodeStyleSettingsProvider codeStyleSettingsProvider = LanguageCodeStyleSettingsProvider.forLanguage(file.getLanguage());
if (codeStyleSettingsProvider != null && codeStyleSettingsProvider.isIndentBasedLanguageSemantics()) {
+ isApplicable = false;
+ return;
+ }
+ Document document = editor.getDocument();
+ CharSequence charSequence = document.getCharsSequence();
+ CaretModel caretModel = editor.getCaretModel();
+ int caretOffset = caretModel.getOffset();
+ LogicalPosition pos = caretModel.getLogicalPosition();
+ isApplicable = true;
+ caretWasAtLineStart = pos.column == 0;
+ precalculatedSpacing = null;
+ if (caretWasAtLineStart && pos.line > 0 && caretOffset < charSequence.length() && !StringUtil.isWhiteSpace(charSequence.charAt(caretOffset))) {
+ int prevLineEnd = document.getLineEndOffset(pos.line - 1);
+ if (prevLineEnd > 0 && !StringUtil.isWhiteSpace(charSequence.charAt(prevLineEnd - 1))) {
+ PsiDocumentManager.getInstance(file.getProject()).commitDocument(document);
+ precalculatedSpacing = getSpacing(file, caretOffset);
+ }
+ }
+ }
+
+ @Override
+ public boolean charDeleted(char c, PsiFile file, Editor editor) {
+ if (!isApplicable) {
return false;
}
+ Project project = file.getProject();
Document document = editor.getDocument();
+ CaretModel caretModel = editor.getCaretModel();
- int caretOffset = editor.getCaretModel().getOffset();
+ int caretOffset = caretModel.getOffset();
int offset = CharArrayUtil.shiftForward(document.getCharsSequence(), caretOffset, " \t");
int beforeWhitespaceOffset = CharArrayUtil.shiftBackward(document.getCharsSequence(), offset - 1, " \t") + 1;
- LogicalPosition logicalPosition = caretOffset < offset ? editor.offsetToLogicalPosition(offset) : editor.getCaretModel().getLogicalPosition();
+ LogicalPosition logicalPosition = caretOffset < offset ? editor.offsetToLogicalPosition(offset) : caretModel.getLogicalPosition();
int lineStartOffset = document.getLineStartOffset(logicalPosition.line);
if (lineStartOffset < beforeWhitespaceOffset) {
- if (caretWasAtLineStart && beforeWhitespaceOffset < offset) {
- document.deleteString(beforeWhitespaceOffset, offset);
- return true;
+ if (caretWasAtLineStart && beforeWhitespaceOffset <= offset) {
+ String spacing;
+ if (precalculatedSpacing == null) {
+ PsiDocumentManager.getInstance(project).commitDocument(document);
+ spacing = getSpacing(file, offset);
+ }
+ else {
+ spacing = precalculatedSpacing;
+ }
+ if (beforeWhitespaceOffset < offset || !spacing.isEmpty()) {
+ document.replaceString(beforeWhitespaceOffset, offset, spacing);
+ caretModel.moveToOffset(beforeWhitespaceOffset + spacing.length());
+ return true;
+ }
}
return false;
}
- CodeStyleFacade codeStyleFacade = CodeStyleFacade.getInstance(editor.getProject());
- String indent = codeStyleFacade.getLineIndent(document, lineStartOffset);
+ PsiDocumentManager.getInstance(project).commitDocument(document);
+ CodeStyleFacade codeStyleFacade = CodeStyleFacade.getInstance(project);
+ String indent = codeStyleFacade.getLineIndent(document, offset);
if (indent == null) {
return false;
}
@@ -79,7 +121,7 @@ public class IndentingBackspaceHandler extends BackspaceHandlerDelegate {
if (logicalPosition.column == targetColumn) {
if (caretOffset < offset) {
- editor.getCaretModel().moveToLogicalPosition(logicalPosition);
+ caretModel.moveToLogicalPosition(logicalPosition);
return true;
}
return false;
@@ -87,7 +129,7 @@ public class IndentingBackspaceHandler extends BackspaceHandlerDelegate {
if (caretWasAtLineStart || logicalPosition.column > targetColumn) {
document.replaceString(lineStartOffset, offset, indent);
- editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(logicalPosition.line, targetColumn));
+ caretModel.moveToLogicalPosition(new LogicalPosition(logicalPosition.line, targetColumn));
return true;
}
@@ -100,12 +142,13 @@ public class IndentingBackspaceHandler extends BackspaceHandlerDelegate {
int targetOffset = CharArrayUtil.shiftBackward(document.getCharsSequence(), prevLineEndOffset - 1, " \t") + 1;
if (prevLineStartOffset < targetOffset) {
- document.deleteString(targetOffset, offset);
- editor.getCaretModel().moveToOffset(targetOffset);
+ String spacing = getSpacing(file, offset);
+ document.replaceString(targetOffset, offset, spacing);
+ caretModel.moveToOffset(targetOffset + spacing.length());
}
else {
document.replaceString(prevLineStartOffset, offset, indent);
- editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(logicalPosition.line - 1, targetColumn));
+ caretModel.moveToLogicalPosition(new LogicalPosition(logicalPosition.line - 1, targetColumn));
}
return true;
}
@@ -132,4 +175,15 @@ public class IndentingBackspaceHandler extends BackspaceHandlerDelegate {
}
return width;
}
+
+ private static String getSpacing(PsiFile file, int offset) {
+ FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
+ if (builder == null) {
+ return "";
+ }
+ CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(file.getProject());
+ FormattingModel model = builder.createModel(file, settings);
+ int spacing = FormatterEx.getInstance().getSpacingForBlockAtOffset(model, offset);
+ return StringUtil.repeatSymbol(' ', spacing);
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
index bb21eac69ecd..ba4768f73099 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/TypedHandler.java
@@ -148,14 +148,17 @@ public class TypedHandler extends TypedActionHandlerBase {
return;
}
+ final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
+ final Document originalDocument = originalEditor.getDocument();
originalEditor.getCaretModel().runForEachCaret(new CaretAction() {
@Override
public void perform(Caret caret) {
- PsiDocumentManager.getInstance(project)
- .doPostponedOperationsAndUnblockDocument(originalEditor.getDocument()); // to clean up after previous caret processing
+ if (psiDocumentManager.isDocumentBlockedByPsi(originalDocument)) {
+ psiDocumentManager.doPostponedOperationsAndUnblockDocument(originalDocument); // to clean up after previous caret processing
+ }
Editor editor = injectedEditorIfCharTypedIsSignificant(charTyped, originalEditor, originalFile);
- PsiFile file = editor == originalEditor ? originalFile : PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
+ PsiFile file = editor == originalEditor ? originalFile : psiDocumentManager.getPsiFile(editor.getDocument());
final TypedHandlerDelegate[] delegates = Extensions.getExtensions(TypedHandlerDelegate.EP_NAME);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
index 3a1f04b80414..9a71909fcca8 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java
@@ -372,31 +372,34 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
checkValid();
CollectionListModel<LookupElement> listModel = getListModel();
- synchronized (myList) {
- Pair<List<LookupElement>, Integer> pair = myPresentableArranger.arrangeItems(this, onExplicitAction || reused);
- List<LookupElement> items = pair.first;
- Integer toSelect = pair.second;
- if (toSelect == null || toSelect < 0 || items.size() > 0 && toSelect >= items.size()) {
- LOG.error("Arranger " + myPresentableArranger + " returned invalid selection index=" + toSelect + "; items=" + items);
- }
-
- myOffsets.checkMinPrefixLengthChanges(items, this);
- List<LookupElement> oldModel = listModel.toList();
- listModel.removeAll();
- if (!items.isEmpty()) {
- listModel.add(items);
- }
- else {
- addEmptyItem(listModel);
- }
+ Pair<List<LookupElement>, Integer> pair;
+ synchronized (myList) {
+ pair = myPresentableArranger.arrangeItems(this, onExplicitAction || reused);
+ }
+
+ List<LookupElement> items = pair.first;
+ Integer toSelect = pair.second;
+ if (toSelect == null || toSelect < 0 || items.size() > 0 && toSelect >= items.size()) {
+ LOG.error("Arranger " + myPresentableArranger + " returned invalid selection index=" + toSelect + "; items=" + items);
+ toSelect = 0;
+ }
- updateListHeight(listModel);
+ myOffsets.checkMinPrefixLengthChanges(items, this);
+ List<LookupElement> oldModel = listModel.toList();
- myList.setSelectedIndex(toSelect);
- return !ContainerUtil.equalsIdentity(oldModel, items);
+ listModel.removeAll();
+ if (!items.isEmpty()) {
+ listModel.add(items);
}
+ else {
+ addEmptyItem(listModel);
+ }
+
+ updateListHeight(listModel);
+ myList.setSelectedIndex(toSelect);
+ return !ContainerUtil.equalsIdentity(oldModel, items);
}
private boolean isSelectionVisible() {
@@ -566,7 +569,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
public void perform(Caret caret) {
EditorModificationUtil.deleteSelectedText(hostEditor);
final int caretOffset = hostEditor.getCaretModel().getOffset();
- int lookupStart = caretOffset - prefix;
+ int lookupStart = Math.max(caretOffset - prefix, 0);
int len = hostEditor.getDocument().getTextLength();
LOG.assertTrue(lookupStart >= 0 && lookupStart <= len,
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java
index 3c0e84a11656..3617c944e888 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/NavigationUtil.java
@@ -19,30 +19,46 @@ package com.intellij.codeInsight.navigation;
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
import com.intellij.ide.util.EditSourceUtil;
import com.intellij.ide.util.PsiElementListCellRenderer;
+import com.intellij.navigation.GotoRelatedItem;
+import com.intellij.navigation.GotoRelatedProvider;
import com.intellij.navigation.NavigationItem;
+import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.fileEditor.impl.EditorHistoryManager;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
+import com.intellij.openapi.ui.popup.PopupStep;
+import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
+import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.ElementBase;
import com.intellij.psi.search.PsiElementProcessor;
-import com.intellij.ui.JBListWithHintProvider;
+import com.intellij.ui.*;
+import com.intellij.ui.popup.list.ListPopupImpl;
+import com.intellij.ui.popup.list.PopupListElementRenderer;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.util.*;
+import java.util.List;
/**
* @author ven
@@ -220,4 +236,242 @@ public final class NavigationUtil {
}
return attributes;
}
+
+ @NotNull
+ public static JBPopup getRelatedItemsPopup(final List<? extends GotoRelatedItem> items, String title) {
+ Object[] elements = new Object[items.size()];
+ //todo[nik] move presentation logic to GotoRelatedItem class
+ final Map<PsiElement, GotoRelatedItem> itemsMap = new HashMap<PsiElement, GotoRelatedItem>();
+ for (int i = 0; i < items.size(); i++) {
+ GotoRelatedItem item = items.get(i);
+ elements[i] = item.getElement() != null ? item.getElement() : item;
+ itemsMap.put(item.getElement(), item);
+ }
+
+ return getPsiElementPopup(elements, itemsMap, title, new Processor<Object>() {
+ @Override
+ public boolean process(Object element) {
+ if (element instanceof PsiElement) {
+ //noinspection SuspiciousMethodCalls
+ itemsMap.get(element).navigate();
+ }
+ else {
+ ((GotoRelatedItem)element).navigate();
+ }
+ return true;
+ }
+ }
+ );
+ }
+
+ private static JBPopup getPsiElementPopup(final Object[] elements, final Map<PsiElement, GotoRelatedItem> itemsMap,
+ final String title, final Processor<Object> processor) {
+
+ final Ref<Boolean> hasMnemonic = Ref.create(false);
+ final DefaultPsiElementCellRenderer renderer = new DefaultPsiElementCellRenderer() {
+ {
+ setFocusBorderEnabled(false);
+ }
+
+ @Override
+ public String getElementText(PsiElement element) {
+ String customName = itemsMap.get(element).getCustomName();
+ return (customName != null ? customName : super.getElementText(element));
+ }
+
+ @Override
+ protected Icon getIcon(PsiElement element) {
+ Icon customIcon = itemsMap.get(element).getCustomIcon();
+ return customIcon != null ? customIcon : super.getIcon(element);
+ }
+
+ @Override
+ public String getContainerText(PsiElement element, String name) {
+ String customContainerName = itemsMap.get(element).getCustomContainerName();
+
+ if (customContainerName != null) {
+ return customContainerName;
+ }
+ PsiFile file = element.getContainingFile();
+ return file != null && !getElementText(element).equals(file.getName())
+ ? "(" + file.getName() + ")"
+ : null;
+ }
+
+ @Override
+ protected DefaultListCellRenderer getRightCellRenderer(Object value) {
+ return null;
+ }
+
+ @Override
+ protected boolean customizeNonPsiElementLeftRenderer(ColoredListCellRenderer renderer,
+ JList list,
+ Object value,
+ int index,
+ boolean selected,
+ boolean hasFocus) {
+ final GotoRelatedItem item = (GotoRelatedItem)value;
+ Color color = list.getForeground();
+ final SimpleTextAttributes nameAttributes = new SimpleTextAttributes(Font.PLAIN, color);
+ final String name = item.getCustomName();
+ if (name == null) return false;
+ renderer.append(name, nameAttributes);
+ renderer.setIcon(item.getCustomIcon());
+ return true;
+ }
+
+ @Override
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ final JPanel component = (JPanel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ if (!hasMnemonic.get()) return component;
+
+ final JPanel panelWithMnemonic = new JPanel(new BorderLayout());
+ final int mnemonic = getMnemonic(value, itemsMap);
+ final JLabel label = new JLabel("");
+ if (mnemonic != -1) {
+ label.setText(mnemonic + ".");
+ label.setDisplayedMnemonicIndex(0);
+ }
+ label.setPreferredSize(new JLabel("8.").getPreferredSize());
+
+ final JComponent leftRenderer = (JComponent)component.getComponents()[0];
+ component.remove(leftRenderer);
+ panelWithMnemonic.setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 0));
+ panelWithMnemonic.setBackground(leftRenderer.getBackground());
+ label.setBackground(leftRenderer.getBackground());
+ panelWithMnemonic.add(label, BorderLayout.WEST);
+ panelWithMnemonic.add(leftRenderer, BorderLayout.CENTER);
+ component.add(panelWithMnemonic);
+ return component;
+ }
+ };
+ final ListPopupImpl popup = new ListPopupImpl(new BaseListPopupStep<Object>(title, Arrays.asList(elements)) {
+ @Override
+ public boolean isSpeedSearchEnabled() {
+ return true;
+ }
+
+ @Override
+ public String getIndexedString(Object value) {
+ if (value instanceof GotoRelatedItem) {
+ //noinspection ConstantConditions
+ return ((GotoRelatedItem)value).getCustomName();
+ }
+ final PsiElement element = (PsiElement)value;
+ return renderer.getElementText(element) + " " + renderer.getContainerText(element, null);
+ }
+
+ @Override
+ public PopupStep onChosen(Object selectedValue, boolean finalChoice) {
+ processor.process(selectedValue);
+ return super.onChosen(selectedValue, finalChoice);
+ }
+ }) {
+ };
+ popup.getList().setCellRenderer(new PopupListElementRenderer(popup) {
+ Map<Object, String> separators = new HashMap<Object, String>();
+ {
+ final ListModel model = popup.getList().getModel();
+ String current = null;
+ boolean hasTitle = false;
+ for (int i = 0; i < model.getSize(); i++) {
+ final Object element = model.getElementAt(i);
+ final GotoRelatedItem item = itemsMap.get(element);
+ if (item != null && !StringUtil.equals(current, item.getGroup())) {
+ current = item.getGroup();
+ separators.put(element, current);
+ if (!hasTitle && !StringUtil.isEmpty(current)) {
+ hasTitle = true;
+ }
+ }
+ }
+
+ if (!hasTitle) {
+ separators.remove(model.getElementAt(0));
+ }
+ }
+ @Override
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ final Component component = renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ final String separator = separators.get(value);
+
+ if (separator != null) {
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.add(component, BorderLayout.CENTER);
+ final SeparatorWithText sep = new SeparatorWithText() {
+ @Override
+ protected void paintComponent(Graphics g) {
+ g.setColor(new JBColor(Color.WHITE, UIUtil.getSeparatorColor()));
+ g.fillRect(0,0,getWidth(), getHeight());
+ super.paintComponent(g);
+ }
+ };
+ sep.setCaption(separator);
+ panel.add(sep, BorderLayout.NORTH);
+ return panel;
+ }
+ return component;
+ }
+ });
+
+ popup.setMinimumSize(new Dimension(200, -1));
+
+ for (Object item : elements) {
+ final int mnemonic = getMnemonic(item, itemsMap);
+ if (mnemonic != -1) {
+ final Action action = createNumberAction(mnemonic, popup, itemsMap, processor);
+ popup.registerAction(mnemonic + "Action", KeyStroke.getKeyStroke(String.valueOf(mnemonic)), action);
+ popup.registerAction(mnemonic + "Action", KeyStroke.getKeyStroke("NUMPAD" + String.valueOf(mnemonic)), action);
+ hasMnemonic.set(true);
+ }
+ }
+ return popup;
+ }
+
+ private static Action createNumberAction(final int mnemonic,
+ final ListPopupImpl listPopup,
+ final Map<PsiElement, GotoRelatedItem> itemsMap,
+ final Processor<Object> processor) {
+ return new AbstractAction() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ for (final Object item : listPopup.getListStep().getValues()) {
+ if (getMnemonic(item, itemsMap) == mnemonic) {
+ listPopup.setFinalRunnable(new Runnable() {
+ @Override
+ public void run() {
+ processor.process(item);
+ }
+ });
+ listPopup.closeOk(null);
+ }
+ }
+ }
+ };
+ }
+
+ private static int getMnemonic(Object item, Map<PsiElement, GotoRelatedItem> itemsMap) {
+ return (item instanceof GotoRelatedItem ? (GotoRelatedItem)item : itemsMap.get((PsiElement)item)).getMnemonic();
+ }
+
+ @NotNull
+ public static List<GotoRelatedItem> collectRelatedItems(@NotNull PsiElement contextElement, @Nullable DataContext dataContext) {
+ Set<GotoRelatedItem> items = ContainerUtil.newLinkedHashSet();
+ for (GotoRelatedProvider provider : Extensions.getExtensions(GotoRelatedProvider.EP_NAME)) {
+ items.addAll(provider.getItems(contextElement));
+ if (dataContext != null) {
+ items.addAll(provider.getItems(dataContext));
+ }
+ }
+ GotoRelatedItem[] result = items.toArray(new GotoRelatedItem[items.size()]);
+ Arrays.sort(result, new Comparator<GotoRelatedItem>() {
+ @Override
+ public int compare(GotoRelatedItem i1, GotoRelatedItem i2) {
+ String o1 = i1.getGroup();
+ String o2 = i2.getGroup();
+ return StringUtil.isEmpty(o1) ? 1 : StringUtil.isEmpty(o2) ? -1 : o1.compareTo(o2);
+ }
+ });
+ return Arrays.asList(result);
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/problems/MockWolfTheProblemSolver.java b/platform/lang-impl/src/com/intellij/codeInsight/problems/MockWolfTheProblemSolver.java
index eeb5e04b8aab..4ea365f34b0c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/problems/MockWolfTheProblemSolver.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/problems/MockWolfTheProblemSolver.java
@@ -44,6 +44,11 @@ public class MockWolfTheProblemSolver extends WolfTheProblemSolver {
}
@Override
+ public void weHaveGotNonIgnorableProblems(@NotNull VirtualFile virtualFile, @NotNull List<Problem> problems) {
+ if (myDelegate != null) myDelegate.weHaveGotNonIgnorableProblems(virtualFile, problems);
+ }
+
+ @Override
public boolean hasProblemFilesBeneath(@NotNull final Condition<VirtualFile> condition) {
return false;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java
index 45b4532713c4..fab185e6ddc0 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/problems/WolfTheProblemSolverImpl.java
@@ -413,6 +413,12 @@ public class WolfTheProblemSolverImpl extends WolfTheProblemSolver {
public void weHaveGotProblems(@NotNull final VirtualFile virtualFile, @NotNull List<Problem> problems) {
if (problems.isEmpty()) return;
if (!isToBeHighlighted(virtualFile)) return;
+ weHaveGotNonIgnorableProblems(virtualFile, problems);
+ }
+
+ @Override
+ public void weHaveGotNonIgnorableProblems(@NotNull VirtualFile virtualFile, @NotNull List<Problem> problems) {
+ if (problems.isEmpty()) return;
boolean fireListener = false;
synchronized (myProblems) {
ProblemFileInfo storedProblems = myProblems.get(virtualFile);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
index 516ed9118c8c..0c838cd05ec5 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
@@ -212,8 +212,11 @@ public class TemplateState implements Disposable {
if (variableName.equals(TemplateImpl.END)) {
return new TextResult("");
}
- if (myPredefinedVariableValues != null && myPredefinedVariableValues.containsKey(variableName)) {
- return new TextResult(myPredefinedVariableValues.get(variableName));
+ if (myPredefinedVariableValues != null) {
+ String text = myPredefinedVariableValues.get(variableName);
+ if (text != null) {
+ return new TextResult(text);
+ }
}
CharSequence text = myDocument.getCharsSequence();
int segmentNumber = myTemplate.getVariableSegmentNumber(variableName);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ExpressionPostfixTemplateWithChooser.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ChooserExpressionSelector.java
index f6b0cedae31e..2989f0d0c97c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ExpressionPostfixTemplateWithChooser.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ChooserExpressionSelector.java
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.template.postfix.templates;
+
import com.intellij.codeInsight.unwrap.ScopeHighlighter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
@@ -30,45 +31,43 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
- * @author ignatov
+ * See {@link PostfixTemplateExpressionSelector} for description
*/
-public abstract class ExpressionPostfixTemplateWithChooser extends PostfixTemplate {
+public class ChooserExpressionSelector implements PostfixTemplateExpressionSelector {
@NotNull
- protected final PostfixTemplatePsiInfoBase myInfo;
+ private final Condition<PsiElement> myCondition;
- protected ExpressionPostfixTemplateWithChooser(@NotNull String name, @NotNull String example, @NotNull PostfixTemplatePsiInfoBase info) {
- super(name, example);
- myInfo = info;
+ public ChooserExpressionSelector(@NotNull Condition<PsiElement> condition) {
+ myCondition = condition;
}
- protected ExpressionPostfixTemplateWithChooser(@NotNull String name,
- @NotNull String key,
- @NotNull String example,
- @NotNull PostfixTemplatePsiInfoBase info) {
- super(name, key, example);
- myInfo = info;
- }
- @Override
- public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- return !getExpressions(context, copyDocument, newOffset).isEmpty();
+ public boolean hasExpression(@NotNull final PostfixTemplateWithExpressionSelector postfixTemplate,
+ @NotNull PsiElement context,
+ @NotNull Document copyDocument,
+ int newOffset) {
+ return !getExpressions(postfixTemplate, context, copyDocument, newOffset).isEmpty();
}
- @Override
- public void expand(@NotNull PsiElement context, @NotNull final Editor editor) {
- List<PsiElement> expressions = getExpressions(context, editor.getDocument(), editor.getCaretModel().getOffset());
+ public void expandTemplate(@NotNull final PostfixTemplateWithExpressionSelector postfixTemplate,
+ @NotNull PsiElement context,
+ @NotNull final Editor editor) {
+ List<PsiElement> expressions =
+ getExpressions(postfixTemplate, context, editor.getDocument(), editor.getCaretModel().getOffset());
if (expressions.isEmpty()) {
PostfixTemplatesUtils.showErrorHint(context.getProject(), editor);
}
else if (expressions.size() == 1) {
- doIt(editor, expressions.get(0));
+ postfixTemplate.expandForChooseExpression(expressions.get(0), editor);
}
else {
if (ApplicationManager.getApplication().isUnitTestMode()) {
- doIt(editor, expressions.get(expressions.size() - 1));
+ PsiElement item = ContainerUtil.getLastItem(expressions);
+ assert item != null;
+ postfixTemplate.expandForChooseExpression(item, editor);
return;
}
@@ -81,22 +80,25 @@ public abstract class ExpressionPostfixTemplateWithChooser extends PostfixTempla
public void run() {
CommandProcessor.getInstance().executeCommand(e.getProject(), new Runnable() {
public void run() {
- doIt(editor, e);
+ postfixTemplate.expandForChooseExpression(e, editor);
}
}, "Expand postfix template", PostfixLiveTemplate.POSTFIX_TEMPLATE_ID);
}
});
}
},
- myInfo.getRenderer(),
+ postfixTemplate.getPsiInfo().getRenderer(),
"Expressions", 0, ScopeHighlighter.NATURAL_RANGER
);
}
}
@NotNull
- protected List<PsiElement> getExpressions(@NotNull PsiElement context, @NotNull Document document, final int offset) {
- List<PsiElement> possibleExpressions = myInfo.getExpressions(context, document, offset);
+ private List<PsiElement> getExpressions(@NotNull PostfixTemplateWithExpressionSelector postfixTemplate,
+ @NotNull PsiElement context,
+ @NotNull Document document,
+ final int offset) {
+ List<PsiElement> possibleExpressions = postfixTemplate.getPsiInfo().getExpressions(context, document, offset);
List<PsiElement> expressions = ContainerUtil.filter(possibleExpressions,
new Condition<PsiElement>() {
@Override
@@ -105,19 +107,13 @@ public abstract class ExpressionPostfixTemplateWithChooser extends PostfixTempla
}
}
);
- return ContainerUtil.filter(expressions.isEmpty() ? maybeTopmostExpression(context) : expressions, getTypeCondition());
+ return ContainerUtil
+ .filter(expressions.isEmpty() ? maybeTopmostExpression(postfixTemplate, context) : expressions, myCondition);
}
- @NotNull
- @SuppressWarnings("unchecked")
- protected Condition<PsiElement> getTypeCondition() {
- return Condition.TRUE;
- }
@NotNull
- private List<PsiElement> maybeTopmostExpression(@NotNull PsiElement context) {
- return ContainerUtil.createMaybeSingletonList(myInfo.getTopmostExpression(context));
+ private static List<PsiElement> maybeTopmostExpression(@NotNull PostfixTemplateWithExpressionSelector postfixTemplate, @NotNull PsiElement context) {
+ return ContainerUtil.createMaybeSingletonList(postfixTemplate.getPsiInfo().getTopmostExpression(context));
}
-
- protected abstract void doIt(@NotNull Editor editor, @NotNull PsiElement expression);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/NotPostfixTemplate.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/NotPostfixTemplate.java
index 9c1d9c66b94d..3944cd930af0 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/NotPostfixTemplate.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/NotPostfixTemplate.java
@@ -16,26 +16,34 @@
package com.intellij.codeInsight.template.postfix.templates;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
-public class NotPostfixTemplate extends ExpressionPostfixTemplateWithChooser {
+import static com.intellij.codeInsight.template.postfix.templates.PostfixTemplatesUtils.selectorWithChooser;
- public NotPostfixTemplate(@NotNull PostfixTemplatePsiInfoBase info) {
- super("not", "!expr", info);
+public class NotPostfixTemplate extends PostfixTemplateWithExpressionSelector {
+
+ public NotPostfixTemplate(@NotNull PostfixTemplatePsiInfo info, @NotNull Condition<PsiElement> typeChecker) {
+ super("not", "!expr", info, selectorWithChooser(typeChecker));
}
+ public NotPostfixTemplate(@NotNull PostfixTemplatePsiInfo info) {
+ super("not", "!expr", info, selectorWithChooser());
+ }
public NotPostfixTemplate(@NotNull String name,
@NotNull String key,
@NotNull String example,
- @NotNull PostfixTemplatePsiInfoBase info) {
- super(name, key, example, info);
+ @NotNull PostfixTemplatePsiInfo info,
+ @NotNull Condition<PsiElement> typeChecker
+ ) {
+ super(name, key, example, info, selectorWithChooser(typeChecker));
}
@Override
- protected void doIt(@NotNull Editor editor, @NotNull PsiElement expression) {
- PsiElement element = myInfo.getNegatedExpression(expression);
+ protected void expandForChooseExpression(@NotNull PsiElement expression, @NotNull Editor editor) {
+ PsiElement element = myPsiInfo.getNegatedExpression(expression);
expression.replace(element);
}
} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedPostfixTemplate.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedPostfixTemplate.java
index 9a5d03a9359c..3f1dd1143348 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedPostfixTemplate.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/ParenthesizedPostfixTemplate.java
@@ -16,16 +16,25 @@
package com.intellij.codeInsight.template.postfix.templates;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
-public class ParenthesizedPostfixTemplate extends ExpressionPostfixTemplateWithChooser {
- public ParenthesizedPostfixTemplate(PostfixTemplatePsiInfoBase psiInfo) {
- super("par", "(expr)", psiInfo);
+import static com.intellij.codeInsight.template.postfix.templates.PostfixTemplatesUtils.selectorWithChooser;
+
+public class ParenthesizedPostfixTemplate extends PostfixTemplateWithExpressionSelector {
+
+ public ParenthesizedPostfixTemplate(PostfixTemplatePsiInfo psiInfo, Condition<PsiElement> condition) {
+ super("par", "(expr)", psiInfo, selectorWithChooser(condition));
+ }
+
+
+ public ParenthesizedPostfixTemplate(PostfixTemplatePsiInfo psiInfo) {
+ super("par", "(expr)", psiInfo, selectorWithChooser());
}
@Override
- protected void doIt(@NotNull Editor editor, @NotNull PsiElement expression) {
- expression.replace(myInfo.createExpression(expression, "(", ")"));
+ protected void expandForChooseExpression(@NotNull PsiElement expression, @NotNull Editor editor) {
+ expression.replace(myPsiInfo.createExpression(expression, "(", ")"));
}
} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateExpressionSelector.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateExpressionSelector.java
new file mode 100644
index 000000000000..6b5d559da1de
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateExpressionSelector.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.template.postfix.templates;
+
+
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Interface provides method used in {@link com.intellij.codeInsight.template.postfix.templates.PostfixTemplateWithExpressionSelector}
+ *
+ * You should implement the interface if you have non-trivial logic how to determine expression for next processing in postfix template
+ * Otherwise, you can use one of existing simple implementations:
+ *
+ * 1) {@link com.intellij.codeInsight.template.postfix.templates.ChooserExpressionSelector} - The selector get all expression
+ * in the current position and show to user chooser for these expressions.
+ *
+ * 2) {@link com.intellij.codeInsight.template.postfix.templates.TopmostExpressionSelector} - The selector pass to postfix template
+ * top most expression in the current position
+ *
+ *
+ */
+public interface PostfixTemplateExpressionSelector {
+
+ /**
+ * Check that we can select not-null expression(PsiElement) in current context
+ */
+ boolean hasExpression(@NotNull final PostfixTemplateWithExpressionSelector postfixTemplate,
+ @NotNull PsiElement context,
+ @NotNull Document copyDocument,
+ int newOffset);
+
+ /**
+ * Select expression(PsiElement) and call postfixTemplate.expandForChooseExpression for selected expression
+ */
+ void expandTemplate(@NotNull final PostfixTemplateWithExpressionSelector postfixTemplate,
+ @NotNull PsiElement context,
+ @NotNull final Editor editor);
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatePsiInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatePsiInfo.java
index 8f4716787453..6664d6404d64 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatePsiInfo.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatePsiInfo.java
@@ -16,25 +16,42 @@
package com.intellij.codeInsight.template.postfix.templates;
+import com.intellij.openapi.editor.Document;
import com.intellij.psi.PsiElement;
+import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public interface PostfixTemplatePsiInfo {
+import java.util.List;
+
+public abstract class PostfixTemplatePsiInfo {
@NotNull
- PsiElement createStatement(@NotNull PsiElement context,
- @NotNull String prefix,
- @NotNull String suffix);
+ public abstract PsiElement createStatement(@NotNull PsiElement context,
+ @NotNull String prefix,
+ @NotNull String suffix);
@NotNull
- PsiElement createExpression(@NotNull PsiElement context,
- @NotNull String prefix,
- @NotNull String suffix);
+ public abstract PsiElement createExpression(@NotNull PsiElement context,
+ @NotNull String prefix,
+ @NotNull String suffix);
@Nullable
- PsiElement getTopmostExpression(@NotNull PsiElement element);
+ public abstract PsiElement getTopmostExpression(@NotNull PsiElement element);
+
+ @NotNull
+ public abstract PsiElement getNegatedExpression(@NotNull PsiElement element);
+
+ @NotNull
+ public abstract List<PsiElement> getExpressions(@NotNull PsiElement context, @NotNull Document document, int offset);
@NotNull
- PsiElement getNegatedExpression(@NotNull PsiElement element);
+ public Function<PsiElement, String> getRenderer() {
+ return new Function<PsiElement, String>() {
+ @Override
+ public String fun(@NotNull PsiElement element) {
+ return element.getText();
+ }
+ };
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateWithExpressionSelector.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateWithExpressionSelector.java
new file mode 100644
index 000000000000..d7cfbafdf7a8
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplateWithExpressionSelector.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.template.postfix.templates;
+
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+import static com.intellij.codeInsight.template.postfix.templates.PostfixTemplatesUtils.selectorTopmost;
+
+public abstract class PostfixTemplateWithExpressionSelector extends PostfixTemplate {
+
+ @NotNull
+ protected final PostfixTemplatePsiInfo myPsiInfo;
+ @NotNull
+ private final PostfixTemplateExpressionSelector mySelector;
+
+ protected PostfixTemplateWithExpressionSelector(@NotNull String name,
+ @NotNull String key,
+ @NotNull String example,
+ @NotNull PostfixTemplatePsiInfo psiInfo,
+ @NotNull PostfixTemplateExpressionSelector selector) {
+ super(name, key, example);
+ myPsiInfo = psiInfo;
+ mySelector = selector;
+ }
+
+
+ protected PostfixTemplateWithExpressionSelector(@NotNull String name,
+ @NotNull String example,
+ @NotNull PostfixTemplatePsiInfo psiInfo,
+ @NotNull PostfixTemplateExpressionSelector selector) {
+ super(name, example);
+ myPsiInfo = psiInfo;
+ mySelector = selector;
+ }
+
+ protected PostfixTemplateWithExpressionSelector(@NotNull String name,
+ @NotNull String example,
+ @NotNull PostfixTemplatePsiInfo psiInfo,
+ @NotNull Condition<PsiElement> typeChecker) {
+ this(name, example, psiInfo, selectorTopmost(typeChecker));
+ }
+
+ protected PostfixTemplateWithExpressionSelector(@NotNull String name,
+ @NotNull String example,
+ @NotNull PostfixTemplatePsiInfo psiInfo) {
+ this(name, example, psiInfo, selectorTopmost());
+ }
+
+
+ @Override
+ public final boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
+ return mySelector.hasExpression(this, context, copyDocument, newOffset);
+ }
+
+ @Override
+ public final void expand(@NotNull PsiElement context, @NotNull Editor editor) {
+ mySelector.expandTemplate(this, context, editor);
+ }
+
+ protected abstract void expandForChooseExpression(@NotNull PsiElement expression, @NotNull Editor editor);
+
+ @NotNull
+ PostfixTemplatePsiInfo getPsiInfo() {
+ return myPsiInfo;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatesUtils.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatesUtils.java
index 877e10b53490..5ff744e3d72a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatesUtils.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixTemplatesUtils.java
@@ -21,6 +21,8 @@ import com.intellij.lang.surroundWith.Surrounder;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Conditions;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.util.CommonRefactoringUtil;
@@ -31,6 +33,22 @@ public abstract class PostfixTemplatesUtils {
private PostfixTemplatesUtils() {
}
+ public static PostfixTemplateExpressionSelector selectorWithChooser() {
+ return selectorWithChooser(Conditions.<PsiElement>alwaysTrue());
+ }
+
+ public static PostfixTemplateExpressionSelector selectorTopmost() {
+ return selectorTopmost(Conditions.<PsiElement>alwaysTrue());
+ }
+
+ public static PostfixTemplateExpressionSelector selectorWithChooser(Condition<PsiElement> condition) {
+ return new ChooserExpressionSelector(condition);
+ }
+
+ public static PostfixTemplateExpressionSelector selectorTopmost(Condition<PsiElement> condition) {
+ return new TopmostExpressionSelector(condition);
+ }
+
@Nullable
public static TextRange surround(@NotNull Surrounder surrounder,
@NotNull Editor editor,
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementWrapPostfixTemplate.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementWrapPostfixTemplate.java
index ed1605d3a9fb..5b5c3624f33b 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementWrapPostfixTemplate.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StatementWrapPostfixTemplate.java
@@ -22,7 +22,7 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
-public abstract class StatementWrapPostfixTemplate extends TypedPostfixTemplate {
+public abstract class StatementWrapPostfixTemplate extends PostfixTemplateWithExpressionSelector {
@SuppressWarnings("unchecked")
protected StatementWrapPostfixTemplate(@NotNull String name,
@@ -39,9 +39,7 @@ public abstract class StatementWrapPostfixTemplate extends TypedPostfixTemplate
}
@Override
- public void expand(@NotNull PsiElement context, @NotNull Editor editor) {
- PsiElement topmostExpression = myPsiInfo.getTopmostExpression(context);
- assert topmostExpression != null;
+ public void expandForChooseExpression(@NotNull PsiElement topmostExpression, @NotNull Editor editor) {
PsiElement parent = topmostExpression.getParent();
PsiElement expression = getWrappedExpression(topmostExpression);
PsiElement replace = parent.replace(expression);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StringBasedPostfixTemplate.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StringBasedPostfixTemplate.java
index 4d6582f071de..9f19b2011a49 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StringBasedPostfixTemplate.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/StringBasedPostfixTemplate.java
@@ -26,7 +26,7 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public abstract class StringBasedPostfixTemplate extends TypedPostfixTemplate {
+public abstract class StringBasedPostfixTemplate extends PostfixTemplateWithExpressionSelector {
public StringBasedPostfixTemplate(@NotNull String name,
@NotNull String example,
@@ -36,10 +36,8 @@ public abstract class StringBasedPostfixTemplate extends TypedPostfixTemplate {
}
@Override
- public final void expand(@NotNull PsiElement context, @NotNull Editor editor) {
- PsiElement expr = myPsiInfo.getTopmostExpression(context);
- assert expr != null;
- Project project = context.getProject();
+ public final void expandForChooseExpression(@NotNull PsiElement expr, @NotNull Editor editor) {
+ Project project = expr.getProject();
Document document = editor.getDocument();
PsiElement elementForRemoving = shouldRemoveParent() ? expr.getParent() : expr;
document.deleteString(elementForRemoving.getTextRange().getStartOffset(), elementForRemoving.getTextRange().getEndOffset());
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/SurroundPostfixTemplateBase.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/SurroundPostfixTemplateBase.java
index 52ad0c4cdde8..29ea4d39ac64 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/SurroundPostfixTemplateBase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/SurroundPostfixTemplateBase.java
@@ -40,11 +40,9 @@ public abstract class SurroundPostfixTemplateBase extends StatementWrapPostfixTe
@Override
- public void expand(@NotNull PsiElement context, @NotNull final Editor editor) {
+ public final void expandForChooseExpression(@NotNull PsiElement context, @NotNull final Editor editor) {
PsiElement topmostExpression = myPsiInfo.getTopmostExpression(context);
- PsiElement expression = getWrappedExpression(topmostExpression);
- assert topmostExpression != null;
- PsiElement replace = topmostExpression.replace(expression);
+ PsiElement replace = getReplacedExpression(topmostExpression);
TextRange range = PostfixTemplatesUtils.surround(getSurrounder(), editor, replace);
if (range != null) {
@@ -52,6 +50,12 @@ public abstract class SurroundPostfixTemplateBase extends StatementWrapPostfixTe
}
}
+ protected PsiElement getReplacedExpression(PsiElement topmostExpression) {
+ PsiElement expression = getWrappedExpression(topmostExpression);
+ assert topmostExpression != null;
+ return topmostExpression.replace(expression);
+ }
+
public boolean isStatement() {
return false;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/TopmostExpressionSelector.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/TopmostExpressionSelector.java
new file mode 100644
index 000000000000..bd6028d2d8d2
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/TopmostExpressionSelector.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.template.postfix.templates;
+
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+
+/**
+ * See {@link PostfixTemplateExpressionSelector} for description
+ */
+public class TopmostExpressionSelector implements PostfixTemplateExpressionSelector {
+
+ @NotNull
+ private final Condition<PsiElement> myCondition;
+
+ public TopmostExpressionSelector(@NotNull Condition<PsiElement> condition) {
+
+ myCondition = condition;
+ }
+
+ @Override
+ public boolean hasExpression(@NotNull PostfixTemplateWithExpressionSelector template,
+ @NotNull PsiElement context,
+ @NotNull Document copyDocument,
+ int newOffset) {
+ PsiElement topmostExpression = template.getPsiInfo().getTopmostExpression(context);
+ return topmostExpression != null && myCondition.value(topmostExpression);
+ }
+
+ @Override
+ public void expandTemplate(@NotNull PostfixTemplateWithExpressionSelector template,
+ @NotNull PsiElement context,
+ @NotNull Editor editor) {
+ PostfixTemplatePsiInfo info = template.getPsiInfo();
+ PsiElement expression = info.getTopmostExpression(context);
+ if (expression == null) {
+ return;
+ }
+ template.expandForChooseExpression(expression, editor);
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/TypedPostfixTemplate.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/TypedPostfixTemplate.java
deleted file mode 100644
index 0d7d424d99a8..000000000000
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/TypedPostfixTemplate.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInsight.template.postfix.templates;
-
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.util.Condition;
-import com.intellij.psi.PsiElement;
-import org.jetbrains.annotations.NotNull;
-
-public abstract class TypedPostfixTemplate extends PostfixTemplate {
-
- protected final PostfixTemplatePsiInfo myPsiInfo;
- protected final Condition<PsiElement> myTypeChecker;
-
- protected TypedPostfixTemplate(@NotNull String name,
- @NotNull String example,
- @NotNull PostfixTemplatePsiInfo psiInfo,
- @NotNull Condition<PsiElement> typeChecker) {
- super(name, example);
- this.myPsiInfo = psiInfo;
- this.myTypeChecker = typeChecker;
- }
-
- @Override
- public boolean isApplicable(@NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) {
- PsiElement topmostExpression = myPsiInfo.getTopmostExpression(context);
- return topmostExpression != null && myTypeChecker.value(topmostExpression);
- }
-}
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java
index 2c934d76bbd5..7ae94888c90d 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java
@@ -64,6 +64,8 @@ public class InspectionManagerEx extends InspectionManagerBase {
@NotNull
@Override
protected ContentManager compute() {
+ ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project);
+ toolWindowManager.registerToolWindow(ToolWindowId.INSPECTION, true, ToolWindowAnchor.BOTTOM, project);
return ContentFactory.SERVICE.getInstance().createContentManager(new TabbedPaneContentUI(), true, project);
}
};
diff --git a/platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java b/platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java
index f19d92f76bcf..b27a939dd57c 100644
--- a/platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java
+++ b/platform/lang-impl/src/com/intellij/execution/ProgramRunnerUtil.java
@@ -74,7 +74,7 @@ public class ProgramRunnerUtil {
}
public static void executeConfiguration(Project project,
- DataContext context,
+ @Nullable DataContext context,
@Nullable RunnerAndConfigurationSettings configuration,
Executor executor,
ExecutionTarget target,
diff --git a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
index 6c0bfffd450e..9aab415d5e70 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/ConsoleHistoryController.java
@@ -45,7 +45,9 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.testFramework.LightVirtualFile;
+import com.intellij.util.ExceptionUtil;
import com.intellij.util.ObjectUtils;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.SafeFileOutputStream;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.xml.XppReader;
@@ -56,7 +58,6 @@ import org.xmlpull.v1.XmlSerializer;
import java.awt.event.KeyEvent;
import java.io.*;
-import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
@@ -65,6 +66,8 @@ import java.util.ListIterator;
*/
public class ConsoleHistoryController {
+ private static final int VERSION = 1;
+
private static final Logger LOG = Logger.getInstance("com.intellij.execution.console.ConsoleHistoryController");
private final LanguageConsoleImpl myConsole;
@@ -394,7 +397,15 @@ public class ConsoleHistoryController {
}
}
catch (Exception ex) {
- LOG.error(ex);
+ //noinspection ThrowableResultOfMethodCallIgnored
+ Throwable cause = ExceptionUtil.getRootCause(ex);
+ if (cause instanceof EOFException) {
+ LOG.warn("Failed to load " + myType + " console history from: " + file.getPath(), ex);
+ return false;
+ }
+ else {
+ LOG.error(ex);
+ }
}
finally {
if (xmlReader != null) {
@@ -423,6 +434,7 @@ public class ConsoleHistoryController {
}
serializer.setOutput(os = new SafeFileOutputStream(file), CharsetToolkit.UTF8);
saveHistory(serializer);
+ serializer.flush();
}
catch (Exception ex) {
LOG.error(ex);
@@ -439,47 +451,58 @@ public class ConsoleHistoryController {
}
@Nullable
- private String loadHistory(final HierarchicalStreamReader in, final String expectedId) {
+ private String loadHistory(HierarchicalStreamReader in, String expectedId) {
if (!in.getNodeName().equals("console-history")) return null;
- final String id = in.getAttribute("id");
+ int version = StringUtil.parseInt(in.getAttribute("version"), 0);
+ String id = in.getAttribute("id");
if (!expectedId.equals(id)) return null;
- final ArrayList<String> entries = new ArrayList<String>();
+ List<String> entries = ContainerUtil.newArrayList();
String consoleContent = null;
while (in.hasMoreChildren()) {
in.moveDown();
if ("history-entry".equals(in.getNodeName())) {
- entries.add(in.getValue());
+ entries.add(StringUtil.notNullize(in.getValue()));
}
else if ("console-content".equals(in.getNodeName())) {
- consoleContent = in.getValue();
+ consoleContent = StringUtil.notNullize(in.getValue());
}
in.moveUp();
}
for (ListIterator<String> iterator = entries.listIterator(entries.size()); iterator.hasPrevious(); ) {
- final String entry = iterator.previous();
+ String entry = iterator.previous();
getModel().addToHistory(entry);
}
return consoleContent;
}
- private void saveHistory(final XmlSerializer out) throws IOException {
+ private void saveHistory(XmlSerializer out) throws IOException {
out.startDocument(CharsetToolkit.UTF8, null);
out.startTag(null, "console-history");
+ out.attribute(null, "version", String.valueOf(VERSION));
out.attribute(null, "id", myId);
- for (String s : getModel().getHistory()) {
- out.startTag(null, "history-entry");
- out.text(s);
- out.endTag(null, "history-entry");
+ try {
+ for (String s : getModel().getHistory()) {
+ textTag(out, "history-entry", s);
+ }
+ String current = myContent;
+ if (StringUtil.isNotEmpty(current)) {
+ textTag(out, "console-content", current);
+ }
}
- String current = myContent;
- if (StringUtil.isNotEmpty(current)) {
- out.startTag(null, "console-content");
- out.text(current);
- out.endTag(null, "console-content");
+ finally {
+ out.endTag(null, "console-history");
+ out.endDocument();
}
- out.endTag(null, "console-history");
- out.endDocument();
}
}
+ private static void textTag(@NotNull XmlSerializer out, @NotNull String tag, @NotNull String text) throws IOException {
+ out.startTag(null, tag);
+ try {
+ out.cdsect(text);
+ }
+ finally {
+ out.endTag(null, tag);
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/execution/console/DuplexConsoleView.java b/platform/lang-impl/src/com/intellij/execution/console/DuplexConsoleView.java
index c760310cd391..87e1323fe607 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/DuplexConsoleView.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/DuplexConsoleView.java
@@ -9,6 +9,7 @@ import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.ui.ObservableConsoleView;
import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -34,6 +35,8 @@ public class DuplexConsoleView<S extends ConsoleView, T extends ConsoleView> ext
private final S myPrimaryConsoleView;
@NotNull
private final T mySecondaryConsoleView;
+ @Nullable
+ private final String myStateStorageKey;
private boolean myPrimary;
@Nullable
@@ -41,25 +44,46 @@ public class DuplexConsoleView<S extends ConsoleView, T extends ConsoleView> ext
@NotNull
private final SwitchDuplexConsoleViewAction mySwitchConsoleAction;
+
public DuplexConsoleView(@NotNull S primaryConsoleView, @NotNull T secondaryConsoleView) {
+ this(primaryConsoleView, secondaryConsoleView, null);
+ }
+
+ public DuplexConsoleView(@NotNull S primaryConsoleView, @NotNull T secondaryConsoleView, @Nullable String stateStorageKey) {
super(new CardLayout());
myPrimaryConsoleView = primaryConsoleView;
mySecondaryConsoleView = secondaryConsoleView;
+ myStateStorageKey = stateStorageKey;
add(myPrimaryConsoleView.getComponent(), PRIMARY_CONSOLE_PANEL);
add(mySecondaryConsoleView.getComponent(), SECONDARY_CONSOLE_PANEL);
- mySwitchConsoleAction = new SwitchDuplexConsoleViewAction(this);
+ mySwitchConsoleAction = new SwitchDuplexConsoleViewAction();
myPrimary = true;
- enableConsole(false);
+ enableConsole(getStoredState());
Disposer.register(this, myPrimaryConsoleView);
Disposer.register(this, mySecondaryConsoleView);
}
- public static <S extends ConsoleView, T extends ConsoleView> DuplexConsoleView<S, T> create(S primary, T secondary) {
- return new DuplexConsoleView<S, T>(primary, secondary);
+ public static <S extends ConsoleView, T extends ConsoleView> DuplexConsoleView<S, T> create(@NotNull S primary,
+ @NotNull T secondary,
+ @Nullable String stateStorageKey) {
+ return new DuplexConsoleView<S, T>(primary, secondary, stateStorageKey);
+ }
+
+ private void setStoredState(boolean primary) {
+ if (myStateStorageKey != null) {
+ PropertiesComponent.getInstance().setValue(myStateStorageKey, String.valueOf(primary));
+ }
+ }
+
+ private boolean getStoredState() {
+ if (myStateStorageKey == null) {
+ return false;
+ }
+ return PropertiesComponent.getInstance().getBoolean(myStateStorageKey, false);
}
public void enableConsole(boolean primary) {
@@ -215,23 +239,22 @@ public class DuplexConsoleView<S extends ConsoleView, T extends ConsoleView> ext
return mySwitchConsoleAction.getTemplatePresentation();
}
- private static class SwitchDuplexConsoleViewAction extends ToggleAction implements DumbAware {
- private final DuplexConsoleView myConsole;
+ private class SwitchDuplexConsoleViewAction extends ToggleAction implements DumbAware {
- public SwitchDuplexConsoleViewAction(final DuplexConsoleView console) {
+ public SwitchDuplexConsoleViewAction() {
super(ExecutionBundle.message("run.configuration.show.command.line.action.name"), null,
AllIcons.Debugger.ToolConsole);
- myConsole = console;
}
@Override
public boolean isSelected(final AnActionEvent event) {
- return !myConsole.isPrimaryConsoleEnabled();
+ return !isPrimaryConsoleEnabled();
}
@Override
public void setSelected(final AnActionEvent event, final boolean flag) {
- myConsole.enableConsole(!flag);
+ enableConsole(!flag);
+ setStoredState(!flag);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
@@ -244,12 +267,12 @@ public class DuplexConsoleView<S extends ConsoleView, T extends ConsoleView> ext
public void update(final AnActionEvent event) {
super.update(event);
final Presentation presentation = event.getPresentation();
- final boolean isRunning = myConsole.myProcessHandler != null && !myConsole.myProcessHandler.isProcessTerminated();
+ final boolean isRunning = myProcessHandler != null && !myProcessHandler.isProcessTerminated();
if (isRunning) {
presentation.setEnabled(true);
}
else {
- myConsole.enableConsole(true);
+ enableConsole(true);
presentation.putClientProperty(SELECTED_PROPERTY, false);
presentation.setEnabled(false);
}
diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java
index 9cb57be6ad9d..1a9afd1e25e5 100644
--- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java
@@ -670,12 +670,14 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
}
}
+ @NotNull
public Editor getCurrentEditor() {
- return ObjectUtils.chooseNotNull(myCurrentEditor, myConsoleEditor);
+ return ObjectUtils.notNull(myCurrentEditor, myConsoleEditor);
}
+ @NotNull
public Language getLanguage() {
- return myVirtualFile.getLanguage();
+ return ObjectUtils.assertNotNull(myVirtualFile.getLanguage());
}
public void setLanguage(@NotNull Language language) {
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java
index ae6af9d1064e..edf1352a760c 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java
@@ -49,6 +49,8 @@ import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
@@ -345,6 +347,14 @@ extends BeforeRunTaskProvider<RunConfigurationBeforeRunProvider.RunConfigurableB
mySettings = settings;
init();
myJBList.setSelectedValue(mySelectedSettings, true);
+ myJBList.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() ==2) {
+ doOKAction();
+ }
+ }
+ });
FontMetrics fontMetrics = myJBList.getFontMetrics(myJBList.getFont());
int maxWidth = fontMetrics.stringWidth("m") * 30;
for (RunnerAndConfigurationSettings setting : settings) {
diff --git a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java
index df7f7e1b2e1c..b4b3cd919ec4 100644
--- a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java
+++ b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java
@@ -15,6 +15,9 @@
*/
package com.intellij.execution.runners;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionHelper;
import com.intellij.execution.ExecutionManager;
@@ -129,38 +132,30 @@ public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsole
registerActionShortcuts(actions, getLanguageConsole().getConsoleEditor().getComponent());
registerActionShortcuts(actions, panel);
panel.updateUI();
+
showConsole(defaultExecutor, contentDescriptor);
// Run
myProcessHandler.startNotify();
}
- private String constructConsoleTitle(final @NotNull String consoleTitle) {
+ protected String constructConsoleTitle(final @NotNull String consoleTitle) {
if (shouldAddNumberToTitle()) {
- List<RunContentDescriptor> consoles = ExecutionHelper.collectConsolesByDisplayName(myProject, new NotNullFunction<String, Boolean>() {
- @NotNull
- @Override
- public Boolean fun(String dom) {
- return dom.contains(consoleTitle);
- }
- });
+ List<String> activeConsoleNames = getActiveConsoleNames(consoleTitle);
int max = 0;
- for (RunContentDescriptor dsc : consoles) {
- ProcessHandler handler = dsc.getProcessHandler();
- if (handler != null && !handler.isProcessTerminated()) {
- if (max == 0) {
- max = 1;
- }
- try {
- int num = Integer.parseInt(dsc.getDisplayName().substring(consoleTitle.length() + 1, dsc.getDisplayName().length() - 1));
- if (num > max) {
- max = num;
- }
- }
- catch (Exception ignored) {
- //skip
+ for (String name : activeConsoleNames) {
+ if (max == 0) {
+ max = 1;
+ }
+ try {
+ int num = Integer.parseInt(name.substring(consoleTitle.length() + 1, name.length() - 1));
+ if (num > max) {
+ max = num;
}
}
+ catch (Exception ignored) {
+ //skip
+ }
}
if (max >= 1) {
return consoleTitle + "(" + (max + 1) + ")";
@@ -178,9 +173,9 @@ public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsole
return false;
}
- protected void showConsole(Executor defaultExecutor, RunContentDescriptor myDescriptor) {
+ protected void showConsole(Executor defaultExecutor, RunContentDescriptor contentDescriptor) {
// Show in run toolwindow
- ExecutionManager.getInstance(myProject).getContentManager().showRunContent(defaultExecutor, myDescriptor);
+ ExecutionManager.getInstance(myProject).getContentManager().showRunContent(defaultExecutor, contentDescriptor);
}
protected void finishConsole() {
@@ -245,11 +240,13 @@ public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsole
public static AnAction createConsoleExecAction(@NotNull LanguageConsoleView console,
@NotNull ProcessHandler processHandler,
@NotNull ProcessBackedConsoleExecuteActionHandler consoleExecuteActionHandler) {
- return new ConsoleExecuteAction(console, consoleExecuteActionHandler, consoleExecuteActionHandler.getEmptyExecuteAction(), consoleExecuteActionHandler);
+ return new ConsoleExecuteAction(console, consoleExecuteActionHandler, consoleExecuteActionHandler.getEmptyExecuteAction(),
+ consoleExecuteActionHandler);
}
protected AnAction createConsoleExecAction(@NotNull ProcessBackedConsoleExecuteActionHandler consoleExecuteActionHandler) {
- return new ConsoleExecuteAction(myConsoleView, consoleExecuteActionHandler, consoleExecuteActionHandler.getEmptyExecuteAction(), consoleExecuteActionHandler);
+ return new ConsoleExecuteAction(myConsoleView, consoleExecuteActionHandler, consoleExecuteActionHandler.getEmptyExecuteAction(),
+ consoleExecuteActionHandler);
}
@SuppressWarnings("UnusedDeclaration")
@@ -301,4 +298,31 @@ public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsole
public ProcessBackedConsoleExecuteActionHandler getConsoleExecuteActionHandler() {
return myConsoleExecuteActionHandler;
}
+
+ protected List<String> getActiveConsoleNames(final String consoleTitle) {
+ return getActiveConsolesFromRunToolWindow(consoleTitle);
+ }
+
+ protected List<String> getActiveConsolesFromRunToolWindow(final String consoleTitle) {
+ List<RunContentDescriptor> consoles = ExecutionHelper.collectConsolesByDisplayName(myProject, new NotNullFunction<String, Boolean>() {
+ @NotNull
+ @Override
+ public Boolean fun(String dom) {
+ return dom.contains(consoleTitle);
+ }
+ });
+
+ return FluentIterable.from(consoles).filter(new Predicate<RunContentDescriptor>() {
+ @Override
+ public boolean apply(RunContentDescriptor input) {
+ ProcessHandler handler = input.getProcessHandler();
+ return handler != null && !handler.isProcessTerminated();
+ }
+ }).transform(new Function<RunContentDescriptor, String>() {
+ @Override
+ public String apply(RunContentDescriptor input) {
+ return input.getDisplayName();
+ }
+ }).toList();
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java b/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java
index 507864126430..20b29c2de994 100644
--- a/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java
+++ b/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java
@@ -61,6 +61,15 @@ public class RestartAction extends FakeRerunAction implements DumbAware, AnActio
myDescriptor = descriptor;
myExecutor = executor;
// see IDEADEV-698
+
+ if (descriptor.getRestarter() == null) {
+ descriptor.setRestarter(new Runnable() {
+ @Override
+ public void run() {
+ restart();
+ }
+ });
+ }
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java b/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java
index ab9433e66831..bb6d206f1eb9 100644
--- a/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java
+++ b/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java
@@ -206,12 +206,6 @@ public class RunContentBuilder extends LogConsoleManagerBase {
final RestartAction restartAction = new RestartAction(myExecutor, myRunner, contentDescriptor, getEnvironment());
restartAction.registerShortcut(component);
actionGroup.add(restartAction);
- contentDescriptor.setRestarter(new Runnable() {
- @Override
- public void run() {
- restartAction.restart();
- }
- });
if (myExecutionResult instanceof DefaultExecutionResult) {
final AnAction[] actions = ((DefaultExecutionResult)myExecutionResult).getRestartActions();
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java
index 897d169e1845..821d9dbd6bc3 100644
--- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java
+++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java
@@ -1271,6 +1271,17 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
return null;
}
+ @Nullable
+ public void restoreContent(final String key) {
+ for (AnAction action : myMinimizedViewActions.getChildren(null)) {
+ Content content = ((RestoreViewAction)action).getContent();
+ if (key.equals(content.getUserData(ViewImpl.ID))) {
+ action.actionPerformed(null);
+ return;
+ }
+ }
+ }
+
public void setToDisposeRemovedContent(final boolean toDispose) {
myToDisposeRemovedContent = toDispose;
}
diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java
index 8a36638d993c..9613ac0dd33f 100644
--- a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java
+++ b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java
@@ -392,6 +392,9 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data
if (secondaryActionsAvailable()) {
actionGroup.addAction(new ToggleInCommentsAction(this)).setAsSecondary(true);
actionGroup.addAction(new ToggleInLiteralsOnlyAction(this)).setAsSecondary(true);
+ actionGroup.addAction(new ToggleExceptCommentsAction(this)).setAsSecondary(true);
+ actionGroup.addAction(new ToggleExceptLiteralsAction(this)).setAsSecondary(true);
+ actionGroup.addAction(new ToggleExceptCommentsAndLiteralsAction(this)).setAsSecondary(true);
}
actionGroup.addAction(new TogglePreserveCaseAction(this));
actionGroup.addAction(new ToggleSelectionOnlyAction(this));
@@ -473,8 +476,7 @@ public class EditorSearchComponent extends EditorHeaderComponent implements Data
to.setCaseSensitive(from.isCaseSensitive());
to.setWholeWordsOnly(from.isWholeWordsOnly());
to.setRegularExpressions(from.isRegularExpressions());
- to.setInCommentsOnly(from.isInCommentsOnly());
- to.setInStringLiteralsOnly(from.isInStringLiteralsOnly());
+ to.setSearchContext(from.getSearchContext());
if (from.isReplaceState()) {
to.setPreserveCase(from.isPreserveCase());
}
diff --git a/platform/lang-impl/src/com/intellij/find/FindSettings.java b/platform/lang-impl/src/com/intellij/find/FindSettings.java
index 964670a45723..d61fd395eadd 100644
--- a/platform/lang-impl/src/com/intellij/find/FindSettings.java
+++ b/platform/lang-impl/src/com/intellij/find/FindSettings.java
@@ -119,4 +119,13 @@ public abstract class FindSettings{
public abstract boolean isInCommentsOnly();
public abstract void setInCommentsOnly(boolean selected);
+
+ public abstract boolean isExceptStringLiterals();
+ public abstract void setExceptStringLiterals(boolean selected);
+
+ public abstract boolean isExceptComments();
+ public abstract void setExceptComments(boolean selected);
+
+ public abstract boolean isExceptCommentsAndLiterals();
+ public abstract void setExceptCommentsAndLiterals(boolean selected);
}
diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java
index edc906481398..674358a49379 100644
--- a/platform/lang-impl/src/com/intellij/find/FindUtil.java
+++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java
@@ -321,7 +321,7 @@ public class FindUtil {
public static void searchBack(final Project project, final Editor editor, @Nullable DataContext context) {
FindManager findManager = FindManager.getInstance(project);
- if (!findManager.findWasPerformed()) {
+ if (!findManager.findWasPerformed() && !findManager.selectNextOccurrenceWasPerformed()) {
new IncrementalFindAction().getHandler().execute(editor, context);
return;
}
@@ -363,7 +363,7 @@ public class FindUtil {
public static boolean searchAgain(final Project project, final Editor editor, @Nullable DataContext context) {
FindManager findManager = FindManager.getInstance(project);
- if (!findManager.findWasPerformed()) {
+ if (!findManager.findWasPerformed() && !findManager.selectNextOccurrenceWasPerformed()) {
new IncrementalFindAction().getHandler().execute(editor, context);
return false;
}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptCommentsAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptCommentsAction.java
new file mode 100644
index 000000000000..ae60f31a70b7
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptCommentsAction.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.find.editorHeaderActions;
+
+import com.intellij.find.EditorSearchComponent;
+import com.intellij.find.FindModel;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+
+public class ToggleExceptCommentsAction extends EditorHeaderToggleAction implements SecondaryHeaderAction {
+ private static final String TEXT = "Except C&omments";
+
+ public ToggleExceptCommentsAction(EditorSearchComponent editorSearchComponent) {
+ super(editorSearchComponent, TEXT);
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return getEditorSearchComponent().getFindModel().isExceptComments();
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ getEditorSearchComponent().getFindModel().setSearchContext(state ? FindModel.SearchContext.EXCEPT_COMMENTS : FindModel.SearchContext.ANY);
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptCommentsAndLiteralsAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptCommentsAndLiteralsAction.java
new file mode 100644
index 000000000000..d3ff1015e610
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptCommentsAndLiteralsAction.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.find.editorHeaderActions;
+
+import com.intellij.find.EditorSearchComponent;
+import com.intellij.find.FindModel;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+
+public class ToggleExceptCommentsAndLiteralsAction extends EditorHeaderToggleAction implements SecondaryHeaderAction {
+ private static final String TEXT = "Except Comments and Li&terals";
+
+ public ToggleExceptCommentsAndLiteralsAction(EditorSearchComponent editorSearchComponent) {
+ super(editorSearchComponent, TEXT);
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return getEditorSearchComponent().getFindModel().isExceptCommentsAndStringLiterals();
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ getEditorSearchComponent().getFindModel().setSearchContext(state ? FindModel.SearchContext.EXCEPT_COMMENTS_AND_STRING_LITERALS : FindModel.SearchContext.ANY);
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptLiteralsAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptLiteralsAction.java
new file mode 100644
index 000000000000..4b7f09c2b211
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleExceptLiteralsAction.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.find.editorHeaderActions;
+
+import com.intellij.find.EditorSearchComponent;
+import com.intellij.find.FindModel;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+
+public class ToggleExceptLiteralsAction extends EditorHeaderToggleAction implements SecondaryHeaderAction {
+ private static final String TEXT = "Except L&iterals";
+
+ public ToggleExceptLiteralsAction(EditorSearchComponent editorSearchComponent) {
+ super(editorSearchComponent, TEXT);
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return getEditorSearchComponent().getFindModel().isExceptStringLiterals();
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ getEditorSearchComponent().getFindModel().setSearchContext(state ? FindModel.SearchContext.EXCEPT_STRING_LITERALS : FindModel.SearchContext.ANY);
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleInCommentsAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleInCommentsAction.java
index e6cae36868af..4d9d5ad44cac 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleInCommentsAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleInCommentsAction.java
@@ -18,8 +18,6 @@ public class ToggleInCommentsAction extends EditorHeaderToggleAction implements
@Override
public void setSelected(AnActionEvent e, boolean state) {
- FindModel findModel = getEditorSearchComponent().getFindModel();
- findModel.setInCommentsOnly(state);
- if (state) findModel.setInStringLiteralsOnly(false);
+ getEditorSearchComponent().getFindModel().setSearchContext(state ? FindModel.SearchContext.IN_COMMENTS : FindModel.SearchContext.ANY);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleInLiteralsOnlyAction.java b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleInLiteralsOnlyAction.java
index c4d47e024f5e..d8fc5d530095 100644
--- a/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleInLiteralsOnlyAction.java
+++ b/platform/lang-impl/src/com/intellij/find/editorHeaderActions/ToggleInLiteralsOnlyAction.java
@@ -18,8 +18,6 @@ public class ToggleInLiteralsOnlyAction extends EditorHeaderToggleAction implem
@Override
public void setSelected(AnActionEvent e, boolean state) {
- FindModel findModel = getEditorSearchComponent().getFindModel();
- findModel.setInStringLiteralsOnly(state);
- if (state) findModel.setInCommentsOnly(false);
+ getEditorSearchComponent().getFindModel().setSearchContext(state ? FindModel.SearchContext.IN_STRING_LITERALS : FindModel.SearchContext.ANY);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java b/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
index 7bc0e0c595f8..d7f7665a9299 100644
--- a/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
+++ b/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
@@ -25,6 +25,7 @@ import com.intellij.find.impl.FindManagerImpl;
import com.intellij.find.replaceInProject.ReplaceInProjectManager;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -71,8 +72,14 @@ public class FindInProjectManager {
findModel.setOpenInNewTab(toOpenInNewTab[0]);
FindInProjectUtil.setDirectoryName(findModel, dataContext);
- Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
- FindUtil.initStringToFindWithSelection(findModel, editor);
+ String text = PlatformDataKeys.PREDEFINED_TEXT.getData(dataContext);
+ if (text != null) {
+ FindModel.initStringToFindNoMultiline(findModel, text);
+ }
+ else {
+ Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
+ FindUtil.initStringToFindWithSelection(findModel, editor);
+ }
findManager.showFindDialog(findModel, new Runnable() {
@Override
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java
index fe47fb8558a6..3315eac0b979 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java
@@ -16,8 +16,8 @@
package com.intellij.find.findUsages;
+import com.intellij.lang.HelpID;
import com.intellij.lang.findUsages.DescriptiveNameUtil;
-import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
@@ -26,7 +26,9 @@ import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.usageView.UsageViewUtil;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -35,6 +37,7 @@ import javax.swing.*;
*/
public class CommonFindUsagesDialog extends AbstractFindUsagesDialog {
@NotNull protected final PsiElement myPsiElement;
+ @Nullable private final String myHelpId;
public CommonFindUsagesDialog(@NotNull PsiElement element,
@NotNull Project project,
@@ -46,6 +49,7 @@ public class CommonFindUsagesDialog extends AbstractFindUsagesDialog {
super(project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, isTextSearch(element, isSingleFile, handler),
!isSingleFile && !element.getManager().isInProject(element));
myPsiElement = element;
+ myHelpId = ObjectUtils.chooseNotNull(handler.getHelpId(), HelpID.FIND_OTHER_USAGES);
init();
}
@@ -71,8 +75,9 @@ public class CommonFindUsagesDialog extends AbstractFindUsagesDialog {
coloredComponent.append(DescriptiveNameUtil.getDescriptiveName(myPsiElement), SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
}
+ @Nullable
@Override
- protected void doHelpAction() {
- HelpManager.getInstance().invokeHelp(FindUsagesManager.getHelpID(myPsiElement));
+ protected String getHelpId() {
+ return myHelpId;
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java
index a9291cf612ba..b0dcc459d55b 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java
@@ -83,6 +83,11 @@ public abstract class FindUsagesHandler {
return PsiElement.EMPTY_ARRAY;
}
+ @Nullable
+ protected String getHelpId() {
+ return FindUsagesManager.getHelpID(myPsiElement);
+ }
+
@NotNull
public static FindUsagesOptions createFindUsagesOptions(@NotNull Project project, @Nullable final DataContext dataContext) {
FindUsagesOptions findUsagesOptions = new FindUsagesOptions(project, dataContext);
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java
index b6a6152b678b..c25456da1988 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,6 @@ import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.*;
-import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -50,8 +49,6 @@ import com.intellij.ui.EditorComboBoxRenderer;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.StateRestoringCheckBox;
-import com.intellij.ui.components.labels.LinkLabel;
-import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
@@ -60,7 +57,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.text.BadLocationException;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
@@ -78,8 +74,7 @@ public class FindDialog extends DialogWrapper {
private StateRestoringCheckBox myCbCaseSensitive;
private StateRestoringCheckBox myCbPreserveCase;
private StateRestoringCheckBox myCbWholeWordsOnly;
- private StateRestoringCheckBox myCbInCommentsOnly;
- private StateRestoringCheckBox myCbInStringLiteralsOnly;
+ private ComboBox mySearchContext;
private StateRestoringCheckBox myCbRegularExpressions;
private JRadioButton myRbGlobal;
private JRadioButton myRbSelectedText;
@@ -223,7 +218,7 @@ public class FindDialog extends DialogWrapper {
myReplacePrompt.setVisible(myModel.isReplaceState());
myReplaceComboBox.setVisible(myModel.isReplaceState());
if (myCbToSkipResultsWhenOneUsage != null) {
- myCbToSkipResultsWhenOneUsage.setVisible(myModel.isReplaceState());
+ myCbToSkipResultsWhenOneUsage.setVisible(!myModel.isReplaceState());
}
myCbPreserveCase.setVisible(myModel.isReplaceState());
}
@@ -354,9 +349,9 @@ public class FindDialog extends DialogWrapper {
gbConstraints.gridwidth = GridBagConstraints.REMAINDER;
optionsPanel.add(createFilterPanel(),gbConstraints);
- myCbToSkipResultsWhenOneUsage = createCheckbox(FindSettings.getInstance().isSkipResultsWithOneUsage(), FindBundle.message("find.options.skip.results.tab.with.one.usage.checkbox"));
+ myCbToSkipResultsWhenOneUsage = createCheckbox(FindSettings.getInstance().isSkipResultsWithOneUsage(), FindBundle.message("find.options.skip.results.tab.with.one.occurrence.checkbox"));
optionsPanel.add(myCbToSkipResultsWhenOneUsage, gbConstraints);
- myCbToSkipResultsWhenOneUsage.setVisible(myModel.isReplaceState());
+ myCbToSkipResultsWhenOneUsage.setVisible(!myModel.isReplaceState());
}
else {
if (FindManagerImpl.ourHasSearchInCommentsAndLiterals) {
@@ -476,6 +471,9 @@ public class FindDialog extends DialogWrapper {
findSettings.setWholeWordsOnly(myModel.isWholeWordsOnly());
findSettings.setInStringLiteralsOnly(myModel.isInStringLiteralsOnly());
findSettings.setInCommentsOnly(myModel.isInCommentsOnly());
+ findSettings.setExceptComments(myModel.isExceptComments());
+ findSettings.setExceptStringLiterals(myModel.isExceptStringLiterals());
+ findSettings.setExceptCommentsAndLiterals(myModel.isExceptCommentsAndStringLiterals());
findSettings.setRegularExpressions(myModel.isRegularExpressions());
if (!myModel.isMultipleFiles()){
@@ -603,39 +601,26 @@ public class FindDialog extends DialogWrapper {
regExPanel.setLayout(new BoxLayout(regExPanel, BoxLayout.X_AXIS));
regExPanel.add(myCbRegularExpressions);
- regExPanel.add(new LinkLabel("[Help]", null, new LinkListener() {
- @Override
- public void linkSelected(LinkLabel aSource, Object aLinkData) {
- try {
- final JBPopup helpPopup = RegExHelpPopup.createRegExHelpPopup();
- helpPopup.showInCenterOf(regExPanel);
- }
- catch (BadLocationException e) {
- LOG.info(e);
- }
- }
- }));
+ regExPanel.add(RegExHelpPopup.createRegExLink("[Help]", regExPanel, LOG));
findOptionsPanel.add(regExPanel);
- myCbInCommentsOnly = createCheckbox(FindBundle.message("find.options.comments.only"));
- myCbInStringLiteralsOnly = createCheckbox(FindBundle.message("find.options.string.literals.only"));
- ItemListener itemListener = new ItemListener() {
- @Override
- public void itemStateChanged(ItemEvent e) {
- if (e.getSource() == myCbInCommentsOnly) {
- if (myCbInCommentsOnly.isSelected()) myCbInStringLiteralsOnly.setSelected(false);
- } else if (e.getSource() == myCbInStringLiteralsOnly) {
- if (myCbInStringLiteralsOnly.isSelected()) myCbInCommentsOnly.setSelected(false);
- }
- }
- };
- myCbInCommentsOnly.addItemListener(itemListener);
- myCbInStringLiteralsOnly.addItemListener(itemListener);
+ mySearchContext = new ComboBox(new Object[] {FindBundle.message("find.context.anywhere.scope.label", 200),
+ FindBundle.message("find.context.in.comments.scope.label"), FindBundle.message("find.context.in.literals.scope.label"),
+ FindBundle.message("find.context.except.comments.scope.label"),
+ FindBundle.message("find.context.except.literals.scope.label"),
+ FindBundle.message("find.context.except.comments.and.literals.scope.label")});
+ final JPanel searchContextPanel = new JPanel(new BorderLayout());
+ searchContextPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
+
+ JLabel searchContextLabel = new JLabel(FindBundle.message("find.context.combo.label"));
+ searchContextLabel.setLabelFor(mySearchContext);
+ searchContextPanel.add(searchContextLabel, BorderLayout.WEST);
+
+ searchContextPanel.add(mySearchContext, BorderLayout.CENTER);
if (FindManagerImpl.ourHasSearchInCommentsAndLiterals) {
- findOptionsPanel.add(myCbInCommentsOnly);
- findOptionsPanel.add(myCbInStringLiteralsOnly);
+ findOptionsPanel.add(searchContextPanel);
}
ActionListener actionListener = new ActionListener() {
@@ -1000,9 +985,25 @@ public class FindDialog extends DialogWrapper {
}
model.setWholeWordsOnly(myCbWholeWordsOnly.isSelected());
- model.setInStringLiteralsOnly(myCbInStringLiteralsOnly.isSelected());
- model.setInCommentsOnly(myCbInCommentsOnly.isSelected());
+ String selectedSearchContextInUi = (String)mySearchContext.getSelectedItem();
+ FindModel.SearchContext searchContext = FindModel.SearchContext.ANY;
+ if (FindBundle.message("find.context.in.literals.scope.label").equals(selectedSearchContextInUi)) {
+ searchContext = FindModel.SearchContext.IN_STRING_LITERALS;
+ }
+ else if (FindBundle.message("find.context.in.comments.scope.label").equals(selectedSearchContextInUi)) {
+ searchContext = FindModel.SearchContext.IN_COMMENTS;
+ }
+ else if (FindBundle.message("find.context.except.comments.scope.label").equals(selectedSearchContextInUi)) {
+ searchContext = FindModel.SearchContext.EXCEPT_COMMENTS;
+ }
+ else if (FindBundle.message("find.context.except.literals.scope.label").equals(selectedSearchContextInUi)) {
+ searchContext = FindModel.SearchContext.EXCEPT_STRING_LITERALS;
+ } else if (FindBundle.message("find.context.except.comments.and.literals.scope.label").equals(selectedSearchContextInUi)) {
+ searchContext = FindModel.SearchContext.EXCEPT_COMMENTS_AND_STRING_LITERALS;
+ }
+
+ model.setSearchContext(searchContext);
model.setRegularExpressions(myCbRegularExpressions.isSelected());
String stringToFind = getStringToFind();
@@ -1068,8 +1069,14 @@ public class FindDialog extends DialogWrapper {
private void initByModel() {
myCbCaseSensitive.setSelected(myModel.isCaseSensitive());
myCbWholeWordsOnly.setSelected(myModel.isWholeWordsOnly());
- myCbInStringLiteralsOnly.setSelected(myModel.isInStringLiteralsOnly());
- myCbInCommentsOnly.setSelected(myModel.isInCommentsOnly());
+ String searchContext = FindBundle.message("find.context.anywhere.scope.label");
+ if (myModel.isInCommentsOnly()) searchContext = FindBundle.message("find.context.in.comments.scope.label");
+ else if (myModel.isInStringLiteralsOnly()) searchContext = FindBundle.message("find.context.in.literals.scope.label");
+ else if (myModel.isExceptStringLiterals()) searchContext = FindBundle.message("find.context.except.literals.scope.label");
+ else if (myModel.isExceptComments()) searchContext = FindBundle.message("find.context.except.comments.scope.label");
+ else if (myModel.isExceptCommentsAndStringLiterals()) searchContext = FindBundle.message("find.context.except.comments.and.literals.scope.label");
+ mySearchContext.setSelectedItem(searchContext);
+
myCbRegularExpressions.setSelected(myModel.isRegularExpressions());
if (myModel.isMultipleFiles()) {
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
index 59adf1e62bd0..7e9e71d7a94d 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
@@ -19,6 +19,7 @@ import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import com.intellij.find.FindBundle;
import com.intellij.find.FindModel;
+import com.intellij.find.findInProject.FindInProjectManager;
import com.intellij.find.ngrams.TrigramIndex;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
@@ -182,7 +183,7 @@ class FindInProjectTask {
private void searchInFiles(@NotNull Collection<PsiFile> psiFiles,
@NotNull FindUsagesProcessPresentation processPresentation,
- @NotNull Processor<UsageInfo> consumer) {
+ @NotNull final Processor<UsageInfo> consumer) {
int i = 0;
long totalFilesSize = 0;
int count = 0;
@@ -195,7 +196,8 @@ class FindInProjectTask {
long fileLength = UsageViewManagerImpl.getFileLength(virtualFile);
if (fileLength == -1) continue; // Binary or invalid
- if (ProjectCoreUtil.isProjectOrWorkspaceFile(virtualFile) && !Registry.is("find.search.in.project.files")) continue;
+ final boolean skipProjectFile = ProjectCoreUtil.isProjectOrWorkspaceFile(virtualFile) && !myFindModel.isSearchInProjectFiles();
+ if (skipProjectFile && !Registry.is("find.search.in.project.files")) continue;
if (fileLength > SINGLE_FILE_SIZE_LIMIT) {
myLargeFiles.add(psiFile);
@@ -209,7 +211,24 @@ class FindInProjectTask {
myProgress.setText(text);
myProgress.setText2(FindBundle.message("find.searching.for.string.in.file.occurrences.progress", count));
- int countInFile = FindInProjectUtil.processUsagesInFile(psiFile, myFindModel, consumer);
+ int countInFile = FindInProjectUtil.processUsagesInFile(psiFile, myFindModel, new Processor<UsageInfo>() {
+ @Override
+ public boolean process(UsageInfo info) {
+ return skipProjectFile || consumer.process(info);
+ }
+ });
+
+ if (countInFile > 0 && skipProjectFile) {
+ processPresentation.projectFileUsagesFound(new Runnable() {
+ @Override
+ public void run() {
+ FindModel model = myFindModel.clone();
+ model.setSearchInProjectFiles(true);
+ FindInProjectManager.getInstance(myProject).startFindInProject(model);
+ }
+ });
+ continue;
+ }
count += countInFile;
if (countInFile > 0) {
@@ -231,6 +250,7 @@ class FindInProjectTask {
final GlobalSearchScope globalCustomScope = toGlobal(customScope);
final ProjectFileIndex fileIndex = ProjectFileIndex.SERVICE.getInstance(myProject);
+ final boolean hasTrigrams = hasTrigrams(myFindModel.getStringToFind());
class EnumContentIterator implements ContentIterator {
final Set<PsiFile> myFiles = new LinkedHashSet<PsiFile>();
@@ -238,8 +258,6 @@ class FindInProjectTask {
@Override
public boolean processFile(@NotNull final VirtualFile virtualFile) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
- final boolean hasTrigrams = hasTrigrams(myFindModel.getStringToFind());
-
@Override
public void run() {
ProgressManager.checkCanceled();
@@ -249,9 +267,6 @@ class FindInProjectTask {
return;
}
- if (virtualFile.getFileType().isBinary()) {
- return;
- }
if (skipIndexed && isCoveredByIndex(virtualFile) &&
(fileIndex.isInContent(virtualFile) || fileIndex.isInLibraryClasses(virtualFile) || fileIndex.isInLibrarySource(virtualFile))) {
return;
@@ -261,7 +276,9 @@ class FindInProjectTask {
if (psiFile != null && !(psiFile instanceof PsiBinaryFile) && !alreadySearched.contains(psiFile)) {
PsiFile sourceFile = (PsiFile)psiFile.getNavigationElement();
if (sourceFile != null) psiFile = sourceFile;
- myFiles.add(psiFile);
+ if (!psiFile.getFileType().isBinary()) {
+ myFiles.add(psiFile);
+ }
}
}
@@ -290,7 +307,9 @@ class FindInProjectTask {
for (VirtualFile file : getLocalScopeFiles((LocalSearchScope)customScope)) {
iterator.processFile(file);
}
- } else if (customScope instanceof Iterable) { // GlobalSearchScope can span files out of project roots e.g. FileScope / FilesScope
+ }
+ else if (customScope instanceof Iterable) { // GlobalSearchScope can span files out of project roots e.g. FileScope / FilesScope
+ //noinspection unchecked
for (VirtualFile file : (Iterable<VirtualFile>)customScope) {
iterator.processFile(file);
}
@@ -382,16 +401,14 @@ class FindInProjectTask {
return myFindModel.isWholeWordsOnly() && text.indexOf('$') < 0 && !StringUtil.getWordsInStringLongestFirst(text).isEmpty();
}
- private static boolean hasTrigrams(String text) {
- if (TrigramIndex.ENABLED) {
- return !TrigramBuilder.processTrigrams(text, new TrigramBuilder.TrigramProcessor() {
- @Override
- public boolean execute(int value) {
- return false;
- }
- });
- }
- return false;
+ private static boolean hasTrigrams(@NotNull String text) {
+ return TrigramIndex.ENABLED &&
+ !TrigramBuilder.processTrigrams(text, new TrigramBuilder.TrigramProcessor() {
+ @Override
+ public boolean execute(int value) {
+ return false;
+ }
+ });
}
@@ -430,6 +447,7 @@ class FindInProjectTask {
final List<VirtualFile> hits = new ArrayList<VirtualFile>();
final GlobalSearchScope finalScope = scope;
ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
public void run() {
FileBasedIndex.getInstance().getFilesWithKey(TrigramIndex.INDEX_ID, keys, new CommonProcessors.CollectProcessor<VirtualFile>(hits),
finalScope);
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
index e4570b7379bf..23f14c5eb0b4 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
@@ -47,7 +47,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.ex.VirtualFileManagerEx;
import com.intellij.psi.*;
-import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.ui.content.Content;
@@ -55,7 +54,6 @@ import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewManager;
import com.intellij.usages.ConfigurableUsageTarget;
import com.intellij.usages.FindUsagesProcessPresentation;
-import com.intellij.usages.UsageView;
import com.intellij.usages.UsageViewPresentation;
import com.intellij.util.Function;
import com.intellij.util.PatternUtil;
@@ -326,7 +324,7 @@ public class FindInProjectUtil {
return processPresentation;
}
- public static class StringUsageTarget implements ConfigurableUsageTarget, ItemPresentation, TypeSafeDataProvider {
+ public static class StringUsageTarget implements ConfigurableUsageTarget, ItemPresentation {
@NotNull protected final Project myProject;
@NotNull protected final FindModel myFindModel;
@@ -425,12 +423,5 @@ public class FindInProjectUtil {
public KeyboardShortcut getShortcut() {
return ActionManager.getInstance().getKeyboardShortcut("FindInPath");
}
-
- @Override
- public void calcData(DataKey key, DataSink sink) {
- if (key == UsageView.USAGE_SCOPE) {
- sink.put(UsageView.USAGE_SCOPE, GlobalSearchScope.allScope(myProject));
- }
- }
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
index e327ec79c227..27e2b7215f25 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java
@@ -27,7 +27,6 @@ import com.intellij.find.impl.livePreview.SearchResults;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.ParserDefinition;
-import com.intellij.lexer.LayeredLexer;
import com.intellij.lexer.Lexer;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.actionSystem.ActionManager;
@@ -42,11 +41,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.ex.FoldingModelEx;
-import com.intellij.openapi.editor.ex.util.LayeredHighlighterIterator;
-import com.intellij.openapi.editor.ex.util.LayeredLexerEditorHighlighter;
-import com.intellij.openapi.editor.highlighter.EditorHighlighter;
-import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
-import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.TextEditor;
@@ -58,15 +52,17 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.search.LexerEditorHighlighterLexer;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.ui.LightweightHint;
import com.intellij.ui.ReplacePromptDialog;
+import com.intellij.usages.ChunkExtractor;
import com.intellij.usages.UsageViewManager;
+import com.intellij.usages.impl.SyntaxHighlighterOverEditorHighlighter;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.Predicate;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.text.StringSearcher;
@@ -96,6 +92,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
private final FindUsagesManager myFindUsagesManager;
private boolean isFindWasPerformed = false;
+ private boolean isSelectNextOccurrenceWasPerformed = false;
private Point myReplaceInFilePromptPos = new Point(-1, -1);
private Point myReplaceInProjectPromptPos = new Point(-1, -1);
private final FindModel myFindInProjectModel = new FindModel();
@@ -257,7 +254,18 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
@Override
public void setFindWasPerformed() {
isFindWasPerformed = true;
- //myFindUsagesManager.clearFindingNextUsageInFile();
+ isSelectNextOccurrenceWasPerformed = false;
+ }
+
+ @Override
+ public boolean selectNextOccurrenceWasPerformed() {
+ return isSelectNextOccurrenceWasPerformed;
+ }
+
+ @Override
+ public void setSelectNextOccurrenceWasPerformed() {
+ isSelectNextOccurrenceWasPerformed = true;
+ isFindWasPerformed = false;
}
@Override
@@ -270,7 +278,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
if (myFindNextModel == null) return null;
final JComponent header = editor.getHeaderComponent();
- if (header instanceof EditorSearchComponent) {
+ if (header instanceof EditorSearchComponent && !isSelectNextOccurrenceWasPerformed) {
final EditorSearchComponent searchComponent = (EditorSearchComponent)header;
final String textInField = searchComponent.getTextInField();
if (!Comparing.equal(textInField, myFindInFileModel.getStringToFind()) && !textInField.isEmpty()) {
@@ -305,25 +313,103 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
LOG.debug(model.toString());
}
- final char[] textArray = CharArrayUtil.fromSequenceWithoutCopying(text);
+ return findStringLoop(text, offset, model, file, getFindContextPredicate(model, file, text));
+ }
+ private FindResult findStringLoop(CharSequence text, int offset, FindModel model, VirtualFile file, @Nullable Predicate<FindResult> filter) {
+ final char[] textArray = CharArrayUtil.fromSequenceWithoutCopying(text);
while(true) {
FindResult result = doFindString(text, textArray, offset, model, file);
+ if (filter == null || filter.apply(result)) {
+ if (!model.isWholeWordsOnly()) {
+ return result;
+ }
+ if (!result.isStringFound()) {
+ return result;
+ }
+ if (isWholeWord(text, result.getStartOffset(), result.getEndOffset())) {
+ return result;
+ }
+ }
+
+ offset = model.isForward() ? result.getStartOffset() + 1 : result.getEndOffset() - 1;
+ if (offset > text.length() || offset < 0) return NOT_FOUND_RESULT;
+ }
+ }
+
+ private class FindExceptCommentsOrLiteralsData implements Predicate<FindResult> {
+ private final VirtualFile myFile;
+ private final FindModel myFindModel;
+ private final TreeMap<Integer, Integer> mySkipRangesSet;
+
+ private FindExceptCommentsOrLiteralsData(VirtualFile file, FindModel model, CharSequence text) {
+ myFile = file;
+ myFindModel = model.clone();
- if (!model.isWholeWordsOnly()) {
- return result;
+ TreeMap<Integer, Integer> result = new TreeMap<Integer, Integer>();
+
+ if (model.isExceptComments() || model.isExceptCommentsAndStringLiterals()) {
+ addRanges(file, model, text, result, FindModel.SearchContext.IN_COMMENTS);
}
- if (!result.isStringFound()){
- return result;
+
+ if (model.isExceptStringLiterals() || model.isExceptCommentsAndStringLiterals()) {
+ addRanges(file, model, text, result, FindModel.SearchContext.IN_STRING_LITERALS);
}
- if (isWholeWord(text, result.getStartOffset(), result.getEndOffset())){
- return result;
+
+ mySkipRangesSet = result;
+ }
+
+ private void addRanges(VirtualFile file,
+ FindModel model,
+ CharSequence text,
+ TreeMap<Integer, Integer> result,
+ FindModel.SearchContext searchContext) {
+ FindModel clonedModel = model.clone();
+ clonedModel.setSearchContext(searchContext);
+ clonedModel.setForward(true);
+ int offset = 0;
+
+ while(true) {
+ FindResult customResult = findStringLoop(text, offset, clonedModel, file, null);
+ if (!customResult.isStringFound()) break;
+ result.put(customResult.getStartOffset(), customResult.getEndOffset());
+ offset = Math.max(customResult.getEndOffset(), offset + 1); // avoid loop for zero size reg exps matches
+ if (offset >= text.length()) break;
}
+ }
- offset = model.isForward() ? result.getStartOffset() + 1 : result.getEndOffset() - 1;
- if (offset > text.length() || offset < 0) return NOT_FOUND_RESULT;
+ boolean isAcceptableFor(FindModel model, VirtualFile file) {
+ return Comparing.equal(myFile, file) && myFindModel.equals(model);
+ }
+
+ @Override
+ public boolean apply(@Nullable FindResult input) {
+ if (input == null || !input.isStringFound()) return true;
+ NavigableMap<Integer, Integer> map = mySkipRangesSet.headMap(input.getStartOffset(), true);
+ for(Map.Entry<Integer, Integer> e:map.descendingMap().entrySet()) {
+ if (e.getKey() <= input.getStartOffset() && e.getValue() >= input.getEndOffset()) return false;
+ if (e.getValue() <= input.getStartOffset()) break;
+ }
+ return true;
}
}
+ private static Key<FindExceptCommentsOrLiteralsData> ourExceptCommentsOrLiteralsDataKey = Key.create("except.comments.literals.search.data");
+
+ private Predicate<FindResult> getFindContextPredicate(@NotNull FindModel model, VirtualFile file, CharSequence text) {
+ if (file == null) return null;
+ FindModel.SearchContext context = model.getSearchContext();
+ if( context == FindModel.SearchContext.ANY || context == FindModel.SearchContext.IN_COMMENTS ||
+ context == FindModel.SearchContext.IN_STRING_LITERALS) {
+ return null;
+ }
+
+ FindExceptCommentsOrLiteralsData data = model.getUserData(ourExceptCommentsOrLiteralsDataKey);
+ if (data == null || !data.isAcceptableFor(model, file)) {
+ model.putUserData(ourExceptCommentsOrLiteralsDataKey, data = new FindExceptCommentsOrLiteralsData(file, model, text));
+ }
+
+ return data;
+ }
@Override
public int showMalformedReplacementPrompt(@NotNull FindModel model, String title, MalformedReplacementStringException exception) {
@@ -408,11 +494,15 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
return new StringSearcher(model.getStringToFind(), model.isCaseSensitive(), model.isForward());
}
+ public static void clearPreviousFindData(FindModel model) {
+ model.putUserData(ourCommentsLiteralsSearchDataKey, null);
+ model.putUserData(ourExceptCommentsOrLiteralsDataKey, null);
+ }
+
private static class CommentsLiteralsSearchData {
final VirtualFile lastFile;
int startOffset = 0;
- final SyntaxHighlighter highlighter;
- final Lexer highlightingLexer;
+ final SyntaxHighlighterOverEditorHighlighter highlighter;
TokenSet tokensOfInterest;
final StringSearcher searcher;
@@ -420,8 +510,8 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
final Set<Language> relevantLanguages;
final FindModel model;
- public CommentsLiteralsSearchData(VirtualFile lastFile, Set<Language> relevantLanguages, SyntaxHighlighter highlighter,
- Lexer lexer, TokenSet tokensOfInterest,
+ public CommentsLiteralsSearchData(VirtualFile lastFile, Set<Language> relevantLanguages,
+ SyntaxHighlighterOverEditorHighlighter highlighter, TokenSet tokensOfInterest,
StringSearcher searcher, Matcher matcher, FindModel model) {
this.lastFile = lastFile;
this.highlighter = highlighter;
@@ -429,12 +519,11 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
this.searcher = searcher;
this.matcher = matcher;
this.relevantLanguages = relevantLanguages;
- highlightingLexer = lexer;
this.model = model;
}
}
- public static final Key<CommentsLiteralsSearchData> ourCommentsLiteralsSearchDataKey = Key.create("comments.literals.search.data");
+ private static final Key<CommentsLiteralsSearchData> ourCommentsLiteralsSearchDataKey = Key.create("comments.literals.search.data");
@NotNull
private FindResult findInCommentsAndLiterals(@NotNull CharSequence text,
@@ -512,38 +601,15 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
Matcher matcher = model.isRegularExpressions() ? compileRegExp(model, ""):null;
StringSearcher searcher = matcher != null ? null: new StringSearcher(model.getStringToFind(), model.isCaseSensitive(), true);
- LayeredLexer.ourDisableLayersFlag.set(Boolean.TRUE);
- EditorHighlighter editorHighlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, file);
- Lexer lexer;
-
- try {
- if (editorHighlighter instanceof LayeredLexerEditorHighlighter) {
- lexer = new LexerEditorHighlighterLexer(editorHighlighter, false);
- } else {
- lexer = highlighter.getHighlightingLexer();
- }
- }
- finally {
- LayeredLexer.ourDisableLayersFlag.set(null);
- }
-
- data = new CommentsLiteralsSearchData(file, relevantLanguages, highlighter, lexer, tokensOfInterest, searcher, matcher, (FindModel)model.clone());
- lexer.start(text, 0, text.length(), 0);
+ SyntaxHighlighterOverEditorHighlighter highlighterAdapter = new SyntaxHighlighterOverEditorHighlighter(highlighter, file, myProject);
+ data = new CommentsLiteralsSearchData(file, relevantLanguages, highlighterAdapter, tokensOfInterest, searcher, matcher, model.clone());
+ data.highlighter.restart(text);
model.putUserData(ourCommentsLiteralsSearchDataKey, data);
}
int initialStartOffset = model.isForward() && data.startOffset < offset ? data.startOffset : 0;
- final Lexer lexer = data.highlightingLexer;
- LayeredHighlighterIterator layeredHighlighterIterator = null;
- if (lexer instanceof LexerEditorHighlighterLexer) {
- ((LexerEditorHighlighterLexer)lexer).resetPosition(initialStartOffset);
- HighlighterIterator iterator = ((LexerEditorHighlighterLexer)lexer).getHighlighterIterator();
- if (iterator instanceof LayeredHighlighterIterator) {
- layeredHighlighterIterator = (LayeredHighlighterIterator)iterator;
- }
- } else {
- lexer.start(text, initialStartOffset, text.length(), 0);
- }
+ data.highlighter.resetPosition(initialStartOffset);
+ final Lexer lexer = data.highlighter.getHighlightingLexer();
IElementType tokenType;
TokenSet tokens = data.tokensOfInterest;
@@ -555,13 +621,11 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
while((tokenType = lexer.getTokenType()) != null) {
if (lexer.getState() == 0) lastGoodOffset = lexer.getTokenStart();
- final SyntaxHighlighter activeSyntaxHighlighter =
- layeredHighlighterIterator != null ? layeredHighlighterIterator.getActiveSyntaxHighlighter() : data.highlighter;
- final TextAttributesKey[] keys = activeSyntaxHighlighter.getTokenHighlights(tokenType);
+ final TextAttributesKey[] keys = data.highlighter.getTokenHighlights(tokenType);
if (tokens.contains(tokenType) ||
- (model.isInStringLiteralsOnly() && isHighlightedAsString(keys)) ||
- (model.isInCommentsOnly() && isHighlightedAsDocComment(keys))
+ (model.isInStringLiteralsOnly() && ChunkExtractor.isHighlightedAsString(keys)) ||
+ (model.isInCommentsOnly() && ChunkExtractor.isHighlightedAsComment(keys))
) {
int start = lexer.getTokenStart();
int end = lexer.getTokenEnd();
@@ -634,32 +698,6 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
return prevFindResult;
}
- private static boolean isHighlightedAsDocComment(TextAttributesKey... keys) {
- for (TextAttributesKey key : keys) {
- if (key == DefaultLanguageHighlighterColors.DOC_COMMENT || key == SyntaxHighlighterColors.DOC_COMMENT) {
- return true;
- }
- final TextAttributesKey fallbackAttributeKey = key.getFallbackAttributeKey();
- if (fallbackAttributeKey != null && isHighlightedAsDocComment(fallbackAttributeKey)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean isHighlightedAsString(TextAttributesKey... keys) {
- for (TextAttributesKey key : keys) {
- if (key == DefaultLanguageHighlighterColors.STRING || key == SyntaxHighlighterColors.STRING) {
- return true;
- }
- final TextAttributesKey fallbackAttributeKey = key.getFallbackAttributeKey();
- if (fallbackAttributeKey != null && isHighlightedAsString(fallbackAttributeKey)) {
- return true;
- }
- }
- return false;
- }
-
private static TokenSet addTokenTypesForLanguage(FindModel model, Language lang, TokenSet tokensOfInterest) {
ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
if (definition != null) {
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java b/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java
index 2c372795ea85..ee8d98422250 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java
@@ -80,7 +80,7 @@ public class FindResultUsageInfo extends UsageInfo {
Long data = myFindModel.getUserData(ourDocumentTimestampKey);
if (data == null || data != myTimestamp) {
data = myTimestamp;
- myFindModel.putUserData(FindManagerImpl.ourCommentsLiteralsSearchDataKey, null);
+ FindManagerImpl.clearPreviousFindData(myFindModel);
}
myFindModel.putUserData(ourDocumentTimestampKey, data);
FindResult result;
@@ -110,7 +110,13 @@ public class FindResultUsageInfo extends UsageInfo {
assert result.isStringFound();
- if (myFindModel.isRegularExpressions() || myFindModel.isInCommentsOnly() || myFindModel.isInStringLiteralsOnly()) {
+ if (myFindModel.isRegularExpressions() ||
+ myFindModel.isInCommentsOnly() ||
+ myFindModel.isInStringLiteralsOnly() ||
+ myFindModel.isExceptStringLiterals() ||
+ myFindModel.isExceptCommentsAndStringLiterals() ||
+ myFindModel.isExceptComments()
+ ) {
myAnchor = SmartPointerManager.getInstance(getProject()).createSmartPsiFileRangePointer(file, TextRange.from(offset, 0));
}
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java
index 5fb74f190ac0..c9c8e3492834 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java
@@ -103,6 +103,9 @@ public class FindSettingsImpl extends FindSettings implements PersistentStateCom
@SuppressWarnings({"WeakerAccess"}) public boolean WHOLE_WORDS_ONLY = false;
@SuppressWarnings({"WeakerAccess"}) public boolean COMMENTS_ONLY = false;
@SuppressWarnings({"WeakerAccess"}) public boolean STRING_LITERALS_ONLY = false;
+ @SuppressWarnings({"WeakerAccess"}) public boolean EXCEPT_COMMENTS = false;
+ @SuppressWarnings({"WeakerAccess"}) public boolean EXCEPT_COMMENTS_AND_STRING_LITERALS = false;
+ @SuppressWarnings({"WeakerAccess"}) public boolean EXCEPT_STRING_LITERALS = false;
@SuppressWarnings({"WeakerAccess"}) public boolean LOCAL_WHOLE_WORDS_ONLY = false;
@SuppressWarnings({"WeakerAccess"}) public boolean REGULAR_EXPRESSIONS = false;
@SuppressWarnings({"WeakerAccess"}) public boolean LOCAL_REGULAR_EXPRESSIONS = false;
@@ -276,8 +279,18 @@ public class FindSettingsImpl extends FindSettings implements PersistentStateCom
model.setGlobal(isGlobal());
model.setRegularExpressions(isRegularExpressions());
model.setWholeWordsOnly(isWholeWordsOnly());
- model.setInCommentsOnly(isInCommentsOnly());
- model.setInStringLiteralsOnly(isInStringLiteralsOnly());
+ FindModel.SearchContext searchContext = isInCommentsOnly() ?
+ FindModel.SearchContext.IN_COMMENTS :
+ isInStringLiteralsOnly() ?
+ FindModel.SearchContext.IN_STRING_LITERALS :
+ isExceptComments() ?
+ FindModel.SearchContext.EXCEPT_COMMENTS :
+ isExceptStringLiterals() ?
+ FindModel.SearchContext.EXCEPT_STRING_LITERALS :
+ isExceptCommentsAndLiterals() ?
+ FindModel.SearchContext.EXCEPT_COMMENTS_AND_STRING_LITERALS :
+ FindModel.SearchContext.ANY;
+ model.setSearchContext(searchContext);
model.setWithSubdirectories(isWithSubdirectories());
model.setFileFilter(FILE_MASK);
@@ -384,4 +397,34 @@ public class FindSettingsImpl extends FindSettings implements PersistentStateCom
public void setCustomScope(final String SEARCH_SCOPE) {
this.SEARCH_SCOPE = SEARCH_SCOPE;
}
+
+ @Override
+ public boolean isExceptComments() {
+ return EXCEPT_COMMENTS;
+ }
+
+ @Override
+ public void setExceptCommentsAndLiterals(boolean selected) {
+ EXCEPT_COMMENTS_AND_STRING_LITERALS = selected;
+ }
+
+ @Override
+ public boolean isExceptCommentsAndLiterals() {
+ return EXCEPT_COMMENTS_AND_STRING_LITERALS;
+ }
+
+ @Override
+ public void setExceptComments(boolean selected) {
+ EXCEPT_COMMENTS = selected;
+ }
+
+ @Override
+ public boolean isExceptStringLiterals() {
+ return EXCEPT_STRING_LITERALS;
+ }
+
+ @Override
+ public void setExceptStringLiterals(boolean selected) {
+ EXCEPT_STRING_LITERALS = selected;
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/find/impl/RegExHelpPopup.java b/platform/lang-impl/src/com/intellij/find/impl/RegExHelpPopup.java
index 23dee12e362f..0aace901a409 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/RegExHelpPopup.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/RegExHelpPopup.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,12 +17,19 @@ package com.intellij.find.impl;
import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.ide.BrowserUtil;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.popup.ComponentPopupBuilder;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.util.MinimizeButton;
+import com.intellij.openapi.util.Disposer;
import com.intellij.ui.ScrollPaneFactory;
+import com.intellij.ui.components.labels.LinkLabel;
+import com.intellij.ui.components.labels.LinkListener;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
@@ -331,6 +338,36 @@ public class RegExHelpPopup extends JPanel {
add(myScrollPane, BorderLayout.CENTER);
}
+ @NotNull
+ public static LinkLabel createRegExLink(@NotNull String title, @Nullable final Component owner, @Nullable final Logger logger) {
+ return new LinkLabel(title, null, new LinkListener() {
+ JBPopup helpPopup;
+ @Override
+ public void linkSelected(LinkLabel aSource, Object aLinkData) {
+ try {
+ if (helpPopup != null && !helpPopup.isDisposed() && helpPopup.isVisible()) {
+ return;
+ }
+ helpPopup = createRegExHelpPopup();
+ Disposer.register(helpPopup, new Disposable() {
+ @Override
+ public void dispose() {
+ destroyPopup();
+ }
+ });
+ helpPopup.showInCenterOf(owner);
+ }
+ catch (BadLocationException e) {
+ if (logger != null) logger.info(e);
+ }
+ }
+
+ private void destroyPopup() {
+ helpPopup = null;
+ }
+ });
+ }
+
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 300);
diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java b/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java
index e9e8c130a6f4..f5417dfb5a25 100644
--- a/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java
+++ b/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -116,7 +116,14 @@ public abstract class FormatterEx{
TextRange affectedRange);
public abstract void setProgressTask(@NotNull FormattingProgressTask progressIndicator);
-
+
+ /**
+ * Calculates minimum spacing, allowed by formatting model (in columns) for a block starting at given offset,
+ * relative to its previous sibling block.
+ * Returns zero, if required block cannot be found at provided offset, or spacing cannot be calculated due to some other reason.
+ */
+ public abstract int getSpacingForBlockAtOffset(FormattingModel model, int offset);
+
public interface IndentInfoStorage {
void saveIndentInfo(@Nullable IndentInfo info, int startOffset);
diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java
index e1366431efd0..7b40b786ff7a 100644
--- a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java
+++ b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
@@ -109,6 +110,58 @@ public class FormatterImpl extends FormatterEx
}
@Override
+ public int getSpacingForBlockAtOffset(FormattingModel model, int offset) {
+ Couple<Block> blockWithParent = getBlockAtOffset(null, model.getRootBlock(), offset);
+ if (blockWithParent == null) {
+ return 0;
+ }
+ Block parentBlock = blockWithParent.first;
+ Block targetBlock = blockWithParent.second;
+ if (parentBlock == null || targetBlock == null) {
+ return 0;
+ }
+ Block prevBlock = findPreviousSibling(parentBlock, targetBlock);
+ if (prevBlock == null) {
+ return 0;
+ }
+ SpacingImpl spacing = (SpacingImpl)parentBlock.getSpacing(prevBlock, targetBlock);
+ if (spacing == null) {
+ return 0;
+ }
+ return Math.max(spacing.getMinSpaces(), 0);
+ }
+
+ private static Couple<Block> getBlockAtOffset(Block parent, Block block, int offset) {
+ TextRange textRange = block.getTextRange();
+ int startOffset = textRange.getStartOffset();
+ int endOffset = textRange.getEndOffset();
+ if (startOffset == offset) {
+ return Couple.of(parent, block);
+ }
+ if (startOffset > offset || endOffset < offset || block.isLeaf()) {
+ return null;
+ }
+ for (Block subBlock : block.getSubBlocks()) {
+ Couple<Block> result = getBlockAtOffset(block, subBlock, offset);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ private static Block findPreviousSibling(Block parent, Block block) {
+ Block result = null;
+ for (Block subBlock : parent.getSubBlocks()) {
+ if (subBlock == block) {
+ return result;
+ }
+ result = subBlock;
+ }
+ return null;
+ }
+
+ @Override
public void format(final FormattingModel model, final CodeStyleSettings settings,
final CommonCodeStyleSettings.IndentOptions indentOptions,
final CommonCodeStyleSettings.IndentOptions javaIndentOptions,
diff --git a/platform/lang-impl/src/com/intellij/framework/detection/impl/exclude/DetectionExcludesConfigurable.java b/platform/lang-impl/src/com/intellij/framework/detection/impl/exclude/DetectionExcludesConfigurable.java
index 88d675b168de..6239cbbab4ac 100644
--- a/platform/lang-impl/src/com/intellij/framework/detection/impl/exclude/DetectionExcludesConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/framework/detection/impl/exclude/DetectionExcludesConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,17 +28,21 @@ import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.ui.popup.PopupStep;
import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
+import com.intellij.ui.border.CustomLineBorder;
import com.intellij.ui.components.JBList;
+import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -66,15 +70,33 @@ public class DetectionExcludesConfigurable implements Configurable {
@NotNull
public JComponent createComponent() {
myEnabledDetectionCheckBox = new JCheckBox("Enable framework detection");
+ myEnabledDetectionCheckBox.setBorder(new EmptyBorder(10, 10, 0, 0));
final JBList excludesList = new JBList(myModel);
- excludesList.setCellRenderer(new ColoredListCellRenderer() {
+ final ColoredListCellRenderer renderer = new ColoredListCellRenderer() {
+ JPanel panel = new JPanel(new BorderLayout());
+ {
+ panel.setBorder(new EmptyBorder(2, 10, 2, 0));
+ panel.add(this);
+ }
+
@Override
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
+ setIconTextGap(4);
if (value instanceof ExcludeListItem) {
((ExcludeListItem)value).renderItem(this);
+ setBorder(new EmptyBorder(0, 10, 0, 0));
}
}
- });
+
+ @Override
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected, boolean hasFocus) {
+ super.getListCellRendererComponent(list, value, index, selected, hasFocus);
+ panel.setBackground(UIUtil.getListBackground(selected));
+ return panel;
+ }
+ };
+ renderer.setMyBorder(new EmptyBorder(0,0,0,0));
+ excludesList.setCellRenderer(renderer);
final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(excludesList)
.disableUpAction().disableDownAction()
.setAddAction(new AnActionButtonRunnable() {
@@ -83,9 +105,12 @@ public class DetectionExcludesConfigurable implements Configurable {
doAddAction(button);
}
});
+ if (Registry.is("ide.new.project.settings")) {
+ decorator.setPanelBorder(new CustomLineBorder(1, 0, 0, 0));
+ }
myMainPanel = new JPanel(new BorderLayout(0, 5));
myMainPanel.add(myEnabledDetectionCheckBox, BorderLayout.NORTH);
- final LabeledComponent<JPanel> excludesComponent = LabeledComponent.create(decorator.createPanel(), "Exclude from detection:");
+ final LabeledComponent<JPanel> excludesComponent = LabeledComponent.create(decorator.createPanel(), " Exclude from detection:");
myMainPanel.add(excludesComponent);
myEnabledDetectionCheckBox.addActionListener(new ActionListener() {
@Override
diff --git a/platform/lang-impl/src/com/intellij/framework/detection/impl/exclude/InvalidExcludeListItem.java b/platform/lang-impl/src/com/intellij/framework/detection/impl/exclude/InvalidExcludeListItem.java
index 6848b039ceed..0dcdde7c6297 100644
--- a/platform/lang-impl/src/com/intellij/framework/detection/impl/exclude/InvalidExcludeListItem.java
+++ b/platform/lang-impl/src/com/intellij/framework/detection/impl/exclude/InvalidExcludeListItem.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package com.intellij.framework.detection.impl.exclude;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.ui.EmptyIcon;
/**
* @author nik
@@ -51,6 +52,7 @@ class InvalidExcludeListItem extends ExcludeListItem {
else {
renderer.append(myFileUrl, SimpleTextAttributes.ERROR_ATTRIBUTES);
}
+ renderer.setIcon(EmptyIcon.ICON_16);
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedFileAction.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedFileAction.java
index 6d734d52a584..e86caec534f6 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedFileAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedFileAction.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.actions;
+import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.navigation.GotoRelatedItem;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.ui.popup.JBPopup;
@@ -25,22 +26,25 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
- * @deprecated API compatibility. Utility methods will be moved to NavigationUtil
+ * @deprecated API compatibility. Utility methods moved to NavigationUtil.
+ * todo [neuro] REMOVE-ME when September Ends..
* @author gregsh
*/
public class GotoRelatedFileAction {
/**
- * @deprecated This method will be moved to NavigationUtil
+ * @deprecated
+ * @see com.intellij.codeInsight.navigation.NavigationUtil#getRelatedItemsPopup(java.util.List, String)
*/
public static JBPopup createPopup(List<? extends GotoRelatedItem> items, final String title) {
- return GotoRelatedSymbolAction.createPopup(items, title);
+ return NavigationUtil.getRelatedItemsPopup(items, title);
}
/**
- * @deprecated This method will be moved to NavigationUtil
+ * @deprecated
+ * @see com.intellij.codeInsight.navigation.NavigationUtil#collectRelatedItems(com.intellij.psi.PsiElement, com.intellij.openapi.actionSystem.DataContext)
*/
public static List<GotoRelatedItem> getItems(@NotNull PsiElement contextElement, @Nullable DataContext dataContext) {
- return GotoRelatedSymbolAction.getItems(contextElement, dataContext);
+ return NavigationUtil.collectRelatedItems(contextElement, dataContext);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java
index 2870f806ab8a..229531b3ef53 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java
@@ -15,39 +15,19 @@
*/
package com.intellij.ide.actions;
-import com.intellij.ide.util.DefaultPsiElementCellRenderer;
+import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.navigation.GotoRelatedItem;
-import com.intellij.navigation.GotoRelatedProvider;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.ui.popup.JBPopup;
-import com.intellij.openapi.ui.popup.PopupStep;
-import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
-import com.intellij.ui.ColoredListCellRenderer;
-import com.intellij.ui.JBColor;
-import com.intellij.ui.SeparatorWithText;
-import com.intellij.ui.SimpleTextAttributes;
-import com.intellij.ui.popup.list.ListPopupImpl;
-import com.intellij.ui.popup.list.PopupListElementRenderer;
-import com.intellij.util.Processor;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.util.*;
import java.util.List;
/**
@@ -66,210 +46,20 @@ public class GotoRelatedSymbolAction extends AnAction {
PsiElement element = getContextElement(e.getDataContext());
if (element == null) return;
- List<GotoRelatedItem> items = getItems(element, e.getDataContext());
+ List<GotoRelatedItem> items = NavigationUtil.collectRelatedItems(element, e.getDataContext());
if (items.isEmpty()) return;
if (items.size() == 1 && items.get(0).getElement() != null) {
items.get(0).navigate();
return;
}
- createPopup(items, "Choose Target").showInBestPositionFor(e.getDataContext());
- }
-
- public static JBPopup createPopup(final List<? extends GotoRelatedItem> items, final String title) {
- Object[] elements = new Object[items.size()];
- //todo[nik] move presentation logic to GotoRelatedItem class
- final Map<PsiElement, GotoRelatedItem> itemsMap = new HashMap<PsiElement, GotoRelatedItem>();
- for (int i = 0; i < items.size(); i++) {
- GotoRelatedItem item = items.get(i);
- elements[i] = item.getElement() != null ? item.getElement() : item;
- itemsMap.put(item.getElement(), item);
- }
-
- return getPsiElementPopup(elements, itemsMap, title, new Processor<Object>() {
- @Override
- public boolean process(Object element) {
- if (element instanceof PsiElement) {
- //noinspection SuspiciousMethodCalls
- itemsMap.get(element).navigate();
- }
- else {
- ((GotoRelatedItem)element).navigate();
- }
- return true;
- }
- }
- );
- }
-
- private static JBPopup getPsiElementPopup(final Object[] elements, final Map<PsiElement, GotoRelatedItem> itemsMap,
- final String title, final Processor<Object> processor) {
-
- final Ref<Boolean> hasMnemonic = Ref.create(false);
- final DefaultPsiElementCellRenderer renderer = new DefaultPsiElementCellRenderer() {
- {
- setFocusBorderEnabled(false);
- }
-
- @Override
- public String getElementText(PsiElement element) {
- String customName = itemsMap.get(element).getCustomName();
- return (customName != null ? customName : super.getElementText(element));
- }
-
- @Override
- protected Icon getIcon(PsiElement element) {
- Icon customIcon = itemsMap.get(element).getCustomIcon();
- return customIcon != null ? customIcon : super.getIcon(element);
- }
-
- @Override
- public String getContainerText(PsiElement element, String name) {
- String customContainerName = itemsMap.get(element).getCustomContainerName();
-
- if (customContainerName != null) {
- return customContainerName;
- }
- PsiFile file = element.getContainingFile();
- return file != null && !getElementText(element).equals(file.getName())
- ? "(" + file.getName() + ")"
- : null;
- }
-
- @Override
- protected DefaultListCellRenderer getRightCellRenderer(Object value) {
- return null;
- }
-
- @Override
- protected boolean customizeNonPsiElementLeftRenderer(ColoredListCellRenderer renderer,
- JList list,
- Object value,
- int index,
- boolean selected,
- boolean hasFocus) {
- final GotoRelatedItem item = (GotoRelatedItem)value;
- Color color = list.getForeground();
- final SimpleTextAttributes nameAttributes = new SimpleTextAttributes(Font.PLAIN, color);
- final String name = item.getCustomName();
- if (name == null) return false;
- renderer.append(name, nameAttributes);
- renderer.setIcon(item.getCustomIcon());
- return true;
- }
-
- @Override
- public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
- final JPanel component = (JPanel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
- if (!hasMnemonic.get()) return component;
-
- final JPanel panelWithMnemonic = new JPanel(new BorderLayout());
- final int mnemonic = getMnemonic(value, itemsMap);
- final JLabel label = new JLabel("");
- if (mnemonic != -1) {
- label.setText(mnemonic + ".");
- label.setDisplayedMnemonicIndex(0);
- }
- label.setPreferredSize(new JLabel("8.").getPreferredSize());
-
- final JComponent leftRenderer = (JComponent)component.getComponents()[0];
- component.remove(leftRenderer);
- panelWithMnemonic.setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 0));
- panelWithMnemonic.setBackground(leftRenderer.getBackground());
- label.setBackground(leftRenderer.getBackground());
- panelWithMnemonic.add(label, BorderLayout.WEST);
- panelWithMnemonic.add(leftRenderer, BorderLayout.CENTER);
- component.add(panelWithMnemonic);
- return component;
- }
- };
- final ListPopupImpl popup = new ListPopupImpl(new BaseListPopupStep<Object>(title, Arrays.asList(elements)) {
- @Override
- public boolean isSpeedSearchEnabled() {
- return true;
- }
-
- @Override
- public String getIndexedString(Object value) {
- if (value instanceof GotoRelatedItem) {
- //noinspection ConstantConditions
- return ((GotoRelatedItem)value).getCustomName();
- }
- final PsiElement element = (PsiElement)value;
- return renderer.getElementText(element) + " " + renderer.getContainerText(element, null);
- }
-
- @Override
- public PopupStep onChosen(Object selectedValue, boolean finalChoice) {
- processor.process(selectedValue);
- return super.onChosen(selectedValue, finalChoice);
- }
- }) {
- };
- popup.getList().setCellRenderer(new PopupListElementRenderer(popup) {
- Map<Object, String> separators = new HashMap<Object, String>();
- {
- final ListModel model = popup.getList().getModel();
- String current = null;
- boolean hasTitle = false;
- for (int i = 0; i < model.getSize(); i++) {
- final Object element = model.getElementAt(i);
- final GotoRelatedItem item = itemsMap.get(element);
- if (item != null && !StringUtil.equals(current, item.getGroup())) {
- current = item.getGroup();
- separators.put(element, current);
- if (!hasTitle && !StringUtil.isEmpty(current)) {
- hasTitle = true;
- }
- }
- }
-
- if (!hasTitle) {
- separators.remove(model.getElementAt(0));
- }
- }
- @Override
- public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
- final Component component = renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
- final String separator = separators.get(value);
-
- if (separator != null) {
- JPanel panel = new JPanel(new BorderLayout());
- panel.add(component, BorderLayout.CENTER);
- final SeparatorWithText sep = new SeparatorWithText() {
- @Override
- protected void paintComponent(Graphics g) {
- g.setColor(new JBColor(Color.WHITE, UIUtil.getSeparatorColor()));
- g.fillRect(0,0,getWidth(), getHeight());
- super.paintComponent(g);
- }
- };
- sep.setCaption(separator);
- panel.add(sep, BorderLayout.NORTH);
- return panel;
- }
- return component;
- }
- });
-
- popup.setMinimumSize(new Dimension(200, -1));
-
- for (Object item : elements) {
- final int mnemonic = getMnemonic(item, itemsMap);
- if (mnemonic != -1) {
- final Action action = createNumberAction(mnemonic, popup, itemsMap, processor);
- popup.registerAction(mnemonic + "Action", KeyStroke.getKeyStroke(String.valueOf(mnemonic)), action);
- popup.registerAction(mnemonic + "Action", KeyStroke.getKeyStroke("NUMPAD" + String.valueOf(mnemonic)), action);
- hasMnemonic.set(true);
- }
- }
- return popup;
+ NavigationUtil.getRelatedItemsPopup(items, "Choose Target").showInBestPositionFor(e.getDataContext());
}
@TestOnly
@NotNull
public static List<GotoRelatedItem> getItems(@NotNull PsiFile psiFile, @Nullable Editor editor, @Nullable DataContext dataContext) {
- return getItems(getContextElement(psiFile, editor), dataContext);
+ return NavigationUtil.collectRelatedItems(getContextElement(psiFile, editor), dataContext);
}
@Nullable
@@ -294,65 +84,4 @@ public class GotoRelatedSymbolAction extends AnAction {
}
return contextElement;
}
-
- @NotNull
- public static List<GotoRelatedItem> getItems(@NotNull PsiElement contextElement, @Nullable DataContext dataContext) {
- Set<GotoRelatedItem> items = ContainerUtil.newLinkedHashSet();
- for (GotoRelatedProvider provider : Extensions.getExtensions(GotoRelatedProvider.EP_NAME)) {
- items.addAll(provider.getItems(contextElement));
- if (dataContext != null) {
- items.addAll(provider.getItems(dataContext));
- }
- }
- sortByGroupNames(items);
- return new ArrayList<GotoRelatedItem>(items);
- }
-
- private static void sortByGroupNames(Set<GotoRelatedItem> items) {
- Map<String, List<GotoRelatedItem>> map = new HashMap<String, List<GotoRelatedItem>>();
- for (GotoRelatedItem item : items) {
- final String key = item.getGroup();
- if (!map.containsKey(key)) {
- map.put(key, new ArrayList<GotoRelatedItem>());
- }
- map.get(key).add(item);
- }
- final List<String> keys = new ArrayList<String>(map.keySet());
- Collections.sort(keys, new Comparator<String>() {
- @Override
- public int compare(String o1, String o2) {
- return StringUtil.isEmpty(o1) ? 1 : StringUtil.isEmpty(o2) ? -1 : o1.compareTo(o2);
- }
- });
- items.clear();
- for (String key : keys) {
- items.addAll(map.get(key));
- }
- }
-
- private static Action createNumberAction(final int mnemonic,
- final ListPopupImpl listPopup,
- final Map<PsiElement, GotoRelatedItem> itemsMap,
- final Processor<Object> processor) {
- return new AbstractAction() {
- @Override
- public void actionPerformed(ActionEvent e) {
- for (final Object item : listPopup.getListStep().getValues()) {
- if (getMnemonic(item, itemsMap) == mnemonic) {
- listPopup.setFinalRunnable(new Runnable() {
- @Override
- public void run() {
- processor.process(item);
- }
- });
- listPopup.closeOk(null);
- }
- }
- }
- };
- }
-
- private static int getMnemonic(Object item, Map<PsiElement, GotoRelatedItem> itemsMap) {
- return (item instanceof GotoRelatedItem ? (GotoRelatedItem)item : itemsMap.get((PsiElement)item)).getMnemonic();
- }
}
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java
index 3e28023a935c..531f3e52159f 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,7 +49,8 @@ public class SearchAgainAction extends AnAction implements DumbAware {
public void run() {
PsiDocumentManager.getInstance(project).commitAllDocuments();
IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation();
- if(FindManager.getInstance(project).findNextUsageInEditor(editor)) {
+ FindManager findManager = FindManager.getInstance(project);
+ if(!findManager.selectNextOccurrenceWasPerformed() && findManager.findNextUsageInEditor(editor)) {
return;
}
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java
index 4783205ae8c0..5f6e0d9959bd 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,8 @@ public class SearchBackAction extends AnAction implements DumbAware {
@Override
public void run() {
PsiDocumentManager.getInstance(project).commitAllDocuments();
- if(FindManager.getInstance(project).findPreviousUsageInEditor(editor)) {
+ FindManager findManager = FindManager.getInstance(project);
+ if(!findManager.selectNextOccurrenceWasPerformed() && findManager.findPreviousUsageInEditor(editor)) {
return;
}
FindUtil.searchBack(project, editor, e.getDataContext());
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
index ae7ee4363247..d704e738efa3 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
@@ -108,11 +108,9 @@ import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.*;
-import java.lang.reflect.Field;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
/**
* @author Konstantin Bulenkov
@@ -2120,13 +2118,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
private SearchListModel() {
super();
- try {
- final Field field = DefaultListModel.class.getDeclaredField("delegate");
- field.setAccessible(true);
- myDelegate = (Vector)field.get(this);
- }
- catch (NoSuchFieldException ignore) {}
- catch (IllegalAccessException ignore) {}
+ myDelegate = ReflectionUtil.getField(DefaultListModel.class, this, Vector.class, "delegate");
}
int next(int index) {
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java
index bb80f55237e5..c4708c48d19f 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/AbstractProjectViewPane.java
@@ -29,6 +29,7 @@ import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.impl.nodes.AbstractModuleNode;
import com.intellij.ide.projectView.impl.nodes.AbstractProjectNode;
import com.intellij.ide.projectView.impl.nodes.ModuleGroupNode;
+import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
import com.intellij.ide.util.treeView.*;
import com.intellij.injected.editor.VirtualFileWindow;
import com.intellij.openapi.Disposable;
@@ -54,6 +55,7 @@ import com.intellij.psi.util.PsiUtilCore;
import com.intellij.refactoring.move.MoveHandler;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ReflectionUtil;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
@@ -481,6 +483,27 @@ public abstract class AbstractProjectViewPane implements DataProvider, Disposabl
}
public PsiDirectory[] getSelectedDirectories() {
+ List<PsiDirectory> directories = ContainerUtil.newArrayList();
+ for (PsiDirectoryNode node : getSelectedNodes(PsiDirectoryNode.class)) {
+ PsiDirectory directory = node.getValue();
+ if (directory != null) {
+ directories.add(directory);
+ Object parentValue = node.getParent().getValue();
+ if (parentValue instanceof PsiDirectory) {
+ while (true) {
+ directory = directory.getParentDirectory();
+ if (directory == null || directory.equals(parentValue)) {
+ break;
+ }
+ directories.add(directory);
+ }
+ }
+ }
+ }
+ if (!directories.isEmpty()) {
+ return directories.toArray(new PsiDirectory[directories.size()]);
+ }
+
final PsiElement[] elements = getSelectedPSIElements();
if (elements.length == 1) {
final PsiElement element = elements[0];
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/ChangeListTodosPanel.java b/platform/lang-impl/src/com/intellij/ide/todo/ChangeListTodosPanel.java
index 2aa89adeb3b5..2a6c396e1e3e 100644
--- a/platform/lang-impl/src/com/intellij/ide/todo/ChangeListTodosPanel.java
+++ b/platform/lang-impl/src/com/intellij/ide/todo/ChangeListTodosPanel.java
@@ -65,7 +65,12 @@ public abstract class ChangeListTodosPanel extends TodoPanel{
@Override
public void changeListRenamed(final ChangeList list, final String oldName) {
- setDisplayName(IdeBundle.message("changelist.todo.title", list.getName()));
+ AppUIUtil.invokeOnEdt(new Runnable() {
+ @Override
+ public void run() {
+ setDisplayName(IdeBundle.message("changelist.todo.title", list.getName()));
+ }
+ });
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
index f260c732adf5..35f7f658edfd 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
@@ -65,6 +65,7 @@ import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.HashSet;
@@ -83,7 +84,6 @@ import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.*;
-import java.lang.reflect.Field;
import java.util.*;
import java.util.List;
@@ -1018,22 +1018,13 @@ public class FileStructurePopup implements Disposable {
public FileStructureTree(Object rootElement, boolean fastExpand) {
super(new DefaultMutableTreeNode(rootElement));
if (fastExpand) {
- boolean newValueIsSet;
- try {
- final Field field = JTree.class.getDeclaredField("expandedState");
- field.setAccessible(true);
- field.set(this, new Hashtable() {
- @Override
- public synchronized Object get(Object key) {
- return Boolean.TRUE;
- }
- });
- newValueIsSet = true;
- }
- catch (Exception e) {
- newValueIsSet = false;
- }
- fast = newValueIsSet;
+ Hashtable hashtable = new Hashtable() {
+ @Override
+ public synchronized Object get(Object key) {
+ return Boolean.TRUE;
+ }
+ };
+ fast = ReflectionUtil.setField(JTree.class, this, Hashtable.class, "expandedState", hashtable);
}
else {
fast = false;
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
index dcc1429c8bbd..3e90f2310884 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java
@@ -35,6 +35,7 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationAdapter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.fileTypes.UnknownFileType;
@@ -102,6 +103,7 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public abstract class ChooseByNameBase {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.ChooseByNameBase");
protected final Project myProject;
protected final ChooseByNameModel myModel;
protected ChooseByNameItemProvider myProvider;
@@ -133,7 +135,6 @@ public abstract class ChooseByNameBase {
private final ListUpdater myListUpdater = new ListUpdater();
- private volatile boolean myListIsUpToDate = false;
private boolean myDisposedFlag = false;
private ActionCallback myPostponedOkAction;
@@ -278,7 +279,7 @@ public abstract class ChooseByNameBase {
if (PlatformDataKeys.HELP_ID.is(dataId)) {
return myModel.getHelpId();
}
- if (!myListIsUpToDate) {
+ if (myCalcElementsThread != null) {
return null;
}
if (CommonDataKeys.PSI_ELEMENT.is(dataId)) {
@@ -499,7 +500,7 @@ public abstract class ChooseByNameBase {
myTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(@NotNull final FocusEvent e) {
- cancelCalcElementsThread(); // cancel thread as early as possible
+ cancelListUpdater(); // cancel thread as early as possible
myHideAlarm.addRequest(new Runnable() {
@Override
public void run() {
@@ -531,7 +532,7 @@ public abstract class ChooseByNameBase {
if (queue instanceof IdeEventQueue) {
if (!((IdeEventQueue)queue).wasRootRecentlyClicked(oppositeComponent)) {
Component root = SwingUtilities.getRoot(myTextField);
- if (root != null) {
+ if (root != null && root.isShowing()) {
root.requestFocus();
myTextField.requestFocus();
return;
@@ -759,24 +760,29 @@ public abstract class ChooseByNameBase {
}
protected void doClose(final boolean ok) {
- try {
- if (checkDisposed()) return;
+ if (checkDisposed()) return;
- if (postponeCloseWhenListReady(ok)) return;
+ if (postponeCloseWhenListReady(ok)) return;
- cancelListUpdater();
- close(ok);
+ cancelListUpdater();
+ close(ok);
- clearPostponedOkAction(ok);
- }
- finally {
- myListModel.clear();
- cancelCalcElementsThread();
- }
+ clearPostponedOkAction(ok);
+ myListModel.clear();
}
protected void cancelListUpdater() {
- cancelCalcElementsThread();
+ final CalcElementsThread calcElementsThread = myCalcElementsThread;
+ if (calcElementsThread != null && calcElementsThread.cancel()) {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ if (!checkDisposed() && calcElementsThread == myCalcElementsThread) {
+ backgroundCalculationFinished(Collections.emptyList(), 0);
+ }
+ }
+ });
+ }
myListUpdater.cancelAll();
}
@@ -784,7 +790,7 @@ public abstract class ChooseByNameBase {
if (!isToFixLostTyping()) return false;
final String text = myTextField.getText();
- if (ok && !myListIsUpToDate && text != null && !text.trim().isEmpty()) {
+ if (ok && myCalcElementsThread != null && text != null && !text.trim().isEmpty()) {
myPostponedOkAction = new ActionCallback();
IdeFocusManager.getInstance(myProject).typeAheadUntil(myPostponedOkAction);
return true;
@@ -885,7 +891,7 @@ public abstract class ChooseByNameBase {
Disposer.register(myTextPopup, new Disposable() {
@Override
public void dispose() {
- cancelCalcElementsThread();
+ cancelListUpdater();
}
});
myTextPopup.show(layeredPane);
@@ -917,8 +923,6 @@ public abstract class ChooseByNameBase {
return layeredPane;
}
- private final Object myRebuildMutex = new Object();
-
protected void rebuildList(final int pos,
final int delay,
@NotNull final ModalityState modalityState,
@@ -928,11 +932,13 @@ public abstract class ChooseByNameBase {
return;
}
- myListIsUpToDate = false;
myAlarm.cancelAllRequests();
myListUpdater.cancelAll();
- cancelCalcElementsThread();
+ final CalcElementsThread calcElementsThread = myCalcElementsThread;
+ if (calcElementsThread != null) {
+ calcElementsThread.cancel();
+ }
final String text = myTextField.getText();
if (!canShowListForEmptyPattern() &&
@@ -960,24 +966,14 @@ public abstract class ChooseByNameBase {
scheduleCalcElements(text, myCheckBox.isSelected(), modalityState, new Consumer<Set<?>>() {
@Override
public void consume(Set<?> elements) {
- synchronized (myRebuildMutex) {
- ApplicationManager.getApplication().assertIsDispatchThread();
- if (checkDisposed()) {
- return;
- }
-
- myListIsUpToDate = true;
- setElementsToList(pos, elements);
- myList.repaint();
- chosenElementMightChange();
-
- if (elements.isEmpty()) {
- myTextFieldPanel.hideHint();
- }
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ if (checkDisposed()) {
+ return;
+ }
+ backgroundCalculationFinished(elements, pos);
- if (postRunnable != null) {
- postRunnable.run();
- }
+ if (postRunnable != null) {
+ postRunnable.run();
}
}
});
@@ -992,6 +988,17 @@ public abstract class ChooseByNameBase {
}
}
+ private void backgroundCalculationFinished(Collection<?> result, int toSelect) {
+ myCalcElementsThread = null;
+ setElementsToList(toSelect, result);
+ myList.repaint();
+ chosenElementMightChange();
+
+ if (result.isEmpty()) {
+ myTextFieldPanel.hideHint();
+ }
+ }
+
public void scheduleCalcElements(String text,
boolean checkboxState,
ModalityState modalityState,
@@ -1008,16 +1015,7 @@ public abstract class ChooseByNameBase {
return myShowListAfterCompletionKeyStroke;
}
- private CalcElementsThread cancelCalcElementsThread() {
- CalcElementsThread calcElementsThread = myCalcElementsThread;
- if (calcElementsThread != null) {
- calcElementsThread.cancel();
- myCalcElementsThread = null;
- }
- return calcElementsThread;
- }
-
- private void setElementsToList(int pos, @NotNull Set<?> elements) {
+ private void setElementsToList(int pos, @NotNull Collection<?> elements) {
myListUpdater.cancelAll();
if (checkDisposed()) return;
if (elements.isEmpty()) {
@@ -1202,33 +1200,12 @@ public abstract class ChooseByNameBase {
}
protected List<Object> getChosenElements() {
-
- List<Object> values = new ArrayList<Object>(Arrays.asList(myList.getSelectedValues()));
- values.remove(EXTRA_ELEM);
- values.remove(NON_PREFIX_SEPARATOR);
-
- if (myListIsUpToDate || !values.isEmpty()) {
- return values;
- }
-
- final String text = myTextField.getText();
- if (text.length() == 0) return Collections.emptyList();
- final boolean checkBoxState = myCheckBox.isSelected();
- final String[] names = ourLoadNamesEachTime ? ensureNamesLoaded(checkBoxState) : getNamesSync(checkBoxState);
- if (names == null) return Collections.emptyList();
-
- Object uniqueElement = null;
-
- for (final String name : names) {
- if (text.equalsIgnoreCase(name)) {
- final Object[] elements = myModel.getElementsByName(name, checkBoxState, text);
- if (elements.length > 1) return Collections.emptyList();
- if (elements.length == 0) continue;
- if (uniqueElement != null) return Collections.emptyList();
- uniqueElement = elements[0];
+ return ContainerUtil.filter(myList.getSelectedValues(), new Condition<Object>() {
+ @Override
+ public boolean value(Object o) {
+ return o != EXTRA_ELEM && o != NON_PREFIX_SEPARATOR;
}
- }
- return uniqueElement == null ? Collections.emptyList() : Collections.singletonList(uniqueElement);
+ });
}
protected void chosenElementMightChange() {
@@ -1565,6 +1542,7 @@ public abstract class ChooseByNameBase {
@Override
public void run() {
if (!myCancelled.isCanceled()) {
+ LOG.assertTrue(myCalcElementsThread == CalcElementsThread.this);
myCallback.consume(edt ? filter(elements) : filtered);
}
}
@@ -1622,8 +1600,12 @@ public abstract class ChooseByNameBase {
return elementsArray.size() >= myMaximumListSizeLimit;
}
- private void cancel() {
+ private boolean cancel() {
+ if (myCancelled.isCanceled()) {
+ return false;
+ }
myCancelled.cancel();
+ return true;
}
}
@@ -1705,7 +1687,7 @@ public abstract class ChooseByNameBase {
final LinkedHashSet<Object> nonPrefixMatchElementsArray = new LinkedHashSet<Object>();
hideHint();
ProgressManager.getInstance().run(new Task.Modal(myProject, prefixPattern, true) {
- private ChooseByNameBase.CalcElementsThread myCalcElementsThread;
+ private ChooseByNameBase.CalcElementsThread myCalcUsagesThread;
@Override
public void run(@NotNull final ProgressIndicator indicator) {
@@ -1716,7 +1698,7 @@ public abstract class ChooseByNameBase {
@Override
public void run() {
final boolean[] overFlow = {false};
- myCalcElementsThread = new CalcElementsThread(text, everywhere, null, ModalityState.NON_MODAL, false) {
+ myCalcUsagesThread = new CalcElementsThread(text, everywhere, null, ModalityState.NON_MODAL, false) {
private final AtomicBoolean userAskedToAbort = new AtomicBoolean();
@Override
protected boolean isOverflow(@NotNull Set<Object> elementsArray) {
@@ -1734,11 +1716,11 @@ public abstract class ChooseByNameBase {
boolean anyPlace = isSearchInAnyPlace();
setSearchInAnyPlace(false);
- myCalcElementsThread.addElementsByPattern(text, prefixMatchElementsArray, indicator, everywhere);
+ myCalcUsagesThread.addElementsByPattern(text, prefixMatchElementsArray, indicator, everywhere);
setSearchInAnyPlace(anyPlace);
if (anyPlace && !overFlow[0]) {
- myCalcElementsThread.addElementsByPattern(text, nonPrefixMatchElementsArray, indicator, everywhere);
+ myCalcUsagesThread.addElementsByPattern(text, nonPrefixMatchElementsArray, indicator, everywhere);
nonPrefixMatchElementsArray.removeAll(prefixMatchElementsArray);
}
@@ -1756,7 +1738,7 @@ public abstract class ChooseByNameBase {
@Override
public void onCancel() {
- cancelCalcElementsThread();
+ myCalcUsagesThread.cancel();
}
});
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java
index cb03b68bfadb..86d9c1782b2a 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java
@@ -339,7 +339,7 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP
}
private static final Pattern patternToDetectLinesAndColumns = Pattern.compile("([^:]+)(?::|@|,|)\\[?(\\d+)?(?:(?:\\D)(\\d+)?)?\\]?");
- private static final Pattern patternToDetectAnonymousClasses = Pattern.compile("([\\.\\w]+)((\\$[\\d]+)*(\\$)?)");
+ public static final Pattern patternToDetectAnonymousClasses = Pattern.compile("([\\.\\w]+)((\\$[\\d]+)*(\\$)?)");
private static final Pattern patternToDetectMembers = Pattern.compile("(.+)(#)(.*)");
@Override
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java
index aa6a360c84e5..cc5915c26bb6 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultChooseByNameItemProvider.java
@@ -189,6 +189,7 @@ public class DefaultChooseByNameItemProvider implements ChooseByNameItemProvider
@NotNull
private static String getQualifierPattern(@NotNull ChooseByNameBase base, @NotNull String pattern) {
+ pattern = base.transformPattern(pattern);
final String[] separators = base.getModel().getSeparators();
int lastSeparatorOccurrence = 0;
for (String separator : separators) {
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionItemProvider.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionItemProvider.java
index a6e6c8fdf658..99d3c9b338ae 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionItemProvider.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionItemProvider.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.impl.ActionManagerImpl;
import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
import com.intellij.util.Function;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
@@ -128,17 +129,19 @@ public class GotoActionItemProvider implements ChooseByNameItemProvider {
List<AnAction> actions = ContainerUtil.newArrayList();
if (everywhere) {
for (String id : ((ActionManagerImpl)myActionManager).getActionIds()) {
+ ProgressManager.checkCanceled();
ContainerUtil.addIfNotNull(actions, myActionManager.getAction(id));
}
} else {
- actions.addAll(myModel.myActionsMap.keySet());
+ actions.addAll(myModel.myActionGroups.keySet());
}
List<ActionWrapper> actionWrappers = ContainerUtil.newArrayList();
for (AnAction action : actions) {
+ ProgressManager.checkCanceled();
MatchMode mode = myModel.actionMatches(pattern, action);
if (mode != MatchMode.NONE) {
- actionWrappers.add(new ActionWrapper(action, myModel.myActionsMap.get(action), mode, dataContext));
+ actionWrappers.add(new ActionWrapper(action, myModel.myActionGroups.get(action), mode, dataContext));
}
}
return processItems(pattern, actionWrappers, consumer);
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java
index 91f0d3368521..348283dc3885 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java
@@ -66,16 +66,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
private Pattern myCompiledPattern;
protected final SearchableOptionsRegistrar myIndex;
- protected final Map<AnAction, String> myActionsMap = new TreeMap<AnAction, String>(new Comparator<AnAction>() {
- @Override
- public int compare(@NotNull AnAction o1, @NotNull AnAction o2) {
- int compare = Comparing.compare(o1.getTemplatePresentation().getText(), o2.getTemplatePresentation().getText());
- if (compare == 0 && !o1.equals(o2)) {
- return o1.hashCode() - o2.hashCode();
- }
- return compare;
- }
- });
+ protected final Map<AnAction, String> myActionGroups = ContainerUtil.newHashMap();
protected final Map<String, ApplyIntentionAction> myIntentions = new TreeMap<String, ApplyIntentionAction>();
private final Map<String, String> myConfigurablesNames = ContainerUtil.newTroveMap();
@@ -88,7 +79,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
myProject = project;
myContextComponent = component;
final ActionGroup mainMenu = (ActionGroup)myActionManager.getActionOrStub(IdeActions.GROUP_MAIN_MENU);
- collectActions(myActionsMap, mainMenu, mainMenu.getTemplatePresentation().getText());
+ collectActions(myActionGroups, mainMenu, mainMenu.getTemplatePresentation().getText());
if (project != null && editor != null && file != null) {
final ApplyIntentionAction[] children = ApplyIntentionAction.getAvailableIntentions(editor, file);
if (children != null) {
@@ -98,6 +89,9 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
}
}
myIndex = SearchableOptionsRegistrar.getInstance();
+ if (!EventQueue.isDispatchThread()) {
+ return;
+ }
fillConfigurablesNames(ShowSettingsUtilImpl.getConfigurables(project, true));
}
@@ -457,11 +451,14 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
else if (description != null && !description.equals(text) && matcher.matches(description, compiledPattern)) {
return MatchMode.DESCRIPTION;
}
- final String groupName = myActionsMap.get(anAction);
+ if (text == null) {
+ return MatchMode.NONE;
+ }
+ final String groupName = myActionGroups.get(anAction);
if (groupName == null) {
- return text != null && matcher.matches(text, compiledPattern) ? MatchMode.NON_MENU : MatchMode.NONE;
+ return matcher.matches(text, compiledPattern) ? MatchMode.NON_MENU : MatchMode.NONE;
}
- return text != null && matcher.matches(groupName + " " + text, compiledPattern) ? MatchMode.GROUP : MatchMode.NONE;
+ return matcher.matches(groupName + " " + text, compiledPattern) ? MatchMode.GROUP : MatchMode.NONE;
}
@Nullable
@@ -611,7 +608,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C
PatternMatcher getMatcher() {
return myMatcher.get();
}
-
+
public static class ActionWrapper implements Comparable<ActionWrapper>{
private final AnAction myAction;
private final MatchMode myMode;
diff --git a/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java b/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java
index 63d8a6038b6a..6350642c772e 100644
--- a/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java
+++ b/platform/lang-impl/src/com/intellij/internal/DumpLookupElementWeights.java
@@ -22,7 +22,6 @@ import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
@@ -53,7 +52,12 @@ public class DumpLookupElementWeights extends AnAction implements DumbAware {
}
public static void dumpLookupElementWeights(final LookupImpl lookup) {
- String sb = StringUtil.join(getLookupElementWeights(lookup), "\n");
+ LookupElement selected = lookup.getCurrentItem();
+ String sb = "selected: " + selected;
+ if (selected != null) {
+ sb += "\nprefix: " + lookup.itemPattern(selected);
+ }
+ sb += "\nweights:\n" + StringUtil.join(getLookupElementWeights(lookup), "\n");
System.out.println(sb);
LOG.info(sb);
}
diff --git a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java
index ad322c232fa0..ccf63a429346 100644
--- a/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java
+++ b/platform/lang-impl/src/com/intellij/lang/parser/GeneratedParserUtilBase.java
@@ -100,8 +100,7 @@ public class GeneratedParserUtilBase {
if (!goodMarker) return false;
ErrorState state = ErrorState.get(builder_);
- Frame frame = state.frameStack.peekLast();
- return frame == null || frame.errorReportedAt <= builder_.rawTokenIndex();
+ return !state.frameStack.isEmpty();
}
public static TokenSet create_token_set_(IElementType... tokenTypes_) {
@@ -399,6 +398,11 @@ public class GeneratedParserUtilBase {
private static void enter_section_impl_(PsiBuilder builder_, int level, int modifiers, @Nullable String frameName) {
ErrorState state = ErrorState.get(builder_);
Frame frame = state.FRAMES.alloc().init(builder_, state, level, modifiers, frameName);
+ Frame prevFrame = state.frameStack.peekLast();
+ if (prevFrame != null && prevFrame.errorReportedAt > frame.position) {
+ // report error for previous unsuccessful frame
+ reportError(builder_, state, frame, true, false);
+ }
if (((frame.modifiers & _LEFT_) | (frame.modifiers & _LEFT_INNER_)) != 0) {
PsiBuilder.Marker left = (PsiBuilder.Marker)builder_.getLatestDoneMarker();
if (invalid_left_marker_guard_(builder_, left, frameName)) {
@@ -456,10 +460,10 @@ public class GeneratedParserUtilBase {
state.clearVariants(true, frame.variantCount);
addVariantInner(state, initialPos, frame.name);
}
+ int lastErrorPos = getLastVariantPos(state, initialPos);
if (!state.suppressErrors && eatMore != null) {
state.suppressErrors = true;
final boolean eatMoreFlagOnce = !builder_.eof() && eatMore.parse(builder_, frame.level + 1);
- final int lastErrorPos = getLastVariantPos(state, initialPos);
boolean eatMoreFlag = eatMoreFlagOnce || !result && frame.position == initialPos && lastErrorPos > frame.position;
PsiBuilderImpl.ProductionMarker latestDoneMarker =
@@ -497,7 +501,7 @@ public class GeneratedParserUtilBase {
errorReported = reportError(builder_, state, frame, true, true);
parseAsTree(state, builder_, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
}
- else if (eatMoreFlagOnce || (!result && frame.position != builder_.rawTokenIndex())) {
+ else if (eatMoreFlagOnce || (!result && frame.position != builder_.rawTokenIndex()) || frame.errorReportedAt > initialPos) {
errorReported = reportError(builder_, state, frame, true, false);
}
if (extensionMarker != null) {
@@ -512,10 +516,14 @@ public class GeneratedParserUtilBase {
}
else if (!result && pinned && frame.errorReportedAt < 0) {
// do not report if there are errors beyond current position
- if (getLastVariantPos(state, initialPos) == initialPos) {
+ if (lastErrorPos == initialPos) {
// do not force, inner recoverRoot might have skipped some tokens
reportError(builder_, state, frame, false, false);
}
+ else if (lastErrorPos > initialPos) {
+ // set error pos here as if it is reported for future reference
+ frame.errorReportedAt = lastErrorPos;
+ }
}
// propagate errorReportedAt up the stack to avoid duplicate reporting
Frame prevFrame = willFail && eatMore == null ? null : state.frameStack.peekLast();
@@ -607,7 +615,7 @@ public class GeneratedParserUtilBase {
return;
}
int position = builder_.rawTokenIndex();
- if (frame.errorReportedAt < position && getLastVariantPos(state, position) <= position) {
+ if (frame.errorReportedAt < position && getLastVariantPos(state, position + 1) <= position) {
reportError(builder_, state, frame, true, advance);
}
}
@@ -865,7 +873,7 @@ public class GeneratedParserUtilBase {
((modifiers & _LEFT_INNER_) != 0? "_LEFT_INNER_, ": "") +
((modifiers & _AND_) != 0? "_AND_, ": "") +
((modifiers & _NOT_) != 0? "_NOT_, ": "");
- return "<" + offset + ", " + mod + level + (errorReportedAt > -1 ? ", [" + errorReportedAt + "]" : "") + ">";
+ return String.format("{%s:%s:%d, %d, %s%s}", offset, position, level, errorReportedAt, mod, name);
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java
index 3e284ff6b2cc..ae2a4dc0d53c 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectAllOccurrencesAction.java
@@ -42,8 +42,6 @@ public class SelectAllOccurrencesAction extends EditorAction {
@Override
public void doExecute(final Editor editor, @Nullable Caret c, DataContext dataContext) {
- if (executeEquivalentFindPanelAction(editor, dataContext)) return;
-
Caret caret = c == null ? editor.getCaretModel().getPrimaryCaret() : c;
boolean wholeWordsSearch = false;
@@ -88,10 +86,5 @@ public class SelectAllOccurrencesAction extends EditorAction {
}, caretShiftFromSelectionStart);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
-
- @Override
- protected EditorHeaderAction getEquivalentFindPanelAction(EditorSearchComponent searchComponent) {
- return new SelectAllAction(searchComponent);
- }
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectNextOccurrenceAction.java b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectNextOccurrenceAction.java
index 7d3c408ee152..74390f15b149 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectNextOccurrenceAction.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectNextOccurrenceAction.java
@@ -40,8 +40,6 @@ public class SelectNextOccurrenceAction extends EditorAction {
@Override
public void doExecute(Editor editor, @Nullable Caret c, DataContext dataContext) {
- if (executeEquivalentFindPanelAction(editor, dataContext)) return;
-
Caret caret = c == null ? editor.getCaretModel().getPrimaryCaret() : c;
TextRange wordSelectionRange = getSelectionRange(editor, caret);
boolean notFoundPreviously = getAndResetNotFoundStatus(editor);
@@ -56,7 +54,7 @@ public class SelectNextOccurrenceAction extends EditorAction {
FindModel model = getFindModel(selectedText, wholeWordSearch);
- findManager.setFindWasPerformed();
+ findManager.setSelectNextOccurrenceWasPerformed();
findManager.setFindNextModel(model);
int searchStartOffset = notFoundPreviously ? 0 : caret.getSelectionEnd();
@@ -84,10 +82,5 @@ public class SelectNextOccurrenceAction extends EditorAction {
}
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
-
- @Override
- protected EditorHeaderAction getEquivalentFindPanelAction(EditorSearchComponent searchComponent) {
- return new AddOccurrenceAction(searchComponent);
- }
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectOccurrencesActionHandler.java b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectOccurrencesActionHandler.java
index 7b189281dfd0..1858ef53b3f5 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectOccurrencesActionHandler.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/actions/SelectOccurrencesActionHandler.java
@@ -107,25 +107,4 @@ abstract public class SelectOccurrencesActionHandler extends EditorActionHandler
model.setWholeWordsOnly(wholeWords);
return model;
}
-
- protected boolean executeEquivalentFindPanelAction(Editor editor, DataContext context) {
- if (editor.getHeaderComponent() instanceof EditorSearchComponent) {
- EditorSearchComponent searchComponent = (EditorSearchComponent)editor.getHeaderComponent();
- EditorHeaderAction action = getEquivalentFindPanelAction(searchComponent);
- if (action != null) {
- Presentation presentation = new Presentation();
- AnActionEvent event = new AnActionEvent(null, context, ActionPlaces.MAIN_MENU, presentation, ActionManager.getInstance(), 0);
- action.update(event);
- if (presentation.isEnabled()) {
- action.actionPerformed(event);
- return true;
- }
- }
- }
- return false;
- }
-
- protected EditorHeaderAction getEquivalentFindPanelAction(EditorSearchComponent searchComponent) {
- return null;
- }
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectPreviousOccurrenceAction.java b/platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectPreviousOccurrenceAction.java
index fffff56b12dc..a5657ff89b27 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectPreviousOccurrenceAction.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/actions/UnselectPreviousOccurrenceAction.java
@@ -15,9 +15,6 @@
*/
package com.intellij.openapi.editor.actions;
-import com.intellij.find.EditorSearchComponent;
-import com.intellij.find.editorHeaderActions.EditorHeaderAction;
-import com.intellij.find.editorHeaderActions.RemoveOccurrenceAction;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
@@ -38,8 +35,6 @@ public class UnselectPreviousOccurrenceAction extends EditorAction {
@Override
public void doExecute(Editor editor, @Nullable Caret caret, DataContext dataContext) {
- if (executeEquivalentFindPanelAction(editor, dataContext)) return;
-
if (editor.getCaretModel().getCaretCount() > 1) {
editor.getCaretModel().removeCaret(editor.getCaretModel().getPrimaryCaret());
}
@@ -49,10 +44,5 @@ public class UnselectPreviousOccurrenceAction extends EditorAction {
getAndResetNotFoundStatus(editor);
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
}
-
- @Override
- protected EditorHeaderAction getEquivalentFindPanelAction(EditorSearchComponent searchComponent) {
- return new RemoveOccurrenceAction(searchComponent);
- }
}
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/FontMapper.java b/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/FontMapper.java
index 4fec39342090..c5fd5592b634 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/FontMapper.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/FontMapper.java
@@ -16,10 +16,10 @@
package com.intellij.openapi.editor.richcopy;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
-import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Locale;
@@ -46,20 +46,18 @@ public class FontMapper {
}
Method findFontMethod = Class.forName("sun.font.FontManager").getMethod("findFont2D", String.class, int.class, int.class);
for (String logicalFont : logicalFontsToMap) {
- String physicalFont = null;
Object font2D = findFontMethod.invoke(fontManager, logicalFont, Font.PLAIN, 0);
if (font2D == null) {
continue;
}
String fontClassName = font2D.getClass().getName();
+ String physicalFont = null;
if ("sun.font.CompositeFont".equals(fontClassName)) { // Windows and Linux case
Object physicalFontObject = Class.forName("sun.font.CompositeFont").getMethod("getSlotFont", int.class).invoke(font2D, 0);
physicalFont = (String)Class.forName("sun.font.Font2D").getMethod("getFamilyName", Locale.class).invoke(physicalFontObject, Locale.getDefault());
}
else if ("sun.font.CFont".equals(fontClassName)) { // MacOS case
- Field field = Class.forName("sun.font.CFont").getDeclaredField("nativeFontName");
- field.setAccessible(true);
- physicalFont = (String)field.get(font2D);
+ physicalFont = ReflectionUtil.getField(Class.forName("sun.font.CFont"), font2D, String.class, "nativeFontName");
}
if (physicalFont != null) {
logicalToPhysicalMapping.put(logicalFont, physicalFont);
diff --git a/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/TextWithMarkupProcessor.java b/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/TextWithMarkupProcessor.java
index 54406106b976..504496a27716 100644
--- a/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/TextWithMarkupProcessor.java
+++ b/platform/lang-impl/src/com/intellij/openapi/editor/richcopy/TextWithMarkupProcessor.java
@@ -23,6 +23,7 @@ import com.intellij.ide.highlighter.HighlighterFactory;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.colors.FontPreferences;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.ex.DisposableIterator;
import com.intellij.openapi.editor.ex.MarkupModelEx;
@@ -418,7 +419,7 @@ public class TextWithMarkupProcessor extends CopyPastePostProcessor<RawTextWithM
private MarkupIterator(@NotNull CharSequence charSequence, @NotNull RangeIterator rangeIterator, @NotNull EditorColorsScheme colorsScheme) {
myRangeIterator = rangeIterator;
- mySegmentIterator = new SegmentIterator(charSequence, colorsScheme.getEditorFontName(), colorsScheme.getEditorFontSize());
+ mySegmentIterator = new SegmentIterator(charSequence, colorsScheme.getFontPreferences());
}
public boolean atEnd() {
@@ -812,8 +813,7 @@ public class TextWithMarkupProcessor extends CopyPastePostProcessor<RawTextWithM
private static class SegmentIterator {
private final CharSequence myCharSequence;
- private final String myDefaultFontFamilyName;
- private final int myFontSize;
+ private final FontPreferences myFontPreferences;
private int myCurrentStartOffset;
private int myCurrentOffset;
@@ -822,10 +822,9 @@ public class TextWithMarkupProcessor extends CopyPastePostProcessor<RawTextWithM
private String myCurrentFontFamilyName;
private String myNextFontFamilyName;
- private SegmentIterator(CharSequence charSequence, String defaultFontFamilyName, int fontSize) {
+ private SegmentIterator(CharSequence charSequence, FontPreferences fontPreferences) {
myCharSequence = charSequence;
- myDefaultFontFamilyName = defaultFontFamilyName;
- myFontSize = fontSize;
+ myFontPreferences = fontPreferences;
}
public void reset(int startOffset, int endOffset, int fontStyle) {
@@ -843,9 +842,8 @@ public class TextWithMarkupProcessor extends CopyPastePostProcessor<RawTextWithM
myCurrentStartOffset = myCurrentOffset;
for (; myCurrentOffset < myEndOffset; myCurrentOffset++) {
FontInfo fontInfo = ComplementaryFontsRegistry.getFontAbleToDisplay(myCharSequence.charAt(myCurrentOffset),
- myFontSize,
myFontStyle,
- myDefaultFontFamilyName);
+ myFontPreferences);
String fontFamilyName = fontInfo.getFont().getFamily();
if (myCurrentFontFamilyName == null) {
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java
index b1385686bc3a..09e489b3d1df 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java
@@ -25,15 +25,14 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ModuleRootAdapter;
-import com.intellij.openapi.roots.ModuleRootEvent;
-import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.*;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
+import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Query;
import com.intellij.util.containers.ConcurrentIntObjectMap;
import com.intellij.util.containers.StripedLockIntObjectConcurrentHashMap;
@@ -43,6 +42,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
public class DirectoryIndexImpl extends DirectoryIndex {
@@ -68,7 +69,7 @@ public class DirectoryIndexImpl extends DirectoryIndex {
});
}
- private void subscribeToFileChanges() {
+ protected void subscribeToFileChanges() {
myConnection.subscribe(FileTypeManager.TOPIC, new FileTypeListener.Adapter() {
@Override
public void fileTypesChanged(@NotNull FileTypeEvent event) {
@@ -98,7 +99,7 @@ public class DirectoryIndexImpl extends DirectoryIndex {
});
}
- private void markContentRootsForRefresh() {
+ protected void markContentRootsForRefresh() {
Module[] modules = ModuleManager.getInstance(myProject).getModules();
for (Module module : modules) {
VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
@@ -110,7 +111,7 @@ public class DirectoryIndexImpl extends DirectoryIndex {
}
}
- private void dispatchPendingEvents() {
+ protected void dispatchPendingEvents() {
myConnection.deliverImmediately();
}
@@ -124,24 +125,27 @@ public class DirectoryIndexImpl extends DirectoryIndex {
private RootIndex getRootIndex() {
RootIndex rootIndex = myRootIndex;
if (rootIndex == null) {
- myRootIndex = rootIndex = new RootIndex(myProject, new RootIndex.InfoCache() {
- // Upsource can't use int-mapping because different files may have the same id there
- private final ConcurrentIntObjectMap<DirectoryInfo> myInfoCache = new StripedLockIntObjectConcurrentHashMap<DirectoryInfo>();
- @Override
- public void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info) {
- myInfoCache.put(((NewVirtualFile)dir).getId(), info);
- }
-
- @Override
- public DirectoryInfo getCachedInfo(@NotNull VirtualFile dir) {
- return myInfoCache.get(((NewVirtualFile)dir).getId());
- }
- });
+ myRootIndex = rootIndex = new RootIndex(myProject, createRootInfoCache());
}
return rootIndex;
}
- @Override
+ protected RootIndex.InfoCache createRootInfoCache() {
+ return new RootIndex.InfoCache() {
+ // Upsource can't use int-mapping because different files may have the same id there
+ private final ConcurrentIntObjectMap<DirectoryInfo> myInfoCache = new StripedLockIntObjectConcurrentHashMap<DirectoryInfo>();
+ @Override
+ public void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info) {
+ myInfoCache.put(((NewVirtualFile)dir).getId(), info);
+ }
+
+ @Override
+ public DirectoryInfo getCachedInfo(@NotNull VirtualFile dir) {
+ return myInfoCache.get(((NewVirtualFile)dir).getId());
+ }
+ };
+ }
+
@TestOnly
public void checkConsistency() {
getRootIndex().checkConsistency();
@@ -181,6 +185,21 @@ public class DirectoryIndexImpl extends DirectoryIndex {
return getRootIndex().getPackageName(dir);
}
+ @NotNull
+ @Override
+ public OrderEntry[] getOrderEntries(@NotNull DirectoryInfo info) {
+ checkAvailability();
+ return getRootIndex().getOrderEntries(info);
+ }
+
+ @TestOnly
+ void assertConsistency(DirectoryInfo info) {
+ OrderEntry[] entries = getOrderEntries(info);
+ for (int i = 1; i < entries.length; i++) {
+ assert RootIndex.BY_OWNER_MODULE.compare(entries[i - 1], entries[i]) <= 0;
+ }
+ }
+
private void checkAvailability() {
if (myDisposed) {
ProgressManager.checkCanceled();
@@ -188,4 +207,95 @@ public class DirectoryIndexImpl extends DirectoryIndex {
}
}
+ @NotNull
+ private static OrderEntry createFakeOrderEntry(@NotNull final Module ownerModule) {
+ return new OrderEntry() {
+ @NotNull
+ @Override
+ public VirtualFile[] getFiles(OrderRootType type) {
+ throw new IncorrectOperationException();
+ }
+
+ @NotNull
+ @Override
+ public String[] getUrls(OrderRootType rootType) {
+ throw new IncorrectOperationException();
+ }
+
+ @NotNull
+ @Override
+ public String getPresentableName() {
+ throw new IncorrectOperationException();
+ }
+
+ @Override
+ public boolean isValid() {
+ throw new IncorrectOperationException();
+ }
+
+ @NotNull
+ @Override
+ public Module getOwnerModule() {
+ return ownerModule;
+ }
+
+ @Override
+ public <R> R accept(RootPolicy<R> policy, @Nullable R initialValue) {
+ throw new IncorrectOperationException();
+ }
+
+ @Override
+ public int compareTo(@NotNull OrderEntry o) {
+ throw new IncorrectOperationException();
+ }
+
+ @Override
+ public boolean isSynthetic() {
+ throw new IncorrectOperationException();
+ }
+ };
+ }
+
+ @Override
+ @Nullable
+ OrderEntry findOrderEntryWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule) {
+ OrderEntry[] entries = getOrderEntries(info);
+ if (entries.length < 10) {
+ for (OrderEntry entry : entries) {
+ if (entry.getOwnerModule() == ownerModule) return entry;
+ }
+ return null;
+ }
+ int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), RootIndex.BY_OWNER_MODULE);
+ return index < 0 ? null : entries[index];
+ }
+
+ @Override
+ @NotNull
+ List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule) {
+ OrderEntry[] entries = getOrderEntries(info);
+ if (entries.length == 0) return Collections.emptyList();
+
+ if (entries.length == 1) {
+ OrderEntry entry = entries[0];
+ return entry.getOwnerModule() == ownerModule ? Arrays.asList(entries) : Collections.<OrderEntry>emptyList();
+ }
+ int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), RootIndex.BY_OWNER_MODULE);
+ if (index < 0) {
+ return Collections.emptyList();
+ }
+ int firstIndex = index;
+ while (firstIndex - 1 >= 0 && entries[firstIndex - 1].getOwnerModule() == ownerModule) {
+ firstIndex--;
+ }
+ int lastIndex = index + 1;
+ while (lastIndex < entries.length && entries[lastIndex].getOwnerModule() == ownerModule) {
+ lastIndex++;
+ }
+
+ OrderEntry[] subArray = new OrderEntry[lastIndex - firstIndex];
+ System.arraycopy(entries, firstIndex, subArray, 0, lastIndex - firstIndex);
+
+ return Arrays.asList(subArray);
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java
index 932204c6dbd3..4ba8b7b03a8d 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java
@@ -72,10 +72,8 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl {
private Set<LocalFileSystem.WatchRequest> myRootsToWatch = new THashSet<LocalFileSystem.WatchRequest>();
private final boolean myDoLogCachesUpdate;
- public ProjectRootManagerComponent(Project project,
- DirectoryIndex directoryIndex,
- StartupManager startupManager) {
- super(project, directoryIndex);
+ public ProjectRootManagerComponent(Project project, StartupManager startupManager) {
+ super(project);
myConnection = project.getMessageBus().connect(project);
myConnection.subscribe(FileTypeManager.TOPIC, new FileTypeListener() {
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/DetectedRootsChooserDialog.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/DetectedRootsChooserDialog.java
index ee44bdf2f08b..bf3d383aeebb 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/DetectedRootsChooserDialog.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/DetectedRootsChooserDialog.java
@@ -26,11 +26,13 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.*;
import com.intellij.ui.treeStructure.treetable.TreeColumnInfo;
import com.intellij.util.PlatformIcons;
+import com.intellij.util.containers.Convertor;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ComboBoxCellEditor;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -38,12 +40,11 @@ import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
+import javax.swing.tree.TreePath;
import java.awt.*;
import java.io.File;
-import java.util.Arrays;
-import java.util.HashMap;
+import java.util.*;
import java.util.List;
-import java.util.Map;
/**
* This dialog allows selecting paths inside selected archives or directories.
@@ -108,17 +109,17 @@ public class DetectedRootsChooserDialog extends DialogWrapper {
private JScrollPane myPane;
private String myDescription;
- public DetectedRootsChooserDialog(Component component, List<SuggestedChildRootInfo> suggestedRoots) {
+ public DetectedRootsChooserDialog(Component component, Collection<SuggestedChildRootInfo> suggestedRoots) {
super(component, true);
init(suggestedRoots);
}
- public DetectedRootsChooserDialog(Project project, List<SuggestedChildRootInfo> suggestedRoots) {
+ public DetectedRootsChooserDialog(Project project, Collection<SuggestedChildRootInfo> suggestedRoots) {
super(project, true);
init(suggestedRoots);
}
- private void init(List<SuggestedChildRootInfo> suggestedRoots) {
+ private void init(Collection<SuggestedChildRootInfo> suggestedRoots) {
myDescription = XmlStringUtil.wrapInHtml(ApplicationNamesInfo.getInstance().getFullProductName() +
" just scanned files and detected the following " + StringUtil.pluralize("root", suggestedRoots.size()) + ".<br>" +
"Select items in the tree below or press Cancel to cancel operation.");
@@ -128,7 +129,7 @@ public class DetectedRootsChooserDialog extends DialogWrapper {
init();
}
- private static CheckboxTreeTable createTreeTable(List<SuggestedChildRootInfo> suggestedRoots) {
+ private static CheckboxTreeTable createTreeTable(Collection<SuggestedChildRootInfo> suggestedRoots) {
final CheckedTreeNode root = createRoot(suggestedRoots);
CheckboxTreeTable treeTable = new CheckboxTreeTable(root, new CheckboxTree.CheckboxTreeCellRenderer(true) {
@Override
@@ -189,14 +190,30 @@ public class DetectedRootsChooserDialog extends DialogWrapper {
column.setPreferredWidth(width);
column.setMaxWidth(width);
treeTable.setRootVisible(false);
+ new TreeTableSpeedSearch(treeTable, new Convertor<TreePath, String>() {
+ @Override
+ public String convert(TreePath o) {
+ Object node = o.getLastPathComponent();
+ if (!(node instanceof VirtualFileCheckedTreeNode)) return "";
+ return ((VirtualFileCheckedTreeNode)node).getFile().getPresentableUrl();
+ }
+ });
TreeUtil.expandAll(treeTable.getTree());
return treeTable;
}
- private static CheckedTreeNode createRoot(List<SuggestedChildRootInfo> suggestedRoots) {
+ private static CheckedTreeNode createRoot(Collection<SuggestedChildRootInfo> suggestedRoots) {
+ SuggestedChildRootInfo[] sortedRoots = suggestedRoots.toArray(new SuggestedChildRootInfo[suggestedRoots.size()]);
+ Arrays.sort(sortedRoots, new Comparator<SuggestedChildRootInfo>() {
+ @Override
+ public int compare(@NotNull SuggestedChildRootInfo o1, @NotNull SuggestedChildRootInfo o2) {
+ return o1.getDetectedRoot().getFile().getPresentableUrl().compareTo(o2.getDetectedRoot().getFile().getPresentableUrl());
+ }
+ });
+
CheckedTreeNode root = new CheckedTreeNode(null);
Map<VirtualFile, CheckedTreeNode> rootCandidateNodes = new HashMap<VirtualFile, CheckedTreeNode>();
- for (SuggestedChildRootInfo rootInfo : suggestedRoots) {
+ for (SuggestedChildRootInfo rootInfo : sortedRoots) {
final VirtualFile rootCandidate = rootInfo.getRootCandidate();
CheckedTreeNode parent = rootCandidateNodes.get(rootCandidate);
if (parent == null) {
@@ -230,6 +247,12 @@ public class DetectedRootsChooserDialog extends DialogWrapper {
return "DetectedRootsChooserDialog";
}
+ @Nullable
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myTreeTable;
+ }
+
private static class VirtualFileCheckedTreeNode extends CheckedTreeNode {
private final VirtualFile myFile;
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/SuggestedChildRootInfo.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/SuggestedChildRootInfo.java
index 743e408b8c97..725216600ffa 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/SuggestedChildRootInfo.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/SuggestedChildRootInfo.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.roots.libraries.LibraryRootType;
import com.intellij.openapi.roots.libraries.ui.DetectedLibraryRoot;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Map;
@@ -32,17 +33,19 @@ class SuggestedChildRootInfo {
private final Map<LibraryRootType, String> myRootTypeNames;
private LibraryRootType mySelectedRootType;
- SuggestedChildRootInfo(VirtualFile rootCandidate, DetectedLibraryRoot detectedRoot, Map<LibraryRootType, String> rootTypeNames) {
+ SuggestedChildRootInfo(@NotNull VirtualFile rootCandidate, @NotNull DetectedLibraryRoot detectedRoot, @NotNull Map<LibraryRootType, String> rootTypeNames) {
myRootCandidate = rootCandidate;
myDetectedRoot = detectedRoot;
myRootTypeNames = rootTypeNames;
mySelectedRootType = detectedRoot.getTypes().get(0);
}
+ @NotNull
public VirtualFile getRootCandidate() {
return myRootCandidate;
}
+ @NotNull
public DetectedLibraryRoot getDetectedRoot() {
return myDetectedRoot;
}
@@ -51,6 +54,7 @@ class SuggestedChildRootInfo {
return myRootTypeNames.get(type);
}
+ @NotNull
public LibraryRootType getSelectedRootType() {
return mySelectedRootType;
}
@@ -64,6 +68,7 @@ class SuggestedChildRootInfo {
}
}
+ @NotNull
public String[] getRootTypeNames() {
final String[] types = ArrayUtil.toStringArray(myRootTypeNames.values());
Arrays.sort(types, String.CASE_INSENSITIVE_ORDER);
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java
index 72f9c5a965c0..04f908a17c00 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/CommonContentEntriesEditor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,12 +33,15 @@ import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.roots.ui.componentsList.components.ScrollablePanel;
import com.intellij.openapi.roots.ui.componentsList.layout.VerticalStackLayout;
import com.intellij.openapi.roots.ui.configuration.actions.IconWithTextAction;
-import com.intellij.openapi.ui.Splitter;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.ex.VirtualFileManagerAdapter;
+import com.intellij.ui.JBSplitter;
+import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.ScrollPaneFactory;
+import com.intellij.ui.border.CustomLineBorder;
import com.intellij.ui.roots.ToolbarPanel;
import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
@@ -48,6 +51,7 @@ import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import javax.swing.*;
import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
@@ -146,7 +150,9 @@ public class CommonContentEntriesEditor extends ModuleElementsEditor {
myContentEntryEditorListener = new MyContentEntryEditorListener();
final JPanel mainPanel = new JPanel(new BorderLayout());
- mainPanel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
+ if (!Registry.is("ide.new.project.settings")) {
+ mainPanel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
+ }
addAdditionalSettingsToPanel(mainPanel);
@@ -159,21 +165,32 @@ public class CommonContentEntriesEditor extends ModuleElementsEditor {
myEditorsPanel = new ScrollablePanel(new VerticalStackLayout());
myEditorsPanel.setBackground(BACKGROUND_COLOR);
- JScrollPane myScrollPane = ScrollPaneFactory.createScrollPane(myEditorsPanel);
- entriesPanel.add(new ToolbarPanel(myScrollPane, group), BorderLayout.CENTER);
+ JScrollPane myScrollPane = ScrollPaneFactory.createScrollPane(myEditorsPanel, Registry.is("ide.new.project.settings"));
+ final ToolbarPanel toolbarPanel = new ToolbarPanel(myScrollPane, group);
+ if (Registry.is("ide.new.project.settings")) {
+ toolbarPanel.setBorder(new CustomLineBorder(1,0,0,0));
+ }
+ entriesPanel.add(toolbarPanel, BorderLayout.CENTER);
- final Splitter splitter = new Splitter(false);
+ final JBSplitter splitter = Registry.is("ide.new.project.settings") ? new OnePixelSplitter(false) : new JBSplitter(false);
splitter.setProportion(0.6f);
splitter.setHonorComponentsMinimumSize(true);
myRootTreeEditor = createContentEntryTreeEditor(project);
- splitter.setFirstComponent(myRootTreeEditor.createComponent());
+ final JComponent component = myRootTreeEditor.createComponent();
+ if (Registry.is("ide.new.project.settings")) {
+ component.setBorder(new CustomLineBorder(1,0,0,0));
+ }
+
+ splitter.setFirstComponent(component);
splitter.setSecondComponent(entriesPanel);
JPanel contentPanel = new JPanel(new GridBagLayout());
- contentPanel.setBorder(BorderFactory.createEtchedBorder());
+ if (!Registry.is("ide.new.project.settings")) {
+ contentPanel.setBorder(BorderFactory.createEtchedBorder());
+ }
final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, myRootTreeEditor.getEditingActionsGroup(), true);
contentPanel.add(new JLabel("Mark as:"),
- new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, 0, new Insets(0, 5, 0, 5), 0, 0));
+ new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, 0, new Insets(0, 10, 0, 10), 0, 0));
contentPanel.add(actionToolbar.getComponent(),
new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
@@ -236,7 +253,11 @@ public class CommonContentEntriesEditor extends ModuleElementsEditor {
if (componentBorder != null) {
border = BorderFactory.createCompoundBorder(border, componentBorder);
}
- component.setBorder(border);
+ if (Registry.is("ide.new.project.settings")) {
+ component.setBorder(new EmptyBorder(0,0,0,0));
+ } else {
+ component.setBorder(border);
+ }
myEditorsPanel.add(component);
}
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java
index 469d966a29d8..bc10302c9c43 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/ui/configuration/ContentRootPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@ import com.intellij.ui.roots.IconActionComponent;
import com.intellij.ui.roots.ResizingWrapper;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.util.NotNullProducer;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -59,10 +60,22 @@ import java.util.Map;
*/
public abstract class ContentRootPanel extends JPanel {
private static final Color EXCLUDED_COLOR = new JBColor(new Color(0x992E00), DarculaColors.RED);
- private static final Color SELECTED_HEADER_COLOR = new JBColor(new Color(0xDEF2FF), UIUtil.getPanelBackground().darker());
+ private static final Color SELECTED_HEADER_COLOR = new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ return UIUtil.isUnderDarcula() ? UIUtil.getPanelBackground().darker() : new Color(0xDEF2FF);
+ }
+ });
private static final Color HEADER_COLOR = new JBColor(new Color(0xF5F5F5), Gray._82);
private static final Color SELECTED_CONTENT_COLOR = new Color(0xF0F9FF);
- private static final Color CONTENT_COLOR = new JBColor(Color.WHITE, UIUtil.getPanelBackground());
+ private static final Color CONTENT_COLOR = new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ return UIUtil.isUnderDarcula() ? UIUtil.getPanelBackground() : Gray._255;
+ }
+ });
private static final Color UNSELECTED_TEXT_COLOR = Gray._51;
protected final ActionCallback myCallback;
@@ -140,7 +153,7 @@ public abstract class ContentRootPanel extends JPanel {
headerLabel.setFont(headerLabel.getFont().deriveFont(Font.BOLD));
headerLabel.setOpaque(false);
if (getContentEntry().getFile() == null) {
- headerLabel.setForeground(Color.RED);
+ headerLabel.setForeground(JBColor.RED);
}
final IconActionComponent deleteIconComponent = new IconActionComponent(AllIcons.Modules.DeleteContentRoot,
AllIcons.Modules.DeleteContentRootRollover,
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/AddScopeUtil.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/AddScopeUtil.java
deleted file mode 100644
index d92445254f28..000000000000
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/AddScopeUtil.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2000-2012 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * User: anna
- * Date: 14-May-2009
- */
-package com.intellij.profile.codeInspection.ui;
-
-import com.intellij.codeHighlighting.HighlightDisplayLevel;
-import com.intellij.codeInspection.ex.Descriptor;
-import com.intellij.codeInspection.ex.InspectionProfileImpl;
-import com.intellij.codeInspection.ex.InspectionToolWrapper;
-import com.intellij.codeInspection.ex.ScopeToolState;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionConfigTreeNode;
-import com.intellij.psi.search.scope.packageSet.CustomScopesProviderEx;
-import com.intellij.psi.search.scope.packageSet.NamedScope;
-import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
-import com.intellij.ui.treeStructure.Tree;
-import com.intellij.ui.treeStructure.treetable.TreeTable;
-import com.intellij.util.ArrayUtil;
-
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.TreePath;
-import java.util.*;
-
-public class AddScopeUtil {
- public static ScopeToolState performAddScope(final TreeTable treeTable,
- final Project project,
- final InspectionProfileImpl inspectionProfile,
- final Collection<InspectionConfigTreeNode> selectedNodes) {
- final List<InspectionConfigTreeNode> nodes = new ArrayList<InspectionConfigTreeNode>();
- final List<Descriptor> descriptors = new ArrayList<Descriptor>();
- for (final InspectionConfigTreeNode node : selectedNodes) {
- collect(descriptors, nodes, node);
- }
-
- final List<String> availableScopes = getAvailableScopes(descriptors, project, inspectionProfile);
- final int idx = Messages.showChooseDialog(treeTable, "Scope:", "Choose Scope", ArrayUtil.toStringArray(availableScopes), availableScopes.get(0), Messages.getQuestionIcon());
- if (idx == -1) return null;
- final NamedScope chosenScope = NamedScopesHolder.getScope(project, availableScopes.get(idx));
-
- ScopeToolState scopeToolState = null;
- final Tree tree = treeTable.getTree();
-
- for (final InspectionConfigTreeNode node : nodes) {
- final Descriptor descriptor = node.getDefaultDescriptor();
- final InspectionToolWrapper toolWrapper = descriptor.getToolWrapper().createCopy(); //copy
- final HighlightDisplayLevel level = inspectionProfile.getErrorLevel(descriptor.getKey(), chosenScope, project);
- final boolean enabled = inspectionProfile.isToolEnabled(descriptor.getKey());
- scopeToolState = inspectionProfile.addScope(toolWrapper, chosenScope, level, enabled, project);
- node.dropCache();
- ((DefaultTreeModel)tree.getModel()).reload(node);
- tree.expandPath(new TreePath(node.getPath()));
- }
- tree.revalidate();
- return scopeToolState;
- }
-
- private static void collect(final List<Descriptor> descriptors,
- final List<InspectionConfigTreeNode> nodes,
- final InspectionConfigTreeNode node) {
- final ToolDescriptors currentDescriptors = node.getDescriptors();
- if (currentDescriptors != null) {
- nodes.add(node);
- descriptors.add(currentDescriptors.getDefaultDescriptor());
- descriptors.addAll(currentDescriptors.getNonDefaultDescriptors());
- } else if (node.getUserObject() instanceof String) {
- for(int i = 0; i < node.getChildCount(); i++) {
- final InspectionConfigTreeNode childNode = (InspectionConfigTreeNode)node.getChildAt(i);
- collect(descriptors, nodes, childNode);
- }
- }
- }
-
- private static List<String> getAvailableScopes(final List<Descriptor> descriptors, final Project project, final InspectionProfileImpl inspectionProfile) {
- final ArrayList<NamedScope> scopes = new ArrayList<NamedScope>();
- for (final NamedScopesHolder holder : NamedScopesHolder.getAllNamedScopeHolders(project)) {
- Collections.addAll(scopes, holder.getScopes());
- }
- scopes.remove(CustomScopesProviderEx.getAllScope());
-
- CustomScopesProviderEx.filterNoSettingsScopes(project, scopes);
-
- final Set<NamedScope> used = new HashSet<NamedScope>();
- for (final Descriptor descriptor : descriptors) {
- final List<ScopeToolState> nonDefaultTools = inspectionProfile.getNonDefaultTools(descriptor.getKey().toString(), project);
- if (nonDefaultTools != null) {
- for (final ScopeToolState state : nonDefaultTools) {
- used.add(state.getScope(project));
- }
- }
- }
- scopes.removeAll(used);
-
- final List<String> availableScopes = new ArrayList<String>();
- for (final NamedScope scope : scopes) {
- availableScopes.add(scope.getName());
- }
- return availableScopes;
- }
-} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/AdvancedSettingsAction.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/AdvancedSettingsAction.java
new file mode 100644
index 000000000000..b0746769d83c
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/AdvancedSettingsAction.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.profile.codeInspection.ui;
+
+import com.intellij.codeInspection.ex.InspectionProfileImpl;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationNamesInfo;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.PopupStep;
+import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
+import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionConfigTreeNode;
+import com.intellij.ui.LayeredIcon;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.ui.components.JBLabel;
+import com.intellij.ui.popup.list.ListPopupImpl;
+import com.intellij.util.Consumer;
+import com.intellij.util.PlatformIcons;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.EmptyIcon;
+import com.intellij.util.ui.UIUtil;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public abstract class AdvancedSettingsAction extends AnAction {
+ private final int myCheckBoxIndent;
+ private Project myProject;
+ private InspectionConfigTreeNode myRoot;
+
+ public AdvancedSettingsAction(final Project project, InspectionConfigTreeNode root) {
+ super("Advanced Settings");
+ getTemplatePresentation().setIcon(AllIcons.General.Gear);
+ myProject = project;
+ myRoot = root;
+ myCheckBoxIndent = calculateCheckBoxIndent();
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ final InspectionProfileImpl inspectionProfile = getInspectionProfile();
+ final Icon icon = AllIcons.General.Gear;
+ e.getPresentation().setIcon(
+ (inspectionProfile != null && inspectionProfile.isProfileLocked()) ? LayeredIcon.create(icon, PlatformIcons.LOCKED_ICON) : icon);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ final ListPopupImpl actionGroupPopup = (ListPopupImpl)JBPopupFactory.getInstance().createListPopup(
+ new BaseListPopupStep<MyAction>(null, ContainerUtil.list(new MyDisableNewInspectionsAction(), new MyResetAction())) {
+ @Override
+ public PopupStep onChosen(MyAction selectedValue, boolean finalChoice) {
+ if (selectedValue.enabled()) {
+ selectedValue.actionPerformed();
+ }
+ return FINAL_CHOICE;
+ }
+ });
+ actionGroupPopup.getList().setCellRenderer(new ListCellRenderer() {
+ @Override
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ return ((MyAction)value).createCustomComponent(isSelected);
+ }
+ });
+ final Component component = e.getInputEvent().getComponent();
+ actionGroupPopup.show(new RelativePoint(component, new Point(component.getWidth() - 1, 0)));
+ }
+
+ private JLabel installLeftIndentToLabel(final JLabel label) {
+ label.setBorder(BorderFactory.createEmptyBorder(0, myCheckBoxIndent, 0, 0));
+ return label;
+ }
+
+ private class MyResetAction extends MyAction {
+
+ protected MyResetAction() {
+ super("All your changes will be lost");
+ }
+
+ @Override
+ protected JComponent createBaseComponent() {
+ return installLeftIndentToLabel(new JLabel("Reset to Defaults Settings"));
+ }
+
+ @Override
+ public void actionPerformed() {
+ final InspectionProfileImpl inspectionProfile = getInspectionProfile();
+ if (inspectionProfile == null) {
+ return;
+ }
+ inspectionProfile.resetToBase(myProject);
+ postProcessModification();
+ }
+
+ @Override
+ protected boolean enabled() {
+ return myRoot.isProperSetting();
+ }
+ }
+
+ private class MyDisableNewInspectionsAction extends MyAction {
+ public MyDisableNewInspectionsAction() {
+ super("New inspections may appear when " + ApplicationNamesInfo.getInstance().getFullProductName() + " is updated");
+ }
+
+ @Override
+ protected JComponent createBaseComponent() {
+ final JCheckBox checkBox = new JCheckBox("Disable new inspections by default");
+ final InspectionProfileImpl profile = getInspectionProfile();
+ checkBox.setEnabled(profile != null);
+ if (profile != null) {
+ checkBox.setSelected(profile.isProfileLocked());
+ }
+ checkBox.setOpaque(false);
+ return checkBox;
+ }
+
+ @Override
+ public void actionPerformed() {
+ final InspectionProfileImpl profile = getInspectionProfile();
+ if (profile != null) {
+ profile.lockProfile(!profile.isProfileLocked());
+ }
+ }
+
+
+ @Override
+ protected boolean enabled() {
+ return true;
+ }
+ }
+
+ private abstract class MyAction {
+ private final String myDescription;
+
+ protected MyAction(String description) {
+ myDescription = description;
+ }
+
+ protected abstract JComponent createBaseComponent();
+
+ protected abstract void actionPerformed();
+
+ protected abstract boolean enabled();
+
+ public JComponent createCustomComponent(final boolean selected) {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
+ panel.add(createBaseComponent());
+ panel.add(installLeftIndentToLabel(new JBLabel(myDescription, UIUtil.ComponentStyle.MINI)));
+ panel.setBackground(selected ? UIUtil.getListSelectionBackground() : UIUtil.getListBackground());
+ panel.setForeground(selected ? UIUtil.getListSelectionForeground() : UIUtil.getListForeground());
+ UIUtil.setEnabled(panel, enabled(), true);
+ return panel;
+ }
+ }
+
+ protected abstract InspectionProfileImpl getInspectionProfile();
+
+ protected abstract void postProcessModification();
+
+ private static int calculateCheckBoxIndent() {
+ JCheckBox checkBox = new JCheckBox();
+ Icon icon = checkBox.getIcon();
+ int indent = 0;
+ if (icon == null) {
+ icon = UIManager.getIcon("CheckBox.icon");
+ }
+ if (UIUtil.isUnderDarcula() || UIUtil.isUnderIntelliJLaF()) {
+ icon = EmptyIcon.create(20, 18);
+ }
+ if (icon != null) {
+ final Insets i = checkBox.getInsets();
+ final Rectangle r = checkBox.getBounds();
+ final Rectangle r1 = new Rectangle();
+ r1.x = i.left;
+ r1.y = i.top;
+ r1.width = r.width - (i.right + r1.x);
+ r1.height = r.height - (i.bottom + r1.y);
+ final Rectangle iconRect = new Rectangle();
+ SwingUtilities.layoutCompoundLabel(
+ checkBox, checkBox.getFontMetrics(checkBox.getFont()), checkBox.getText(), icon,
+ checkBox.getVerticalAlignment(), checkBox.getHorizontalAlignment(),
+ checkBox.getVerticalTextPosition(), checkBox.getHorizontalTextPosition(),
+ r1, new Rectangle(), iconRect,
+ checkBox.getText() == null ? 0 : checkBox.getIconTextGap());
+ indent = iconRect.x;
+ }
+ return indent + checkBox.getIconTextGap();
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java
index 794945268d19..efc60c63f89d 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java
@@ -151,7 +151,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
final Set<String> levels = new HashSet<String>();
for (Object o : rootElement.getChildren("inspection_tool")) {
final Element inspectElement = (Element)o;
- levels.add(inspectElement.getAttributeValue("l"));
+ levels.add(inspectElement.getAttributeValue("level"));
for (Object s : inspectElement.getChildren("scope")) {
levels.add(((Element)s).getAttributeValue("level"));
}
@@ -532,6 +532,6 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple
public JComponent getPreferredFocusedComponent() {
final InspectionProfileImpl inspectionProfile = getSelectedObject();
assert inspectionProfile != null : configuredProfiles();
- return getProfilePanel(inspectionProfile).getTree();
+ return getProfilePanel(inspectionProfile).getPreferredFocusedComponent();
}
}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooserAction.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooserAction.java
index 1067a60ed358..df3b8bda3f3b 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooserAction.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/LevelChooserAction.java
@@ -43,7 +43,11 @@ public abstract class LevelChooserAction extends ComboBoxAction {
private HighlightSeverity myChosen = null;
public LevelChooserAction(final InspectionProfileImpl profile) {
- mySeverityRegistrar = ((SeverityProvider)profile.getProfileManager()).getOwnSeverityRegistrar();
+ this(((SeverityProvider)profile.getProfileManager()).getOwnSeverityRegistrar());
+ }
+
+ public LevelChooserAction(final SeverityRegistrar severityRegistrar) {
+ mySeverityRegistrar = severityRegistrar;
}
@NotNull
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/MultiScopeSeverityIcon.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/MultiScopeSeverityIcon.java
deleted file mode 100644
index 2bf909666f82..000000000000
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/MultiScopeSeverityIcon.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.profile.codeInspection.ui;
-
-import javax.swing.*;
-import java.awt.*;
-import java.util.List;
-
-/**
- * @author Dmitry Batkovich
- */
-public class MultiScopeSeverityIcon implements Icon {
- private final int mySize;
- private final List<Color> myColors;
-
- public MultiScopeSeverityIcon(final int size, final List<Color> colors) {
- mySize = size;
- myColors = colors;
- }
-
- @Override
- public void paintIcon(final Component c, final Graphics g, final int i, final int j) {
- final int iconWidth = getIconWidth();
- final int iconHeightCoordinate = j + getIconHeight();
-
- final int partWidth = iconWidth / myColors.size();
-
- for (int idx = 0; idx < myColors.size(); idx++) {
- final Color color = myColors.get(idx);
- g.setColor(color);
- final int x = i + partWidth * idx;
- g.fillRect(x, j, x + partWidth, iconHeightCoordinate);
- }
- }
-
- @Override
- public int getIconWidth() {
- return mySize;
- }
-
- @Override
- public int getIconHeight() {
- return mySize;
- }
-}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopeOrderComparator.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopeOrderComparator.java
new file mode 100644
index 000000000000..f2d8c5e1fd82
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopeOrderComparator.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.profile.codeInspection.ui;
+
+import com.intellij.codeInspection.ex.InspectionProfileImpl;
+import com.intellij.util.ArrayUtil;
+
+import java.util.Comparator;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ScopeOrderComparator implements Comparator<String> {
+ private final String[] myScopesOrder;
+
+ public ScopeOrderComparator(final InspectionProfileImpl inspectionProfile) {
+ this(inspectionProfile.getScopesOrder());
+ }
+
+ public ScopeOrderComparator(String[] scopesOrder) {
+ myScopesOrder = scopesOrder;
+ }
+
+ private int getKey(String scope) {
+ return myScopesOrder == null ? -1 : ArrayUtil.indexOf(myScopesOrder, scope);
+ }
+
+ @Override
+ public int compare(String scope1, String scope2) {
+ final int key = getKey(scope1);
+ final int key1 = getKey(scope2);
+ if (key >= 0) {
+ if (key1 >= 0) {
+ return key - key1;
+ }
+ else {
+ return -1;
+ }
+ }
+ else {
+ if (key1 >= 0) {
+ return 1;
+ }
+ else {
+ return scope1.compareTo(scope2);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesChooser.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesChooser.java
index 4932e7ff5ca9..fde3b141084d 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesChooser.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesChooser.java
@@ -22,13 +22,16 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
import com.intellij.openapi.project.Project;
+import com.intellij.psi.search.scope.NonProjectFilesScope;
import com.intellij.psi.search.scope.packageSet.CustomScopesProviderEx;
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.ArrayList;
+import java.util.Set;
import java.util.List;
import java.util.Collections;
@@ -36,22 +39,28 @@ import java.util.Collections;
* @author Dmitry Batkovich
*/
public abstract class ScopesChooser extends ComboBoxAction {
+ public static final String TITLE = "Select a scope to change its settings";
private final List<Descriptor> myDefaultDescriptors;
private final InspectionProfileImpl myInspectionProfile;
private final Project myProject;
+ private final Set<String> myExcludedScopeNames;
- public ScopesChooser(final List<Descriptor> defaultDescriptors, final InspectionProfileImpl inspectionProfile, final Project project) {
+ public ScopesChooser(final List<Descriptor> defaultDescriptors,
+ final InspectionProfileImpl inspectionProfile,
+ final Project project,
+ final String[] excludedScopeNames) {
myDefaultDescriptors = defaultDescriptors;
myInspectionProfile = inspectionProfile;
myProject = project;
- setPopupTitle("Select a scope to change its settings");
+ myExcludedScopeNames = excludedScopeNames == null ? Collections.<String>emptySet() : ContainerUtil.newHashSet(excludedScopeNames);
+ setPopupTitle(TITLE);
getTemplatePresentation().setText("In All Scopes");
}
@NotNull
@Override
- protected DefaultActionGroup createPopupActionGroup(final JComponent button) {
+ public DefaultActionGroup createPopupActionGroup(final JComponent component) {
final DefaultActionGroup group = new DefaultActionGroup();
final List<NamedScope> predefinedScopes = new ArrayList<NamedScope>();
@@ -61,30 +70,47 @@ public abstract class ScopesChooser extends ComboBoxAction {
predefinedScopes.addAll(holder.getPredefinedScopes());
}
predefinedScopes.remove(CustomScopesProviderEx.getAllScope());
- fillActionGroup(group, predefinedScopes, myDefaultDescriptors, myInspectionProfile);
+ for (NamedScope predefinedScope : predefinedScopes) {
+ if (predefinedScope instanceof NonProjectFilesScope) {
+ predefinedScopes.remove(predefinedScope);
+ break;
+ }
+ }
+
+ fillActionGroup(group, predefinedScopes, myDefaultDescriptors, myInspectionProfile, myExcludedScopeNames);
group.addSeparator();
- fillActionGroup(group, customScopes, myDefaultDescriptors, myInspectionProfile);
+ fillActionGroup(group, customScopes, myDefaultDescriptors, myInspectionProfile, myExcludedScopeNames);
- //TODO edit scopes order
- //group.addSeparator();
- //group.add(new AnAction("Edit Scopes Order...") {
- // @Override
- // public void actionPerformed(final AnActionEvent e) {
- //
- // }
- //});
+ group.addSeparator();
+ group.add(new AnAction("Edit Scopes Order...") {
+ @Override
+ public void actionPerformed(final AnActionEvent e) {
+ final ScopesOrderDialog dlg = new ScopesOrderDialog(component, myInspectionProfile, myProject);
+ dlg.show();
+ if (dlg.isOK()) {
+ onScopesOrderChanged();
+ }
+ }
+ });
return group;
}
+ protected abstract void onScopesOrderChanged();
+
protected abstract void onScopeAdded();
private void fillActionGroup(final DefaultActionGroup group,
- final List<NamedScope> scopes,
- final List<Descriptor> defaultDescriptors,
- final InspectionProfileImpl inspectionProfile) {
+ final List<NamedScope> scopes,
+ final List<Descriptor> defaultDescriptors,
+ final InspectionProfileImpl inspectionProfile,
+ final Set<String> excludedScopeNames) {
for (final NamedScope scope : scopes) {
- group.add(new AnAction(scope.getName()) {
+ final String scopeName = scope.getName();
+ if (excludedScopeNames.contains(scopeName)) {
+ continue;
+ }
+ group.add(new AnAction(scopeName) {
@Override
public void actionPerformed(final AnActionEvent e) {
for (final Descriptor defaultDescriptor : defaultDescriptors) {
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesOrderDialog.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesOrderDialog.java
new file mode 100644
index 000000000000..c69a3e5566a2
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/ScopesOrderDialog.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.profile.codeInspection.ui;
+
+import com.intellij.codeInspection.ex.InspectionProfileImpl;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.psi.search.scope.NonProjectFilesScope;
+import com.intellij.psi.search.scope.packageSet.CustomScopesProviderEx;
+import com.intellij.psi.search.scope.packageSet.NamedScope;
+import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
+import com.intellij.ui.*;
+import com.intellij.ui.components.JBList;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class ScopesOrderDialog extends DialogWrapper {
+
+ private final JList myOptionsList = new JBList();
+
+ private final InspectionProfileImpl myInspectionProfile;
+ private final Project myProject;
+ private final JPanel myPanel;
+
+ public ScopesOrderDialog(final @NotNull Component parent,
+ final InspectionProfileImpl inspectionProfile,
+ final Project project) {
+ super(parent, true);
+ myInspectionProfile = inspectionProfile;
+ myProject = project;
+
+ final JPanel listPanel = ToolbarDecorator.createDecorator(myOptionsList).setMoveDownAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton anActionButton) {
+ ListUtil.moveSelectedItemsDown(myOptionsList);
+ }
+ }).setMoveUpAction(new AnActionButtonRunnable() {
+ @Override
+ public void run(AnActionButton anActionButton) {
+ ListUtil.moveSelectedItemsUp(myOptionsList);
+ }
+ }).disableRemoveAction().disableAddAction().createPanel();
+ final JLabel descr = new JLabel("<html><p>If file appears in two or more scopes, it will be" +
+ "inspected with settings of the topmost scope in list above.</p><p/>" +
+ "<p>Scope order is set globally for all inspections in the profile.</p></html>");
+ descr.setPreferredSize(new Dimension(300, 100));
+ UIUtil.applyStyle(UIUtil.ComponentStyle.SMALL, descr);
+ myPanel = new JPanel();
+ myPanel.setLayout(new BorderLayout());
+ myPanel.add(listPanel, BorderLayout.CENTER);
+ myPanel.add(descr, BorderLayout.SOUTH);
+ fillList();
+ init();
+ setTitle("Scopes Order");
+ }
+
+ private void fillList() {
+ DefaultListModel model = new DefaultListModel();
+ model.removeAllElements();
+
+ final List<String> scopes = new ArrayList<String>();
+ for (final NamedScopesHolder holder : NamedScopesHolder.getAllNamedScopeHolders(myProject)) {
+ for (final NamedScope scope : holder.getScopes()) {
+ if (!(scope instanceof NonProjectFilesScope)) {
+ scopes.add(scope.getName());
+ }
+ }
+ }
+ scopes.remove(CustomScopesProviderEx.getAllScope().getName());
+ Collections.sort(scopes, new ScopeOrderComparator(myInspectionProfile));
+ for (String scopeName : scopes) {
+ model.addElement(scopeName);
+ }
+ myOptionsList.setModel(model);
+ myOptionsList.setSelectedIndex(0);
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ return myPanel;
+ }
+
+ @Override
+ protected void doOKAction() {
+ final int size = myOptionsList.getModel().getSize();
+ final String[] newScopeOrder = new String[size];
+ for (int i = 0; i < size; i++) {
+ final String scopeName = (String) myOptionsList.getModel().getElementAt(i);
+ newScopeOrder[i] = scopeName;
+ }
+ if (!Arrays.equals(newScopeOrder, myInspectionProfile.getScopesOrder())) {
+ myInspectionProfile.setScopesOrder(newScopeOrder);
+ }
+ super.doOKAction();
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java
index ce5f308c1305..2da5c80a758b 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java
@@ -132,6 +132,8 @@ public class SingleInspectionProfilePanel extends JPanel {
private Splitter myRightSplitter;
private Splitter myMainSplitter;
+ private String[] myInitialScopesOrder;
+
public SingleInspectionProfilePanel(@NotNull InspectionProjectProfileManager projectProfileManager,
@NotNull String inspectionProfileName,
@NotNull ModifiableModel profile) {
@@ -186,8 +188,10 @@ public class SingleInspectionProfilePanel extends JPanel {
if (myTreeTable != null) {
final TreePath selectionPath = myTreeTable.getTree().getSelectionPath();
if (selectionPath != null) {
- TreeUtil.selectNode(myTreeTable.getTree(), (TreeNode)selectionPath.getLastPathComponent());
- TreeUtil.showRowCentered(myTreeTable.getTree(), myTreeTable.getTree().getRowForPath(selectionPath), false);
+ TreeUtil.selectNode(myTreeTable.getTree(), (TreeNode) selectionPath.getLastPathComponent());
+ final int rowForPath = myTreeTable.getTree().getRowForPath(selectionPath);
+ TableUtil.selectRows(myTreeTable, new int[]{rowForPath});
+ scrollToCenter();
}
}
}
@@ -258,6 +262,7 @@ public class SingleInspectionProfilePanel extends JPanel {
if (!accept(state.getTool())) continue;
myInitialToolDescriptors.add(ToolDescriptors.fromScopeToolState(state, profile, project));
}
+ myInitialScopesOrder = mySelectedProfile.getScopesOrder();
}
protected boolean accept(InspectionToolWrapper entry) {
@@ -364,24 +369,6 @@ public class SingleInspectionProfilePanel extends JPanel {
actions.add(actionManager.createExpandAllAction(myTreeExpander, myTreeTable));
actions.add(actionManager.createCollapseAllAction(myTreeExpander, myTreeTable));
-
- actions.add(new AnAction(CommonBundle.message("button.reset.to.default"), CommonBundle.message("button.reset.to.default"),
- AllIcons.General.Reset) {
- {
- registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK)), myTreeTable);
- }
- @Override
- public void update(AnActionEvent e) {
- e.getPresentation().setEnabled(myRoot.isProperSetting());
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- mySelectedProfile.resetToBase(myProjectProfileManager.getProject());
- postProcessModification();
- }
- });
-
actions.add(new AnAction("Reset to Empty", "Reset to empty", AllIcons.Actions.Reset_to_empty){
@Override
@@ -396,18 +383,19 @@ public class SingleInspectionProfilePanel extends JPanel {
}
});
- actions.add(new ToggleAction("Lock Profile", "Lock profile", AllIcons.Nodes.Padlock) {
+ actions.add(new AdvancedSettingsAction(myProjectProfileManager.getProject(), myRoot) {
@Override
- public boolean isSelected(AnActionEvent e) {
- return mySelectedProfile != null && mySelectedProfile.isProfileLocked();
+ protected InspectionProfileImpl getInspectionProfile() {
+ return mySelectedProfile;
}
@Override
- public void setSelected(AnActionEvent e, boolean state) {
- mySelectedProfile.lockProfile(state);
+ protected void postProcessModification() {
+ SingleInspectionProfilePanel.this.postProcessModification();
}
});
+
final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actions, true);
actionToolbar.setTargetComponent(this);
return actionToolbar;
@@ -424,11 +412,24 @@ public class SingleInspectionProfilePanel extends JPanel {
public void selectInspectionTool(String name) {
final InspectionConfigTreeNode node = findNodeByKey(name, myRoot);
if (node != null) {
- TreeUtil.showRowCentered(myTreeTable.getTree(), myTreeTable.getTree().getRowForPath(new TreePath(node.getPath())) - 1, true);//myTree.isRootVisible ? 0 : 1;
TreeUtil.selectNode(myTreeTable.getTree(), node);
+ final int rowForPath = myTreeTable.getTree().getRowForPath(new TreePath(node.getPath()));
+ TableUtil.selectRows(myTreeTable, new int[]{rowForPath});
+ scrollToCenter();
}
}
+ private void scrollToCenter() {
+ ListSelectionModel selectionModel = myTreeTable.getSelectionModel();
+ int maxSelectionIndex = selectionModel.getMaxSelectionIndex();
+ final int maxColumnSelectionIndex = Math.max(0, myTreeTable.getColumnModel().getSelectionModel().getMinSelectionIndex());
+ Rectangle maxCellRect = myTreeTable.getCellRect(maxSelectionIndex, maxColumnSelectionIndex, false);
+
+ final Point selectPoint = maxCellRect.getLocation();
+ final int allHeight = myTreeTable.getVisibleRect().height;
+ myTreeTable.scrollRectToVisible(new Rectangle(new Point(0, Math.max(0, selectPoint.y - allHeight / 2)), new Dimension(0, allHeight)));
+ }
+
@Nullable
private static InspectionConfigTreeNode findNodeByKey(String name, InspectionConfigTreeNode root) {
for (int i = 0; i < root.getChildCount(); i++) {
@@ -524,6 +525,7 @@ public class SingleInspectionProfilePanel extends JPanel {
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTreeTable);
+ myTreeTable.getTree().setShowsRootHandles(true);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
TreeUtil.collapseAll(myTreeTable.getTree(), 1);
@@ -684,14 +686,15 @@ public class SingleInspectionProfilePanel extends JPanel {
}
private void updateOptionsAndDescriptionPanel(final TreePath... paths) {
- if (paths == null || paths.length == 0) {
+ if (mySelectedProfile == null || paths == null || paths.length == 0) {
return;
}
final TreePath path = paths[0];
if (path == null) return;
final List<InspectionConfigTreeNode> nodes = InspectionsAggregationUtil.getInspectionsNodes(paths);
if (!nodes.isEmpty()) {
- final InspectionConfigTreeNode singleNode = nodes.size() == 1 ? ContainerUtil.getFirstItem(nodes) : null;
+ final InspectionConfigTreeNode singleNode = paths.length == 1 && ((InspectionConfigTreeNode)paths[0].getLastPathComponent()).getDefaultDescriptor() != null
+ ? ContainerUtil.getFirstItem(nodes) : null;
if (singleNode != null && singleNode.getDefaultDescriptor().loadDescription() != null) {
// need this in order to correctly load plugin-supplied descriptions
final Descriptor defaultDescriptor = singleNode.getDefaultDescriptor();
@@ -721,7 +724,7 @@ public class SingleInspectionProfilePanel extends JPanel {
}
else {
try {
- myBrowser.read(new StringReader(EMPTY_HTML), null);
+ myBrowser.read(new StringReader("<html><body>Multiple inspections are selected. You can edit them as a single inspection.</body></html>"), null);
}
catch (IOException e1) {
//Can't be
@@ -733,7 +736,6 @@ public class SingleInspectionProfilePanel extends JPanel {
final JPanel severityPanel = new JPanel(new GridBagLayout());
final double severityPanelWeightY;
final JPanel configPanelAnchor = new JPanel(new GridLayout());
- configPanelAnchor.setBorder(IdeBorderFactory.createTitledBorder("Options", false, new Insets(0, 0, 0, 0)));
final Set<String> scopesNames = new THashSet<String>();
for (final InspectionConfigTreeNode node : nodes) {
@@ -754,7 +756,7 @@ public class SingleInspectionProfilePanel extends JPanel {
final HighlightDisplayKey key = node.getDefaultDescriptor().getKey();
final NamedScope scope = node.getDefaultDescriptor().getScope();
final boolean toUpdate = mySelectedProfile.getErrorLevel(key, scope, project) != level;
- mySelectedProfile.setErrorLevel(key, level, -1, project);
+ mySelectedProfile.setErrorLevel(key, level, null, project);
if (toUpdate) node.dropCache();
}
@@ -774,7 +776,13 @@ public class SingleInspectionProfilePanel extends JPanel {
public Descriptor fun(final InspectionConfigTreeNode node) {
return node.getDefaultDescriptor();
}
- }), mySelectedProfile, project) {
+ }), mySelectedProfile, project, null) {
+ @Override
+ protected void onScopesOrderChanged() {
+ myTreeTable.getTree().updateUI();
+ updateOptionsAndDescriptionPanel();
+ }
+
@Override
protected void onScopeAdded() {
updateOptionsAndDescriptionPanel();
@@ -812,12 +820,19 @@ public class SingleInspectionProfilePanel extends JPanel {
}
@Override
- protected void onChange() {
+ protected void onSettingsChanged() {
myTreeTable.getTree().updateUI();
}
@Override
protected void onScopeAdded() {
+ updateOptionsAndDescriptionPanel();
+ }
+
+ @Override
+ protected void onScopesOrderChanged() {
+ myTreeTable.getTree().updateUI();
+ updateOptionsAndDescriptionPanel();
}
@Override
@@ -829,8 +844,9 @@ public class SingleInspectionProfilePanel extends JPanel {
});
- final ToolbarDecorator wrappedTable = ToolbarDecorator.createDecorator(scopesAndScopesAndSeveritiesTable);
+ final ToolbarDecorator wrappedTable = ToolbarDecorator.createDecorator(scopesAndScopesAndSeveritiesTable).disableUpDownActions();
final JPanel panel = wrappedTable.createPanel();
+ panel.setMinimumSize(new Dimension(getMinimumSize().width, 3 * scopesAndScopesAndSeveritiesTable.getRowHeight()));
severityPanel.add(new JBLabel("Scopes & Severities"),
new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
new Insets(5, 0, 2, 10), 0, 0));
@@ -842,8 +858,13 @@ public class SingleInspectionProfilePanel extends JPanel {
severityPanelWeightY = 0.3;
}
myOptionsPanel.add(severityPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, severityPanelWeightY, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
- myOptionsPanel.add(configPanelAnchor, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
- new Insets(0, 0, 0, 0), 0, 0));
+ if (configPanelAnchor.getComponentCount() != 0) {
+ configPanelAnchor.setBorder(IdeBorderFactory.createTitledBorder("Options", false, new Insets(0, 0, 0, 0)));
+ }
+ if (configPanelAnchor.getComponentCount() != 0 || scopesNames.isEmpty()) {
+ myOptionsPanel.add(configPanelAnchor, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
+ new Insets(0, 0, 0, 0), 0, 0));
+ }
myOptionsPanel.revalidate();
GuiUtils.enableChildren(myOptionsPanel, isThoughOneNodeEnabled(nodes));
}
@@ -887,7 +908,10 @@ public class SingleInspectionProfilePanel extends JPanel {
private static void setConfigPanel(final JPanel configPanelAnchor, final ScopeToolState state) {
configPanelAnchor.removeAll();
- configPanelAnchor.add(state.getAdditionalConfigPanel());
+ final JComponent additionalConfigPanel = state.getAdditionalConfigPanel();
+ if (additionalConfigPanel != null) {
+ configPanelAnchor.add(ScrollPaneFactory.createScrollPane(additionalConfigPanel, SideBorder.NONE));
+ }
}
private static InspectionConfigTreeNode getGroupNode(InspectionConfigTreeNode root, String[] groupPath) {
@@ -1001,6 +1025,7 @@ public class SingleInspectionProfilePanel extends JPanel {
if (mySelectedProfile.isChanged()) return true;
if (myShareProfile != (mySelectedProfile.getProfileManager() == myProjectProfileManager)) return true;
if (!Comparing.strEqual(myInitialProfile, mySelectedProfile.getName())) return true;
+ if (!Comparing.equal(myInitialScopesOrder, mySelectedProfile.getScopesOrder())) return true;
if (descriptorsAreChanged()) {
return true;
}
@@ -1111,10 +1136,6 @@ public class SingleInspectionProfilePanel extends JPanel {
return false;
}
- public Tree getTreeTable() {
- return myTreeTable.getTree();
- }
-
public boolean isProfileShared() {
return myShareProfile;
}
@@ -1176,15 +1197,15 @@ public class SingleInspectionProfilePanel extends JPanel {
final boolean showOptionsAndDescriptorPanels,
@NotNull HighlightDisplayLevel level) {
final HighlightDisplayKey key = child.getDefaultDescriptor().getKey();
- mySelectedProfile.setErrorLevel(key, level, -1, myProjectProfileManager.getProject());
+ mySelectedProfile.setErrorLevel(key, level, null, myProjectProfileManager.getProject());
child.dropCache();
if (showOptionsAndDescriptorPanels) {
updateOptionsAndDescriptionPanel(new TreePath(child.getPath()));
}
}
- public JComponent getTree() {
- return myTreeTable.getTree();
+ public JComponent getPreferredFocusedComponent() {
+ return myTreeTable;
}
private class MyFilterComponent extends FilterComponent {
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/filter/InspectionFilterAction.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/filter/InspectionFilterAction.java
index cbd1c2482032..bccd2db28e21 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/filter/InspectionFilterAction.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/filter/InspectionFilterAction.java
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.daemon.impl.SeverityRegistrar;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.icons.AllIcons;
import com.intellij.lang.annotation.HighlightSeverity;
-import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.ex.CheckboxAction;
@@ -60,6 +59,23 @@ public class InspectionFilterAction extends DefaultActionGroup {
addSeparator();
add(new ShowAvailableOnlyOnAnalyzeInspectionsAction());
+ add(new ShowOnlyCleanupInspectionsAction());
+ }
+
+ private class ShowOnlyCleanupInspectionsAction extends CheckboxAction {
+ public ShowOnlyCleanupInspectionsAction() {
+ super("Show Only Cleanup Inspections");
+ }
+
+ @Override
+ public boolean isSelected(final AnActionEvent e) {
+ return myInspectionsFilter.isShowOnlyCleanupInspections();
+ }
+
+ @Override
+ public void setSelected(final AnActionEvent e, final boolean state) {
+ myInspectionsFilter.setShowOnlyCleanupInspections(state);
+ }
}
private class ShowAvailableOnlyOnAnalyzeInspectionsAction extends CheckboxAction {
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/filter/InspectionsFilter.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/filter/InspectionsFilter.java
index 432ef560ba58..117cd774dff8 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/filter/InspectionsFilter.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/filter/InspectionsFilter.java
@@ -33,11 +33,16 @@ public abstract class InspectionsFilter {
private final Set<HighlightSeverity> mySuitableSeverities = new HashSet<HighlightSeverity>();
private Boolean mySuitableInspectionsStates;
private boolean myAvailableOnlyForAnalyze;
+ private boolean myShowOnlyCleanupInspections;
public boolean isAvailableOnlyForAnalyze() {
return myAvailableOnlyForAnalyze;
}
+ public boolean isShowOnlyCleanupInspections() {
+ return myShowOnlyCleanupInspections;
+ }
+
public Boolean getSuitableInspectionsStates() {
return mySuitableInspectionsStates;
}
@@ -46,6 +51,11 @@ public abstract class InspectionsFilter {
return mySuitableSeverities.contains(severity);
}
+ public void setShowOnlyCleanupInspections(final boolean showOnlyCleanupInspections) {
+ myShowOnlyCleanupInspections = showOnlyCleanupInspections;
+ filterChanged();
+ }
+
public void setAvailableOnlyForAnalyze(final boolean availableOnlyForAnalyze) {
myAvailableOnlyForAnalyze = availableOnlyForAnalyze;
filterChanged();
@@ -67,10 +77,17 @@ public abstract class InspectionsFilter {
}
public boolean isEmptyFilter() {
- return mySuitableInspectionsStates == null && !myAvailableOnlyForAnalyze && mySuitableSeverities.isEmpty();
+ return mySuitableInspectionsStates == null
+ && !myAvailableOnlyForAnalyze
+ && !myShowOnlyCleanupInspections
+ && mySuitableSeverities.isEmpty();
}
public boolean matches(final Tools tools) {
+ if (myShowOnlyCleanupInspections && !tools.getTool().isCleanupTool()) {
+ return false;
+ }
+
if (mySuitableInspectionsStates != null && mySuitableInspectionsStates != tools.isEnabled()) {
return false;
}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java
index 966a456e1d38..92cb62f0f800 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java
@@ -28,17 +28,21 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.profile.codeInspection.ui.InspectionsAggregationUtil;
import com.intellij.profile.codeInspection.ui.table.ScopesAndSeveritiesTable;
import com.intellij.profile.codeInspection.ui.table.ThreeStateCheckBoxRenderer;
+import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.treeStructure.treetable.TreeTable;
import com.intellij.ui.treeStructure.treetable.TreeTableModel;
+import com.intellij.ui.treeStructure.treetable.TreeTableTree;
+import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
import java.awt.*;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
+import java.awt.event.*;
import java.util.*;
import java.util.List;
@@ -60,8 +64,8 @@ public class InspectionsConfigTreeTable extends TreeTable {
final TableColumn isEnabledColumn = getColumnModel().getColumn(IS_ENABLED_COLUMN);
isEnabledColumn.setMaxWidth(20);
- isEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer());
- isEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer());
+ isEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer(false));
+ isEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer(true));
addMouseMotionListener(new MouseAdapter() {
@Override
@@ -76,10 +80,42 @@ public class InspectionsConfigTreeTable extends TreeTable {
if (maybeIcon instanceof MultiScopeSeverityIcon) {
final LinkedHashMap<String, HighlightSeverity> scopeToAverageSeverityMap =
((MultiScopeSeverityIcon)maybeIcon).getScopeToAverageSeverityMap();
- IdeTooltipManager.getInstance().show(new IdeTooltip(InspectionsConfigTreeTable.this, point, new ScopesAndSeveritiesHintTable(scopeToAverageSeverityMap)), false);
+ IdeTooltipManager.getInstance().show(
+ new IdeTooltip(InspectionsConfigTreeTable.this, point, new ScopesAndSeveritiesHintTable(scopeToAverageSeverityMap)), false);
}
}
});
+
+ new DoubleClickListener() {
+ @Override
+ protected boolean onDoubleClick(MouseEvent event) {
+ final TreePath path = getTree().getPathForRow(getTree().getLeadSelectionRow());
+ if (path != null) {
+ final InspectionConfigTreeNode node = (InspectionConfigTreeNode)path.getLastPathComponent();
+ if (node.isLeaf()) {
+ swapInspectionEnableState();
+ }
+ }
+ return true;
+ }
+ }.installOn(this);
+
+ registerKeyboardAction(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ swapInspectionEnableState();
+ updateUI();
+ }
+ }, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), JComponent.WHEN_FOCUSED);
+
+ getEmptyText().setText("No enabled inspections available");
+ }
+
+ private void swapInspectionEnableState() {
+ for (int selectedRow : getSelectedRows()) {
+ final Object value = getValueAt(selectedRow, IS_ENABLED_COLUMN);
+ final boolean newValue = !Boolean.TRUE.equals(value);
+ setValueAt(newValue, selectedRow, IS_ENABLED_COLUMN);
+ }
}
public abstract static class InspectionsConfigTreeTableSettings {
@@ -107,6 +143,7 @@ public class InspectionsConfigTreeTable extends TreeTable {
private static class InspectionsConfigTreeTableModel extends DefaultTreeModel implements TreeTableModel {
private final InspectionsConfigTreeTableSettings mySettings;
+ private TreeTable myTreeTable;
public InspectionsConfigTreeTableModel(final InspectionsConfigTreeTableSettings settings) {
super(settings.getRoot());
@@ -154,7 +191,7 @@ public class InspectionsConfigTreeTable extends TreeTable {
mySettings.getInspectionProfile().getNonDefaultTools(toolId, mySettings.getProject()));
}
}
- return sink.constructIcon();
+ return sink.constructIcon(mySettings.getInspectionProfile());
} else if (column == IS_ENABLED_COLUMN) {
return isEnabled(inspectionsKeys);
}
@@ -195,26 +232,34 @@ public class InspectionsConfigTreeTable extends TreeTable {
aNode.dropCache();
mySettings.onChanged(aNode);
}
+ if (myTreeTable != null) {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ public void run() {
+ ((AbstractTableModel)myTreeTable.getModel()).fireTableDataChanged();
+ }
+ });
+ }
}
@Override
public void setTree(final JTree tree) {
+ myTreeTable = ((TreeTableTree)tree).getTreeTable();
}
}
private static class MultiColoredHighlightSeverityIconSink {
- private final LinkedHashMap<String, HighlightSeverity> myScopeToAverageSeverityMap = new LinkedHashMap<String, HighlightSeverity>();
+ private final Map<String, HighlightSeverity> myScopeToAverageSeverityMap = new HashMap<String, HighlightSeverity>();
+ private String myDefaultScopeName;
private boolean myIsFirst = true;
- public Icon constructIcon() {
+ public Icon constructIcon(final InspectionProfileImpl inspectionProfile) {
if (myScopeToAverageSeverityMap.isEmpty()) {
return null;
}
- //TODO order scopes
return !allScopesHasMixedSeverity()
- ? new MultiScopeSeverityIcon(myScopeToAverageSeverityMap)
+ ? new MultiScopeSeverityIcon(myScopeToAverageSeverityMap, myDefaultScopeName, inspectionProfile)
: ScopesAndSeveritiesTable.MIXED_FAKE_LEVEL.getIcon();
}
@@ -229,6 +274,9 @@ public class InspectionsConfigTreeTable extends TreeTable {
public void put(final ScopeToolState defaultState, final Collection<ScopeToolState> nonDefault) {
putOne(defaultState);
+ if (myDefaultScopeName == null) {
+ myDefaultScopeName = defaultState.getScopeName();
+ }
for (final ScopeToolState scopeToolState : nonDefault) {
putOne(scopeToolState);
}
@@ -237,7 +285,7 @@ public class InspectionsConfigTreeTable extends TreeTable {
}
}
- public void putOne(final ScopeToolState state) {
+ private void putOne(final ScopeToolState state) {
final Icon icon = state.getLevel().getIcon();
final String scopeName = state.getScopeName();
if (icon instanceof HighlightDisplayLevel.SingleColorIconWithMask) {
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/MultiScopeSeverityIcon.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/MultiScopeSeverityIcon.java
index 6f093ca66349..099dbb622261 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/MultiScopeSeverityIcon.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/MultiScopeSeverityIcon.java
@@ -17,13 +17,15 @@ package com.intellij.profile.codeInspection.ui.inspectionsTree;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.profile.codeInspection.ui.ScopeOrderComparator;
import com.intellij.ui.JBColor;
import javax.swing.*;
import java.awt.*;
-import java.util.Collection;
-import java.util.LinkedHashMap;
+import java.util.*;
+import java.util.List;
/**
* @author Dmitry Batkovich
@@ -35,8 +37,17 @@ public class MultiScopeSeverityIcon implements Icon {
private final LinkedHashMap<String, HighlightSeverity> myScopeToAverageSeverityMap;
- public MultiScopeSeverityIcon(final LinkedHashMap<String, HighlightSeverity> scopeToAverageSeverityMap) {
- myScopeToAverageSeverityMap = scopeToAverageSeverityMap;
+ public MultiScopeSeverityIcon(final Map<String, HighlightSeverity> scopeToAverageSeverityMap,
+ final String defaultScopeName,
+ final InspectionProfileImpl inspectionProfile) {
+ final List<String> sortedScopeNames = new ArrayList<String>(scopeToAverageSeverityMap.keySet());
+ myScopeToAverageSeverityMap = new LinkedHashMap<String, HighlightSeverity>();
+ Collections.sort(sortedScopeNames, new ScopeOrderComparator(inspectionProfile));
+ sortedScopeNames.remove(defaultScopeName);
+ sortedScopeNames.add(defaultScopeName);
+ for (final String scopeName : sortedScopeNames) {
+ myScopeToAverageSeverityMap.put(scopeName, scopeToAverageSeverityMap.get(scopeName));
+ }
}
public LinkedHashMap<String, HighlightSeverity> getScopeToAverageSeverityMap() {
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/ScopesAndSeveritiesHintTable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/ScopesAndSeveritiesHintTable.java
index 05cb7ab193f5..68c7f20119bd 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/ScopesAndSeveritiesHintTable.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/ScopesAndSeveritiesHintTable.java
@@ -19,10 +19,12 @@ import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel;
import com.intellij.ui.table.JBTable;
+import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableColumn;
import java.awt.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@@ -38,9 +40,20 @@ public class ScopesAndSeveritiesHintTable extends JBTable {
public ScopesAndSeveritiesHintTable(final LinkedHashMap<String, HighlightSeverity> scopeToAverageSeverityMap) {
super(new MyModel(scopeToAverageSeverityMap));
- final DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer();
- cellRenderer.setOpaque(false);
- getColumnModel().getColumn(SCOPE_COLUMN).setCellRenderer(cellRenderer);
+ getColumnModel().getColumn(SCOPE_COLUMN).setCellRenderer(new DefaultTableCellRenderer() {
+ @Override
+ public Component getTableCellRendererComponent(JTable table,
+ Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row,
+ int column) {
+ super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ setOpaque(false);
+ UIUtil.applyStyle(UIUtil.ComponentStyle.SMALL, this);
+ return this;
+ }
+ });
getColumnModel().getColumn(SEVERITY_COLUMN).setCellRenderer(new DefaultTableCellRenderer() {
@Override
@@ -55,6 +68,7 @@ public class ScopesAndSeveritiesHintTable extends JBTable {
setIcon(HighlightDisplayLevel.find(severity).getIcon());
setText(SingleInspectionProfilePanel.renderSeverity(severity));
setOpaque(false);
+ UIUtil.applyStyle(UIUtil.ComponentStyle.SMALL, this);
return this;
}
});
@@ -62,6 +76,16 @@ public class ScopesAndSeveritiesHintTable extends JBTable {
setRowSelectionAllowed(false);
setColumnSelectionAllowed(false);
setOpaque(false);
+
+ for (int i = 0; i < getColumnModel().getColumnCount(); i++) {
+ int w = 0;
+ final TableColumn column = getColumnModel().getColumn(i);
+ for (int j = 0; j < getModel().getRowCount(); j++) {
+ final Component component = prepareRenderer(column.getCellRenderer(), j, i);
+ w = Math.max(component.getPreferredSize().width, w);
+ }
+ column.setPreferredWidth(w);
+ }
}
private final static class MyModel extends AbstractTableModel {
@@ -96,7 +120,7 @@ public class ScopesAndSeveritiesHintTable extends JBTable {
@Override
public Object getValueAt(final int rowIndex, final int columnIndex) {
switch (columnIndex) {
- case SCOPE_COLUMN: return myScopes.get(rowIndex);
+ case SCOPE_COLUMN: return rowIndex < getRowCount() - 1 ? myScopes.get(rowIndex) : "Everywhere else";
case SEVERITY_COLUMN: return myScopeToAverageSeverityMap.get(myScopes.get(rowIndex));
default: throw new IllegalArgumentException();
}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java
index ad7dc946fff8..3b2c36bf7d34 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ScopesAndSeveritiesTable.java
@@ -17,20 +17,30 @@ package com.intellij.profile.codeInspection.ui.table;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.codeInspection.ex.Descriptor;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.codeInspection.ex.ScopeToolState;
import com.intellij.icons.AllIcons;
+import com.intellij.ide.DataManager;
import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.util.Comparing;
-import com.intellij.profile.codeInspection.ui.AddScopeUtil;
+import com.intellij.profile.codeInspection.ui.ScopeOrderComparator;
+import com.intellij.profile.codeInspection.ui.ScopesChooser;
import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionConfigTreeNode;
import com.intellij.psi.search.scope.packageSet.NamedScope;
+import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.table.JBTable;
import com.intellij.ui.treeStructure.treetable.TreeTable;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.EditableModel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,8 +51,8 @@ import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
+import java.awt.*;
+import java.util.*;
import java.util.List;
/**
@@ -66,8 +76,8 @@ public class ScopesAndSeveritiesTable extends JBTable {
final TableColumn scopeEnabledColumn = columnModel.getColumn(SCOPE_ENABLED_COLUMN);
scopeEnabledColumn.setMaxWidth(30);
- scopeEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer());
- scopeEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer());
+ scopeEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer(false));
+ scopeEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer(true));
final TableColumn severityColumn = columnModel.getColumn(SEVERITY_COLUMN);
severityColumn.setCellRenderer(SeverityRenderer.create(tableSettings.getInspectionProfile()));
@@ -94,6 +104,8 @@ public class ScopesAndSeveritiesTable extends JBTable {
setStriped(true);
setShowGrid(false);
+
+ ((MyTableModel)getModel()).setTable(this);
}
public abstract static class TableSettings {
@@ -148,11 +160,13 @@ public class ScopesAndSeveritiesTable extends JBTable {
protected abstract void onScopeAdded();
+ protected abstract void onScopesOrderChanged();
+
protected abstract void onScopeRemoved(final int scopesCount);
protected abstract void onScopeChosen(final @NotNull ScopeToolState scopeToolState);
- protected abstract void onChange();
+ protected abstract void onSettingsChanged();
}
@NotNull
@@ -177,7 +191,9 @@ public class ScopesAndSeveritiesTable extends JBTable {
private final Project myProject;
private final TableSettings myTableSettings;
private final List<HighlightDisplayKey> myKeys;
+ private final Comparator<String> myScopeComparator;
+ private JTable myTable;
private String[] myScopeNames;
public MyTableModel(final TableSettings tableSettings) {
@@ -188,12 +204,24 @@ public class ScopesAndSeveritiesTable extends JBTable {
myKeyNames = tableSettings.getKeyNames();
myNodes = tableSettings.getNodes();
myTreeTable = tableSettings.getTreeTable();
+ myScopeComparator = new ScopeOrderComparator(myInspectionProfile);
refreshAggregatedScopes();
}
+ public void setTable(JTable table) {
+ myTable = table;
+ }
+
@Override
public boolean isCellEditable(final int rowIndex, final int columnIndex) {
- return columnIndex != SCOPE_NAME_COLUMN;
+ if (columnIndex == SCOPE_NAME_COLUMN) {
+ return false;
+ } else if (columnIndex == SCOPE_ENABLED_COLUMN) {
+ return true;
+ }
+ assert columnIndex == SEVERITY_COLUMN;
+ final ExistedScopesStatesAndNonExistNames scopeToolState = getScopeToolState(rowIndex);
+ return scopeToolState.getNonExistNames().isEmpty();
}
@Override
@@ -221,7 +249,7 @@ public class ScopesAndSeveritiesTable extends JBTable {
return String.class;
}
if (SEVERITY_COLUMN == columnIndex) {
- return HighlightSeverity.class;
+ return SeverityState.class;
}
throw new IllegalArgumentException();
}
@@ -235,9 +263,9 @@ public class ScopesAndSeveritiesTable extends JBTable {
case SCOPE_ENABLED_COLUMN:
return isEnabled(rowIndex);
case SCOPE_NAME_COLUMN:
- return getScope(rowIndex).getName();
+ return rowIndex == lastRowIndex() ? "Everywhere else" : getScope(rowIndex).getName();
case SEVERITY_COLUMN:
- return getSeverity(rowIndex);
+ return getSeverityState(rowIndex);
default:
throw new IllegalArgumentException("Invalid column index " + columnIndex);
}
@@ -248,12 +276,12 @@ public class ScopesAndSeveritiesTable extends JBTable {
}
@NotNull
- private HighlightSeverity getSeverity(final int rowIndex) {
+ private SeverityState getSeverityState(final int rowIndex) {
final ExistedScopesStatesAndNonExistNames existedScopesStatesAndNonExistNames = getScopeToolState(rowIndex);
if (!existedScopesStatesAndNonExistNames.getNonExistNames().isEmpty()) {
- return MIXED_FAKE_SEVERITY;
+ return new SeverityState(MIXED_FAKE_SEVERITY, false);
}
- return ScopesAndSeveritiesTable.getSeverity(existedScopesStatesAndNonExistNames.getExistedStates());
+ return new SeverityState(ScopesAndSeveritiesTable.getSeverity(existedScopesStatesAndNonExistNames.getExistedStates()), true);
}
@Nullable
@@ -314,6 +342,7 @@ public class ScopesAndSeveritiesTable extends JBTable {
}
}
myScopeNames = ArrayUtil.toStringArray(scopesNames);
+ Arrays.sort(myScopeNames, myScopeComparator);
}
private int lastRowIndex() {
@@ -326,13 +355,14 @@ public class ScopesAndSeveritiesTable extends JBTable {
return;
}
if (columnIndex == SEVERITY_COLUMN) {
- final HighlightDisplayLevel level = HighlightDisplayLevel.find(((HighlightSeverity)value).getName());
+ final SeverityState severityState = (SeverityState)value;
+ final HighlightDisplayLevel level = HighlightDisplayLevel.find(severityState.getSeverity().getName());
if (level == null) {
- LOG.error("no display level found for name " + ((HighlightSeverity)value).getName());
+ LOG.error("no display level found for name " + severityState.getSeverity().getName());
return;
}
- final int idx = rowIndex == lastRowIndex() ? -1 : rowIndex;
- myInspectionProfile.setErrorLevel(myKeys, level, idx, myProject);
+ final String scopeName = rowIndex == lastRowIndex() ? null : getScope(rowIndex).getName();
+ myInspectionProfile.setErrorLevel(myKeys, level, scopeName, myProject);
}
else if (columnIndex == SCOPE_ENABLED_COLUMN) {
final NamedScope scope = getScope(rowIndex);
@@ -354,7 +384,7 @@ public class ScopesAndSeveritiesTable extends JBTable {
}
}
}
- myTableSettings.onChange();
+ myTableSettings.onSettingsChanged();
}
@Override
@@ -368,9 +398,31 @@ public class ScopesAndSeveritiesTable extends JBTable {
@Override
public void addRow() {
- AddScopeUtil.performAddScope(myTreeTable, myProject, myInspectionProfile, myNodes);
- myTableSettings.onScopeAdded();
- refreshAggregatedScopes();
+ final List<Descriptor> descriptors = ContainerUtil.map(myTableSettings.getNodes(), new Function<InspectionConfigTreeNode, Descriptor>() {
+ @Override
+ public Descriptor fun(InspectionConfigTreeNode inspectionConfigTreeNode) {
+ return inspectionConfigTreeNode.getDefaultDescriptor();
+ }
+ });
+ final ScopesChooser scopesChooser = new ScopesChooser(descriptors, myInspectionProfile, myProject, myScopeNames) {
+ @Override
+ protected void onScopeAdded() {
+ myTableSettings.onScopeAdded();
+ refreshAggregatedScopes();
+ }
+
+ @Override
+ protected void onScopesOrderChanged() {
+ myTableSettings.onScopesOrderChanged();
+ }
+ };
+ DataContext dataContext = DataManager.getInstance().getDataContext(myTable);
+ final JComponent component = (JComponent)PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);
+ final ListPopup popup = JBPopupFactory.getInstance()
+ .createActionGroupPopup(ScopesChooser.TITLE, scopesChooser.createPopupActionGroup(myTable), dataContext,
+ JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false);
+ final RelativePoint point = new RelativePoint(myTable, new Point(myTable.getWidth() - popup.getContent().getPreferredSize().width, 0));
+ popup.show(point);
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityRenderer.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityRenderer.java
index 2fe95e6d7224..e1b3d54b8fb7 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityRenderer.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityRenderer.java
@@ -22,6 +22,8 @@ import com.intellij.openapi.ui.ComboBoxTableRenderer;
import com.intellij.profile.codeInspection.SeverityProvider;
import com.intellij.profile.codeInspection.ui.LevelChooserAction;
import com.intellij.profile.codeInspection.ui.SingleInspectionProfilePanel;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -32,33 +34,40 @@ import java.util.SortedSet;
/**
* @author Dmitry Batkovich
*/
-public class SeverityRenderer extends ComboBoxTableRenderer<HighlightSeverity> {
- public SeverityRenderer(final HighlightSeverity[] values) {
+public class SeverityRenderer extends ComboBoxTableRenderer<SeverityState> {
+ public SeverityRenderer(final SeverityState[] values) {
super(values);
}
public static SeverityRenderer create(final InspectionProfileImpl inspectionProfile) {
final SortedSet<HighlightSeverity> severities =
LevelChooserAction.getSeverities(((SeverityProvider)inspectionProfile.getProfileManager()).getOwnSeverityRegistrar());
- return new SeverityRenderer(severities.toArray(new HighlightSeverity[severities.size()]));
+ return new SeverityRenderer(ContainerUtil.map2Array(severities, new SeverityState[severities.size()], new Function<HighlightSeverity, SeverityState>() {
+ @Override
+ public SeverityState fun(HighlightSeverity severity) {
+ return new SeverityState(severity, true);
+ }
+ }));
}
+ @Override
+ protected void customizeComponent(SeverityState value, JTable table, boolean isSelected) {
+ super.customizeComponent(value, table, isSelected);
+ setPaintArrow(value.isEnabledForEditing());
+ }
@Override
- protected String getTextFor(@NotNull final HighlightSeverity value) {
- return SingleInspectionProfilePanel.renderSeverity(value);
+ protected String getTextFor(@NotNull final SeverityState value) {
+ return SingleInspectionProfilePanel.renderSeverity(value.getSeverity());
}
@Override
- protected Icon getIconFor(@NotNull final HighlightSeverity value) {
- return HighlightDisplayLevel.find(value).getIcon();
+ protected Icon getIconFor(@NotNull final SeverityState value) {
+ return HighlightDisplayLevel.find(value.getSeverity()).getIcon();
}
@Override
public boolean isCellEditable(final EventObject event) {
- if (event instanceof MouseEvent) {
- return ((MouseEvent)event).getClickCount() >= 1;
- }
- return true;
+ return !(event instanceof MouseEvent) || ((MouseEvent)event).getClickCount() >= 1;
}
}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityState.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityState.java
new file mode 100644
index 000000000000..2aefde070af7
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/SeverityState.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.profile.codeInspection.ui.table;
+
+import com.intellij.lang.annotation.HighlightSeverity;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class SeverityState {
+
+ private final HighlightSeverity mySeverity;
+ private final boolean myEnabledForEditing;
+
+ public SeverityState(HighlightSeverity severity, boolean enabledForEditing) {
+ mySeverity = severity;
+ myEnabledForEditing = enabledForEditing;
+ }
+
+ public HighlightSeverity getSeverity() {
+ return mySeverity;
+ }
+
+ public boolean isEnabledForEditing() {
+ return myEnabledForEditing;
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java
index 7d8cfdfc9db5..455e2a60cd19 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java
@@ -15,11 +15,9 @@
*/
package com.intellij.profile.codeInspection.ui.table;
-import com.intellij.ui.ClickListener;
import com.intellij.util.SmartList;
import com.intellij.util.ui.ThreeStateCheckBox;
import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -28,7 +26,7 @@ import javax.swing.event.ChangeEvent;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
-import java.awt.event.MouseEvent;
+import java.awt.event.*;
import java.util.EventObject;
import java.util.List;
@@ -39,10 +37,16 @@ public class ThreeStateCheckBoxRenderer extends ThreeStateCheckBox implements Ta
private final List<CellEditorListener> myListeners = new SmartList<CellEditorListener>();
- public ThreeStateCheckBoxRenderer() {
+ public ThreeStateCheckBoxRenderer(final boolean isEditor) {
setThirdStateEnabled(false);
setHorizontalAlignment(CENTER);
setVerticalAlignment(CENTER);
+ addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ stopCellEditing();
+ }
+ });
}
@Override
@@ -69,16 +73,6 @@ public class ThreeStateCheckBoxRenderer extends ThreeStateCheckBox implements Ta
} else {
setSelected((Boolean) value);
}
- new ClickListener() {
- @Override
- public boolean onClick(@NotNull final MouseEvent event, final int clickCount) {
- if (clickCount == 1) {
- stopCellEditing();
- return true;
- }
- return false;
- }
- }.installOn(this);
return this;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java
index 1b17faf21905..42dcb46c7ac0 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerRunnable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -149,7 +149,7 @@ abstract class CodeStyleManagerRunnable<T> {
SourceTreeToPsiMap.psiElementToTree(CodeStyleManagerImpl.findElementInTreeWithFormatterEnabled(file, offset));
if (elementAtOffset == null) {
int significantRangeStart = CharArrayUtil.shiftBackward(file.getText(), offset - 1, "\r\t ");
- return new TextRange(significantRangeStart, offset);
+ return new TextRange(Math.max(significantRangeStart, 0), offset);
}
final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(file);
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java
index 27089fa70e91..fdc434d8d11a 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/InjectedLanguageUtil.java
@@ -16,6 +16,7 @@
package com.intellij.psi.impl.source.tree.injected;
+import com.intellij.extapi.psi.PsiFileBase;
import com.intellij.injected.editor.*;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageUtil;
@@ -48,8 +49,10 @@ import java.util.List;
* @author cdr
*/
public class InjectedLanguageUtil {
- static final Key<List<Trinity<IElementType, SmartPsiElementPointer<PsiLanguageInjectionHost>, TextRange>>> HIGHLIGHT_TOKENS = Key.create("HIGHLIGHT_TOKENS");
- public static Key<Boolean> FRANKENSTEIN_INJECTION = Key.create("FRANKENSTEIN_INJECTION"); // meaning: injected file text is probably incorrect
+ static final Key<List<Trinity<IElementType, SmartPsiElementPointer<PsiLanguageInjectionHost>, TextRange>>> HIGHLIGHT_TOKENS =
+ Key.create("HIGHLIGHT_TOKENS");
+ public static Key<Boolean> FRANKENSTEIN_INJECTION = Key.create("FRANKENSTEIN_INJECTION");
+ // meaning: injected file text is probably incorrect
public static void forceInjectionOnElement(@NotNull PsiElement host) {
enumerate(host, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
@@ -113,9 +116,9 @@ public class InjectedLanguageUtil {
* @return true if enumerated successfully
*/
public static boolean enumerate(@NotNull PsiElement host,
- @NotNull PsiFile containingFile,
- boolean probeUp,
- @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) {
+ @NotNull PsiFile containingFile,
+ boolean probeUp,
+ @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) {
//do not inject into nonphysical files except during completion
if (!containingFile.isPhysical() && containingFile.getOriginalFile() == containingFile) {
final PsiElement context = InjectedLanguageManager.getInstance(containingFile.getProject()).getInjectionHost(containingFile);
@@ -175,6 +178,32 @@ public class InjectedLanguageUtil {
return null;
}
+ /**
+ * Finds injected language in expression
+ *
+ * @param expression where to find
+ * @param classToFind class that represents language we look for
+ * @param <T> class that represents language we look for
+ * @return instance of class that represents language we look for or null of not found
+ */
+ @Nullable
+ @SuppressWarnings("unchecked") // We check types dynamically (using isAssignableFrom)
+ public static <T extends PsiFileBase> T findInjectedFile(@NotNull final PsiElement expression,
+ @NotNull final Class<T> classToFind) {
+ final List<Pair<PsiElement, TextRange>> files =
+ InjectedLanguageManager.getInstance(expression.getProject()).getInjectedPsiFiles(expression);
+ if (files == null) {
+ return null;
+ }
+ for (final Pair<PsiElement, TextRange> fileInfo : files) {
+ final PsiElement injectedFile = fileInfo.first;
+ if (classToFind.isAssignableFrom(injectedFile.getClass())) {
+ return (T)injectedFile;
+ }
+ }
+ return null;
+ }
+
public static Editor getEditorForInjectedLanguageNoCommit(@Nullable Editor editor, @Nullable PsiFile file, final int offset) {
if (editor == null || file == null || editor instanceof EditorWindow) return editor;
PsiFile injectedFile = findInjectedPsiNoCommit(file, offset);
@@ -200,7 +229,9 @@ public class InjectedLanguageUtil {
}
}
}
- if (!documentWindow.isValid()) return hostEditor; // since the moment we got hold of injectedFile and this moment call, document may have been dirtied
+ if (!documentWindow.isValid()) {
+ return hostEditor; // since the moment we got hold of injectedFile and this moment call, document may have been dirtied
+ }
return EditorWindowImpl.create(documentWindow, (EditorImpl)hostEditor, injectedFile);
}
@@ -284,7 +315,8 @@ public class InjectedLanguageUtil {
ParameterizedCachedValue<MultiHostRegistrarImpl, PsiElement> cachedValue =
CachedValuesManager.getManager(project).createParameterizedCachedValue(INJECTED_PSI_PROVIDER, false);
- CachedValueProvider.Result<MultiHostRegistrarImpl> result = CachedValueProvider.Result.create(registrar, PsiModificationTracker.MODIFICATION_COUNT, registrar);
+ CachedValueProvider.Result<MultiHostRegistrarImpl> result =
+ CachedValueProvider.Result.create(registrar, PsiModificationTracker.MODIFICATION_COUNT, registrar);
((PsiParameterizedCachedValue<MultiHostRegistrarImpl, PsiElement>)cachedValue).setValue(result);
e.putUserData(INJECTED_PSI, cachedValue);
@@ -307,7 +339,9 @@ public class InjectedLanguageUtil {
// returns (injected psi, leaf element at the offset, language of the leaf element)
// since findElementAt() is expensive, we trying to reuse its result
@NotNull
- private static Trinity<PsiElement,PsiElement,Language> tryOffset(@NotNull PsiFile hostFile, final int offset, @NotNull PsiDocumentManager documentManager) {
+ private static Trinity<PsiElement, PsiElement, Language> tryOffset(@NotNull PsiFile hostFile,
+ final int offset,
+ @NotNull PsiDocumentManager documentManager) {
FileViewProvider provider = hostFile.getViewProvider();
Language leafLanguage = null;
PsiElement leafElement = null;
@@ -319,11 +353,11 @@ public class InjectedLanguageUtil {
leafElement = element;
}
PsiElement injected = findInside(element, hostFile, offset, documentManager);
- if (injected != null) return Trinity.create(injected,element, language);
+ if (injected != null) return Trinity.create(injected, element, language);
}
// maybe we are at the border between two psi elements, then try to find injection at the end of the left element
if (offset != 0 && (element == null || element.getTextRange().getStartOffset() == offset)) {
- PsiElement leftElement = provider.findElementAt(offset-1, language);
+ PsiElement leftElement = provider.findElementAt(offset - 1, language);
if (leftElement != null && leftElement.getTextRange().getEndOffset() == offset) {
PsiElement injected = findInside(leftElement, hostFile, offset, documentManager);
if (injected != null) return Trinity.create(injected, element, language);
@@ -334,7 +368,10 @@ public class InjectedLanguageUtil {
return Trinity.create(null, leafElement, leafLanguage);
}
- private static PsiElement findInside(@NotNull PsiElement element, @NotNull PsiFile hostFile, final int hostOffset, @NotNull final PsiDocumentManager documentManager) {
+ private static PsiElement findInside(@NotNull PsiElement element,
+ @NotNull PsiFile hostFile,
+ final int hostOffset,
+ @NotNull final PsiDocumentManager documentManager) {
final Ref<PsiElement> out = new Ref<PsiElement>();
enumerate(element, hostFile, true, new PsiLanguageInjectionHost.InjectedPsiVisitor() {
@Override
@@ -361,10 +398,12 @@ public class InjectedLanguageUtil {
// modification of cachedInjectedDocuments must be under PsiLock only
ConcurrentList<DocumentWindow> injected = hostPsiFile.getUserData(INJECTED_DOCS_KEY);
if (injected == null) {
- injected = ((UserDataHolderEx)hostPsiFile).putUserDataIfAbsent(INJECTED_DOCS_KEY, ContainerUtil.<DocumentWindow>createConcurrentList());
+ injected =
+ ((UserDataHolderEx)hostPsiFile).putUserDataIfAbsent(INJECTED_DOCS_KEY, ContainerUtil.<DocumentWindow>createConcurrentList());
}
return injected;
}
+
public static void clearCachedInjectedFragmentsForFile(@NotNull PsiFile file) {
file.putUserData(INJECTED_DOCS_KEY, null);
}
@@ -426,10 +465,12 @@ public class InjectedLanguageUtil {
}
return containingFile;
}
+
@NotNull
public static Editor getTopLevelEditor(@NotNull Editor editor) {
return editor instanceof EditorWindow ? ((EditorWindow)editor).getDelegate() : editor;
}
+
public static boolean isInInjectedLanguagePrefixSuffix(@NotNull final PsiElement element) {
PsiFile injectedFile = element.getContainingFile();
if (injectedFile == null) return false;
@@ -461,13 +502,13 @@ public class InjectedLanguageUtil {
public static String getUnescapedText(PsiFile file, @Nullable final PsiElement startElement, @Nullable final PsiElement endElement) {
final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(file.getProject());
if (manager.getInjectionHost(file) == null) {
- return file.getText().substring(startElement == null? 0 : startElement.getTextRange().getStartOffset(),
- endElement == null? file.getTextLength() : endElement.getTextRange().getStartOffset());
+ return file.getText().substring(startElement == null ? 0 : startElement.getTextRange().getStartOffset(),
+ endElement == null ? file.getTextLength() : endElement.getTextRange().getStartOffset());
}
final StringBuilder sb = new StringBuilder();
file.accept(new PsiRecursiveElementWalkingVisitor() {
- Boolean myState = startElement == null? Boolean.TRUE : null;
+ Boolean myState = startElement == null ? Boolean.TRUE : null;
@Override
public void visitElement(PsiElement element) {
diff --git a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/KeyboardComboSwitcher.java b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/KeyboardComboSwitcher.java
index 99ac9f7ec586..232ddd7bec3b 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/KeyboardComboSwitcher.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/KeyboardComboSwitcher.java
@@ -28,7 +28,7 @@ public class KeyboardComboSwitcher {
if (toggleStrategy) {
final int size = comboBox.getModel().getSize();
int next = comboBox.getSelectedIndex() + 1;
- if (next < 0 || next >= size) {
+ if (size > 0 && (next < 0 || next >= size)) {
if (!UISettings.getInstance().CYCLE_SCROLLING) {
return;
}
diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java
index 1301079a1967..6e37711a9493 100644
--- a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java
@@ -151,6 +151,7 @@ public class DetailViewImpl extends JPanel implements DetailView, UserDataHolder
getEditor().getSettings().setRefrainFromScrolling(false);
getEditor().getSettings().setLineNumbersShown(true);
getEditor().getSettings().setFoldingOutlineShown(false);
+ ((EditorEx)getEditor()).getFoldingModel().setFoldingEnabled(false);
add(getEditor().getComponent(), BorderLayout.CENTER);
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ContentHashesSupport.java b/platform/lang-impl/src/com/intellij/util/indexing/ContentHashesSupport.java
index 34f80dae5cc9..451b0e7c1954 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/ContentHashesSupport.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/ContentHashesSupport.java
@@ -84,7 +84,7 @@ class ContentHashesSupport {
messageDigest.update((byte)0);
messageDigest.update(String.valueOf(bytes.length).getBytes(defaultCharset));
messageDigest.update((byte)0);
- messageDigest.update((charset != null ? charset.displayName():"null_charset").getBytes(defaultCharset));
+ messageDigest.update((charset != null ? charset.name():"null_charset").getBytes(defaultCharset));
messageDigest.update((byte)0);
messageDigest.update(bytes, 0, bytes.length);
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/DebugAssertions.java b/platform/lang-impl/src/com/intellij/util/indexing/DebugAssertions.java
index 6c866ad2283f..09aeea33b71e 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/DebugAssertions.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/DebugAssertions.java
@@ -31,7 +31,7 @@ public class DebugAssertions {
public static final boolean EXTRA_SANITY_CHECKS = SystemProperties.getBooleanProperty(
"intellij.idea.indices.debug.extra.sanity",
- true
+ DEBUG
);
public static void assertTrue(boolean value) {
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
index 5242ee3b70cf..85077380ea6e 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -1964,33 +1964,38 @@ public class FileBasedIndexImpl extends FileBasedIndex {
// For 'normal indices' schedule the file for update and reset stamps for all affected indices (there
// can be client that used indices between before and after events, in such case indices are up to date due to force update
// with old content)
- if (!fileIsDirectory && !isTooLarge(file)) {
- FileTypeManagerImpl.cacheFileType(file, file.getFileType());
- try {
- final List<ID<?, ?>> candidates = getAffectedIndexCandidates(file);
- //noinspection ForLoopReplaceableByForEach
- boolean scheduleForUpdate = false;
- boolean resetStamp = false;
-
- //noinspection ForLoopReplaceableByForEach
- for (int i = 0, size = candidates.size(); i < size; ++i) {
- final ID<?, ?> indexId = candidates.get(i);
- if (needsFileContentLoading(indexId) && getInputFilter(indexId).acceptInput(file)) {
- if (IndexingStamp.isFileIndexedStateCurrent(file, indexId)) {
- IndexingStamp.setFileIndexedStateOutdated(file, indexId);
- resetStamp = true;
+ if (!fileIsDirectory) {
+ if (isTooLarge(file)) {
+ // large file might be scheduled for update in before event when its size was not large
+ myChangedFilesCollector.myFilesToUpdate.remove(file);
+ } else {
+ FileTypeManagerImpl.cacheFileType(file, file.getFileType());
+ try {
+ final List<ID<?, ?>> candidates = getAffectedIndexCandidates(file);
+ //noinspection ForLoopReplaceableByForEach
+ boolean scheduleForUpdate = false;
+ boolean resetStamp = false;
+
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0, size = candidates.size(); i < size; ++i) {
+ final ID<?, ?> indexId = candidates.get(i);
+ if (needsFileContentLoading(indexId) && getInputFilter(indexId).acceptInput(file)) {
+ if (IndexingStamp.isFileIndexedStateCurrent(file, indexId)) {
+ IndexingStamp.setFileIndexedStateOutdated(file, indexId);
+ resetStamp = true;
+ }
+ scheduleForUpdate = true;
}
- scheduleForUpdate = true;
}
- }
- if (scheduleForUpdate) {
- if (resetStamp) IndexingStamp.flushCache(file);
- scheduleForUpdate(file);
+ if (scheduleForUpdate) {
+ if (resetStamp) IndexingStamp.flushCache(file);
+ scheduleForUpdate(file);
+ }
+ }
+ finally {
+ FileTypeManagerImpl.cacheFileType(file, null);
}
- }
- finally {
- FileTypeManagerImpl.cacheFileType(file, null);
}
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java
index 6bdd55b1d343..5ef1379eaaf4 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/IndexingStamp.java
@@ -59,7 +59,7 @@ public class IndexingStamp {
private static final long UNINDEXED_STAMP = -1L; // we don't store trivial "absent" state
private static final long INDEX_DATA_OUTDATED_STAMP = -2L;
- private static final int VERSION = 12;
+ private static final int VERSION = 13;
private static final ConcurrentHashMap<ID<?, ?>, Long> ourIndexIdToCreationStamp = new ConcurrentHashMap<ID<?, ?>, Long>();
private static volatile long ourLastStamp; // ensure any file index stamp increases
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
index ebb7911e82be..6427765295c5 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java
@@ -354,7 +354,7 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
FileContent fileContent = (FileContent)content;
hashId = getHashOfContent(fileContent);
if (doReadSavedPersistentData) {
- if (!myContents.isBusyReading()) { // avoid blocking read, we can calculate index value
+ if (!myContents.isBusyReading() || DebugAssertions.EXTRA_SANITY_CHECKS) { // avoid blocking read, we can calculate index value
ByteSequence bytes = myContents.get(hashId);
if (bytes != null) {
data = deserializeSavedPersistentData(bytes);
@@ -367,7 +367,7 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
"Unexpected difference in indexing of %s by index %s, file type %s, charset %s\ndiff %s\nprevious indexed info %s",
fileContent.getFile(),
myIndexId,
- fileContent.getFileType(),
+ fileContent.getFileType().getName(),
((FileContentImpl)fileContent).getCharset(),
buildDiff(data, contentData),
myIndexingTrace.get(hashId)
@@ -396,7 +396,7 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
FileContent fileContent = (FileContent)content;
try {
- myIndexingTrace.put(hashId, ((FileContentImpl)fileContent).getCharset() + "," + fileContent.getFileType()+"," + fileContent.getFile().getPath() + "," +
+ myIndexingTrace.put(hashId, ((FileContentImpl)fileContent).getCharset() + "," + fileContent.getFileType().getName()+"," + fileContent.getFile().getPath() + "," +
ExceptionUtil.getThrowableText(new Throwable()));
} catch (IOException ex) {
LOG.error(ex);
diff --git a/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java b/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java
index 18961ca843c3..fcbaa21f330b 100644
--- a/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java
+++ b/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.webcore.packaging;
import com.intellij.icons.AllIcons;
@@ -93,6 +108,7 @@ public class ManagePackagesDialog extends DialogWrapper {
public void run() {
try {
myController.reloadAllPackages();
+ initModel();
myPackages.setPaintBusy(false);
}
catch (final IOException e) {
@@ -310,6 +326,7 @@ public class ManagePackagesDialog extends DialogWrapper {
@Override
public void run() {
myPackages.setModel(myPackagesModel);
+ ((MyPackageFilter)myFilter).filter();
doSelectPackage(mySelectedPackageName);
setDownloadStatus(false);
}
@@ -473,6 +490,7 @@ public class ManagePackagesDialog extends DialogWrapper {
final Object pyPackage = myPackages.getSelectedValue();
if (pyPackage instanceof RepoPackage) {
final String packageName = ((RepoPackage)pyPackage).getName();
+ mySelectedPackageName = packageName;
myVersionComboBox.removeAllItems();
if (myVersionCheckBox.isEnabled()) {
myController.fetchPackageVersions(packageName, new CatchingConsumer<List<String>, Exception>() {
diff --git a/platform/lang-impl/src/com/intellij/webcore/packaging/PackagesNotificationPanel.java b/platform/lang-impl/src/com/intellij/webcore/packaging/PackagesNotificationPanel.java
index cb281cb3d7af..1513bb451aa2 100644
--- a/platform/lang-impl/src/com/intellij/webcore/packaging/PackagesNotificationPanel.java
+++ b/platform/lang-impl/src/com/intellij/webcore/packaging/PackagesNotificationPanel.java
@@ -8,6 +8,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.HyperlinkAdapter;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBLabel;
+import com.intellij.util.ui.SwingHelper;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -22,18 +23,17 @@ import java.util.Map;
* @author yole
*/
public class PackagesNotificationPanel {
- private final JEditorPane myEditorPane = new MyNotificationPane();
private final Project myProject;
+ private final JEditorPane myHtmlViewer;
private final Map<String, Runnable> myLinkHandlers = new HashMap<String, Runnable>();
private String myErrorTitle;
private String myErrorDescription;
- public PackagesNotificationPanel(Project project) {
+ public PackagesNotificationPanel(@NotNull Project project) {
myProject = project;
- myEditorPane.setBackground(UIManager.getColor("ArrowButton.background"));
- myEditorPane.setContentType("text/html");
- myEditorPane.setEditable(false);
- myEditorPane.addHyperlinkListener(new HyperlinkAdapter() {
+ myHtmlViewer = SwingHelper.createHtmlViewer(true, null, null, null);
+ myHtmlViewer.setVisible(false);
+ myHtmlViewer.addHyperlinkListener(new HyperlinkAdapter() {
@Override
protected void hyperlinkActivated(HyperlinkEvent e) {
final Runnable handler = myLinkHandlers.get(e.getDescription());
@@ -76,11 +76,18 @@ public class PackagesNotificationPanel {
public void showResult(String packageName, @Nullable String errorDescription) {
if (StringUtil.isEmpty(errorDescription)) {
- showSuccess("Package successfully installed.");
+ String message = "Package installed successfully";
+ if (packageName != null) {
+ message = "Package '" + packageName + "' installed successfully";
+ }
+ showSuccess(message);
}
else {
- String title = "Install packages failed";
- final String firstLine = title + ": Error occurred when installing package " + packageName + ". ";
+ String title = "Failed to install packages";
+ if (packageName != null) {
+ title = "Failed to install package '" + packageName + "'";
+ }
+ String firstLine = "Error occurred when installing package '" + packageName + "'. ";
showError(firstLine + "<a href=\"xxx\">Details...</a>",
title,
firstLine + errorDescription);
@@ -96,19 +103,18 @@ public class PackagesNotificationPanel {
}
public JComponent getComponent() {
- return myEditorPane;
+ return myHtmlViewer;
}
public void showSuccess(String text) {
showContent(text, MessageType.INFO.getPopupBackground());
}
- private void showContent(String text, final Color background) {
- myEditorPane.removeAll();
+ private void showContent(@NotNull String text, @NotNull Color background) {
String htmlText = text.startsWith("<html>") ? text : UIUtil.toHtml(text);
- myEditorPane.setText(htmlText);
- myEditorPane.setBackground(background);
- myEditorPane.setVisible(true);
+ myHtmlViewer.setText(htmlText);
+ myHtmlViewer.setBackground(background);
+ setVisibleEditorPane(true);
myErrorTitle = null;
myErrorDescription = null;
}
@@ -124,22 +130,20 @@ public class PackagesNotificationPanel {
}
public void hide() {
- myEditorPane.setVisible(false);
+ setVisibleEditorPane(false);
}
- public boolean hasLinkHandler(String key) {
- return myLinkHandlers.containsKey(key);
+ private void setVisibleEditorPane(boolean visible) {
+ boolean oldVisible = myHtmlViewer.isVisible();
+ myHtmlViewer.setVisible(visible);
+ if (oldVisible != visible) {
+ myHtmlViewer.revalidate();
+ myHtmlViewer.repaint();
+ }
}
- private static class MyNotificationPane extends JEditorPane {
- @Override
- public Dimension getPreferredSize() {
- // This trick makes text component to carry text over to the next line
- // iff the text line width exceeds parent's width
- Dimension dimension = super.getPreferredSize();
- dimension.width = 0;
- return dimension;
- }
+ public boolean hasLinkHandler(String key) {
+ return myLinkHandlers.containsKey(key);
}
public void removeLinkHandler(String key) {
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/beforeBrace-after.java b/platform/lang-impl/testData/editor/indentingBackspace/beforeBrace-after.java
new file mode 100644
index 000000000000..f1733f5e6d06
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/beforeBrace-after.java
@@ -0,0 +1,4 @@
+class A {
+ void foo() {
+ }
+<caret>}
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/beforeBrace.java b/platform/lang-impl/testData/editor/indentingBackspace/beforeBrace.java
new file mode 100644
index 000000000000..5fd42398e146
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/beforeBrace.java
@@ -0,0 +1,5 @@
+class A {
+ void foo() {
+ }
+
+<caret>}
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/spacingInsert-after.java b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsert-after.java
new file mode 100644
index 000000000000..3284439c1b24
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsert-after.java
@@ -0,0 +1,3 @@
+class Foo {
+ int <caret>i;
+}
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/spacingInsert.java b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsert.java
new file mode 100644
index 000000000000..25766081e3c2
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsert.java
@@ -0,0 +1,4 @@
+class Foo {
+ int
+ <caret>i;
+}
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart-after.java b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart-after.java
new file mode 100644
index 000000000000..3284439c1b24
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart-after.java
@@ -0,0 +1,3 @@
+class Foo {
+ int <caret>i;
+}
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart.java b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart.java
new file mode 100644
index 000000000000..29e2260c35b8
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart.java
@@ -0,0 +1,4 @@
+class Foo {
+ int
+<caret> i;
+}
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart2-after.java b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart2-after.java
new file mode 100644
index 000000000000..3284439c1b24
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart2-after.java
@@ -0,0 +1,3 @@
+class Foo {
+ int <caret>i;
+}
diff --git a/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart2.java b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart2.java
new file mode 100644
index 000000000000..6c1bbe85b269
--- /dev/null
+++ b/platform/lang-impl/testData/editor/indentingBackspace/spacingInsertAfterBackspaceAtLineStart2.java
@@ -0,0 +1,4 @@
+class Foo {
+ int
+<caret>i;
+}
diff --git a/platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerUncommittedDocumentTest.java b/platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerUncommittedDocumentTest.java
new file mode 100644
index 000000000000..f51179dfa5d8
--- /dev/null
+++ b/platform/lang-impl/testSources/com/intellij/codeInsight/editorActions/IndentingBackspaceHandlerUncommittedDocumentTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.editorActions;
+
+import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
+
+import java.io.IOException;
+
+public class IndentingBackspaceHandlerUncommittedDocumentTest extends LightPlatformCodeInsightTestCase {
+ public void testSequentialBackspaceInvocation() throws IOException {
+ configureFromFileText(getTestName(false) + ".java",
+ "class Foo {\n" +
+ "\n" +
+ "\n" +
+ "<caret>}");
+ backspace();
+ backspace();
+ checkResultByText("class Foo {\n" +
+ "<caret>}");
+ }
+
+ public void testMulticaretSequentialBackspaceInvocation() throws IOException {
+ configureFromFileText(getTestName(false) + ".java",
+ "class Foo {\n" +
+ " void m1() {\n" +
+ " \n" +
+ " <caret>}\n" +
+ " void m2() {\n" +
+ " \n" +
+ " <caret>}\n" +
+ "}");
+ backspace();
+ backspace();
+ checkResultByText("class Foo {\n" +
+ " void m1() {<caret>}\n" +
+ " void m2() {<caret>}\n" +
+ "}");
+ }
+} \ No newline at end of file
diff --git a/platform/lvcs-impl/src/com/intellij/history/core/Paths.java b/platform/lvcs-impl/src/com/intellij/history/core/Paths.java
index 440fd699ef7d..bd98591b4cb3 100644
--- a/platform/lvcs-impl/src/com/intellij/history/core/Paths.java
+++ b/platform/lvcs-impl/src/com/intellij/history/core/Paths.java
@@ -67,9 +67,18 @@ public class Paths {
}
public static Iterable<String> split(String path) {
- Iterable<String> result = StringUtil.tokenize(path, String.valueOf(DELIM));
- if (path.indexOf(DELIM) == 0) {
- result = ContainerUtil.concat(Collections.singleton(String.valueOf(DELIM)), result);
+ //must be consistent with LocalFileSystemBase.extractRootPath()
+ int prefixLen = 0;
+ if (path.startsWith("//")) {
+ prefixLen = path.indexOf(DELIM, 2);
+ if (prefixLen == -1) prefixLen = path.length();
+ }
+ else if (StringUtil.startsWithChar(path, DELIM)) {
+ prefixLen = 1;
+ }
+ Iterable<String> result = StringUtil.tokenize(path.substring(prefixLen), String.valueOf(DELIM));
+ if (prefixLen > 0) {
+ result = ContainerUtil.concat(Collections.singleton(path.substring(0, prefixLen)), result);
}
return result;
}
diff --git a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java
index 90308f5dbfda..cd1d1b0dba49 100644
--- a/platform/platform-api/src/com/intellij/ide/BrowserUtil.java
+++ b/platform/platform-api/src/com/intellij/ide/BrowserUtil.java
@@ -20,6 +20,7 @@ import com.intellij.execution.util.ExecUtil;
import com.intellij.ide.browsers.BrowserLauncher;
import com.intellij.ide.browsers.BrowserLauncherAppless;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -106,6 +107,10 @@ public class BrowserUtil {
getBrowserLauncher().browse(uri);
}
+ public static void browse(@NotNull String url, @Nullable Project project) {
+ getBrowserLauncher().browse(url, null, project);
+ }
+
@SuppressWarnings("UnusedDeclaration")
@NotNull
@Deprecated
@@ -145,6 +150,9 @@ public class BrowserUtil {
else if (SystemInfo.isMac) {
return "open";
}
+ else if (SystemInfo.isUnix) {
+ return "/usr/bin/firefox";
+ }
else {
return "";
}
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/BrowserFamily.java b/platform/platform-api/src/com/intellij/ide/browsers/BrowserFamily.java
index f6826b528427..f767ec90d49f 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/BrowserFamily.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/BrowserFamily.java
@@ -35,9 +35,9 @@ public enum BrowserFamily implements Iconable {
private final Icon myIcon;
BrowserFamily(@NotNull String name,
- @NotNull final String windowsPath,
- @Nullable final String unixPath,
- @Nullable final String macPath,
+ @NotNull String windowsPath,
+ @Nullable String unixPath,
+ @Nullable String macPath,
@NotNull Icon icon) {
myName = name;
myWindowsPath = windowsPath;
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java b/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
index 0c34152861d1..736dcd8afe22 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
@@ -74,10 +74,10 @@ public class BrowserLauncherAppless extends BrowserLauncher {
Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(action);
}
- public static boolean canStartDefaultBrowser() {
+ public static boolean canUseSystemDefaultBrowserPolicy() {
return isDesktopActionSupported(Desktop.Action.BROWSE) ||
SystemInfo.isMac || SystemInfo.isWindows ||
- SystemInfo.isUnix && SystemInfo.hasXdgOpen();
+ (SystemInfo.isUnix && SystemInfo.hasXdgOpen());
}
private static GeneralSettings getGeneralSettingsInstance() {
@@ -109,7 +109,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
@Override
public void open(@NotNull String url) {
- openOrBrowse(url, false);
+ openOrBrowse(url, false, null);
}
@Override
@@ -119,6 +119,10 @@ public class BrowserLauncherAppless extends BrowserLauncher {
@Override
public void browse(@NotNull URI uri) {
+ browse(uri, null);
+ }
+
+ public void browse(@NotNull URI uri, @Nullable Project project) {
LOG.debug("Launch browser: [" + uri + "]");
GeneralSettings settings = getGeneralSettingsInstance();
@@ -136,15 +140,19 @@ public class BrowserLauncherAppless extends BrowserLauncher {
List<String> command = getDefaultBrowserCommand();
if (command != null) {
- doLaunch(uri.toString(), command, null, null, ArrayUtil.EMPTY_STRING_ARRAY, null);
+ doLaunch(uri.toString(), command, null, project, ArrayUtil.EMPTY_STRING_ARRAY, null);
return;
}
}
- browseUsingPath(uri.toString(), settings.getBrowserPath(), null, null, ArrayUtil.EMPTY_STRING_ARRAY);
+ browseUsingNotSystemDefaultBrowserPolicy(uri, settings, project);
}
- private void openOrBrowse(@NotNull String url, boolean browse) {
+ protected void browseUsingNotSystemDefaultBrowserPolicy(@NotNull URI uri, @NotNull GeneralSettings settings, @Nullable Project project) {
+ browseUsingPath(uri.toString(), settings.getBrowserPath(), null, project, ArrayUtil.EMPTY_STRING_ARRAY);
+ }
+
+ private void openOrBrowse(@NotNull String url, boolean browse, @Nullable Project project) {
url = url.trim();
if (url.startsWith("jar:")) {
@@ -181,7 +189,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
}
if (uri == null) {
- doShowError(IdeBundle.message("error.malformed.url", url), null, null, null, null);
+ doShowError(IdeBundle.message("error.malformed.url", url), null, project, null, null);
}
else {
browse(uri);
@@ -380,7 +388,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
@Override
public void browse(@NotNull String url, @Nullable WebBrowser browser, @Nullable Project project) {
if (browser == null) {
- openOrBrowse(url, true);
+ openOrBrowse(url, true, project);
}
else {
for (UrlOpener urlOpener : UrlOpener.EP_NAME.getExtensions()) {
@@ -436,8 +444,8 @@ public class BrowserLauncherAppless extends BrowserLauncher {
private boolean doLaunch(@Nullable String url,
@NotNull List<String> command,
- @Nullable final WebBrowser browser,
- @Nullable final Project project,
+ @Nullable WebBrowser browser,
+ @Nullable Project project,
@NotNull String[] additionalParameters,
@Nullable Runnable launchTask) {
GeneralCommandLine commandLine = new GeneralCommandLine(command);
@@ -454,7 +462,13 @@ public class BrowserLauncherAppless extends BrowserLauncher {
commandLine.addParameter(url);
}
- addArgs(commandLine, browser == null ? null : browser.getSpecificSettings(), additionalParameters);
+ final BrowserSpecificSettings browserSpecificSettings = browser == null ? null : browser.getSpecificSettings();
+ if (browserSpecificSettings != null) {
+ commandLine.getEnvironment().putAll(browserSpecificSettings.getEnvironmentVariables());
+ }
+
+ addArgs(commandLine, browserSpecificSettings, additionalParameters);
+
try {
Process process = commandLine.createProcess();
checkCreatedProcess(browser, project, commandLine, process, launchTask);
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/BrowserSpecificSettings.java b/platform/platform-api/src/com/intellij/ide/browsers/BrowserSpecificSettings.java
index 826ca80cd21a..b7fd90ef3ade 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/BrowserSpecificSettings.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/BrowserSpecificSettings.java
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
public abstract class BrowserSpecificSettings implements Cloneable {
@NotNull
@@ -30,6 +31,11 @@ public abstract class BrowserSpecificSettings implements Cloneable {
return Collections.emptyList();
}
+ @NotNull
+ public Map<String, String> getEnvironmentVariables() {
+ return Collections.emptyMap();
+ }
+
@Override
public BrowserSpecificSettings clone() {
try {
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/chrome/ChromeSettings.java b/platform/platform-api/src/com/intellij/ide/browsers/chrome/ChromeSettings.java
index b6ca3e7ac44f..555097bb546c 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/chrome/ChromeSettings.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/chrome/ChromeSettings.java
@@ -21,7 +21,9 @@ import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.execution.ParametersListUtil;
+import com.intellij.util.xmlb.annotations.MapAnnotation;
import com.intellij.util.xmlb.annotations.Tag;
+import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,6 +35,7 @@ public final class ChromeSettings extends BrowserSpecificSettings {
private @Nullable String myCommandLineOptions;
private @Nullable String myUserDataDirectoryPath;
private boolean myUseCustomProfile;
+ private @NotNull THashMap<String, String> myEnvironmentVariables = new THashMap<String, String>();
public ChromeSettings() {
}
@@ -85,6 +88,18 @@ public final class ChromeSettings extends BrowserSpecificSettings {
return cliOptions;
}
+ @Override
+ @NotNull
+ @Tag("environment-variables")
+ @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false)
+ public THashMap<String, String> getEnvironmentVariables() {
+ return myEnvironmentVariables;
+ }
+
+ public void setEnvironmentVariables(@NotNull final THashMap<String, String> environmentVariables) {
+ myEnvironmentVariables = environmentVariables;
+ }
+
@NotNull
@Override
public ChromeSettingsConfigurable createConfigurable() {
@@ -92,6 +107,13 @@ public final class ChromeSettings extends BrowserSpecificSettings {
}
@Override
+ public ChromeSettings clone() {
+ ChromeSettings clone = (ChromeSettings)super.clone();
+ clone.myEnvironmentVariables = myEnvironmentVariables.clone();
+ return clone;
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o) {
return true;
@@ -103,6 +125,7 @@ public final class ChromeSettings extends BrowserSpecificSettings {
ChromeSettings settings = (ChromeSettings)o;
return myUseCustomProfile == settings.myUseCustomProfile &&
Comparing.equal(myCommandLineOptions, settings.myCommandLineOptions) &&
- (!myUseCustomProfile || Comparing.equal(myUserDataDirectoryPath, settings.myUserDataDirectoryPath));
+ (!myUseCustomProfile || Comparing.equal(myUserDataDirectoryPath, settings.myUserDataDirectoryPath)) &&
+ myEnvironmentVariables.equals(settings.myEnvironmentVariables);
}
}
diff --git a/platform/platform-api/src/com/intellij/ide/browsers/firefox/FirefoxSettingsConfigurable.java b/platform/platform-api/src/com/intellij/ide/browsers/firefox/FirefoxSettingsConfigurable.java
index ef95f7cb872e..c28b7e495b41 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/firefox/FirefoxSettingsConfigurable.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/firefox/FirefoxSettingsConfigurable.java
@@ -26,7 +26,6 @@ import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.DocumentAdapter;
-import com.intellij.util.ObjectUtils;
import com.intellij.util.PathUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.Nullable;
@@ -48,7 +47,7 @@ public class FirefoxSettingsConfigurable implements Configurable {
private final FirefoxSettings mySettings;
private String myLastProfilesIniPath;
private String myDefaultProfilesIniPath;
- private String myDefaultProfile;
+ private String defaultProfile;
public FirefoxSettingsConfigurable(FirefoxSettings settings) {
mySettings = settings;
@@ -89,11 +88,8 @@ public class FirefoxSettingsConfigurable implements Configurable {
@Nullable
private String getConfiguredProfileName() {
- final String selected = (String)myProfileCombobox.getSelectedItem();
- if (Comparing.equal(myDefaultProfile, selected)) {
- return null;
- }
- return selected;
+ String selected = (String)myProfileCombobox.getSelectedItem();
+ return Comparing.equal(defaultProfile, selected) ? null : selected;
}
@Override
@@ -110,7 +106,9 @@ public class FirefoxSettingsConfigurable implements Configurable {
String path = mySettings.getProfilesIniPath();
myProfilesIniPathField.setText(path != null ? FileUtilRt.toSystemDependentName(path) : myDefaultProfilesIniPath);
updateProfilesList();
- myProfileCombobox.setSelectedItem(ObjectUtils.notNull(mySettings.getProfile(), myDefaultProfile));
+
+ String profile = mySettings.getProfile();
+ myProfileCombobox.setSelectedItem(profile == null ? defaultProfile : profile);
}
private void updateProfilesList() {
@@ -122,7 +120,7 @@ public class FirefoxSettingsConfigurable implements Configurable {
myProfileCombobox.removeAllItems();
final List<FirefoxProfile> profiles = FirefoxUtil.computeProfiles(new File(profilesIniPath));
final FirefoxProfile defaultProfile = FirefoxUtil.getDefaultProfile(profiles);
- myDefaultProfile = defaultProfile != null ? defaultProfile.getName() : null;
+ this.defaultProfile = defaultProfile != null ? defaultProfile.getName() : null;
for (FirefoxProfile profile : profiles) {
//noinspection unchecked
myProfileCombobox.addItem(profile.getName());
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
index 1d4fea4c01de..049bde52f582 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java
@@ -36,6 +36,8 @@ public interface IdeActions {
@NonNls String ACTION_EDITOR_SELECT_WORD_AT_CARET = "EditorSelectWord";
@NonNls String ACTION_EDITOR_UNSELECT_WORD_AT_CARET = "EditorUnSelectWord";
@NonNls String ACTION_EDITOR_BACKSPACE = "EditorBackSpace";
+ @NonNls String ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION = "EditorLeftWithSelection";
+ @NonNls String ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION = "EditorRightWithSelection";
@NonNls String ACTION_EDITOR_MOVE_CARET_UP = "EditorUp";
@NonNls String ACTION_EDITOR_MOVE_CARET_LEFT = "EditorLeft";
@NonNls String ACTION_EDITOR_MOVE_CARET_DOWN = "EditorDown";
@@ -269,7 +271,7 @@ public interface IdeActions {
String ACTION_UNDO = "$Undo";
String ACTION_REDO = "$Redo";
String GROUP_REFACTOR = "RefactoringMenu";
- String SELECTED_CHANGES_ROLLBACK = "RollbackLineStatusChanges";
+ String SELECTED_CHANGES_ROLLBACK = "Vcs.RollbackChangedLines";
String CHANGES_VIEW_ROLLBACK = "ChangesView.Rollback";
String CONSOLE_CLEAR_ALL = "ConsoleView.ClearAll";
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
index 92a1d9c8b42c..7398bf706c78 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ComboBoxAction.java
@@ -110,10 +110,10 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
private boolean myMouseInside = false;
private JBPopup myPopup;
private boolean myForceTransparent = false;
- private Boolean myForceEnabled = null;
public ComboBoxButton(Presentation presentation) {
myPresentation = presentation;
+ setEnabled(myPresentation.isEnabled());
setModel(new MyButtonModel());
setHorizontalAlignment(LEFT);
setFocusable(false);
@@ -207,12 +207,6 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
}
}
- @Override
- public void setEnabled(final boolean enabled) {
- super.setEnabled(enabled);
- myForceEnabled = enabled;
- }
-
public void setForceTransparent(boolean transparent) {
myForceTransparent = transparent;
}
@@ -282,7 +276,6 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
private void initButton() {
setIcon(myPresentation.getIcon());
- setEnabled(myPresentation.isEnabled());
setText(myPresentation.getText());
updateTooltipText(myPresentation.getDescription());
updateButtonSize();
@@ -383,7 +376,7 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
final Dimension size = getSize();
final boolean isEmpty = getIcon() == null && StringUtil.isEmpty(getText());
- final Color textColor = (myForceEnabled == null ? myPresentation.isEnabled() : myForceEnabled)
+ final Color textColor = isEnabled()
? UIManager.getColor("Panel.foreground")
: UIUtil.getInactiveTextColor();
if (myForceTransparent) {
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/DiffRequestFactory.java b/platform/platform-api/src/com/intellij/openapi/diff/DiffRequestFactory.java
index 78f07a04b4a9..e2c9175ac915 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/DiffRequestFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/diff/DiffRequestFactory.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.diff;
import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -59,4 +60,12 @@ public abstract class DiffRequestFactory {
Project project,
@Nullable ActionButtonPresentation okButtonPresentation,
@Nullable ActionButtonPresentation cancelButtonPresentation);
+
+ public abstract MergeRequest create3WayDiffRequest(String leftText,
+ String rightText,
+ String originalContent,
+ @Nullable FileType type,
+ Project project,
+ @Nullable ActionButtonPresentation okButtonPresentation,
+ @Nullable ActionButtonPresentation cancelButtonPresentation);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java b/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java
index 26537316b4e9..d630bad790df 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java
+++ b/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java
@@ -41,18 +41,28 @@ public class FragmentContent extends DiffContent {
private final FileType myType;
private final MyDocumentsSynchronizer mySynchonizer;
public static final Key<Document> ORIGINAL_DOCUMENT = new Key<Document>("ORIGINAL_DOCUMENT");
+ private final boolean myForceReadOnly;
public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, VirtualFile file) {
- this(original, range, project, file != null ? DiffContentUtil.getContentType(file) : null);
+ this(original, range, project, file, false);
+ }
+
+ public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, VirtualFile file, boolean forceReadOnly) {
+ this(original, range, project, file != null ? DiffContentUtil.getContentType(file) : null, forceReadOnly);
}
public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, FileType fileType) {
+ this(original, range, project, fileType, false);
+ }
+
+ public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, FileType fileType, boolean forceReadOnly) {
RangeMarker rangeMarker = original.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true);
rangeMarker.setGreedyToLeft(true);
rangeMarker.setGreedyToRight(true);
mySynchonizer = new MyDocumentsSynchronizer(project, rangeMarker);
myOriginal = original;
myType = fileType;
+ myForceReadOnly = forceReadOnly;
}
public FragmentContent(DiffContent original, TextRange range, Project project) {
@@ -152,7 +162,7 @@ public class FragmentContent extends DiffContent {
String textInRange =
originalDocument.getCharsSequence().subSequence(myRangeMarker.getStartOffset(), myRangeMarker.getEndOffset()).toString();
final Document result = EditorFactory.getInstance().createDocument(textInRange);
- result.setReadOnly(!originalDocument.isWritable());
+ result.setReadOnly(myForceReadOnly || !originalDocument.isWritable());
result.putUserData(ORIGINAL_DOCUMENT, originalDocument);
return result;
}
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/MergeRequest.java b/platform/platform-api/src/com/intellij/openapi/diff/MergeRequest.java
index 29243f7b9be0..ce8d56044f96 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/MergeRequest.java
+++ b/platform/platform-api/src/com/intellij/openapi/diff/MergeRequest.java
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
* @see DiffRequestFactory#createMergeRequest
*/
public abstract class MergeRequest extends DiffRequest {
- protected MergeRequest(Project project) {
+ protected MergeRequest(@Nullable Project project) {
super(project);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorCopyPasteHelper.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorCopyPasteHelper.java
new file mode 100644
index 000000000000..f698d34efb50
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorCopyPasteHelper.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.editor;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.util.TextRange;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.datatransfer.Transferable;
+
+/**
+ * Support for data transfer between editor and clipboard.
+ */
+public abstract class EditorCopyPasteHelper {
+ public static EditorCopyPasteHelper getInstance() {
+ return ServiceManager.getService(EditorCopyPasteHelper.class);
+ }
+
+ /**
+ * Copies text selected in editor to clipboard.
+ */
+ public abstract void copySelectionToClipboard(@NotNull Editor editor);
+
+ /**
+ * Pastes from clipboard into editor at caret(s) position.
+ *
+ * @return ranges of text in the document, corresponding to pasted fragments, if paste succeeds, or <code>null</code> otherwise
+ */
+ @Nullable
+ public abstract TextRange[] pasteFromClipboard(@NotNull Editor editor);
+
+ /**
+ * Pastes given Transferable instance into editor at caret(s) position.
+ *
+ * @return ranges of text in the document, corresponding to pasted fragments, if paste succeeds, or <code>null</code> otherwise
+ */
+ @Nullable
+ public abstract TextRange[] pasteTransferable(@NotNull Editor editor, @NotNull Transferable content);
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
index ee5527967440..6ba31d7edb47 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/EditorModificationUtil.java
@@ -19,14 +19,19 @@ import com.intellij.codeStyle.CodeStyleFacade;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.MockDocumentEvent;
+import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.LineTokenizer;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.util.Producer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
import java.util.List;
public class EditorModificationUtil {
@@ -176,22 +181,100 @@ public class EditorModificationUtil {
}
/**
- * @deprecated Use {@link com.intellij.openapi.editor.CopyPasteSupport#pasteTransferable(Editor, com.intellij.util.Producer)} instead.
+ * @deprecated Use {@link com.intellij.openapi.editor.EditorCopyPasteHelper} methods instead.
* (to remove in IDEA 15)
*/
@Nullable
public static TextRange pasteTransferable(final Editor editor, @Nullable Producer<Transferable> producer) {
- return CopyPasteSupport.pasteTransferable(editor, producer);
+ EditorCopyPasteHelper helper = EditorCopyPasteHelper.getInstance();
+ if (producer == null) {
+ TextRange[] ranges = helper.pasteFromClipboard(editor);
+ return ranges != null && ranges.length == 1 ? ranges[0] : null;
+ }
+ Transferable transferable = producer.produce();
+ if (transferable == null) {
+ return null;
+ }
+ TextRange[] ranges = helper.pasteTransferable(editor, transferable);
+ return ranges != null && ranges.length == 1 ? ranges[0] : null;
}
- /**
- * @deprecated Use {@link com.intellij.openapi.editor.CopyPasteSupport#pasteTransferableAsBlock(Editor, com.intellij.util.Producer)} instead.
- * (to remove in IDEA 15)
- */
public static void pasteTransferableAsBlock(Editor editor, @Nullable Producer<Transferable> producer) {
- CopyPasteSupport.pasteTransferableAsBlock(editor, producer);
+ Transferable content = getTransferable(producer);
+ if (content == null) return;
+ String text = getStringContent(content);
+ if (text == null) return;
+
+ int caretLine = editor.getCaretModel().getLogicalPosition().line;
+ int originalCaretLine = caretLine;
+ int selectedLinesCount = 0;
+
+ final SelectionModel selectionModel = editor.getSelectionModel();
+ if (selectionModel.hasBlockSelection()) {
+ final LogicalPosition start = selectionModel.getBlockStart();
+ final LogicalPosition end = selectionModel.getBlockEnd();
+ assert start != null;
+ assert end != null;
+ LogicalPosition caret = new LogicalPosition(Math.min(start.line, end.line), Math.min(start.column, end.column));
+ selectedLinesCount = Math.abs(end.line - start.line);
+ caretLine = caret.line;
+
+ deleteSelectedText(editor);
+ editor.getCaretModel().moveToLogicalPosition(caret);
+ }
+
+ LogicalPosition caretToRestore = editor.getCaretModel().getLogicalPosition();
+
+ String[] lines = LineTokenizer.tokenize(text.toCharArray(), false);
+ if (lines.length > 1 || selectedLinesCount == 0) {
+ int longestLineLength = 0;
+ for (int i = 0; i < lines.length; i++) {
+ String line = lines[i];
+ longestLineLength = Math.max(longestLineLength, line.length());
+ editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
+ insertStringAtCaret(editor, line, false, true);
+ }
+ caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + longestLineLength);
+ }
+ else {
+ for (int i = 0; i <= selectedLinesCount; i++) {
+ editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
+ insertStringAtCaret(editor, text, false, true);
+ }
+ caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + text.length());
+ }
+
+ editor.getCaretModel().moveToLogicalPosition(caretToRestore);
+ zeroWidthBlockSelectionAtCaretColumn(editor, caretLine, caretLine + selectedLinesCount);
}
+ @Nullable
+ private static String getStringContent(@NotNull Transferable content) {
+ RawText raw = RawText.fromTransferable(content);
+ if (raw != null) return raw.rawText;
+
+ try {
+ return (String)content.getTransferData(DataFlavor.stringFlavor);
+ }
+ catch (UnsupportedFlavorException ignore) { }
+ catch (IOException ignore) { }
+
+ return null;
+ }
+
+ private static Transferable getTransferable(Producer<Transferable> producer) {
+ Transferable content = null;
+ if (producer != null) {
+ content = producer.produce();
+ }
+ else {
+ CopyPasteManager manager = CopyPasteManager.getInstance();
+ if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) {
+ content = manager.getContents();
+ }
+ }
+ return content;
+ }
/**
* Calculates difference in columns between current editor caret position and end of the logical line fragment displayed
* on a current visual line.
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
index 3780e3a79e0c..942a33aaace8 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
@@ -15,276 +15,19 @@
*/
package com.intellij.openapi.editor;
-import com.intellij.codeStyle.CodeStyleFacade;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.SmartList;
-import com.intellij.util.containers.WeakList;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-
-public class LazyRangeMarkerFactory {
- private final Project myProject;
- private static final Key<WeakList<LazyMarker>> LAZY_MARKERS_KEY = Key.create("LAZY_MARKERS_KEY");
+public abstract class LazyRangeMarkerFactory {
public static LazyRangeMarkerFactory getInstance(Project project) {
return ServiceManager.getService(project, LazyRangeMarkerFactory.class);
}
- public LazyRangeMarkerFactory(@NotNull Project project, @NotNull final FileDocumentManager fileDocumentManager) {
- myProject = project;
-
- EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentAdapter() {
- @Override
- public void beforeDocumentChange(DocumentEvent e) {
- transformRangeMarkers(e);
- }
-
- @Override
- public void documentChanged(DocumentEvent e) {
- transformRangeMarkers(e);
- }
-
- private void transformRangeMarkers(@NotNull DocumentEvent e) {
- Document document = e.getDocument();
- VirtualFile file = fileDocumentManager.getFile(document);
- if (file == null) {
- return;
- }
-
- WeakList<LazyMarker> lazyMarkers = file.getUserData(LAZY_MARKERS_KEY);
- if (lazyMarkers == null) {
- return;
- }
-
- List<LazyMarker> markers = lazyMarkers.toStrongList();
- List<LazyMarker> markersToRemove = null;
- for (LazyMarker marker : markers) {
- if (file.equals(marker.getFile()) && marker.documentChanged(document) != null) {
- if (markersToRemove == null) {
- markersToRemove = new SmartList<LazyMarker>();
- }
- markersToRemove.add(marker);
- }
- }
- if (markersToRemove != null) {
- lazyMarkers.removeAll(markersToRemove);
- }
- }
- }, project);
- }
-
- private static void addToLazyMarkersList(@NotNull LazyMarker marker, @NotNull VirtualFile file) {
- WeakList<LazyMarker> markers = file.getUserData(LAZY_MARKERS_KEY);
-
- if (markers == null) {
- markers = file.putUserDataIfAbsent(LAZY_MARKERS_KEY, new WeakList<LazyMarker>());
- }
- markers.add(marker);
- }
-
@NotNull
- public RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int offset) {
- return ApplicationManager.getApplication().runReadAction(new Computable<RangeMarker>() {
- @Override
- public RangeMarker compute() {
- // even for already loaded document do not create range marker yet - wait until it really needed when e.g. user clicked to jump to OpenFileDescriptor
- final LazyMarker marker = new OffsetLazyMarker(file, offset);
- addToLazyMarkersList(marker, file);
- return marker;
- }
- });
- }
+ public abstract RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int offset);
@NotNull
- public RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int line, final int column, final boolean persistent) {
- return ApplicationManager.getApplication().runReadAction(new Computable<RangeMarker>() {
- @Override
- public RangeMarker compute() {
- final Document document = FileDocumentManager.getInstance().getCachedDocument(file);
- if (document != null) {
- final int offset = calculateOffset(myProject, file, document, line, column);
- return document.createRangeMarker(offset, offset, persistent);
- }
-
- final LazyMarker marker = new LineColumnLazyMarker(file, line, column);
- addToLazyMarkersList(marker, file);
- return marker;
- }
- });
- }
-
- private abstract static class LazyMarker extends UserDataHolderBase implements RangeMarker {
- private RangeMarker myDelegate;
- private final VirtualFile myFile;
- protected final int myInitialOffset;
-
- private LazyMarker(@NotNull VirtualFile file, int offset) {
- myFile = file;
- myInitialOffset = offset;
- }
-
- @NotNull
- public VirtualFile getFile() {
- return myFile;
- }
-
- @Nullable
- protected final RangeMarker getOrCreateDelegate() {
- if (myDelegate == null) {
- Document document = FileDocumentManager.getInstance().getDocument(myFile);
- if (document == null) {
- return null;
- }
- myDelegate = createDelegate(myFile, document);
- }
- return myDelegate;
- }
-
- @Nullable
- protected final RangeMarker documentChanged(@NotNull Document document) {
- if (myDelegate == null) {
- myDelegate = createDelegate(myFile, document);
- }
- return myDelegate;
- }
-
- @Nullable
- protected abstract RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull Document document);
-
- @Override
- @NotNull
- public Document getDocument() {
- RangeMarker delegate = getOrCreateDelegate();
- if (delegate == null) {
- //noinspection ConstantConditions
- return FileDocumentManager.getInstance().getDocument(myFile);
- }
- return delegate.getDocument();
- }
-
- @Override
- public int getStartOffset() {
- return myDelegate == null ? myInitialOffset : myDelegate.getStartOffset();
- }
-
-
- @Override
- public int getEndOffset() {
- return myDelegate == null ? myInitialOffset : myDelegate.getEndOffset();
- }
-
- @Override
- public boolean isValid() {
- RangeMarker delegate = getOrCreateDelegate();
- return delegate != null && delegate.isValid();
- }
-
- @Override
- public void setGreedyToLeft(boolean greedy) {
- getOrCreateDelegate().setGreedyToLeft(greedy);
- }
-
- @Override
- public void setGreedyToRight(boolean greedy) {
- getOrCreateDelegate().setGreedyToRight(greedy);
- }
-
- @Override
- public boolean isGreedyToRight() {
- return getOrCreateDelegate().isGreedyToRight();
- }
-
- @Override
- public boolean isGreedyToLeft() {
- return getOrCreateDelegate().isGreedyToLeft();
- }
-
- @Override
- public void dispose() {
- RangeMarker delegate = getOrCreateDelegate();
- if (delegate != null) {
- delegate.dispose();
- }
- }
- }
-
- private static class OffsetLazyMarker extends LazyMarker {
- private OffsetLazyMarker(@NotNull VirtualFile file, int offset) {
- super(file, offset);
- }
-
- @Override
- @NotNull
- public RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull final Document document) {
- final int offset = Math.min(myInitialOffset, document.getTextLength());
- return document.createRangeMarker(offset, offset);
- }
- }
-
- private class LineColumnLazyMarker extends LazyMarker {
- private final int myLine;
- private final int myColumn;
-
- private LineColumnLazyMarker(@NotNull VirtualFile file, int line, int column) {
- super(file, -1);
- myLine = line;
- myColumn = column;
- }
-
- @Override
- @Nullable
- public RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull Document document) {
- if (document.getTextLength() == 0 && !(myLine == 0 && myColumn == 0)) {
- return null;
- }
-
- int offset = calculateOffset(myProject, file, document, myLine, myColumn);
- return document.createRangeMarker(offset, offset);
- }
-
- @Override
- public int getStartOffset() {
- getOrCreateDelegate();
- return super.getStartOffset();
- }
-
- @Override
- public int getEndOffset() {
- getOrCreateDelegate();
- return super.getEndOffset();
- }
- }
-
- private static int calculateOffset(@NotNull Project project, @NotNull VirtualFile file, @NotNull Document document, final int line, final int column) {
- int offset;
- if (line < document.getLineCount()) {
- final int lineStart = document.getLineStartOffset(line);
- final int lineEnd = document.getLineEndOffset(line);
- final CharSequence docText = document.getCharsSequence();
- final int tabSize = CodeStyleFacade.getInstance(project).getTabSize(file.getFileType());
-
- offset = lineStart;
- int col = 0;
- while (offset < lineEnd && col < column) {
- col += docText.charAt(offset) == '\t' ? tabSize : 1;
- offset++;
- }
- }
- else {
- offset = document.getTextLength();
- }
- return offset;
- }
-
+ public abstract RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int line, final int column, final boolean persistent);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/DialogAwareDataContext.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/DialogAwareDataContext.java
new file mode 100644
index 000000000000..c49645254ebd
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/DialogAwareDataContext.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.editor.actionSystem;
+
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.DataKey;
+import com.intellij.openapi.editor.Editor;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.intellij.openapi.actionSystem.CommonDataKeys.*;
+import static com.intellij.openapi.actionSystem.PlatformDataKeys.PROJECT_FILE_DIRECTORY;
+
+/**
+* @author Konstantin Bulenkov
+*/
+final class DialogAwareDataContext implements DataContext {
+ private static final DataKey[] keys = {PROJECT, PROJECT_FILE_DIRECTORY, EDITOR, VIRTUAL_FILE, PSI_FILE};
+ private final Map<String, Object> values = new HashMap<String, Object>();
+
+ DialogAwareDataContext(DataContext context) {
+ for (DataKey key : keys) {
+ values.put(key.getName(), key.getData(context));
+ }
+ }
+
+ @Override
+ public Object getData(@NonNls String dataId) {
+ if (values.keySet().contains(dataId)) {
+ return values.get(dataId);
+ }
+ final Editor editor = (Editor)values.get(EDITOR.getName());
+ if (editor != null) {
+ return DataManager.getInstance().getDataContext(editor.getContentComponent()).getData(dataId);
+ }
+ return null;
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java
index 217ff70c3fb5..945c52022984 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/actionSystem/EditorAction.java
@@ -26,6 +26,8 @@ import org.jetbrains.annotations.Nullable;
import java.awt.event.KeyEvent;
+import static com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT;
+
public abstract class EditorAction extends AnAction implements DumbAware {
private EditorActionHandler myHandler;
private boolean myHandlersLoaded;
@@ -126,14 +128,14 @@ public abstract class EditorAction extends AnAction implements DumbAware {
}
private static DataContext getProjectAwareDataContext(final Editor editor, @NotNull final DataContext original) {
- if (CommonDataKeys.PROJECT.getData(original) == editor.getProject()) {
- return original;
+ if (PROJECT.getData(original) == editor.getProject()) {
+ return new DialogAwareDataContext(original);
}
return new DataContext() {
@Override
public Object getData(String dataId) {
- if (CommonDataKeys.PROJECT.is(dataId)) {
+ if (PROJECT.is(dataId)) {
return editor.getProject();
}
return original.getData(dataId);
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java
index 9cd9ab29f4cd..db138237af81 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java
@@ -71,31 +71,17 @@ public class FragmentedEditorHighlighter implements EditorHighlighter {
if (range.getEndOffset() >= iterator.getStart()) {
int relativeStart = Math.max(iterator.getStart() - range.getStartOffset(), 0);
int relativeEnd = Math.min(iterator.getEnd() - range.getStartOffset(), range.getLength() + 1);
- boolean merged = false;
- if (myMergeByTextAttributes && !myPieces.isEmpty()) {
- Element element = myPieces.get(myPieces.size() - 1);
- if (element.getEnd() >= offset + relativeStart &&
- Comparing.equal(element.getAttributes(), iterator.getTextAttributes()) &&
- Comparing.equal(element.getElementType(), iterator.getTokenType())) {
- merged = true;
- myPieces.add(new Element(element.getStart(),
- offset + relativeEnd,
- iterator.getTokenType(),
- iterator.getTextAttributes()));
- }
- }
- if (!merged) {
- myPieces.add(new Element(offset + relativeStart,
- offset + relativeEnd,
- iterator.getTokenType(),
- iterator.getTextAttributes()));
- }
+
+ addElement(new Element(offset + relativeStart,
+ offset + relativeEnd,
+ iterator.getTokenType(),
+ iterator.getTextAttributes()));
}
if (range.getEndOffset() < iterator.getEnd()) {
offset += range.getLength() + 1 + myAdditionalOffset; // myAdditionalOffset because of extra line - for shoene separators
int lastEnd = myPieces.isEmpty() ? -1 : myPieces.get(myPieces.size() - 1).getEnd();
- myPieces.add(new Element(Math.max(offset - 1 - myAdditionalOffset, lastEnd), offset, null, TextAttributes.ERASE_MARKER));
+ addElement(new Element(Math.max(offset - 1 - myAdditionalOffset, lastEnd), offset, null, TextAttributes.ERASE_MARKER));
index++;
continue;
}
@@ -104,6 +90,26 @@ public class FragmentedEditorHighlighter implements EditorHighlighter {
}
}
+ private void addElement(@NotNull Element element) {
+ boolean merged = false;
+ if (myMergeByTextAttributes && !myPieces.isEmpty()) {
+ Element oldElement = myPieces.get(myPieces.size() - 1);
+ if (oldElement.getEnd() >= element.getStart() &&
+ Comparing.equal(oldElement.getAttributes(), element.getAttributes()) &&
+ Comparing.equal(oldElement.getElementType(), element.getElementType())) {
+ merged = true;
+ myPieces.remove(myPieces.size() - 1);
+ myPieces.add(new Element(oldElement.getStart(),
+ element.getEnd(),
+ element.getElementType(),
+ element.getAttributes()));
+ }
+ }
+ if (!merged) {
+ myPieces.add(element);
+ }
+ }
+
@NotNull
@Override
public HighlighterIterator createIterator(int startOffset) {
diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
index 1e43287a1d94..c958dbca878e 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
@@ -19,9 +19,11 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.UIBundle;
+import org.jetbrains.annotations.NotNull;
public class FileChooserDescriptorFactory {
- private FileChooserDescriptorFactory() { }
+ private FileChooserDescriptorFactory() {
+ }
public static FileChooserDescriptor createAllButJarContentsDescriptor() {
return new FileChooserDescriptor(true, true, true, true, false, true);
@@ -83,7 +85,18 @@ public class FileChooserDescriptorFactory {
}
public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType) {
- return new FileChooserDescriptor(true, false, false, false, false, false) {
+ return createSingleFileDescriptor(fileType, false);
+ }
+
+ /**
+ * Creates file descriptor with certain type and (possible) folders.
+ * @param fileType supported type
+ * @param supportDirectories support directories or not
+ * @return descriptor
+ */
+ @NotNull
+ public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType, final boolean supportDirectories) {
+ return new FileChooserDescriptor(true, supportDirectories, false, false, false, false) {
@Override
public boolean isFileVisible(final VirtualFile file, final boolean showHiddenFiles) {
return file.isDirectory() || file.getFileType() == fileType;
@@ -91,18 +104,22 @@ public class FileChooserDescriptorFactory {
@Override
public boolean isFileSelectable(final VirtualFile file) {
- return super.isFileSelectable(file) && file.getFileType() == fileType;
+ return super.isFileSelectable(file) && (file.getFileType() == fileType || ((file.isDirectory() && supportDirectories)));
}
};
}
- /** @deprecated use {@link #createSingleFileNoJarsDescriptor()} (to be removed in IDEA 15) */
+ /**
+ * @deprecated use {@link #createSingleFileNoJarsDescriptor()} (to be removed in IDEA 15)
+ */
@SuppressWarnings({"UnusedDeclaration", "deprecation"})
public static FileChooserDescriptorBuilder onlyFiles() {
return FileChooserDescriptorBuilder.onlyFiles();
}
- /** @deprecated use {@link #createSingleFileOrFolderDescriptor()} ()} (to be removed in IDEA 15) */
+ /**
+ * @deprecated use {@link #createSingleFileOrFolderDescriptor()} ()} (to be removed in IDEA 15)
+ */
@SuppressWarnings({"UnusedDeclaration", "deprecation"})
public static FileChooserDescriptorBuilder filesAndFolders() {
return FileChooserDescriptorBuilder.filesAndFolders();
diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java
index 366f69db9cc6..b9589574059d 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java
@@ -30,7 +30,7 @@ public abstract class FileEditorManager {
public static final Key<Boolean> USE_CURRENT_WINDOW = Key.create("OpenFile.searchForOpen");
- public static FileEditorManager getInstance(Project project) {
+ public static FileEditorManager getInstance(@NotNull Project project) {
return project.getComponent(FileEditorManager.class);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
index 9ec804def43d..fdf32b9adcba 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/OpenFileDescriptor.java
@@ -55,34 +55,31 @@ public class OpenFileDescriptor implements Navigatable {
private boolean myUseCurrentWindow = false;
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int offset) {
- this(project, file, -1, -1, offset, null, false);
+ this(project, file, -1, -1, offset, false);
}
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file, int logicalLine, int logicalColumn) {
- this(project, file, logicalLine, logicalColumn, -1, null, false);
+ this(project, file, logicalLine, logicalColumn, -1, false);
}
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file,
int logicalLine, int logicalColumn, boolean persistent) {
- this(project, file, logicalLine, logicalColumn, -1, null, persistent);
+ this(project, file, logicalLine, logicalColumn, -1, persistent);
}
public OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file) {
- this(project, file, -1, -1, -1, null, false);
+ this(project, file, -1, -1, -1, false);
}
private OpenFileDescriptor(@NotNull Project project, @NotNull VirtualFile file,
- int logicalLine, int logicalColumn, int offset, @Nullable RangeMarker rangeMarker, boolean persistent) {
+ int logicalLine, int logicalColumn, int offset, boolean persistent) {
myProject = project;
myFile = file;
myLogicalLine = logicalLine;
myLogicalColumn = logicalColumn;
myOffset = offset;
- if (rangeMarker != null) {
- myRangeMarker = rangeMarker;
- }
- else if (offset >= 0) {
+ if (offset >= 0) {
myRangeMarker = LazyRangeMarkerFactory.getInstance(project).createRangeMarker(file, offset);
}
else if (logicalLine >= 0 ){
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/Banner.java b/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
index 3f4a92aec5ff..8dbe02228bae 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
@@ -16,6 +16,8 @@
package com.intellij.openapi.ui;
import com.intellij.icons.AllIcons;
+import com.intellij.openapi.options.OptionsBundle;
+import com.intellij.openapi.project.Project;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.ui.components.panels.NonOpaquePanel;
@@ -35,7 +37,7 @@ import java.util.Set;
class Banner extends NonOpaquePanel implements PropertyChangeListener{
private int myBannerMinHeight;
private final JComponent myText = new MyText();
-
+ private final JLabel myProjectIcon = new JLabel(AllIcons.General.ProjectConfigurableBanner, SwingConstants.LEFT);
private final NonOpaquePanel myActionsPanel = new NonOpaquePanel(new FlowLayout(FlowLayout.RIGHT, 2, 2));
private final Map<Action, LinkLabel> myActions = new HashMap<Action, LinkLabel>();
@@ -45,7 +47,10 @@ class Banner extends NonOpaquePanel implements PropertyChangeListener{
setBorder(new EmptyBorder(2, 6, 2, 4));
- add(myText, BorderLayout.CENTER);
+ myProjectIcon.setVisible(false);
+ myProjectIcon.setBorder(new EmptyBorder(0, 12, 0, 4));
+ add(myText, BorderLayout.WEST);
+ add(myProjectIcon, BorderLayout.CENTER);
add(myActionsPanel, BorderLayout.EAST);
}
@@ -112,6 +117,17 @@ class Banner extends NonOpaquePanel implements PropertyChangeListener{
repaint();
}
+ public void forProject(Project project) {
+ if (project != null) {
+ myProjectIcon.setVisible(true);
+ myProjectIcon.setText(OptionsBundle.message(project.isDefault()
+ ? "configurable.default.project.tooltip"
+ : "configurable.current.project.tooltip"));
+ } else {
+ myProjectIcon.setVisible(false);
+ }
+ }
+
public void setText(@NotNull final String... text) {
myText.removeAll();
for (int i = 0; i < text.length; i++) {
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java b/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java
index 5d2ecafb1b7e..c02f27af5d4b 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/ComboBoxTableRenderer.java
@@ -46,6 +46,7 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
private WeakReference<ListPopup> myPopupRef;
private ChangeEvent myChangeEvent = null;
private T myValue;
+ private boolean myPaintArrow = true;
protected EventListenerList myListenerList = new EventListenerList();
@@ -80,6 +81,10 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
return null;
}
+ public void setPaintArrow(final boolean paintArrow) {
+ myPaintArrow = paintArrow;
+ }
+
protected Runnable onChosen(@NotNull final T value) {
stopCellEditing(value);
@@ -94,7 +99,7 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
protected void paintComponent(Graphics g) {
super.paintComponent(g);
- if (!StringUtil.isEmpty(getText())) {
+ if (!StringUtil.isEmpty(getText()) && myPaintArrow) {
final Rectangle r = getBounds();
final Insets i = getInsets();
final int x = r.width - i.right - AllIcons.General.ArrowDown.getIconWidth();
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
index 34aaa93d2741..463d950ae900 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
@@ -16,7 +16,7 @@
package com.intellij.openapi.ui;
-import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.project.Project;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.util.ArrayUtil;
@@ -45,15 +45,21 @@ public class DetailsComponent {
private final NonOpaquePanel myBanner;
private String[] myBannerText;
- private boolean myDetailsEnabled = !Registry.is("ide.new.project.settings");
+ private boolean myDetailsEnabled;
private String[] myPrefix;
private String[] myText;
private final Wrapper myContentGutter = new Wrapper();
- private boolean myPaintBorder = !Registry.is("ide.new.project.settings");
+ private boolean myPaintBorder;
public DetailsComponent() {
+ this(true, true);
+ }
+
+ public DetailsComponent(boolean detailsEnabled, boolean paintBorder) {
+ myDetailsEnabled = detailsEnabled;
+ myPaintBorder = paintBorder;
myComponent = new JPanel(new BorderLayout()) {
@Override
protected void paintComponent(final Graphics g) {
@@ -110,7 +116,7 @@ public class DetailsComponent {
myBanner = new NonOpaquePanel(new BorderLayout());
myBannerLabel = new Banner();
- if (!Registry.is("ide.new.project.settings")) {
+ if (myDetailsEnabled) {
myBanner.add(myBannerLabel, BorderLayout.CENTER);
}
@@ -174,6 +180,9 @@ public class DetailsComponent {
}
}
+ public void forProject(Project project) {
+ myBannerLabel.forProject(project);
+ }
public void setPrefix(@Nullable String... prefix) {
myPrefix = prefix;
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/FixedComboBoxEditor.java b/platform/platform-api/src/com/intellij/openapi/ui/FixedComboBoxEditor.java
index 25c52c75b077..6ef25dddb5bc 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/FixedComboBoxEditor.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/FixedComboBoxEditor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package com.intellij.openapi.ui;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.Gray;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.ui.MacUIUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
@@ -34,7 +35,6 @@ import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
@@ -118,17 +118,7 @@ public class FixedComboBoxEditor implements ComboBoxEditor {
final ComboBoxUI ui = comboBox.getUI();
ComboPopup popup = null;
if (ui instanceof BasicComboBoxUI) {
- try {
- final Field popupField = BasicComboBoxUI.class.getDeclaredField("popup");
- popupField.setAccessible(true);
- popup = (ComboPopup)popupField.get(ui);
- }
- catch (NoSuchFieldException e1) {
- popup = null;
- }
- catch (IllegalAccessException e1) {
- popup = null;
- }
+ popup = ReflectionUtil.getField(BasicComboBoxUI.class, ui, ComboPopup.class, "popup");
}
return popup;
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
index 816349ed1c37..6c13964d5789 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/MasterDetailsComponent.java
@@ -111,7 +111,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
protected MyNode myRoot = new MyRootNode();
protected Tree myTree = new Tree();
- private final DetailsComponent myDetails = new DetailsComponent();
+ private final DetailsComponent myDetails = new DetailsComponent(!Registry.is("ide.new.project.settings"), !Registry.is("ide.new.project.settings"));
protected JPanel myWholePanel;
public JPanel myNorthPanel = new JPanel(new BorderLayout());
@@ -131,12 +131,9 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
protected MasterDetailsComponent(MasterDetailsState state) {
myState = state;
- mySplitter = new JBSplitter(false, .2f);
+ mySplitter = Registry.is("ide.new.project.settings") ? new OnePixelSplitter(false, .2f) : new JBSplitter(false, .2f);
mySplitter.setSplitterProportionKey("ProjectStructure.SecondLevelElements");
mySplitter.setHonorComponentsMinimumSize(true);
- if (Registry.is("ide.new.project.settings")) {
- mySplitter.setOnePixelMode();
- }
installAutoScroll();
reInitWholePanelIfNeeded();
@@ -300,6 +297,7 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
@NotNull
public JComponent createComponent() {
+ myTree.updateUI();
reInitWholePanelIfNeeded();
updateSelectionFromTree();
@@ -962,7 +960,11 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
myPreselection != null ? myPreselection.getDefaultIndex() : 0, true);
final ListPopup listPopup = popupFactory.createListPopup(step);
listPopup.setHandleAutoSelectionBeforeShow(true);
- listPopup.showUnderneathOf(myNorthPanel);
+ if (e instanceof AnActionButton.AnActionEventWrapper) {
+ ((AnActionButton.AnActionEventWrapper)e).showPopup(listPopup);
+ } else {
+ listPopup.showUnderneathOf(myNorthPanel);
+ }
}
}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/NamedConfigurable.java b/platform/platform-api/src/com/intellij/openapi/ui/NamedConfigurable.java
index 12b84f8db465..e619473197e7 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/NamedConfigurable.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/NamedConfigurable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,10 +18,12 @@ package com.intellij.openapi.ui;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.DocumentAdapter;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import java.awt.*;
@@ -55,6 +57,11 @@ public abstract class NamedConfigurable<T> implements Configurable {
}
});
}
+ if (Registry.is("ide.new.project.settings")) {
+ myNamePanel.setBorder(new EmptyBorder(10, 10, 6, 10));
+ } else {
+ myNamePanel.setBorder(new EmptyBorder(0,0,0,0));
+ }
}
public boolean isNameEditable() {
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java b/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java
new file mode 100644
index 000000000000..2b0097005dc1
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/openapi/ui/OnePixelDivider.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.ui;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.Weighted;
+import com.intellij.openapi.wm.IdeGlassPane;
+import com.intellij.openapi.wm.IdeGlassPaneUtil;
+import com.intellij.ui.Gray;
+import com.intellij.ui.JBColor;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class OnePixelDivider extends Divider {
+ private boolean myVertical;
+ private Splitter mySplitter;
+ private boolean myResizeEnabled;
+ private boolean mySwitchOrientationEnabled;
+ protected Point myPoint;
+ private IdeGlassPane myGlassPane;
+ private final MouseAdapter myListener = new MyMouseAdapter();
+ private Disposable myDisposable;
+
+ public OnePixelDivider(boolean vertical, Splitter splitter) {
+ super(new GridBagLayout());
+ mySplitter = splitter;
+ myResizeEnabled = true;
+ mySwitchOrientationEnabled = false;
+ setFocusable(false);
+ enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
+ //setOpaque(false);
+ setOrientation(vertical);
+ setBackground(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128)));
+ }
+
+ @Override
+ public void addNotify() {
+ super.addNotify();
+ init();
+ }
+
+ @Override
+ public void removeNotify() {
+ super.removeNotify();
+ if (myDisposable != null && !Disposer.isDisposed(myDisposable)) {
+ Disposer.dispose(myDisposable);
+ }
+ }
+
+ private boolean dragging = false;
+ private class MyMouseAdapter extends MouseAdapter implements Weighted {
+ @Override
+ public void mousePressed(MouseEvent e) {
+ dragging = isInDragZone(e);
+ _processMouseEvent(e);
+ }
+
+ boolean isInDragZone(MouseEvent e) {
+ final MouseEvent event = getTargetEvent(e);
+ final Point p = event.getPoint();
+ final int r = Math.abs(isVertical() ? p.y : p.x);
+ return r < 6;
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ _processMouseEvent(e);
+ dragging = false;
+ }
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ final OnePixelDivider divider = OnePixelDivider.this;
+ if (isInDragZone(e)) {
+ myGlassPane.setCursor(divider.getCursor(), divider);
+ } else {
+ myGlassPane.setCursor(null, divider);
+ }
+ _processMouseMotionEvent(e);
+ }
+
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ _processMouseMotionEvent(e);
+ }
+ @Override
+ public double getWeight() {
+ return 1;
+ }
+ private void _processMouseMotionEvent(MouseEvent e) {
+ MouseEvent event = getTargetEvent(e);
+ if (event == null) {
+ myGlassPane.setCursor(null, myListener);
+ return;
+ }
+
+ processMouseMotionEvent(event);
+ if (event.isConsumed()) {
+ e.consume();
+ }
+ }
+
+ private void _processMouseEvent(MouseEvent e) {
+ MouseEvent event = getTargetEvent(e);
+ if (event == null) {
+ myGlassPane.setCursor(null, myListener);
+ return;
+ }
+
+ processMouseEvent(event);
+ if (event.isConsumed()) {
+ e.consume();
+ }
+ }
+ }
+
+ private MouseEvent getTargetEvent(MouseEvent e) {
+ return SwingUtilities.convertMouseEvent(e.getComponent(), e, this);
+ }
+
+ private void init() {
+ myGlassPane = IdeGlassPaneUtil.find(this);
+ myDisposable = Disposer.newDisposable();
+ myGlassPane.addMouseMotionPreprocessor(myListener, myDisposable);
+ myGlassPane.addMousePreprocessor(myListener, myDisposable);
+ }
+
+ public void setOrientation(boolean vertical) {
+ removeAll();
+ myVertical = vertical;
+ final int cursorType = isVertical() ? Cursor.N_RESIZE_CURSOR : Cursor.W_RESIZE_CURSOR;
+ setCursor(Cursor.getPredefinedCursor(cursorType));
+ }
+
+ @Override
+ protected void processMouseMotionEvent(MouseEvent e) {
+ super.processMouseMotionEvent(e);
+ if (!myResizeEnabled) return;
+ if (MouseEvent.MOUSE_DRAGGED == e.getID() && dragging) {
+ myPoint = SwingUtilities.convertPoint(this, e.getPoint(), mySplitter);
+ float proportion;
+ final float firstMinProportion = getMinProportion(mySplitter.getFirstComponent());
+ final float secondMinProportion = getMinProportion(mySplitter.getSecondComponent());
+ if (isVertical()) {
+ if (getHeight() > 0) {
+ proportion = Math.min(1.0f, Math
+ .max(.0f, Math.min(Math.max(firstMinProportion, (float)myPoint.y / (float)mySplitter.getHeight()), 1 - secondMinProportion)));
+ mySplitter.setProportion(proportion);
+ }
+ }
+ else {
+ if (getWidth() > 0) {
+ proportion = Math.min(1.0f, Math.max(.0f, Math.min(
+ Math.max(firstMinProportion, (float)myPoint.x / (float)mySplitter.getWidth()), 1 - secondMinProportion)));
+ mySplitter.setProportion(proportion);
+ }
+ }
+ }
+ }
+
+ private float getMinProportion(JComponent component) {
+ if (component != null &&
+ mySplitter.getFirstComponent() != null &&
+ mySplitter.getFirstComponent().isVisible() &&
+ mySplitter.getSecondComponent() != null &&
+ mySplitter.getSecondComponent().isVisible()) {
+ if (isVertical()) {
+ return (float)component.getMinimumSize().height / (float)(mySplitter.getHeight() - 1);
+ } else {
+ return (float)component.getMinimumSize().width / (float)(mySplitter.getWidth() - 1);
+ }
+ }
+
+ return 0.0f;
+ }
+
+ @Override
+ protected void processMouseEvent(MouseEvent e) {
+ super.processMouseEvent(e);
+ if (e.getID() == MouseEvent.MOUSE_CLICKED) {
+ if (mySwitchOrientationEnabled
+ && e.getClickCount() == 1
+ && SwingUtilities.isLeftMouseButton(e) && (SystemInfo.isMac ? e.isMetaDown() : e.isControlDown())) {
+ mySplitter.setOrientation(!mySplitter.getOrientation());
+ }
+ if (myResizeEnabled && e.getClickCount() == 2) {
+ mySplitter.setProportion(.5f);
+ }
+ }
+ }
+
+ public void setResizeEnabled(boolean resizeEnabled) {
+ myResizeEnabled = resizeEnabled;
+ if (!myResizeEnabled) {
+ setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+ else {
+ setCursor(isVertical() ?
+ Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR) :
+ Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
+ }
+ }
+
+ public void setSwitchOrientationEnabled(boolean switchOrientationEnabled) {
+ mySwitchOrientationEnabled = switchOrientationEnabled;
+ }
+
+
+ public boolean isVertical() {
+ return myVertical;
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java b/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java
index fc9eec268ece..6c40a04f5831 100644
--- a/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java
+++ b/platform/platform-api/src/com/intellij/openapi/wm/FocusCommand.java
@@ -43,7 +43,7 @@ public abstract class FocusCommand extends ActiveRunnable implements Expirable {
private boolean myInvalidatesPendingFurtherRequestors = true;
private Expirable myExpirable;
- public static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.FocusCommand");
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.FocusCommand");
public boolean isForced() {
return myForced;
diff --git a/platform/platform-api/src/com/intellij/ui/AnActionButton.java b/platform/platform-api/src/com/intellij/ui/AnActionButton.java
index 7c539b1bb2a4..d1c19df6e3ad 100644
--- a/platform/platform-api/src/com/intellij/ui/AnActionButton.java
+++ b/platform/platform-api/src/com/intellij/ui/AnActionButton.java
@@ -17,6 +17,7 @@ package com.intellij.ui;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.containers.SmartHashSet;
import com.intellij.util.ui.UIUtil;
@@ -187,7 +188,7 @@ public abstract class AnActionButton extends AnAction implements ShortcutProvide
@Override
public void actionPerformed(AnActionEvent e) {
- myAction.actionPerformed(e);
+ myAction.actionPerformed(new AnActionEventWrapper(e, this));
}
@Override
@@ -205,4 +206,20 @@ public abstract class AnActionButton extends AnAction implements ShortcutProvide
return myAction.isDumbAware();
}
}
+
+ public static class AnActionEventWrapper extends AnActionEvent {
+ private final AnActionButton myPeer;
+
+ private AnActionEventWrapper(AnActionEvent e, AnActionButton peer) {
+ super(e.getInputEvent(), e.getDataContext(), e.getPlace(), e.getPresentation(), e.getActionManager(), e.getModifiers());
+ myPeer = peer;
+ }
+
+ public void showPopup(JBPopup popup) {
+ popup.show(myPeer.getPreferredPopupPoint());
+ }
+
+
+
+ }
}
diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java
new file mode 100644
index 000000000000..186904a4a843
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeAdapter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class CheckboxTreeAdapter implements CheckboxTreeListener {
+ @Override
+ public void mouseDoubleClicked(@NotNull CheckedTreeNode node) {
+ }
+
+ @Override
+ public void nodeStateChanged(@NotNull CheckedTreeNode node) {
+ }
+
+ @Override
+ public void beforeNodeStateChanged(@NotNull CheckedTreeNode node) {
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
index d9755f342a3f..88f433f7c62a 100644
--- a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
+++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java
@@ -16,67 +16,49 @@
package com.intellij.ui;
import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.EventDispatcher;
import com.intellij.util.ui.UIUtil;
-import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.tree.*;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeCellRenderer;
+import javax.swing.tree.TreeNode;
import java.awt.*;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Enumeration;
public class CheckboxTreeBase extends Tree {
- private final CheckPolicy myCheckPolicy;
- private static final CheckPolicy DEFAULT_POLICY = new CheckPolicy(true, true, false, true);
+ private final CheckboxTreeHelper myHelper;
+ private final EventDispatcher<CheckboxTreeListener> myEventDispatcher;
public CheckboxTreeBase() {
this(new CheckboxTreeCellRendererBase(), null);
}
public CheckboxTreeBase(final CheckboxTreeCellRendererBase cellRenderer, CheckedTreeNode root) {
- this(cellRenderer, root, DEFAULT_POLICY);
+ this(cellRenderer, root, CheckboxTreeHelper.DEFAULT_POLICY);
}
public CheckboxTreeBase(CheckboxTreeCellRendererBase cellRenderer, @Nullable CheckedTreeNode root, CheckPolicy checkPolicy) {
- myCheckPolicy = checkPolicy;
-
- setRootVisible(false);
- setShowsRootHandles(true);
- setLineStyleAngled();
- TreeUtil.installActions(this);
-
- installRenderer(cellRenderer);
-
- addKeyListener(new KeyAdapter() {
- public void keyPressed(KeyEvent e) {
- if (isToggleEvent(e)) {
- TreePath treePath = getLeadSelectionPath();
- if (treePath == null) return;
- final Object o = treePath.getLastPathComponent();
- if (!(o instanceof CheckedTreeNode)) return;
- CheckedTreeNode firstNode = (CheckedTreeNode)o;
- boolean checked = toggleNode(firstNode);
-
- TreePath[] selectionPaths = getSelectionPaths();
- for (int i = 0; selectionPaths != null && i < selectionPaths.length; i++) {
- final TreePath selectionPath = selectionPaths[i];
- final Object o1 = selectionPath.getLastPathComponent();
- if (!(o1 instanceof CheckedTreeNode)) continue;
- CheckedTreeNode node = (CheckedTreeNode)o1;
- checkNode(node, checked);
- ((DefaultTreeModel)getModel()).nodeChanged(node);
- }
-
- e.consume();
- }
+ myEventDispatcher = EventDispatcher.create(CheckboxTreeListener.class);
+ myEventDispatcher.addListener(new CheckboxTreeListener() {
+ @Override
+ public void mouseDoubleClicked(@NotNull CheckedTreeNode node) {
+ onDoubleClick(node);
+ }
+
+ @Override
+ public void nodeStateChanged(@NotNull CheckedTreeNode node) {
+ CheckboxTreeBase.this.onNodeStateChanged(node);
+ }
+
+ @Override
+ public void beforeNodeStateChanged(@NotNull CheckedTreeNode node) {
+ CheckboxTreeBase.this.nodeStateWillChange(node);
}
});
+ myHelper = new CheckboxTreeHelper(checkPolicy, myEventDispatcher);
+ myHelper.initTree(this, this, cellRenderer);
setSelectionRow(0);
if (root != null) {
@@ -84,55 +66,37 @@ public class CheckboxTreeBase extends Tree {
}
}
+ @Deprecated
public void installRenderer(final CheckboxTreeCellRendererBase cellRenderer) {
setCellRenderer(cellRenderer);
- new ClickListener() {
- @Override
- public boolean onClick(@NotNull MouseEvent e, int clickCount) {
- int row = getRowForLocation(e.getX(), e.getY());
- if (row < 0) return false;
- final Object o = getPathForRow(row).getLastPathComponent();
- if (!(o instanceof CheckedTreeNode)) return false;
- Rectangle rowBounds = getRowBounds(row);
- cellRenderer.setBounds(rowBounds);
- Rectangle checkBounds = cellRenderer.myCheckbox.getBounds();
- checkBounds.setLocation(rowBounds.getLocation());
-
- if (checkBounds.height == 0) checkBounds.height = checkBounds.width = rowBounds.height;
-
- final CheckedTreeNode node = (CheckedTreeNode)o;
- if (checkBounds.contains(e.getPoint())) {
- if (node.isEnabled()) {
- toggleNode(node);
- setSelectionRow(row);
- return true;
- }
- }
- else if (clickCount > 1) {
- onDoubleClick(node);
- return true;
- }
- return false;
- }
- }.installOn(this);
}
- protected void onDoubleClick(final CheckedTreeNode node) {
+ /**
+ * @deprecated use {@link #setNodeState} to change node state or subscribe to {@link #addCheckboxTreeListener} to get notifications about state changes
+ */
+ @Deprecated
+ protected boolean toggleNode(CheckedTreeNode node) {
+ setNodeState(node, !node.isChecked());
+ return node.isChecked();
}
- protected boolean isToggleEvent(KeyEvent e) {
- return e.getKeyCode() == KeyEvent.VK_SPACE;
+ /**
+ * @deprecated use {@link #setNodeState} to change node state or subscribe to {@link #addCheckboxTreeListener} to get notifications about state changes
+ */
+ @Deprecated
+ protected void checkNode(CheckedTreeNode node, boolean checked) {
+ setNodeState(node, checked);
}
- protected boolean toggleNode(CheckedTreeNode node) {
- boolean checked = !node.isChecked();
- checkNode(node, checked);
+ public void setNodeState(@NotNull CheckedTreeNode node, boolean checked) {
+ myHelper.setNodeState(this, node, checked);
+ }
- // notify model listeners about model change
- final TreeModel model = getModel();
- model.valueForPathChanged(new TreePath(node.getPath()), node.getUserObject());
+ public void addCheckboxTreeListener(@NotNull CheckboxTreeListener listener) {
+ myEventDispatcher.addListener(listener);
+ }
- return checked;
+ protected void onDoubleClick(final CheckedTreeNode node) {
}
/**
@@ -144,38 +108,8 @@ public class CheckboxTreeBase extends Tree {
* @param <T> the type of the node
* @return an array of collected nodes
*/
- @SuppressWarnings("unchecked")
public <T> T[] getCheckedNodes(final Class<T> nodeType, @Nullable final NodeFilter<T> filter) {
- final ArrayList<T> nodes = new ArrayList<T>();
- final Object root = getModel().getRoot();
- if (!(root instanceof CheckedTreeNode)) {
- throw new IllegalStateException(
- "The root must be instance of the " + CheckedTreeNode.class.getName() + ": " + root.getClass().getName());
- }
- new Object() {
- @SuppressWarnings("unchecked")
- public void collect(CheckedTreeNode node) {
- if (node.isLeaf()) {
- Object userObject = node.getUserObject();
- if (node.isChecked() && userObject != null && nodeType.isAssignableFrom(userObject.getClass())) {
- final T value = (T)userObject;
- if (filter != null && !filter.accept(value)) return;
- nodes.add(value);
- }
- }
- else {
- for (int i = 0; i < node.getChildCount(); i++) {
- final TreeNode child = node.getChildAt(i);
- if (child instanceof CheckedTreeNode) {
- collect((CheckedTreeNode)child);
- }
- }
- }
- }
- }.collect((CheckedTreeNode)root);
- T[] result = (T[])Array.newInstance(nodeType, nodes.size());
- nodes.toArray(result);
- return result;
+ return CheckboxTreeHelper.getCheckedNodes(nodeType, filter, getModel());
}
@@ -184,118 +118,14 @@ public class CheckboxTreeBase extends Tree {
return -1;
}
- protected void checkNode(CheckedTreeNode node, boolean checked) {
- adjustParentsAndChildren(node, checked);
- repaint();
- }
-
protected void onNodeStateChanged(CheckedTreeNode node) {
-
}
protected void nodeStateWillChange(CheckedTreeNode node) {
-
- }
-
- protected void adjustParentsAndChildren(final CheckedTreeNode node, final boolean checked) {
- changeNodeState(node, checked);
- if (!checked) {
- if (myCheckPolicy.uncheckParentWithUncheckedChild) {
- TreeNode parent = node.getParent();
- while (parent != null) {
- if (parent instanceof CheckedTreeNode) {
- changeNodeState((CheckedTreeNode)parent, false);
- }
- parent = parent.getParent();
- }
- }
- if (myCheckPolicy.uncheckChildrenWithUncheckedParent) {
- uncheckChildren(node);
- }
-
- }
- else {
- if (myCheckPolicy.checkChildrenWithCheckedParent) {
- checkChildren(node);
- }
-
- if (myCheckPolicy.checkParentWithCheckedChild) {
- TreeNode parent = node.getParent();
- while (parent != null) {
- if (parent instanceof CheckedTreeNode) {
- changeNodeState((CheckedTreeNode)parent, true);
- }
- parent = parent.getParent();
- }
- }
-
- }
- repaint();
- }
-
- private void changeNodeState(final CheckedTreeNode node, final boolean checked) {
- if (node.isChecked() != checked) {
- nodeStateWillChange(node);
- node.setChecked(checked);
- onNodeStateChanged(node);
- }
- }
-
- private void uncheckChildren(final CheckedTreeNode node) {
- final Enumeration children = node.children();
- while (children.hasMoreElements()) {
- final Object o = children.nextElement();
- if (!(o instanceof CheckedTreeNode)) continue;
- CheckedTreeNode child = (CheckedTreeNode)o;
- changeNodeState(child, false);
- uncheckChildren(child);
- }
- }
-
- private void checkChildren(final CheckedTreeNode node) {
- final Enumeration children = node.children();
- while (children.hasMoreElements()) {
- final Object o = children.nextElement();
- if (!(o instanceof CheckedTreeNode)) continue;
- CheckedTreeNode child = (CheckedTreeNode)o;
- changeNodeState(child, true);
- checkChildren(child);
- }
}
+ @Deprecated
protected void adjustParents(final CheckedTreeNode node, final boolean checked) {
- TreeNode parentNode = node.getParent();
- if (!(parentNode instanceof CheckedTreeNode)) return;
- CheckedTreeNode parent = (CheckedTreeNode)parentNode;
-
- if (!checked && isAllChildrenUnchecked(parent)) {
- changeNodeState(parent, false);
- adjustParents(parent, false);
- }
- else if (checked && isAllChildrenChecked(parent)) {
- changeNodeState(parent, true);
- adjustParents(parent, true);
- }
- }
-
- private static boolean isAllChildrenUnchecked(final CheckedTreeNode node) {
- for (int i = 0; i < node.getChildCount(); i++) {
- final TreeNode o = node.getChildAt(i);
- if ((o instanceof CheckedTreeNode) && ((CheckedTreeNode)o).isChecked()) {
- return false;
- }
- }
- return true;
- }
-
- private static boolean isAllChildrenChecked(final CheckedTreeNode node) {
- for (int i = 0; i < node.getChildCount(); i++) {
- final TreeNode o = node.getChildAt(i);
- if ((o instanceof CheckedTreeNode) && !((CheckedTreeNode)o).isChecked()) {
- return false;
- }
- }
- return true;
}
public static class CheckboxTreeCellRendererBase extends JPanel implements TreeCellRenderer {
@@ -395,8 +225,8 @@ public class CheckboxTreeBase extends Tree {
}
/**
- * @deprecated
* @see CheckboxTreeCellRendererBase#customizeRenderer(javax.swing.JTree, Object, boolean, boolean, boolean, int, boolean)
+ * @deprecated
*/
@Deprecated
public void customizeCellRenderer(JTree tree,
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/CheckboxTreeTable.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeHelper.java
index dd72da957fa2..3048d131caa7 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/CheckboxTreeTable.java
+++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,19 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.openapi.roots.libraries.ui.impl;
-
-import com.intellij.ui.CheckboxTree;
-import com.intellij.ui.CheckedTreeNode;
-import com.intellij.ui.ClickListener;
-import com.intellij.ui.dualView.TreeTableView;
-import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
-import com.intellij.ui.treeStructure.treetable.TreeTableTree;
-import com.intellij.util.ui.ColumnInfo;
+package com.intellij.ui;
+
+import com.intellij.ui.speedSearch.SpeedSearchSupply;
+import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.EventDispatcher;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import javax.swing.tree.DefaultTreeModel;
+import javax.swing.*;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
@@ -40,122 +37,82 @@ import java.util.Enumeration;
/**
* @author nik
*/
-public class CheckboxTreeTable extends TreeTableView {
- public CheckboxTreeTable(CheckedTreeNode root, CheckboxTree.CheckboxTreeCellRenderer renderer, final ColumnInfo[] columns) {
- super(new ListTreeTableModelOnColumns(root, columns));
- initTree(getTree(), renderer);
+class CheckboxTreeHelper {
+ static final CheckboxTreeBase.CheckPolicy DEFAULT_POLICY = new CheckboxTreeBase.CheckPolicy(true, true, false, true);
+ private final CheckboxTreeBase.CheckPolicy myCheckPolicy;
+ private final EventDispatcher<CheckboxTreeListener> myEventDispatcher;
+
+ CheckboxTreeHelper(CheckboxTreeBase.CheckPolicy checkPolicy, EventDispatcher<CheckboxTreeListener> dispatcher) {
+ myCheckPolicy = checkPolicy;
+ myEventDispatcher = dispatcher;
}
- //todo[nik] I hate to copy-paste but have to copy the code below from CheckboxTreeBase to support CheckboxTree inside TreeTable in IDEA 11.1.x branch
- //todo[nik] I solemnly swear to get rid of this code in IDEA 12 branch
- private void initTree(final TreeTableTree tree, final CheckboxTree.CheckboxTreeCellRenderer cellRenderer) {
+ public void initTree(@NotNull final Tree tree, JComponent mainComponent, CheckboxTreeBase.CheckboxTreeCellRendererBase cellRenderer) {
tree.setCellRenderer(cellRenderer);
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
tree.setLineStyleAngled();
TreeUtil.installActions(tree);
- new ClickListener() {
- @Override
- public boolean onClick(@NotNull MouseEvent e, int clickCount) {
- int row = tree.getRowForLocation(e.getX(), e.getY());
- if (row < 0) return false;
- final Object o = tree.getPathForRow(row).getLastPathComponent();
- if (!(o instanceof CheckedTreeNode)) return false;
- Rectangle rowBounds = tree.getRowBounds(row);
- cellRenderer.setBounds(rowBounds);
- Rectangle checkBounds = cellRenderer.myCheckbox.getBounds();
- checkBounds.setLocation(rowBounds.getLocation());
-
- if (checkBounds.height == 0) checkBounds.height = rowBounds.height;
-
- final CheckedTreeNode node = (CheckedTreeNode)o;
- if (checkBounds.contains(e.getPoint())) {
- if (node.isEnabled()) {
- toggleNode(node);
- tree.setSelectionRow(row);
- return true;
- }
- }
-
- return false;
- }
- }.installOn(this);
-
- addKeyListener(new KeyAdapter() {
- @Override
- public void keyPressed(KeyEvent e) {
- if (isToggleEvent(e)) {
- TreePath treePath = tree.getLeadSelectionPath();
- if (treePath == null) return;
- final Object o = treePath.getLastPathComponent();
- if (!(o instanceof CheckedTreeNode)) return;
- CheckedTreeNode firstNode = (CheckedTreeNode)o;
- boolean checked = toggleNode(firstNode);
-
- TreePath[] selectionPaths = tree.getSelectionPaths();
- for (int i = 0; selectionPaths != null && i < selectionPaths.length; i++) {
- final TreePath selectionPath = selectionPaths[i];
- final Object o1 = selectionPath.getLastPathComponent();
- if (!(o1 instanceof CheckedTreeNode)) continue;
- CheckedTreeNode node = (CheckedTreeNode)o1;
- checkNode(node, checked);
- ((DefaultTreeModel)tree.getModel()).nodeChanged(node);
- }
-
- e.consume();
- }
- }
- });
-
- tree.setSelectionRow(0);
+ setupKeyListener(tree, mainComponent);
+ setupMouseListener(tree, mainComponent, cellRenderer);
}
- private static boolean isToggleEvent(KeyEvent e) {
- return e.getKeyCode() == KeyEvent.VK_SPACE;
- }
-
- protected boolean toggleNode(CheckedTreeNode node) {
- boolean checked = !node.isChecked();
- checkNode(node, checked);
+ public void setNodeState(Tree tree, CheckedTreeNode node, boolean checked) {
+ changeNodeState(node, checked);
+ adjustParentsAndChildren(node, checked);
+ tree.repaint();
// notify model listeners about model change
- final TreeModel model = getTree().getModel();
+ final TreeModel model = tree.getModel();
model.valueForPathChanged(new TreePath(node.getPath()), node.getUserObject());
-
- return checked;
}
- private void checkNode(CheckedTreeNode node, boolean checked) {
- adjustParentsAndChildren(node, checked);
- repaint();
+ private void toggleNode(Tree tree, CheckedTreeNode node) {
+ setNodeState(tree, node, !node.isChecked());
}
private void adjustParentsAndChildren(final CheckedTreeNode node, final boolean checked) {
- changeNodeState(node, checked);
if (!checked) {
- TreeNode parent = node.getParent();
- while (parent != null) {
- if (parent instanceof CheckedTreeNode) {
- changeNodeState((CheckedTreeNode)parent, false);
+ if (myCheckPolicy.uncheckParentWithUncheckedChild) {
+ TreeNode parent = node.getParent();
+ while (parent != null) {
+ if (parent instanceof CheckedTreeNode) {
+ changeNodeState((CheckedTreeNode)parent, false);
+ }
+ parent = parent.getParent();
}
- parent = parent.getParent();
}
- uncheckChildren(node);
+ if (myCheckPolicy.uncheckChildrenWithUncheckedParent) {
+ uncheckChildren(node);
+ }
}
else {
- checkChildren(node);
+ if (myCheckPolicy.checkChildrenWithCheckedParent) {
+ checkChildren(node);
+ }
+
+ if (myCheckPolicy.checkParentWithCheckedChild) {
+ TreeNode parent = node.getParent();
+ while (parent != null) {
+ if (parent instanceof CheckedTreeNode) {
+ changeNodeState((CheckedTreeNode)parent, true);
+ }
+ parent = parent.getParent();
+ }
+ }
}
- repaint();
}
- private static void changeNodeState(final CheckedTreeNode node, final boolean checked) {
+ private void changeNodeState(final CheckedTreeNode node, final boolean checked) {
if (node.isChecked() != checked) {
+ myEventDispatcher.getMulticaster().beforeNodeStateChanged(node);
node.setChecked(checked);
+ myEventDispatcher.getMulticaster().nodeStateChanged(node);
}
}
- private static void uncheckChildren(final CheckedTreeNode node) {
+ private void uncheckChildren(final CheckedTreeNode node) {
final Enumeration children = node.children();
while (children.hasMoreElements()) {
final Object o = children.nextElement();
@@ -166,7 +123,7 @@ public class CheckboxTreeTable extends TreeTableView {
}
}
- private static void checkChildren(final CheckedTreeNode node) {
+ private void checkChildren(final CheckedTreeNode node) {
final Enumeration children = node.children();
while (children.hasMoreElements()) {
final Object o = children.nextElement();
@@ -177,12 +134,77 @@ public class CheckboxTreeTable extends TreeTableView {
}
}
+ private void setupKeyListener(final Tree tree, final JComponent mainComponent) {
+ mainComponent.addKeyListener(new KeyAdapter() {
+ public void keyPressed(@NotNull KeyEvent e) {
+ if (isToggleEvent(e, mainComponent)) {
+ TreePath treePath = tree.getLeadSelectionPath();
+ if (treePath == null) return;
+ final Object o = treePath.getLastPathComponent();
+ if (!(o instanceof CheckedTreeNode)) return;
+ CheckedTreeNode firstNode = (CheckedTreeNode)o;
+ toggleNode(tree, firstNode);
+ boolean checked = firstNode.isChecked();
+
+ TreePath[] selectionPaths = tree.getSelectionPaths();
+ for (int i = 0; selectionPaths != null && i < selectionPaths.length; i++) {
+ final TreePath selectionPath = selectionPaths[i];
+ final Object o1 = selectionPath.getLastPathComponent();
+ if (!(o1 instanceof CheckedTreeNode)) continue;
+ CheckedTreeNode node = (CheckedTreeNode)o1;
+ setNodeState(tree, node, checked);
+ }
+
+ e.consume();
+ }
+ }
+ });
+ }
+
+ private static boolean isToggleEvent(KeyEvent e, JComponent mainComponent) {
+ return e.getKeyCode() == KeyEvent.VK_SPACE && SpeedSearchSupply.getSupply(mainComponent) == null;
+ }
+
+ private void setupMouseListener(final Tree tree, JComponent mainComponent, final CheckboxTreeBase.CheckboxTreeCellRendererBase cellRenderer) {
+ new ClickListener() {
+ @Override
+ public boolean onClick(@NotNull MouseEvent e, int clickCount) {
+ int row = tree.getRowForLocation(e.getX(), e.getY());
+ if (row < 0) return false;
+ final Object o = tree.getPathForRow(row).getLastPathComponent();
+ if (!(o instanceof CheckedTreeNode)) return false;
+ Rectangle rowBounds = tree.getRowBounds(row);
+ cellRenderer.setBounds(rowBounds);
+ Rectangle checkBounds = cellRenderer.myCheckbox.getBounds();
+ checkBounds.setLocation(rowBounds.getLocation());
+
+ if (checkBounds.height == 0) checkBounds.height = checkBounds.width = rowBounds.height;
+
+ final CheckedTreeNode node = (CheckedTreeNode)o;
+ if (checkBounds.contains(e.getPoint())) {
+ if (node.isEnabled()) {
+ toggleNode(tree, node);
+ tree.setSelectionRow(row);
+ return true;
+ }
+ }
+ else if (clickCount > 1) {
+ myEventDispatcher.getMulticaster().mouseDoubleClicked(node);
+ return true;
+ }
+
+ return false;
+ }
+ }.installOn(mainComponent);
+ }
+
@SuppressWarnings("unchecked")
- public <T> T[] getCheckedNodes(final Class<T> nodeType) {
+ public static <T> T[] getCheckedNodes(final Class<T> nodeType, @Nullable final Tree.NodeFilter<T> filter, final TreeModel model) {
final ArrayList<T> nodes = new ArrayList<T>();
- final Object root = getTree().getModel().getRoot();
+ final Object root = model.getRoot();
if (!(root instanceof CheckedTreeNode)) {
- throw new IllegalStateException("The root must be instance of the " + CheckedTreeNode.class.getName() + ": " + root.getClass().getName());
+ throw new IllegalStateException(
+ "The root must be instance of the " + CheckedTreeNode.class.getName() + ": " + root.getClass().getName());
}
new Object() {
@SuppressWarnings("unchecked")
@@ -191,6 +213,7 @@ public class CheckboxTreeTable extends TreeTableView {
Object userObject = node.getUserObject();
if (node.isChecked() && userObject != null && nodeType.isAssignableFrom(userObject.getClass())) {
final T value = (T)userObject;
+ if (filter != null && !filter.accept(value)) return;
nodes.add(value);
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeListener.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeListener.java
new file mode 100644
index 000000000000..792c4589c85d
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeListener.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.EventListener;
+
+/**
+ * @author nik
+ */
+public interface CheckboxTreeListener extends EventListener {
+ void mouseDoubleClicked(@NotNull CheckedTreeNode node);
+
+ void nodeStateChanged(@NotNull CheckedTreeNode node);
+
+ void beforeNodeStateChanged(@NotNull CheckedTreeNode node);
+}
diff --git a/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java b/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java
index 846378cc1633..2d4213da3954 100644
--- a/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java
+++ b/platform/platform-api/src/com/intellij/ui/CommonActionsPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -165,6 +165,9 @@ public class CommonActionsPanel extends JPanel {
@Override
public void addNotify() {
+ if (getBackground() != null && !getBackground().equals(UIUtil.getPanelBackground())) {
+ SwingUtilities.updateComponentTreeUI(this.getParent());
+ }
final JRootPane pane = getRootPane();
for (AnActionButton button : myActions) {
final ShortcutSet shortcut = button.getShortcut();
diff --git a/platform/platform-api/src/com/intellij/ui/JBSplitter.java b/platform/platform-api/src/com/intellij/ui/JBSplitter.java
index b4000dbcfae2..5f01602d92c5 100644
--- a/platform/platform-api/src/com/intellij/ui/JBSplitter.java
+++ b/platform/platform-api/src/com/intellij/ui/JBSplitter.java
@@ -94,14 +94,6 @@ public class JBSplitter extends Splitter {
saveProportion();
}
- public void setOnePixelMode() {
- setDividerWidth(1);
- setShowDividerIcon(false);
- getDivider().setBackground(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128)));
- setShowDividerControls(false);
- setOrientation(getOrientation());
- }
-
protected void loadProportion() {
if (! StringUtil.isEmpty(mySplitterProportionKey)) {
setProportion(PropertiesComponent.getInstance().getFloat(mySplitterProportionKey, myProportion));
diff --git a/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java b/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java
new file mode 100644
index 000000000000..15dd5fdc2abb
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/OnePixelSplitter.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui;
+
+import com.intellij.openapi.ui.Divider;
+import com.intellij.openapi.ui.OnePixelDivider;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class OnePixelSplitter extends JBSplitter {
+
+ public OnePixelSplitter() {
+ super();
+ init();
+ }
+
+ public OnePixelSplitter(boolean vertical) {
+ super(vertical);
+ init();
+ }
+
+ public OnePixelSplitter(boolean vertical, float proportion) {
+ super(vertical, proportion);
+ init();
+ }
+
+ public OnePixelSplitter(float proportion) {
+ super(proportion);
+ init();
+ }
+
+ public OnePixelSplitter(boolean vertical, float proportion, float minProp, float maxProp) {
+ super(vertical, proportion, minProp, maxProp);
+ init();
+ }
+
+ protected void init() {
+ setDividerWidth(1);
+ }
+
+ @Override
+ protected Divider createDivider() {
+ return new OnePixelDivider(isVertical(), this);
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java b/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java
index ee68a3f94ae8..2f5bf0343ed6 100644
--- a/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java
+++ b/platform/platform-api/src/com/intellij/ui/border/CustomLineBorder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package com.intellij.ui.border;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.border.Border;
import java.awt.*;
@@ -28,17 +29,17 @@ public class CustomLineBorder implements Border {
private final Color myColor;
private final Insets myInsets;
- public CustomLineBorder(@NotNull Color color, @NotNull Insets insets) {
+ public CustomLineBorder(@Nullable Color color, @NotNull Insets insets) {
myColor = color;
myInsets = insets;
}
- public CustomLineBorder(@NotNull Color color, int top, int left, int bottom, int right) {
+ public CustomLineBorder(@Nullable Color color, int top, int left, int bottom, int right) {
this(color, new Insets(top, left, bottom, right));
}
public CustomLineBorder(@NotNull Insets insets) {
- this(UIUtil.getBorderColor(), insets);
+ this(null, insets);
}
public CustomLineBorder(int top, int left, int bottom, int right) {
@@ -59,7 +60,7 @@ public class CustomLineBorder implements Border {
}
protected Color getColor() {
- return myColor;
+ return myColor == null ? UIUtil.getBorderColor() : myColor;
}
@Override
diff --git a/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java b/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java
index a79349b5f6aa..46bce6b3834d 100644
--- a/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java
+++ b/platform/platform-api/src/com/intellij/ui/table/BaseTableView.java
@@ -17,12 +17,12 @@ package com.intellij.ui.table;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.config.Storage;
-import com.intellij.util.ui.ListTableModel;
import org.jetbrains.annotations.NonNls;
import javax.swing.*;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableModel;
import java.util.ArrayList;
import java.util.Arrays;
@@ -33,10 +33,14 @@ import java.util.Arrays;
public class BaseTableView extends JBTable {
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.table.BaseTableView");
- public BaseTableView(final ListTableModel model) {
+ public BaseTableView(final TableModel model) {
super(model);
}
+ public BaseTableView(TableModel model, TableColumnModel columnModel) {
+ super(model, columnModel);
+ }
+
@NonNls
private static String orderPropertyName(final int index) {
return "Order"+index;
diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
index e7ff935e57f9..435c4358959f 100644
--- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java
+++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
@@ -62,8 +62,12 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
this(new DefaultTableModel());
}
- public JBTable(final TableModel model) {
- super(model);
+ public JBTable(TableModel model) {
+ this(model, null);
+ }
+
+ public JBTable(final TableModel model, final TableColumnModel columnModel) {
+ super(model, columnModel);
myEmptyText = new StatusText(this) {
@Override
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java b/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java
index d1dfa976e479..c8c944c86e4a 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/TabInfo.java
@@ -92,6 +92,7 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
* out of its container. (IDEA-61536)
*/
private WeakReference<TabInfo> myPreviousSelection = new WeakReference<TabInfo>(null);
+ private boolean myTitleShortened;
public TabInfo(final JComponent component) {
myComponent = component;
@@ -392,6 +393,14 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
return myPreviousSelection.get();
}
+ public boolean isTitleShortened() {
+ return myTitleShortened;
+ }
+
+ public void setTitleIsShortened(boolean titleIsShortened) {
+ myTitleShortened = titleIsShortened;
+ }
+
public interface DragOutDelegate {
void dragOutStarted(MouseEvent mouseEvent, TabInfo info);
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java
index 655854ac933c..b0df0917dfe0 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java
@@ -240,7 +240,7 @@ class DragHelper extends MouseDragHelper {
final JBTabsPosition position = myTabs.getTabsPosition();
- if (!willDragOutStart && JBEditorTabs.isAlphabeticalMode() && position != JBTabsPosition.top && position != JBTabsPosition.bottom) {
+ if (!willDragOutStart && myTabs.isAlphabeticalMode() && position != JBTabsPosition.top && position != JBTabsPosition.bottom) {
Point p = new Point(event.getPoint());
p = SwingUtilities.convertPoint(event.getComponent(), p, myTabs);
if (myTabs.getVisibleRect().contains(p) && myPressedOnScreenPoint.distance(new RelativePoint(event).getScreenPoint()) > 15) {
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java
index 761d3ea0d341..a842f623ac45 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java
@@ -43,7 +43,8 @@ import java.util.List;
* @author pegov
*/
public class JBEditorTabs extends JBTabsImpl {
- private static final String TABS_ALPHABETICAL_KEY = "tabs.alphabetical";
+ public static final String TABS_ALPHABETICAL_KEY = "tabs.alphabetical";
+ static final String TABS_SHORTEN_TITLE_IF_NEED = "tabs.shorten.title.if.need";
private JBEditorTabsPainter myDarkPainter = new DarculaEditorTabsPainter();
private JBEditorTabsPainter myDefaultPainter = new DefaultEditorTabsPainter();
@@ -61,6 +62,13 @@ public class JBEditorTabs extends JBTabsImpl {
}
@Override
+ protected TabLabel createTabLabel(TabInfo info) {
+ TabLabel label = super.createTabLabel(info);
+ label.putClientProperty(TABS_SHORTEN_TITLE_IF_NEED, Boolean.TRUE);
+ return label;
+ }
+
+ @Override
public boolean isEditorTabs() {
return true;
}
@@ -130,7 +138,7 @@ public class JBEditorTabs extends JBTabsImpl {
return UIUtil.isUnderDarcula() ? myDarkPainter : myDefaultPainter;
}
- public static boolean isAlphabeticalMode() {
+ public boolean isAlphabeticalMode() {
return Registry.is(TABS_ALPHABETICAL_KEY);
}
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
index a058badddd41..60898a6e9bd8 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
@@ -1262,6 +1262,10 @@ public class JBTabsImpl extends JComponent
return null;
}
+ public boolean isAlphabeticalMode() {
+ return false;
+ }
+
@Nullable
private TabInfo findEnabledBackward(int from, boolean cycle) {
if (from < 0) return null;
@@ -1653,19 +1657,13 @@ public class JBTabsImpl extends JComponent
config.setAntialiasing(false);
- if (isSideComponentVertical()) {
- Toolbar toolbarComp = myInfo2Toolbar.get(mySelectedInfo);
- if (toolbarComp != null && !toolbarComp.isEmpty()) {
- Rectangle toolBounds = toolbarComp.getBounds();
- g2d.setColor(CaptionPanel.CNT_ACTIVE_BORDER_COLOR);
+ Toolbar toolbarComp = myInfo2Toolbar.get(mySelectedInfo);
+ if (toolbarComp != null && !toolbarComp.isEmpty()) {
+ Rectangle toolBounds = toolbarComp.getBounds();
+ g2d.setColor(CaptionPanel.CNT_ACTIVE_BORDER_COLOR);
+ if (isSideComponentVertical()) {
g2d.drawLine((int)toolBounds.getMaxX(), toolBounds.y, (int)toolBounds.getMaxX(), (int)toolBounds.getMaxY() - 1);
- }
- }
- else if (!isSideComponentOnTabs()) {
- Toolbar toolbarComp = myInfo2Toolbar.get(mySelectedInfo);
- if (toolbarComp != null && !toolbarComp.isEmpty()) {
- Rectangle toolBounds = toolbarComp.getBounds();
- g2d.setColor(CaptionPanel.CNT_ACTIVE_BORDER_COLOR);
+ } else if (!isSideComponentOnTabs()) {
g2d.drawLine(toolBounds.x, (int)toolBounds.getMaxY(), (int)toolBounds.getMaxX() - 1, (int)toolBounds.getMaxY());
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
index 21c36d5dd66a..a360c4e9294f 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.util.Pass;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.ui.tabs.JBTabsPosition;
@@ -317,6 +318,16 @@ public class TabLabel extends JPanel {
public void setText(final SimpleColoredText text) {
+ myInfo.setTitleIsShortened(false);
+ if (text != null && text.getTexts().size() == 1 && Boolean.TRUE == getClientProperty(JBEditorTabs.TABS_SHORTEN_TITLE_IF_NEED)) {
+ String title = text.getTexts().get(0);
+ if (title.length() > UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT) {
+ SimpleTextAttributes attributes = text.getAttributes().get(0);
+ text.clear();
+ text.append(StringUtil.getShortened(title, UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT), attributes);
+ myInfo.setTitleIsShortened(true);
+ }
+ }
myLabel.change(new Runnable() {
public void run() {
myLabel.clear();
diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java
index 653420ae261f..4e5925d2a2ee 100644
--- a/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java
+++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/singleRow/SingleRowLayout.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -147,7 +147,7 @@ public class SingleRowLayout extends TabLayout {
}
public LayoutPassInfo layoutSingleRow(List<TabInfo> visibleInfos) {
- if (JBEditorTabs.isAlphabeticalMode()) {
+ if (myTabs.isAlphabeticalMode()) {
Collections.sort(visibleInfos, new Comparator<TabInfo>() {
@Override
public int compare(TabInfo o1, TabInfo o2) {
diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java
index 169b5d57479b..0975876055b2 100644
--- a/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java
+++ b/platform/platform-api/src/com/intellij/ui/treeStructure/Tree.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -828,4 +828,35 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith
public void setHorizontalAutoScrollingEnabled(boolean enabled) {
myHorizontalAutoScrolling = enabled;
}
+
+ /**
+ * Returns the deepest visible component
+ * that will be rendered at the specified location.
+ *
+ * @param x horizontal location in the tree
+ * @param y vertical location in the tree
+ * @return the deepest visible component of the renderer
+ */
+ @Nullable
+ protected Component getDeepestRendererComponentAt(int x, int y) {
+ int row = getRowForLocation(x, y);
+ if (row >= 0) {
+ TreeCellRenderer renderer = getCellRenderer();
+ if (renderer != null) {
+ TreePath path = getPathForRow(row);
+ Object node = path.getLastPathComponent();
+ Component component = renderer.getTreeCellRendererComponent(this, node,
+ isRowSelected(row),
+ isExpanded(row),
+ getModel().isLeaf(node),
+ row, true);
+ Rectangle bounds = getPathBounds(path);
+ if (bounds != null) {
+ component.setBounds(bounds); // initialize size to layout complex renderer
+ return SwingUtilities.getDeepestComponentAt(component, x - bounds.x, y - bounds.y);
+ }
+ }
+ }
+ return null;
+ }
} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java b/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java
index dac3354a24fb..b574926a7eb8 100644
--- a/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java
+++ b/platform/platform-api/src/com/intellij/ui/treeStructure/treetable/TreeTableTree.java
@@ -98,7 +98,9 @@ public class TreeTableTree extends Tree {
public void setVisibleRow(int row) {
myVisibleRow = row;
- setPreferredSize(new Dimension(getRowBounds(myVisibleRow).width, getPreferredSize().height));
+ final Rectangle rowBounds = getRowBounds(myVisibleRow);
+ final int indent = rowBounds.x - getVisibleRect().x;
+ setPreferredSize(new Dimension(getRowBounds(myVisibleRow).width + indent, getPreferredSize().height));
}
public void _processKeyEvent(KeyEvent e){
diff --git a/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java b/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
index 94eaa4db1ccb..0bcb416c7334 100644
--- a/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
+++ b/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.util.SystemProperties;
import com.intellij.util.WaitForProgressToShow;
import com.intellij.util.proxy.CommonProxy;
import com.intellij.util.proxy.JavaProxyProperty;
@@ -64,6 +65,7 @@ import java.util.*;
)
public class HttpConfigurable implements PersistentStateComponent<HttpConfigurable>, ApplicationComponent,
ExportableApplicationComponent {
+ public static final int CONNECTION_TIMEOUT = SystemProperties.getIntProperty("connection.timeout", 10000);
private static final Logger LOG = Logger.getInstance("#com.intellij.util.net.HttpConfigurable");
public boolean PROXY_TYPE_IS_SOCKS = false;
public boolean USE_HTTP_PROXY = false;
@@ -348,8 +350,8 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
final URLConnection connection = openConnection(url);
try {
- connection.setConnectTimeout(3 * 1000);
- connection.setReadTimeout(3 * 1000);
+ connection.setConnectTimeout(CONNECTION_TIMEOUT);
+ connection.setReadTimeout(CONNECTION_TIMEOUT);
connection.connect();
connection.getInputStream();
}
diff --git a/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java b/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java
index c2d3d829440d..89d5a238c188 100644
--- a/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java
+++ b/platform/platform-api/src/com/intellij/util/ui/FormBuilder.java
@@ -108,6 +108,11 @@ public class FormBuilder {
}
public FormBuilder addVerticalGap(final int height) {
+ if (height == -1) {
+ myPanel.add(new JLabel(), new GridBagConstraints(0, myLineCount++, 2, 1, 0, 1, CENTER, NONE, new Insets(0, 0, 0, 0), 0, 0));
+ return this;
+ }
+
return addLabeledComponent((JLabel)null,
new Box.Filler(new Dimension(0, height), new Dimension(0, height), new Dimension(Short.MAX_VALUE, height)));
}
diff --git a/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java b/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java
index 669766ee104b..3000b49656c6 100644
--- a/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java
+++ b/platform/platform-api/src/org/jetbrains/ide/HttpRequestHandler.java
@@ -29,7 +29,7 @@ public abstract class HttpRequestHandler {
public static final ExtensionPointName<HttpRequestHandler> EP_NAME = ExtensionPointName.create("com.intellij.httpRequestHandler");
public boolean isSupported(@NotNull FullHttpRequest request) {
- return request.getMethod() == HttpMethod.GET || request.getMethod() == HttpMethod.HEAD;
+ return request.method() == HttpMethod.GET || request.method() == HttpMethod.HEAD;
}
public abstract boolean process(@NotNull QueryStringDecoder urlDecoder, @NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context)
diff --git a/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java b/platform/platform-impl/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java
index 7d972816769c..7d972816769c 100644
--- a/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java
+++ b/platform/platform-impl/src/com/intellij/codeInsight/editorActions/TextBlockTransferable.java
diff --git a/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java b/platform/platform-impl/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java
index bdaf6f2ea546..bdaf6f2ea546 100644
--- a/platform/platform-api/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java
+++ b/platform/platform-impl/src/com/intellij/codeInsight/editorActions/TextBlockTransferableData.java
diff --git a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java
index 64aefa4c0977..b8e17ea3eded 100644
--- a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java
+++ b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -115,7 +115,7 @@ public class DelayedDocumentWatcher {
public void documentChanged(DocumentEvent event) {
if (myDocumentSavingInProgress) {
/** When {@link FileDocumentManager#saveAllDocuments} is called,
- * {@link com.intellij.openapi.fileEditor.impl.TrailingSpacesStripper} can change a document.
+ * {@link com.intellij.openapi.editor.impl.TrailingSpacesStripper} can change a document.
* These needless 'documentChanged' events should be filtered out.
*/
return;
diff --git a/platform/platform-impl/src/com/intellij/help/impl/MacHelpUtil.java b/platform/platform-impl/src/com/intellij/help/impl/MacHelpUtil.java
index 90d633f0d621..a73295c90f74 100644
--- a/platform/platform-impl/src/com/intellij/help/impl/MacHelpUtil.java
+++ b/platform/platform-impl/src/com/intellij/help/impl/MacHelpUtil.java
@@ -41,7 +41,7 @@ public class MacHelpUtil {
}
static boolean isApplicable() {
- return SystemInfo.isMac && Registry.is("ide.mac.show.native.help", false) && !PlatformUtils.isCidr() && !PlatformUtils
+ return SystemInfo.isMac && Registry.is("ide.mac.show.native.help") && !PlatformUtils.isCidr() && !PlatformUtils
.isIdeaCommunity();
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
index 1bbd74984fcc..c8699c083ef4 100644
--- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
+++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
@@ -952,25 +952,18 @@ public class IdeEventQueue extends EventQueue {
}
private static class WindowsAltSupressor implements EventDispatcher {
-
- private boolean myPureAltWasPressed;
private boolean myWaitingForAltRelease;
- private boolean myWaiterScheduled;
-
private Robot myRobot;
@Override
public boolean dispatch(AWTEvent e) {
boolean dispatch = true;
- if (!Registry.is("actionSystem.win.suppressAlt.new") && e instanceof KeyEvent) {
+ if (e instanceof KeyEvent) {
KeyEvent ke = (KeyEvent)e;
final Component component = ke.getComponent();
- final Window window = component == null ? null : SwingUtilities.windowForComponent(component);
boolean pureAlt = ke.getKeyCode() == KeyEvent.VK_ALT && (ke.getModifiers() | InputEvent.ALT_MASK) == InputEvent.ALT_MASK;
if (!pureAlt) {
- myPureAltWasPressed = false;
myWaitingForAltRelease = false;
- myWaiterScheduled = false;
}
else {
if (ApplicationManager.getApplication() == null ||
@@ -978,28 +971,25 @@ public class IdeEventQueue extends EventQueue {
!SystemInfo.isWindows ||
!Registry.is("actionSystem.win.suppressAlt") ||
!(UISettings.getInstance().HIDE_TOOL_STRIPES || UISettings.getInstance().PRESENTATION_MODE)) {
- return !dispatch;
+ return true;
}
if (ke.getID() == KeyEvent.KEY_PRESSED) {
- myPureAltWasPressed = true;
dispatch = !myWaitingForAltRelease;
}
else if (ke.getID() == KeyEvent.KEY_RELEASED) {
if (myWaitingForAltRelease) {
- myPureAltWasPressed = false;
myWaitingForAltRelease = false;
- myWaiterScheduled = false;
dispatch = false;
}
- else {
- myWaiterScheduled = true;
+ else if (component != null) {
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
- if (SystemInfo.isWindows || window == null || !window.isActive()) {
+ final Window window = component instanceof Window ? (Window)component : SwingUtilities.windowForComponent(component);
+ if (window == null || !window.isActive()) {
return;
}
myWaitingForAltRelease = true;
diff --git a/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java b/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
index 8aa0e38c0d0d..d7118949e5de 100644
--- a/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,13 +24,12 @@ package com.intellij.ide;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.reference.SoftReference;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.util.ReflectionUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.image.VolatileImage;
import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
import java.util.Map;
/**
@@ -40,7 +39,6 @@ public class IdeRepaintManager extends RepaintManager {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.HackyRepaintManager");
private Map<GraphicsConfiguration, VolatileImage> myImagesMap;
- @NonNls private static final String FAULTY_FIELD_NAME = "volatileMap";
WeakReference<JComponent> myLastComponent;
@@ -53,14 +51,7 @@ public class IdeRepaintManager extends RepaintManager {
// sync here is to avoid data race when two(!) AWT threads on startup try to compete for the single myImagesMap
private synchronized void clearLeakyImages(boolean force) {
if (myImagesMap == null) {
- try {
- Field volMapField = RepaintManager.class.getDeclaredField(FAULTY_FIELD_NAME);
- volMapField.setAccessible(true);
- myImagesMap = (Map<GraphicsConfiguration, VolatileImage>)volMapField.get(this);
- }
- catch (Exception e) {
- LOG.error(e);
- }
+ myImagesMap = ReflectionUtil.getField(RepaintManager.class, this, Map.class, "volatileMap");
}
if (force ||
@@ -90,12 +81,12 @@ public class IdeRepaintManager extends RepaintManager {
// We must keep a strong reference to the DisplayChangedListener,
// since SunDisplayChanger keeps only a WeakReference to it.
- private Object displayChangeHack;
+ private DisplayChangeHandler displayChangeHack;
{
try {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice[] devices = env.getScreenDevices(); // init
+ env.getScreenDevices(); // init
Class<?> aClass = Class.forName("sun.awt.DisplayChangedListener"); // might be absent
displayChangeHack = new DisplayChangeHandler();
@@ -104,7 +95,8 @@ public class IdeRepaintManager extends RepaintManager {
.getMethod("addDisplayChangedListener", new Class[]{aClass})
.invoke(env, displayChangeHack);
}
- } catch (Throwable t) {
+ }
+ catch (Throwable t) {
if (!(t instanceof HeadlessException)) LOG.error("Cannot setup display change listener", t);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java
index e3e1945d14f1..3b8bacee5457 100644
--- a/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/XmlRpcServerImpl.java
@@ -59,7 +59,7 @@ public class XmlRpcServerImpl implements XmlRpcServer {
static final class XmlRpcRequestHandler extends HttpRequestHandler {
@Override
public boolean isSupported(@NotNull FullHttpRequest request) {
- return request.getMethod() == HttpMethod.POST || request.getMethod() == HttpMethod.OPTIONS;
+ return request.method() == HttpMethod.POST || request.method() == HttpMethod.OPTIONS;
}
@Override
@@ -89,7 +89,7 @@ public class XmlRpcServerImpl implements XmlRpcServer {
return false;
}
- if (request.getMethod() == HttpMethod.POST) {
+ if (request.method() == HttpMethod.POST) {
ByteBuf result;
ByteBufInputStream in = new ByteBufInputStream(request.content());
try {
@@ -116,7 +116,7 @@ public class XmlRpcServerImpl implements XmlRpcServer {
return true;
}
else if (HttpMethod.POST.name().equals(request.headers().get("Access-Control-Request-Method"))) {
- LOG.assertTrue(request.getMethod() == HttpMethod.OPTIONS);
+ LOG.assertTrue(request.method() == HttpMethod.OPTIONS);
Responses.sendOptionsResponse("POST, OPTIONS", request, context);
return true;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java b/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java
index 7bbc3e0c6cba..006830479db3 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ChooseComponentsToExportDialog.java
@@ -33,6 +33,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.FieldPanel;
import com.intellij.util.Consumer;
+import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,15 +56,14 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
private final boolean myShowFilePath;
private final String myDescription;
- public ChooseComponentsToExportDialog(List<ExportableComponent> components,
- Map<File, Set<ExportableComponent>> fileToComponents,
+ public ChooseComponentsToExportDialog(MultiMap<File, ExportableComponent> fileToComponents,
boolean showFilePath, final String title, String description) {
super(false);
myDescription = description;
myShowFilePath = showFilePath;
Map<ExportableComponent, ComponentElementProperties> componentToContainingListElement = new LinkedHashMap<ExportableComponent, ComponentElementProperties>();
- for (ExportableComponent component : components) {
+ for (ExportableComponent component : fileToComponents.values()) {
if (!addToExistingListElement(component, componentToContainingListElement, fileToComponents)) {
ComponentElementProperties componentElementProperties = new ComponentElementProperties();
componentElementProperties.addComponent(component);
@@ -149,14 +149,14 @@ public class ChooseComponentsToExportDialog extends DialogWrapper {
}
private static boolean addToExistingListElement(ExportableComponent component,
- Map<ExportableComponent,ComponentElementProperties> componentToContainingListElement,
- Map<File, Set<ExportableComponent>> fileToComponents) {
+ Map<ExportableComponent, ComponentElementProperties> componentToContainingListElement,
+ MultiMap<File, ExportableComponent> fileToComponents) {
final File[] exportFiles = component.getExportFiles();
File file = null;
for (File exportFile : exportFiles) {
- final Set<ExportableComponent> tiedComponents = fileToComponents.get(exportFile);
+ Collection<ExportableComponent> tiedComponents = fileToComponents.get(exportFile);
- for (final ExportableComponent tiedComponent : tiedComponents) {
+ for (ExportableComponent tiedComponent : tiedComponents) {
if (tiedComponent == component) continue;
final ComponentElementProperties elementProperties = componentToContainingListElement.get(tiedComponent);
if (elementProperties != null && !FileUtil.filesEqual(exportFile, file)) {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
index e82e22d926ea..19a6502b8add 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ExportSettingsAction.java
@@ -35,7 +35,9 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
import com.intellij.util.io.ZipUtil;
+import org.jetbrains.annotations.NotNull;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -47,10 +49,18 @@ import java.util.jar.JarOutputStream;
public class ExportSettingsAction extends AnAction implements DumbAware {
public void actionPerformed(AnActionEvent e) {
Project project = getEventProject(e);
- List<ExportableComponent> exportableComponents = new ArrayList<ExportableComponent>();
- Map<File,Set<ExportableComponent>> fileToComponents = getRegisteredComponentsAndFiles(exportableComponents);
- final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(exportableComponents, fileToComponents, true,
+ ApplicationManager.getApplication().saveSettings();
+
+ MultiMap<File, ExportableComponent> fileToComponents = getExportableComponentsMap();
+ for (Iterator<File> it = fileToComponents.keySet().iterator(); it.hasNext(); ) {
+ File file = it.next();
+ if (!file.exists()) {
+ it.remove();
+ }
+ }
+
+ final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(fileToComponents, true,
IdeBundle.message("title.select.components.to.export"),
IdeBundle.message(
"prompt.please.check.all.components.to.export"));
@@ -65,8 +75,6 @@ public class ExportSettingsAction extends AnAction implements DumbAware {
ContainerUtil.addAll(exportFiles, markedComponent.getExportFiles());
}
- ApplicationManager.getApplication().saveSettings();
-
final File saveFile = dialog.getExportFile();
try {
if (saveFile.exists()) {
@@ -121,24 +129,18 @@ public class ExportSettingsAction extends AnAction implements DumbAware {
}
}
- public static Map<File, Set<ExportableComponent>> getRegisteredComponentsAndFiles(List<ExportableComponent> exportableComponents) {
- Map<File,Set<ExportableComponent>> fileToComponents = new HashMap<File, Set<ExportableComponent>>();
+ @NotNull
+ public static MultiMap<File, ExportableComponent> getExportableComponentsMap() {
+ MultiMap<File, ExportableComponent> result = MultiMap.createSet();
- final List<ExportableComponent> components = new ArrayList<ExportableComponent>(Arrays.asList(ApplicationManager.getApplication().getComponents(ExportableApplicationComponent.class)));
+ ExportableApplicationComponent[] components1 = ApplicationManager.getApplication().getComponents(ExportableApplicationComponent.class);
+ List<ExportableComponent> components2 = ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent.class);
- components.addAll(ServiceBean.loadServicesFromBeans(ExportableComponent.EXTENSION_POINT, ExportableComponent.class));
-
- for (ExportableComponent component : components) {
- exportableComponents.add(component);
+ for (ExportableComponent component : ContainerUtil.concat(Arrays.asList(components1), components2)) {
for (File exportFile : component.getExportFiles()) {
- Set<ExportableComponent> componentsTied = fileToComponents.get(exportFile);
- if (componentsTied == null) {
- componentsTied = new HashSet<ExportableComponent>();
- fileToComponents.put(exportFile, componentsTied);
- }
- componentsTied.add(component);
+ result.putValue(exportFile, component);
}
}
- return fileToComponents;
+ return result;
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java
index 1e989946ab2f..f06c45e1af7a 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ImportSettingsAction.java
@@ -36,13 +36,17 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.updateSettings.impl.UpdateSettings;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.Consumer;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
import com.intellij.util.io.ZipUtil;
import java.awt.*;
import java.io.File;
import java.io.IOException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
@@ -77,10 +81,10 @@ public class ImportSettingsAction extends AnAction implements DumbAware {
return;
}
- final ArrayList<ExportableComponent> registeredComponents = new ArrayList<ExportableComponent>();
- final Map<File, Set<ExportableComponent>> filesToComponents = ExportSettingsAction.getRegisteredComponentsAndFiles(registeredComponents);
- List<ExportableComponent> components = getComponentsStored(saveFile, registeredComponents);
- final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(components, filesToComponents, false,
+ MultiMap<File, ExportableComponent> filesToComponents = ExportSettingsAction.getExportableComponentsMap();
+ List<ExportableComponent> components = getComponentsStored(saveFile, ContainerUtil.newArrayList(filesToComponents.values()));
+ filesToComponents.values().retainAll(components);
+ final ChooseComponentsToExportDialog dialog = new ChooseComponentsToExportDialog(filesToComponents, false,
IdeBundle.message("title.select.components.to.import"),
IdeBundle.message("prompt.check.components.to.import"));
dialog.show();
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java b/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java
index 40bfe41fb26f..4a72eda21a3e 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/SendFeedbackAction.java
@@ -27,17 +27,20 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
import com.intellij.ui.LicensingFacade;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.Nullable;
import java.awt.*;
public class SendFeedbackAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(AnActionEvent e) {
- launchBrowser();
+ launchBrowser(e.getProject());
}
- public static void launchBrowser() {
+ public static void launchBrowser(@Nullable Project project) {
final ApplicationInfoEx appInfo = ApplicationInfoEx.getInstanceEx();
boolean eap = appInfo.isEAP();
String urlTemplate = eap ? appInfo.getEAPFeedbackUrl() : appInfo.getReleaseFeedbackUrl();
@@ -47,7 +50,7 @@ public class SendFeedbackAction extends AnAction implements DumbAware {
.replace("$VERSION", appInfo.getFullVersion())
.replace("$EVAL", isEvaluationLicense() ? "true" : "false")
.replace("$DESCR", getDescription());
- BrowserUtil.browse(urlTemplate);
+ BrowserUtil.browse(urlTemplate, project);
}
private static String getDescription() {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/SplitterActionBase.java b/platform/platform-impl/src/com/intellij/ide/actions/SplitterActionBase.java
index 851c9096a38b..dde5a5c898dd 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/SplitterActionBase.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/SplitterActionBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,14 +27,9 @@ public abstract class SplitterActionBase extends AnAction implements DumbAware {
public void update(final AnActionEvent event) {
final Project project = CommonDataKeys.PROJECT.getData(event.getDataContext());
final Presentation presentation = event.getPresentation();
- boolean enabled;
- if (project == null) {
- enabled = false;
- }
- else {
- enabled = isActionEnabled(project);
- }
- if (ActionPlaces.isPopupPlace(event.getPlace())) {
+ boolean inContextMenu = ActionPlaces.isPopupPlace(event.getPlace());
+ boolean enabled = project != null && isActionEnabled(project, inContextMenu);
+ if (inContextMenu) {
presentation.setVisible(enabled);
}
else {
@@ -42,7 +37,17 @@ public abstract class SplitterActionBase extends AnAction implements DumbAware {
}
}
- protected boolean isActionEnabled(Project project) {
+ /**
+ * This method determines whether the action is enabled for {@code project}
+ * if {@code inContextMenu} is set to {@code false}. Otherwise,
+ * it determines whether the action is visible in the context menu.
+ *
+ * @param project the specified project
+ * @param inContextMenu whether the action is used in context menu
+ * @return {@code true} if the action is enabled,
+ * {@code false} otherwise
+ */
+ protected boolean isActionEnabled(Project project, boolean inContextMenu) {
final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project);
return fileEditorManager.isInSplitter();
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java
index 4541f4664751..cb35b5a504f9 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java
@@ -1071,7 +1071,7 @@ public class Switcher extends AnAction implements DumbAware {
public void layoutContainer(Container target) {
final JScrollPane scrollPane = UIUtil.getParentOfType(JScrollPane.class, files);
JComponent filesPane = scrollPane != null ? scrollPane : files;
- if (sBounds == null) {
+ if (sBounds == null || !target.isShowing()) {
super.layoutContainer(target);
sBounds = separator.getBounds();
tBounds = toolWindows.getBounds();
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/TabsAlphabeticalModeSwitcher.java b/platform/platform-impl/src/com/intellij/ide/actions/TabsAlphabeticalModeSwitcher.java
index 8431364c5d61..7b000f530bdf 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/TabsAlphabeticalModeSwitcher.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/TabsAlphabeticalModeSwitcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package com.intellij.ide.actions;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.tabs.impl.JBEditorTabs;
import javax.swing.*;
@@ -28,7 +29,7 @@ import javax.swing.*;
public class TabsAlphabeticalModeSwitcher extends ToggleAction {
@Override
public boolean isSelected(AnActionEvent e) {
- return JBEditorTabs.isAlphabeticalMode();
+ return Registry.is(JBEditorTabs.TABS_ALPHABETICAL_KEY);
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/UnsplitAllAction.java b/platform/platform-impl/src/com/intellij/ide/actions/UnsplitAllAction.java
index 12df75e75656..ec724884ef2d 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/UnsplitAllAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/UnsplitAllAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,8 +32,8 @@ public final class UnsplitAllAction extends SplitterActionBase {
}
@Override
- protected boolean isActionEnabled(Project project) {
+ protected boolean isActionEnabled(Project project, boolean inContextMenu) {
final FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project);
- return fileEditorManager.getWindowSplitCount() > 2;
+ return inContextMenu ? fileEditorManager.getWindowSplitCount() > 2 : fileEditorManager.isInSplitter();
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
index d450cf454291..1af2fb883efb 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
@@ -25,7 +25,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.IconUtil;
-import com.intellij.util.PlatformUtils;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
@@ -55,12 +54,12 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
myLafNames.put(DARCULA, IconLoader.getIcon("/lafs/OSXDarcula.png"));
}
else if (SystemInfo.isWindows) {
- if (PlatformUtils.isIdeaCommunity()) {
+ //if (PlatformUtils.isIdeaCommunity()) {
myLafNames.put(INTELLIJ, IconLoader.getIcon("/lafs/WindowsIntelliJ.png"));
- }
- else {
- myLafNames.put(ALLOY, IconLoader.getIcon("/lafs/WindowsAlloy.png"));
- }
+ //}
+ //else {
+ // myLafNames.put(ALLOY, IconLoader.getIcon("/lafs/WindowsAlloy.png"));
+ //}
myLafNames.put(DARCULA, IconLoader.getIcon("/lafs/WindowsDarcula.png"));
}
else {
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java
index e5b9f1530256..b1ea1332986e 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/PasswordStorage.java
@@ -25,21 +25,15 @@ import org.jetbrains.annotations.Nullable;
* The interface defines basic password management operations
*/
public interface PasswordStorage {
-
/**
- * @deprecated To remove in IDEA 15. Use {@link #getPassword(Project, Class, String, ModalityState)}
- */
- @Deprecated
- @Nullable
- String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException;
-
- /**
- * Get password stored in a password safe.
- * <p/>
- * The method may be called from any thread. It may need to show a master password dialog to unlock the password database,
- * and then will use {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()}.
- * So make sure to pass correct {@link ModalityState} to the method to make sure the dialog is shown above all other dialog or progress
- * windows.
+ * <p>Get password stored in a password safe.</p>
+ *
+ * <p><b>NB: </b>
+ * This method may be called from the background,
+ * and it may need to ask user to enter the master password to access the database by calling
+ * {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()} to show a modal dialog.
+ * So make sure not to call it from the read action.
+ * Calling this method from the dispatch thread is allowed.</p>
*
* @param project the project, that is used to ask for the master password if this is the first access to password safe
* @param requestor the requestor class
@@ -49,53 +43,25 @@ public interface PasswordStorage {
* @throws IllegalStateException if the method is called from the read action.
*/
@Nullable
- String getPassword(@Nullable Project project, @NotNull Class requestor, String key,
- @Nullable ModalityState state) throws PasswordSafeException;
-
+ String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException;
/**
- * Store password in password safe
- * <p/>
- * The method may be called from any thread. It may need to show a master password dialog to unlock the password database,
- * and then will use {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()}.
- * So make sure to pass correct {@link ModalityState} to the method to make sure the dialog is shown above all other dialog or progress
- * windows.
+ * Remove password stored in a password safe
*
* @param project the project, that is used to ask for the master password if this is the first access to password safe
* @param requestor the requestor class
* @param key the key for the password
- * @param value the value to store
+ * @return the plugin key
* @throws PasswordSafeException if password safe cannot be accessed
*/
- void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value,
- @Nullable ModalityState modalityState) throws PasswordSafeException;
-
- /**
- * @deprecated To remove in IDEA 15. Use {@link #storePassword(Project, Class, String, String, ModalityState)}
- */
- @Deprecated
- void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException;
-
- /**
- * @deprecated To remove in IDEA 15. Use {@link #removePassword(Project, Class, String, ModalityState)}
- */
- @Deprecated
void removePassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException;
-
/**
- * Remove password stored in a password safe
- * <p/>
- * The method may be called from any thread. It may need to show a master password dialog to unlock the password database,
- * and then will use {@link Application#invokeAndWait(Runnable, ModalityState) invokeAndWait()}.
- * So make sure to pass correct {@link ModalityState} to the method to make sure the dialog is shown above all other dialog or progress
- * windows.
+ * Store password in password safe
*
* @param project the project, that is used to ask for the master password if this is the first access to password safe
* @param requestor the requestor class
* @param key the key for the password
- * @return the plugin key
+ * @param value the value to store
* @throws PasswordSafeException if password safe cannot be accessed
*/
- void removePassword(@Nullable Project project, @NotNull Class requestor, String key,
- @Nullable ModalityState modalityState) throws PasswordSafeException;
-
+ void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java
index 34aee7aaad38..6d5127b376ad 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeImpl.java
@@ -22,7 +22,6 @@ import com.intellij.ide.passwordSafe.impl.providers.masterKey.MasterKeyPasswordS
import com.intellij.ide.passwordSafe.impl.providers.masterKey.PasswordDatabase;
import com.intellij.ide.passwordSafe.impl.providers.memory.MemoryPasswordSafe;
import com.intellij.ide.passwordSafe.impl.providers.nil.NilProvider;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
@@ -71,19 +70,11 @@ public class PasswordSafeImpl extends PasswordSafe {
}
@Nullable
- @Override
public String getPassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException {
- return getPassword(project, requester, key, null);
- }
-
- @Nullable
- @Override
- public String getPassword(@Nullable Project project, @NotNull Class requester, String key,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
if (mySettings.getProviderType().equals(PasswordSafeSettings.ProviderType.MASTER_PASSWORD)) {
- String password = getMemoryProvider().getPassword(project, requester, key, modalityState);
+ String password = getMemoryProvider().getPassword(project, requester, key);
if (password == null) {
- password = provider().getPassword(project, requester, key, modalityState);
+ password = provider().getPassword(project, requester, key);
if (password != null) {
// cache the password in memory as well for easier access during the session
getMemoryProvider().storePassword(project, requester, key, password);
@@ -91,35 +82,21 @@ public class PasswordSafeImpl extends PasswordSafe {
}
return password;
}
- return provider().getPassword(project, requester, key, modalityState);
+ return provider().getPassword(project, requester, key);
}
- @Override
- public void removePassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException {
- removePassword(project, requestor, key, null);
- }
-
- @Override
- public void removePassword(@Nullable Project project, @NotNull Class requester, String key,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
+ public void removePassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException {
if (mySettings.getProviderType().equals(PasswordSafeSettings.ProviderType.MASTER_PASSWORD)) {
getMemoryProvider().removePassword(project, requester, key);
}
- provider().removePassword(project, requester, key, modalityState);
- }
-
- @Override
- public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException {
- storePassword(project, requestor, key, value, null);
+ provider().removePassword(project, requester, key);
}
- @Override
- public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
+ public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value) throws PasswordSafeException {
if (mySettings.getProviderType().equals(PasswordSafeSettings.ProviderType.MASTER_PASSWORD)) {
getMemoryProvider().storePassword(project, requester, key, value);
}
- provider().storePassword(project, requester, key, value, modalityState);
+ provider().storePassword(project, requester, key, value);
}
/**
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java
index 3a40d617e99b..18dee7c755f5 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/PasswordSafeProvider.java
@@ -15,11 +15,7 @@
*/
package com.intellij.ide.passwordSafe.impl;
-import com.intellij.ide.passwordSafe.PasswordSafeException;
import com.intellij.ide.passwordSafe.PasswordStorage;
-import com.intellij.openapi.project.Project;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* The provider for password safe component
@@ -38,21 +34,4 @@ public abstract class PasswordSafeProvider implements PasswordStorage {
* @return the name of provider
*/
public abstract String getName();
-
- @Nullable
- @Override
- public String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException {
- return getPassword(project, requestor, key, null);
- }
-
- @Override
- public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException {
- storePassword(project, requestor, key, value, null);
- }
-
- @Override
- public void removePassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException {
- removePassword(project, requestor, key, null);
- }
-
}
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java
index 8c8f921f18b8..a0b001824d90 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/BasePasswordSafeProvider.java
@@ -43,15 +43,13 @@ public abstract class BasePasswordSafeProvider extends PasswordSafeProvider {
* @throws PasswordSafeException in case of problems with access to the password database.
* @throws IllegalStateException if the method is called from the read action.
*/
- protected abstract byte[] key(@Nullable Project project, @NotNull Class requestor,
- @Nullable ModalityState modalityState) throws PasswordSafeException;
+ protected abstract byte[] key(@Nullable Project project, @NotNull Class requestor) throws PasswordSafeException;
@Nullable
- public String getPassword(@Nullable Project project, @NotNull Class requestor, String key,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
- byte[] k = dbKey(project, requestor, key, modalityState);
+ public String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException {
+ byte[] k = dbKey(project, requestor, key);
byte[] ct = getEncryptedPassword(k);
- return ct == null ? null : EncryptionUtil.decryptText(key(project, requestor, modalityState), ct);
+ return ct == null ? null : EncryptionUtil.decryptText(key(project, requestor), ct);
}
/**
@@ -68,17 +66,14 @@ public abstract class BasePasswordSafeProvider extends PasswordSafeProvider {
* @param project
* @param requestor the requestor class
* @param key the key to use
- * @param modalityState
* @return the key to use for map
*/
- private byte[] dbKey(@Nullable Project project, @NotNull Class requestor, String key,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
- return EncryptionUtil.dbKey(key(project, requestor, modalityState), requestor, key);
+ private byte[] dbKey(@Nullable Project project, Class requestor, String key) throws PasswordSafeException {
+ return EncryptionUtil.dbKey(key(project, requestor), requestor, key);
}
- public void removePassword(@Nullable Project project, @NotNull Class requester, String key,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
- byte[] k = dbKey(project, requester, key, modalityState);
+ public void removePassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException {
+ byte[] k = dbKey(project, requester, key);
removeEncryptedPassword(k);
}
@@ -89,10 +84,9 @@ public abstract class BasePasswordSafeProvider extends PasswordSafeProvider {
*/
protected abstract void removeEncryptedPassword(byte[] key);
- public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
- byte[] k = dbKey(project, requestor, key, modalityState);
- byte[] ct = EncryptionUtil.encryptText(key(project, requestor, modalityState), value);
+ public void storePassword(@Nullable Project project, @NotNull Class requestor, String key, String value) throws PasswordSafeException {
+ byte[] k = dbKey(project, requestor, key);
+ byte[] ct = EncryptionUtil.encryptText(key(project, requestor), value);
storeEncryptedPassword(k, ct);
}
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
index b74e51315cd5..840159270a8d 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java
@@ -154,8 +154,7 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
}
@Override
- protected byte[] key(@Nullable final Project project, @NotNull final Class requestor,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
+ protected byte[] key(@Nullable final Project project, @NotNull final Class requestor) throws PasswordSafeException {
Application application = ApplicationManager.getApplication();
if (!isTestMode() && application.isHeadlessEnvironment()) {
throw new MasterPasswordUnavailableException("The provider is not available in headless environment");
@@ -200,7 +199,7 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
}
}
}
- }, modalityState == null ? ModalityState.defaultModalityState() : modalityState);
+ }, ModalityState.any());
//noinspection ThrowableResultOfMethodCallIgnored
if (ex.get() != null) {
throw ex.get();
@@ -211,12 +210,11 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
}
@Override
- public String getPassword(@Nullable Project project, @NotNull Class requestor, String key,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
+ public String getPassword(@Nullable Project project, @NotNull Class requestor, String key) throws PasswordSafeException {
if (database.isEmpty()) {
return null;
}
- return super.getPassword(project, requestor, key, modalityState);
+ return super.getPassword(project, requestor, key);
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java
index da82bb986fdb..4989789b4ec0 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/memory/MemoryPasswordSafe.java
@@ -19,12 +19,10 @@ import com.intellij.ide.passwordSafe.impl.PasswordSafeTimed;
import com.intellij.ide.passwordSafe.impl.providers.BasePasswordSafeProvider;
import com.intellij.ide.passwordSafe.impl.providers.ByteArrayWrapper;
import com.intellij.ide.passwordSafe.impl.providers.EncryptionUtil;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.security.SecureRandom;
import java.util.Collections;
@@ -60,7 +58,7 @@ public class MemoryPasswordSafe extends BasePasswordSafeProvider {
}
@Override
- protected byte[] key(Project project, @NotNull Class requestor, @Nullable ModalityState modalityState) {
+ protected byte[] key(Project project, @NotNull Class requestor) {
if (key.get() == null) {
byte[] rnd = new byte[EncryptionUtil.SECRET_KEY_SIZE_BYTES * 16];
new SecureRandom().nextBytes(rnd);
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java
index e3a77325b06e..4bf024d697c2 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/nil/NilProvider.java
@@ -17,7 +17,6 @@ package com.intellij.ide.passwordSafe.impl.providers.nil;
import com.intellij.ide.passwordSafe.PasswordSafeException;
import com.intellij.ide.passwordSafe.impl.PasswordSafeProvider;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,22 +41,16 @@ public final class NilProvider extends PasswordSafeProvider {
return "Do not Store";
}
- @Nullable
- public String getPassword(@Nullable Project project, @NotNull Class requester, String key,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
+ public String getPassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException {
// nothing is stored
return null;
}
- @Override
- public void removePassword(@Nullable Project project, @NotNull Class requester, String key,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
+ public void removePassword(@Nullable Project project, @NotNull Class requester, String key) throws PasswordSafeException {
// do nothing
}
- @Override
- public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value,
- @Nullable ModalityState modalityState) throws PasswordSafeException {
+ public void storePassword(@Nullable Project project, @NotNull Class requester, String key, String value) throws PasswordSafeException {
// just forget about password
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java b/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java
index 353e836f3f33..8aa0099ccd1d 100644
--- a/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/passwordSafe/ui/PasswordSafePromptDialog.java
@@ -73,10 +73,7 @@ public class PasswordSafePromptDialog extends DialogWrapper {
/**
* Ask password possibly asking password database first. The method could be invoked from any thread. If UI needs to be shown,
* the method invokes {@link UIUtil#invokeAndWaitIfNeeded(Runnable)}
- *
* @param project the context project
- * @param modalityState the modality state using which any prompts initiated by the git process should be shown in the UI.
- * If null then {@link ModalityState#defaultModalityState() the default modality state} will be used.
* @param title the dialog title
* @param message the message describing a resource for which password is asked
* @param requestor the password requestor
@@ -86,13 +83,12 @@ public class PasswordSafePromptDialog extends DialogWrapper {
*/
@Nullable
public static String askPassword(final Project project,
- @Nullable ModalityState modalityState,
final String title,
final String message,
@NotNull final Class<?> requestor,
final String key,
boolean resetPassword, String error) {
- return askPassword(project, modalityState, title, message, requestor, key, resetPassword, error, null, null);
+ return askPassword(project, title, message, requestor, key, resetPassword, error, null, null);
}
/**
@@ -112,17 +108,14 @@ public class PasswordSafePromptDialog extends DialogWrapper {
@NotNull final Class<?> requestor,
final String key,
boolean resetPassword) {
- return askPassword(null, null, title, message, requestor, key, resetPassword, null);
+ return askPassword(null, title, message, requestor, key, resetPassword, null);
}
/**
* Ask passphrase possibly asking password database first. The method could be invoked from any thread. If UI needs to be shown,
* the method invokes {@link UIUtil#invokeAndWaitIfNeeded(Runnable)}
- *
* @param project the context project (might be null)
- * @param modalityState the modality state using which any prompts initiated by the git process should be shown in the UI.
- * If null then {@link ModalityState#defaultModalityState() the default modality state} will be used.
* @param title the dialog title
* @param message the message describing a resource for which password is asked
* @param requestor the password requestor
@@ -132,13 +125,13 @@ public class PasswordSafePromptDialog extends DialogWrapper {
*/
@Nullable
public static String askPassphrase(final Project project,
- @Nullable ModalityState modalityState, final String title,
+ final String title,
final String message,
@NotNull final Class<?> requestor,
final String key,
boolean resetPassword,
String error) {
- return askPassword(project, modalityState, title, message, requestor, key, resetPassword, error,
+ return askPassword(project, title, message, requestor, key, resetPassword, error,
"Passphrase:", "Remember the passphrase");
}
@@ -146,10 +139,7 @@ public class PasswordSafePromptDialog extends DialogWrapper {
/**
* Ask password possibly asking password database first. The method could be invoked from any thread. If UI needs to be shown,
* the method invokes {@link UIUtil#invokeAndWaitIfNeeded(Runnable)}
- *
* @param project the context project
- * @param modalityState the modality state using which any prompts initiated by the git process should be shown in the UI.
- * If null then {@link ModalityState#defaultModalityState() the default modality state} will be used.
* @param title the dialog title
* @param message the message describing a resource for which password is asked
* @param requestor the password requestor
@@ -161,7 +151,6 @@ public class PasswordSafePromptDialog extends DialogWrapper {
*/
@Nullable
private static String askPassword(final Project project,
- @Nullable ModalityState modalityState,
final String title,
final String message,
@NotNull final Class<?> requestor,
@@ -176,7 +165,7 @@ public class PasswordSafePromptDialog extends DialogWrapper {
ps.removePassword(project, requestor, key);
}
else {
- String pw = ps.getPassword(project, requestor, key, modalityState);
+ String pw = ps.getPassword(project, requestor, key);
if (pw != null) {
return pw;
}
@@ -214,7 +203,7 @@ public class PasswordSafePromptDialog extends DialogWrapper {
}
}
}
- }, modalityState == null ? ModalityState.defaultModalityState() : modalityState);
+ }, ModalityState.any());
return ref.get();
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java
index 20a41e3a886a..931458ff8bc0 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java
@@ -161,7 +161,7 @@ public abstract class PluginManagerMain implements Disposable {
g.fillRect(0,0, getWidth(), getHeight());
}
};
- header.setBorder(new CustomLineBorder(UIUtil.getBorderColor(), 1, 1, 0, 1));
+ header.setBorder(new CustomLineBorder(1, 1, 0, 1));
final JLabel mySortLabel = new JLabel();
mySortLabel.setForeground(UIUtil.getLabelDisabledForeground());
mySortLabel.setBorder(new EmptyBorder(1, 1, 1, 5));
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java
index be7aa3c8f600..ec763a8d5a76 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java
@@ -68,6 +68,8 @@ public class RepositoryHelper {
HttpConfigurable.getInstance().openHttpConnection(url) :
(HttpURLConnection)new URL(url).openConnection();
connection.setRequestProperty("Accept-Encoding", "gzip");
+ connection.setReadTimeout(HttpConfigurable.CONNECTION_TIMEOUT);
+ connection.setConnectTimeout(HttpConfigurable.CONNECTION_TIMEOUT);
if (indicator != null) {
indicator.setText2(IdeBundle.message("progress.waiting.for.reply.from.plugin.manager", appInfo.getPluginManagerUrl()));
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
index 19d924dff777..1036307e97d7 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java
@@ -46,6 +46,7 @@ import com.intellij.ui.JBColor;
import com.intellij.ui.ScreenUtil;
import com.intellij.ui.content.Content;
import com.intellij.ui.mac.MacPopupMenuUI;
+import com.intellij.ui.popup.OurHeavyWeightPopup;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.ObjectUtils;
import com.intellij.util.PlatformUtils;
@@ -853,6 +854,9 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
final Point point = fixPopupLocation(contents, x, y);
final int popupType = UIUtil.isUnderGTKLookAndFeel() ? WEIGHT_HEAVY : PopupUtil.getPopupType(this);
+ if (popupType == WEIGHT_HEAVY && OurHeavyWeightPopup.isEnabled()) {
+ return new OurHeavyWeightPopup(owner, contents, point.x, point.y);
+ }
if (popupType >= 0) {
PopupUtil.setPopupType(myDelegate, popupType);
}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java
index a86a28a375d5..b06cd21daa60 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java
@@ -79,7 +79,7 @@ public class DarculaLaf extends BasicLookAndFeel {
@SuppressWarnings("UnusedParameters")
private static void log(Exception e) {
// everything is gonna be alright
- e.printStackTrace();
+// e.printStackTrace();
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties
index 255d356d5bc0..5ddd24560338 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties
@@ -48,6 +48,13 @@ MenuBar.shadow=3c3f41
MenuBar.darcula.borderColor=555555
MenuBar.darcula.borderShadowColor=282828
+CheckBoxMenuItemUI=com.intellij.ide.ui.laf.darcula.ui.DarculaCheckBoxMenuItemUI
+CheckBoxMenuItem.borderPainted=false
+
+RadioButtonMenuItemUI=com.intellij.ide.ui.laf.darcula.ui.DarculaRadioButtonMenuItemUI
+RadioButtonMenuItem.borderPainted=false
+
+
TabbedPaneUI=com.intellij.ide.ui.laf.darcula.ui.DarculaTabbedPaneUI
TabbedPane.tabInsets=0,4,0,4
TabbedPane.highlight=292b2d
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxMenuItemUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxMenuItemUI.java
new file mode 100644
index 000000000000..d9c4ac7895e6
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxMenuItemUI.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.ui.laf.darcula.ui;
+
+import com.intellij.openapi.ui.GraphicsConfig;
+import com.intellij.ui.Gray;
+import com.intellij.util.ui.UIUtil;
+import sun.swing.MenuItemLayoutHelper;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+import java.awt.*;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class DarculaCheckBoxMenuItemUI extends DarculaMenuItemUIBase {
+
+ @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
+ public static ComponentUI createUI(JComponent c) {
+ return new DarculaCheckBoxMenuItemUI();
+ }
+
+ protected String getPropertyPrefix() {
+ return "CheckBoxMenuItem";
+ }
+
+ @Override
+ public Dimension getPreferredSize(JComponent c) {
+ return super.getPreferredSize(c);
+ }
+
+ @Override
+ protected void paintCheckIcon(Graphics g2, MenuItemLayoutHelper lh, MenuItemLayoutHelper.LayoutResult lr, Color holdc, Color foreground) {
+ Graphics2D g = (Graphics2D) g2;
+ final GraphicsConfig config = new GraphicsConfig(g);
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
+
+ g.translate(lr.getCheckRect().x-2, lr.getCheckRect().y);
+
+ final int sz = 13;
+ g.setPaint(new GradientPaint(sz / 2, 1, Gray._110, sz / 2, sz, Gray._95));
+ g.fillRoundRect(0, 0, sz, sz - 1 , 4, 4);
+
+ g.setPaint(new GradientPaint(sz / 2, 1, Gray._120.withAlpha(0x5a), sz / 2, sz, Gray._105.withAlpha(90)));
+ g.drawRoundRect(0, (UIUtil.isUnderDarcula() ? 1 : 0), sz, sz - 1, 4, 4);
+
+ g.setPaint(Gray._40.withAlpha(180));
+ g.drawRoundRect(0, 0, sz, sz - 1, 4, 4);
+
+
+ if (lh.getMenuItem().isSelected()) {
+ g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+ g.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+ g.setPaint(Gray._30);
+ g.drawLine(4, 7, 7, 10);
+ g.drawLine(7, 10, sz, 2);
+ g.setPaint(Gray._170);
+ g.drawLine(4, 5, 7, 8);
+ g.drawLine(7, 8, sz, 0);
+ }
+
+ g.translate(-lr.getCheckRect().x+2, -lr.getCheckRect().y);
+ config.restore();
+ g.setColor(foreground);
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaMenuItemUIBase.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaMenuItemUIBase.java
new file mode 100644
index 000000000000..cc69d24b6ca3
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaMenuItemUIBase.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.ui.laf.darcula.ui;
+
+import sun.swing.MenuItemLayoutHelper;
+import sun.swing.SwingUtilities2;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.basic.BasicMenuItemUI;
+import java.awt.*;
+import java.awt.event.MouseEvent;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class DarculaMenuItemUIBase extends BasicMenuItemUI {
+ @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
+ public static ComponentUI createUI(JComponent c) {
+ return new DarculaMenuItemUIBase();
+ }
+
+ public void processMouseEvent(JMenuItem item, MouseEvent e, MenuElement path[], MenuSelectionManager manager) {
+ Point p = e.getPoint();
+ if (p.x >= 0 && p.x < item.getWidth() &&
+ p.y >= 0 && p.y < item.getHeight()) {
+ if (e.getID() == MouseEvent.MOUSE_RELEASED) {
+ manager.clearSelectedPath();
+ item.doClick(0);
+ item.setArmed(false);
+ } else
+ manager.setSelectedPath(path);
+ } else if (item.getModel().isArmed()) {
+ MenuElement newPath[] = new MenuElement[path.length - 1];
+ int i, c;
+ for (i = 0, c = path.length - 1; i < c; i++)
+ newPath[i] = path[i];
+ manager.setSelectedPath(newPath);
+ }
+ }
+
+ protected void paintMenuItem(Graphics g, JComponent c,
+ Icon checkIcon, Icon arrowIcon,
+ Color background, Color foreground,
+ int defaultTextIconGap) {
+ // Save original graphics font and color
+ Font holdf = g.getFont();
+ Color holdc = g.getColor();
+
+ JMenuItem mi = (JMenuItem) c;
+ g.setFont(mi.getFont());
+
+ Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight());
+ applyInsets(viewRect, mi.getInsets());
+
+ MenuItemLayoutHelper lh = new MenuItemLayoutHelper(mi, checkIcon,
+ arrowIcon, viewRect, defaultTextIconGap, "-", //todo[kb] use protected field BasicMenuItemUI.acceleratorDelimiter when we move to java 1.7
+ mi.getComponentOrientation().isLeftToRight(), mi.getFont(),
+ acceleratorFont, MenuItemLayoutHelper.useCheckAndArrow(menuItem),
+ getPropertyPrefix());
+ MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem();
+
+ paintBackground(g, mi, background);
+ paintCheckIcon(g, lh, lr, holdc, foreground);
+ paintIcon(g, lh, lr, holdc);
+ g.setColor(foreground);
+ paintText(g, lh, lr);
+ paintAccText(g, lh, lr);
+ paintArrowIcon(g, lh, lr, foreground);
+
+ // Restore original graphics font and color
+ g.setColor(holdc);
+ g.setFont(holdf);
+ }
+
+ protected void paintIcon(Graphics g, MenuItemLayoutHelper lh,
+ MenuItemLayoutHelper.LayoutResult lr, Color holdc) {
+ if (lh.getIcon() != null) {
+ Icon icon;
+ ButtonModel model = lh.getMenuItem().getModel();
+ if (!model.isEnabled()) {
+ icon = lh.getMenuItem().getDisabledIcon();
+ } else if (model.isPressed() && model.isArmed()) {
+ icon = lh.getMenuItem().getPressedIcon();
+ if (icon == null) {
+ // Use default icon
+ icon = lh.getMenuItem().getIcon();
+ }
+ } else {
+ icon = lh.getMenuItem().getIcon();
+ }
+
+ if (icon != null) {
+ icon.paintIcon(lh.getMenuItem(), g, lr.getIconRect().x,
+ lr.getIconRect().y);
+ g.setColor(holdc);
+ }
+ }
+ }
+
+ protected void paintCheckIcon(Graphics g, MenuItemLayoutHelper lh,
+ MenuItemLayoutHelper.LayoutResult lr,
+ Color holdc, Color foreground) {
+ if (lh.getCheckIcon() != null) {
+ ButtonModel model = lh.getMenuItem().getModel();
+ if (model.isArmed() || (lh.getMenuItem() instanceof JMenu
+ && model.isSelected())) {
+ g.setColor(foreground);
+ } else {
+ g.setColor(holdc);
+ }
+ if (lh.useCheckAndArrow()) {
+ lh.getCheckIcon().paintIcon(lh.getMenuItem(), g,
+ lr.getCheckRect().x, lr.getCheckRect().y);
+ }
+ g.setColor(holdc);
+ }
+ }
+
+ protected void paintAccText(Graphics g, MenuItemLayoutHelper lh,
+ MenuItemLayoutHelper.LayoutResult lr) {
+ if (!lh.getAccText().equals("")) {
+ ButtonModel model = lh.getMenuItem().getModel();
+ g.setFont(lh.getAccFontMetrics().getFont());
+ if (!model.isEnabled()) {
+ // *** paint the accText disabled
+ if (disabledForeground != null) {
+ g.setColor(disabledForeground);
+ SwingUtilities2.drawString(lh.getMenuItem(), g,
+ lh.getAccText(), lr.getAccRect().x,
+ lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
+ } else {
+ g.setColor(lh.getMenuItem().getBackground().brighter());
+ SwingUtilities2.drawString(lh.getMenuItem(), g,
+ lh.getAccText(), lr.getAccRect().x,
+ lr.getAccRect().y + lh.getAccFontMetrics().getAscent());
+ g.setColor(lh.getMenuItem().getBackground().darker());
+ SwingUtilities2.drawString(lh.getMenuItem(), g,
+ lh.getAccText(), lr.getAccRect().x - 1,
+ lr.getAccRect().y + lh.getFontMetrics().getAscent() - 1);
+ }
+ } else {
+ // *** paint the accText normally
+ if (model.isArmed()
+ || (lh.getMenuItem() instanceof JMenu
+ && model.isSelected())) {
+ g.setColor(acceleratorSelectionForeground);
+ } else {
+ g.setColor(acceleratorForeground);
+ }
+ SwingUtilities2.drawString(lh.getMenuItem(), g, lh.getAccText(),
+ lr.getAccRect().x, lr.getAccRect().y +
+ lh.getAccFontMetrics().getAscent());
+ }
+ }
+ }
+
+ protected void paintText(Graphics g, MenuItemLayoutHelper lh,
+ MenuItemLayoutHelper.LayoutResult lr) {
+ if (!lh.getText().equals("")) {
+ if (lh.getHtmlView() != null) {
+ // Text is HTML
+ lh.getHtmlView().paint(g, lr.getTextRect());
+ } else {
+ // Text isn't HTML
+ paintText(g, lh.getMenuItem(), lr.getTextRect(), lh.getText());
+ }
+ }
+ }
+
+ protected void paintArrowIcon(Graphics g, MenuItemLayoutHelper lh,
+ MenuItemLayoutHelper.LayoutResult lr,
+ Color foreground) {
+ if (lh.getArrowIcon() != null) {
+ ButtonModel model = lh.getMenuItem().getModel();
+ if (model.isArmed() || (lh.getMenuItem() instanceof JMenu
+ && model.isSelected())) {
+ g.setColor(foreground);
+ }
+ if (lh.useCheckAndArrow()) {
+ lh.getArrowIcon().paintIcon(lh.getMenuItem(), g,
+ lr.getArrowRect().x, lr.getArrowRect().y);
+ }
+ }
+ }
+
+ protected void applyInsets(Rectangle rect, Insets insets) {
+ if(insets != null) {
+ rect.x += insets.left;
+ rect.y += insets.top;
+ rect.width -= (insets.right + rect.x);
+ rect.height -= (insets.bottom + rect.y);
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonMenuItemUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonMenuItemUI.java
new file mode 100644
index 000000000000..1048e5d0449b
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonMenuItemUI.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.ui.laf.darcula.ui;
+
+import com.intellij.openapi.ui.GraphicsConfig;
+import com.intellij.ui.ColorUtil;
+import com.intellij.ui.Gray;
+import sun.swing.MenuItemLayoutHelper;
+
+import javax.swing.*;
+import javax.swing.plaf.ComponentUI;
+import java.awt.*;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class DarculaRadioButtonMenuItemUI extends DarculaMenuItemUIBase {
+ @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
+ public static ComponentUI createUI(JComponent c) {
+ return new DarculaRadioButtonMenuItemUI();
+ }
+
+ protected String getPropertyPrefix() {
+ return "RadioButtonMenuItem";
+ }
+
+ @Override
+ protected void paintCheckIcon(Graphics g2, MenuItemLayoutHelper lh, MenuItemLayoutHelper.LayoutResult lr, Color holdc, Color foreground) {
+ Graphics2D g = (Graphics2D) g2;
+ final GraphicsConfig config = new GraphicsConfig(g);
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
+
+ g.translate(lr.getCheckRect().x-1, lr.getCheckRect().y-1);
+
+ int rad = 5;
+
+ final int x = 0;
+ final int y = 0;
+ final int w = 13;
+ final int h = 13;
+
+ g.translate(x, y);
+
+ //setup AA for lines
+ Color bg = lh.getMenuItem().getBackground();
+ g.setPaint(new GradientPaint(0, 0, ColorUtil.shift(bg, 1.5),
+ 0, 16, ColorUtil.shift(bg, 1.2)));
+
+ g.fillOval(0, 1, w - 1, h - 1);
+
+ g.setPaint(new GradientPaint(w / 2, 1, Gray._160.withAlpha(90), w / 2, h, Gray._100.withAlpha(90)));
+ g.drawOval(0, 2, w - 1, h - 1);
+
+ g.setPaint(Gray._40.withAlpha(200));
+ g.drawOval(0, 1, w - 1, h - 1);
+
+ if (lh.getMenuItem().isSelected()) {
+ final boolean enabled = lh.getMenuItem().isEnabled();
+ g.setColor(UIManager.getColor(enabled ? "RadioButton.darcula.selectionEnabledShadowColor" : "RadioButton.darcula.selectionDisabledShadowColor"));
+ g.fillOval((w - rad)/2 , h/2 , rad, rad);
+ g.setColor(UIManager.getColor(enabled ? "RadioButton.darcula.selectionEnabledColor" : "RadioButton.darcula.selectionDisabledColor"));
+ g.fillOval((w - rad)/2 , h/2 - 1, rad, rad);
+ }
+ config.restore();
+ g.translate(-x, -y);
+
+
+ g.translate(-lr.getCheckRect().x+1, -lr.getCheckRect().y+1);
+ config.restore();
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java b/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java
index 2b8a8a499621..fcbe27f5c4a5 100644
--- a/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java
+++ b/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java
@@ -15,383 +15,89 @@
*/
package com.intellij.ide.util;
-import com.intellij.ui.*;
-import com.intellij.ui.table.JBTable;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.ui.ComponentWithEmptyText;
-import com.intellij.util.ui.StatusText;
-import com.intellij.util.ui.Table;
-import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
-import javax.swing.event.ListSelectionListener;
-import javax.swing.table.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.util.*;
+import javax.swing.table.TableCellRenderer;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
/**
* @see ChooseElementsDialog
*/
-public class ElementsChooser<T> extends JPanel implements ComponentWithEmptyText, ComponentWithExpandableItems<TableCell> {
- private JBTable myTable = null;
- private MyTableModel myTableModel = null;
- private boolean myColorUnmarkedElements = true;
- private final List<ElementsMarkListener<T>> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
- private final Map<T,ElementProperties> myElementToPropertiesMap = new HashMap<T, ElementProperties>();
- private final Map<T, Boolean> myDisabledMap = new HashMap<T, Boolean>();
+public class ElementsChooser<T> extends MultiStateElementsChooser<T, Boolean> {
+ private static final BooleanMarkStateDescriptor MARK_STATE_DESCRIPTOR = new BooleanMarkStateDescriptor();
public interface ElementsMarkListener<T> {
void elementMarkChanged(T element, boolean isMarked);
}
public ElementsChooser(final boolean elementsCanBeMarked) {
- this(null, false, elementsCanBeMarked);
+ super(elementsCanBeMarked, ElementsChooser.<T>getMarkStateDescriptor());
}
public ElementsChooser(List<T> elements, boolean marked) {
- this(elements, marked, true);
- }
-
- private ElementsChooser(@Nullable List<T> elements, boolean marked, boolean elementsCanBeMarked) {
- super(new BorderLayout());
-
- myTableModel = new MyTableModel(elementsCanBeMarked);
- myTable = new Table(myTableModel);
- myTable.setShowGrid(false);
- myTable.setIntercellSpacing(new Dimension(0, 0));
- myTable.setTableHeader(null);
- myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
- myTable.setColumnSelectionAllowed(false);
- JScrollPane pane = ScrollPaneFactory.createScrollPane(myTable);
- pane.setPreferredSize(new Dimension(100, 155));
- TableColumnModel columnModel = myTable.getColumnModel();
-
- if (elementsCanBeMarked) {
- TableColumn checkMarkColumn = columnModel.getColumn(myTableModel.CHECK_MARK_COLUM_INDEX);
- TableUtil.setupCheckboxColumn(checkMarkColumn);
- checkMarkColumn.setCellRenderer(new CheckMarkColumnCellRenderer(myTable.getDefaultRenderer(Boolean.class)));
- }
- columnModel.getColumn(myTableModel.ELEMENT_COLUMN_INDEX).setCellRenderer(new MyElementColumnCellRenderer());
-
- add(pane, BorderLayout.CENTER);
- myTable.registerKeyboardAction(
- new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- final int[] selectedRows = myTable.getSelectedRows();
- boolean currentlyMarked = true;
- for (int selectedRow : selectedRows) {
- currentlyMarked = myTableModel.isElementMarked(selectedRow);
- if (!currentlyMarked) {
- break;
- }
- }
- myTableModel.setMarked(selectedRows, !currentlyMarked);
- }
- },
- KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0),
- JComponent.WHEN_FOCUSED
- );
-
- final SpeedSearchBase<JBTable> speedSearch = new SpeedSearchBase<JBTable>(myTable) {
- @Override
- public int getSelectedIndex() {
- return myTable.getSelectedRow();
- }
-
- @Override
- protected int convertIndexToModel(int viewIndex) {
- return myTable.convertRowIndexToModel(viewIndex);
- }
-
- @Override
- public Object[] getAllElements() {
- final int count = myTableModel.getRowCount();
- Object[] elements = new Object[count];
- for (int idx = 0; idx < count; idx++) {
- elements[idx] = myTableModel.getElementAt(idx);
- }
- return elements;
- }
-
- @Override
- public String getElementText(Object element) {
- return getItemText((T)element);
- }
-
- @Override
- public void selectElement(Object element, String selectedText) {
- final int count = myTableModel.getRowCount();
- for (int row = 0; row < count; row++) {
- if (element.equals(myTableModel.getElementAt(row))) {
- final int viewRow = myTable.convertRowIndexToView(row);
- myTable.getSelectionModel().setSelectionInterval(viewRow, viewRow);
- TableUtil.scrollSelectionToVisible(myTable);
- break;
- }
- }
- }
- };
- speedSearch.setComparator(new SpeedSearchComparator(false));
- setElements(elements, marked);
- installActions(myTable);
- }
-
- private static void installActions(JTable table) {
- InputMap inputMap = table.getInputMap(WHEN_FOCUSED);
- inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, 0), "selectLastRow");
- inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0), "selectFirstRow");
- inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, InputEvent.SHIFT_DOWN_MASK), "selectFirstRowExtendSelection");
- inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, InputEvent.SHIFT_DOWN_MASK), "selectLastRowExtendSelection");
- }
-
- @NotNull
- @Override
- public StatusText getEmptyText() {
- return myTable.getEmptyText();
- }
-
- @NotNull
- @Override
- public ExpandableItemsHandler<TableCell> getExpandableItemsHandler() {
- return myTable.getExpandableItemsHandler();
- }
-
- @Override
- public void setExpandableItemsEnabled(boolean enabled) {
- myTable.setExpandableItemsEnabled(enabled);
- }
-
- public void setSingleSelectionMode() {
- myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- }
-
- public void refresh() {
- myTableModel.fireTableDataChanged();
- }
-
- public void refresh(T element) {
- final int row = myTableModel.getElementRow(element);
- if (row >= 0) {
- myTableModel.fireTableRowsUpdated(row, row);
- }
- }
-
- private int[] mySavedSelection = null;
- public void saveSelection() {
- mySavedSelection = myTable.getSelectedRows();
- }
-
- public void restoreSelection() {
- if (mySavedSelection != null) {
- TableUtil.selectRows(myTable, mySavedSelection);
- mySavedSelection = null;
- }
- }
-
- public boolean isColorUnmarkedElements() {
- return myColorUnmarkedElements;
- }
-
- public void setColorUnmarkedElements(boolean colorUnmarkedElements) {
- myColorUnmarkedElements = colorUnmarkedElements;
+ super(elements, marked, ElementsChooser.<T>getMarkStateDescriptor());
}
public void addElementsMarkListener(ElementsMarkListener<T> listener) {
- myListeners.add(listener);
+ addElementsMarkListener(new ElementsMarkStateListenerAdapter<T>(listener));
}
public void removeElementsMarkListener(ElementsMarkListener<T> listener) {
- myListeners.remove(listener);
- }
-
- public void addListSelectionListener(ListSelectionListener listener) {
- myTable.getSelectionModel().addListSelectionListener(listener);
- }
- public void removeListSelectionListener(ListSelectionListener listener) {
- myTable.getSelectionModel().removeListSelectionListener(listener);
+ removeElementsMarkListener(new ElementsMarkStateListenerAdapter<T>(listener));
}
public void addElement(T element, final boolean isMarked) {
- addElement(element, isMarked, element instanceof ElementProperties ? (ElementProperties)element : null);
+ addElement(element, getMarkState(isMarked));
}
/**
* Check if element is marked
+ *
* @param element an element to test
* @return true if element is marked
*/
public boolean isElementMarked(T element) {
- final int elementRow = myTableModel.getElementRow(element);
- return myTableModel.isElementMarked(elementRow);
+ return getElementMarkState(element);
}
/**
- * Check if element is marked
+ * Update element mark
+ *
* @param element an element to test
- * @param marked a new value of mark.
+ * @param marked a new value of mark.
*/
public void setElementMarked(T element, boolean marked) {
- final int elementRow = myTableModel.getElementRow(element);
- myTableModel.setMarked(elementRow, marked);
- }
-
-
- public void removeElement(T element) {
- final int elementRow = myTableModel.getElementRow(element);
- if (elementRow < 0) {
- return; // no such element
- }
- final boolean wasSelected = myTable.getSelectionModel().isSelectedIndex(elementRow);
-
- myTableModel.removeElement(element);
- myElementToPropertiesMap.remove(element);
-
- if (wasSelected) {
- final int rowCount = myTableModel.getRowCount();
- if (rowCount > 0) {
- selectRow(elementRow % rowCount);
- }
- else {
- myTable.getSelectionModel().clearSelection();
- }
- }
- myTable.requestFocus();
+ setElementMarkState(element, getMarkState(marked));
}
- public void removeAllElements() {
- myTableModel.removeAllElements();
- myTable.getSelectionModel().clearSelection();
- }
-
- private void selectRow(final int row) {
- myTable.getSelectionModel().setSelectionInterval(row, row);
- myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
- }
-
- public void moveElement(T element, int newRow) {
- final int elementRow = myTableModel.getElementRow(element);
- if (elementRow < 0 || elementRow == newRow || newRow < 0 || newRow >= myTableModel.getRowCount()) {
- return;
- }
- final boolean wasSelected = myTable.getSelectionModel().isSelectedIndex(elementRow);
- myTableModel.changeElementRow(element, newRow);
- if (wasSelected) {
- selectRow(newRow);
- }
- }
-
- public interface ElementProperties {
- @Nullable
- Icon getIcon();
- @Nullable
- Color getColor();
- }
public void addElement(T element, final boolean isMarked, ElementProperties elementProperties) {
- myTableModel.addElement(element, isMarked);
- myElementToPropertiesMap.put(element, elementProperties);
- selectRow(myTableModel.getRowCount() - 1);
- myTable.requestFocus();
- }
-
- public void setElementProperties(T element, ElementProperties properties) {
- myElementToPropertiesMap.put(element, properties);
+ addElement(element, getMarkState(isMarked), elementProperties);
}
public void setElements(List<T> elements, boolean marked) {
- myTableModel.clear();
- myTableModel.addElements(elements, marked);
- }
-
- @Nullable
- public T getSelectedElement() {
- final int selectedRow = getSelectedElementRow();
- return selectedRow < 0? null : myTableModel.getElementAt(selectedRow);
- }
-
- public int getSelectedElementRow() {
- return myTable.getSelectedRow();
- }
-
- @NotNull
- public List<T> getSelectedElements() {
- final List<T> elements = new ArrayList<T>();
- final int[] selectedRows = myTable.getSelectedRows();
- for (int selectedRow : selectedRows) {
- if (selectedRow < 0) {
- continue;
- }
- elements.add(myTableModel.getElementAt(selectedRow));
- }
- return elements;
- }
-
- public void selectElements(Collection<? extends T> elements) {
- if (elements.isEmpty()) {
- myTable.clearSelection();
- return;
- }
- final int[] rows = getElementsRows(elements);
- TableUtil.selectRows(myTable, rows);
- TableUtil.scrollSelectionToVisible(myTable);
- myTable.requestFocus();
- }
-
- private int[] getElementsRows(final Collection<? extends T> elements) {
- final int[] rows = new int[elements.size()];
- int index = 0;
- for (final T element : elements) {
- rows[index++] = myTable.convertRowIndexToView(myTableModel.getElementRow(element));
- }
- return rows;
+ setElements(elements, getMarkState(marked));
}
public void markElements(Collection<T> elements) {
- myTableModel.setMarked(getElementsRows(elements), true);
+ markElements(elements, Boolean.TRUE);
}
@NotNull
public List<T> getMarkedElements() {
- final int count = myTableModel.getRowCount();
+ Map<T, Boolean> elementMarkStates = getElementMarkStates();
List<T> elements = new ArrayList<T>();
- for (int idx = 0; idx < count; idx++) {
- final T element = myTableModel.getElementAt(idx);
- if (myTableModel.isElementMarked(idx)) {
- elements.add(element);
+ for (Map.Entry<T, Boolean> entry : elementMarkStates.entrySet()) {
+ if (entry.getValue()) {
+ elements.add(entry.getKey());
}
}
return elements;
}
- public void sort(Comparator<T> comparator) {
- myTableModel.sort(comparator);
- }
-
- @Override
- public void setEnabled(boolean enabled) {
- super.setEnabled(enabled);
- myTable.setRowSelectionAllowed(enabled);
- myTableModel.fireTableDataChanged();
- }
-
- public void stopEditing() {
- TableCellEditor editor = myTable.getCellEditor();
- if (editor != null) {
- editor.stopCellEditing();
- }
- }
-
- public JComponent getComponent() {
- return myTable;
- }
-
public void invertSelection() {
final int count = getElementCount();
for (int i = 0; i < count; i++) {
@@ -401,264 +107,89 @@ public class ElementsChooser<T> extends JPanel implements ComponentWithEmptyText
}
public void setAllElementsMarked(boolean marked) {
- final int[] rows = new int[myTableModel.getRowCount()];
- for (int idx = 0; idx < rows.length; idx++) {
- rows[idx] = idx;
- }
- myTableModel.setMarked(rows, marked);
- }
-
- private void notifyElementMarked(T element, boolean isMarked) {
- for (ElementsMarkListener<T> listener : myListeners) {
- listener.elementMarkChanged(element, isMarked);
- }
+ setAllElementsMarked(getMarkState(marked));
}
- public void clear() {
- myTableModel.clear();
- myElementToPropertiesMap.clear();
+ private static Boolean getMarkState(boolean marked) {
+ return marked;
}
- public int getElementCount() {
- return myTableModel.getRowCount();
+ @SuppressWarnings("unchecked")
+ private static <T> MarkStateDescriptor<T, Boolean> getMarkStateDescriptor() {
+ return MARK_STATE_DESCRIPTOR;
}
- public T getElementAt(int row) {
- return myTableModel.getElementAt(row);
- }
-
- public void disableElement(T element) {
- myDisabledMap.put(element, Boolean.TRUE);
- }
-
- private final class MyTableModel extends AbstractTableModel {
- private final List<T> myElements = new ArrayList<T>();
- private final Map<T, Boolean> myMarkedMap = new HashMap<T, Boolean>();
- public final int CHECK_MARK_COLUM_INDEX;
- public final int ELEMENT_COLUMN_INDEX;
- private final boolean myElementsCanBeMarked;
-
- public MyTableModel(final boolean elementsCanBeMarked) {
- myElementsCanBeMarked = elementsCanBeMarked;
- if (elementsCanBeMarked) {
- CHECK_MARK_COLUM_INDEX = 0;
- ELEMENT_COLUMN_INDEX = 1;
- }
- else {
- CHECK_MARK_COLUM_INDEX = -1;
- ELEMENT_COLUMN_INDEX = 0;
- }
- }
-
- public void sort(Comparator<T> comparator) {
- Collections.sort(myElements, comparator);
- fireTableDataChanged();
- }
-
- public T getElementAt(int index) {
- return myElements.get(index);
- }
-
- public boolean isElementMarked(int index) {
- final T element = myElements.get(index);
- final Boolean isMarked = myMarkedMap.get(element);
- return isMarked.booleanValue();
- }
-
- private void addElement(T element, boolean isMarked) {
- myElements.add(element);
- myMarkedMap.put(element, isMarked? Boolean.TRUE : Boolean.FALSE);
- int row = myElements.size() - 1;
- fireTableRowsInserted(row, row);
- }
-
- private void addElements(@Nullable List<T> elements, boolean isMarked) {
- if (elements == null || elements.isEmpty()) {
- return;
- }
- for (final T element : elements) {
- myElements.add(element);
- myMarkedMap.put(element, isMarked ? Boolean.TRUE : Boolean.FALSE);
- }
- fireTableRowsInserted(myElements.size() - elements.size(), myElements.size() - 1);
- }
-
- public void removeElement(T element) {
- final boolean reallyRemoved = myElements.remove(element);
- if (reallyRemoved) {
- myMarkedMap.remove(element);
- fireTableDataChanged();
- }
- }
-
- public void changeElementRow(T element, int row) {
- final boolean reallyRemoved = myElements.remove(element);
- if (reallyRemoved) {
- myElements.add(row, element);
- fireTableDataChanged();
- }
- }
-
- public int getElementRow(T element) {
- return myElements.indexOf(element);
- }
-
- public void removeAllElements() {
- myElements.clear();
- fireTableDataChanged();
- }
-
- public void removeRows(int[] rows) {
- final List<T> toRemove = new ArrayList<T>();
- for (int row : rows) {
- final T element = myElements.get(row);
- toRemove.add(element);
- myMarkedMap.remove(element);
- }
- myElements.removeAll(toRemove);
- fireTableDataChanged();
- }
-
+ private static class BooleanMarkStateDescriptor<T> implements MarkStateDescriptor<T, Boolean> {
+ @NotNull
@Override
- public int getRowCount() {
- return myElements.size();
+ public Boolean getDefaultState(@NotNull T element) {
+ return Boolean.FALSE;
}
+ @NotNull
@Override
- public int getColumnCount() {
- return myElementsCanBeMarked? 2 : 1;
+ public Boolean getNextState(@NotNull T element, @NotNull Boolean state) {
+ return !state;
}
- @Override
@Nullable
- public Object getValueAt(int rowIndex, int columnIndex) {
- T element = myElements.get(rowIndex);
- if (columnIndex == ELEMENT_COLUMN_INDEX) {
- return element;
- }
- if (columnIndex == CHECK_MARK_COLUM_INDEX) {
- return myMarkedMap.get(element);
- }
- return null;
- }
-
@Override
- public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
- if (columnIndex == CHECK_MARK_COLUM_INDEX) {
- setMarked(rowIndex, ((Boolean)aValue).booleanValue());
- }
- }
-
- private void setMarked(int rowIndex, final boolean marked) {
- final T element = myElements.get(rowIndex);
- final Boolean newValue = marked? Boolean.TRUE : Boolean.FALSE;
- final Boolean prevValue = myMarkedMap.put(element, newValue);
- fireTableRowsUpdated(rowIndex, rowIndex);
- if (!newValue.equals(prevValue)) {
- notifyElementMarked(element, marked);
- }
- }
-
- private void setMarked(int[] rows, final boolean marked) {
- if (rows == null || rows.length == 0) {
- return;
- }
- int firstRow = Integer.MAX_VALUE;
- int lastRow = Integer.MIN_VALUE;
- final Boolean newValue = marked? Boolean.TRUE : Boolean.FALSE;
- for (final int row : rows) {
- final T element = myElements.get(row);
- final Boolean prevValue = myMarkedMap.put(element, newValue);
- if (!newValue.equals(prevValue)) {
- notifyElementMarked(element, newValue.booleanValue());
+ public Boolean getNextState(@NotNull Map<T, Boolean> elementsWithStates) {
+ boolean currentlyMarked = true;
+ for (Boolean state : elementsWithStates.values()) {
+ currentlyMarked = state;
+ if (!currentlyMarked) {
+ break;
}
- firstRow = Math.min(firstRow, row);
- lastRow = Math.max(lastRow, row);
}
- fireTableRowsUpdated(firstRow, lastRow);
+ return !currentlyMarked;
}
@Override
- public Class getColumnClass(int columnIndex) {
- if (columnIndex == CHECK_MARK_COLUM_INDEX) {
- return Boolean.class;
- }
- return super.getColumnClass(columnIndex);
+ public boolean isMarked(@NotNull Boolean state) {
+ return state;
}
+ @Nullable
@Override
- public boolean isCellEditable(int rowIndex, int columnIndex) {
- if (!isEnabled() || columnIndex != CHECK_MARK_COLUM_INDEX) {
- return false;
- }
- final T o = (T)getValueAt(rowIndex, ELEMENT_COLUMN_INDEX);
- return myDisabledMap.get(o) == null;
+ public Boolean getMarkState(@Nullable Object value) {
+ return value instanceof Boolean ? ((Boolean)value) : null;
}
- public void clear() {
- myElements.clear();
- myMarkedMap.clear();
- fireTableDataChanged();
+ @Nullable
+ @Override
+ public TableCellRenderer getMarkRenderer() {
+ return null;
}
}
- protected String getItemText(@NotNull T value) {
- return value.toString();
- }
+ private static class ElementsMarkStateListenerAdapter<T> implements ElementsMarkStateListener<T, Boolean> {
+ private final ElementsMarkListener<T> myListener;
- @Nullable
- protected Icon getItemIcon(@NotNull T value) {
- return null;
- }
+ public ElementsMarkStateListenerAdapter(ElementsMarkListener<T> listener) {
+ myListener = listener;
+ }
- private class MyElementColumnCellRenderer extends DefaultTableCellRenderer {
@Override
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
- final Color color = UIUtil.getTableFocusCellBackground();
- Component component;
- T t = (T)value;
- try {
- UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, table.getSelectionBackground());
- component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
- setText(t != null ? getItemText(t) : "");
- if (component instanceof JLabel) {
- ((JLabel)component).setBorder(noFocusBorder);
- }
- }
- finally {
- UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, color);
- }
- final MyTableModel model = (MyTableModel)table.getModel();
- component.setEnabled(ElementsChooser.this.isEnabled() && (!myColorUnmarkedElements || model.isElementMarked(row)));
- final ElementProperties properties = myElementToPropertiesMap.get(t);
- if (component instanceof JLabel) {
- final Icon icon = properties != null ? properties.getIcon() : t != null ? getItemIcon(t) : null;
- JLabel label = (JLabel)component;
- label.setIcon(icon);
- label.setDisabledIcon(icon);
- }
- component.setForeground(properties != null && properties.getColor() != null ?
- properties.getColor() :
- isSelected ? table.getSelectionForeground() : table.getForeground());
- return component;
+ public void elementMarkChanged(T element, Boolean markState) {
+ myListener.elementMarkChanged(element, markState);
}
- }
- private class CheckMarkColumnCellRenderer implements TableCellRenderer {
- private final TableCellRenderer myDelegate;
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ElementsMarkStateListenerAdapter that = (ElementsMarkStateListenerAdapter)o;
- public CheckMarkColumnCellRenderer(TableCellRenderer delegate) {
- myDelegate = delegate;
+ if (!myListener.equals(that.myListener)) return false;
+
+ return true;
}
@Override
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
- Component component = myDelegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
- component.setEnabled(isEnabled());
- if (component instanceof JComponent) {
- ((JComponent)component).setBorder(null);
- }
- return component;
+ public int hashCode() {
+ return myListener.hashCode();
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/util/MultiStateElementsChooser.java b/platform/platform-impl/src/com/intellij/ide/util/MultiStateElementsChooser.java
new file mode 100644
index 000000000000..bccbd7b144ac
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/util/MultiStateElementsChooser.java
@@ -0,0 +1,692 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.util;
+
+import com.intellij.ui.*;
+import com.intellij.ui.table.JBTable;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.ComponentWithEmptyText;
+import com.intellij.util.ui.StatusText;
+import com.intellij.util.ui.Table;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.util.*;
+import java.util.List;
+
+public class MultiStateElementsChooser<T, S> extends JPanel implements ComponentWithEmptyText, ComponentWithExpandableItems<TableCell> {
+ private MarkStateDescriptor<T, S> myMarkStateDescriptor;
+ private JBTable myTable = null;
+ private MyTableModel myTableModel = null;
+ private boolean myColorUnmarkedElements = true;
+ private final List<ElementsMarkStateListener<T, S>> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private final Map<T,ElementProperties> myElementToPropertiesMap = new HashMap<T, ElementProperties>();
+ private final Map<T, Boolean> myDisabledMap = new HashMap<T, Boolean>();
+
+ public interface ElementsMarkStateListener<T, S> {
+ void elementMarkChanged(T element, S markState);
+ }
+
+ public interface MarkStateDescriptor<T, S> {
+ @NotNull
+ S getDefaultState(@NotNull T element);
+
+ @NotNull
+ S getNextState(@NotNull T element, @NotNull S state);
+
+ @Nullable
+ S getNextState(@NotNull Map<T, S> elementsWithStates);
+
+ boolean isMarked(@NotNull S state);
+
+ @Nullable
+ S getMarkState(@Nullable Object value);
+
+ @Nullable
+ TableCellRenderer getMarkRenderer();
+ }
+
+ public MultiStateElementsChooser(final boolean elementsCanBeMarked, MarkStateDescriptor<T, S> markStateDescriptor) {
+ this(null, null, elementsCanBeMarked, markStateDescriptor);
+ }
+
+ public MultiStateElementsChooser(List<T> elements, S markState, MarkStateDescriptor<T, S> markStateDescriptor) {
+ this(elements, markState, true, markStateDescriptor);
+ }
+
+ private MultiStateElementsChooser(@Nullable List<T> elements,
+ S markState,
+ boolean elementsCanBeMarked,
+ MarkStateDescriptor<T, S> markStateDescriptor) {
+ super(new BorderLayout());
+
+ myMarkStateDescriptor = markStateDescriptor;
+
+ myTableModel = new MyTableModel(elementsCanBeMarked);
+ myTable = new Table(myTableModel);
+ myTable.setShowGrid(false);
+ myTable.setIntercellSpacing(new Dimension(0, 0));
+ myTable.setTableHeader(null);
+ myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+ myTable.setColumnSelectionAllowed(false);
+ JScrollPane pane = ScrollPaneFactory.createScrollPane(myTable);
+ pane.setPreferredSize(new Dimension(100, 155));
+ TableColumnModel columnModel = myTable.getColumnModel();
+
+ if (elementsCanBeMarked) {
+ TableColumn checkMarkColumn = columnModel.getColumn(myTableModel.CHECK_MARK_COLUM_INDEX);
+ TableUtil.setupCheckboxColumn(checkMarkColumn);
+ TableCellRenderer checkMarkRenderer = myMarkStateDescriptor.getMarkRenderer();
+ if (checkMarkRenderer == null) {
+ checkMarkRenderer = new CheckMarkColumnCellRenderer(myTable.getDefaultRenderer(Boolean.class));
+ }
+ checkMarkColumn.setCellRenderer(checkMarkRenderer);
+ }
+ columnModel.getColumn(myTableModel.ELEMENT_COLUMN_INDEX).setCellRenderer(new MyElementColumnCellRenderer());
+
+ add(pane, BorderLayout.CENTER);
+ myTable.registerKeyboardAction(
+ new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ final int[] selectedRows = myTable.getSelectedRows();
+ Map<T, S> selectedElements = new LinkedHashMap<T, S>(selectedRows.length);
+ for (int selectedRow : selectedRows) {
+ selectedElements.put(myTableModel.getElementAt(selectedRow), myTableModel.getElementMarkState(selectedRow));
+ }
+ S nextState = myMarkStateDescriptor.getNextState(selectedElements);
+ if (nextState != null) {
+ myTableModel.setMarkState(selectedRows, nextState);
+ }
+ }
+ },
+ KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0),
+ JComponent.WHEN_FOCUSED
+ );
+
+ final SpeedSearchBase<JBTable> speedSearch = new SpeedSearchBase<JBTable>(myTable) {
+ @Override
+ public int getSelectedIndex() {
+ return myTable.getSelectedRow();
+ }
+
+ @Override
+ protected int convertIndexToModel(int viewIndex) {
+ return myTable.convertRowIndexToModel(viewIndex);
+ }
+
+ @Override
+ public Object[] getAllElements() {
+ final int count = myTableModel.getRowCount();
+ Object[] elements = new Object[count];
+ for (int idx = 0; idx < count; idx++) {
+ elements[idx] = myTableModel.getElementAt(idx);
+ }
+ return elements;
+ }
+
+ @Override
+ public String getElementText(Object element) {
+ return getItemText((T)element);
+ }
+
+ @Override
+ public void selectElement(Object element, String selectedText) {
+ final int count = myTableModel.getRowCount();
+ for (int row = 0; row < count; row++) {
+ if (element.equals(myTableModel.getElementAt(row))) {
+ final int viewRow = myTable.convertRowIndexToView(row);
+ myTable.getSelectionModel().setSelectionInterval(viewRow, viewRow);
+ TableUtil.scrollSelectionToVisible(myTable);
+ break;
+ }
+ }
+ }
+ };
+ speedSearch.setComparator(new SpeedSearchComparator(false));
+ setElements(elements, markState);
+ installActions(myTable);
+ }
+
+ private static void installActions(JTable table) {
+ InputMap inputMap = table.getInputMap(WHEN_FOCUSED);
+ inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, 0), "selectLastRow");
+ inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0), "selectFirstRow");
+ inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, InputEvent.SHIFT_DOWN_MASK), "selectFirstRowExtendSelection");
+ inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_END, InputEvent.SHIFT_DOWN_MASK), "selectLastRowExtendSelection");
+ }
+
+ @NotNull
+ @Override
+ public StatusText getEmptyText() {
+ return myTable.getEmptyText();
+ }
+
+ @NotNull
+ @Override
+ public ExpandableItemsHandler<TableCell> getExpandableItemsHandler() {
+ return myTable.getExpandableItemsHandler();
+ }
+
+ @Override
+ public void setExpandableItemsEnabled(boolean enabled) {
+ myTable.setExpandableItemsEnabled(enabled);
+ }
+
+ public void setSingleSelectionMode() {
+ myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ }
+
+ public void refresh() {
+ myTableModel.fireTableDataChanged();
+ }
+
+ public void refresh(T element) {
+ final int row = myTableModel.getElementRow(element);
+ if (row >= 0) {
+ myTableModel.fireTableRowsUpdated(row, row);
+ }
+ }
+
+ private int[] mySavedSelection = null;
+ public void saveSelection() {
+ mySavedSelection = myTable.getSelectedRows();
+ }
+
+ public void restoreSelection() {
+ if (mySavedSelection != null) {
+ TableUtil.selectRows(myTable, mySavedSelection);
+ mySavedSelection = null;
+ }
+ }
+
+ public boolean isColorUnmarkedElements() {
+ return myColorUnmarkedElements;
+ }
+
+ public void setColorUnmarkedElements(boolean colorUnmarkedElements) {
+ myColorUnmarkedElements = colorUnmarkedElements;
+ }
+
+ public void addElementsMarkListener(ElementsMarkStateListener<T, S> listener) {
+ myListeners.add(listener);
+ }
+
+ public void removeElementsMarkListener(ElementsMarkStateListener<T, S> listener) {
+ myListeners.remove(listener);
+ }
+
+ public void addListSelectionListener(ListSelectionListener listener) {
+ myTable.getSelectionModel().addListSelectionListener(listener);
+ }
+ public void removeListSelectionListener(ListSelectionListener listener) {
+ myTable.getSelectionModel().removeListSelectionListener(listener);
+ }
+
+ public void addElement(T element, final S markState) {
+ addElement(element, markState, element instanceof ElementProperties ? (ElementProperties)element : null);
+ }
+
+ /**
+ * Gets element mark state
+ * @param element an element to test
+ * @return state of element
+ */
+ public S getElementMarkState(T element) {
+ final int elementRow = myTableModel.getElementRow(element);
+ return myTableModel.getElementMarkState(elementRow);
+ }
+
+ /**
+ * Update element mark state
+ * @param element an element to test
+ * @param markState a new value of mark state
+ */
+ public void setElementMarkState(T element, S markState) {
+ final int elementRow = myTableModel.getElementRow(element);
+ myTableModel.setMarkState(elementRow, markState);
+ }
+
+
+ public void removeElement(T element) {
+ final int elementRow = myTableModel.getElementRow(element);
+ if (elementRow < 0) {
+ return; // no such element
+ }
+ final boolean wasSelected = myTable.getSelectionModel().isSelectedIndex(elementRow);
+
+ myTableModel.removeElement(element);
+ myElementToPropertiesMap.remove(element);
+
+ if (wasSelected) {
+ final int rowCount = myTableModel.getRowCount();
+ if (rowCount > 0) {
+ selectRow(elementRow % rowCount);
+ }
+ else {
+ myTable.getSelectionModel().clearSelection();
+ }
+ }
+ myTable.requestFocus();
+ }
+
+ public void removeAllElements() {
+ myTableModel.removeAllElements();
+ myTable.getSelectionModel().clearSelection();
+ }
+
+ private void selectRow(final int row) {
+ myTable.getSelectionModel().setSelectionInterval(row, row);
+ myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
+ }
+
+ public void moveElement(T element, int newRow) {
+ final int elementRow = myTableModel.getElementRow(element);
+ if (elementRow < 0 || elementRow == newRow || newRow < 0 || newRow >= myTableModel.getRowCount()) {
+ return;
+ }
+ final boolean wasSelected = myTable.getSelectionModel().isSelectedIndex(elementRow);
+ myTableModel.changeElementRow(element, newRow);
+ if (wasSelected) {
+ selectRow(newRow);
+ }
+ }
+
+ public interface ElementProperties {
+ @Nullable
+ Icon getIcon();
+ @Nullable
+ Color getColor();
+ }
+
+ public void addElement(T element, final S markState, ElementProperties elementProperties) {
+ myTableModel.addElement(element, markState);
+ myElementToPropertiesMap.put(element, elementProperties);
+ selectRow(myTableModel.getRowCount() - 1);
+ myTable.requestFocus();
+ }
+
+ public void setElementProperties(T element, ElementProperties properties) {
+ myElementToPropertiesMap.put(element, properties);
+ }
+
+ public void setElements(List<T> elements, S markState) {
+ myTableModel.clear();
+ myTableModel.addElements(elements, markState);
+ }
+
+ @Nullable
+ public T getSelectedElement() {
+ final int selectedRow = getSelectedElementRow();
+ return selectedRow < 0? null : myTableModel.getElementAt(selectedRow);
+ }
+
+ public int getSelectedElementRow() {
+ return myTable.getSelectedRow();
+ }
+
+ @NotNull
+ public List<T> getSelectedElements() {
+ final List<T> elements = new ArrayList<T>();
+ final int[] selectedRows = myTable.getSelectedRows();
+ for (int selectedRow : selectedRows) {
+ if (selectedRow < 0) {
+ continue;
+ }
+ elements.add(myTableModel.getElementAt(selectedRow));
+ }
+ return elements;
+ }
+
+ public void selectElements(Collection<? extends T> elements) {
+ if (elements.isEmpty()) {
+ myTable.clearSelection();
+ return;
+ }
+ final int[] rows = getElementsRows(elements);
+ TableUtil.selectRows(myTable, rows);
+ TableUtil.scrollSelectionToVisible(myTable);
+ myTable.requestFocus();
+ }
+
+ private int[] getElementsRows(final Collection<? extends T> elements) {
+ final int[] rows = new int[elements.size()];
+ int index = 0;
+ for (final T element : elements) {
+ rows[index++] = myTable.convertRowIndexToView(myTableModel.getElementRow(element));
+ }
+ return rows;
+ }
+
+ public void markElements(Collection<T> elements, S markState) {
+ myTableModel.setMarkState(getElementsRows(elements), markState);
+ }
+
+ @NotNull
+ public Map<T, S> getElementMarkStates() {
+ final int count = myTableModel.getRowCount();
+ Map<T, S> elements = new LinkedHashMap<T, S>();
+ for (int idx = 0; idx < count; idx++) {
+ final T element = myTableModel.getElementAt(idx);
+ elements.put(element, myTableModel.getElementMarkState(idx));
+ }
+ return elements;
+ }
+
+ public void sort(Comparator<T> comparator) {
+ myTableModel.sort(comparator);
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ myTable.setRowSelectionAllowed(enabled);
+ myTableModel.fireTableDataChanged();
+ }
+
+ public void stopEditing() {
+ TableCellEditor editor = myTable.getCellEditor();
+ if (editor != null) {
+ editor.stopCellEditing();
+ }
+ }
+
+ public JComponent getComponent() {
+ return myTable;
+ }
+
+ public void setAllElementsMarked(S markState) {
+ final int[] rows = new int[myTableModel.getRowCount()];
+ for (int idx = 0; idx < rows.length; idx++) {
+ rows[idx] = idx;
+ }
+ myTableModel.setMarkState(rows, markState);
+ }
+
+ private void notifyElementMarked(T element, S markState) {
+ for (ElementsMarkStateListener<T, S> listener : myListeners) {
+ listener.elementMarkChanged(element, markState);
+ }
+ }
+
+ public void clear() {
+ myTableModel.clear();
+ myElementToPropertiesMap.clear();
+ }
+
+ public int getElementCount() {
+ return myTableModel.getRowCount();
+ }
+
+ public T getElementAt(int row) {
+ return myTableModel.getElementAt(row);
+ }
+
+ public void disableElement(T element) {
+ myDisabledMap.put(element, Boolean.TRUE);
+ }
+
+ private final class MyTableModel extends AbstractTableModel {
+ private final List<T> myElements = new ArrayList<T>();
+ private final Map<T, S> myMarkedMap = new HashMap<T, S>();
+ public final int CHECK_MARK_COLUM_INDEX;
+ public final int ELEMENT_COLUMN_INDEX;
+ private final boolean myElementsCanBeMarked;
+
+ public MyTableModel(final boolean elementsCanBeMarked) {
+ myElementsCanBeMarked = elementsCanBeMarked;
+ if (elementsCanBeMarked) {
+ CHECK_MARK_COLUM_INDEX = 0;
+ ELEMENT_COLUMN_INDEX = 1;
+ }
+ else {
+ CHECK_MARK_COLUM_INDEX = -1;
+ ELEMENT_COLUMN_INDEX = 0;
+ }
+ }
+
+ public void sort(Comparator<T> comparator) {
+ Collections.sort(myElements, comparator);
+ fireTableDataChanged();
+ }
+
+ public T getElementAt(int index) {
+ return myElements.get(index);
+ }
+
+ public S getElementMarkState(int index) {
+ final T element = myElements.get(index);
+ return myMarkedMap.get(element);
+ }
+
+ private void addElement(T element, S markState) {
+ myElements.add(element);
+ myMarkedMap.put(element, notNullMarkState(element, markState));
+ int row = myElements.size() - 1;
+ fireTableRowsInserted(row, row);
+ }
+
+ private void addElements(@Nullable List<T> elements, S markState) {
+ if (elements == null || elements.isEmpty()) {
+ return;
+ }
+ for (final T element : elements) {
+ myElements.add(element);
+ myMarkedMap.put(element, notNullMarkState(element, markState));
+ }
+ fireTableRowsInserted(myElements.size() - elements.size(), myElements.size() - 1);
+ }
+
+ public void removeElement(T element) {
+ final boolean reallyRemoved = myElements.remove(element);
+ if (reallyRemoved) {
+ myMarkedMap.remove(element);
+ fireTableDataChanged();
+ }
+ }
+
+ public void changeElementRow(T element, int row) {
+ final boolean reallyRemoved = myElements.remove(element);
+ if (reallyRemoved) {
+ myElements.add(row, element);
+ fireTableDataChanged();
+ }
+ }
+
+ public int getElementRow(T element) {
+ return myElements.indexOf(element);
+ }
+
+ public void removeAllElements() {
+ myElements.clear();
+ fireTableDataChanged();
+ }
+
+ public void removeRows(int[] rows) {
+ final List<T> toRemove = new ArrayList<T>();
+ for (int row : rows) {
+ final T element = myElements.get(row);
+ toRemove.add(element);
+ myMarkedMap.remove(element);
+ }
+ myElements.removeAll(toRemove);
+ fireTableDataChanged();
+ }
+
+ @Override
+ public int getRowCount() {
+ return myElements.size();
+ }
+
+ @Override
+ public int getColumnCount() {
+ return myElementsCanBeMarked? 2 : 1;
+ }
+
+ @Override
+ @Nullable
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ T element = myElements.get(rowIndex);
+ if (columnIndex == ELEMENT_COLUMN_INDEX) {
+ return element;
+ }
+ if (columnIndex == CHECK_MARK_COLUM_INDEX) {
+ return myMarkedMap.get(element);
+ }
+ return null;
+ }
+
+ @Override
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+ if (columnIndex == CHECK_MARK_COLUM_INDEX) {
+ S nextState = myMarkStateDescriptor.getMarkState(aValue);
+ if (nextState == null) {
+ T element = myTableModel.getElementAt(rowIndex);
+ S currentState = myTableModel.getElementMarkState(rowIndex);
+ nextState = myMarkStateDescriptor.getNextState(element, currentState);
+ }
+ setMarkState(rowIndex, nextState);
+ }
+ }
+
+ private void setMarkState(int rowIndex, final S markState) {
+ final T element = myElements.get(rowIndex);
+ final S newValue = notNullMarkState(element, markState);
+ final S prevValue = myMarkedMap.put(element, newValue);
+ fireTableRowsUpdated(rowIndex, rowIndex);
+ if (!newValue.equals(prevValue)) {
+ notifyElementMarked(element, newValue);
+ }
+ }
+
+ private void setMarkState(int[] rows, final S markState) {
+ if (rows == null || rows.length == 0) {
+ return;
+ }
+ int firstRow = Integer.MAX_VALUE;
+ int lastRow = Integer.MIN_VALUE;
+ for (final int row : rows) {
+ final T element = myElements.get(row);
+ final S newValue = notNullMarkState(element, markState);
+ final S prevValue = myMarkedMap.put(element, newValue);
+ if (!newValue.equals(prevValue)) {
+ notifyElementMarked(element, newValue);
+ }
+ firstRow = Math.min(firstRow, row);
+ lastRow = Math.max(lastRow, row);
+ }
+ fireTableRowsUpdated(firstRow, lastRow);
+ }
+
+ @NotNull
+ private S notNullMarkState(T element, S markState) {
+ return markState != null ? markState : myMarkStateDescriptor.getDefaultState(element);
+ }
+
+ @Override
+ public Class getColumnClass(int columnIndex) {
+ if (columnIndex == CHECK_MARK_COLUM_INDEX) {
+ return Boolean.class;
+ }
+ return super.getColumnClass(columnIndex);
+ }
+
+ @Override
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ if (!isEnabled() || columnIndex != CHECK_MARK_COLUM_INDEX) {
+ return false;
+ }
+ final T o = (T)getValueAt(rowIndex, ELEMENT_COLUMN_INDEX);
+ return myDisabledMap.get(o) == null;
+ }
+
+ public void clear() {
+ myElements.clear();
+ myMarkedMap.clear();
+ fireTableDataChanged();
+ }
+ }
+
+ protected String getItemText(@NotNull T value) {
+ return value.toString();
+ }
+
+ @Nullable
+ protected Icon getItemIcon(@NotNull T value) {
+ return null;
+ }
+
+ private class MyElementColumnCellRenderer extends DefaultTableCellRenderer {
+ @Override
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ final Color color = UIUtil.getTableFocusCellBackground();
+ Component component;
+ T t = (T)value;
+ try {
+ UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, table.getSelectionBackground());
+ component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ setText(t != null ? getItemText(t) : "");
+ if (component instanceof JLabel) {
+ ((JLabel)component).setBorder(noFocusBorder);
+ }
+ }
+ finally {
+ UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, color);
+ }
+ final MyTableModel model = (MyTableModel)table.getModel();
+ component.setEnabled(MultiStateElementsChooser.this.isEnabled() &&
+ (!myColorUnmarkedElements || myMarkStateDescriptor.isMarked(model.getElementMarkState(row))));
+ final ElementProperties properties = myElementToPropertiesMap.get(t);
+ if (component instanceof JLabel) {
+ final Icon icon = properties != null ? properties.getIcon() : t != null ? getItemIcon(t) : null;
+ JLabel label = (JLabel)component;
+ label.setIcon(icon);
+ label.setDisabledIcon(icon);
+ }
+ component.setForeground(properties != null && properties.getColor() != null ?
+ properties.getColor() :
+ isSelected ? table.getSelectionForeground() : table.getForeground());
+ return component;
+ }
+ }
+
+ private class CheckMarkColumnCellRenderer implements TableCellRenderer {
+ private final TableCellRenderer myDelegate;
+
+ public CheckMarkColumnCellRenderer(TableCellRenderer delegate) {
+ myDelegate = delegate;
+ }
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ Component component = myDelegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ component.setEnabled(isEnabled());
+ if (component instanceof JComponent) {
+ ((JComponent)component).setBorder(null);
+ }
+ return component;
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/ideSettings/IdeSettingsStatisticsUtils.java b/platform/platform-impl/src/com/intellij/internal/statistic/ideSettings/IdeSettingsStatisticsUtils.java
index 897491532833..2873ed3a222a 100644
--- a/platform/platform-impl/src/com/intellij/internal/statistic/ideSettings/IdeSettingsStatisticsUtils.java
+++ b/platform/platform-impl/src/com/intellij/internal/statistic/ideSettings/IdeSettingsStatisticsUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,12 +21,11 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.Function;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.hash.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
@@ -60,19 +59,11 @@ public class IdeSettingsStatisticsUtils {
@Nullable
private static Object getPropertyValue(Object componentInstance, String propertyName) {
final Class<? extends Object> componentInstanceClass = componentInstance.getClass();
- Object propertyValue = null;
- try {
- Field field = componentInstanceClass.getDeclaredField(propertyName);
- propertyValue = field.get(componentInstance);
- }
- catch (NoSuchFieldException ignored) {
- }
- catch (IllegalAccessException ignored) {
- }
+ Object propertyValue = ReflectionUtil.getField(componentInstanceClass, componentInstance, null, propertyName);
if (propertyValue == null) {
- Method method = getMethod(componentInstanceClass, "get" + StringUtil.capitalize(propertyName));
+ Method method = ReflectionUtil.getMethod(componentInstanceClass, "get" + StringUtil.capitalize(propertyName));
if (method == null) {
- method = getMethod(componentInstanceClass, "is" + StringUtil.capitalize(propertyName));
+ method = ReflectionUtil.getMethod(componentInstanceClass, "is" + StringUtil.capitalize(propertyName));
}
if (method != null) {
try {
@@ -85,16 +76,6 @@ public class IdeSettingsStatisticsUtils {
return propertyValue;
}
- @Nullable
- private static Method getMethod(@NotNull Class componentInstanceClass, @NotNull String name) {
- try {
- return componentInstanceClass.getMethod(name);
- }
- catch (NoSuchMethodException ignored) {
- }
- return null;
- }
-
private static String getUsageDescriptorKey(@NotNull String providerName, @NotNull String name, @NotNull String value) {
final String shortName = StringUtil.getShortName(providerName);
return shortName + "#" + name + "(" + value + ")";
diff --git a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java
index 73af2c304beb..2d6a768a92c2 100644
--- a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java
+++ b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.ComboBoxTableRenderer;
import com.intellij.openapi.ui.StripeTable;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.TableSpeedSearch;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.ui.UIUtil;
@@ -30,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.ActionEvent;
@@ -126,6 +128,22 @@ public class NotificationsConfigurablePanel extends JPanel implements Disposable
final TableColumn idColumn = getColumnModel().getColumn(ID_COLUMN);
idColumn.setPreferredWidth(200);
+ idColumn.setCellRenderer(new DefaultTableCellRenderer() {
+ @NotNull
+ @Override
+ public Component getTableCellRendererComponent(@NotNull JTable table,
+ Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row,
+ int column) {
+ Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ if (component instanceof JComponent) {
+ ((JComponent)component).setBorder(IdeBorderFactory.createEmptyBorder(0, 4, 0, 4));
+ }
+ return component;
+ }
+ });
final TableColumn displayTypeColumn = getColumnModel().getColumn(DISPLAY_TYPE_COLUMN);
displayTypeColumn.setMaxWidth(300);
diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java
index ed40589a7d20..8120b0644675 100644
--- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java
+++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.AppUIUtil;
import com.intellij.util.PlatformUtils;
-import com.intellij.util.SystemProperties;
import com.intellij.util.ThreeState;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -423,15 +422,12 @@ public class ConfigImportHelper {
dir = dir.substring(1, dir.length() - 1);
}
if (replaceUserHome) {
- if (dir.startsWith("~\\") || dir.startsWith("~//") || StringUtil.startsWithConcatenation(dir, "~", File.separator)) {
- dir = SystemProperties.getUserHome() + dir.substring(1);
- }
+ dir = FileUtil.expandUserHome(dir);
}
return dir;
}
- public static boolean isInstallationHomeOrConfig(@NotNull final String installationHome,
- @NotNull final ConfigImportSettings settings) {
+ public static boolean isInstallationHomeOrConfig(@NotNull final String installationHome, @NotNull final ConfigImportSettings settings) {
if (new File(installationHome, OPTIONS_XML).exists()) return true;
if (new File(installationHome, CONFIG_RELATED_PATH + OPTIONS_XML).exists()) return true;
diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java
index b0d4d3f909c2..005c006d1717 100644
--- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java
+++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportSettings.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,7 @@
*/
package com.intellij.openapi.application;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.util.SystemProperties;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.ThreeState;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -74,10 +73,7 @@ public class ConfigImportSettings {
}
protected String getAutoImportLabel(File guessedOldConfig) {
- String path = guessedOldConfig.getAbsolutePath();
- if (SystemInfo.isUnix) {
- path = path.replace(SystemProperties.getUserHome(), "~");
- }
+ String path = FileUtil.getLocationRelativeToUserHome(guessedOldConfig.getAbsolutePath());
return ApplicationBundle.message("radio.import.auto", path);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java
index bf7fe9c9652f..9f43164cf9d4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java
@@ -20,7 +20,6 @@ import com.intellij.ide.DataManager;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.*;
@@ -96,11 +95,11 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap
}
public static int getGlobalUndoLimit() {
- return Registry.intValue("undo.globalUndoLimit", 10);
+ return Registry.intValue("undo.globalUndoLimit");
}
public static int getDocumentUndoLimit() {
- return Registry.intValue("undo.documentUndoLimit", 100);
+ return Registry.intValue("undo.documentUndoLimit");
}
public UndoManagerImpl(Application application, CommandProcessor commandProcessor) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/actions/CompareClipboardWithSelection.java b/platform/platform-impl/src/com/intellij/openapi/diff/actions/CompareClipboardWithSelection.java
index a916d9e5bb34..372b14efcfe6 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/actions/CompareClipboardWithSelection.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/actions/CompareClipboardWithSelection.java
@@ -73,8 +73,9 @@ public class CompareClipboardWithSelection extends BaseDiffAction {
SelectionModel selectionModel = myEditor.getSelectionModel();
if (selectionModel.hasSelection()) {
TextRange range = new TextRange(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
+ boolean forceReadOnly = myEditor.isViewer();
myContents[1] = new FragmentContent(DiffContent.fromDocument(getProject(), getDocument()),
- range, getProject(), getDocumentFile(getDocument()));
+ range, getProject(), getDocumentFile(getDocument()), forceReadOnly);
}
else {
myContents [1] = DiffContent.fromDocument(getProject(), getDocument());
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java b/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java
index 538058d2d190..ec7a316357e2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java
@@ -23,6 +23,8 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.DialogWrapperDialog;
import com.intellij.openapi.util.Disposer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.awt.*;
@@ -56,25 +58,26 @@ public class DiffPanelOptions {
myShowSourcePolicy = showSourcePolicy;
}
- public void showSource(OpenFileDescriptor descriptor) {
+ public void showSource(@Nullable OpenFileDescriptor descriptor) {
+ if (descriptor == null || myDiffPanel.getProject() == null) return;
myShowSourcePolicy.showSource(descriptor, myDiffPanel);
}
public interface ShowSourcePolicy {
- void showSource(OpenFileDescriptor descriptor, DiffPanelImpl diffPanel);
+ void showSource(@NotNull OpenFileDescriptor descriptor, @NotNull DiffPanelImpl diffPanel);
ShowSourcePolicy DONT_SHOW = new ShowSourcePolicy() {
- public void showSource(OpenFileDescriptor descriptor, DiffPanelImpl diffPanel) {}
+ public void showSource(@NotNull OpenFileDescriptor descriptor, @NotNull DiffPanelImpl diffPanel) {}
};
ShowSourcePolicy OPEN_EDITOR = new ShowSourcePolicy() {
- public void showSource(OpenFileDescriptor descriptor, DiffPanelImpl diffPanel) {
+ public void showSource(@NotNull OpenFileDescriptor descriptor, @NotNull DiffPanelImpl diffPanel) {
FileEditorManager.getInstance(diffPanel.getProject()).openTextEditor(descriptor, true);
}
};
ShowSourcePolicy OPEN_EDITOR_AND_CLOSE_DIFF = new ShowSourcePolicy() {
- public void showSource(OpenFileDescriptor descriptor, DiffPanelImpl diffPanel) {
+ public void showSource(@NotNull OpenFileDescriptor descriptor, @NotNull DiffPanelImpl diffPanel) {
OPEN_EDITOR.showSource(descriptor, diffPanel);
if (diffPanel.getOwnerWindow() == null) return;
Disposer.dispose(diffPanel);
@@ -97,7 +100,7 @@ public class DiffPanelOptions {
};
ShowSourcePolicy DEFAULT = new ShowSourcePolicy() {
- public void showSource(OpenFileDescriptor descriptor, DiffPanelImpl diffPanel) {
+ public void showSource(@NotNull OpenFileDescriptor descriptor, @NotNull DiffPanelImpl diffPanel) {
Window window = diffPanel.getOwnerWindow();
if (window == null) return;
else if (window instanceof Frame) OPEN_EDITOR.showSource(descriptor, diffPanel);
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java
index 5f169146145c..8ea3242d9361 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java
@@ -73,7 +73,6 @@ import com.intellij.util.LineSeparator;
import com.intellij.util.containers.CacheOneStepIterator;
import com.intellij.util.diff.FilesTooBigForDiffException;
import com.intellij.util.ui.PlatformColors;
-import com.intellij.util.ui.UIUtil;
import gnu.trove.TIntFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -160,8 +159,8 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
myOwnerWindow = owner;
myIsSyncScroll = true;
final boolean v = !horizontal;
- myLeftSide = new DiffSideView(this, new CustomLineBorder(UIUtil.getBorderColor(), 1, 0, v ? 0 : 1, v ? 0 : 1));
- myRightSide = new DiffSideView(this, new CustomLineBorder(UIUtil.getBorderColor(), v ? 0 : 1, v ? 0 : 1, 1, 0));
+ myLeftSide = new DiffSideView(this, new CustomLineBorder(1, 0, v ? 0 : 1, v ? 0 : 1));
+ myRightSide = new DiffSideView(this, new CustomLineBorder(v ? 0 : 1, v ? 0 : 1, 1, 0));
myLeftSide.becomeMaster();
myDiffUpdater = new Rediffers(this);
@@ -298,13 +297,11 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
myData.setContents(content1, content2);
Project project = myData.getProject();
FileType[] types = DiffUtil.chooseContentTypes(new DiffContent[]{content1, content2});
- VirtualFile baseFile = content1.getFile();
- if (baseFile == null && myDiffRequest != null) {
- String path = myDiffRequest.getWindowTitle();
- if (path != null) baseFile = LocalFileSystem.getInstance().findFileByPath(path);
- }
- myLeftSide.setHighlighterFactory(createHighlighter(types[0], baseFile, project));
- myRightSide.setHighlighterFactory(createHighlighter(types[1], baseFile, project));
+ VirtualFile beforeFile = content1.getFile();
+ VirtualFile afterFile = content2.getFile();
+ String path = myDiffRequest == null ? null : myDiffRequest.getWindowTitle();
+ myLeftSide.setHighlighterFactory(createHighlighter(types[0], beforeFile, afterFile, path, project));
+ myRightSide.setHighlighterFactory(createHighlighter(types[1], afterFile, beforeFile, path, project));
setSplitterProportion(content1, content2);
rediff();
if (myIsRequestFocus) {
@@ -344,8 +341,16 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
}
}
// todo pay attention here
- private static DiffHighlighterFactory createHighlighter(FileType contentType, VirtualFile file, Project project) {
- return new DiffHighlighterFactoryImpl(contentType, file, project);
+ private static DiffHighlighterFactory createHighlighter(FileType contentType,
+ VirtualFile file,
+ VirtualFile otherFile,
+ String path,
+ Project project) {
+ VirtualFile baseFile = file;
+ if (baseFile == null) baseFile = otherFile;
+ if (baseFile == null && path != null) baseFile = LocalFileSystem.getInstance().findFileByPath(path);
+
+ return new DiffHighlighterFactoryImpl(contentType, baseFile, project);
}
void rediff() {
@@ -607,7 +612,7 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
return myData.getProject();
}
- public void showSource(OpenFileDescriptor descriptor) {
+ public void showSource(@Nullable OpenFileDescriptor descriptor) {
myOptions.showSource(descriptor);
}
@@ -1004,10 +1009,7 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid
@Override
public void navigate(boolean requestFocus) {
- final OpenFileDescriptor descriptor = mySide.getCurrentOpenFileDescriptor();
- if (descriptor != null) {
- showSource(descriptor);
- }
+ showSource(mySide.getCurrentOpenFileDescriptor());
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSplitter.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSplitter.java
index 5f4507dcfad3..4b6a289d476e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSplitter.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffSplitter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import com.intellij.openapi.diff.impl.highlighting.DiffPanelState;
import com.intellij.openapi.diff.impl.splitter.DiffDividerPaint;
import com.intellij.openapi.editor.event.VisibleAreaEvent;
import com.intellij.openapi.editor.event.VisibleAreaListener;
+import com.intellij.openapi.ui.Divider;
import com.intellij.openapi.ui.Splitter;
import javax.swing.*;
@@ -43,8 +44,8 @@ class DiffSplitter extends Splitter implements DiffSplitterI {
setHonorComponentsMinimumSize(false);
}
- protected Splitter.Divider createDivider() {
- return new Divider(){
+ protected Divider createDivider() {
+ return new DividerImpl(){
public void paint(Graphics g) {
super.paint(g);
myPaint.paint(g, this);
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java
index 10362cc8b304..cbad541fe129 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ui/MergePanel2.java
@@ -27,9 +27,7 @@ import com.intellij.openapi.diff.*;
import com.intellij.openapi.diff.actions.NextDiffAction;
import com.intellij.openapi.diff.actions.PreviousDiffAction;
import com.intellij.openapi.diff.actions.ToggleAutoScrollAction;
-import com.intellij.openapi.diff.impl.DiffUtil;
-import com.intellij.openapi.diff.impl.EditingSides;
-import com.intellij.openapi.diff.impl.GenericDataProvider;
+import com.intellij.openapi.diff.impl.*;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.incrementalMerge.ChangeCounter;
import com.intellij.openapi.diff.impl.incrementalMerge.ChangeList;
@@ -49,16 +47,20 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.EditorMarkupModel;
+import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogBuilder;
+import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.LabeledComponent;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
-import com.intellij.util.diff.FilesTooBigForDiffException;
+import com.intellij.util.containers.Convertor;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -141,9 +143,6 @@ public class MergePanel2 implements DiffViewer {
private DiffRequest.ToolbarAddons createToolbar() {
return new DiffRequest.ToolbarAddons() {
public void customize(DiffToolbar toolbar) {
- ActionManager actionManager = ActionManager.getInstance();
- toolbar.addAction(actionManager.getAction(IdeActions.ACTION_COPY));
- toolbar.addAction(actionManager.getAction(IdeActions.ACTION_FIND));
toolbar.addAction(PreviousDiffAction.find());
toolbar.addAction(NextDiffAction.find());
toolbar.addSeparator();
@@ -235,6 +234,8 @@ public class MergePanel2 implements DiffViewer {
Editor base = getEditor(1);
Editor right = getEditor(2);
+ setupHighlighterSettings(left, base, right);
+
myMergeList.setMarkups(left, base, right);
EditingSides[] sides = {getFirstEditingSide(), getSecondEditingSide()};
myScrollSupport.install(sides);
@@ -271,6 +272,37 @@ public class MergePanel2 implements DiffViewer {
return myScrollSupport.isEnabled();
}
+ private void setupHighlighterSettings(Editor left, Editor base, Editor right) {
+ Editor[] editors = new Editor[]{left, base, right};
+ DiffContent[] contents = myData.getContents();
+ FileType[] types = DiffUtil.chooseContentTypes(contents);
+
+ VirtualFile fallbackFile = contents[1].getFile();
+ FileType fallbackType = contents[1].getContentType();
+
+ for (int i = 0; i < 3; i++) {
+ Editor editor = editors[i];
+ DiffContent content = contents[i];
+
+ EditorHighlighter highlighter =
+ createHighlighter(types[i], content.getFile(), fallbackFile, fallbackType, myData.getProject()).createHighlighter();
+ if (highlighter != null) {
+ ((EditorEx)editor).setHighlighter(highlighter);
+ }
+ }
+ }
+
+ private static DiffHighlighterFactory createHighlighter(FileType contentType,
+ VirtualFile file,
+ VirtualFile otherFile,
+ FileType otherType,
+ Project project) {
+ if (file == null) file = otherFile;
+ if (contentType == null) contentType = otherType;
+
+ return new DiffHighlighterFactoryImpl(contentType, file, project);
+ }
+
public void setHighlighterSettings(@Nullable EditorColorsScheme settings) {
for (EditorPlace place : getEditorPlaces()) {
setHighlighterSettings(settings, place);
@@ -337,7 +369,20 @@ public class MergePanel2 implements DiffViewer {
data.customizeToolbar(myPanel.resetToolbar());
myPanel.registerToolbarActions();
if ( data instanceof MergeRequestImpl && myBuilder != null){
- ((MergeRequestImpl)data).setActions(myBuilder, this);
+ Convertor<DialogWrapper, Boolean> preOkHook = new Convertor<DialogWrapper, Boolean>() {
+ @Override
+ public Boolean convert(DialogWrapper dialog) {
+ ChangeCounter counter = ChangeCounter.getOrCreate(myMergeList);
+ int changes = counter.getChangeCounter();
+ int conflicts = counter.getConflictCounter();
+ if (changes == 0 && conflicts == 0) return true;
+ return Messages.showYesNoDialog(dialog.getRootPane(),
+ DiffBundle.message("merge.dialog.apply.partially.resolved.changes.confirmation.message", changes, conflicts),
+ DiffBundle.message("apply.partially.resolved.merge.dialog.title"),
+ Messages.getQuestionIcon()) == Messages.YES;
+ }
+ };
+ ((MergeRequestImpl)data).setActions(myBuilder, this, preOkHook);
}
}
finally {
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/DiffRequestFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/DiffRequestFactoryImpl.java
index 3b13543e6972..962a0712465b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/DiffRequestFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/DiffRequestFactoryImpl.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.diff.DiffRequestFactory;
import com.intellij.openapi.diff.MergeRequest;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -27,11 +28,11 @@ import org.jetbrains.annotations.Nullable;
public class DiffRequestFactoryImpl extends DiffRequestFactory {
- public MergeRequest createMergeRequest(String leftText,
- String rightText,
- String originalContent,
+ public MergeRequest createMergeRequest(@NotNull String leftText,
+ @NotNull String rightText,
+ @NotNull String originalContent,
@NotNull VirtualFile file,
- Project project,
+ @Nullable Project project,
@Nullable final ActionButtonPresentation okButtonPresentation,
@Nullable final ActionButtonPresentation cancelButtonPresentation) {
final Document document = FileDocumentManager.getInstance().getDocument(file);
@@ -41,16 +42,26 @@ public class DiffRequestFactoryImpl extends DiffRequestFactory {
cancelButtonPresentation);
}
else {
- return create3WayDiffRequest(leftText, rightText, originalContent, project, okButtonPresentation, cancelButtonPresentation);
+ return create3WayDiffRequest(leftText, rightText, originalContent, file.getFileType(), project, okButtonPresentation, cancelButtonPresentation);
}
}
- public MergeRequest create3WayDiffRequest(final String leftText,
- final String rightText,
- final String originalContent,
- final Project project,
+ public MergeRequest create3WayDiffRequest(@NotNull String leftText,
+ @NotNull String rightText,
+ @NotNull String originalContent,
+ @Nullable FileType type,
+ @Nullable Project project,
@Nullable final ActionButtonPresentation okButtonPresentation,
@Nullable final ActionButtonPresentation cancelButtonPresentation) {
- return new MergeRequestImpl(leftText, originalContent, rightText, project, okButtonPresentation, cancelButtonPresentation);
+ return new MergeRequestImpl(leftText, originalContent, rightText, type, project, okButtonPresentation, cancelButtonPresentation);
+ }
+
+ public MergeRequest create3WayDiffRequest(@NotNull String leftText,
+ @NotNull String rightText,
+ @NotNull String originalContent,
+ @Nullable Project project,
+ @Nullable final ActionButtonPresentation okButtonPresentation,
+ @Nullable final ActionButtonPresentation cancelButtonPresentation) {
+ return create3WayDiffRequest(leftText, rightText, originalContent, null, project, okButtonPresentation, cancelButtonPresentation);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java
index 3b1385eb7a59..938c1ee7a42d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/mergeTool/MergeRequestImpl.java
@@ -28,6 +28,7 @@ import com.intellij.openapi.ui.DialogBuilder;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.Convertor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -46,39 +47,51 @@ public class MergeRequestImpl extends MergeRequest {
@Nullable private final ActionButtonPresentation myOkButtonPresentation;
@Nullable private final ActionButtonPresentation myCancelButtonPresentation;
- public MergeRequestImpl(String left,
- MergeVersion base,
- String right,
- Project project,
+ public MergeRequestImpl(@NotNull String left,
+ @NotNull MergeVersion base,
+ @NotNull String right,
+ @Nullable Project project,
@Nullable final ActionButtonPresentation okButtonPresentation,
@Nullable final ActionButtonPresentation cancelButtonPresentation) {
this(new SimpleContent(left), new MergeContent(base, project), new SimpleContent(right), project, okButtonPresentation,
cancelButtonPresentation);
}
- public MergeRequestImpl(DiffContent left,
- MergeVersion base,
- DiffContent right,
- Project project,
+ public MergeRequestImpl(@NotNull DiffContent left,
+ @NotNull MergeVersion base,
+ @NotNull DiffContent right,
+ @Nullable Project project,
@Nullable final ActionButtonPresentation okButtonPresentation,
@Nullable final ActionButtonPresentation cancelButtonPresentation) {
this(left, new MergeContent(base, project), right, project, okButtonPresentation, cancelButtonPresentation);
}
- public MergeRequestImpl(String left,
- String base,
- String right,
- Project project,
+ public MergeRequestImpl(@NotNull String left,
+ @NotNull String base,
+ @NotNull String right,
+ @Nullable Project project,
@Nullable final ActionButtonPresentation okButtonPresentation,
@Nullable final ActionButtonPresentation cancelButtonPresentation) {
- this(new SimpleContent(left), new SimpleContent(base), new SimpleContent(right), project, okButtonPresentation,
- cancelButtonPresentation);
+ this(left, base, right, null, project, okButtonPresentation, cancelButtonPresentation);
}
- private MergeRequestImpl(DiffContent left,
- DiffContent base,
- DiffContent right,
- Project project,
+ public MergeRequestImpl(@NotNull String left,
+ @NotNull String base,
+ @NotNull String right,
+ @Nullable FileType type,
+ @Nullable Project project,
+ @Nullable final ActionButtonPresentation okButtonPresentation,
+ @Nullable final ActionButtonPresentation cancelButtonPresentation) {
+ this(new SimpleContent(left, type),
+ new SimpleContent(base, type),
+ new SimpleContent(right, type),
+ project, okButtonPresentation, cancelButtonPresentation);
+ }
+
+ private MergeRequestImpl(@NotNull DiffContent left,
+ @NotNull DiffContent base,
+ @NotNull DiffContent right,
+ @Nullable Project project,
@Nullable final ActionButtonPresentation okButtonPresentation,
@Nullable final ActionButtonPresentation cancelButtonPresentation) {
super(project);
@@ -176,6 +189,10 @@ public class MergeRequestImpl extends MergeRequest {
}
public void setActions(final DialogBuilder builder, MergePanel2 mergePanel) {
+ setActions(builder, mergePanel, null);
+ }
+
+ public void setActions(final DialogBuilder builder, MergePanel2 mergePanel, final Convertor<DialogWrapper, Boolean> preOkHook) {
builder.removeAllActions(); // otherwise dialog will get default actions (OK, Cancel)
if (myOkButtonPresentation != null) {
@@ -187,6 +204,7 @@ public class MergeRequestImpl extends MergeRequest {
builder.setOkOperation(new Runnable() {
@Override
public void run() {
+ if (preOkHook != null && !preOkHook.convert(builder.getDialogWrapper())) return;
myOkButtonPresentation.run(builder.getDialogWrapper());
}
});
@@ -221,11 +239,11 @@ public class MergeRequestImpl extends MergeRequest {
}
public static class MergeContent extends DiffContent {
- private final MergeVersion myTarget;
+ @NotNull private final MergeVersion myTarget;
private final Document myWorkingDocument;
private final Project myProject;
- public MergeContent(MergeVersion target, Project project) {
+ public MergeContent(@NotNull MergeVersion target, Project project) {
myTarget = target;
myProject = project;
myWorkingDocument = myTarget.createWorkingDocument(project);
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/CaretStateTransferableData.java b/platform/platform-impl/src/com/intellij/openapi/editor/CaretStateTransferableData.java
index f0d2085cbb6b..f0d2085cbb6b 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/CaretStateTransferableData.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/CaretStateTransferableData.java
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java b/platform/platform-impl/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java
index a3e62412f4a4..a3e62412f4a4 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/ClipboardTextPerCaretSplitter.java
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretAbove.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretAbove.java
index f8b3cf7bc83a..c42cd6533e1c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretAbove.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretAbove.java
@@ -15,31 +15,10 @@
*/
package com.intellij.openapi.editor.actions;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.editor.Caret;
-import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorAction;
-import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
-import org.jetbrains.annotations.NotNull;
public class CloneCaretAbove extends EditorAction {
public CloneCaretAbove() {
- super(new Handler());
- }
-
- private static class Handler extends EditorActionHandler {
- public Handler() {
- super(true);
- }
-
- @Override
- public void doExecute(Editor editor, @NotNull Caret caret, DataContext dataContext) {
- caret.clone(true);
- }
-
- @Override
- public boolean isEnabled(Editor editor, DataContext dataContext) {
- return editor.getCaretModel().supportsMultipleCarets();
- }
+ super(new CloneCaretActionHandler(true));
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretActionHandler.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretActionHandler.java
new file mode 100644
index 000000000000..5c5528a38153
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretActionHandler.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.editor.actions;
+
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.openapi.editor.Caret;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.EditorLastActionTracker;
+import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
+import com.intellij.openapi.util.Key;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+public class CloneCaretActionHandler extends EditorActionHandler {
+ private static final Key<Integer> LEVEL = Key.create("CloneCaretActionHandler.level");
+
+ private static final Set<String> OUR_ACTIONS = new HashSet<String>(Arrays.asList(
+ IdeActions.ACTION_EDITOR_CLONE_CARET_ABOVE,
+ IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW,
+ IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION,
+ IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION
+ ));
+
+ private final boolean myCloneAbove;
+
+ public CloneCaretActionHandler(boolean above) {
+ myCloneAbove = above;
+ }
+
+ @Override
+ public boolean isEnabled(Editor editor, DataContext dataContext) {
+ return editor.getCaretModel().supportsMultipleCarets();
+ }
+
+ @Override
+ protected void doExecute(Editor editor, @Nullable Caret targetCaret, DataContext dataContext) {
+ if (targetCaret != null) {
+ targetCaret.clone(myCloneAbove);
+ return;
+ }
+ int currentLevel = 0;
+ List<Caret> currentCarets = new ArrayList<Caret>();
+ for (Caret caret : editor.getCaretModel().getAllCarets()) {
+ int level = getLevel(caret);
+ if (Math.abs(level) > Math.abs(currentLevel)) {
+ currentLevel = level;
+ currentCarets.clear();
+ }
+ if (Math.abs(level) == Math.abs(currentLevel)) {
+ currentCarets.add(caret);
+ }
+ }
+ boolean removeCarets = currentLevel > 0 && myCloneAbove || currentLevel < 0 && !myCloneAbove;
+ Integer newLevel = myCloneAbove ? currentLevel - 1 : currentLevel + 1;
+ for (Caret caret : currentCarets) {
+ if (removeCarets) {
+ editor.getCaretModel().removeCaret(caret);
+ }
+ else {
+ Caret clone = caret;
+ do {
+ Caret original = clone;
+ clone = clone.clone(myCloneAbove);
+ if (original != caret) {
+ editor.getCaretModel().removeCaret(original);
+ }
+ } while (clone != null && caret.hasSelection() && !clone.hasSelection());
+ if (clone != null) {
+ clone.putUserData(LEVEL, newLevel);
+ }
+ }
+ }
+ if (removeCarets) {
+ editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
+ }
+ }
+
+ private static int getLevel(Caret caret) {
+ if (isRepeatedActionInvocation()) {
+ Integer value = caret.getUserData(LEVEL);
+ return value == null ? 0 : value;
+ }
+ else {
+ caret.putUserData(LEVEL, null);
+ return 0;
+ }
+ }
+
+ private static boolean isRepeatedActionInvocation() {
+ String lastActionId = EditorLastActionTracker.getInstance().getLastActionId();
+ return OUR_ACTIONS.contains(lastActionId);
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretBelow.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretBelow.java
index 17d17708b900..974087796e08 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretBelow.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/CloneCaretBelow.java
@@ -15,35 +15,10 @@
*/
package com.intellij.openapi.editor.actions;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.editor.Caret;
-import com.intellij.openapi.editor.CaretModel;
-import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorAction;
-import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
-import org.jetbrains.annotations.NotNull;
public class CloneCaretBelow extends EditorAction {
public CloneCaretBelow() {
- super(new Handler());
- }
-
- private static class Handler extends EditorActionHandler {
- public Handler() {
- super(true);
- }
-
- @Override
- public void doExecute(Editor editor, @NotNull Caret caret, DataContext dataContext) {
- CaretModel caretModel = editor.getCaretModel();
- if (caretModel.supportsMultipleCarets()) {
- caret.clone(false);
- }
- }
-
- @Override
- public boolean isEnabled(Editor editor, DataContext dataContext) {
- return editor.getCaretModel().supportsMultipleCarets();
- }
+ super(new CloneCaretActionHandler(false));
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
index cfd039a5d504..c769f92fff78 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
@@ -62,7 +62,13 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
private int myVisualLineEnd;
private RangeMarker savedBeforeBulkCaretMarker;
private boolean mySkipChangeRequests;
+ /**
+ * Initial horizontal caret position during vertical navigation.
+ * Similar to {@link #myDesiredX}, but represents logical caret position (<code>getLogicalPosition().column</code>) rather than visual.
+ */
private int myLastColumnNumber = 0;
+ private int myDesiredSelectionStartColumn = -1;
+ private int myDesiredSelectionEndColumn = -1;
/**
* We check that caret is located at the target offset at the end of {@link #moveToOffset(int, boolean)} method. However,
* it's possible that the following situation occurs:
@@ -82,11 +88,10 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
*/
private boolean myReportCaretMoves;
/**
- * There is a possible case that user defined non-monospaced font for editor. That means that various symbols have different
- * visual widths. That means that if we move caret vertically it may deviate to the left/right. However, we can try to preserve
- * its initial visual position when possible.
+ * This field holds initial horizontal caret position during vertical navigation. It's used to determine target position when
+ * moving to the new line. It is stored in pixels, not in columns, to account for non-monospaced fonts as well.
* <p/>
- * This field holds desired value for visual <code>'x'</code> caret coordinate (negative value if no coordinate should be preserved).
+ * Negative value means no coordinate should be preserved.
*/
private int myDesiredX = -1;
@@ -255,10 +260,11 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
EditorSettings editorSettings = myEditor.getSettings();
VisualPosition visualCaret = getVisualPosition();
+ int lastColumnNumber = myLastColumnNumber;
int desiredX = myDesiredX;
if (columnShift == 0) {
if (myDesiredX < 0) {
- desiredX = myEditor.visualPositionToXY(visualCaret).x;
+ desiredX = getCurrentX();
}
}
else {
@@ -267,15 +273,12 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
int newLineNumber = visualCaret.line + lineShift;
int newColumnNumber = visualCaret.column + columnShift;
- if (desiredX >= 0 && !ApplicationManager.getApplication().isUnitTestMode()) {
+ if (desiredX >= 0) {
newColumnNumber = myEditor.xyToVisualPosition(new Point(desiredX, Math.max(0, newLineNumber) * myEditor.getLineHeight())).column;
}
Document document = myEditor.getDocument();
- if (!editorSettings.isVirtualSpace() && columnShift == 0 && getLogicalPosition().softWrapLinesOnCurrentLogicalLine <= 0) {
- newColumnNumber = supportsMultipleCarets() ? myLastColumnNumber : myEditor.getLastColumnNumber();
- }
- else if (!editorSettings.isVirtualSpace() && lineShift == 0 && columnShift == 1) {
+ if (!editorSettings.isVirtualSpace() && lineShift == 0 && columnShift == 1) {
int lastLine = document.getLineCount() - 1;
if (lastLine < 0) lastLine = 0;
if (EditorModificationUtil.calcAfterLineEnd(myEditor) >= 0 &&
@@ -303,18 +306,21 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
// We want to move caret to the first column if it's already located at the first line and 'Up' is pressed.
newColumnNumber = 0;
desiredX = -1;
+ lastColumnNumber = -1;
}
VisualPosition pos = new VisualPosition(newLineNumber, newColumnNumber);
- int lastColumnNumber = newColumnNumber;
if (!myEditor.getSoftWrapModel().isInsideSoftWrap(pos)) {
LogicalPosition log = myEditor.visualToLogicalPosition(new VisualPosition(newLineNumber, newColumnNumber));
int offset = myEditor.logicalPositionToOffset(log);
if (offset >= document.getTextLength()) {
int lastOffsetColumn = myEditor.offsetToVisualPosition(document.getTextLength()).column;
// We want to move caret to the last column if if it's located at the last line and 'Down' is pressed.
- newColumnNumber = lastColumnNumber = Math.max(lastOffsetColumn, newColumnNumber);
- desiredX = -1;
+ if (lastOffsetColumn > newColumnNumber) {
+ newColumnNumber = lastOffsetColumn;
+ desiredX = -1;
+ lastColumnNumber = -1;
+ }
}
if (!editorSettings.isCaretInsideTabs()) {
CharSequence text = document.getCharsSequence();
@@ -353,7 +359,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
else {
moveToVisualPosition(pos);
- if (!editorSettings.isVirtualSpace() && columnShift == 0) {
+ if (!editorSettings.isVirtualSpace() && columnShift == 0 && lastColumnNumber >=0) {
setLastColumnNumber(lastColumnNumber);
}
}
@@ -550,6 +556,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
setLastColumnNumber(myLogicalCaret.column);
+ myDesiredSelectionStartColumn = myDesiredSelectionEndColumn = -1;
myVisibleCaret = myEditor.logicalToVisualPosition(myLogicalCaret);
updateOffsetsFromLogicalPosition();
@@ -705,7 +712,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
myEditor.getFoldingModel().flushCaretPosition();
- setLastColumnNumber(column);
+ setLastColumnNumber(myLogicalCaret.column);
+ myDesiredSelectionStartColumn = myDesiredSelectionEndColumn = -1;
myEditor.updateCaretCursor();
requestRepaint(oldInfo);
@@ -962,6 +970,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
clone.myLastColumnNumber = this.myLastColumnNumber;
clone.myReportCaretMoves = this.myReportCaretMoves;
clone.myDesiredX = this.myDesiredX;
+ clone.myDesiredSelectionStartColumn = -1;
+ clone.myDesiredSelectionEndColumn = -1;
return clone;
}
@@ -971,10 +981,10 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
assertIsDispatchThread();
int lineShift = above ? -1 : 1;
final CaretImpl clone = cloneWithoutSelection();
- final int newSelectionStartOffset, newSelectionEndOffset;
+ final int newSelectionStartOffset, newSelectionEndOffset, newSelectionStartColumn, newSelectionEndColumn;
final VisualPosition newSelectionStartPosition, newSelectionEndPosition;
final boolean hasNewSelection;
- if (hasSelection()) {
+ if (hasSelection() || myDesiredSelectionStartColumn >=0 || myDesiredSelectionEndColumn >= 0) {
VisualPosition startPosition = getSelectionStartPosition();
VisualPosition endPosition = getSelectionEndPosition();
VisualPosition leadPosition = getLeadSelectionPosition();
@@ -982,8 +992,10 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
boolean leadIsEnd = leadPosition.equals(endPosition);
LogicalPosition selectionStart = myEditor.visualToLogicalPosition(leadIsStart || leadIsEnd ? leadPosition : startPosition);
LogicalPosition selectionEnd = myEditor.visualToLogicalPosition(leadIsEnd ? startPosition : endPosition);
- LogicalPosition newSelectionStart = truncate(new LogicalPosition(selectionStart.line + lineShift, selectionStart.column));
- LogicalPosition newSelectionEnd = truncate(new LogicalPosition(selectionEnd.line + lineShift, selectionEnd.column));
+ newSelectionStartColumn = myDesiredSelectionStartColumn < 0 ? selectionStart.column : myDesiredSelectionStartColumn;
+ newSelectionEndColumn = myDesiredSelectionEndColumn < 0 ? selectionEnd.column : myDesiredSelectionEndColumn;
+ LogicalPosition newSelectionStart = truncate(selectionStart.line + lineShift, newSelectionStartColumn);
+ LogicalPosition newSelectionEnd = truncate(selectionEnd.line + lineShift, newSelectionEndColumn);
newSelectionStartOffset = myEditor.logicalPositionToOffset(newSelectionStart);
newSelectionEndOffset = myEditor.logicalPositionToOffset(newSelectionEnd);
newSelectionStartPosition = myEditor.logicalToVisualPosition(newSelectionStart);
@@ -996,6 +1008,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
newSelectionStartPosition = null;
newSelectionEndPosition = null;
hasNewSelection = false;
+ newSelectionStartColumn = -1;
+ newSelectionEndColumn = -1;
}
LogicalPosition oldPosition = getLogicalPosition();
int newLine = oldPosition.line + lineShift;
@@ -1003,7 +1017,12 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
Disposer.dispose(clone);
return null;
}
- clone.moveToLogicalPosition(new LogicalPosition(newLine, oldPosition.column), false, null, false);
+ clone.moveToLogicalPosition(new LogicalPosition(newLine, myLastColumnNumber), false, null, false);
+ clone.myLastColumnNumber = myLastColumnNumber;
+ clone.myDesiredX = myDesiredX >= 0 ? myDesiredX : getCurrentX();
+ clone.myDesiredSelectionStartColumn = newSelectionStartColumn;
+ clone.myDesiredSelectionEndColumn = newSelectionEndColumn;
+
if (myEditor.getCaretModel().addCaret(clone)) {
if (hasNewSelection) {
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
@@ -1025,15 +1044,15 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
}
- private LogicalPosition truncate(LogicalPosition position) {
- if (position.line < 0) {
+ private LogicalPosition truncate(int line, int column) {
+ if (line < 0) {
return new LogicalPosition(0, 0);
}
- else if (position.line >= myEditor.getDocument().getLineCount()) {
+ else if (line >= myEditor.getDocument().getLineCount()) {
return myEditor.offsetToLogicalPosition(myEditor.getDocument().getTextLength());
}
else {
- return position;
+ return new LogicalPosition(line, column);
}
}
@@ -1396,9 +1415,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
}
try {
- EditorActionHandler handler = EditorActionManager.getInstance().getActionHandler(
- IdeActions.ACTION_EDITOR_SELECT_WORD_AT_CARET);
- handler.execute(myEditor, myEditor.getDataContext());
+ EditorActionHandler handler = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_SELECT_WORD_AT_CARET);
+ handler.execute(myEditor, CaretImpl.this, myEditor.getDataContext());
}
finally {
if (needOverrideSetting) {
@@ -1453,6 +1471,10 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
return marker != null && marker.isValid() && isVirtualSelectionEnabled() && myEndVirtualOffset > myStartVirtualOffset;
}
+ private int getCurrentX() {
+ return myEditor.visualPositionToXY(myVisibleCaret).x;
+ }
+
@Override
@NotNull
public EditorImpl getEditor() {
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/CopyPasteSupport.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorCopyPasteHelperImpl.java
index 7095080aa13d..c26c7e99ba63 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/CopyPasteSupport.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorCopyPasteHelperImpl.java
@@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.openapi.editor;
+package com.intellij.openapi.editor.impl;
import com.intellij.codeInsight.editorActions.TextBlockTransferable;
import com.intellij.codeInsight.editorActions.TextBlockTransferableData;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.*;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.LineTokenizer;
-import com.intellij.util.Producer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -36,12 +36,11 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
-public class CopyPasteSupport {
- private static final Logger LOG = Logger.getInstance(CopyPasteSupport.class);
+public class EditorCopyPasteHelperImpl extends EditorCopyPasteHelper {
+ private static final Logger LOG = Logger.getInstance(EditorCopyPasteHelperImpl.class);
- private CopyPasteSupport() { }
-
- public static void copySelectionToClipboard(@NotNull Editor editor) {
+ @Override
+ public void copySelectionToClipboard(@NotNull Editor editor) {
ApplicationManager.getApplication().assertIsDispatchThread();
List<TextBlockTransferableData> extraData = new ArrayList<TextBlockTransferableData>();
String s = editor.getCaretModel().supportsMultipleCarets() ? getSelectedTextForClipboard(editor, extraData)
@@ -73,25 +72,22 @@ public class CopyPasteSupport {
return buf.toString();
}
-
- public static TextRange pasteFromClipboard(Editor editor) {
- return pasteTransferable(editor, (Producer<Transferable>)null);
- }
-
- public static TextRange pasteTransferable(Editor editor, final Transferable content) {
- return pasteTransferable(editor, new Producer<Transferable>() {
- @Nullable
- @Override
- public Transferable produce() {
- return content;
+ @Nullable
+ @Override
+ public TextRange[] pasteFromClipboard(@NotNull Editor editor) {
+ CopyPasteManager manager = CopyPasteManager.getInstance();
+ if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) {
+ Transferable clipboardContents = manager.getContents();
+ if (clipboardContents != null) {
+ return pasteTransferable(editor, clipboardContents);
}
- });
+ }
+ return null;
}
@Nullable
- public static TextRange pasteTransferable(final Editor editor, @Nullable Producer<Transferable> producer) {
- Transferable content = getTransferable(producer);
- if (content == null) return null;
+ @Override
+ public TextRange[] pasteTransferable(final @NotNull Editor editor, @NotNull Transferable content) {
String text = getStringContent(content);
if (text == null) return null;
@@ -117,69 +113,25 @@ public class CopyPasteSupport {
catch (Exception e) {
LOG.error(e);
}
+ final TextRange[] ranges = new TextRange[caretCount];
final Iterator<String> segments = new ClipboardTextPerCaretSplitter().split(text, caretData, caretCount).iterator();
+ final int[] index = {0};
editor.getCaretModel().runForEachCaret(new CaretAction() {
@Override
public void perform(Caret caret) {
- EditorModificationUtil.insertStringAtCaret(editor, segments.next(), false, true);
+ String segment = segments.next();
+ int caretOffset = caret.getOffset();
+ ranges[index[0]++] = new TextRange(caretOffset, caretOffset + segment.length());
+ EditorModificationUtil.insertStringAtCaret(editor, segment, false, true);
}
});
- return null;
+ return ranges;
}
else {
int caretOffset = editor.getCaretModel().getOffset();
EditorModificationUtil.insertStringAtCaret(editor, text, false, true);
- return new TextRange(caretOffset, caretOffset + text.length());
- }
- }
-
- public static void pasteTransferableAsBlock(Editor editor, @Nullable Producer<Transferable> producer) {
- Transferable content = getTransferable(producer);
- if (content == null) return;
- String text = getStringContent(content);
- if (text == null) return;
-
- int caretLine = editor.getCaretModel().getLogicalPosition().line;
- int originalCaretLine = caretLine;
- int selectedLinesCount = 0;
-
- final SelectionModel selectionModel = editor.getSelectionModel();
- if (selectionModel.hasBlockSelection()) {
- final LogicalPosition start = selectionModel.getBlockStart();
- final LogicalPosition end = selectionModel.getBlockEnd();
- assert start != null;
- assert end != null;
- LogicalPosition caret = new LogicalPosition(Math.min(start.line, end.line), Math.min(start.column, end.column));
- selectedLinesCount = Math.abs(end.line - start.line);
- caretLine = caret.line;
-
- EditorModificationUtil.deleteSelectedText(editor);
- editor.getCaretModel().moveToLogicalPosition(caret);
+ return new TextRange[] { new TextRange(caretOffset, caretOffset + text.length())};
}
-
- LogicalPosition caretToRestore = editor.getCaretModel().getLogicalPosition();
-
- String[] lines = LineTokenizer.tokenize(text.toCharArray(), false);
- if (lines.length > 1 || selectedLinesCount == 0) {
- int longestLineLength = 0;
- for (int i = 0; i < lines.length; i++) {
- String line = lines[i];
- longestLineLength = Math.max(longestLineLength, line.length());
- editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
- EditorModificationUtil.insertStringAtCaret(editor, line, false, true);
- }
- caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + longestLineLength);
- }
- else {
- for (int i = 0; i <= selectedLinesCount; i++) {
- editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(caretLine + i, caretToRestore.column));
- EditorModificationUtil.insertStringAtCaret(editor, text, false, true);
- }
- caretToRestore = new LogicalPosition(originalCaretLine, caretToRestore.column + text.length());
- }
-
- editor.getCaretModel().moveToLogicalPosition(caretToRestore);
- EditorModificationUtil.zeroWidthBlockSelectionAtCaretColumn(editor, caretLine, caretLine + selectedLinesCount);
}
@Nullable
@@ -195,18 +147,4 @@ public class CopyPasteSupport {
return null;
}
-
- private static Transferable getTransferable(Producer<Transferable> producer) {
- Transferable content = null;
- if (producer != null) {
- content = producer.produce();
- }
- else {
- CopyPasteManager manager = CopyPasteManager.getInstance();
- if (manager.areDataFlavorsAvailable(DataFlavor.stringFlavor)) {
- content = manager.getContents();
- }
- }
- return content;
- }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
index f600c606a98d..39706f016adc 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
@@ -992,7 +992,16 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
}
public void setLineNumberAreaWidth(@NotNull TIntFunction calculator) {
- final int lineNumberAreaWidth = calculator.execute(myLineNumberConvertor.execute(endLineNumber()));
+ int maxLineNumber = 0;
+ for (int i = endLineNumber(); i >= 0; i--) {
+ int number = myLineNumberConvertor.execute(i);
+ if (number >= 0) {
+ maxLineNumber = number;
+ break;
+ }
+ }
+
+ final int lineNumberAreaWidth = calculator.execute(maxLineNumber);
if (myLineNumberAreaWidth != lineNumberAreaWidth) {
myLineNumberAreaWidth = lineNumberAreaWidth;
fireResized();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHighlighterCache.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHighlighterCache.java
index c1499a71a71b..8be2284e8360 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHighlighterCache.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHighlighterCache.java
@@ -15,10 +15,19 @@
*/
package com.intellij.openapi.editor.impl;
+import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
+import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding;
+import com.intellij.psi.impl.search.LexerEditorHighlighterLexer;
import com.intellij.reference.SoftReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,4 +64,28 @@ public class EditorHighlighterCache {
return null;
}
+ @Nullable
+ public static Lexer getLexerBasedOnLexerHighlighter(CharSequence text, VirtualFile virtualFile, Project project) {
+ EditorHighlighter highlighter = null;
+
+ PsiFile psiFile = virtualFile != null ? PsiManager.getInstance(project).findFile(virtualFile) : null;
+ final Document document = psiFile != null ? PsiDocumentManager.getInstance(project).getDocument(psiFile) : null;
+ final EditorHighlighter cachedEditorHighlighter;
+ boolean alreadyInitializedHighlighter = false;
+
+ if (document != null &&
+ (cachedEditorHighlighter = getEditorHighlighterForCachesBuilding(document)) != null &&
+ PlatformIdTableBuilding.checkCanUseCachedEditorHighlighter(text, cachedEditorHighlighter)) {
+ highlighter = cachedEditorHighlighter;
+ alreadyInitializedHighlighter = true;
+ }
+ else if (virtualFile != null) {
+ highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(project, virtualFile);
+ }
+
+ if (highlighter != null) {
+ return new LexerEditorHighlighterLexer(highlighter, alreadyInitializedHighlighter);
+ }
+ return null;
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index b708f38a9190..c0ffbd10aca4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -33,7 +33,7 @@ import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.actionSystem.impl.MouseGestureManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.application.ex.ApplicationManagerEx;
+import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.diagnostic.Logger;
@@ -147,7 +147,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@NotNull private final EditorComponentImpl myEditorComponent;
@NotNull private final EditorGutterComponentImpl myGutterComponent;
private final TraceableDisposable myTraceableDisposable = new TraceableDisposable(new Throwable());
- private volatile boolean hasTabs; // optimisation flag: when editor contains no tabs it is dramatically easier to calculate positions
static {
ComplementaryFontsRegistry.getFontAbleToDisplay(' ', 0, 0, UIManager.getFont("Label.font").getFamily()); // load costly font info
@@ -168,6 +167,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@NotNull private final CaretCursor myCaretCursor;
private final ScrollingTimer myScrollingTimer = new ScrollingTimer();
+ @SuppressWarnings("RedundantStringConstructorCall")
private final Object MOUSE_DRAGGED_GROUP = new String("MouseDraggedGroup");
@NotNull private final SettingsImpl mySettings;
@@ -246,8 +246,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@Nullable private Color myForcedBackground = null;
@Nullable private Dimension myPreferredSize;
private int myVirtualPageHeight;
- @Nullable private Runnable myGutterSizeUpdater = null;
- private boolean myGutterNeedsUpdate = false;
private Alarm myAppleRepaintAlarm;
private final Alarm myMouseSelectionStateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
@@ -317,8 +315,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
EditorImpl(@NotNull Document document, boolean viewer, @Nullable Project project) {
+ assertIsDispatchThread();
myProject = project;
myDocument = (DocumentEx)document;
+ if (myDocument instanceof DocumentImpl) {
+ ((DocumentImpl)myDocument).requestTabTracking();
+ }
myScheme = createBoundColorSchemeDelegate(null);
initTabPainter();
myIsViewer = viewer;
@@ -433,13 +435,13 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (myPrimaryCaret != null) {
myPrimaryCaret.updateVisualPosition(); // repainting old primary caret's row background
}
- ((CaretImpl)e.getCaret()).updateVisualPosition(); // repainting caret region
+ updateCaretVisualPosition(e);
myPrimaryCaret = myCaretModel.getPrimaryCaret();
}
@Override
public void caretRemoved(CaretEvent e) {
- ((CaretImpl)e.getCaret()).updateVisualPosition(); // repainting caret region
+ updateCaretVisualPosition(e);
myPrimaryCaret = myCaretModel.getPrimaryCaret(); // repainting new primary caret's row background
myPrimaryCaret.updateVisualPosition();
}
@@ -548,7 +550,13 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
});
}
- updateHasTabsFlag(document.getImmutableCharSequence());
+ }
+
+ private static void updateCaretVisualPosition(CaretEvent e) {
+ CaretImpl caretImpl = ((CaretImpl)e.getCaret());
+ if (caretImpl != null) {
+ caretImpl.updateVisualPosition(); // repainting caret region
+ }
}
@NotNull
@@ -575,7 +583,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myPrefixWidthInPixels = 0;
if (myPrefixText != null) {
for (char c : myPrefixText) {
- myPrefixWidthInPixels += EditorUtil.charWidth(c, myPrefixAttributes.getFontType(), this);
+ LOG.assertTrue(myPrefixAttributes != null);
+ if (myPrefixAttributes != null) {
+ myPrefixWidthInPixels += EditorUtil.charWidth(c, myPrefixAttributes.getFontType(), this);
+ }
}
}
mySoftWrapModel.recalculate();
@@ -791,6 +802,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (myConnection != null) {
myConnection.disconnect();
}
+ if (myDocument instanceof DocumentImpl) {
+ ((DocumentImpl)myDocument).giveUpTabTracking();
+ }
Disposer.dispose(myDisposable);
}
@@ -898,9 +912,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
new UiNotifyConnector(myEditorComponent, new Activatable.Adapter(){
@Override
public void showNotify() {
- if (myGutterNeedsUpdate) {
- updateGutterSize();
- }
+ myGutterComponent.updateSize();
}
});
@@ -1505,7 +1517,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
private final int[] myLastXOffsets = new int[myLastStartOffsets.length];
private final int[] myLastXs = new int[myLastStartOffsets.length];
private int myCurrentCachePosition;
- private int myLastCacheHits, myTotalRequests; // todo remove
+ private int myLastCacheHits;
+ private int myTotalRequests; // todo remove
private int getTabbedTextWidth(int startOffset, int targetColumn, int xOffset) {
int x = xOffset;
@@ -1621,7 +1634,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
@Override
public void repaint(final int startOffset, int endOffset) {
- if (!isShowing() || myScrollPane == null || myDocument.isInBulkUpdate()) {
+ if (!isShowing() || myDocument.isInBulkUpdate()) {
return;
}
@@ -1638,7 +1651,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
private boolean isShowing() {
- return myGutterComponent != null && myGutterComponent.isShowing();
+ return myGutterComponent.isShowing();
}
private void repaintToScreenBottom(int startLine) {
@@ -1679,9 +1692,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
private void bulkUpdateFinished() {
- if (myScrollPane == null) {
- return;
- }
clearTextWidthCache();
@@ -1700,7 +1710,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (isStickySelection()) {
setStickySelection(false);
}
- if (myDocument.isInBulkUpdate() || myScrollingModel == null) {
+ if (myDocument.isInBulkUpdate()) {
// Assuming that the job is done at bulk listener callback methods.
return;
}
@@ -1716,7 +1726,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
private void changedUpdate(DocumentEvent e) {
- if (myScrollPane == null || myDocument.isInBulkUpdate()) return;
+ if (myDocument.isInBulkUpdate()) return;
clearTextWidthCache();
mySelectionModel.removeBlockSelection();
@@ -1754,16 +1764,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
Point caretLocation = visualPositionToXY(getCaretModel().getVisualPosition());
int scrollOffset = caretLocation.y - myCaretUpdateVShift;
getScrollingModel().scrollVertically(scrollOffset);
- updateHasTabsFlag(e.getNewFragment());
}
- private void updateHasTabsFlag(@NotNull CharSequence newChars) {
- if (!hasTabs) {
- hasTabs = StringUtil.contains(newChars, 0, newChars.length(), '\t');
- }
- }
public boolean hasTabs() {
- return hasTabs;
+ return !(myDocument instanceof DocumentImpl) || ((DocumentImpl)myDocument).mightContainTabs();
}
public boolean isScrollToCaret() {
@@ -1784,24 +1788,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
private void updateGutterSize() {
- if (myGutterSizeUpdater != null) return;
- myGutterSizeUpdater = new Runnable() {
+ LaterInvocator.invokeLater(new Runnable() {
@Override
public void run() {
- if (!isDisposed()) {
- if (isShowing()) {
- myGutterComponent.updateSize();
- myGutterNeedsUpdate = false;
- }
- else {
- myGutterNeedsUpdate = true;
- }
- }
- myGutterSizeUpdater = null;
+ myGutterComponent.updateSize();
}
- };
-
- SwingUtilities.invokeLater(myGutterSizeUpdater);
+ });
}
void validateSize() {
@@ -1945,7 +1937,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
if (isReleased) {
- g.setColor(new Color(128, 255, 128));
+ g.setColor(new JBColor(new Color(128, 255, 128), new Color(128, 255, 128)));
g.fillRect(clip.x, clip.y, clip.width, clip.height);
return;
}
@@ -2239,7 +2231,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myLastBackgroundColor = null;
int start = clipStartOffset;
- int end = clipEndOffset;
+
if (!myPurePaintingMode) {
getSoftWrapModel().registerSoftWrapsIfNecessary();
}
@@ -2250,7 +2242,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return;
}
- IterationState iterationState = new IterationState(this, start, end, isPaintSelection());
+ IterationState iterationState = new IterationState(this, start, clipEndOffset, isPaintSelection());
TextAttributes attributes = iterationState.getMergedAttributes();
Color backColor = getBackgroundColor(attributes);
int fontType = attributes.getFontType();
@@ -2322,7 +2314,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
position.y += lineHeight;
start = lEnd;
}
- else if (collapsedFolderAt.getEndOffset() == end) {
+ else if (collapsedFolderAt.getEndOffset() == clipEndOffset) {
softWrap = mySoftWrapModel.getSoftWrap(collapsedFolderAt.getStartOffset());
if (softWrap != null) {
position.x = drawSoftWrapAwareBackground(
@@ -3677,19 +3669,16 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return logicalToVisualPosition(logicalPos, true);
}
- // TODO den remove as soon as the problem is fixed.
- private final ThreadLocal<Integer> stackDepth = new ThreadLocal<Integer>();
-
- // TODO den remove as soon as the problem is fixed.
@Override
@NotNull
public VisualPosition logicalToVisualPosition(@NotNull LogicalPosition logicalPos, boolean softWrapAware) {
- stackDepth.set(0);
- return doLogicalToVisualPosition(logicalPos, softWrapAware);
+ return doLogicalToVisualPosition(logicalPos, softWrapAware,0);
}
@NotNull
- private VisualPosition doLogicalToVisualPosition(@NotNull LogicalPosition logicalPos, boolean softWrapAware) {
+ private VisualPosition doLogicalToVisualPosition(@NotNull LogicalPosition logicalPos, boolean softWrapAware,
+ // TODO den remove as soon as the problem is fixed.
+ int stackDepth) {
assertReadAccess();
if (!myFoldingModel.isFoldingEnabled() && !mySoftWrapModel.isSoftWrappingEnabled()) {
return new VisualPosition(logicalPos.line, logicalPos.column);
@@ -3703,25 +3692,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
offset = outermostCollapsed.getStartOffset();
LogicalPosition foldStart = offsetToLogicalPosition(offset);
// TODO den remove as soon as the problem is fixed.
- Integer depth = stackDepth.get();
- if (depth >= 0) {
- stackDepth.set(depth + 1);
- if (depth > 15) {
- LOG.error("Detected potential StackOverflowError at logical->visual position mapping. Given logical position: '" +
- logicalPos + "'. State: " + dumpState());
- stackDepth.set(-1);
- }
- }
- // TODO den remove as soon as the problem is fixed.
- try {
- return doLogicalToVisualPosition(foldStart, true);
- }
- finally {
- depth = stackDepth.get();
- if (depth > 0) {
- stackDepth.set(depth - 1);
- }
+ if (stackDepth > 15) {
+ LOG.error("Detected potential StackOverflowError at logical->visual position mapping. Given logical position: '" +
+ logicalPos + "'. State: " + dumpState());
+ stackDepth = -1;
}
+ return doLogicalToVisualPosition(foldStart, true, stackDepth+1);
}
else {
offset = outermostCollapsed.getEndOffset() + 3; // WTF?
@@ -3988,7 +3964,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return false;
}
- if (e.getComponent() != myInitialMouseEvent.getComponent() || !e.getPoint().equals(myInitialMouseEvent.getPoint())) {
+ if (myInitialMouseEvent!= null && (e.getComponent() != myInitialMouseEvent.getComponent() || !e.getPoint().equals(myInitialMouseEvent.getPoint()))) {
myIgnoreMouseEventsConsecutiveToInitial = false;
myInitialMouseEvent = null;
return false;
@@ -4197,7 +4173,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
} else {
final LogicalPosition blockStart = selectionModel.hasBlockSelection() ? selectionModel.getBlockStart() : oldLogicalCaret;
- setBlockSelectionAndBlockActions(e, blockStart, getCaretModel().getLogicalPosition());
+ if (blockStart != null) {
+ setBlockSelectionAndBlockActions(e, blockStart, getCaretModel().getLogicalPosition());
+ }
}
}
else {
@@ -5002,7 +4980,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
void assertIsDispatchThread() {
- ApplicationManagerEx.getApplicationEx().assertIsDispatchThread();
+ ApplicationManager.getApplication().assertIsDispatchThread();
}
private static void assertReadAccess() {
@@ -5392,7 +5370,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
public void run() {
int docLength = doc.getTextLength();
ProperTextRange range = composedTextRange.intersection(new TextRange(0, docLength));
- doc.deleteString(range.getStartOffset(), range.getEndOffset());
+ if (range != null) {
+ doc.deleteString(range.getStartOffset(), range.getEndOffset());
+ }
}
});
}
@@ -6745,7 +6725,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
private class TablessBorder extends SideBorder {
private TablessBorder() {
- super(UIUtil.getBorderColor(), SideBorder.ALL);
+ super(JBColor.border(), SideBorder.ALL);
}
@Override
@@ -6769,7 +6749,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
public Insets getBorderInsets(Component c) {
Container splitters = SwingUtilities.getAncestorOfClass(EditorsSplitters.class, c);
boolean thereIsSomethingAbove = !SystemInfo.isMac || UISettings.getInstance().SHOW_MAIN_TOOLBAR || UISettings.getInstance().SHOW_NAVIGATION_BAR ||
- EditorImpl.this.myProject != null && !ToolWindowManagerEx.getInstanceEx(EditorImpl.this.myProject).getIdsOn(ToolWindowAnchor.TOP).isEmpty();
+ myProject != null && !ToolWindowManagerEx.getInstanceEx(myProject).getIdsOn(ToolWindowAnchor.TOP).isEmpty();
return splitters == null ? super.getBorderInsets(c) : new Insets(thereIsSomethingAbove ? 1 : 0, 0, 0, 0);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
index a2f45fe33857..6ec29e58dc0b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorFontType;
import com.intellij.openapi.editor.ex.*;
import com.intellij.openapi.editor.markup.ErrorStripeRenderer;
@@ -45,7 +46,7 @@ import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.ProperTextRange;
-import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
import com.intellij.ui.*;
@@ -428,7 +429,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
}
@Override
- public void paint(Graphics g) {
+ public void paint(@NotNull Graphics g) {
((ApplicationImpl)ApplicationManager.getApplication()).editorPaintStart();
final Rectangle bounds = getBounds();
@@ -437,7 +438,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
errorIconBounds.y = bounds.height / 2 - errorIconBounds.height / 2;
try {
- if (UISettings.getInstance().PRESENTATION_MODE || SystemInfo.isMac) {
+ if (UISettings.getInstance().PRESENTATION_MODE || ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) {
g.setColor(getEditor().getColorsScheme().getDefaultBackground());
g.fillRect(0, 0, bounds.width, bounds.height);
@@ -493,7 +494,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
}
@Override
- public void uninstallUI(JComponent c) {
+ public void uninstallUI(@NotNull JComponent c) {
super.uninstallUI(c);
myCachedTrack = null;
}
@@ -528,7 +529,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
@Override
protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
- if (UISettings.getInstance().PRESENTATION_MODE || SystemInfo.isMac) {
+ if (UISettings.getInstance().PRESENTATION_MODE || ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) {
super.paintThumb(g, c, thumbBounds);
return;
}
@@ -565,13 +566,13 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
@Override
protected int getThickness() {
- if (UISettings.getInstance().PRESENTATION_MODE || SystemInfo.isMac) return super.getThickness();
+ if (UISettings.getInstance().PRESENTATION_MODE || ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) return super.getThickness();
return super.getThickness() + (isMacOverlayScrollbar() ? 2 : 7);
}
@Override
protected void doPaintTrack(Graphics g, JComponent c, Rectangle bounds) {
- if (UISettings.getInstance().PRESENTATION_MODE || SystemInfo.isMac) {
+ if (UISettings.getInstance().PRESENTATION_MODE || ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) {
g.setColor(getEditor().getColorsScheme().getDefaultBackground());
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
//return;
@@ -609,7 +610,9 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
}
private void paintTrackBasement(Graphics g, Rectangle bounds) {
- if (UISettings.getInstance().PRESENTATION_MODE || SystemInfo.isMac) {
+ if (UISettings.getInstance().PRESENTATION_MODE || ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) {
+ g.setColor(EditorColorsManager.getInstance().getGlobalScheme().getDefaultBackground());
+ g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
return;
}
@@ -647,13 +650,13 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
private void drawMarkup(final Graphics g, final int width, int startOffset, int endOffset, MarkupModelEx markup) {
final Queue<PositionedStripe> thinEnds = new PriorityQueue<PositionedStripe>(5, new Comparator<PositionedStripe>() {
@Override
- public int compare(PositionedStripe o1, PositionedStripe o2) {
+ public int compare(@NotNull PositionedStripe o1, @NotNull PositionedStripe o2) {
return o1.yEnd - o2.yEnd;
}
});
final Queue<PositionedStripe> wideEnds = new PriorityQueue<PositionedStripe>(5, new Comparator<PositionedStripe>() {
@Override
- public int compare(PositionedStripe o1, PositionedStripe o2) {
+ public int compare(@NotNull PositionedStripe o1, @NotNull PositionedStripe o2) {
return o1.yEnd - o2.yEnd;
}
});
@@ -757,12 +760,21 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
boolean drawBottomDecoration) {
int x = isMirrored() ? 3 : 5;
int paintWidth = width;
+ boolean flatStyle = Registry.is("ide.new.markup.markers");
if (thinErrorStripeMark) {
paintWidth /= 2;
- paintWidth += 1;
+ paintWidth += flatStyle ? 0 : 1;
x = isMirrored() ? width + 2 : 0;
}
if (color == null) return;
+ Color darker = UIUtil.isUnderDarcula()? color : ColorUtil.shift(color, 0.75);
+
+ if (flatStyle) {
+ g.setColor(darker);
+ g.fillRect(x, yStart, paintWidth, yEnd - yStart + 1);
+ return;
+ }
+
g.setColor(color);
g.fillRect(x + 1, yStart, paintWidth - 2, yEnd - yStart + 1);
@@ -774,7 +786,6 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
//top decoration
UIUtil.drawLine(g, x + 1, yStart, x + paintWidth - 2, yStart);
}
- Color darker = ColorUtil.shift(color, 0.75);
g.setColor(darker);
if (drawBottomDecoration) {
@@ -787,7 +798,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
// mouse events
@Override
- public void mouseClicked(final MouseEvent e) {
+ public void mouseClicked(@NotNull final MouseEvent e) {
CommandProcessor.getInstance().executeCommand(myEditor.getProject(), new Runnable() {
@Override
public void run() {
@@ -801,11 +812,11 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
}
@Override
- public void mousePressed(MouseEvent e) {
+ public void mousePressed(@NotNull MouseEvent e) {
}
@Override
- public void mouseReleased(MouseEvent e) {
+ public void mouseReleased(@NotNull MouseEvent e) {
}
private int getWidth() {
@@ -824,7 +835,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
}
@Override
- public void mouseMoved(MouseEvent e) {
+ public void mouseMoved(@NotNull MouseEvent e) {
EditorImpl.MyScrollBar scrollBar = myEditor.getVerticalScrollBar();
int buttonHeight = scrollBar.getDecScrollButtonHeight();
int lineCount = getDocument().getLineCount() + myEditor.getSettings().getAdditionalLinesCount();
@@ -897,16 +908,16 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
}
@Override
- public void mouseEntered(MouseEvent e) {
+ public void mouseEntered(@NotNull MouseEvent e) {
}
@Override
- public void mouseExited(MouseEvent e) {
+ public void mouseExited(@NotNull MouseEvent e) {
cancelMyToolTips(e, true);
}
@Override
- public void mouseDragged(MouseEvent e) {
+ public void mouseDragged(@NotNull MouseEvent e) {
cancelMyToolTips(e, true);
}
@@ -943,13 +954,15 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
}
public void markDirtied(@NotNull ProperTextRange yPositions) {
- int start = Math.max(0, yPositions.getStartOffset() - myEditor.getLineHeight());
- int end = myEditorScrollbarTop + myEditorTargetHeight == 0 ? yPositions.getEndOffset() + myEditor.getLineHeight()
- : Math
- .min(myEditorScrollbarTop + myEditorTargetHeight, yPositions.getEndOffset() + myEditor.getLineHeight());
- ProperTextRange adj = new ProperTextRange(start, Math.max(end, start));
+ if (myDirtyYPositions != WHOLE_DOCUMENT) {
+ int start = Math.max(0, yPositions.getStartOffset() - myEditor.getLineHeight());
+ int end = myEditorScrollbarTop + myEditorTargetHeight == 0 ? yPositions.getEndOffset() + myEditor.getLineHeight()
+ : Math
+ .min(myEditorScrollbarTop + myEditorTargetHeight, yPositions.getEndOffset() + myEditor.getLineHeight());
+ ProperTextRange adj = new ProperTextRange(start, Math.max(end, start));
- myDirtyYPositions = myDirtyYPositions == null ? adj : myDirtyYPositions.union(adj);
+ myDirtyYPositions = myDirtyYPositions == null ? adj : myDirtyYPositions.union(adj);
+ }
myEditorScrollbarTop = 0;
myEditorSourceHeight = 0;
@@ -1137,7 +1150,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
myHighlighters.add(rangeHighlighter);
}
Collections.sort(myHighlighters, new Comparator<RangeHighlighterEx>() {
- public int compare(RangeHighlighterEx ex1, RangeHighlighterEx ex2) {
+ public int compare(@NotNull RangeHighlighterEx ex1, @NotNull RangeHighlighterEx ex2) {
LogicalPosition startPos1 = myEditor.offsetToLogicalPosition(ex1.getAffectedAreaStartOffset());
LogicalPosition startPos2 = myEditor.offsetToLogicalPosition(ex2.getAffectedAreaStartOffset());
if (startPos1.line != startPos2.line) return 0;
@@ -1167,7 +1180,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
}
@Override
- protected void paintComponent(Graphics g) {
+ protected void paintComponent(@NotNull Graphics g) {
if (myVisualLine ==-1) return;
Dimension size = getPreferredSize();
EditorGutterComponentEx gutterComponentEx = myEditor.getGutterComponentEx();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/LazyRangeMarkerFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/LazyRangeMarkerFactoryImpl.java
new file mode 100644
index 000000000000..5a9c704173aa
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/LazyRangeMarkerFactoryImpl.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.editor.impl;
+
+import com.intellij.codeStyle.CodeStyleFacade;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.LazyRangeMarkerFactory;
+import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.editor.event.DocumentAdapter;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.UserDataHolderBase;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.WeakList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public class LazyRangeMarkerFactoryImpl extends LazyRangeMarkerFactory {
+ private final Project myProject;
+ private static final Key<WeakList<LazyMarker>> LAZY_MARKERS_KEY = Key.create("LAZY_MARKERS_KEY");
+
+ public LazyRangeMarkerFactoryImpl(@NotNull Project project, @NotNull final FileDocumentManager fileDocumentManager) {
+ myProject = project;
+
+ EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentAdapter() {
+ @Override
+ public void beforeDocumentChange(DocumentEvent e) {
+ transformRangeMarkers(e);
+ }
+
+ @Override
+ public void documentChanged(DocumentEvent e) {
+ transformRangeMarkers(e);
+ }
+
+ private void transformRangeMarkers(@NotNull DocumentEvent e) {
+ Document document = e.getDocument();
+ VirtualFile file = fileDocumentManager.getFile(document);
+ if (file == null) {
+ return;
+ }
+
+ WeakList<LazyMarker> lazyMarkers = getMarkers(file);
+ if (lazyMarkers == null) {
+ return;
+ }
+
+ List<LazyMarker> markers = lazyMarkers.toStrongList();
+ for (LazyMarker marker : markers) {
+ if (file.equals(marker.getFile())) {
+ marker.getOrCreateDelegate();
+ }
+ }
+ }
+ }, project);
+ }
+
+ static WeakList<LazyMarker> getMarkers(@NotNull VirtualFile file) {
+ return file.getUserData(LazyRangeMarkerFactoryImpl.LAZY_MARKERS_KEY);
+ }
+
+ private static void addToLazyMarkersList(@NotNull LazyMarker marker, @NotNull VirtualFile file) {
+ WeakList<LazyMarker> markers = getMarkers(file);
+
+ if (markers == null) {
+ markers = file.putUserDataIfAbsent(LAZY_MARKERS_KEY, new WeakList<LazyMarker>());
+ }
+ markers.add(marker);
+ }
+
+ private static void removeFromLazyMarkersList(@NotNull LazyMarker marker, @NotNull VirtualFile file) {
+ WeakList<LazyMarker> markers = getMarkers(file);
+
+ if (markers != null) {
+ markers.remove(marker);
+ }
+ }
+
+ @Override
+ @NotNull
+ public RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int offset) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<RangeMarker>() {
+ @Override
+ public RangeMarker compute() {
+ // even for already loaded document do not create range marker yet - wait until it really needed when e.g. user clicked to jump to OpenFileDescriptor
+ final LazyMarker marker = new OffsetLazyMarker(file, offset);
+ addToLazyMarkersList(marker, file);
+ return marker;
+ }
+ });
+ }
+
+ @Override
+ @NotNull
+ public RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int line, final int column, final boolean persistent) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<RangeMarker>() {
+ @Override
+ public RangeMarker compute() {
+ final Document document = FileDocumentManager.getInstance().getCachedDocument(file);
+ if (document != null) {
+ final int offset = calculateOffset(myProject, file, document, line, column);
+ return document.createRangeMarker(offset, offset, persistent);
+ }
+
+ final LazyMarker marker = new LineColumnLazyMarker(file, line, column);
+ addToLazyMarkersList(marker, file);
+ return marker;
+ }
+ });
+ }
+
+ abstract static class LazyMarker extends UserDataHolderBase implements RangeMarker {
+ protected RangeMarker myDelegate; // the real range marker which is created only when document is opened, or (this) which means it's disposed
+ protected final VirtualFile myFile;
+ protected final int myInitialOffset;
+
+ private LazyMarker(@NotNull VirtualFile file, int offset) {
+ myFile = file;
+ myInitialOffset = offset;
+ }
+
+ boolean isDelegated() {
+ return myDelegate != null;
+ }
+
+ @NotNull
+ public VirtualFile getFile() {
+ return myFile;
+ }
+
+ @Nullable
+ protected final RangeMarker getOrCreateDelegate() {
+ if (myDelegate == null) {
+ Document document = FileDocumentManager.getInstance().getDocument(myFile);
+ if (document == null) {
+ return null;
+ }
+ myDelegate = createDelegate(myFile, document);
+ removeFromLazyMarkersList(this, myFile);
+ }
+ return isDisposed() ? null : myDelegate;
+ }
+
+ @Nullable
+ protected abstract RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull Document document);
+
+ @Override
+ @NotNull
+ public Document getDocument() {
+ RangeMarker delegate = getOrCreateDelegate();
+ if (delegate == null) {
+ //noinspection ConstantConditions
+ return FileDocumentManager.getInstance().getDocument(myFile);
+ }
+ return delegate.getDocument();
+ }
+
+ @Override
+ public int getStartOffset() {
+ return myDelegate == null || isDisposed() ? myInitialOffset : myDelegate.getStartOffset();
+ }
+
+ public boolean isDisposed() {
+ return myDelegate == this;
+ }
+
+
+ @Override
+ public int getEndOffset() {
+ return myDelegate == null || isDisposed() ? myInitialOffset : myDelegate.getEndOffset();
+ }
+
+ @Override
+ public boolean isValid() {
+ RangeMarker delegate = getOrCreateDelegate();
+ return delegate != null && !isDisposed() && delegate.isValid();
+ }
+
+ @Override
+ public void setGreedyToLeft(boolean greedy) {
+ getOrCreateDelegate().setGreedyToLeft(greedy);
+ }
+
+ @Override
+ public void setGreedyToRight(boolean greedy) {
+ getOrCreateDelegate().setGreedyToRight(greedy);
+ }
+
+ @Override
+ public boolean isGreedyToRight() {
+ return getOrCreateDelegate().isGreedyToRight();
+ }
+
+ @Override
+ public boolean isGreedyToLeft() {
+ return getOrCreateDelegate().isGreedyToLeft();
+ }
+
+ @Override
+ public void dispose() {
+ assert !isDisposed();
+ RangeMarker delegate = myDelegate;
+ if (delegate == null) {
+ removeFromLazyMarkersList(this, myFile);
+ myDelegate = this; // mark of disposed marker
+ }
+ else {
+ delegate.dispose();
+ }
+ }
+ }
+
+ private static class OffsetLazyMarker extends LazyMarker {
+ private OffsetLazyMarker(@NotNull VirtualFile file, int offset) {
+ super(file, offset);
+ }
+
+ @Override
+ public boolean isValid() {
+ RangeMarker delegate = myDelegate;
+ if (delegate == null) {
+ Document document = FileDocumentManager.getInstance().getDocument(myFile);
+ return document != null;
+ }
+
+ return super.isValid();
+ }
+
+ @Override
+ @NotNull
+ public RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull final Document document) {
+ final int offset = Math.min(myInitialOffset, document.getTextLength());
+ return document.createRangeMarker(offset, offset);
+ }
+ }
+
+ private class LineColumnLazyMarker extends LazyMarker {
+ private final int myLine;
+ private final int myColumn;
+
+ private LineColumnLazyMarker(@NotNull VirtualFile file, int line, int column) {
+ super(file, -1);
+ myLine = line;
+ myColumn = column;
+ }
+
+ @Override
+ @Nullable
+ public RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull Document document) {
+ if (document.getTextLength() == 0 && !(myLine == 0 && myColumn == 0)) {
+ return null;
+ }
+
+ int offset = calculateOffset(myProject, file, document, myLine, myColumn);
+ return document.createRangeMarker(offset, offset);
+ }
+
+ @Override
+ public boolean isValid() {
+ RangeMarker delegate = myDelegate;
+ if (delegate == null) {
+ Document document = FileDocumentManager.getInstance().getDocument(myFile);
+ return document != null && (document.getTextLength() != 0 || myLine == 0 && myColumn == 0);
+ }
+
+ return super.isValid();
+ }
+
+ @Override
+ public int getStartOffset() {
+ getOrCreateDelegate();
+ return super.getStartOffset();
+ }
+
+ @Override
+ public int getEndOffset() {
+ getOrCreateDelegate();
+ return super.getEndOffset();
+ }
+ }
+
+ private static int calculateOffset(@NotNull Project project, @NotNull VirtualFile file, @NotNull Document document, final int line, final int column) {
+ int offset;
+ if (line < document.getLineCount()) {
+ final int lineStart = document.getLineStartOffset(line);
+ final int lineEnd = document.getLineEndOffset(line);
+ final CharSequence docText = document.getCharsSequence();
+ final int tabSize = CodeStyleFacade.getInstance(project).getTabSize(file.getFileType());
+
+ offset = lineStart;
+ int col = 0;
+ while (offset < lineEnd && col < column) {
+ col += docText.charAt(offset) == '\t' ? tabSize : 1;
+ offset++;
+ }
+ }
+ else {
+ offset = document.getTextLength();
+ }
+ return offset;
+ }
+
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java
index 2f5a81153579..731d1e26a289 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SelectionModelImpl.java
@@ -567,7 +567,7 @@ public class SelectionModelImpl implements SelectionModel, PrioritizedDocumentLi
@Override
public void copySelectionToClipboard() {
- CopyPasteSupport.copySelectionToClipboard(myEditor);
+ EditorCopyPasteHelper.getInstance().copySelectionToClipboard(myEditor);
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
index 6f1b9820132b..d8b6697dc8d1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
@@ -303,14 +303,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi
if (!isSoftWrappingEnabled()) {
return 0;
}
- int result = 0;
- FoldingModel foldingModel = myEditor.getFoldingModel();
- for (SoftWrap softWrap : myStorage.getSoftWraps()) {
- if (!foldingModel.isOffsetCollapsed(softWrap.getStart())) {
- result++; // Assuming that soft wrap has single line feed all the time
- }
- }
- return result;
+ return myStorage.getSoftWraps().size(); // Assuming that soft wrap has single line feed all the time
}
/**
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/TrailingSpacesStripper.java
index a5c477facfb3..165ff5776756 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/TrailingSpacesStripper.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/TrailingSpacesStripper.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.openapi.fileEditor.impl;
+package com.intellij.openapi.editor.impl;
import com.intellij.ide.DataManager;
import com.intellij.injected.editor.DocumentWindow;
@@ -23,7 +23,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
-import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter;
import com.intellij.openapi.project.Project;
@@ -37,11 +36,12 @@ import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
+import java.util.Set;
public final class TrailingSpacesStripper extends FileDocumentManagerAdapter {
-
public static final Key<String> OVERRIDE_STRIP_TRAILING_SPACES_KEY = Key.create("OVERRIDE_TRIM_TRAILING_SPACES_KEY");
public static final Key<Boolean> OVERRIDE_ENSURE_NEWLINE_KEY = Key.create("OVERRIDE_ENSURE_NEWLINE_KEY");
@@ -61,7 +61,7 @@ public final class TrailingSpacesStripper extends FileDocumentManagerAdapter {
strip(document);
}
- private void strip(final Document document) {
+ private void strip(@NotNull final Document document) {
if (!document.isWritable()) return;
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
VirtualFile file = fileDocumentManager.getFile(document);
@@ -149,7 +149,7 @@ public final class TrailingSpacesStripper extends FileDocumentManagerAdapter {
((DocumentImpl)document).clearLineModificationFlagsExcept(caretLines);
}
- public static boolean stripIfNotCurrentLine(Document document, boolean inChangedLinesOnly) {
+ public static boolean stripIfNotCurrentLine(@NotNull Document document, boolean inChangedLinesOnly) {
if (document instanceof DocumentWindow) {
document = ((DocumentWindow)document).getDelegate();
}
@@ -168,10 +168,11 @@ public final class TrailingSpacesStripper extends FileDocumentManagerAdapter {
if (activeEditor != null && activeEditor.getCaretModel().supportsMultipleCarets()) {
List<Caret> carets = activeEditor.getCaretModel().getAllCarets();
List<VisualPosition> visualCarets = new ArrayList<VisualPosition>(carets.size());
- List<Integer> caretOffsets = new ArrayList<Integer>(carets.size());
- for (Caret caret : carets) {
+ int[] caretOffsets = new int[carets.size()];
+ for (int i = 0; i < carets.size(); i++) {
+ Caret caret = carets.get(i);
visualCarets.add(caret.getVisualPosition());
- caretOffsets.add(caret.getOffset());
+ caretOffsets[i] = caret.getOffset();
}
markAsNeedsStrippingLater = ((DocumentImpl)document).stripTrailingSpaces(activeEditor.getProject(), inChangedLinesOnly, isVirtualSpaceEnabled, caretOffsets);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java
index c2353d5db207..03b03faffe03 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorTabbedContainer.java
@@ -277,6 +277,8 @@ public final class EditorTabbedContainer implements Disposable, CloseAction.Clos
myTabs.getTabAt(index).setTooltipText(text);
}
+ public boolean isTitleShortened(int index) { return myTabs.getTabAt(index).isTitleShortened(); }
+
public void setBackgroundColorAt(final int index, final Color color) {
myTabs.getTabAt(index).setTabColor(color);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
index 3519ab6a1af4..06a3966ade1d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java
@@ -34,6 +34,7 @@ import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
+import com.intellij.openapi.ui.ThreeComponentsSplitter;
import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
@@ -319,6 +320,16 @@ public class EditorWindow {
if (disposeIfNeeded && getTabCount() == 0) {
removeFromSplitter();
+ if (UISettings.getInstance().EDITOR_TAB_PLACEMENT == UISettings.TABS_NONE) {
+ final EditorsSplitters owner = getOwner();
+ if (owner != null) {
+ final ThreeComponentsSplitter splitter = UIUtil.getParentOfType(ThreeComponentsSplitter.class, owner);
+ if (splitter != null) {
+ splitter.revalidate();
+ splitter.repaint();
+ }
+ }
+ }
}
else {
myPanel.revalidate();
@@ -453,6 +464,10 @@ public class EditorWindow {
}
}
+ private boolean isTitleShortenedAt(int index) {
+ return myTabbedPane != null && myTabbedPane.isTitleShortened(index);
+ }
+
private void setBackgroundColorAt(final int index, final Color color) {
if (myTabbedPane != null) {
myTabbedPane.setBackgroundColorAt(index, color);
@@ -897,7 +912,9 @@ public class EditorWindow {
final int index = findEditorIndex(findFileComposite(file));
if (index != -1) {
setTitleAt(index, EditorTabbedContainer.calcTabTitle(getManager().getProject(), file));
- setToolTipTextAt(index, UISettings.getInstance().SHOW_TABS_TOOLTIPS ? getManager().getFileTooltipText(file) : null);
+ setToolTipTextAt(index, UISettings.getInstance().SHOW_TABS_TOOLTIPS || isTitleShortenedAt(index)
+ ? getManager().getFileTooltipText(file)
+ : null);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
index f396b1eed399..091ff1171157 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java
@@ -37,6 +37,7 @@ import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.impl.EditorFactoryImpl;
+import com.intellij.openapi.editor.impl.TrailingSpacesStripper;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl;
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
index e36a120d609b..c7fa51f770d1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
@@ -227,7 +227,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
fm.doWhenFocusSettlesDown(run);
}
else {
- run.run();
+ UIUtil.invokeAndWaitIfNeeded(run);
}
return result;
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java
index 69a91ec31970..b19b2aa3e943 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/NonProjectFileWritingAccessProvider.java
@@ -16,7 +16,6 @@
package com.intellij.openapi.fileEditor.impl;
import com.intellij.ProjectTopics;
-import com.intellij.ide.IdeEventQueue;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.components.impl.stores.IProjectStore;
@@ -30,6 +29,7 @@ import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NotNullLazyKey;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.*;
import com.intellij.util.NotNullFunction;
import com.intellij.util.NullableFunction;
@@ -114,9 +114,7 @@ public class NonProjectFileWritingAccessProvider extends WritingAccessProvider {
if (deniedFiles.isEmpty()) return Collections.emptyList();
- final int savedEventCount = IdeEventQueue.getInstance().getEventCount();
UnlockOption unlockOption = askToUnlock(deniedFiles);
- IdeEventQueue.getInstance().setEventCount(savedEventCount);
if (unlockOption == null) return deniedFiles;
@@ -144,7 +142,9 @@ public class NonProjectFileWritingAccessProvider extends WritingAccessProvider {
}
private boolean isProjectFile(@NotNull VirtualFile file) {
- if (ProjectFileIndex.SERVICE.getInstance(myProject).isInContent(file)) return true;
+ ProjectFileIndex fileIndex = ProjectFileIndex.SERVICE.getInstance(myProject);
+ if (fileIndex.isInContent(file)) return true;
+ if (!Registry.is("ide.hide.excluded.files") && fileIndex.isExcluded(file) && !fileIndex.isUnderIgnored(file)) return true;
if (myProject instanceof ProjectEx) {
IProjectStore store = ((ProjectEx)myProject).getStateStore();
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java
index 60b42f75c22c..690e7c7d2820 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java
@@ -278,19 +278,22 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
}
protected void setStateImpl(final Project project, final Editor editor, final TextEditorState state){
- if (editor.getCaretModel().supportsMultipleCarets()) {
- CaretModel caretModel = editor.getCaretModel();
- List<CaretState> states = new ArrayList<CaretState>(state.CARETS.length);
- for (TextEditorState.CaretState caretState : state.CARETS) {
- states.add(new CaretState(new LogicalPosition(caretState.LINE, caretState.COLUMN),
- new LogicalPosition(caretState.SELECTION_START_LINE, caretState.SELECTION_START_COLUMN),
- new LogicalPosition(caretState.SELECTION_END_LINE, caretState.SELECTION_END_COLUMN)));
+ if (state.CARETS != null) {
+ if (editor.getCaretModel().supportsMultipleCarets()) {
+ CaretModel caretModel = editor.getCaretModel();
+ List<CaretState> states = new ArrayList<CaretState>(state.CARETS.length);
+ for (TextEditorState.CaretState caretState : state.CARETS) {
+ states.add(new CaretState(new LogicalPosition(caretState.LINE, caretState.COLUMN),
+ new LogicalPosition(caretState.SELECTION_START_LINE, caretState.SELECTION_START_COLUMN),
+ new LogicalPosition(caretState.SELECTION_END_LINE, caretState.SELECTION_END_COLUMN)));
+ }
+ caretModel.setCaretsAndSelections(states);
+ }
+ else {
+ LogicalPosition pos = new LogicalPosition(state.CARETS[0].LINE, state.CARETS[0].COLUMN);
+ editor.getCaretModel().moveToLogicalPosition(pos);
+ editor.getSelectionModel().removeSelection();
}
- caretModel.setCaretsAndSelections(states);
- } else {
- LogicalPosition pos = new LogicalPosition(state.CARETS[0].LINE, state.CARETS[0].COLUMN);
- editor.getCaretModel().moveToLogicalPosition(pos);
- editor.getSelectionModel().removeSelection();
}
EditorEx editorEx = editor instanceof EditorEx ? (EditorEx)editor : null;
boolean preciselyScrollVertically =
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java
index 6c78ec12f9df..4b4d19136f01 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeMouseEventDispatcher.java
@@ -30,6 +30,7 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.impl.FocusManagerImpl;
import com.intellij.openapi.wm.impl.IdeGlassPaneImpl;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
@@ -38,7 +39,6 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -230,12 +230,7 @@ public final class IdeMouseEventDispatcher {
}
private static void resetPopupTrigger(final MouseEvent e) {
- try {
- final Field popupTrigger = e.getClass().getDeclaredField("popupTrigger");
- popupTrigger.setAccessible(true);
- popupTrigger.set(e, false);
- }
- catch (Exception ignored) { }
+ ReflectionUtil.setField(MouseEvent.class, e, boolean.class, "popupTrigger", false);
}
/**
@@ -247,14 +242,7 @@ public final class IdeMouseEventDispatcher {
*/
public static boolean patchClickCount(final MouseEvent e) {
if (e.getClickCount() != 1 && e.getButton() > 3) {
- try {
- final Field clickCount = e.getClass().getDeclaredField("clickCount");
- clickCount.setAccessible(true);
- clickCount.set(e, 1);
- return true;
- }
- catch (Exception ignored) {
- }
+ ReflectionUtil.setField(MouseEvent.class, e, int.class, "clickCount", 1);
}
return false;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java
index 7b4f5a0371ba..7c65a805ee6c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java
@@ -99,8 +99,8 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat
if (Registry.is("editor.add.carets.on.double.control.arrows")) {
ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_CLONE_CARET_ABOVE, KeyEvent.VK_CONTROL, KeyEvent.VK_UP);
ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW, KeyEvent.VK_CONTROL, KeyEvent.VK_DOWN);
- ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT, KeyEvent.VK_CONTROL, KeyEvent.VK_LEFT);
- ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT, KeyEvent.VK_CONTROL, KeyEvent.VK_RIGHT);
+ ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT_WITH_SELECTION, KeyEvent.VK_CONTROL, KeyEvent.VK_LEFT);
+ ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION, KeyEvent.VK_CONTROL, KeyEvent.VK_RIGHT);
}
ourKeymapManagerInitialized = true;
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java
index 28536453b713..13a8aaecb724 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java
@@ -17,10 +17,10 @@ package com.intellij.openapi.keymap.impl;
import com.intellij.ide.DataManager;
import com.intellij.ide.IdeEventQueue;
-import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.util.Clock;
import com.intellij.openapi.util.Couple;
@@ -39,6 +39,10 @@ import java.util.concurrent.atomic.AtomicLong;
/**
* Support for keyboard shortcuts like Control-double-click or Control-double-click+A
+ *
+ * Timings that are used in the implementation to detect double click were tuned for SearchEverywhere
+ * functionality (invoked on double Shift), so if you need to change them, please make sure
+ * SearchEverywhere behaviour remains intact.
*/
public class ModifierKeyDoubleClickHandler {
private static final ModifierKeyDoubleClickHandler INSTANCE = new ModifierKeyDoubleClickHandler();
@@ -121,7 +125,7 @@ public class ModifierKeyDoubleClickHandler {
return false;
} else if (ourPressed.first.get() && ourReleased.first.get() && ourPressed.second.get() && myActionKeyCode != -1) {
if (keyCode == myActionKeyCode) {
- if (event.getID() == KeyEvent.KEY_RELEASED) {
+ if (event.getID() == KeyEvent.KEY_PRESSED) {
run(keyEvent);
}
return true;
@@ -192,7 +196,7 @@ public class ModifierKeyDoubleClickHandler {
}
private void run(KeyEvent event) {
- final ActionManager actionManager = ActionManager.getInstance();
+ final ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
final AnAction action = actionManager.getAction(myActionId);
final AnActionEvent anActionEvent = new AnActionEvent(event,
DataManager.getInstance().getDataContext(IdeFocusManager.findInstance().getFocusOwner()),
@@ -200,7 +204,9 @@ public class ModifierKeyDoubleClickHandler {
action.getTemplatePresentation(),
actionManager,
0);
+ actionManager.fireBeforeActionPerformed(action, anActionEvent.getDataContext(), anActionEvent);
action.actionPerformed(anActionEvent);
+ actionManager.fireAfterActionPerformed(action, anActionEvent.getDataContext(), anActionEvent);
}
private boolean isActionBound() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java
index b99f19242fa9..ebb3686969f0 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java
@@ -393,7 +393,7 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi
group.add(commonActionsManager.createExpandAllAction(treeExpander, myActionsTree.getTree()));
group.add(commonActionsManager.createCollapseAllAction(treeExpander, myActionsTree.getTree()));
- group.add(new AnAction("Edit Shortcut", "Edit Shortcut", AllIcons.Actions.Properties) {
+ group.add(new AnAction("Edit Shortcut", "Edit Shortcut", AllIcons.ToolbarDecorator.Edit) {
{
registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)), myActionsTree.getTree());
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java b/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java
index 104dc7b30ec7..d7c7dca2f19b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java
@@ -1,18 +1,64 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.openapi.options;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public abstract class ConfigurableBase<UI extends ConfigurableUi<S>, S> implements SearchableConfigurable, Configurable.NoScroll {
+ private final String id;
+ private final String displayName;
+ private final String helpTopic;
+
private UI ui;
+ protected ConfigurableBase(@NotNull String id, @NotNull String displayName, @Nullable String helpTopic) {
+ this.id = id;
+ this.displayName = displayName;
+ this.helpTopic = helpTopic;
+ }
+
+ @NotNull
+ @Override
+ public final String getId() {
+ return id;
+ }
+
+ @Nls
+ @Override
+ public final String getDisplayName() {
+ return displayName;
+ }
+
+ @Nullable
+ @Override
+ public final String getHelpTopic() {
+ return helpTopic;
+ }
+
@Nullable
@Override
public Runnable enableSearch(String option) {
return null;
}
+ @NotNull
protected abstract S getSettings();
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java b/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java
index e454099318ea..0ecb19a7ce8e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.openapi.options;
import org.jetbrains.annotations.NotNull;
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SimpleConfigurable.java b/platform/platform-impl/src/com/intellij/openapi/options/SimpleConfigurable.java
new file mode 100644
index 000000000000..9812165932a2
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/options/SimpleConfigurable.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.options;
+
+import com.intellij.openapi.util.Getter;
+import com.intellij.util.ReflectionUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public final class SimpleConfigurable<UI extends ConfigurableUi<S>, S> extends ConfigurableBase<UI, S> {
+ private final Class<UI> uiClass;
+ private final Getter<S> settingsGetter;
+
+ private SimpleConfigurable(@NotNull String id, @NotNull String displayName, @Nullable String helpTopic, @NotNull Class<UI> uiClass, @NotNull Getter<S> settingsGetter) {
+ super(id, displayName, helpTopic);
+
+ this.uiClass = uiClass;
+ this.settingsGetter = settingsGetter;
+ }
+
+ public static <UI extends ConfigurableUi<S>, S> SimpleConfigurable<UI, S> create(@NotNull String id, @NotNull String displayName, @Nullable String helpTopic, @NotNull Class<UI> uiClass, @NotNull Getter<S> settingsGetter) {
+ return new SimpleConfigurable<UI, S>(id, displayName, helpTopic, uiClass, settingsGetter);
+ }
+
+ public static <UI extends ConfigurableUi<S>, S> SimpleConfigurable<UI, S> create(@NotNull String id, @NotNull String displayName, @NotNull Class<UI> uiClass, @NotNull Getter<S> settingsGetter) {
+ return create(id, displayName, id, uiClass, settingsGetter);
+ }
+
+ @NotNull
+ @Override
+ protected S getSettings() {
+ return settingsGetter.get();
+ }
+
+ @Override
+ protected UI createUi() {
+ return ReflectionUtil.newInstance(uiClass);
+ }
+} \ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/TabbedConfigurable.java b/platform/platform-impl/src/com/intellij/openapi/options/TabbedConfigurable.java
index 35b75fe7c8d2..47d3881ee815 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/TabbedConfigurable.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/TabbedConfigurable.java
@@ -33,6 +33,7 @@ public abstract class TabbedConfigurable extends CompositeConfigurable<Configura
myParent = parent;
}
+ @Override
public JComponent createComponent() {
myTabbedPane = new TabbedPaneWrapper(myParent);
createConfigurableTabs();
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
index 6ee4a1b947ef..07e5a93670e6 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.ui.*;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.EdtRunnable;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeGlassPaneUtil;
import com.intellij.ui.DocumentAdapter;
@@ -366,6 +367,9 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
myOwnDetails.setContent(myContentWrapper);
myOwnDetails.setBannerMinHeight(mySearchWrapper.getHeight());
myOwnDetails.setText(getBannerText(configurable));
+ if (Registry.is("ide.file.settings.order.new")) {
+ myOwnDetails.forProject(myTree.getConfigurableProject(configurable));
+ }
final ConfigurableContent content = myConfigurable2Content.get(current);
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
index 5524df2bb2cb..e0ab24815ece 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java
@@ -308,7 +308,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
myHandle.setOpaque(false);
content.add(myHandle, BorderLayout.WEST);
content.add(myComponent, BorderLayout.CENTER);
- myProjectIcon = new JLabel(" ", AllIcons.General.ProjectConfigurable, SwingConstants.LEFT);
+ myProjectIcon = new JLabel(" ", SwingConstants.LEFT);
myProjectIcon.setOpaque(true);
content.add(myProjectIcon, BorderLayout.EAST);
myRendererComponent.add(content, BorderLayout.CENTER);
@@ -407,32 +407,17 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
Project project = getConfigurableProject(base);
if (project != null && Registry.is("ide.file.settings.order.new")) {
myProjectIcon.setBackground(selected ? getSelectionBackground() : getBackground());
+ myProjectIcon.setIcon(selected ? AllIcons.General.ProjectConfigurableSelected : AllIcons.General.ProjectConfigurable);
myProjectIcon.setVisible(true);
- tree.setToolTipText(OptionsBundle.message(project.isDefault()
+ myProjectIcon.setToolTipText(OptionsBundle.message(project.isDefault()
? "configurable.default.project.tooltip"
: "configurable.current.project.tooltip"));
} else {
myProjectIcon.setVisible(false);
- tree.setToolTipText(null);
}
return result;
}
- private Project getConfigurableProject(SimpleNode node) {
- if (node == null) {
- return null;
- }
- if (node instanceof EditorNode) {
- EditorNode editor = (EditorNode)node;
- Configurable configurable = editor.getConfigurable();
- if (configurable instanceof ConfigurableWrapper) {
- ConfigurableWrapper wrapper = (ConfigurableWrapper)configurable;
- return wrapper.getExtensionPoint().getProject();
- }
- }
- return getConfigurableProject(node.getParent());
- }
-
protected JComponent createItemComponent() {
myTextLabel = new ErrorLabel();
return myTextLabel;
@@ -642,6 +627,24 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
}
@Override
+ public final String getToolTipText(MouseEvent event) {
+ if (event != null) {
+ Point point = event.getPoint();
+ Component component = getDeepestRendererComponentAt(point.x, point.y);
+ if (component instanceof JLabel) {
+ JLabel label = (JLabel)component;
+ if (label.getIcon() != null) {
+ String text = label.getToolTipText();
+ if (text != null) {
+ return text;
+ }
+ }
+ }
+ }
+ return super.getToolTipText(event);
+ }
+
+ @Override
protected boolean paintNodes() {
return false;
}
@@ -877,4 +880,27 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
}
}
+
+ Project getConfigurableProject(Configurable configurable) {
+ if (configurable instanceof ConfigurableWrapper) {
+ ConfigurableWrapper wrapper = (ConfigurableWrapper)configurable;
+ return wrapper.getExtensionPoint().getProject();
+ }
+ return getConfigurableProject(myConfigurable2Node.get(configurable));
+ }
+
+ private static Project getConfigurableProject(SimpleNode node) {
+ if (node == null) {
+ return null;
+ }
+ if (node instanceof EditorNode) {
+ EditorNode editor = (EditorNode)node;
+ Configurable configurable = editor.getConfigurable();
+ if (configurable instanceof ConfigurableWrapper) {
+ ConfigurableWrapper wrapper = (ConfigurableWrapper)configurable;
+ return wrapper.getExtensionPoint().getProject();
+ }
+ }
+ return getConfigurableProject(node.getParent());
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
index a393d937dcfb..27bb8eb5f245 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java
@@ -56,7 +56,10 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
private final ScheduledFuture<?> myCheckCancelledFuture;
public ProgressManagerImpl(Application application) {
- if (/*!application.isUnitTestMode() && */!DISABLED) {
+ if (DISABLED) {
+ myCheckCancelledFuture = null;
+ }
+ else {
myCheckCancelledFuture = JobScheduler.getScheduler().scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
@@ -65,9 +68,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
}
}, 0, 10, TimeUnit.MILLISECONDS);
}
- else {
- myCheckCancelledFuture = null;
- }
}
@Override
@@ -105,8 +105,8 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
private static class NonCancelableIndicator extends EmptyProgressIndicator implements NonCancelableSection {
private final ProgressIndicator myOld;
- private NonCancelableIndicator(ProgressIndicator old) {
- myOld = old;
+ private NonCancelableIndicator() {
+ myOld = myThreadIndicator.get();
}
@Override
@@ -124,16 +124,17 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
}
}
+ @NotNull
@Override
public final NonCancelableSection startNonCancelableSection() {
- NonCancelableIndicator nonCancelor = new NonCancelableIndicator(myThreadIndicator.get());
+ NonCancelableIndicator nonCancelor = new NonCancelableIndicator();
myThreadIndicator.set(nonCancelor);
return nonCancelor;
}
@Override
public void executeNonCancelableSection(@NotNull Runnable runnable) {
- executeProcessUnderProgress(runnable, new NonCancelableIndicator(getProgressIndicator()));
+ executeProcessUnderProgress(runnable, new NonCancelableIndicator());
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
index 6ffa084931b4..d1abc0816845 100644
--- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java
@@ -49,6 +49,7 @@ import com.intellij.ui.components.JBLayeredPane;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import com.intellij.ui.mac.foundation.MacUtil;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -59,7 +60,6 @@ import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferStrategy;
import java.lang.ref.WeakReference;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -887,18 +887,12 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
if (rootPane != null) { // Workaround for bug in native code to hold rootPane
try {
- Field field = rootPane.getClass().getDeclaredField("glassPane");
- field.setAccessible(true);
- field.set(rootPane, null);
+ ReflectionUtil.resetField(rootPane.getClass(), null, "glassPane");
+ ReflectionUtil.resetField(rootPane.getClass(), null, "contentPane");
- field = rootPane.getClass().getDeclaredField("contentPane");
- field.setAccessible(true);
- field.set(rootPane, null);
rootPane = null;
- field = Window.class.getDeclaredField("windowListener");
- field.setAccessible(true);
- field.set(this, null);
+ ReflectionUtil.resetField(Window.class, null, "windowListener");
}
catch (Exception ignored) {
}
@@ -906,9 +900,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
// http://bugs.sun.com/view_bug.do?bug_id=6614056
try {
- final Field field = Dialog.class.getDeclaredField("modalDialogs");
- field.setAccessible(true);
- final List<?> list = (List<?>)field.get(null);
+ final List<?> list = ReflectionUtil.getField(Dialog.class, null, null, "modalDialogs");
list.remove(this);
}
catch (final Exception ignored) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java
index 9dd3dd21f879..7e1c81ad2fbc 100755
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java
@@ -618,12 +618,21 @@ public final class UpdateChecker {
Future<?> downloadThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
try {
- URL requestUrl = new URL(url);
- if (!StandardFileSystems.FILE_PROTOCOL.equals(requestUrl.getProtocol())) {
- HttpConfigurable.getInstance().prepareURL(url);
- requestUrl = new URL(url + (url.contains("?") ? "&" : "?") + "build=" + ApplicationInfo.getInstance().getBuild().asString());
+ final String urlToCheck;
+ if (!StandardFileSystems.FILE_PROTOCOL.equals(new URL(url).getProtocol())) {
+ urlToCheck = url + (url.contains("?") ? "&" : "?") + "build=" + ApplicationInfo.getInstance().getBuild().asString();
+ } else {
+ urlToCheck = url;
}
- inputStreams[0] = requestUrl.openStream();
+
+ HttpURLConnection connection = ApplicationManager.getApplication() != null ?
+ HttpConfigurable.getInstance().openHttpConnection(urlToCheck) :
+ (HttpURLConnection)new URL(urlToCheck).openConnection();
+ connection.setReadTimeout(HttpConfigurable.CONNECTION_TIMEOUT);
+ connection.setConnectTimeout(HttpConfigurable.CONNECTION_TIMEOUT);
+ connection.connect();
+
+ inputStreams[0] = connection.getInputStream();
}
catch (IOException e) {
exception[0] = e;
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpFileSystemBase.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpFileSystemBase.java
index 7177138d1d9a..a2d32fd1307f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpFileSystemBase.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpFileSystemBase.java
@@ -67,7 +67,9 @@ public abstract class HttpFileSystemBase extends HttpFileSystem {
@Override
@NotNull
public VirtualFile createChild(@NotNull VirtualFile parent, @NotNull String name, boolean isDirectory) {
- return getRemoteFileManager().getOrCreateFile((VirtualFileImpl)parent, Urls.newFromIdea(parent.getUrl() + '/' + name), parent.getPath() + '/' + name, isDirectory);
+ String parentPath = parent.getPath();
+ boolean hasEndSlash = parentPath.charAt(parentPath.length() - 1) == '/';
+ return getRemoteFileManager().getOrCreateFile((HttpVirtualFileImpl)parent, Urls.newFromIdea(parent.getUrl() + (hasEndSlash ? "" : '/') + name), parentPath + (hasEndSlash ? "" : '/') + name, isDirectory);
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpVirtualFileImpl.java
index ba49cfb5a690..a8a1a447d66c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/HttpVirtualFileImpl.java
@@ -35,7 +35,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
-class VirtualFileImpl extends HttpVirtualFile {
+class HttpVirtualFileImpl extends HttpVirtualFile {
private final HttpFileSystemBase myFileSystem;
@Nullable private final RemoteFileInfoImpl myFileInfo;
private FileType myInitialFileType;
@@ -45,7 +45,7 @@ class VirtualFileImpl extends HttpVirtualFile {
private List<VirtualFile> myChildren;
- VirtualFileImpl(@NotNull HttpFileSystemBase fileSystem, @Nullable VirtualFileImpl parent, String path, @Nullable RemoteFileInfoImpl fileInfo) {
+ HttpVirtualFileImpl(@NotNull HttpFileSystemBase fileSystem, @Nullable HttpVirtualFileImpl parent, String path, @Nullable RemoteFileInfoImpl fileInfo) {
if (parent != null) {
if (parent.myChildren == null) {
parent.myChildren = new SmartList<VirtualFile>();
@@ -63,7 +63,7 @@ class VirtualFileImpl extends HttpVirtualFile {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
- VirtualFileImpl file = VirtualFileImpl.this;
+ HttpVirtualFileImpl file = HttpVirtualFileImpl.this;
FileDocumentManager.getInstance().reloadFiles(file);
if (!localFile.getFileType().equals(myInitialFileType)) {
FileContentUtilCore.reparseFiles(file);
@@ -135,8 +135,7 @@ class VirtualFileImpl extends HttpVirtualFile {
@Override
public VirtualFile getParent() {
- if (myParentPath == null) return null;
- return myFileSystem.findFileByPath(myParentPath, true);
+ return myParentPath == null ? null : myFileSystem.findFileByPath(myParentPath, true);
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileManagerImpl.java
index b69c0befd376..904233a35cdf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/RemoteFileManagerImpl.java
@@ -17,7 +17,6 @@ package com.intellij.openapi.vfs.impl.http;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.ex.http.HttpVirtualFileListener;
import com.intellij.util.EventDispatcher;
@@ -35,7 +34,10 @@ import java.util.Map;
*/
public class RemoteFileManagerImpl extends RemoteFileManager implements Disposable {
private final LocalFileStorage myStorage;
- private final Map<Pair<Boolean, Url>, VirtualFileImpl> myRemoteFiles = new THashMap<Pair<Boolean, Url>, VirtualFileImpl>();
+
+ private final Map<Url, HttpVirtualFileImpl> remoteFiles = new THashMap<Url, HttpVirtualFileImpl>();
+ private final Map<Url, HttpVirtualFileImpl> remoteDirectories = new THashMap<Url, HttpVirtualFileImpl>();
+
private final EventDispatcher<HttpVirtualFileListener> myDispatcher = EventDispatcher.create(HttpVirtualFileListener.class);
private final List<RemoteContentProvider> myProviders = new ArrayList<RemoteContentProvider>();
private final DefaultRemoteContentProvider myDefaultRemoteContentProvider;
@@ -55,19 +57,19 @@ public class RemoteFileManagerImpl extends RemoteFileManager implements Disposab
return myDefaultRemoteContentProvider;
}
- public synchronized VirtualFileImpl getOrCreateFile(@Nullable VirtualFileImpl parent, @NotNull Url url, @NotNull String path, final boolean directory) {
- Pair<Boolean, Url> key = Pair.create(directory, url);
- VirtualFileImpl file = myRemoteFiles.get(key);
+ public synchronized HttpVirtualFileImpl getOrCreateFile(@Nullable HttpVirtualFileImpl parent, @NotNull Url url, @NotNull String path, final boolean directory) {
+ Map<Url, HttpVirtualFileImpl> cache = directory ? remoteDirectories : remoteFiles;
+ HttpVirtualFileImpl file = cache.get(url);
if (file == null) {
if (directory) {
- file = new VirtualFileImpl(getHttpFileSystem(url), parent, path, null);
+ file = new HttpVirtualFileImpl(getHttpFileSystem(url), parent, path, null);
}
else {
RemoteFileInfoImpl fileInfo = new RemoteFileInfoImpl(url, this);
- file = new VirtualFileImpl(getHttpFileSystem(url), parent, path, fileInfo);
+ file = new HttpVirtualFileImpl(getHttpFileSystem(url), parent, path, fileInfo);
fileInfo.addDownloadingListener(new MyDownloadingListener(file));
}
- myRemoteFiles.put(key, file);
+ cache.put(url, file);
}
return file;
}
@@ -133,9 +135,9 @@ public class RemoteFileManagerImpl extends RemoteFileManager implements Disposab
}
private class MyDownloadingListener extends FileDownloadingAdapter {
- private final VirtualFileImpl myFile;
+ private final HttpVirtualFileImpl myFile;
- public MyDownloadingListener(final VirtualFileImpl file) {
+ public MyDownloadingListener(final HttpVirtualFileImpl file) {
myFile = file;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java
index efaf84d08b8e..98c3884cc993 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.NotNullLazyValue;
+import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.io.FileAttributes;
import com.intellij.openapi.util.io.FileSystemUtil;
import com.intellij.openapi.util.io.FileUtil;
@@ -30,6 +31,7 @@ import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsBundle;
import com.intellij.openapi.vfs.impl.ZipHandler;
import com.intellij.openapi.vfs.newvfs.persistent.FSRecords;
+import com.intellij.openapi.vfs.newvfs.persistent.FlushingDaemon;
import com.intellij.util.io.DataExternalizer;
import com.intellij.util.io.EnumeratorStringDescriptor;
import com.intellij.util.io.IOUtil;
@@ -169,7 +171,6 @@ public class JarHandler extends ZipHandler {
info = new CacheLibraryInfo(mirrorFile.getName(), originalAttributes.lastModified, originalAttributes.length);
CacheLibraryInfo.ourCachedLibraryInfo.put(path, info);
- CacheLibraryInfo.ourCachedLibraryInfo.force();
return mirrorFile;
}
catch (IOException ex) {
@@ -260,6 +261,23 @@ public class JarHandler extends ZipHandler {
}
assert info != null;
ourCachedLibraryInfo = info;
+ FlushingDaemon.everyFiveSeconds(new Runnable() {
+ @Override
+ public void run() {
+ flushCachedLibraryInfos();
+ }
+ });
+
+ ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
+ @Override
+ public void run() {
+ flushCachedLibraryInfos();
+ }
+ });
+ }
+
+ private static void flushCachedLibraryInfos() {
+ if (ourCachedLibraryInfo.isDirty()) ourCachedLibraryInfo.force();
}
private CacheLibraryInfo(@NotNull String path, long time, long length) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java b/platform/platform-impl/src/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java
index ba44d2b21d10..2ecb28327857 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/ex/IdeFocusTraversalPolicy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,17 +19,15 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.impl.EditorComponentImpl;
import com.intellij.openapi.fileEditor.impl.EditorWindowHolder;
import com.intellij.openapi.util.Computable;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
-import java.lang.reflect.Field;
public class IdeFocusTraversalPolicy extends LayoutFocusTraversalPolicyExt {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy");
- @NonNls private static final String FOCUS_TRAVERSAL_POLICY_FIELD = "focusTraversalPolicy";
protected Component getDefaultComponentImpl(Container focusCycleRoot) {
if (!(focusCycleRoot instanceof JComponent)) {
@@ -103,15 +101,7 @@ public class IdeFocusTraversalPolicy extends LayoutFocusTraversalPolicyExt {
}
private static FocusTraversalPolicy getFocusTraversalPolicyAwtImpl(final JComponent component) {
- try {
- final Field field = Container.class.getDeclaredField(FOCUS_TRAVERSAL_POLICY_FIELD);
- field.setAccessible(true);
- return (FocusTraversalPolicy)field.get(component);
- }
- catch (Exception e) {
- LOG.error(e);
- return null;
- }
+ return ReflectionUtil.getField(Container.class, component, FocusTraversalPolicy.class, "focusTraversalPolicy");
}
protected final boolean accept(final Component aComponent) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
index 83696e07c7f8..71f964504102 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/IdeGlassPaneImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,8 +20,9 @@ import com.intellij.ide.IdeTooltipManager;
import com.intellij.ide.dnd.DnDAware;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.ui.Divider;
import com.intellij.openapi.ui.Painter;
-import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.ui.impl.GlassPaneDialogWrapperPeer;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
@@ -42,6 +43,8 @@ import java.util.List;
public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEventQueue.EventDispatcher, Painter.Listener {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.IdeGlassPaneImpl");
+
private final List<EventListener> myMouseListeners = new ArrayList<EventListener>();
private final Set<EventListener> mySortedMouseListeners = new TreeSet<EventListener>(new Comparator<EventListener>() {
@Override
@@ -360,9 +363,12 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent
}
else {
cursor = Cursor.getDefaultCursor();
- getRootPane().setCursor(cursor);
-
-
+ JRootPane rootPane = getRootPane();
+ if (rootPane != null) {
+ rootPane.setCursor(cursor);
+ } else {
+ LOG.warn("Root pane is null. Event: " + e);
+ }
restoreLastComponent(null);
myLastOriginalCursor = null;
myLastCursorComponent = null;
@@ -375,7 +381,7 @@ public class IdeGlassPaneImpl extends JPanel implements IdeGlassPaneEx, IdeEvent
private boolean canProcessCursorFor(Component target) {
if (target instanceof JMenu ||
target instanceof JMenuItem ||
- target instanceof Splitter.Divider ||
+ target instanceof Divider ||
target instanceof JSeparator ||
(target instanceof JEditorPane && ((JEditorPane)target).getEditorKit() instanceof HTMLEditorKit)) {
return false;
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java
index d6e1d9994500..8b78b1632f79 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeadlessManagerImpl.java
@@ -27,9 +27,11 @@ import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.ActionCallback;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.*;
@@ -41,7 +43,7 @@ import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.content.ContentManagerListener;
import com.intellij.util.ArrayUtil;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -50,12 +52,18 @@ import javax.swing.event.HyperlinkListener;
import java.awt.*;
import java.awt.event.InputEvent;
import java.beans.PropertyChangeListener;
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.*;
import java.util.List;
@SuppressWarnings({"ConstantConditions"})
public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
+ private final Map<String, ToolWindow> myToolWindows = new HashMap<String, ToolWindow>();
+ private final Project myProject;
+
+ public ToolWindowHeadlessManagerImpl(Project project) {
+ myProject = project;
+ }
+
@Override
public boolean canShowNotification(@NotNull String toolWindowId) {
return false;
@@ -65,7 +73,184 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
public void notifyByBalloon(@NotNull final String toolWindowId, @NotNull final MessageType type, @NotNull final String htmlBody) {
}
- public static final ToolWindow HEADLESS_WINDOW = new ToolWindowEx() {
+ private ToolWindow doRegisterToolWindow(final String id, @Nullable Disposable parentDisposable) {
+ MockToolWindow tw = new MockToolWindow(myProject);
+ myToolWindows.put(id, tw);
+ if (parentDisposable != null) {
+ Disposer.register(parentDisposable, new Disposable() {
+ @Override
+ public void dispose() {
+ unregisterToolWindow(id);
+ }
+ });
+ }
+ return tw;
+ }
+
+ @Override
+ public ToolWindow registerToolWindow(@NotNull String id,
+ @NotNull JComponent component,
+ @NotNull ToolWindowAnchor anchor,
+ Disposable parentDisposable,
+ boolean canWorkInDumbMode) {
+ return doRegisterToolWindow(id, parentDisposable);
+ }
+
+ @Override
+ public ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor) {
+ return doRegisterToolWindow(id, null);
+ }
+
+ @Override
+ public ToolWindow registerToolWindow(@NotNull String id,
+ @NotNull JComponent component,
+ @NotNull ToolWindowAnchor anchor,
+ Disposable parentDisposable,
+ boolean canWorkInDumbMode,
+ boolean canCloseContents) {
+ return doRegisterToolWindow(id, parentDisposable);
+ }
+
+ @Override
+ public ToolWindow registerToolWindow(@NotNull String id,
+ @NotNull JComponent component,
+ @NotNull ToolWindowAnchor anchor,
+ Disposable parentDisposable) {
+ return doRegisterToolWindow(id, parentDisposable);
+ }
+
+ @Override
+ public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor) {
+ return doRegisterToolWindow(id, null);
+ }
+
+ @Override
+ public ToolWindow registerToolWindow(@NotNull final String id,
+ final boolean canCloseContent,
+ @NotNull final ToolWindowAnchor anchor,
+ final boolean secondary) {
+ return doRegisterToolWindow(id, null);
+ }
+
+ @Override
+ public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor,
+ final Disposable parentDisposable, final boolean dumbAware) {
+ return doRegisterToolWindow(id, parentDisposable);
+ }
+
+ @Override
+ public void unregisterToolWindow(@NotNull String id) {
+ myToolWindows.remove(id);
+ }
+
+ @Override
+ public void activateEditorComponent() {
+ }
+
+ @Override
+ public boolean isEditorComponentActive() {
+ return false;
+ }
+
+ @Override
+ public String[] getToolWindowIds() {
+ return ArrayUtil.EMPTY_STRING_ARRAY;
+ }
+
+ @Override
+ public String getActiveToolWindowId() {
+ return null;
+ }
+
+ @Override
+ public ToolWindow getToolWindow(String id) {
+ return myToolWindows.get(id);
+ }
+
+ @Override
+ public void invokeLater(Runnable runnable) {
+ }
+
+ @Override
+ public IdeFocusManager getFocusManager() {
+ return IdeFocusManagerHeadless.INSTANCE;
+ }
+
+ @Override
+ public void notifyByBalloon(@NotNull final String toolWindowId,
+ @NotNull final MessageType type,
+ @NotNull final String text,
+ @Nullable final Icon icon,
+ @Nullable final HyperlinkListener listener) {
+ }
+
+ @Override
+ public Balloon getToolWindowBalloon(String id) {
+ return null;
+ }
+
+ @Override
+ public void initToolWindow(ToolWindowEP bean) {
+
+ }
+
+ @Override
+ public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l) {
+
+ }
+
+ @Override
+ public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l) {
+ }
+
+ @Override
+ public String getLastActiveToolWindowId() {
+ return null;
+ }
+
+ @Override
+ public String getLastActiveToolWindowId(Condition<JComponent> condition) {
+ return null;
+ }
+
+ @Override
+ public DesktopLayout getLayout() {
+ return new DesktopLayout();
+ }
+
+ @Override
+ public void setLayoutToRestoreLater(DesktopLayout layout) {
+ }
+
+ @Override
+ public DesktopLayout getLayoutToRestoreLater() {
+ return new DesktopLayout();
+ }
+
+ @Override
+ public void setLayout(@NotNull DesktopLayout layout) {
+ }
+
+ @Override
+ public void clearSideStack() {
+ }
+
+ @Override
+ public void hideToolWindow(@NotNull final String id, final boolean hideSide) {
+ }
+
+ @Override
+ public List<String> getIdsOn(@NotNull final ToolWindowAnchor anchor) {
+ return new ArrayList<String>();
+ }
+
+ public static class MockToolWindow implements ToolWindowEx {
+ ContentManager myContentManager = new MockContentManager();
+
+ public MockToolWindow(@NotNull Project project) {
+ Disposer.register(project, myContentManager);
+ }
+
@Override
public boolean isActive() {
return false;
@@ -206,7 +391,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
@Override
public ContentManager getContentManager() {
- return MOCK_CONTENT_MANAGER;
+ return myContentManager;
}
@Override
@@ -270,9 +455,9 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
public boolean isUseLastFocusedOnActivation() {
return false;
}
- };
+ }
- @NonNls private static final ContentManager MOCK_CONTENT_MANAGER = new ContentManager() {
+ private static class MockContentManager implements ContentManager {
private final List<Content> myContents = new ArrayList<Content>();
private Content mySelected;
@@ -284,27 +469,33 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
@Override
public void addContent(@NotNull final Content content) {
+ myContents.add(content);
+ if (mySelected == null) mySelected = content;
}
@Override
public void addContent(@NotNull Content content, int order) {
myContents.add(order, content);
+ if (mySelected == null) mySelected = content;
}
@Override
public void addContent(@NotNull final Content content, final Object constraints) {
+ addContent(content);
}
@Override
- public void addContentManagerListener(@NotNull final ContentManagerListener l) {
+ public void addSelectedContent(@NotNull final Content content) {
+ addContent(content);
+ setSelectedContent(content);
}
@Override
- public void addDataProvider(@NotNull final DataProvider provider) {
+ public void addContentManagerListener(@NotNull final ContentManagerListener l) {
}
@Override
- public void addSelectedContent(@NotNull final Content content) {
+ public void addDataProvider(@NotNull final DataProvider provider) {
}
@Override
@@ -319,6 +510,9 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
@Override
public Content findContent(final String displayName) {
+ for (Content each : myContents) {
+ if (each.getDisplayName().equals(displayName)) return each;
+ }
return null;
}
@@ -359,18 +553,24 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
@Override
public Content getContent(final JComponent component) {
+ Content[] contents = getContents();
+ for (Content content : contents) {
+ if (Comparing.equal(component, content.getComponent())) {
+ return content;
+ }
+ }
return null;
}
@Override
@Nullable
public Content getContent(final int index) {
- return null;
+ return myContents.get(index);
}
@Override
public int getContentCount() {
- return 0;
+ return myContents.size();
}
@Override
@@ -381,7 +581,7 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
@Override
public int getIndexOfContent(final Content content) {
- return -1;
+ return myContents.indexOf(content);
}
@Override
@@ -393,35 +593,37 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
@Override
@NotNull
public Content[] getSelectedContents() {
- return new Content[0];
+ return mySelected != null ? new Content[]{mySelected} : new Content[0];
}
@Override
public boolean isSelected(@NotNull final Content content) {
- return false;
+ return content == mySelected;
}
@Override
public void removeAllContents(final boolean dispose) {
for (int i = myContents.size() - 1; i >= 0; i--) {
Content content = myContents.get(i);
- removeContent(content, true);
+ removeContent(content, dispose);
}
mySelected = null;
}
@Override
public boolean removeContent(@NotNull final Content content, final boolean dispose) {
- Disposer.dispose(content);
+ if (dispose) Disposer.dispose(content);
+ boolean result = myContents.remove(content);
if (mySelected == content) {
- mySelected = null;
+ mySelected = ContainerUtil.getFirstItem(myContents);
}
- return myContents.remove(content);
+ return result;
}
@NotNull
@Override
public ActionCallback removeContent(@NotNull Content content, boolean dispose, boolean trackFocus, boolean implicitFocus) {
+ removeContent(content, dispose);
return new ActionCallback.Done();
}
@@ -451,33 +653,36 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
@NotNull
@Override
public ActionCallback setSelectedContentCB(@NotNull Content content) {
+ setSelectedContent(content);
return new ActionCallback.Done();
}
@Override
public void setSelectedContent(@NotNull final Content content, final boolean requestFocus) {
+ setSelectedContent(content);
}
@NotNull
@Override
public ActionCallback setSelectedContentCB(@NotNull final Content content, final boolean requestFocus) {
- return new ActionCallback.Done();
+ return setSelectedContentCB(content);
}
@Override
public void setSelectedContent(@NotNull Content content, boolean requestFocus, boolean forcedFocus) {
+ setSelectedContent(content);
}
@NotNull
@Override
public ActionCallback setSelectedContentCB(@NotNull final Content content, final boolean requestFocus, final boolean forcedFocus) {
- return new ActionCallback.Done();
+ return setSelectedContentCB(content);
}
@NotNull
@Override
public ActionCallback setSelectedContent(@NotNull Content content, boolean requestFocus, boolean forcedFocus, boolean implicit) {
- return new ActionCallback.Done();
+ return setSelectedContentCB(content);
}
@NotNull
@@ -506,161 +711,4 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
public ContentFactory getFactory() {
return ServiceManager.getService(ContentFactory.class);
}
- };
-
- @Override
- public ToolWindow registerToolWindow(@NotNull String id,
- @NotNull JComponent component,
- @NotNull ToolWindowAnchor anchor,
- Disposable parentDisposable,
- boolean canWorkInDumbMode) {
- return HEADLESS_WINDOW;
- }
-
- @Override
- public ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor) {
- return HEADLESS_WINDOW;
- }
-
- @Override
- public ToolWindow registerToolWindow(@NotNull String id,
- @NotNull JComponent component,
- @NotNull ToolWindowAnchor anchor,
- Disposable parentDisposable,
- boolean canWorkInDumbMode,
- boolean canCloseContents) {
- return HEADLESS_WINDOW;
- }
-
- @Override
- public ToolWindow registerToolWindow(@NotNull String id,
- @NotNull JComponent component,
- @NotNull ToolWindowAnchor anchor,
- Disposable parentDisposable) {
- return HEADLESS_WINDOW;
- }
-
- @Override
- public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor) {
- return HEADLESS_WINDOW;
- }
-
- @Override
- public ToolWindow registerToolWindow(@NotNull final String id,
- final boolean canCloseContent,
- @NotNull final ToolWindowAnchor anchor,
- final boolean secondary) {
- return HEADLESS_WINDOW;
- }
-
- @Override
- public ToolWindow registerToolWindow(@NotNull final String id, final boolean canCloseContent, @NotNull final ToolWindowAnchor anchor,
- final Disposable parentDisposable, final boolean dumbAware) {
- return HEADLESS_WINDOW;
- }
-
- @Override
- public void unregisterToolWindow(@NotNull String id) {
- }
-
- @Override
- public void activateEditorComponent() {
- }
-
- @Override
- public boolean isEditorComponentActive() {
- return false;
- }
-
- @Override
- public String[] getToolWindowIds() {
- return ArrayUtil.EMPTY_STRING_ARRAY;
- }
-
- @Override
- public String getActiveToolWindowId() {
- return null;
- }
-
- @Override
- public ToolWindow getToolWindow(String id) {
- return HEADLESS_WINDOW;
- }
-
- @Override
- public void invokeLater(Runnable runnable) {
- }
-
- @Override
- public IdeFocusManager getFocusManager() {
- return IdeFocusManagerHeadless.INSTANCE;
- }
-
- @Override
- public void notifyByBalloon(@NotNull final String toolWindowId,
- @NotNull final MessageType type,
- @NotNull final String text,
- @Nullable final Icon icon,
- @Nullable final HyperlinkListener listener) {
- }
-
- @Override
- public Balloon getToolWindowBalloon(String id) {
- return null;
- }
-
- @Override
- public void initToolWindow(ToolWindowEP bean) {
-
- }
-
- @Override
- public void addToolWindowManagerListener(@NotNull ToolWindowManagerListener l) {
-
- }
-
- @Override
- public void removeToolWindowManagerListener(@NotNull ToolWindowManagerListener l) {
- }
-
- @Override
- public String getLastActiveToolWindowId() {
- return null;
- }
-
- @Override
- public String getLastActiveToolWindowId(Condition<JComponent> condition) {
- return null;
- }
-
- @Override
- public DesktopLayout getLayout() {
- return new DesktopLayout();
- }
-
- @Override
- public void setLayoutToRestoreLater(DesktopLayout layout) {
- }
-
- @Override
- public DesktopLayout getLayoutToRestoreLater() {
- return new DesktopLayout();
- }
-
- @Override
- public void setLayout(@NotNull DesktopLayout layout) {
- }
-
- @Override
- public void clearSideStack() {
- }
-
- @Override
- public void hideToolWindow(@NotNull final String id, final boolean hideSide) {
- }
-
- @Override
- public List<String> getIdsOn(@NotNull final ToolWindowAnchor anchor) {
- return new ArrayList<String>();
- }
-}
+ }}
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java
index 6c6bcd137949..120579bcb809 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,11 @@
package com.intellij.openapi.wm.impl;
import com.intellij.Patches;
+import com.intellij.execution.util.ExecUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import org.jetbrains.annotations.Nullable;
@@ -29,6 +31,8 @@ import java.awt.*;
import java.awt.peer.ComponentPeer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import static com.intellij.util.ArrayUtil.newLongArray;
import static com.intellij.util.containers.ContainerUtil.newHashSet;
@@ -254,11 +258,17 @@ public class X11UiUtil {
setWM("MARCO_WM", "METACITY_WM");
}
else if ("awesome".equals(wmName)) {
- setWM("SAWFISH_WM");
+ String version = getAwesomeWMVersion();
+ if (StringUtil.compareVersionNumbers(version, "3.5") >= 0) {
+ setWM("SAWFISH_WM");
+ }
+ else if (version != null) {
+ setWM("OTHER_NONREPARENTING_WM", "LG3D_WM");
+ }
}
}
- catch (Throwable e) {
- LOG.warn(e);
+ catch (Throwable t) {
+ LOG.warn(t);
}
}
@@ -273,6 +283,7 @@ public class X11UiUtil {
if (id != null) {
field(xwmClass, "awt_wmgr").set(null, id);
field(xwmClass, "WMID").set(xwm, id);
+ LOG.info("impersonated WM: " + wmConstant);
break;
}
}
@@ -281,6 +292,23 @@ public class X11UiUtil {
}
}
+ @Nullable
+ private static String getAwesomeWMVersion() {
+ try {
+ String version = ExecUtil.execAndReadLine("awesome", "--version");
+ if (version != null) {
+ Matcher m = Pattern.compile("awesome v([0-9.]+)").matcher(version);
+ if (m.find()) {
+ return m.group(1);
+ }
+ }
+ }
+ catch (Throwable t) {
+ LOG.warn(t);
+ }
+ return null;
+ }
+
// full-screen support
public static boolean isFullScreenSupported() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java
index 7a772e7aed34..2c681856a328 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/commands/RequestFocusInEditorComponentCmd.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,11 +19,13 @@
*/
package com.intellij.openapi.wm.impl.commands;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.impl.EditorWindow;
import com.intellij.openapi.fileEditor.impl.EditorWithProviderComposite;
import com.intellij.openapi.fileEditor.impl.EditorsSplitters;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Expirable;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.impl.FloatingDecorator;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
@@ -44,10 +46,16 @@ public final class RequestFocusInEditorComponentCmd extends FinalizableCommand{
private final IdeFocusManager myFocusManager;
private final Expirable myTimestamp;
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.commands.RequestFocusInEditorComponentCmd");
+
public RequestFocusInEditorComponentCmd(@NotNull final EditorsSplitters splitters, IdeFocusManager
focusManager, final Runnable finishCallBack, boolean forced){
super(finishCallBack);
+ boolean shouldLogFocuses = Registry.is("ide.log.focuses");
+ if (shouldLogFocuses) {
+ LOG.info(new Exception());
+ }
myComponent = null;
final EditorWindow window = splitters.getCurrentWindow();
if (window != null) {
@@ -94,7 +102,8 @@ public final class RequestFocusInEditorComponentCmd extends FinalizableCommand{
}
if(myComponent != null){
- myFocusManager.requestFocus(myComponent, myForced).notifyWhenDone(myDoneCallback).doWhenDone(new Runnable() {
+ final boolean forced = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == null;
+ myFocusManager.requestFocus(myComponent, myForced || forced).notifyWhenDone(myDoneCallback).doWhenDone(new Runnable() {
public void run() {
// if owner is active window or it has active child window which isn't floating decorator then
// don't bring owner window to font. If we will make toFront every time then it's possible
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java
index 9140fc200a77..82dba7430827 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/RecentProjectPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -186,14 +186,11 @@ public class RecentProjectPanel extends JPanel {
private String getTitle2Text(ReopenProjectAction action, JComponent pathLabel) {
String fullText = action.getProjectPath();
- int labelWidth = pathLabel.getWidth();
if (fullText == null || fullText.length() == 0) return " ";
- String home = SystemProperties.getUserHome();
- if (FileUtil.startsWith(fullText, home)) {
- fullText = "~" + fullText.substring(home.length());
- }
+ fullText = FileUtil.getLocationRelativeToUserHome(fullText, false);
+ int labelWidth = pathLabel.getWidth();
if (pathLabel.getFontMetrics(pathLabel.getFont()).stringWidth(fullText) > labelWidth) {
return myPathShortener.getShortPath(action);
}
diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java b/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java
index e31b067e5d79..8d85ae106c44 100644
--- a/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java
+++ b/platform/platform-impl/src/com/intellij/remote/RemoteConnectionCredentialsWrapper.java
@@ -116,11 +116,24 @@ public class RemoteConnectionCredentialsWrapper {
return new IllegalStateException("Unknown connection type"); //TODO
}
- public void copyTo(RemoteConnectionCredentialsWrapper copy) {
+ public void copyTo(final RemoteConnectionCredentialsWrapper copy) {
copy.myCredentialsTypeHolder = new UserDataHolderBase();
- copy.setPlainSshCredentials(getPlainSshCredentials());
- copy.setVagrantConnectionType(getVagrantCredentials());
- copy.setWebDeploymentCredentials(getWebDeploymentCredentials());
+ switchType(new RemoteSdkConnectionAcceptor() {
+ @Override
+ public void ssh(@NotNull RemoteCredentialsHolder cred) {
+ copy.setPlainSshCredentials(getPlainSshCredentials());
+ }
+
+ @Override
+ public void vagrant(@NotNull VagrantBasedCredentialsHolder cred) {
+ copy.setVagrantConnectionType(getVagrantCredentials());
+ }
+
+ @Override
+ public void deployment(@NotNull WebDeploymentCredentialsHolder cred) {
+ copy.setWebDeploymentCredentials(getWebDeploymentCredentials());
+ }
+ });
}
public String getId() {
diff --git a/platform/platform-impl/src/com/intellij/remote/VagrantSupport.java b/platform/platform-impl/src/com/intellij/remote/VagrantSupport.java
index a5ebae6fe567..9e2b60a54416 100644
--- a/platform/platform-impl/src/com/intellij/remote/VagrantSupport.java
+++ b/platform/platform-impl/src/com/intellij/remote/VagrantSupport.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -43,6 +44,10 @@ public abstract class VagrantSupport {
@NotNull
public abstract RemoteCredentials getVagrantSettings(@NotNull Project project, String vagrantFolder);
+ public abstract void getVagrantSettingsAsync(@Nullable Project project,
+ @NotNull String vagrantFolder,
+ @NotNull Consumer<RemoteCredentials> onSuccess);
+
@NotNull
public abstract RemoteCredentials getCredentials(@NotNull String folder) throws IOException;
diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
index 4e65063e7939..d8b204cfd76c 100644
--- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
+++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
@@ -223,6 +223,7 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
if (selected == null
|| !myComponent.isEnabled()
|| !myComponent.isShowing()
+ || !myComponent.getVisibleRect().intersects(getVisibleRect(selected))
|| !myComponent.isFocusOwner() && !processIfUnfocused
|| isPopup()) {
hideHint();
diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
index 50a7ebbca92b..2a7d44d017bd 100644
--- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
+++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.util.PlatformUtils;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -38,7 +39,6 @@ import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.InputStream;
-import java.lang.reflect.Field;
import java.net.URL;
import java.util.List;
import java.util.Locale;
@@ -111,9 +111,7 @@ public class AppUIUtil {
final Toolkit toolkit = Toolkit.getDefaultToolkit();
final Class<? extends Toolkit> aClass = toolkit.getClass();
if ("sun.awt.X11.XToolkit".equals(aClass.getName())) {
- final Field awtAppClassName = aClass.getDeclaredField("awtAppClassName");
- awtAppClassName.setAccessible(true);
- awtAppClassName.set(toolkit, getFrameClass());
+ ReflectionUtil.setField(aClass, toolkit, null, "awtAppClassName", getFrameClass());
}
}
catch (Exception ignore) { }
diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java
index c6c209ed4b88..513d5cedb2ab 100644
--- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java
@@ -200,8 +200,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
if (cmp == myCloseRec) return true;
if (UIUtil.isDescendingFrom(cmp, myComp)) return true;
if (myComp == null || !myComp.isShowing()) return false;
- Rectangle rectangleOnScreen = new Rectangle(myComp.getLocationOnScreen(), myComp.getSize());
- return rectangleOnScreen.contains(target.getScreenPoint());
+ return myComp.contains(target.getScreenPoint().x, target.getScreenPoint().y);
}
public boolean isMovingForward(RelativePoint target) {
@@ -614,7 +613,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
myComp.setBorder(new EmptyBorder(borderSize, borderSize, borderSize, borderSize));
myLayeredPane.add(myComp);
- myLayeredPane.setLayer(myComp, getLayer());
+ myLayeredPane.setLayer(myComp, getLayer(), 0); // the second balloon must be over the first one
myPosition.updateBounds(this);
if (myBlockClicks) {
myComp.addMouseListener(new MouseAdapter() {
diff --git a/platform/platform-impl/src/com/intellij/ui/CheckboxTree.java b/platform/platform-impl/src/com/intellij/ui/CheckboxTree.java
index c91be65978c1..1443a9303e39 100644
--- a/platform/platform-impl/src/com/intellij/ui/CheckboxTree.java
+++ b/platform/platform-impl/src/com/intellij/ui/CheckboxTree.java
@@ -15,8 +15,6 @@
*/
package com.intellij.ui;
-import java.awt.event.KeyEvent;
-
/**
* User: lex
* Date: Sep 18, 2003
@@ -56,11 +54,4 @@ public class CheckboxTree extends CheckboxTreeBase {
protected void installSpeedSearch() {
new TreeSpeedSearch(this);
}
-
-
- protected boolean isToggleEvent(KeyEvent e) {
- return super.isToggleEvent(e) && !SpeedSearchBase.hasActiveSpeedSearch(this);
- }
-
-
}
diff --git a/platform/platform-impl/src/com/intellij/ui/CheckboxTreeTable.java b/platform/platform-impl/src/com/intellij/ui/CheckboxTreeTable.java
new file mode 100644
index 000000000000..369dd0cc1803
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/CheckboxTreeTable.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui;
+
+import com.intellij.ui.dualView.TreeTableView;
+import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
+import com.intellij.ui.treeStructure.treetable.TreeTableTree;
+import com.intellij.util.EventDispatcher;
+import com.intellij.util.ui.ColumnInfo;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class CheckboxTreeTable extends TreeTableView {
+ private final EventDispatcher<CheckboxTreeListener> myEventDispatcher;
+
+ public CheckboxTreeTable(CheckedTreeNode root, CheckboxTree.CheckboxTreeCellRenderer renderer, final ColumnInfo[] columns) {
+ super(new ListTreeTableModelOnColumns(root, columns));
+ final TreeTableTree tree = getTree();
+ myEventDispatcher = EventDispatcher.create(CheckboxTreeListener.class);
+ CheckboxTreeHelper helper = new CheckboxTreeHelper(CheckboxTreeHelper.DEFAULT_POLICY, myEventDispatcher);
+ helper.initTree(tree, this, renderer);
+ tree.setSelectionRow(0);
+ }
+
+ public void addCheckboxTreeListener(@NotNull CheckboxTreeListener listener) {
+ myEventDispatcher.addListener(listener);
+ }
+
+ public <T> T[] getCheckedNodes(final Class<T> nodeType) {
+ return CheckboxTreeHelper.getCheckedNodes(nodeType, null, getTree().getModel());
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java b/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java
index 39c8aaf41ace..d5fc8dcca1ba 100644
--- a/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/JBTabsPaneImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,8 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.tabs.*;
-import com.intellij.ui.tabs.impl.JBTabsImpl;
+import com.intellij.ui.tabs.impl.JBEditorTabs;
+import com.intellij.ui.tabs.impl.TabLabel;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,7 +39,45 @@ public class JBTabsPaneImpl implements TabbedPane, SwingConstants {
private final CopyOnWriteArraySet<ChangeListener> myListeners = new CopyOnWriteArraySet<ChangeListener>();
public JBTabsPaneImpl(@Nullable Project project, int tabPlacement, @NotNull Disposable parent) {
- myTabs = new JBTabsImpl(project, ActionManager.getInstance(), project == null ? null : IdeFocusManager.getInstance(project), parent);
+ myTabs = new JBEditorTabs(project, ActionManager.getInstance(), project == null ? null : IdeFocusManager.getInstance(project), parent) {
+ @Override
+ public boolean isAlphabeticalMode() {
+ return false;
+ }
+
+ @Override
+ protected void doPaintBackground(Graphics2D g2d, Rectangle clip) {
+ super.doPaintBackground(g2d, clip);
+ if (getTabsPosition() == JBTabsPosition.top && isSingleRow()) {
+ int maxOffset = 0;
+ int maxLength = 0;
+
+ for (int i = getVisibleInfos().size() - 1; i >= 0; i--) {
+ TabInfo visibleInfo = getVisibleInfos().get(i);
+ TabLabel tabLabel = myInfo2Label.get(visibleInfo);
+ Rectangle r = tabLabel.getBounds();
+ if (r.width == 0 || r.height == 0) continue;
+ maxOffset = r.x + r.width;
+ maxLength = r.height;
+ break;
+ }
+
+ maxOffset++;
+ g2d.setPaint(UIUtil.getPanelBackground());
+ g2d.fillRect(clip.x + maxOffset, clip.y, clip.width - maxOffset, clip.y + maxLength - TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT);
+ g2d.setPaint(new JBColor(Gray._181, UIUtil.getPanelBackground()));
+ g2d.drawLine(clip.x + maxOffset, clip.y + maxLength - TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT, clip.x + clip.width, clip.y + maxLength - TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT);
+ g2d.setPaint(UIUtil.getPanelBackground());
+ g2d.drawLine(clip.x, clip.y + maxLength, clip.width, clip.y + maxLength);
+ }
+ }
+
+ @Override
+ protected void paintSelectionAndBorder(Graphics2D g2d) {
+ super.paintSelectionAndBorder(g2d);
+ }
+ };
+
myTabs.addListener(new TabsListener.Adapter() {
@Override
public void selectionChanged(TabInfo oldSelection, TabInfo newSelection) {
diff --git a/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java b/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java
index 99c41b52cbea..e219b778f44d 100644
--- a/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java
+++ b/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package com.intellij.ui;
import com.intellij.icons.AllIcons;
+import com.intellij.openapi.ui.Divider;
import com.intellij.openapi.ui.PseudoSplitter;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.vcs.changes.RefreshablePanel;
@@ -41,7 +42,7 @@ public abstract class SplitterWithSecondHideable {
private final boolean myVertical;
private final OnOffListener<Integer> myListener;
private final JPanel myFictivePanel;
- private Splitter.Divider mySuperDivider;
+ private Splitter.DividerImpl mySuperDivider;
private float myPreviousProportion;
public SplitterWithSecondHideable(final boolean vertical,
@@ -185,7 +186,7 @@ public abstract class SplitterWithSecondHideable {
return vertical ? myTitledSeparator.getHeight() : myTitledSeparator.getWidth();
}
- class MyDivider extends Divider {
+ class MyDivider extends DividerImpl {
@Override
public void processMouseMotionEvent(MouseEvent e) {
super.processMouseMotionEvent(e);
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
index 78802ccdf6bb..e50403abef45 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java
@@ -162,6 +162,25 @@ public class AbstractPopup implements JBPopup {
private UiActivity myActivityKey;
private Disposable myProjectDisposable;
+ private volatile State myState = State.NEW;
+
+ private enum State {NEW, INIT, SHOWING, SHOWN, CANCEL, DISPOSE}
+
+ private void debugState(String message, State... states) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(hashCode() + " - " + message);
+ if (!ApplicationManager.getApplication().isDispatchThread()) {
+ LOG.debug("unexpected thread");
+ }
+ for (State state : states) {
+ if (state == myState) {
+ return;
+ }
+ }
+ LOG.debug(new IllegalStateException("myState=" + myState));
+ }
+ }
+
AbstractPopup() { }
AbstractPopup init(Project project,
@@ -302,6 +321,8 @@ public class AbstractPopup implements JBPopup {
}
myKeyEventHandler = keyEventHandler;
+ debugState("popup initialized", State.NEW);
+ myState = State.INIT;
return this;
}
@@ -582,10 +603,18 @@ public class AbstractPopup implements JBPopup {
@Override
public void cancel(InputEvent e) {
+ if (myState == State.CANCEL || myState == State.DISPOSE) {
+ return;
+ }
+ debugState("cancel popup", State.SHOWN);
+ myState = State.CANCEL;
+
if (isDisposed()) return;
if (myPopup != null) {
if (!canClose()) {
+ debugState("cannot cancel popup", State.CANCEL);
+ myState = State.SHOWN;
return;
}
storeDimensionSize(myContent.getSize());
@@ -610,8 +639,13 @@ public class AbstractPopup implements JBPopup {
}
if (myInStack) {
- myFocusTrackback.setForcedRestore(!myOk && myFocusable);
- myFocusTrackback.restoreFocus();
+ if (myFocusTrackback != null) {
+ myFocusTrackback.setForcedRestore(!myOk && myFocusable);
+ myFocusTrackback.restoreFocus();
+ }
+ else if (LOG.isDebugEnabled()) {
+ LOG.debug("cancel before show @ " + Thread.currentThread());
+ }
}
@@ -664,6 +698,9 @@ public class AbstractPopup implements JBPopup {
assert ApplicationManager.getApplication().isDispatchThread();
+ debugState("show popup", State.INIT);
+ myState = State.SHOWING;
+
installWindowHook(this);
installProjectDisposer();
addActivity();
@@ -673,6 +710,8 @@ public class AbstractPopup implements JBPopup {
final boolean shouldShow = beforeShow();
if (!shouldShow) {
removeActivity();
+ debugState("rejected to show popup", State.SHOWING);
+ myState = State.INIT;
return;
}
@@ -758,10 +797,11 @@ public class AbstractPopup implements JBPopup {
PopupComponent.Factory factory = getFactory(myForcedHeavyweight || myResizable, forcedDialog);
myNativePopup = factory.isNativePopup();
Component popupOwner = myOwner;
- if (popupOwner instanceof RootPaneContainer) {
+ if (popupOwner instanceof RootPaneContainer && !(popupOwner instanceof IdeFrame && !Registry.is("popup.fix.ide.frame.owner"))) {
// JDK uses cached heavyweight popup for a window ancestor
RootPaneContainer root = (RootPaneContainer)popupOwner;
popupOwner = root.getRootPane();
+ LOG.debug("popup owner fixed for JDK cache");
}
if (LOG.isDebugEnabled()) {
LOG.debug("expected preferred size: " + myContent.getPreferredSize());
@@ -957,6 +997,8 @@ public class AbstractPopup implements JBPopup {
}
});
}
+ debugState("popup shown", State.SHOWING);
+ myState = State.SHOWN;
}
public void focusPreferredComponent() {
@@ -1232,6 +1274,16 @@ public class AbstractPopup implements JBPopup {
@Override
public void dispose() {
+ if (myState == State.SHOWN) {
+ LOG.debug("shown popup must be cancelled");
+ cancel();
+ }
+ if (myState == State.DISPOSE) {
+ return;
+ }
+ debugState("dispose popup", State.INIT, State.CANCEL);
+ myState = State.DISPOSE;
+
if (myDisposed) {
return;
}
@@ -1480,8 +1532,8 @@ public class AbstractPopup implements JBPopup {
@Override
public Dimension getSize() {
if (myPopup != null) {
- final Window popupWindow = SwingUtilities.windowForComponent(myContent);
- return popupWindow.getSize();
+ final Window popupWindow = getContentWindow(myContent);
+ return (popupWindow == null) ? myForcedSize : popupWindow.getSize();
} else {
return myForcedSize;
}
@@ -1491,7 +1543,8 @@ public class AbstractPopup implements JBPopup {
public void moveToFitScreen() {
if (myPopup == null) return;
- final Window popupWindow = SwingUtilities.windowForComponent(myContent);
+ final Window popupWindow = getContentWindow(myContent);
+ if (popupWindow == null) return;
Rectangle bounds = popupWindow.getBounds();
ScreenUtil.moveRectangleToFitTheScreen(bounds);
@@ -1501,7 +1554,8 @@ public class AbstractPopup implements JBPopup {
public static Window setSize(JComponent content, final Dimension size) {
- final Window popupWindow = SwingUtilities.windowForComponent(content);
+ final Window popupWindow = getContentWindow(content);
+ if (popupWindow == null) return null;
Insets insets = content.getInsets();
if (insets != null) {
size.width += insets.left + insets.right;
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java
new file mode 100644
index 000000000000..2a79368f65bb
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui.popup;
+
+import com.intellij.openapi.util.registry.Registry;
+
+import javax.swing.Popup;
+import java.awt.Component;
+import java.awt.GraphicsEnvironment;
+
+/**
+ * @author Sergey Malenkov
+ */
+public final class OurHeavyWeightPopup extends Popup {
+ public OurHeavyWeightPopup(Component owner, Component content, int x, int y) {
+ super(owner, content, x, y);
+ }
+
+ public static boolean isEnabled() {
+ return !GraphicsEnvironment.isHeadless() && Registry.is("our.heavy.weight.popup");
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java
index 301758511612..1670491b91bf 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,6 +58,9 @@ public interface PopupComponent {
class AwtHeavyweight implements Factory {
public PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup) {
+ if (OurHeavyWeightPopup.isEnabled()) {
+ return new AwtPopupWrapper(new OurHeavyWeightPopup(owner, content, x, y), jbPopup);
+ }
final PopupFactory factory = PopupFactory.getSharedInstance();
final int oldType = PopupUtil.getPopupType(factory);
@@ -172,7 +175,7 @@ public interface PopupComponent {
myJBPopup = jbPopup;
if (SystemInfo.isMac && UIUtil.isUnderAquaLookAndFeel()) {
- final Component c = (Component)ReflectionUtil.getField(Popup.class, myPopup, Component.class, "component");
+ final Component c = ReflectionUtil.getField(Popup.class, myPopup, Component.class, "component");
c.setBackground(UIUtil.getPanelBackground());
}
}
@@ -220,7 +223,7 @@ public interface PopupComponent {
}
public Window getWindow() {
- final Component c = (Component)ReflectionUtil.getField(Popup.class, myPopup, Component.class, "component");
+ final Component c = ReflectionUtil.getField(Popup.class, myPopup, Component.class, "component");
return c instanceof JWindow ? (JWindow)c : null;
}
diff --git a/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java b/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java
index ac4c1b12373c..35719ca9366b 100644
--- a/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java
+++ b/platform/platform-impl/src/com/intellij/util/ui/SwingHelper.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.util.ui;
import com.intellij.ide.BrowserUtil;
@@ -48,7 +63,7 @@ public class SwingHelper {
* stacked vertically each on another in a given order.
*
* @param childAlignmentX Component.LEFT_ALIGNMENT, Component.CENTER_ALIGNMENT or Component.RIGHT_ALIGNMENT
- * @param children children components
+ * @param children children components
* @return created panel
*/
@NotNull
@@ -76,7 +91,7 @@ public class SwingHelper {
* stacked each on another in a given order.
*
* @param childAlignmentY Component.TOP_ALIGNMENT, Component.CENTER_ALIGNMENT or Component.BOTTOM_ALIGNMENT
- * @param children children components
+ * @param children children components
* @return created panel
*/
@NotNull
@@ -98,10 +113,11 @@ public class SwingHelper {
for (Component child : children) {
panel.add(child, childAlignment);
if (child instanceof JComponent) {
- JComponent jChild = (JComponent) child;
+ JComponent jChild = (JComponent)child;
if (verticalOrientation) {
jChild.setAlignmentX(childAlignment);
- } else {
+ }
+ else {
jChild.setAlignmentY(childAlignment);
}
}
@@ -259,20 +275,7 @@ public class SwingHelper {
textFieldWithHistory.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
- List<String> newHistory = historyProvider.produce();
- Set<String> newHistorySet = ContainerUtil.newHashSet(newHistory);
- List<String> oldHistory = textFieldWithHistory.getHistory();
- List<String> mergedHistory = ContainerUtil.newArrayList();
- for (String item : oldHistory) {
- if (!newHistorySet.contains(item)) {
- mergedHistory.add(item);
- }
- }
- mergedHistory.addAll(newHistory);
- textFieldWithHistory.setHistory(mergedHistory);
-
- setLongestAsPrototype(textFieldWithHistory, mergedHistory);
-
+ setHistory(textFieldWithHistory, historyProvider.produce(), true);
// one-time initialization
textFieldWithHistory.removePopupMenuListener(this);
}
@@ -287,11 +290,35 @@ public class SwingHelper {
});
}
+ public static void setHistory(@NotNull TextFieldWithHistory textFieldWithHistory,
+ @NotNull List<String> history,
+ boolean mergeWithPrevHistory) {
+ Set<String> newHistorySet = ContainerUtil.newHashSet(history);
+ List<String> prevHistory = textFieldWithHistory.getHistory();
+ List<String> mergedHistory = ContainerUtil.newArrayList();
+ if (mergeWithPrevHistory) {
+ for (String item : prevHistory) {
+ if (!newHistorySet.contains(item)) {
+ mergedHistory.add(item);
+ }
+ }
+ }
+ else {
+ String currentText = textFieldWithHistory.getText();
+ if (StringUtil.isNotEmpty(currentText) && !newHistorySet.contains(currentText)) {
+ mergedHistory.add(currentText);
+ }
+ }
+ mergedHistory.addAll(history);
+ textFieldWithHistory.setHistory(mergedHistory);
+ setLongestAsPrototype(textFieldWithHistory, mergedHistory);
+ }
+
private static void setLongestAsPrototype(@NotNull JComboBox comboBox, @NotNull List<String> variants) {
Object prototypeDisplayValue = comboBox.getPrototypeDisplayValue();
String prototypeDisplayValueStr = null;
if (prototypeDisplayValue instanceof String) {
- prototypeDisplayValueStr = (String) prototypeDisplayValue;
+ prototypeDisplayValueStr = (String)prototypeDisplayValue;
}
else if (prototypeDisplayValue != null) {
return;
@@ -413,15 +440,38 @@ public class SwingHelper {
return textPane;
}
- public static void setHtml(@NotNull JEditorPane editorPane, @NotNull String bodyInnerHtml) {
+ public static void setHtml(@NotNull JEditorPane editorPane,
+ @NotNull String bodyInnerHtml,
+ @Nullable Color foregroundColor) {
String html = String.format(
"<html><head>%s</head><body>%s</body></html>",
- UIUtil.getCssFontDeclaration(editorPane.getFont(), null, null, null),
+ UIUtil.getCssFontDeclaration(editorPane.getFont(), foregroundColor, null, null),
bodyInnerHtml
);
editorPane.setText(html);
}
+ @NotNull
+ public static TextFieldWithHistoryWithBrowseButton createTextFieldWithHistoryWithBrowseButton(@Nullable Project project,
+ @NotNull String browseDialogTitle,
+ @NotNull FileChooserDescriptor fileChooserDescriptor,
+ @Nullable NotNullProducer<List<String>> historyProvider) {
+ TextFieldWithHistoryWithBrowseButton textFieldWithHistoryWithBrowseButton = new TextFieldWithHistoryWithBrowseButton();
+ TextFieldWithHistory textFieldWithHistory = textFieldWithHistoryWithBrowseButton.getChildComponent();
+ textFieldWithHistory.setHistorySize(-1);
+ textFieldWithHistory.setMinimumAndPreferredWidth(0);
+ if (historyProvider != null) {
+ addHistoryOnExpansion(textFieldWithHistory, historyProvider);
+ }
+ installFileCompletionAndBrowseDialog(
+ project,
+ textFieldWithHistoryWithBrowseButton,
+ browseDialogTitle,
+ fileChooserDescriptor
+ );
+ return textFieldWithHistoryWithBrowseButton;
+ }
+
private static class CopyLinkAction extends AnAction {
private final String myUrl;
diff --git a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
index a7d09ab548f2..7310b936246d 100644
--- a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
+++ b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
@@ -170,7 +170,7 @@ public class BuiltInServer implements Disposable {
@Override
protected boolean process(ChannelHandlerContext context, FullHttpRequest request, QueryStringDecoder urlDecoder) throws IOException {
- return (request.getMethod() == HttpMethod.POST || request.getMethod() == HttpMethod.OPTIONS) &&
+ return (request.method() == HttpMethod.POST || request.method() == HttpMethod.OPTIONS) &&
XmlRpcServer.SERVICE.getInstance().process(urlDecoder.path(), request, context, handlers);
}
}
diff --git a/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java b/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
index 3f88327d3d28..1dbf57785dac 100644
--- a/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
+++ b/platform/platform-impl/src/org/jetbrains/io/PortUnificationServerHandler.java
@@ -113,7 +113,7 @@ class PortUnificationServerHandler extends Decoder {
@Override
public void write(ChannelHandlerContext context, Object message, ChannelPromise promise) throws Exception {
if (message instanceof HttpResponse) {
-// BuiltInServer.LOG.debug("OUT HTTP:\n" + message);
+ //BuiltInServer.LOG.debug("OUT HTTP:\n" + message);
HttpResponse response = (HttpResponse)message;
BuiltInServer.LOG.debug("OUT HTTP: " + response.status().code() + " " + response.headers().get(CONTENT_TYPE));
}
diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties
index 1c05af27102c..47c4cef92207 100644
--- a/platform/platform-resources-en/src/messages/ActionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties
@@ -596,6 +596,8 @@ action.MemberPushDown.text=Pu_sh Members Down...
action.MemberPushDown.description=Push class members down to directly inheriting subclasses
action.InheritanceToDelegation.text=Replace _Inheritance with Delegation...
action.InheritanceToDelegation.description=Replace inheritance with delegation
+action.RenameFile.text=Rename File...
+action.RenameFile.description=Rename selected file
action.Inline.text=I_nline...
action.Inline.description=Inline the selected method or variable
action.AnonymousToInner.text=Convert Anon_ymous to Inner...
@@ -1014,8 +1016,8 @@ action.Vcs.ShowDiffAction.text=Show Changes
action.Vcs.ShowDiffAction.description=Show changes
action.Vcs.RollbackChanges.text=Rollback Changes
action.Vcs.RollbackChanges.description=Rollback changes
-action.RollbackLineStatusChanges.text=Rollback
-action.RollbackLineStatusChanges.description=Rollback selected local changes
+action.Vcs.RollbackChangedLines.text=Rollback
+action.Vcs.RollbackChangedLines.description=Rollback changes in selected lines
action.Vcs.EditSourceAction.text=Edit Source
action.Vcs.EditSourceAction.description=Edit source
action.Vcs.ExcludeAction.text=Exclude from Commit
diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties
index bbd737afedf1..5d539357ca3d 100644
--- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties
+++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties
@@ -360,6 +360,7 @@ label.collapse.by.default=Collapse by default:
checkbox.show.code.folding.outline=Show code folding outline
group.tab.appearance=Tab Appearance
editbox.tab.limit=Tab limit:
+editbox.tab.title.limit=Tab title limit:
combobox.editor.tab.placement=Placement:
checkbox.editor.tabs.in.single.row=Show tabs in single row
checkbox.editor.tabs.show.close.button=Show "close" button on editor tabs
diff --git a/platform/platform-resources-en/src/messages/CommonBundle.properties b/platform/platform-resources-en/src/messages/CommonBundle.properties
index 46750d536a06..1fbbd0a61f57 100644
--- a/platform/platform-resources-en/src/messages/CommonBundle.properties
+++ b/platform/platform-resources-en/src/messages/CommonBundle.properties
@@ -31,7 +31,6 @@ action.close=&Close
action.help=Help
action.rerun=Rerun
button.reset=&Reset
-button.reset.to.default=&Reset to Default
button.delete=Delete
button.copy=Copy...
button.close=&Close
diff --git a/platform/platform-resources-en/src/messages/DiffBundle.properties b/platform/platform-resources-en/src/messages/DiffBundle.properties
index 598cc9714697..aafd6884a3d6 100644
--- a/platform/platform-resources-en/src/messages/DiffBundle.properties
+++ b/platform/platform-resources-en/src/messages/DiffBundle.properties
@@ -67,6 +67,8 @@ merge.partial.diff.action.name.0.1=Compare left and middle panel contents
merge.partial.diff.action.name.1.2=Compare middle and right panel contents
merge.dialog.exit.without.applying.changes.confirmation.message=Are you sure you want to exit without applying changes?
cancel.visual.merge.dialog.title=Cancel Visual Merge
+merge.dialog.apply.partially.resolved.changes.confirmation.message=There are {0, choice, 0#|1#one change|2#{0, number} changes}{0, choice, 0#|1#'{1, choice, 0#|1# and }'}{1, choice, 0#|1#one conflict|2#{1, number} conflicts} left unprocessed.\nAre you sure you want to save changes and finish merging?
+apply.partially.resolved.merge.dialog.title=Apply Changes
merge.all.changes.have.processed.save.and.finish.confirmation.text=All changes have been processed.\nWould you like to save changes and finish merging?
all.changes.processed.dialog.title=All Changes Processed
merge.save.and.finish.button=Save and &Finish
diff --git a/platform/platform-resources-en/src/messages/FindBundle.properties b/platform/platform-resources-en/src/messages/FindBundle.properties
index 293d013fe8d6..8a857db74fd0 100644
--- a/platform/platform-resources-en/src/messages/FindBundle.properties
+++ b/platform/platform-resources-en/src/messages/FindBundle.properties
@@ -29,6 +29,7 @@ find.open.in.new.tab.checkbox=Open in new ta&b
find.options.group=Options
find.options.search.for.text.occurences.checkbox=Search for text &occurrences
find.options.skip.results.tab.with.one.usage.checkbox=S&kip results tab with one usage
+find.options.skip.results.tab.with.one.occurrence.checkbox=S&kip results tab when only one occurrence is found
find.options.include.overloaded.methods.checkbox=Include o&verloaded methods
find.scope.label=&Scope
find.searched.elements.have.been.changed.error=Searched elements have been changed.\nCannot search for usages.
@@ -69,6 +70,14 @@ find.text.to.find.label=Text to &find:
find.replace.with.label=Replace &with:
find.filter.file.name.group=File name filter
find.filter.file.mask.checkbox=File m&ask(s)
+find.context.combo.label=Conte&xt:
+find.context.anywhere.scope.label=anywhere
+find.context.in.comments.scope.label=in comments
+find.context.in.literals.scope.label=in string literals
+find.context.except.literals.scope.label=except string literals
+find.context.except.comments.scope.label=except comments
+find.context.except.comments.and.literals.scope.label=except comments and string literals
+
find.directory.not.found.error=Directory {0} is not found
find.invalid.regular.expression.error=Bad pattern \"{0}\": {1}
find.empty.match.regular.expression.error=Regular expression matches empty string
diff --git a/platform/platform-resources-en/src/messages/VcsBundle.properties b/platform/platform-resources-en/src/messages/VcsBundle.properties
index 3d34252c9c7a..573cff8e6261 100644
--- a/platform/platform-resources-en/src/messages/VcsBundle.properties
+++ b/platform/platform-resources-en/src/messages/VcsBundle.properties
@@ -308,7 +308,7 @@ changes.action.rollback.custom.title={0} Changes
changes.action.rollback.nothing=Nothing to {0}
changes.dialog.editchangelist.error.already.exists=A changelist named ''{0}'' already exists
error.adding.files.prompt=The following problems have occurred when adding the files:
-error.adding.files.title=Error adding files
+error.adding.files.title=Error Adding Files
column.name.revision.list.committer=User
column.name.revision.list.number=Number
column.name.revision.list.description=Description
diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
index 878c814e4764..058e446bc896 100644
--- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
+++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
@@ -3,6 +3,8 @@ xdebugger.colors.page.name=Debugger
debugger.configurable.display.name=Debugger
debugger.dataViews.display.name=Data Views
debugger.stepping.display.name=Stepping
+# suppress inspection "UnusedProperty"
+debugger.hotswap.display.name=HotSwap
xdebugger.default.content.title=Debug
xdebugger.debugger.tab.title=Debugger
diff --git a/platform/platform-resources-en/src/messages/XmlBundle.properties b/platform/platform-resources-en/src/messages/XmlBundle.properties
index 70e26de6ffeb..7343727c5b72 100644
--- a/platform/platform-resources-en/src/messages/XmlBundle.properties
+++ b/platform/platform-resources-en/src/messages/XmlBundle.properties
@@ -233,3 +233,6 @@ start.browser.with.js.debugger=with &JavaScript debugger
javascript.debugger.settings.choose.file.title=Select
javascript.debugger.settings.choose.file.subtitle=Select file to debug JavaScript in
+
+setting.value.builtin.server.port.label=Built-in server &port:
+setting.value.can.accept.external.connections=Can accept &external connections \ No newline at end of file
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index 1f40bacf983c..7aa76abcd4f8 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -57,6 +57,9 @@
<applicationService serviceInterface="com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter"
serviceImplementation="com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter" />
+ <applicationService serviceInterface="com.intellij.openapi.editor.EditorCopyPasteHelper"
+ serviceImplementation="com.intellij.openapi.editor.impl.EditorCopyPasteHelperImpl" />
+
<applicationService serviceImplementation="com.intellij.openapi.options.ex.IdeConfigurablesGroup"/>
<applicationService serviceInterface="com.intellij.diagnostic.ErrorReportConfigurable"
@@ -190,7 +193,8 @@
<projectService serviceInterface="com.intellij.openapi.vcs.VcsFileListenerContextHelper"
serviceImplementation="com.intellij.openapi.vcs.VcsFileListenerContextHelper"/>
- <projectService serviceImplementation="com.intellij.openapi.editor.LazyRangeMarkerFactory"/>
+ <projectService serviceInterface="com.intellij.openapi.editor.LazyRangeMarkerFactory"
+ serviceImplementation="com.intellij.openapi.editor.impl.LazyRangeMarkerFactoryImpl"/>
<!-- General -->
<applicationConfigurable groupId="appearance" key="title.general" bundle="messages.IdeBundle" id="preferences.general" instance="com.intellij.ide.GeneralSettingsConfigurable"/>
diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml
index 9a737df77ef6..525ea3c94540 100644
--- a/platform/platform-resources/src/META-INF/XmlPlugin.xml
+++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml
@@ -89,6 +89,10 @@
</extensionPoint>
<extensionPoint name="xml.undefinedElementFixProvider" interface="com.intellij.xml.XmlUndefinedElementFixProvider"/>
+
+ <extensionPoint qualifiedName="org.jetbrains.webServerPathHandler" interface="org.jetbrains.builtInWebServer.WebServerPathHandler"/>
+ <extensionPoint qualifiedName="org.jetbrains.webServerFileHandler" interface="org.jetbrains.builtInWebServer.WebServerFileHandler"/>
+ <extensionPoint qualifiedName="org.jetbrains.webServerRootsProvider" interface="org.jetbrains.builtInWebServer.WebServerRootsProvider"/>
</extensionPoints>
<project-components>
@@ -530,8 +534,21 @@
<applicationConfigurable groupId="tools" instance="com.intellij.ide.browsers.BrowserSettings" id="reference.settings.ide.settings.web.browsers"
key="browsers.settings" bundle="messages.IdeBundle"/>
<lang.inspectionSuppressor language="XML" implementationClass="com.intellij.codeInspection.XmlInspectionSuppressor"/>
+
+ <httpRequestHandler implementation="org.jetbrains.builtInWebServer.BuiltInWebServer"/>
+ <webBrowserUrlProvider implementation="org.jetbrains.builtInWebServer.BuiltInWebBrowserUrlProvider"/>
+
+ <customPortServerManager implementation="org.jetbrains.builtInWebServer.BuiltInServerOptions$MyCustomPortServerManager"/>
+ <xdebugger.configurableProvider implementation="org.jetbrains.builtInWebServer.BuiltInServerOptions$BuiltInServerDebuggerConfigurableProvider"/>
+
+ <exportable serviceInterface="org.jetbrains.builtInWebServer.BuiltInServerOptions"/>
+ <applicationService serviceInterface="org.jetbrains.builtInWebServer.BuiltInServerOptions" serviceImplementation="org.jetbrains.builtInWebServer.BuiltInServerOptions"/>
+ <projectService serviceInterface="org.jetbrains.builtInWebServer.WebServerPathToFileManager" serviceImplementation="org.jetbrains.builtInWebServer.WebServerPathToFileManager"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains">
<urlOpener implementation="com.intellij.ide.browsers.impl.DefaultUrlOpener" order="last"/>
+ <webServerPathHandler implementation="org.jetbrains.builtInWebServer.DefaultWebServerPathHandler"/>
+ <webServerFileHandler implementation="org.jetbrains.builtInWebServer.BuiltInWebServer$StaticFileHandler" order="last"/>
+ <webServerRootsProvider implementation="org.jetbrains.builtInWebServer.DefaultWebServerRootsProvider"/>
</extensions>
</idea-plugin>
diff --git a/platform/platform-resources/src/META-INF/xdebugger.xml b/platform/platform-resources/src/META-INF/xdebugger.xml
index 68111b8eb7b2..4b03978f9473 100644
--- a/platform/platform-resources/src/META-INF/xdebugger.xml
+++ b/platform/platform-resources/src/META-INF/xdebugger.xml
@@ -10,6 +10,7 @@
<extensionPoint name="xdebugger.settings" interface="com.intellij.xdebugger.settings.XDebuggerSettings"/>
<extensionPoint name="xdebugger.breakpointType" interface="com.intellij.xdebugger.breakpoints.XBreakpointType"/>
<extensionPoint name="xdebugger.debuggerSupport" interface="com.intellij.xdebugger.impl.DebuggerSupport"/>
+ <extensionPoint name="xdebugger.configurableProvider" interface="com.intellij.xdebugger.settings.DebuggerConfigurableProvider"/>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
@@ -29,11 +30,12 @@
<projectService serviceInterface="com.intellij.xdebugger.impl.XDebuggerHistoryManager"
serviceImplementation="com.intellij.xdebugger.impl.XDebuggerHistoryManager"/>
- <applicationConfigurable groupId="build" dynamic="true" key="debugger.configurable.display.name" bundle="messages.XDebuggerBundle" provider="com.intellij.xdebugger.impl.settings.DebuggerConfigurableProvider"/>
+ <applicationConfigurable groupId="build" dynamic="true" key="debugger.configurable.display.name" bundle="messages.XDebuggerBundle" instance="com.intellij.xdebugger.impl.settings.DebuggerConfigurable"/>
<customizableActionGroupProvider implementation="com.intellij.xdebugger.impl.ui.XDebugTabCustomizableActionGroupProvider"/>
<xdebugger.debuggerSupport implementation="com.intellij.xdebugger.impl.XDebuggerSupport" order="first"/>
+ <xdebugger.configurableProvider implementation="com.intellij.xdebugger.impl.settings.XDebuggerConfigurableProvider" order="first"/>
<executor implementation="com.intellij.execution.executors.DefaultDebugExecutor" order="first,after run"/>
</extensions>
diff --git a/platform/platform-resources/src/brokenPlugins.txt b/platform/platform-resources/src/brokenPlugins.txt
index 438c23f2ffd2..57b863fb916b 100644
--- a/platform/platform-resources/src/brokenPlugins.txt
+++ b/platform/platform-resources/src/brokenPlugins.txt
@@ -1,15 +1,14 @@
// This file contains list of broken plugins.
// Each line contains plugin ID and list of versions that are broken.
// If plugin name or version contains a space you can quote it like in command line.
-
-NodeJS 138.921 138.447 138.172 138.317 138.21 138.35 138.96 138.85 136.1205 134.1276 134.1163 134.1145 134.1081 134.1039 134.985 134.680 134.31 134.307 134.262 134.198 134.125 136.1141
-com.jetbrains.php 136.1768 136.1672 134.1456 133.982 133.679 133.51 133.326 131.98 131.374 131.332 131.235 131.205 130.1639 130.1481 130.1176 129.91 129.814 129.672 129.362 127.67 127.100 126.334 123.66 122.875 121.62 121.390 121.215 121.12
+NodeJS 138.937 138.1013 138.921 138.447 138.172 138.317 138.21 138.35 138.96 138.85 136.1205 134.1276 134.1163 134.1145 134.1081 134.1039 134.985 134.680 134.31 134.307 134.262 134.198 134.125 136.1141
+com.jetbrains.php 138.826 136.1768 136.1672 134.1456 133.982 133.679 133.51 133.326 131.98 131.374 131.332 131.235 131.205 130.1639 130.1481 130.1176 129.91 129.814 129.672 129.362 127.67 127.100 126.334 123.66 122.875 121.62 121.390 121.215 121.12
com.jetbrains.lang.ejs 131.17 131.12
com.jetbrains.twig 133.51 130.1639
-org.jetbrains.plugins.ruby 6.0.0.20140207 6.5.2.20140512 7.0.0.20140704
-Pythonid 3.1
+org.jetbrains.plugins.ruby 6.0.0.20140207 6.5.2.20140512 7.0.0.20140704 7.0.0.20140707
+Pythonid 3.1 4.0.25
Karma 138.21 134.1163 134.1039 134.686 134.31
-org.intellij.scala 0.32.593 0.32.562 0.32.558 0.32.550 0.32.520 0.32.512
+org.intellij.scala 0.40.20 0.40.18 0.40.16 0.32.593 0.32.562 0.32.558 0.32.550 0.32.520 0.32.512
org.jetbrains.kannotator 0.2.420
org.jetbrains.kotlin 0.7.1360 0.7.1376 0.8.7
SBT 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.4.0 1.5.0
diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml
index 58d6f3a76d27..3508b1d0112e 100644
--- a/platform/platform-resources/src/idea/Keymap_Default.xml
+++ b/platform/platform-resources/src/idea/Keymap_Default.xml
@@ -506,6 +506,9 @@
<action id="EditorPasteFromX11">
<mouse-shortcut keystroke="button2"/>
</action>
+ <action id="Vcs.RollbackChangedLines">
+ <keyboard-shortcut first-keystroke="control alt Z"/>
+ </action>
<action id="GotoNextError">
<keyboard-shortcut first-keystroke="F2"/>
diff --git a/platform/platform-resources/src/idea/Keymap_EclipseMac.xml b/platform/platform-resources/src/idea/Keymap_EclipseMac.xml
index dc1dcb5e66ec..f35e24c776b0 100644
--- a/platform/platform-resources/src/idea/Keymap_EclipseMac.xml
+++ b/platform/platform-resources/src/idea/Keymap_EclipseMac.xml
@@ -312,6 +312,10 @@
<keyboard-shortcut first-keystroke="meta 3"/>
</action>
+ <action id="Vcs.RollbackChangedLines">
+ <keyboard-shortcut first-keystroke="control shift alt Z"/>
+ </action>
+
<action id="ActivateProjectToolWindow"/>
<action id="ActivateFavoritesToolWindow"/>
<action id="ActivateFindToolWindow">
diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml
index 9cebd282ded6..869a8a754886 100644
--- a/platform/platform-resources/src/idea/PlatformActions.xml
+++ b/platform/platform-resources/src/idea/PlatformActions.xml
@@ -563,7 +563,6 @@
</group>
<group id="DiffPanel.Toolbar">
- <reference ref="$Copy"/>
<reference ref="PreviousDiff"/>
<reference ref="NextDiff"/>
<separator/>
diff --git a/platform/platform-resources/src/idea/VcsActions.xml b/platform/platform-resources/src/idea/VcsActions.xml
index dc15f19282bf..5496ab6bf3e7 100644
--- a/platform/platform-resources/src/idea/VcsActions.xml
+++ b/platform/platform-resources/src/idea/VcsActions.xml
@@ -265,7 +265,7 @@
<add-to-group group-id="CloseEditorsGroup" anchor="before" relative-to-action="CloseAllUnpinnedEditors"/>
</action>
- <action id="RollbackLineStatusChanges" class="com.intellij.openapi.vcs.ex.RollbackLineStatusAction">
+ <action id="Vcs.RollbackChangedLines" class="com.intellij.openapi.vcs.ex.RollbackLineStatusAction" icon="AllIcons.Actions.Reset">
</action>
<action id="WelcomeScreen.GetFromVcs" class="com.intellij.openapi.wm.impl.welcomeScreen.GetFromVcsAction"
diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java
index a90148799f5d..dbc05f849a49 100644
--- a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java
@@ -202,42 +202,22 @@ public class ReformatFilesWithFiltersTest extends LightPlatformTestCase {
TestFileStructure fileTree = new TestFileStructure(getModule(), myWorkingDirectory);
fileTree.createDirectoryAndMakeItCurrent("src");
- PsiFile java2 = fileTree.addTestFile("Test2.java", "empty content");
+ PsiFile java2 = fileTree.addTestFile("Test2.tj", "empty content");
PsiFile php2 = fileTree.addTestFile("Pair2.php", "empty content");
PsiFile js2 = fileTree.addTestFile("Pair2.js", "empty content");
PsiDirectory test = fileTree.createDirectoryAndMakeItCurrent("test");
- PsiFile testJava1 = fileTree.addTestFile("testJava1.java", "empty content");
+ PsiFile testJava1 = fileTree.addTestFile("testJava1.tj", "empty content");
PsiFile testPhp1 = fileTree.addTestFile("testPhp1.php", "empty content");
PsiFile testJs1 = fileTree.addTestFile("testJs1.js", "empty content");
GlobalSearchScope testScope = directoryScope(test, true);
- Logger logger = Logger.getInstance(getClass());
- logFiles(logger, "Previously formatted files: ", myMockCodeStyleManager.getFormattedFiles());
-
- reformatWithRearrange(myWorkingDirectory, testScope);
- logFiles(logger, "Currently formatted files: ", myMockCodeStyleManager.getFormattedFiles());
- logFiles(logger, "Should be formatted", ContainerUtil.newArrayList(testJava1, testPhp1, testJs1));
-
- assertWasFormatted(testJava1, testPhp1, testJs1);
- assertWasNotFormatted(java2, php2, js2);
-
reformatAndOptimize(myWorkingDirectory, testScope);
assertWasFormatted(testJava1, testPhp1, testJs1);
assertWasNotFormatted(java2, php2, js2);
}
- private void logFiles(Logger log, String message, Collection<PsiFile> files) {
- StringBuilder builder;
- builder = new StringBuilder();
- builder.append(message).append('\n');
- for (PsiFile file : files) {
- builder.append(file).append('\n');
- }
- log.info(builder.toString());
- }
-
public void assertWasFormatted(PsiFile... files) {
final Set<PsiFile> formattedFiles = myMockCodeStyleManager.getFormattedFiles();
for (PsiFile file : files) {
diff --git a/platform/platform-tests/testSrc/com/intellij/history/core/PathsTest.java b/platform/platform-tests/testSrc/com/intellij/history/core/PathsTest.java
index 32f5ec2eb16e..f8bc13e05aed 100644
--- a/platform/platform-tests/testSrc/com/intellij/history/core/PathsTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/history/core/PathsTest.java
@@ -103,6 +103,11 @@ public class PathsTest extends LocalHistoryTestCase {
assertEquals(array("/", "foo"), ContainerUtil.collect(Paths.split("/foo").iterator()));
assertEquals(array("/"), ContainerUtil.collect(Paths.split("/").iterator()));
assertEquals(array("c:", "foo", "bar"), ContainerUtil.collect(Paths.split("c:/foo/bar").iterator()));
+
+ assertEquals(array("//"), ContainerUtil.collect(Paths.split("//").iterator()));
+ assertEquals(array("//foo"), ContainerUtil.collect(Paths.split("//foo").iterator()));
+ assertEquals(array("//foo"), ContainerUtil.collect(Paths.split("//foo/").iterator()));
+ assertEquals(array("//foo", "bar"), ContainerUtil.collect(Paths.split("//foo/bar").iterator()));
}
@Test
diff --git a/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java b/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java
index 5a47fdf4c5f3..db833c2d8f3e 100644
--- a/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/lang/PsiBuilderQuickTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,16 +18,14 @@ package com.intellij.lang;
import com.intellij.lang.impl.PsiBuilderImpl;
import com.intellij.lexer.Lexer;
import com.intellij.lexer.LexerBase;
+import com.intellij.openapi.fileTypes.PlainTextParserDefinition;
import com.intellij.openapi.project.Project;
-import com.intellij.psi.FileViewProvider;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
import com.intellij.psi.TokenType;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.source.tree.ASTStructure;
import com.intellij.psi.tree.*;
-import com.intellij.testFramework.LightPlatformTestCase;
-import com.intellij.testFramework.PlatformTestCase;
+import com.intellij.testFramework.LightPlatformLangTestCase;
+import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.ThreeState;
import com.intellij.util.diff.DiffTree;
import com.intellij.util.diff.DiffTreeChangeBuilder;
@@ -36,12 +34,9 @@ import com.intellij.util.diff.ShallowNodeComparator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
import java.util.List;
-public class PsiBuilderQuickTest extends LightPlatformTestCase {
+public class PsiBuilderQuickTest extends LightPlatformLangTestCase {
private static final IFileElementType ROOT = new IFileElementType("ROOT", Language.ANY);
private static final IElementType LETTER = new IElementType("LETTER", Language.ANY);
@@ -57,11 +52,6 @@ public class PsiBuilderQuickTest extends LightPlatformTestCase {
private static final TokenSet WHITESPACE_SET = TokenSet.create(TokenType.WHITE_SPACE);
private static final TokenSet COMMENT_SET = TokenSet.create(COMMENT);
- @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
- public PsiBuilderQuickTest() {
- PlatformTestCase.initPlatformLangPrefix();
- }
-
public void testPlain() {
doTest("a<<b",
new Parser() {
@@ -428,15 +418,8 @@ public class PsiBuilderQuickTest extends LightPlatformTestCase {
" PsiElement(OTHER)('}')\n");
}
- private abstract static class MyLazyElementType extends ILazyParseableElementType implements ILightLazyParseableElementType {
- protected MyLazyElementType(@NonNls String debugName) {
- super(debugName, Language.ANY);
- }
- }
-
public void testLightChameleon() {
final IElementType CHAMELEON_2 = new MyChameleon2Type();
-
final IElementType CHAMELEON_1 = new MyChameleon1Type(CHAMELEON_2);
doTest("ab{12[.?]}cd{x}",
@@ -478,60 +461,26 @@ public class PsiBuilderQuickTest extends LightPlatformTestCase {
" PsiElement(OTHER)('}')\n");
}
- @SuppressWarnings("ConstantConditions")
- private static PsiBuilderImpl createBuilder(CharSequence text) {
- ParserDefinition parserDefinition = new ParserDefinition() {
- @NotNull
- @Override
- public Lexer createLexer(Project project) {
- return new MyTestLexer();
- }
-
- @Override
- public PsiParser createParser(Project project) {
- return null;
- }
-
- @Override
- public IFileElementType getFileNodeType() {
- return null;
- }
-
- @NotNull
- @Override
- public TokenSet getWhitespaceTokens() {
- return WHITESPACE_SET;
- }
-
- @NotNull
- @Override
- public TokenSet getCommentTokens() {
- return COMMENT_SET;
- }
-
- @NotNull
- @Override
- public TokenSet getStringLiteralElements() {
- return null;
- }
-
- @NotNull
- @Override
- public PsiElement createElement(ASTNode node) {
- return null;
- }
-
- @Override
- public PsiFile createFile(FileViewProvider viewProvider) {
- return null;
- }
-
- @Override
- public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
- return null;
- }
- };
- return new PsiBuilderImpl(getProject(), null, parserDefinition, parserDefinition.createLexer(getProject()), null, text, null, null);
+ public void testEndMarkersOverlapping() {
+ doTest("a ",
+ new Parser() {
+ @Override
+ public void parse(PsiBuilder builder) {
+ PsiBuilder.Marker e1 = builder.mark();
+ PsiBuilder.Marker e2 = builder.mark();
+ builder.advanceLexer();
+ e2.done(OTHER);
+ e2.setCustomEdgeTokenBinders(null, WhitespacesBinders.GREEDY_RIGHT_BINDER);
+ e1.done(OTHER);
+ e1.setCustomEdgeTokenBinders(null, WhitespacesBinders.DEFAULT_RIGHT_BINDER);
+ assertTrue(builder.eof());
+ }
+ },
+ "Element(ROOT)\n" +
+ " Element(OTHER)\n" +
+ " Element(OTHER)\n" +
+ " PsiElement(LETTER)('a')\n" +
+ " PsiWhiteSpace(' ')\n");
}
private interface Parser {
@@ -594,75 +543,44 @@ public class PsiBuilderQuickTest extends LightPlatformTestCase {
}
private static void doFailTest(@NonNls final String text, final Parser parser, @NonNls final String expected) {
- final PrintStream std = System.err;
- //noinspection IOResourceOpenedButNotSafelyClosed
- System.setErr(new PrintStream(new NullStream()));
- try {
- try {
- ParserDefinition parserDefinition = new ParserDefinition() {
- @NotNull
- @Override
- public Lexer createLexer(Project project) {
- return null;
- }
-
- @Override
- public PsiParser createParser(Project project) {
- return null;
- }
-
- @Override
- public IFileElementType getFileNodeType() {
- return null;
- }
-
- @NotNull
- @Override
- public TokenSet getWhitespaceTokens() {
- return TokenSet.EMPTY;
- }
-
- @NotNull
- @Override
- public TokenSet getCommentTokens() {
- return TokenSet.EMPTY;
- }
-
- @NotNull
- @Override
- public TokenSet getStringLiteralElements() {
- return null;
- }
-
- @NotNull
- @Override
- public PsiElement createElement(ASTNode node) {
- return null;
- }
-
- @Override
- public PsiFile createFile(FileViewProvider viewProvider) {
- return null;
- }
-
- @Override
- public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
- return null;
- }
- };
- final PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(parserDefinition, new MyTestLexer(),text);
- builder.setDebugMode(true);
- parser.parse(builder);
- builder.getLightTree();
- fail("should fail");
+ PlatformTestUtil.withStdErrSuppressed(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(new PlainTextParserDefinition(), new MyTestLexer(), text);
+ builder.setDebugMode(true);
+ parser.parse(builder);
+ builder.getLightTree();
+ fail("should fail");
+ }
+ catch (AssertionError e) {
+ assertEquals(expected, e.getMessage());
+ }
+ }
+ });
+ }
+
+ private static PsiBuilderImpl createBuilder(CharSequence text) {
+ ParserDefinition parserDefinition = new PlainTextParserDefinition() {
+ @NotNull
+ @Override
+ public Lexer createLexer(Project project) {
+ return new MyTestLexer();
}
- catch (AssertionError e) {
- assertEquals(expected, e.getMessage());
+
+ @NotNull
+ @Override
+ public TokenSet getWhitespaceTokens() {
+ return WHITESPACE_SET;
}
- }
- finally {
- System.setErr(std);
- }
+
+ @NotNull
+ @Override
+ public TokenSet getCommentTokens() {
+ return COMMENT_SET;
+ }
+ };
+ return new PsiBuilderImpl(getProject(), null, parserDefinition, parserDefinition.createLexer(getProject()), null, text, null, null);
}
private static class MyTestLexer extends LexerBase {
@@ -719,9 +637,10 @@ public class PsiBuilderQuickTest extends LightPlatformTestCase {
}
}
- private static class NullStream extends OutputStream {
- @Override
- public void write(final int b) throws IOException { }
+ private abstract static class MyLazyElementType extends ILazyParseableElementType implements ILightLazyParseableElementType {
+ protected MyLazyElementType(@NonNls String debugName) {
+ super(debugName, Language.ANY);
+ }
}
private static class MyChameleon1Type extends MyLazyElementType {
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorCloneCaretAboveBelowTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorCloneCaretAboveBelowTest.java
new file mode 100644
index 000000000000..2d73640ff655
--- /dev/null
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorCloneCaretAboveBelowTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.editor.actions;
+
+import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
+
+public class EditorCloneCaretAboveBelowTest extends LightPlatformCodeInsightFixtureTestCase {
+ public void testStoringDesiredXPosition() {
+ init("long line<caret>\n" +
+ "line\n" +
+ "long line\n" +
+ "very long line");
+ cloneCaretBelow();
+ checkResult("long line<caret>\n" +
+ "line<caret>\n" +
+ "long line\n" +
+ "very long line");
+ cloneCaretBelow();
+ checkResult("long line<caret>\n" +
+ "line<caret>\n" +
+ "long line<caret>\n" +
+ "very long line");
+ cloneCaretBelow();
+ checkResult("long line<caret>\n" +
+ "line<caret>\n" +
+ "long line<caret>\n" +
+ "very long<caret> line");
+ }
+
+ public void testCloneAndMove() {
+ init("long line<caret>\n" +
+ "line\n" +
+ "long line");
+ cloneCaretBelow();
+ moveCaretDown();
+ checkResult("long line\n" +
+ "line<caret>\n" +
+ "long line<caret>");
+ }
+
+ public void testCloneBelowAndAbove() {
+ init("line\n" +
+ "<caret>li<caret>ne\n" +
+ "line");
+ cloneCaretBelow();
+ checkResult("line\n" +
+ "<caret>li<caret>ne\n" +
+ "<caret>li<caret>ne");
+ cloneCaretAbove();
+ checkResult("line\n" +
+ "<caret>li<caret>ne\n" +
+ "line");
+ cloneCaretAbove();
+ checkResult("<caret>li<caret>ne\n" +
+ "<caret>li<caret>ne\n" +
+ "line");
+ cloneCaretBelow();
+ checkResult("line\n" +
+ "<caret>li<caret>ne\n" +
+ "line");
+ }
+
+ public void testCloneWithSelection() {
+ init("long <selection>line<caret></selection>\n" +
+ "line\n" +
+ "long line");
+ cloneCaretBelow();
+ checkResult("long <selection>line<caret></selection>\n" +
+ "line\n" +
+ "long <selection>line<caret></selection>");
+ }
+
+ private void cloneCaretBelow() {
+ myFixture.performEditorAction(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW);
+ }
+
+ private void cloneCaretAbove() {
+ myFixture.performEditorAction(IdeActions.ACTION_EDITOR_CLONE_CARET_ABOVE);
+ }
+
+ private void moveCaretDown() {
+ myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN);
+ }
+
+ private void init(String text) {
+ myFixture.configureByText(getTestName(false) + ".txt", text);
+ }
+
+ private void checkResult(String text) {
+ myFixture.checkResult(text);
+ }
+}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/AbstractEditorTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/AbstractEditorTest.java
index 5dd8bbb8c424..fd774b5e817d 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/AbstractEditorTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/AbstractEditorTest.java
@@ -34,6 +34,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.junit.Assert.assertArrayEquals;
@@ -94,6 +95,20 @@ public abstract class AbstractEditorTest extends LightPlatformCodeInsightTestCas
));
}
+ protected static void foldOccurrences(String textToFoldRegexp, final String placeholder) {
+ final Matcher matcher = Pattern.compile(textToFoldRegexp).matcher(myEditor.getDocument().getCharsSequence());
+ myEditor.getFoldingModel().runBatchFoldingOperation(new Runnable() {
+ @Override
+ public void run() {
+ while(matcher.find()) {
+ FoldRegion foldRegion = myEditor.getFoldingModel().addFoldRegion(matcher.start(), matcher.end(), placeholder);
+ assertNotNull(foldRegion);
+ foldRegion.setExpanded(false);
+ }
+ }
+ });
+ }
+
/**
* Setups document of the {@link #getEditor() current editor} according to the given text that is expected to contain
* information about document lines obtained from the {@link DocumentImpl#dumpState()}.
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java
index 5a9d4da33219..aff78b0b1d27 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/EditorImplTest.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.editor.impl;
import com.intellij.codeInsight.folding.CodeFoldingManager;
+import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.VisualPosition;
import com.intellij.testFramework.EditorTestUtil;
@@ -65,6 +66,29 @@ public class EditorImplTest extends AbstractEditorTest {
verifySoftWrapPositions(58, 93);
}
+ public void testCorrectVisibleLineCountCalculation() throws Exception {
+ init("line containing FOLDED_REGION\n" +
+ "next <caret>line\n" +
+ "last line");
+ foldOccurrences("FOLDED_REGION", "...");
+ EditorTestUtil.configureSoftWraps(myEditor, 16); // wrap right at folded region start
+ verifySoftWrapPositions(16);
+
+ executeAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN);
+ checkResultByText("line containing FOLDED_REGION\n" +
+ "next line\n" +
+ "last <caret>line");
+ }
+
+ public void testInsertingFirstTab() throws Exception {
+ init(" <caret>space-indented line");
+ EditorTestUtil.configureSoftWraps(myEditor, 100);
+ myEditor.getSettings().setUseTabCharacter(true);
+
+ executeAction(IdeActions.ACTION_EDITOR_TAB);
+ checkResultByText(" \t<caret>space-indented line");
+ }
+
private void init(String text) throws IOException {
configureFromFileText(getTestName(false) + ".txt", text);
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/RangeMarkerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/RangeMarkerTest.java
index 9f3484b35deb..d11847af849a 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/RangeMarkerTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/RangeMarkerTest.java
@@ -34,6 +34,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.PsiDocumentManagerImpl;
@@ -44,6 +45,7 @@ import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.Timings;
import com.intellij.util.CommonProcessors;
import com.intellij.util.ThrowableRunnable;
+import com.intellij.util.containers.WeakList;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -1077,13 +1079,13 @@ public class RangeMarkerTest extends LightPlatformTestCase {
public void testRangeHighlighterLinesInRangeForLongLinePerformance() throws Exception {
final int N = 50000;
- Document document = EditorFactory.getInstance().createDocument(StringUtil.repeatSymbol('x', 2*N));
+ Document document = EditorFactory.getInstance().createDocument(StringUtil.repeatSymbol('x', 2 * N));
final MarkupModelEx markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, ourProject, true);
for (int i=0; i<N-1;i++) {
markupModel.addRangeHighlighter(2*i, 2*i+1, 0, null, HighlighterTargetArea.EXACT_RANGE);
}
- markupModel.addRangeHighlighter(N/2, N/2+1, 0, null, HighlighterTargetArea.LINES_IN_RANGE);
+ markupModel.addRangeHighlighter(N / 2, N / 2 + 1, 0, null, HighlighterTargetArea.LINES_IN_RANGE);
PlatformTestUtil.startPerformanceTest("slow highlighters lookup", (int)(N*Math.log(N)/1000), new ThrowableRunnable() {
@Override
@@ -1107,6 +1109,42 @@ public class RangeMarkerTest extends LightPlatformTestCase {
RangeHighlighter line = markupModel.addRangeHighlighter(4, 5, 0, null, HighlighterTargetArea.LINES_IN_RANGE);
List<RangeHighlighter> list = new ArrayList<RangeHighlighter>();
markupModel.processRangeHighlightersOverlappingWith(2, 9, new CommonProcessors.CollectProcessor<RangeHighlighter>(list));
- assertEquals(Arrays.asList(line,exact), list);
+ assertEquals(Arrays.asList(line, exact), list);
+ }
+
+ public void testLazyRangeMarkers() {
+ psiFile = createFile("x.txt", "xxx");
+
+ LazyRangeMarkerFactoryImpl factory = (LazyRangeMarkerFactoryImpl)LazyRangeMarkerFactory.getInstance(getProject());
+ VirtualFile virtualFile = psiFile.getVirtualFile();
+ LazyRangeMarkerFactoryImpl.LazyMarker marker = (LazyRangeMarkerFactoryImpl.LazyMarker)factory.createRangeMarker(virtualFile, 0);
+ WeakList<LazyRangeMarkerFactoryImpl.LazyMarker> markers = LazyRangeMarkerFactoryImpl.getMarkers(virtualFile);
+ assertSame(marker, assertOneElement(markers));
+
+ assertFalse(marker.isDelegated());
+ assertTrue(marker.isValid());
+ assertEquals(0, marker.getStartOffset());
+ assertFalse(marker.isDelegated());
+
+ marker.dispose();
+ assertFalse(marker.isValid());
+ assertEmpty(LazyRangeMarkerFactoryImpl.getMarkers(virtualFile));
+
+
+ marker = (LazyRangeMarkerFactoryImpl.LazyMarker)factory.createRangeMarker(virtualFile, 0);
+ assertFalse(marker.isDelegated());
+ assertTrue(marker.isValid());
+ assertEquals(0, marker.getStartOffset());
+ assertFalse(marker.isDelegated());
+
+ Document document = marker.getDocument();
+ document.insertString(2, "yyy");
+ assertTrue(marker.isDelegated());
+ assertTrue(marker.isValid());
+ assertEquals(0, marker.getStartOffset());
+
+ assertEmpty(LazyRangeMarkerFactoryImpl.getMarkers(virtualFile));
+ marker.dispose();
+ assertEmpty(LazyRangeMarkerFactoryImpl.getMarkers(virtualFile));
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/StripTrailingSpacesTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/StripTrailingSpacesTest.java
index abfef7cf0657..285aadbef402 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/StripTrailingSpacesTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/impl/StripTrailingSpacesTest.java
@@ -13,15 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.openapi.editor;
+package com.intellij.openapi.editor.impl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.DocumentEx;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.fileEditor.impl.TrailingSpacesStripper;
import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/NonProjectFileAccessTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/NonProjectFileAccessTest.java
index e517799165e2..06594d2352bf 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/NonProjectFileAccessTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/NonProjectFileAccessTest.java
@@ -245,7 +245,7 @@ public class NonProjectFileAccessTest extends HeavyFileEditorManagerTestCase {
assertNotNull(NonProjectFileWritingAccessProvider.getAccessStatus(getProject(), nonProjectFile1));
assertNull(NonProjectFileWritingAccessProvider.getAccessStatus(getProject(), nonProjectFile2));
- PsiTestUtil.removeContentEntry(myModule, contextRoot);
+ PsiTestUtil.removeContentEntry(myModule, contextRoot.getFile());
// do not add notification panel until access is requested
assertNotNull(NonProjectFileWritingAccessProvider.getAccessStatus(getProject(), nonProjectFile1));
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java
index 490aa294974d..96d85c122624 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java
@@ -118,6 +118,16 @@ public class ModifierKeyDoubleClickHandlerTest extends LightPlatformTestCase {
release();
}
+ public void testRepeatedInvocationOnKeyHold() {
+ press();
+ release();
+ press();
+ key(2);
+ assertInvocationCounts(0, 0, 2);
+ release();
+ assertInvocationCounts(0, 0, 2);
+ }
+
public void assertInvocationCounts(int shiftKeyCount, int shiftShiftCount, int shiftShiftKeyCount) {
assertEquals(shiftKeyCount, myShiftKeyActionInvocationCount);
assertEquals(shiftShiftCount, myShiftShiftActionInvocationCount);
@@ -143,18 +153,24 @@ public class ModifierKeyDoubleClickHandlerTest extends LightPlatformTestCase {
}
private void key() {
- IdeEventQueue.getInstance().dispatchEvent(new KeyEvent(myComponent,
- KeyEvent.KEY_PRESSED,
- Clock.getTime(),
- InputEvent.SHIFT_MASK,
- KeyEvent.VK_BACK_SPACE,
- '\b'));
- IdeEventQueue.getInstance().dispatchEvent(new KeyEvent(myComponent,
- KeyEvent.KEY_TYPED,
- Clock.getTime(),
- InputEvent.SHIFT_MASK,
- 0,
- '\b'));
+ key(1);
+ }
+
+ private void key(int repeat) {
+ for (int i = 0; i < repeat; i++) {
+ IdeEventQueue.getInstance().dispatchEvent(new KeyEvent(myComponent,
+ KeyEvent.KEY_PRESSED,
+ Clock.getTime(),
+ InputEvent.SHIFT_MASK,
+ KeyEvent.VK_BACK_SPACE,
+ '\b'));
+ IdeEventQueue.getInstance().dispatchEvent(new KeyEvent(myComponent,
+ KeyEvent.KEY_TYPED,
+ Clock.getTime(),
+ InputEvent.SHIFT_MASK,
+ 0,
+ '\b'));
+ }
IdeEventQueue.getInstance().dispatchEvent(new KeyEvent(myComponent,
KeyEvent.KEY_RELEASED,
Clock.getTime(),
diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java
index b06cf065fd95..17a7abc2a694 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java
@@ -131,6 +131,7 @@ public interface ProjectFileIndex extends FileIndex {
/**
* @deprecated name of this method may be confusing. If you want to check if the file is excluded or ignored use {@link #isExcluded(com.intellij.openapi.vfs.VirtualFile)}.
* If you want to check if the file is ignored use {@link com.intellij.openapi.fileTypes.FileTypeRegistry#isFileIgnored(com.intellij.openapi.vfs.VirtualFile)}.
+ * If you want to check if the file or one of its parents is ignored use {@link #isUnderIgnored(com.intellij.openapi.vfs.VirtualFile)}.
*/
@Deprecated
boolean isIgnored(@NotNull VirtualFile file);
@@ -143,4 +144,13 @@ public interface ProjectFileIndex extends FileIndex {
* @return true if <code>file</code> is excluded or ignored, false otherwise.
*/
boolean isExcluded(@NotNull VirtualFile file);
+
+ /**
+ * Checks if the specified file or directory is located under project roots but the file itself or one of its parent directories is ignored
+ * by {@link com.intellij.openapi.fileTypes.FileTypeRegistry#isFileIgnored(com.intellij.openapi.vfs.VirtualFile)}).
+ *
+ * @param file the file to check.
+ * @return true if <code>file</code> is ignored, false otherwise.
+ */
+ boolean isUnderIgnored(@NotNull VirtualFile file);
}
diff --git a/platform/projectModel-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java b/platform/projectModel-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java
index 7acb0fb12243..7b436b53c8d6 100644
--- a/platform/projectModel-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java
+++ b/platform/projectModel-impl/src/com/intellij/ide/projectView/impl/ProjectRootsUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,21 +41,21 @@ public class ProjectRootsUtil {
return directoryFile.equals(fileIndex.getSourceRootForFile(directoryFile));
}
- public static boolean isInSource(final PsiDirectory directory) {
+ public static boolean isInSource(@NotNull PsiDirectory directory) {
return isInSource(directory.getVirtualFile(), directory.getProject());
}
- public static boolean isInSource(final VirtualFile directoryFile, final Project project) {
+ public static boolean isInSource(@NotNull VirtualFile directoryFile, @NotNull Project project) {
final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
return projectFileIndex.isInSourceContent(directoryFile);
}
- public static boolean isInTestSource(final VirtualFile directoryFile, final Project project) {
+ public static boolean isInTestSource(@NotNull VirtualFile directoryFile, @NotNull Project project) {
final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
return projectFileIndex.isInTestSourceContent(directoryFile);
}
- public static boolean isModuleSourceRoot(@NotNull VirtualFile virtualFile, final @NotNull Project project) {
+ public static boolean isModuleSourceRoot(@NotNull VirtualFile virtualFile, @NotNull final Project project) {
return getModuleSourceRoot(virtualFile, project) != null;
}
@@ -66,7 +66,7 @@ public class ProjectRootsUtil {
return module != null && !module.isDisposed() ? findSourceFolder(module, root) : null;
}
- public static boolean isLibraryRoot(final VirtualFile directoryFile, final Project project) {
+ public static boolean isLibraryRoot(@NotNull VirtualFile directoryFile, @NotNull Project project) {
final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
if (projectFileIndex.isInLibraryClasses(directoryFile)) {
final VirtualFile parent = directoryFile.getParent();
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/OrderEnumerationHandler.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/OrderEnumerationHandler.java
index 83984e11a80b..7a62c35d0390 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/OrderEnumerationHandler.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/OrderEnumerationHandler.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -65,4 +66,12 @@ public abstract class OrderEnumerationHandler {
@NotNull Collection<String> urls) {
return false;
}
+
+ public boolean addCustomModuleRoots(@NotNull OrderRootType type,
+ @NotNull ModuleRootModel rootModel,
+ @NotNull Collection<String> result,
+ boolean includeProduction,
+ boolean includeTests) {
+ return false;
+ }
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java
index 9fdd8e09a57d..e87d3c749b10 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndex.java
@@ -17,23 +17,23 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Query;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
+import java.util.List;
+
public abstract class DirectoryIndex {
public static DirectoryIndex getInstance(Project project) {
assert !project.isDefault() : "Must not call DirectoryIndex for default project";
return ServiceManager.getService(project, DirectoryIndex.class);
}
- @TestOnly
- public abstract void checkConsistency();
-
/**
* The same as {@link #getInfoForFile} but works only for directories or file roots and returns {@code null} for directories
* which aren't included in project content or libraries
@@ -62,4 +62,13 @@ public abstract class DirectoryIndex {
public boolean isInitialized() {
return true;
}
+
+ @NotNull
+ public abstract OrderEntry[] getOrderEntries(@NotNull DirectoryInfo info);
+
+ @Nullable
+ abstract OrderEntry findOrderEntryWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule);
+
+ @NotNull
+ abstract List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull DirectoryInfo info, @NotNull Module ownerModule);
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexExcludePolicy.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexExcludePolicy.java
index b31519ccb4a2..61838f51ac1d 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexExcludePolicy.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexExcludePolicy.java
@@ -17,7 +17,6 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModuleRootModel;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
@@ -29,10 +28,9 @@ import org.jetbrains.annotations.NotNull;
public interface DirectoryIndexExcludePolicy {
ExtensionPointName<DirectoryIndexExcludePolicy> EP_NAME = ExtensionPointName.create("com.intellij.directoryIndexExcludePolicy");
- boolean isExcludeRoot(VirtualFile file);
- boolean isExcludeRootForModule(@NotNull Module module, final VirtualFile file);
@NotNull
VirtualFile[] getExcludeRootsForProject();
+
@NotNull
VirtualFilePointer[] getExcludeRootsForModule(@NotNull ModuleRootModel rootModel);
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java
index 87448a584a23..cd5fbd7d5867 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java
@@ -17,13 +17,8 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.TestOnly;
-
-import java.util.List;
public abstract class DirectoryInfo {
/**
@@ -61,16 +56,4 @@ public abstract class DirectoryInfo {
@Nullable
public abstract Module getModule();
-
- @NotNull
- public abstract OrderEntry[] getOrderEntries();
-
- @Nullable
- abstract OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule);
-
- @NotNull
- abstract List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule);
-
- @TestOnly
- abstract void assertConsistency();
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java
index 0be339bf3c5f..1c3ca4f2ff8d 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java
@@ -16,34 +16,16 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.roots.OrderEntry;
-import com.intellij.openapi.roots.OrderRootType;
-import com.intellij.openapi.roots.RootPolicy;
-import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.TestOnly;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
/**
* @author nik
*/
-public abstract class DirectoryInfoImpl extends DirectoryInfo {
- public static final Comparator<OrderEntry> BY_OWNER_MODULE = new Comparator<OrderEntry>() {
- @Override
- public int compare(OrderEntry o1, OrderEntry o2) {
- String name1 = o1.getOwnerModule().getName();
- String name2 = o2.getOwnerModule().getName();
- return name1.compareTo(name2);
- }
- };
+public class DirectoryInfoImpl extends DirectoryInfo {
public static final int MAX_ROOT_TYPE_ID = Byte.MAX_VALUE;
+ private final VirtualFile myRoot;//original project root for which this information is calculated
private final Module module; // module to which content it belongs or null
private final VirtualFile libraryClassRoot; // class root in library
private final VirtualFile contentRoot;
@@ -53,8 +35,9 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo {
private final boolean myExcluded;
private final byte mySourceRootTypeId;
- DirectoryInfoImpl(Module module, VirtualFile contentRoot, VirtualFile sourceRoot, VirtualFile libraryClassRoot,
+ DirectoryInfoImpl(@NotNull VirtualFile root, Module module, VirtualFile contentRoot, VirtualFile sourceRoot, VirtualFile libraryClassRoot,
boolean inModuleSource, boolean inLibrarySource, boolean isExcluded, int sourceRootTypeId) {
+ myRoot = root;
this.module = module;
this.libraryClassRoot = libraryClassRoot;
this.contentRoot = contentRoot;
@@ -74,30 +57,12 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- DirectoryInfoImpl info = (DirectoryInfoImpl)o;
-
- return mySourceRootTypeId == info.mySourceRootTypeId &&
- myInModuleSource == info.myInModuleSource &&
- myInLibrarySource == info.myInLibrarySource &&
- myExcluded == info.myExcluded &&
- Comparing.equal(contentRoot, info.contentRoot) &&
- Comparing.equal(libraryClassRoot, info.libraryClassRoot) &&
- Comparing.equal(module, info.module) &&
- Arrays.equals(getOrderEntries(), info.getOrderEntries()) &&
- Comparing.equal(sourceRoot, info.sourceRoot);
+ return myRoot.equals(((DirectoryInfoImpl)o).myRoot);
}
@Override
public int hashCode() {
- int result = module != null ? module.hashCode() : 0;
- result = 31 * result + (libraryClassRoot != null ? libraryClassRoot.hashCode() : 0);
- result = 31 * result + (contentRoot != null ? contentRoot.hashCode() : 0);
- result = 31 * result + (sourceRoot != null ? sourceRoot.hashCode() : 0);
- result = 31 * result + (myInModuleSource ? 1 : 0);
- result = 31 * result + (myInLibrarySource ? 1 : 0);
- result = 31 * result + (myExcluded ? 1 : 0);
- result = 31 * result + (int)mySourceRootTypeId;
- return result;
+ return myRoot.hashCode();
}
@SuppressWarnings({"HardCodedStringLiteral"})
@@ -111,98 +76,9 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo {
", libraryClassRoot=" + getLibraryClassRoot() +
", contentRoot=" + getContentRoot() +
", sourceRoot=" + getSourceRoot() +
- ", orderEntries=" + Arrays.toString(getOrderEntries()) +
"}";
}
- @NotNull
- private static OrderEntry createFakeOrderEntry(@NotNull final Module ownerModule) {
- return new OrderEntry() {
- @NotNull
- @Override
- public VirtualFile[] getFiles(OrderRootType type) {
- throw new IncorrectOperationException();
- }
-
- @NotNull
- @Override
- public String[] getUrls(OrderRootType rootType) {
- throw new IncorrectOperationException();
- }
-
- @NotNull
- @Override
- public String getPresentableName() {
- throw new IncorrectOperationException();
- }
-
- @Override
- public boolean isValid() {
- throw new IncorrectOperationException();
- }
-
- @NotNull
- @Override
- public Module getOwnerModule() {
- return ownerModule;
- }
-
- @Override
- public <R> R accept(RootPolicy<R> policy, @Nullable R initialValue) {
- throw new IncorrectOperationException();
- }
-
- @Override
- public int compareTo(@NotNull OrderEntry o) {
- throw new IncorrectOperationException();
- }
-
- @Override
- public boolean isSynthetic() {
- throw new IncorrectOperationException();
- }
- };
- }
-
- @Nullable
- OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule) {
- OrderEntry[] entries = getOrderEntries();
- if (entries.length < 10) {
- for (OrderEntry entry : entries) {
- if (entry.getOwnerModule() == ownerModule) return entry;
- }
- return null;
- }
- int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), BY_OWNER_MODULE);
- return index < 0 ? null : entries[index];
- }
-
- @NotNull
- List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) {
- OrderEntry[] entries = getOrderEntries();
- if (entries.length == 1) {
- OrderEntry entry = entries[0];
- return entry.getOwnerModule() == ownerModule ? Arrays.asList(entries) : Collections.<OrderEntry>emptyList();
- }
- int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), BY_OWNER_MODULE);
- if (index < 0) {
- return Collections.emptyList();
- }
- int firstIndex = index;
- while (firstIndex-1 >= 0 && entries[firstIndex-1].getOwnerModule() == ownerModule) {
- firstIndex--;
- }
- int lastIndex = index+1;
- while (lastIndex < entries.length && entries[lastIndex].getOwnerModule() == ownerModule) {
- lastIndex++;
- }
-
- OrderEntry[] subArray = new OrderEntry[lastIndex - firstIndex];
- System.arraycopy(entries, firstIndex, subArray, 0, lastIndex - firstIndex);
-
- return Arrays.asList(subArray);
- }
-
public boolean isInProject() {
return !isExcluded();
}
@@ -241,15 +117,12 @@ public abstract class DirectoryInfoImpl extends DirectoryInfo {
return module;
}
- @TestOnly
- void assertConsistency() {
- OrderEntry[] entries = getOrderEntries();
- for (int i=1; i<entries.length; i++) {
- assert BY_OWNER_MODULE.compare(entries[i-1], entries[i]) <= 0;
- }
- }
-
public int getSourceRootTypeId() {
return mySourceRootTypeId;
}
+
+ @NotNull
+ public VirtualFile getRoot() {
+ return myRoot;
+ }
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java
index 3b5ea4fa1610..8140a3c15211 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java
@@ -79,12 +79,12 @@ public class ModuleFileIndexImpl extends FileIndexBase implements ModuleFileInde
@Override
@NotNull
public List<OrderEntry> getOrderEntriesForFile(@NotNull VirtualFile fileOrDir) {
- return getInfoForFileOrDirectory(fileOrDir).findAllOrderEntriesWithOwnerModule(myModule);
+ return myDirectoryIndex.findAllOrderEntriesWithOwnerModule(getInfoForFileOrDirectory(fileOrDir), myModule);
}
@Override
public OrderEntry getOrderEntryForFile(@NotNull VirtualFile fileOrDir) {
- return getInfoForFileOrDirectory(fileOrDir).findOrderEntryWithOwnerModule(myModule);
+ return myDirectoryIndex.findOrderEntryWithOwnerModule(getInfoForFileOrDirectory(fileOrDir), myModule);
}
@Override
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/NonProjectDirectoryInfo.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/NonProjectDirectoryInfo.java
index 7937f08fc7b4..ce09ec2fb819 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/NonProjectDirectoryInfo.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/NonProjectDirectoryInfo.java
@@ -16,14 +16,9 @@
package com.intellij.openapi.roots.impl;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Collections;
-import java.util.List;
-
/**
* @author nik
*/
@@ -53,22 +48,6 @@ class NonProjectDirectoryInfo extends DirectoryInfo {
return false;
}
- @NotNull
- @Override
- public OrderEntry[] getOrderEntries() {
- return OrderEntry.EMPTY_ARRAY;
- }
-
- @Nullable
- OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule) {
- return null;
- }
-
- @NotNull
- List<OrderEntry> findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) {
- return Collections.emptyList();
- }
-
@Override
public String toString() {
return "DirectoryInfo: " + myDebugName;
@@ -118,9 +97,6 @@ class NonProjectDirectoryInfo extends DirectoryInfo {
return null;
}
- void assertConsistency() {
- }
-
public int getSourceRootTypeId() {
return 0;
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEnumeratorBase.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEnumeratorBase.java
index 61a6aee9315b..b13df0560292 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEnumeratorBase.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderEnumeratorBase.java
@@ -356,6 +356,38 @@ abstract class OrderEnumeratorBase extends OrderEnumerator implements OrderEnume
return false;
}
+ boolean addCustomRootsForModule(OrderRootType type,
+ ModuleRootModel rootModel,
+ Collection<VirtualFile> result,
+ boolean includeProduction,
+ boolean includeTests) {
+ for (OrderEnumerationHandler handler : myCustomHandlers) {
+ final List<String> urls = new ArrayList<String>();
+ final boolean added = handler.addCustomModuleRoots(type, rootModel, urls, includeProduction, includeTests);
+ for (String url : urls) {
+ ContainerUtil.addIfNotNull(VirtualFileManager.getInstance().findFileByUrl(url), result);
+ }
+
+ if (added) return true;
+ }
+ return false;
+ }
+
+ boolean addCustomRootUrlsForModule(OrderRootType type,
+ ModuleRootModel rootModel,
+ Collection<String> result,
+ boolean includeProduction,
+ boolean includeTests) {
+ for (OrderEnumerationHandler handler : myCustomHandlers) {
+ final List<String> urls = new ArrayList<String>();
+ final boolean added = handler.addCustomModuleRoots(type, rootModel, urls, includeProduction, includeTests);
+ result.addAll(urls);
+
+ if (added) return true;
+ }
+ return false;
+ }
+
@Override
public boolean isRuntimeOnly() {
return myRuntimeOnly;
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderRootsEnumeratorImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderRootsEnumeratorImpl.java
index ea5742cce176..fb9a75176255 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderRootsEnumeratorImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/OrderRootsEnumeratorImpl.java
@@ -240,6 +240,7 @@ public class OrderRootsEnumeratorImpl implements OrderRootsEnumerator {
}
}
}
+ myOrderEnumerator.addCustomRootsForModule(type, rootModel, result, includeProduction, includeTests);
}
private void collectModuleRootsUrls(OrderRootType type,
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexFacade.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexFacade.java
index 0bb65c600083..e15763716280 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexFacade.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexFacade.java
@@ -69,6 +69,11 @@ public class ProjectFileIndexFacade extends FileIndexFacade {
return myFileIndex.isExcluded(file);
}
+ @Override
+ public boolean isUnderIgnored(@NotNull VirtualFile file) {
+ return myFileIndex.isUnderIgnored(file);
+ }
+
@Nullable
@Override
public Module getModuleForFile(@NotNull VirtualFile file) {
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java
index acb6598f55c8..e2417193149e 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java
@@ -85,6 +85,11 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn
}
@Override
+ public boolean isUnderIgnored(@NotNull VirtualFile file) {
+ return getInfoForFileOrDirectory(file).isIgnored();
+ }
+
+ @Override
public Module getModuleForFile(@NotNull VirtualFile file) {
if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate();
DirectoryInfo info = getInfoForFileOrDirectory(file);
@@ -95,7 +100,7 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn
@Override
@NotNull
public List<OrderEntry> getOrderEntriesForFile(@NotNull VirtualFile file) {
- return Arrays.asList(getInfoForFileOrDirectory(file).getOrderEntries());
+ return Arrays.asList(myDirectoryIndex.getOrderEntries(getInfoForFileOrDirectory(file)));
}
@Override
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java
index 85a098341e4e..8e80670b1f76 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java
@@ -131,8 +131,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
return (ProjectRootManagerImpl)getInstance(project);
}
- public ProjectRootManagerImpl(Project project,
- DirectoryIndex directoryIndex) {
+ public ProjectRootManagerImpl(Project project) {
myProject = project;
myRootsCache = new OrderRootsCache(project);
}
@@ -143,8 +142,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
return ProjectFileIndex.SERVICE.getInstance(myProject);
}
- private final Map<ModuleRootListener, MessageBusConnection> myListenerAdapters = new HashMap<ModuleRootListener, MessageBusConnection>();
-
@Override
@NotNull
public List<String> getContentRootUrls() {
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java
index ca68cee3d061..eb04fb6c103e 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java
@@ -25,13 +25,16 @@ import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.CollectionQuery;
+import com.intellij.util.EmptyQuery;
import com.intellij.util.Query;
+import com.intellij.util.containers.ConcurrentHashSet;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import gnu.trove.TObjectIntHashMap;
@@ -41,7 +44,15 @@ import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
import java.util.*;
-public class RootIndex extends DirectoryIndex {
+public class RootIndex {
+ public static final Comparator<OrderEntry> BY_OWNER_MODULE = new Comparator<OrderEntry>() {
+ @Override
+ public int compare(OrderEntry o1, OrderEntry o2) {
+ String name1 = o1.getOwnerModule().getName();
+ String name2 = o2.getOwnerModule().getName();
+ return name1.compareTo(name2);
+ }
+ };
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.RootIndex");
private final Set<VirtualFile> myProjectExcludedRoots = ContainerUtil.newHashSet();
@@ -54,11 +65,20 @@ public class RootIndex extends DirectoryIndex {
};
private final Map<String, List<VirtualFile>> myDirectoriesByPackageNameCache = ContainerUtil.newConcurrentMap();
+ private final Set<String> myNonExistentPackages = new ConcurrentHashSet<String>();
private final InfoCache myInfoCache;
private final List<JpsModuleSourceRootType<?>> myRootTypes = ContainerUtil.newArrayList();
private final TObjectIntHashMap<JpsModuleSourceRootType<?>> myRootTypeId = new TObjectIntHashMap<JpsModuleSourceRootType<?>>();
@NotNull private final Project myProject;
private volatile Map<VirtualFile, OrderEntry[]> myOrderEntries;
+ @SuppressWarnings("UnusedDeclaration")
+ private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
+ @Override
+ public void run() {
+ myNonExistentPackages.clear();
+ }
+ });
+
// made public for Upsource
public RootIndex(@NotNull Project project, @NotNull InfoCache cache) {
@@ -145,7 +165,6 @@ public class RootIndex extends DirectoryIndex {
}
}
}
-
}
}
}
@@ -171,7 +190,8 @@ public class RootIndex extends DirectoryIndex {
if (orderEntry instanceof ModuleOrderEntry) {
final Module depModule = ((ModuleOrderEntry)orderEntry).getModule();
if (depModule != null) {
- VirtualFile[] importedClassRoots = OrderEnumerator.orderEntries(depModule).exportedOnly().recursively().classes().usingCache().getRoots();
+ VirtualFile[] importedClassRoots =
+ OrderEnumerator.orderEntries(depModule).exportedOnly().recursively().classes().usingCache().getRoots();
for (VirtualFile importedClassRoot : importedClassRoots) {
depEntries.putValue(importedClassRoot, orderEntry);
}
@@ -197,7 +217,9 @@ public class RootIndex extends DirectoryIndex {
Set<VirtualFile> allRoots = rootInfo.getAllRoots();
for (VirtualFile file : allRoots) {
List<VirtualFile> hierarchy = getHierarchy(file, allRoots, rootInfo);
- result.put(file, hierarchy == null ? OrderEntry.EMPTY_ARRAY : calcOrderEntries(rootInfo, depEntries, libClassRootEntries, libSourceRootEntries, hierarchy));
+ result.put(file, hierarchy == null
+ ? OrderEntry.EMPTY_ARRAY
+ : calcOrderEntries(rootInfo, depEntries, libClassRootEntries, libSourceRootEntries, hierarchy));
}
myOrderEntries = result;
return result;
@@ -211,7 +233,8 @@ public class RootIndex extends DirectoryIndex {
@Nullable VirtualFile libraryClassRoot = info.findLibraryRootInfo(hierarchy, false);
@Nullable VirtualFile librarySourceRoot = info.findLibraryRootInfo(hierarchy, true);
Set<OrderEntry> orderEntries = ContainerUtil.newLinkedHashSet();
- orderEntries.addAll(info.getLibraryOrderEntries(hierarchy, libraryClassRoot, librarySourceRoot, libClassRootEntries, libSourceRootEntries));
+ orderEntries
+ .addAll(info.getLibraryOrderEntries(hierarchy, libraryClassRoot, librarySourceRoot, libClassRootEntries, libSourceRootEntries));
for (VirtualFile root : hierarchy) {
orderEntries.addAll(depEntries.get(root));
}
@@ -224,12 +247,11 @@ public class RootIndex extends DirectoryIndex {
}
OrderEntry[] array = orderEntries.toArray(new OrderEntry[orderEntries.size()]);
- Arrays.sort(array, DirectoryInfoImpl.BY_OWNER_MODULE);
+ Arrays.sort(array, BY_OWNER_MODULE);
return array;
}
- @Override
public void checkConsistency() {
for (VirtualFile file : myProjectExcludedRoots) {
assert file.exists() : file.getPath() + " does not exist";
@@ -247,21 +269,14 @@ public class RootIndex extends DirectoryIndex {
int id = myRootTypes.size();
if (id > DirectoryInfoImpl.MAX_ROOT_TYPE_ID) {
- LOG.error("Too many different types of module source roots (" + id + ") registered: " + myRootTypes);
+ LOG.error("Too many different types of module source roots (" + id + ") registered: " + myRootTypes);
}
myRootTypes.add(rootType);
myRootTypeId.put(rootType, id);
return id;
}
- @Override
- public DirectoryInfo getInfoForDirectory(@NotNull VirtualFile dir) {
- DirectoryInfo info = getInfoForFile(dir);
- return info.isInProject() ? info : null;
- }
-
@NotNull
- @Override
public DirectoryInfo getInfoForFile(@NotNull VirtualFile file) {
if (!file.isValid()) {
return NonProjectDirectoryInfo.INVALID;
@@ -314,28 +329,41 @@ public class RootIndex extends DirectoryIndex {
return info;
}
- @Override
@NotNull
public Query<VirtualFile> getDirectoriesByPackageName(@NotNull final String packageName, final boolean includeLibrarySources) {
List<VirtualFile> result = myDirectoriesByPackageNameCache.get(packageName);
if (result == null) {
+ if (myNonExistentPackages.contains(packageName)) return EmptyQuery.getEmptyQuery();
+
result = ContainerUtil.newSmartList();
-
+
if (StringUtil.isNotEmpty(packageName) && !StringUtil.startsWithChar(packageName, '.')) {
- String shortName = StringUtil.getShortName(packageName);
- for (VirtualFile parentDir : getDirectoriesByPackageName(StringUtil.getPackageName(packageName), true)) {
- VirtualFile child = parentDir.findChild(shortName);
- if (child != null && child.isDirectory() && getInfoForFile(child).isInProject()
- && packageName.equals(getPackageName(child))) {
- result.add(child);
+ int i = packageName.lastIndexOf('.');
+ while (true) {
+ String shortName = packageName.substring(i + 1);
+ String parentPackage = i > 0 ? packageName.substring(0, i) : "";
+ for (VirtualFile parentDir : getDirectoriesByPackageName(parentPackage, true)) {
+ VirtualFile child = parentDir.findChild(shortName);
+ if (child != null && child.isDirectory() && getInfoForFile(child).isInProject()
+ && packageName.equals(getPackageName(child))) {
+ result.add(child);
+ }
}
+ if (i < 0) break;
+ i = packageName.lastIndexOf('.', i - 1);
}
}
- result.addAll(myPackagePrefixRoots.get(packageName));
+ for (VirtualFile file : myPackagePrefixRoots.get(packageName)) {
+ if (file.isDirectory()) {
+ result.add(file);
+ }
+ }
if (!result.isEmpty()) {
myDirectoriesByPackageNameCache.put(packageName, result);
+ } else {
+ myNonExistentPackages.add(packageName);
}
}
@@ -351,7 +379,6 @@ public class RootIndex extends DirectoryIndex {
return new CollectionQuery<VirtualFile>(result);
}
- @Override
@Nullable
public String getPackageName(@NotNull final VirtualFile dir) {
if (dir.isDirectory()) {
@@ -380,7 +407,6 @@ public class RootIndex extends DirectoryIndex {
return parentPackageName.isEmpty() ? subdirName : parentPackageName + "." + subdirName;
}
- @Override
@Nullable
public JpsModuleSourceRootType<?> getSourceRootType(@NotNull DirectoryInfo directoryInfo) {
return myRootTypes.get(directoryInfo.getSourceRootTypeId());
@@ -487,8 +513,9 @@ public class RootIndex extends DirectoryIndex {
if (source && libraryOrSdkSources.contains(root) &&
(!sourceOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(sourceOfLibraries.get(root)))) {
return root;
- } else if (!source && libraryOrSdkClasses.contains(root) &&
- (!classOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(classOfLibraries.get(root)))) {
+ }
+ else if (!source && libraryOrSdkClasses.contains(root) &&
+ (!classOfLibraries.containsKey(root) || !librariesToIgnore.containsAll(classOfLibraries.get(root)))) {
return root;
}
}
@@ -569,8 +596,11 @@ public class RootIndex extends DirectoryIndex {
}
}
+
@NotNull
- private Pair<DirectoryInfo, String> calcDirectoryInfo(@NotNull final VirtualFile root, @NotNull final List<VirtualFile> hierarchy, @NotNull RootInfo info) {
+ private static Pair<DirectoryInfo, String> calcDirectoryInfo(@NotNull final VirtualFile root,
+ @NotNull final List<VirtualFile> hierarchy,
+ @NotNull RootInfo info) {
VirtualFile moduleContentRoot = info.findModuleRootInfo(hierarchy);
VirtualFile libraryClassRoot = info.findLibraryRootInfo(hierarchy, false);
VirtualFile librarySourceRoot = info.findLibraryRootInfo(hierarchy, true);
@@ -590,23 +620,26 @@ public class RootIndex extends DirectoryIndex {
int typeId = moduleSourceRoot != null ? info.rootTypeId.get(moduleSourceRoot) : 0;
Module module = parentModuleForExcluded != null ? parentModuleForExcluded : info.contentRootOf.get(moduleContentRoot);
- DirectoryInfo directoryInfo = new DirectoryInfoImpl(module, moduleContentRoot, sourceRoot, libraryClassRoot, inModuleSources, inLibrarySource,
- parentModuleForExcluded != null, typeId) {
- @NotNull
- @Override
- public OrderEntry[] getOrderEntries() {
- OrderEntry[] entries = RootIndex.this.getOrderEntries().get(root);
- return entries == null ? OrderEntry.EMPTY_ARRAY : entries;
- }
- };
+ DirectoryInfo directoryInfo =
+ new DirectoryInfoImpl(root, module, moduleContentRoot, sourceRoot, libraryClassRoot, inModuleSources, inLibrarySource,
+ parentModuleForExcluded != null, typeId);
String packagePrefix = info.calcPackagePrefix(root, hierarchy, moduleContentRoot, libraryClassRoot, librarySourceRoot);
return Pair.create(directoryInfo, packagePrefix);
}
-
+
+ @NotNull
+ public OrderEntry[] getOrderEntries(@NotNull DirectoryInfo info) {
+ if (!(info instanceof DirectoryInfoImpl)) return OrderEntry.EMPTY_ARRAY;
+ OrderEntry[] entries = this.getOrderEntries().get(((DirectoryInfoImpl)info).getRoot());
+ return entries == null ? OrderEntry.EMPTY_ARRAY : entries;
+ }
+
public interface InfoCache {
- @Nullable DirectoryInfo getCachedInfo(@NotNull VirtualFile dir);
- void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info);
+ @Nullable
+ DirectoryInfo getCachedInfo(@NotNull VirtualFile dir);
+
+ void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info);
}
-} \ No newline at end of file
+}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java
index 8ece843b5972..540bfe290645 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java
@@ -213,6 +213,8 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel
LOG.assertTrue(myContent.contains(entry));
if (entry instanceof RootModelComponentBase) {
Disposer.dispose((RootModelComponentBase)entry);
+ RootModelImpl entryModel = ((RootModelComponentBase)entry).getRootModel();
+ LOG.assertTrue(entryModel == this, "Removing from " + this + " content entry obtained from " + entryModel);
}
myContent.remove(entry);
}
@@ -731,6 +733,15 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel
return myModuleRootManager.getRootModel();
}
+ @Override
+ public String toString() {
+ return "RootModelImpl{" +
+ "module=" + getModule().getName() +
+ ", writable=" + myWritable +
+ ", disposed=" + myDisposed +
+ '}';
+ }
+
@Nullable
@Override
public <T> T getModuleExtension(@NotNull final Class<T> klass) {
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java
index 7a8e9ca01922..fa901849867f 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java
@@ -522,10 +522,8 @@ public class LibraryImpl extends TraceableDisposable implements LibraryEx.Modifi
private boolean isUnderRoots(@NotNull String url) {
for (VirtualFilePointerContainer container : myRoots.values()) {
- for (String rootUrl : container.getUrls()) {
- if (VfsUtilCore.isEqualOrAncestor(rootUrl, url)) {
- return true;
- }
+ if (VfsUtilCore.isUnder(url, Arrays.asList(container.getUrls()))) {
+ return true;
}
}
return false;
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java
index f12e646a72b9..8ed6e68b1915 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ServerConnectionManagerImpl.java
@@ -20,8 +20,6 @@ import java.util.Map;
*/
public class ServerConnectionManagerImpl extends ServerConnectionManager {
- private static final int POLL_DEPLOYMENTS_DELAY = 2000;
-
private final Map<RemoteServer<?>, ServerConnection> myConnections = new HashMap<RemoteServer<?>, ServerConnection>();
private final ServerConnectionEventDispatcher myEventDispatcher = new ServerConnectionEventDispatcher();
@@ -34,29 +32,10 @@ public class ServerConnectionManagerImpl extends ServerConnectionManager {
connection = doCreateConnection(server, this);
myConnections.put(server, connection);
myEventDispatcher.fireConnectionCreated(connection);
- pollDeployments(connection);
}
return connection;
}
- private void pollDeployments(final ServerConnection connection) {
- connection.computeDeployments(new Runnable() {
-
- @Override
- public void run() {
- new Alarm().addRequest(new Runnable() {
-
- @Override
- public void run() {
- if (connection == getConnection(connection.getServer())) {
- pollDeployments(connection);
- }
- }
- }, POLL_DEPLOYMENTS_DELAY, ModalityState.any());
- }
- });
- }
-
@NotNull
@Override
public <C extends ServerConfiguration> ServerConnection createTemporaryConnection(@NotNull RemoteServer<C> server) {
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java
index 7a1f27f3b8ee..8a46887be6cf 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java
@@ -6,6 +6,7 @@ import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.ide.util.treeView.NodeRenderer;
import com.intellij.ide.util.treeView.TreeVisitor;
+import com.intellij.openapi.application.ModalityState;
import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
@@ -13,7 +14,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.impl.runtime.log.LoggingHandlerImpl;
import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode;
@@ -28,6 +28,7 @@ import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SideBorder;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.Alarm;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -56,6 +57,8 @@ public class ServersToolWindowContent extends JPanel implements Disposable {
private static final String MESSAGE_CARD = "message";
private static final String EMPTY_SELECTION_MESSAGE = "Select a server or deployment in the tree to view details";
+ private static final int POLL_DEPLOYMENTS_DELAY = 2000;
+
private final Tree myTree;
private final CardLayout myPropertiesPanelLayout;
private final JPanel myPropertiesPanel;
@@ -188,6 +191,7 @@ public class ServersToolWindowContent extends JPanel implements Disposable {
@Override
public void onConnectionCreated(@NotNull ServerConnection<?> connection) {
getBuilder().queueUpdate();
+ pollDeployments(connection);
}
@Override
@@ -210,6 +214,24 @@ public class ServersToolWindowContent extends JPanel implements Disposable {
}
}
+ private static void pollDeployments(final ServerConnection connection) {
+ connection.computeDeployments(new Runnable() {
+
+ @Override
+ public void run() {
+ new Alarm().addRequest(new Runnable() {
+
+ @Override
+ public void run() {
+ if (connection == ServerConnectionManager.getInstance().getConnection(connection.getServer())) {
+ pollDeployments(connection);
+ }
+ }
+ }, POLL_DEPLOYMENTS_DELAY, ModalityState.any());
+ }
+ });
+ }
+
private JComponent createToolbar() {
DefaultActionGroup group = new DefaultActionGroup();
group.add(ActionManager.getInstance().getAction(SERVERS_TOOL_WINDOW_TOOLBAR));
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java
index fa4355eb356c..5a3d150daf57 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java
@@ -15,9 +15,6 @@
*/
package com.intellij.remoteServer.util;
-import com.intellij.execution.RunManagerEx;
-import com.intellij.execution.RunnerAndConfigurationSettings;
-import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.ide.DataManager;
import com.intellij.ide.actions.ShowSettingsUtilImpl;
import com.intellij.ide.util.projectWizard.WizardContext;
@@ -25,11 +22,8 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModulePointer;
-import com.intellij.openapi.module.ModulePointerManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.ex.SingleConfigurableEditor;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Condition;
@@ -38,12 +32,7 @@ import com.intellij.openapi.util.Ref;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.configuration.RemoteServersManager;
-import com.intellij.remoteServer.configuration.ServerConfiguration;
-import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
import com.intellij.remoteServer.impl.configuration.RemoteServerConfigurable;
-import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerConfigurationType;
-import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
-import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceImpl;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.hash.HashMap;
@@ -224,52 +213,7 @@ public class CloudAccountSelectionEditor {
if (account == null) {
return;
}
- createRunConfiguration(account, module, configuration);
- }
-
- public static <SC extends ServerConfiguration, DC extends DeploymentConfiguration>
- DeployToServerRunConfiguration<SC, DC> createRunConfiguration(RemoteServer<SC> account, Module module, DC deploymentConfiguration) {
-
- Project project = module.getProject();
-
- String accountName = account.getName();
-
- String name = generateRunConfigurationName(accountName, module.getName());
-
- final RunManagerEx runManager = RunManagerEx.getInstanceEx(project);
- final RunnerAndConfigurationSettings runSettings
- = runManager.createRunConfiguration(name, getRunConfigurationType(account.getType()).getConfigurationFactories()[0]);
-
- final DeployToServerRunConfiguration<SC, DC> result = (DeployToServerRunConfiguration<SC, DC>)runSettings.getConfiguration();
-
- result.setServerName(accountName);
-
- final ModulePointer modulePointer = ModulePointerManager.getInstance(project).create(module);
- result.setDeploymentSource(new ModuleDeploymentSourceImpl(modulePointer));
-
- result.setDeploymentConfiguration(deploymentConfiguration);
-
- runManager.addConfiguration(runSettings, false);
- runManager.setSelectedConfiguration(runSettings);
-
- return result;
- }
-
- private static DeployToServerConfigurationType getRunConfigurationType(ServerType<?> cloudType) {
- String id = DeployToServerConfigurationType.getId(cloudType);
- for (ConfigurationType configurationType : ConfigurationType.CONFIGURATION_TYPE_EP.getExtensions()) {
- if (configurationType instanceof DeployToServerConfigurationType) {
- DeployToServerConfigurationType deployConfigurationType = (DeployToServerConfigurationType)configurationType;
- if (deployConfigurationType.getId().equals(id)) {
- return deployConfigurationType;
- }
- }
- }
- return null;
- }
-
- private static String generateRunConfigurationName(String serverName, String moduleName) {
- return CloudBundle.getText("run.configuration.name", serverName, moduleName);
+ CloudRunConfigurationUtil.createRunConfiguration(account, module, configuration);
}
private static class AccountItem {
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudRunConfigurationUtil.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudRunConfigurationUtil.java
new file mode 100644
index 000000000000..a717571a7ca6
--- /dev/null
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudRunConfigurationUtil.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.remoteServer.util;
+
+import com.intellij.execution.RunManagerEx;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.configuration.ConfigurationFactoryEx;
+import com.intellij.execution.configurations.ConfigurationFactory;
+import com.intellij.execution.configurations.ConfigurationType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.module.ModulePointerManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.remoteServer.ServerType;
+import com.intellij.remoteServer.configuration.RemoteServer;
+import com.intellij.remoteServer.configuration.ServerConfiguration;
+import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
+import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
+import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerConfigurationType;
+import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
+import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceImpl;
+
+
+public class CloudRunConfigurationUtil {
+
+ public static <SC extends ServerConfiguration, DC extends DeploymentConfiguration>
+ DeployToServerRunConfiguration<SC, DC> createRunConfiguration(RemoteServer<SC> account, Module module, DC deploymentConfiguration) {
+ final ModulePointer modulePointer = ModulePointerManager.getInstance(module.getProject()).create(module);
+ DeploymentSource deploymentSource = new ModuleDeploymentSourceImpl(modulePointer);
+ return createRunConfiguration(account, module, deploymentSource, deploymentConfiguration);
+ }
+
+ public static <SC extends ServerConfiguration, DC extends DeploymentConfiguration>
+ DeployToServerRunConfiguration<SC, DC> createRunConfiguration(RemoteServer<SC> account,
+ Module module,
+ DeploymentSource deploymentSource,
+ DC deploymentConfiguration) {
+ Project project = module.getProject();
+
+ String accountName = account.getName();
+
+ String name = generateRunConfigurationName(accountName, module.getName());
+
+ final RunManagerEx runManager = RunManagerEx.getInstanceEx(project);
+ ConfigurationFactory configurationFactory = getRunConfigurationType(account.getType()).getConfigurationFactories()[0];
+ final RunnerAndConfigurationSettings runSettings = runManager.createRunConfiguration(name, configurationFactory);
+
+ final DeployToServerRunConfiguration<SC, DC> result = (DeployToServerRunConfiguration<SC, DC>)runSettings.getConfiguration();
+
+ result.setServerName(accountName);
+
+ result.setDeploymentSource(deploymentSource);
+
+ result.setDeploymentConfiguration(deploymentConfiguration);
+
+ ((ConfigurationFactoryEx)configurationFactory).onNewConfigurationCreated(runSettings.getConfiguration());
+
+ runManager.addConfiguration(runSettings, false);
+ runManager.setSelectedConfiguration(runSettings);
+
+ return result;
+ }
+
+ private static DeployToServerConfigurationType getRunConfigurationType(ServerType<?> cloudType) {
+ String id = DeployToServerConfigurationType.getId(cloudType);
+ for (ConfigurationType configurationType : ConfigurationType.CONFIGURATION_TYPE_EP.getExtensions()) {
+ if (configurationType instanceof DeployToServerConfigurationType) {
+ DeployToServerConfigurationType deployConfigurationType = (DeployToServerConfigurationType)configurationType;
+ if (deployConfigurationType.getId().equals(id)) {
+ return deployConfigurationType;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static String generateRunConfigurationName(String serverName, String moduleName) {
+ return CloudBundle.getText("run.configuration.name", serverName, moduleName);
+ }
+}
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/Breakpoint.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/Breakpoint.java
index 41b6a35b5e8d..f2180d66a069 100755
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/Breakpoint.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/Breakpoint.java
@@ -24,11 +24,6 @@ public abstract class Breakpoint {
@NotNull
public abstract BreakpointTarget getTarget();
- /**
- * Returns line number of the breakpoint. As source is changed (typically with LiveEdit feature,
- * and particularly by calling {@link ScriptManager#setSourceOnRemote}) this value
- * may become stale.
- */
public abstract int getLine();
/**
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/DebugEventAdapter.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/DebugEventAdapter.java
index 51cf25e1aefb..10a2444fc834 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/DebugEventAdapter.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/DebugEventAdapter.java
@@ -26,7 +26,7 @@ public abstract class DebugEventAdapter implements DebugEventListener {
}
@Override
- public void scriptContentChanged(Script newScript) {
+ public void scriptContentChanged(@NotNull Script newScript) {
}
@Override
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/DebugEventListener.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/DebugEventListener.java
index 5b73448d39c7..a8038bed8f41 100755
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/DebugEventListener.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/DebugEventListener.java
@@ -50,7 +50,7 @@ public interface DebugEventListener extends EventListener {
/**
* Reports that script source has been altered in remote VM.
*/
- void scriptContentChanged(Script newScript);
+ void scriptContentChanged(@NotNull Script newScript);
/**
* Reports a navigation event on the target.
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/VmBase.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/VmBase.java
index befe4221e011..b2ebd332c623 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/VmBase.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/VmBase.java
@@ -19,6 +19,7 @@ public abstract class VmBase implements Vm {
return evaluateContext;
}
+ @NotNull
protected abstract EvaluateContext computeEvaluateContext();
@NotNull
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java
index 431a1156ae89..c033a6979f09 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java
@@ -135,6 +135,10 @@ public final class SourceMapDecoder {
}
List<String> sources = readSources(sourcesReader, sourceRoot);
+ if (sources.isEmpty()) {
+ // empty map, meteor can report such ugly maps
+ return null;
+ }
@SuppressWarnings("unchecked")
List<MappingEntry>[] reverseMappingsBySourceUrl = new List[sources.size()];
diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LazyVariablesGroup.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LazyVariablesGroup.java
index e558f4ba91ab..25b8b3e11ee5 100644
--- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LazyVariablesGroup.java
+++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LazyVariablesGroup.java
@@ -21,24 +21,24 @@ public final class LazyVariablesGroup extends XValueGroup {
private final ObjectValue value;
- private final int start;
- private final int end;
+ private final int startInclusive;
+ private final int endInclusive;
private final VariableContext context;
private final ValueType componentType;
private final boolean sparse;
- public LazyVariablesGroup(@NotNull ObjectValue value, int start, int end, @NotNull VariableContext context) {
- this(value, start, end, context, null, true);
+ public LazyVariablesGroup(@NotNull ObjectValue value, int startInclusive, int endInclusive, @NotNull VariableContext context) {
+ this(value, startInclusive, endInclusive, context, null, true);
}
- public LazyVariablesGroup(@NotNull ObjectValue value, int start, int end, @NotNull VariableContext context, @Nullable ValueType componentType, boolean sparse) {
- super(String.format("[%,d \u2026 %,d]", start, end));
+ public LazyVariablesGroup(@NotNull ObjectValue value, int startInclusive, int endInclusive, @NotNull VariableContext context, @Nullable ValueType componentType, boolean sparse) {
+ super(String.format("[%,d \u2026 %,d]", startInclusive, endInclusive));
this.value = value;
- this.start = start;
- this.end = end;
+ this.startInclusive = startInclusive;
+ this.endInclusive = endInclusive;
this.context = context;
@@ -51,18 +51,17 @@ public final class LazyVariablesGroup extends XValueGroup {
node.setAlreadySorted(true);
int bucketThreshold = XCompositeNode.MAX_CHILDREN_TO_SHOW;
- int size = end - start;
- if (!sparse && size > bucketThreshold) {
- node.addChildren(XValueChildrenList.topGroups(computeNotSparseGroups(value, context, start, end, bucketThreshold)), true);
+ if (!sparse && (endInclusive - startInclusive) > bucketThreshold) {
+ node.addChildren(XValueChildrenList.topGroups(computeNotSparseGroups(value, context, startInclusive, endInclusive + 1, bucketThreshold)), true);
return;
}
- value.getIndexedProperties(start, end + 1, bucketThreshold, new VariableView.ObsolescentIndexedVariablesConsumer(node) {
+ value.getIndexedProperties(startInclusive, endInclusive + 1, bucketThreshold, new VariableView.ObsolescentIndexedVariablesConsumer(node) {
@Override
public void consumeRanges(@Nullable int[] ranges) {
if (ranges == null) {
XValueChildrenList groupList = new XValueChildrenList();
- addGroups(value, GROUP_FACTORY, groupList, start, end, XCompositeNode.MAX_CHILDREN_TO_SHOW, context);
+ addGroups(value, GROUP_FACTORY, groupList, startInclusive, endInclusive, XCompositeNode.MAX_CHILDREN_TO_SHOW, context);
node.addChildren(groupList, true);
}
else {
@@ -78,12 +77,12 @@ public final class LazyVariablesGroup extends XValueGroup {
}
@NotNull
- public static List<XValueGroup> computeNotSparseGroups(@NotNull ObjectValue value, @NotNull VariableContext context, int from, int to, int bucketThreshold) {
- int size = to - from;
+ public static List<XValueGroup> computeNotSparseGroups(@NotNull ObjectValue value, @NotNull VariableContext context, int fromInclusive, int toExclusive, int bucketThreshold) {
+ int size = toExclusive - fromInclusive;
int bucketSize = (int)Math.pow(bucketThreshold, Math.ceil(Math.log(size) / Math.log(bucketThreshold)) - 1);
List<XValueGroup> groupList = new ArrayList<XValueGroup>((int)Math.ceil(size / bucketSize));
- for (; from < to; from += bucketSize) {
- groupList.add(new LazyVariablesGroup(value, from, from + (Math.min(bucketSize, to - from) - 1), context, ValueType.NUMBER, false));
+ for (; fromInclusive < toExclusive; fromInclusive += bucketSize) {
+ groupList.add(new LazyVariablesGroup(value, fromInclusive, fromInclusive + (Math.min(bucketSize, toExclusive - fromInclusive) - 1), context, ValueType.NUMBER, false));
}
return groupList;
}
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/BoxableType.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/BoxableType.java
index 8c7175962c76..3f4b8ea839ac 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/BoxableType.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/BoxableType.java
@@ -2,6 +2,7 @@ package org.jetbrains.protocolReader;
abstract class BoxableType {
static final BoxableType STRING = new StandaloneType(new NamePath("String"), "writeString");
+ static final BoxableType ANY_STRING = new StandaloneType(new NamePath("String"), "writeString");
static final BoxableType INT = new StandaloneType(new NamePath("int"), "writeInt");
static final BoxableType LONG = new StandaloneType(new NamePath("long"), "writeLong");
static final BoxableType NUMBER = new StandaloneType(new NamePath("double"), "writeDouble");
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ClassScope.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ClassScope.java
index 6b27866492a4..31ba16f3438c 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ClassScope.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ClassScope.java
@@ -20,10 +20,6 @@ abstract class ClassScope {
return contextNamespace.getLastComponent();
}
- String getFullName() {
- return contextNamespace.getFullText();
- }
-
NamePath getClassContextNamespace() {
return contextNamespace;
}
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/DomainGenerator.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/DomainGenerator.java
index b74c73e28e1a..6798629e835c 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/DomainGenerator.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/DomainGenerator.java
@@ -153,7 +153,7 @@ class DomainGenerator {
}
@Override
- public <T extends ItemDescriptor> QualifiedTypeData resolveType(T typedObject) {
+ public <T extends ItemDescriptor> TypeDescriptor resolveType(T typedObject) {
throw new UnsupportedOperationException();
}
@@ -162,8 +162,7 @@ class DomainGenerator {
throw new UnsupportedOperationException();
}
};
- QualifiedTypeData itemTypeData = generator.resolveType(items, resolveAndGenerateScope);
- BoxableType itemBoxableType = itemTypeData.getJavaType();
+ BoxableType itemBoxableType = generator.resolveType(items, resolveAndGenerateScope).getType();
final BoxableType arrayType = new ListType(itemBoxableType);
StandaloneTypeBinding.Target target = new StandaloneTypeBinding.Target() {
@@ -178,7 +177,7 @@ class DomainGenerator {
});
}
- StandaloneTypeBinding createStandaloneObjectInputTypeBinding(final ProtocolMetaModel.StandaloneType type, final List<ProtocolMetaModel.ObjectProperty> properties) {
+ StandaloneTypeBinding createStandaloneObjectInputTypeBinding(@NotNull final ProtocolMetaModel.StandaloneType type, @Nullable final List<ProtocolMetaModel.ObjectProperty> properties) {
final String name = type.id();
final NamePath fullTypeName = generator.getNaming().inputValue.getFullName(domain.domain(), name);
generator.jsonProtocolParserClassNames.add(fullTypeName.getFullText());
@@ -198,10 +197,12 @@ class DomainGenerator {
out.doc(type.description());
}
- out.append("@org.chromium.protocolReader.JsonType").newLine();
+ out.append("@org.jetbrains.jsonProtocol.JsonType").newLine();
out.append("public interface ").append(className.getLastComponent()).openBlock();
InputClassScope classScope = new InputClassScope(DomainGenerator.this, className);
- classScope.generateStandaloneTypeBody(out, properties);
+ if (properties != null) {
+ classScope.generateDeclarationBody(out, properties);
+ }
classScope.writeAdditionalMembers(out);
out.closeBlock();
fileUpdater.update();
@@ -309,16 +310,18 @@ class DomainGenerator {
fileUpdater.update();
}
- private void generateJsonProtocolInterface(TextOutput out, String className, String description, List<ProtocolMetaModel.Parameter> parameters, TextOutConsumer additionalMembersText) throws IOException {
+ private void generateJsonProtocolInterface(TextOutput out, String className, String description, List<ProtocolMetaModel.Parameter> parameters, TextOutConsumer additionalMembersText) {
if (description != null) {
out.doc(description);
}
- out.append("@org.chromium.protocolReader.JsonType").newLine().append("public interface ").append(className).openBlock();
+ out.append("@org.jetbrains.jsonProtocol.JsonType").newLine().append("public interface ").append(className).openBlock();
InputClassScope classScope = new InputClassScope(this, new NamePath(className, new NamePath(ClassNameScheme.getPackageName(generator.getNaming().inputPackage, domain.domain()))));
if (additionalMembersText != null) {
classScope.addMember(additionalMembersText);
}
- classScope.generateMainJsonProtocolInterfaceBody(out, parameters);
+ if (parameters != null) {
+ classScope.generateDeclarationBody(out, parameters);
+ }
classScope.writeAdditionalMembers(out);
out.closeBlock();
}
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/Generator.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/Generator.java
index e545f0280f81..b02905ad51ad 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/Generator.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/Generator.java
@@ -114,92 +114,61 @@ class Generator {
fileSet.deleteOtherFiles();
}
- QualifiedTypeData resolveType(final ItemDescriptor typedObject, final ResolveAndGenerateScope scope) {
- UnqualifiedTypeData unqualifiedType = switchByType(typedObject, new TypeVisitor<UnqualifiedTypeData>() {
+ TypeDescriptor resolveType(@NotNull final ItemDescriptor typedObject, @NotNull final ResolveAndGenerateScope scope) {
+ final boolean optional = typedObject instanceof ItemDescriptor.Named && ((ItemDescriptor.Named)typedObject).optional();
+ return switchByType(typedObject, new TypeVisitor<TypeDescriptor>() {
@Override
- public UnqualifiedTypeData visitRef(String refName) {
- return new UnqualifiedTypeData(resolveRefType(scope.getDomainName(), refName, scope.getTypeDirection()));
+ public TypeDescriptor visitRef(String refName) {
+ return new TypeDescriptor(resolveRefType(scope.getDomainName(), refName, scope.getTypeDirection()), optional);
}
@Override
- public UnqualifiedTypeData visitBoolean() {
- return UnqualifiedTypeData.BOOLEAN;
+ public TypeDescriptor visitBoolean() {
+ return new TypeDescriptor(BoxableType.BOOLEAN, optional);
}
@Override
- public UnqualifiedTypeData visitEnum(List<String> enumConstants) {
+ public TypeDescriptor visitEnum(List<String> enumConstants) {
assert scope instanceof MemberScope;
- return new UnqualifiedTypeData(((MemberScope)scope).generateEnum(typedObject.description(), enumConstants));
+ return new TypeDescriptor(((MemberScope)scope).generateEnum(typedObject.description(), enumConstants), optional);
}
@Override
- public UnqualifiedTypeData visitString() {
- return UnqualifiedTypeData.STRING;
+ public TypeDescriptor visitString() {
+ return new TypeDescriptor(BoxableType.STRING, optional);
}
@Override
- public UnqualifiedTypeData visitInteger() {
- return UnqualifiedTypeData.INT;
+ public TypeDescriptor visitInteger() {
+ return new TypeDescriptor(BoxableType.INT, optional);
}
@Override
- public UnqualifiedTypeData visitNumber() {
- return UnqualifiedTypeData.NUMBER;
+ public TypeDescriptor visitNumber() {
+ return new TypeDescriptor(BoxableType.NUMBER, optional);
}
@Override
- public UnqualifiedTypeData visitMap() {
- return UnqualifiedTypeData.MAP;
+ public TypeDescriptor visitMap() {
+ return new TypeDescriptor(BoxableType.MAP, optional);
}
@Override
- public UnqualifiedTypeData visitArray(ArrayItemType items) {
- return new UnqualifiedTypeData(new ListType(scope.resolveType(items).getJavaType()));
+ public TypeDescriptor visitArray(ArrayItemType items) {
+ BoxableType type = scope.resolveType(items).getType();
+ return new TypeDescriptor(new ListType(type), optional, false, type == BoxableType.ANY_STRING);
}
@Override
- public UnqualifiedTypeData visitObject(List<ObjectProperty> properties) {
- return new UnqualifiedTypeData(scope.generateNestedObject(typedObject.description(), properties), false);
+ public TypeDescriptor visitObject(List<ObjectProperty> properties) {
+ return new TypeDescriptor(scope.generateNestedObject(typedObject.description(), properties), optional);
}
@Override
- public UnqualifiedTypeData visitUnknown() {
- return UnqualifiedTypeData.ANY;
+ public TypeDescriptor visitUnknown() {
+ return new TypeDescriptor(BoxableType.STRING, optional, false, true);
}
});
-
- return unqualifiedType.getQualifiedType(typedObject instanceof ItemDescriptor.Named && ((ItemDescriptor.Named)typedObject).optional());
- }
-
- private static class UnqualifiedTypeData {
- private final BoxableType typeRef;
- private final boolean nullable;
- private final boolean asRawString;
-
- UnqualifiedTypeData(BoxableType typeRef) {
- this(typeRef, false);
- }
-
- UnqualifiedTypeData(BoxableType typeRef, boolean nullable) {
- this(typeRef, nullable, false);
- }
-
- UnqualifiedTypeData(BoxableType typeRef, boolean nullable, boolean asRawString) {
- this.typeRef = typeRef;
- this.nullable = nullable;
- this.asRawString = asRawString;
- }
-
- QualifiedTypeData getQualifiedType(boolean optional) {
- return new QualifiedTypeData(typeRef, optional, nullable, asRawString);
- }
-
- static final UnqualifiedTypeData BOOLEAN = new UnqualifiedTypeData(BoxableType.BOOLEAN, false);
- static final UnqualifiedTypeData STRING = new UnqualifiedTypeData(BoxableType.STRING, false);
- static final UnqualifiedTypeData INT = new UnqualifiedTypeData(BoxableType.INT, false);
- static final UnqualifiedTypeData MAP = new UnqualifiedTypeData(BoxableType.MAP, false);
- static final UnqualifiedTypeData NUMBER = new UnqualifiedTypeData(BoxableType.NUMBER, false);
- static final UnqualifiedTypeData ANY = new UnqualifiedTypeData(BoxableType.STRING, false, true);
}
private void generateParserInterfaceList() throws IOException {
@@ -274,11 +243,11 @@ class Generator {
return typeMap.resolve(domainName, shortName, direction);
}
- static String generateMethodNameSubstitute(String originalName, TextOutput out) {
+ static String generateMethodNameSubstitute(@NotNull String originalName, @NotNull TextOutput out) {
if (!BAD_METHOD_NAMES.contains(originalName)) {
return originalName;
}
- out.append("@org.chromium.protocolReader.JsonField(jsonLiteralName=\"").append(originalName).append("\")").newLine();
+ out.append("@org.jetbrains.jsonProtocol.JsonField(jsonLiteralName=\"").append(originalName).append("\")").newLine();
return "get" + Character.toUpperCase(originalName.charAt(0)) + originalName.substring(1);
}
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/InputClassScope.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/InputClassScope.java
index 9411f4d25db1..99c95d8f5ae3 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/InputClassScope.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/InputClassScope.java
@@ -1,8 +1,9 @@
package org.jetbrains.protocolReader;
-import org.jetbrains.jsonProtocol.ProtocolMetaModel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jsonProtocol.ItemDescriptor.Named;
+import org.jetbrains.jsonProtocol.ProtocolMetaModel.ObjectProperty;
-import java.io.IOException;
import java.util.List;
class InputClassScope extends ClassScope {
@@ -10,36 +11,20 @@ class InputClassScope extends ClassScope {
super(generator, namePath);
}
- public void generateMainJsonProtocolInterfaceBody(TextOutput out, List<ProtocolMetaModel.Parameter> parameters) throws IOException {
- if (parameters != null) {
- for (ProtocolMetaModel.Parameter parameter : parameters) {
- if (parameter.description() != null) {
- out.doc(parameter.description());
- }
-
- String methodName = Generator.generateMethodNameSubstitute(getName(parameter), out);
- QualifiedTypeData paramTypeData = newMemberScope(getName(parameter)).resolveType(parameter);
- paramTypeData.writeAnnotations(out);
- out.append(paramTypeData.getJavaType().getShortText(getClassContextNamespace())).space().append(methodName).append("();").newLine();
+ void generateDeclarationBody(@NotNull TextOutput out, @NotNull List<? extends Named> list) {
+ for (int i = 0, n = list.size(); i < n; i++) {
+ Named named = list.get(i);
+ if (named.description() != null) {
+ out.doc(named.description());
}
- }
- }
-
- void generateStandaloneTypeBody(TextOutput out, List<ProtocolMetaModel.ObjectProperty> properties) throws IOException {
- if (properties != null) {
- for (ProtocolMetaModel.ObjectProperty objectProperty : properties) {
- String propertyName = getName(objectProperty);
- if (objectProperty.description() != null) {
- out.doc(objectProperty.description());
- }
-
- String methodName = Generator.generateMethodNameSubstitute(propertyName, out);
- MemberScope memberScope = newMemberScope(propertyName);
- QualifiedTypeData propertyTypeData = memberScope.resolveType(objectProperty);
- propertyTypeData.writeAnnotations(out);
-
- out.append(propertyTypeData.getJavaType().getShortText(getClassContextNamespace()) + ' ' + methodName + "();").newLine();
+ String name = getName(named);
+ String declarationName = Generator.generateMethodNameSubstitute(name, out);
+ TypeDescriptor typeDescriptor = new InputMemberScope(name).resolveType(named);
+ typeDescriptor.writeAnnotations(out);
+ out.append(typeDescriptor.getType().getShortText(getClassContextNamespace())).space().append(declarationName).append("();");
+ if (i != (n - 1)) {
+ out.newLine().newLine();
}
}
}
@@ -49,10 +34,6 @@ class InputClassScope extends ClassScope {
return TypeData.Direction.INPUT;
}
- private MemberScope newMemberScope(String memberName) {
- return new InputMemberScope(memberName);
- }
-
class InputMemberScope extends MemberScope {
InputMemberScope(String memberName) {
super(InputClassScope.this, memberName);
@@ -72,28 +53,28 @@ class InputClassScope extends ClassScope {
}
@Override
- public BoxableType generateNestedObject(final String description, final List<ProtocolMetaModel.ObjectProperty> propertyList) {
+ public BoxableType generateNestedObject(final String description, final List<ObjectProperty> propertyList) {
final String objectName = Generator.capitalizeFirstChar(getMemberName());
addMember(new TextOutConsumer() {
@Override
public void append(TextOutput out) {
out.newLine().doc(description);
if (propertyList == null) {
- out.append("@org.chromium.protocolReader.JsonType(allowsOtherProperties=true)").newLine();
+ out.append("@org.jetbrains.jsonProtocol.JsonType(allowsOtherProperties=true)").newLine();
out.append("public interface ").append(objectName).append(" extends org.jetbrains.jsonProtocol.JsonObjectBased").openBlock();
}
else {
- out.append("@org.chromium.protocolReader.JsonType").newLine();
+ out.append("@org.jetbrains.jsonProtocol.JsonType").newLine();
out.append("public interface ").append(objectName).openBlock();
- for (ProtocolMetaModel.ObjectProperty property : propertyList) {
+ for (ObjectProperty property : propertyList) {
out.doc(property.description());
String methodName = Generator.generateMethodNameSubstitute(getName(property), out);
- MemberScope memberScope = newMemberScope(getName(property));
- QualifiedTypeData propertyTypeData = memberScope.resolveType(property);
+ MemberScope memberScope = new InputMemberScope(getName(property));
+ TypeDescriptor propertyTypeData = memberScope.resolveType(property);
propertyTypeData.writeAnnotations(out);
- out.append(propertyTypeData.getJavaType().getShortText(getClassContextNamespace()) + ' ' + methodName + "();").newLine();
+ out.append(propertyTypeData.getType().getShortText(getClassContextNamespace()) + ' ' + methodName + "();").newLine();
}
}
out.closeBlock();
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/MemberScope.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/MemberScope.java
index 21de2ca3b228..78a83a9127ca 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/MemberScope.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/MemberScope.java
@@ -19,7 +19,7 @@ abstract class MemberScope implements ResolveAndGenerateScope {
}
@Override
- public <T extends ItemDescriptor> QualifiedTypeData resolveType(T typedObject) {
+ public <T extends ItemDescriptor> TypeDescriptor resolveType(T typedObject) {
return classScope.generator.generator.resolveType(typedObject, this);
}
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/MyCreateStandaloneTypeBindingVisitorBase.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/MyCreateStandaloneTypeBindingVisitorBase.java
index e867bf924eaa..90b7068e8cb5 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/MyCreateStandaloneTypeBindingVisitorBase.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/MyCreateStandaloneTypeBindingVisitorBase.java
@@ -60,7 +60,7 @@ class MyCreateStandaloneTypeBindingVisitorBase extends CreateStandaloneTypeBindi
}
@Override
- public <T extends ItemDescriptor> QualifiedTypeData resolveType(T typedObject) {
+ public <T extends ItemDescriptor> TypeDescriptor resolveType(T typedObject) {
throw new UnsupportedOperationException();
}
@@ -68,7 +68,7 @@ class MyCreateStandaloneTypeBindingVisitorBase extends CreateStandaloneTypeBindi
public BoxableType generateNestedObject(String description, List<ProtocolMetaModel.ObjectProperty> properties) {
return context.generateNestedObject("Item", description, properties);
}
- }).getJavaType());
+ }).getType());
}
}, generator.generator.getNaming().outputTypedef, TypeData.Direction.OUTPUT);
}
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/OutputClassScope.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/OutputClassScope.java
index fa7f4f18740f..f88a55d7a039 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/OutputClassScope.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/OutputClassScope.java
@@ -19,8 +19,8 @@ class OutputClassScope extends ClassScope {
return;
}
- List<P> mandatoryParameters = new ArrayList<P>();
- List<P> optionalParameters = new ArrayList<P>();
+ List<P> mandatoryParameters = new ArrayList<>();
+ List<P> optionalParameters = new ArrayList<>();
for (P parameter : parameters) {
if (parameter.optional()) {
optionalParameters.add(parameter);
@@ -34,8 +34,8 @@ class OutputClassScope extends ClassScope {
generateConstructor(out, mandatoryParameters, null);
if (mandatoryParameters.size() == 1) {
P parameter = mandatoryParameters.get(0);
- QualifiedTypeData typeData = new OutputMemberScope(getName(parameter)).resolveType(parameter);
- if (typeData.getJavaType().getFullText().equals("int[]")) {
+ TypeDescriptor typeData = new OutputMemberScope(getName(parameter)).resolveType(parameter);
+ if (typeData.getType().getFullText().equals("int[]")) {
BoxableType[] types = new BoxableType[mandatoryParameters.size()];
types[0] = new ListType(BoxableType.INT) {
@Override
@@ -94,7 +94,7 @@ class OutputClassScope extends ClassScope {
out.append("/**").newLine().append(" * @param v ").append(parameter.description()).newLine().append(" */").newLine();
}
- CharSequence type = new OutputMemberScope(parameter.name()).resolveType(parameter).getJavaType().getShortText(getClassContextNamespace());
+ CharSequence type = new OutputMemberScope(parameter.name()).resolveType(parameter).getType().getShortText(getClassContextNamespace());
if (type.equals(JsonReaderEx.class.getCanonicalName())) {
type = "String";
}
@@ -131,9 +131,10 @@ class OutputClassScope extends ClassScope {
mandatoryParameterTypes = new BoxableType[mandatoryParameters.size()];
}
for (int i = 0, length = mandatoryParameterTypes.length; i < length; i++) {
+ assert mandatoryParameterTypes != null;
if (mandatoryParameterTypes[i] == null) {
P parameter = mandatoryParameters.get(i);
- mandatoryParameterTypes[i] = new OutputMemberScope(parameter.name()).resolveType(parameter).getJavaType();
+ mandatoryParameterTypes[i] = new OutputMemberScope(parameter.name()).resolveType(parameter).getType();
}
}
@@ -144,6 +145,7 @@ class OutputClassScope extends ClassScope {
out.comma();
}
+ assert mandatoryParameterTypes != null;
out.append(mandatoryParameterTypes[i].getShortText(getClassContextNamespace()));
out.space().append(parameter.name());
needComa = true;
@@ -152,6 +154,7 @@ class OutputClassScope extends ClassScope {
for (int i = 0, size = mandatoryParameters.size(); i < size; i++) {
P parameter = mandatoryParameters.get(i);
out.newLine();
+ assert mandatoryParameterTypes != null;
appendWriteValueInvocation(out, parameter, parameter.name(), mandatoryParameterTypes[i]);
}
out.closeBlock();
@@ -159,7 +162,7 @@ class OutputClassScope extends ClassScope {
private void appendWriteValueInvocation(TextOutput out, ItemDescriptor.Named parameter, String valueRefName, @Nullable BoxableType type) {
if (type == null) {
- type = new OutputMemberScope(parameter.name()).resolveType(parameter).getJavaType();
+ type = new OutputMemberScope(parameter.name()).resolveType(parameter).getType();
}
boolean blockOpened = false;
@@ -188,7 +191,7 @@ class OutputClassScope extends ClassScope {
}
// todo CallArgument (we should allow write null as value)
out.append(parameter.name().equals("value") && type.getWriteMethodName().equals("writeString") ? "writeNullableString" : type.getWriteMethodName()).append("(");
- out.quoute(parameter.name()).comma().append(valueRefName).append(");");
+ out.quote(parameter.name()).comma().append(valueRefName).append(");");
if (blockOpened) {
out.closeBlock();
}
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ParserRootInterfaceItem.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ParserRootInterfaceItem.java
index e3e8049c1b6d..e84c641ff9c3 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ParserRootInterfaceItem.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ParserRootInterfaceItem.java
@@ -18,7 +18,7 @@ class ParserRootInterfaceItem implements Comparable<ParserRootInterfaceItem> {
}
void writeCode(TextOutput out) throws IOException {
- out.append("@org.chromium.protocolReader.JsonParseMethod").newLine();
+ out.append("@org.jetbrains.jsonProtocol.JsonParseMethod").newLine();
out.append("public abstract ").append(fullName).space();
appendReadMethodName(out);
out.append("(").append(Util.JSON_READER_PARAMETER_DEF).append(")").semi().newLine();
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ResolveAndGenerateScope.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ResolveAndGenerateScope.java
index 8f117d02ab95..c43c9ff7deff 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ResolveAndGenerateScope.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/ResolveAndGenerateScope.java
@@ -9,7 +9,7 @@ interface ResolveAndGenerateScope {
String getDomainName();
TypeData.Direction getTypeDirection();
- <T extends ItemDescriptor> QualifiedTypeData resolveType(T typedObject);
+ <T extends ItemDescriptor> TypeDescriptor resolveType(T typedObject);
BoxableType generateNestedObject(String description,
List<ProtocolMetaModel.ObjectProperty> properties);
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/TypeData.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/TypeData.java
index 0ab11a07c352..7fbc5f6c2cad 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/TypeData.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/TypeData.java
@@ -4,6 +4,21 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jsonProtocol.ProtocolMetaModel;
class TypeData {
+ public static final StandaloneTypeBinding ANY = new StandaloneTypeBinding() {
+ @Override
+ public BoxableType getJavaType() {
+ return BoxableType.ANY_STRING;
+ }
+
+ @Override
+ public void generate() {
+ }
+
+ @Override
+ public Direction getDirection() {
+ return null;
+ }
+ };
private final String name;
private Input input;
@@ -119,21 +134,7 @@ class TypeData {
};
}
else if (name.equals("any")) {
- return new StandaloneTypeBinding() {
- @Override
- public BoxableType getJavaType() {
- return BoxableType.STRING;
- }
-
- @Override
- public void generate() {
- }
-
- @Override
- public Direction getDirection() {
- return null;
- }
- };
+ return ANY;
}
throw new RuntimeException();
@@ -164,21 +165,7 @@ class TypeData {
};
}
else if (name.equals("any")) {
- return new StandaloneTypeBinding() {
- @Override
- public BoxableType getJavaType() {
- return BoxableType.STRING;
- }
-
- @Override
- public void generate() {
- }
-
- @Override
- public Direction getDirection() {
- return null;
- }
- };
+ return ANY;
}
throw new RuntimeException();
diff --git a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/QualifiedTypeData.java b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/TypeDescriptor.java
index a4ccd0b3c49f..d142e8bdf6d5 100644
--- a/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/QualifiedTypeData.java
+++ b/platform/script-debugger/protocol/protocol-model-generator/src/org/jetbrains/protocolReader/TypeDescriptor.java
@@ -1,13 +1,19 @@
package org.jetbrains.protocolReader;
-class QualifiedTypeData {
- private final BoxableType typeRef;
+import org.jetbrains.annotations.NotNull;
+
+class TypeDescriptor {
+ private final BoxableType type;
private final boolean optional;
private final boolean nullable;
private final boolean asRawString;
- QualifiedTypeData(BoxableType typeRef, boolean optional, boolean nullable, boolean asRawString) {
- this.typeRef = typeRef;
+ TypeDescriptor(@NotNull BoxableType type, boolean optional) {
+ this(type, optional, false, false);
+ }
+
+ TypeDescriptor(@NotNull BoxableType type, boolean optional, boolean nullable, boolean asRawString) {
+ this.type = type;
this.optional = optional;
this.nullable = nullable;
this.asRawString = asRawString;
@@ -17,13 +23,14 @@ class QualifiedTypeData {
return nullable;
}
- BoxableType getJavaType() {
- return typeRef;
+ @NotNull
+ BoxableType getType() {
+ return type;
}
- void writeAnnotations(TextOutput out) {
+ void writeAnnotations(@NotNull TextOutput out) {
if (optional || asRawString) {
- out.append("@org.chromium.protocolReader.JsonField(");
+ out.append("@org.jetbrains.jsonProtocol.JsonField(");
if (optional) {
out.append("optional=true");
}
@@ -37,7 +44,7 @@ class QualifiedTypeData {
}
if (isNullable()) {
- out.append("@org.chromium.protocolReader.JsonNullable").newLine();
+ out.append("@org.jetbrains.jsonProtocol.JsonNullable").newLine();
}
}
}
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonField.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonField.java
index 5dfa26ca057a..3b960b8636a9 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonField.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonField.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.protocolReader;
+package org.jetbrains.jsonProtocol;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -25,6 +25,7 @@ public @interface JsonField {
// read any primitive value as String (true as true, number as string - don't try to parse)
boolean allowAnyPrimitiveValue() default false;
+
boolean allowAnyPrimitiveValueAndMap() default false;
boolean optional() default false;
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonNullable.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonNullable.java
index bbaa82a1b2c5..8e88ab4eb2b4 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonNullable.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonNullable.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.protocolReader;
+package org.jetbrains.jsonProtocol;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonOptionalField.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonOptionalField.java
index a2ede4854bf5..92c9cd978700 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonOptionalField.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonOptionalField.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.protocolReader;
+package org.jetbrains.jsonProtocol;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonParseMethod.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonParseMethod.java
index c964e8057018..8016b9b59539 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonParseMethod.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonParseMethod.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.protocolReader;
+package org.jetbrains.jsonProtocol;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonReaders.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonReaders.java
index aa1d19f1bad2..056e4dc6b78f 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonReaders.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonReaders.java
@@ -234,7 +234,7 @@ public final class JsonReaders {
return list;
}
- public static List<String> readListOfPrimitive(JsonReaderEx reader) {
+ public static List<String> readRawStringArray(JsonReaderEx reader) {
reader.beginArray();
if (!reader.hasNext()) {
reader.endArray();
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonSubtype.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonSubtype.java
index f104d74943cd..b40d4a1b7687 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonSubtype.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonSubtype.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.protocolReader;
+package org.jetbrains.jsonProtocol;
/**
* A base interface for JSON subtype interface. This inheritance serves 2 purposes:
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonSubtypeCasting.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonSubtypeCasting.java
index 05275511e407..cc59fed74eac 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonSubtypeCasting.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonSubtypeCasting.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.protocolReader;
+package org.jetbrains.jsonProtocol;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonType.java b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonType.java
index 62e2c8c12118..79dc453ac9fb 100644
--- a/platform/script-debugger/protocol/protocol-reader-runtime/src/org/chromium/protocolReader/JsonType.java
+++ b/platform/script-debugger/protocol/protocol-reader-runtime/src/org/jetbrains/jsonProtocol/JsonType.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.protocolReader;
+package org.jetbrains.jsonProtocol;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java
index eabc8d8e4337..111e58caa3a6 100644
--- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java
+++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/FieldProcessor.java
@@ -1,6 +1,9 @@
package org.jetbrains.protocolReader;
-import org.chromium.protocolReader.*;
+import org.jetbrains.jsonProtocol.JsonField;
+import org.jetbrains.jsonProtocol.JsonNullable;
+import org.jetbrains.jsonProtocol.JsonOptionalField;
+import org.jetbrains.jsonProtocol.JsonSubtypeCasting;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java
index f80b8c54bb42..cc4e2566f4dd 100644
--- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java
+++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/InterfaceReader.java
@@ -1,10 +1,10 @@
package org.jetbrains.protocolReader;
import gnu.trove.THashSet;
-import org.chromium.protocolReader.JsonField;
-import org.chromium.protocolReader.JsonSubtype;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.io.JsonReaderEx;
+import org.jetbrains.jsonProtocol.JsonField;
+import org.jetbrains.jsonProtocol.JsonSubtype;
import org.jetbrains.jsonProtocol.StringIntPair;
import java.lang.annotation.RetentionPolicy;
@@ -249,7 +249,7 @@ class InterfaceReader {
argumentType = wildcard.getUpperBounds()[0];
}
}
- return new ArrayReader(getFieldTypeParser(argumentType, false, false, null), true, declaredNullable);
+ return new ArrayReader(getFieldTypeParser(argumentType, false, false, method), true, declaredNullable);
}
else if (parameterizedType.getRawType() == Map.class) {
return declaredNullable ? NULLABLE_MAP_PARSER : MAP_PARSER;
diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java
index a76971dc5da7..7914a5103ac6 100644
--- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java
+++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ReaderRoot.java
@@ -2,7 +2,7 @@ package org.jetbrains.protocolReader;
import org.jetbrains.io.JsonReaderEx;
import gnu.trove.THashSet;
-import org.chromium.protocolReader.JsonParseMethod;
+import org.jetbrains.jsonProtocol.JsonParseMethod;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TextOutput.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TextOutput.java
index cd5afa1c27ff..77d4bd1e275f 100644
--- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TextOutput.java
+++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/TextOutput.java
@@ -9,7 +9,7 @@ public class TextOutput {
private int identLevel;
private final static int indentGranularity = 2;
private char[][] indents = {EMPTY_CHARS};
- private boolean justNewlined;
+ private boolean justNewLined;
private final StringBuilder out;
public TextOutput(StringBuilder out) {
@@ -41,7 +41,7 @@ public class TextOutput {
public TextOutput newLine() {
out.append('\n');
- justNewlined = true;
+ justNewLined = true;
return this;
}
@@ -122,14 +122,14 @@ public class TextOutput {
return append("/**").newLine().append(" * ").append(description).newLine().append(" */").newLine();
}
- public TextOutput quoute(CharSequence s) {
+ public TextOutput quote(CharSequence s) {
return append('"').append(s).append('"');
}
public void maybeIndent() {
- if (justNewlined) {
+ if (justNewLined) {
out.append(indents[identLevel]);
- justNewlined = false;
+ justNewLined = false;
}
}
}
diff --git a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ValueReader.java b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ValueReader.java
index 7ef6b3e0fc82..442167687b40 100644
--- a/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ValueReader.java
+++ b/platform/script-debugger/protocol/protocol-reader/src/org/jetbrains/protocolReader/ValueReader.java
@@ -1,7 +1,3 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
package org.jetbrains.protocolReader;
import org.jetbrains.annotations.Nullable;
@@ -51,7 +47,7 @@ abstract class ValueReader {
out.append("name");
}
else {
- out.quoute(fieldName);
+ out.quote(fieldName);
}
}
}
diff --git a/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ItemDescriptor.java b/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ItemDescriptor.java
index 26dbd72d058e..d6f5afcfbe27 100644
--- a/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ItemDescriptor.java
+++ b/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ItemDescriptor.java
@@ -1,7 +1,5 @@
package org.jetbrains.jsonProtocol;
-import org.chromium.protocolReader.JsonOptionalField;
-
import java.util.List;
public interface ItemDescriptor {
diff --git a/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ProtocolMetaModel.java b/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ProtocolMetaModel.java
index c08c50c108aa..a4aeeec15d37 100644
--- a/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ProtocolMetaModel.java
+++ b/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ProtocolMetaModel.java
@@ -1,9 +1,5 @@
package org.jetbrains.jsonProtocol;
-import org.chromium.protocolReader.JsonField;
-import org.chromium.protocolReader.JsonOptionalField;
-import org.chromium.protocolReader.JsonType;
-
import java.util.List;
/**
diff --git a/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ProtocolSchemaReader.java b/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ProtocolSchemaReader.java
index 50aeebbbdf1e..aafe735409fd 100644
--- a/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ProtocolSchemaReader.java
+++ b/platform/script-debugger/protocol/schema-reader-generator/src/org/jetbrains/jsonProtocol/ProtocolSchemaReader.java
@@ -5,7 +5,6 @@
package org.jetbrains.jsonProtocol;
import org.jetbrains.io.JsonReaderEx;
-import org.chromium.protocolReader.JsonParseMethod;
import org.jetbrains.jsonProtocol.ProtocolMetaModel.Root;
import java.io.IOException;
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java
index 8532b9aa4084..b77acd9c03ee 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralToSMTRunnerEventsConvertor.java
@@ -273,7 +273,11 @@ public class GeneralToSMTRunnerEventsConvertor extends GeneralTestEventsProcesso
public void onTestFailure(@NotNull final TestFailedEvent testFailedEvent) {
addToInvokeLater(new Runnable() {
public void run() {
- final String testName = ObjectUtils.assertNotNull(testFailedEvent.getName());
+ final String testName = testFailedEvent.getName();
+ if (testName == null) {
+ logProblem("No test name specified in " + testFailedEvent);
+ return;
+ }
final String localizedMessage = testFailedEvent.getLocalizedFailureMessage();
final String stackTrace = testFailedEvent.getStacktrace();
final boolean isTestError = testFailedEvent.isTestError();
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/SuiteInProgressState.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/SuiteInProgressState.java
index d454ae03bf4c..5d4cf5472204 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/SuiteInProgressState.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/SuiteInProgressState.java
@@ -18,6 +18,7 @@ package com.intellij.execution.testframework.sm.runner.states;
import org.jetbrains.annotations.NotNull;
import com.intellij.execution.testframework.sm.runner.SMTestProxy;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -42,7 +43,7 @@ public class SuiteInProgressState extends TestInProgressState {
}
//Test suit fails if any of its tests fails
- final List<? extends SMTestProxy> children = mySuiteProxy.getChildren();
+ final List<? extends SMTestProxy> children = new ArrayList<SMTestProxy>(mySuiteProxy.getChildren());
for (SMTestProxy child : children) {
if (child.isDefect()) {
myDefectFound = true;
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/CompiledPattern.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/CompiledPattern.java
index 565f80ac01ce..70c1cdccd03e 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/CompiledPattern.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/CompiledPattern.java
@@ -82,7 +82,7 @@ public abstract class CompiledPattern {
public boolean isRealTypedVar(PsiElement element) {
if (element!=null && element.getTextLength()>0) {
String str = getTypedVarString(element);
- if (str.length()==0) {
+ if (str == null || str.length()==0) {
return false;
}
return isTypedVar( str );
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/PatternCompiler.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/PatternCompiler.java
index e290ebb70793..6dba855121cb 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/PatternCompiler.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/compiler/PatternCompiler.java
@@ -272,12 +272,8 @@ public class PatternCompiler {
element.accept(new PsiRecursiveElementWalkingVisitor() {
@Override
- public void visitElement(PsiElement element) {
- super.visitElement(element);
-
- if (!(element instanceof PsiErrorElement)) {
- return;
- }
+ public void visitErrorElement(PsiErrorElement element) {
+ super.visitErrorElement(element);
final int startOffset = element.getTextRange().getStartOffset();
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java
index 368240ff50be..f82ad12e5f4f 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java
@@ -22,7 +22,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComponentWithBrowseButton;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
@@ -36,8 +35,6 @@ import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.EditorTextField;
-import com.intellij.ui.components.labels.LinkLabel;
-import com.intellij.ui.components.labels.LinkListener;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -46,7 +43,6 @@ import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
-import javax.swing.text.BadLocationException;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -117,7 +113,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
withinCombo.getComboBox().setEditable(true);
withinCombo.getButton().addActionListener(new ActionListener() {
- public void actionPerformed(final ActionEvent e) {
+ public void actionPerformed(@NotNull final ActionEvent e) {
final SelectTemplateDialog dialog = new SelectTemplateDialog(project, false, false);
dialog.show();
if (dialog.getExitCode() == OK_EXIT_CODE) {
@@ -191,7 +187,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
new ListSelectionListener() {
boolean rollingBackSelection;
- public void valueChanged(ListSelectionEvent e) {
+ public void valueChanged(@NotNull ListSelectionEvent e) {
if (e.getValueIsAdjusting()) return;
if (rollingBackSelection) {
rollingBackSelection=false;
@@ -212,7 +208,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
parameterList.setCellRenderer(
new DefaultListCellRenderer() {
- public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ public Component getListCellRendererComponent(@NotNull JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
String name = ((Variable)value).getName();
if (Configuration.CONTEXT_VAR_NAME.equals(name)) name = SSRBundle.message("complete.match.variable.name");
if (isReplacementVariable(name)) {
@@ -226,7 +222,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
maxoccursUnlimited.addChangeListener(new MyChangeListener(maxoccurs, true));
customScriptCode.getButton().addActionListener(new ActionListener() {
- public void actionPerformed(final ActionEvent e) {
+ public void actionPerformed(@NotNull final ActionEvent e) {
final EditScriptDialog dialog = new EditScriptDialog(project, customScriptCode.getChildComponent().getText());
dialog.show();
if (dialog.getExitCode() == OK_EXIT_CODE) {
@@ -505,18 +501,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
formalArgType = createRegexComponent();
customScriptCode = new ComponentWithBrowseButton<EditorTextField>(createScriptComponent(), null);
- myRegExHelpLabel = new LinkLabel(SSRBundle.message("regular.expression.help.label"), null, new LinkListener() {
- public void linkSelected(LinkLabel aSource, Object aLinkData) {
- try {
- final JBPopup helpPopup = RegExHelpPopup.createRegExHelpPopup();
- helpPopup.showInCenterOf(mainForm);
- }
- catch (BadLocationException e) {
- LOG.info(e);
- }
- }
- });
-
+ myRegExHelpLabel = RegExHelpPopup.createRegExLink(SSRBundle.message("regular.expression.help.label"), regexp, LOG);
myRegExHelpLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
}
@@ -559,7 +544,7 @@ class EditVarConstraintsDialog extends DialogWrapper {
inverted = _inverted;
}
- public void stateChanged(ChangeEvent e) {
+ public void stateChanged(@NotNull ChangeEvent e) {
final JCheckBox jCheckBox = (JCheckBox)e.getSource();
component.setEnabled(inverted ^ jCheckBox.isSelected());
}
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SubstitutionShortInfoHandler.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SubstitutionShortInfoHandler.java
index 32f1302336f3..ecdccbe0e40b 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SubstitutionShortInfoHandler.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SubstitutionShortInfoHandler.java
@@ -1,6 +1,6 @@
package com.intellij.structuralsearch.plugin.ui;
-import com.intellij.codeInsight.hint.TooltipGroup;
+import com.intellij.codeInsight.hint.TooltipController;
import com.intellij.codeInsight.template.impl.TemplateImplUtil;
import com.intellij.codeInsight.template.impl.Variable;
import com.intellij.openapi.editor.Document;
@@ -11,7 +11,6 @@ import com.intellij.openapi.util.Key;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
-import java.util.Iterator;
/**
* Created by IntelliJ IDEA.
@@ -21,7 +20,6 @@ import java.util.Iterator;
* To change this template use File | Settings | File Templates.
*/
public class SubstitutionShortInfoHandler implements DocumentListener, EditorMouseMotionListener, CaretListener {
- private static final TooltipGroup SS_INFO_TOOLTIP_GROUP = new TooltipGroup("SS_INFO_TOOLTIP_GROUP", 0);
private long modificationTimeStamp;
private final ArrayList<Variable> variables = new ArrayList<Variable>();
@@ -63,9 +61,7 @@ public class SubstitutionShortInfoHandler implements DocumentListener, EditorMou
String varname = elements.subSequence(start + 1, end).toString();
Variable foundVar = null;
- for(Iterator<Variable> i=variables.iterator();i.hasNext();) {
- final Variable var = i.next();
-
+ for (final Variable var : variables) {
if (var.getName().equals(varname)) {
foundVar = var;
break;
@@ -79,7 +75,10 @@ public class SubstitutionShortInfoHandler implements DocumentListener, EditorMou
}
if (text.length() > 0) {
- UIUtil.showTooltip(editor, start, end, text, SS_INFO_TOOLTIP_GROUP);
+ UIUtil.showTooltip(editor, start, end + 1, text);
+ }
+ else {
+ TooltipController.getInstance().cancelTooltips();
}
}
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java
index aa3ca82725b0..e2c16bfbc355 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java
@@ -15,17 +15,14 @@ import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorEx;
-import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.*;
import com.intellij.structuralsearch.*;
import com.intellij.structuralsearch.plugin.StructuralReplaceAction;
import com.intellij.structuralsearch.plugin.StructuralSearchAction;
import com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration;
-import com.intellij.structuralsearch.plugin.util.SmartPsiPointer;
+import com.intellij.ui.HintHint;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,6 +38,7 @@ import java.awt.*;
public class UIUtil {
static Key<SubstitutionShortInfoHandler> LISTENER_KEY = Key.create("sslistener.key");
private static final String MODIFY_EDITOR_CONTENT = SSRBundle.message("modify.editor.content.command.name");
+ private static final TooltipGroup SS_INFO_TOOLTIP_GROUP = new TooltipGroup("SS_INFO_TOOLTIP_GROUP", 0);
@NonNls private static final String SS_GROUP = "structuralsearchgroup";
@NotNull
@@ -191,18 +189,6 @@ public class UIUtil {
buf.append(str);
}
- public static void navigate(PsiElement result) {
- FileEditorManager.getInstance(result.getProject()).openTextEditor(
- new OpenFileDescriptor(result.getProject(), result.getContainingFile().getVirtualFile(), result.getTextOffset()), true);
- }
-
- public static void navigate(MatchResult result) {
- final SmartPsiPointer ref = result.getMatchRef();
-
- FileEditorManager.getInstance(ref.getProject())
- .openTextEditor(new OpenFileDescriptor(ref.getProject(), ref.getFile(), ref.getOffset()), true);
- }
-
public static void invokeAction(Configuration config, SearchContext context) {
if (config instanceof SearchConfiguration) {
StructuralSearchAction.triggerAction(config, context);
@@ -212,22 +198,27 @@ public class UIUtil {
}
}
- static void showTooltip(@NotNull Editor editor, final int start, int end, @NotNull String text, @NotNull TooltipGroup group) {
- Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
- Point top = editor.logicalPositionToXY(editor.offsetToLogicalPosition(start));
+ static void showTooltip(@NotNull Editor editor, final int start, int end, @NotNull String text) {
+ final Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
+ final Point left = editor.logicalPositionToXY(editor.offsetToLogicalPosition(start));
final int documentLength = editor.getDocument().getTextLength();
if (end >= documentLength) end = documentLength;
- Point bottom = editor.logicalPositionToXY(editor.offsetToLogicalPosition(end));
+ final Point right = editor.logicalPositionToXY(editor.offsetToLogicalPosition(end));
- Point bestPoint = new Point(top.x, bottom.y + editor.getLineHeight());
+ final Point bestPoint = new Point(left.x + (right.x - left.x) / 2, right.y + editor.getLineHeight() / 2);
- if (!visibleArea.contains(bestPoint)) {
- int defaultOffset = editor.logicalPositionToOffset(editor.xyToLogicalPosition(new Point(0, 0)));
- bestPoint = editor.logicalPositionToXY(editor.offsetToLogicalPosition(defaultOffset));
+ if (visibleArea.x > bestPoint.x) {
+ bestPoint.x = visibleArea.x;
+ }
+ else if (visibleArea.x + visibleArea.width < bestPoint.x) {
+ bestPoint.x = visibleArea.x + visibleArea.width - 5;
}
- Point p = SwingUtilities.convertPoint(editor.getContentComponent(), bestPoint, editor.getComponent().getRootPane().getLayeredPane());
- TooltipController.getInstance().showTooltip(editor, p, text, false, group);
+ final Point p = SwingUtilities.convertPoint(editor.getContentComponent(), bestPoint,
+ editor.getComponent().getRootPane().getLayeredPane());
+ final HintHint hint = new HintHint(editor, bestPoint).setAwtTooltip(true).setHighlighterType(true)
+ .setCalloutShift(editor.getLineHeight() / 2 - 1);
+ TooltipController.getInstance().showTooltip(editor, p, text, visibleArea.width, false, SS_INFO_TOOLTIP_GROUP, hint);
}
public static void updateHighlighter(Editor editor, StructuralSearchProfile profile) {
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java
index afd2ae1b029d..a55a16d4c379 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java
@@ -1,13 +1,13 @@
package com.intellij.structuralsearch.plugin.ui;
import com.intellij.navigation.ItemPresentation;
-import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
-import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.structuralsearch.SSRBundle;
import com.intellij.structuralsearch.plugin.replace.ui.ReplaceCommand;
import com.intellij.usages.*;
@@ -81,7 +81,7 @@ public class UsageViewContext {
protected void configureActions() {}
- private class MyUsageTarget implements ConfigurableUsageTarget,ItemPresentation, TypeSafeDataProvider {
+ private class MyUsageTarget implements ConfigurableUsageTarget,ItemPresentation {
private final String myPresentableText;
MyUsageTarget(String str) {
@@ -179,12 +179,5 @@ public class UsageViewContext {
public String getLongDescriptiveName() {
return _getPresentableText();
}
-
- @Override
- public void calcData(DataKey key, DataSink sink) {
- if (key == UsageView.USAGE_SCOPE) {
- sink.put(UsageView.USAGE_SCOPE, GlobalSearchScope.allScope(mySearchContext.getProject()));
- }
- }
}
}
diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java
index de9b668be4d3..fe1b6e09d99f 100644
--- a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java
+++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java
@@ -1809,6 +1809,35 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
);
}
+ public void testUseStaticImport() {
+ final String in = "class X {{ Math.abs(-1); }}";
+ final String what = "Math.abs('a)";
+ final String by = "Math.abs($a$)";
+ options.setToUseStaticImport(true);
+
+ final String expected = "import static java.lang.Math.abs;class X {{ abs(-1); }}";
+ assertEquals("Replacing with static import", expected, replacer.testReplace(in, what, by, options, true));
+ }
+
+ public void testUseStaticStarImport() {
+ final String in = "class ImportTest {{\n" +
+ " Math.abs(-0.5);\n" +
+ " Math.sin(0.5);\n" +
+ " Math.max(1, 2);\n" +
+ "}}";
+ final String what = "Math.'m('a*)";
+ final String by = "Math.$m$($a$)";
+ options.setToUseStaticImport(true);
+
+ // depends on default setting being equal to 3 for names count to use import on demand
+ final String expected = "import static java.lang.Math.*;class ImportTest {{\n" +
+ " abs(-0.5);\n" +
+ " sin(0.5);\n" +
+ " max(1,2);\n" +
+ "}}";
+ assertEquals("Replacing with static star import", expected, replacer.testReplace(in, what, by, options, true));
+ }
+
public void testReformatAndShortenClassRefPerformance() throws IOException {
final String testName = getTestName(false);
final String ext = "java";
diff --git a/platform/testFramework/src/com/intellij/FileSetTestCase.java b/platform/testFramework/src/com/intellij/FileSetTestCase.java
index ba2afa2f8d86..d89e175a52c2 100644
--- a/platform/testFramework/src/com/intellij/FileSetTestCase.java
+++ b/platform/testFramework/src/com/intellij/FileSetTestCase.java
@@ -16,6 +16,7 @@ import com.intellij.util.ArrayUtil;
import junit.framework.TestSuite;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
@@ -80,6 +81,10 @@ public abstract class FileSetTestCase extends TestSuite {
}
}
+ protected String loadFile(File testFile) throws IOException {
+ return FileUtil.loadFile(testFile);
+ }
+
protected String getDelimiter() {
return "---";
}
@@ -116,7 +121,7 @@ public abstract class FileSetTestCase extends TestSuite {
@Override
protected void runTest() throws Throwable {
- String content = FileUtil.loadFile(myTestFile);
+ String content = loadFile(myTestFile);
assertNotNull(content);
List<String> input = new ArrayList<String>();
diff --git a/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java b/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java
index 3fa50dec3032..f7a84c0470d9 100644
--- a/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java
+++ b/platform/testFramework/src/com/intellij/GroupBasedTestClassFilter.java
@@ -56,7 +56,7 @@ public class GroupBasedTestClassFilter extends TestClassesFilter {
private final List<Pattern> myTestGroupPatterns;
private boolean myContainsAllExcludeDefinedGroup;
- private GroupBasedTestClassFilter(Map<String, List<String>> filters, List<String> testGroupNames) {
+ public GroupBasedTestClassFilter(Map<String, List<String>> filters, List<String> testGroupNames) {
//empty group means all patterns from each defined group should be excluded
myContainsAllExcludeDefinedGroup = containsAllExcludeDefinedGroup(testGroupNames);
@@ -120,6 +120,10 @@ public class GroupBasedTestClassFilter extends TestClassesFilter {
*/
@NotNull
public static TestClassesFilter createOn(@NotNull Reader reader, @NotNull List<String> testGroupNames) throws IOException {
+ return new GroupBasedTestClassFilter(readGroups(reader), testGroupNames);
+ }
+
+ public static Map<String, List<String>> readGroups(Reader reader) throws IOException {
Map<String, List<String>> groupNameToPatternsMap = new HashMap<String, List<String>>();
String currentGroupName = "";
@@ -137,8 +141,7 @@ public class GroupBasedTestClassFilter extends TestClassesFilter {
groupNameToPatternsMap.get(currentGroupName).add(line);
}
}
-
- return new GroupBasedTestClassFilter(groupNameToPatternsMap, testGroupNames);
+ return groupNameToPatternsMap;
}
/**
diff --git a/platform/testFramework/src/com/intellij/TestCaseLoader.java b/platform/testFramework/src/com/intellij/TestCaseLoader.java
index 5d11e48548b8..a01070363482 100644
--- a/platform/testFramework/src/com/intellij/TestCaseLoader.java
+++ b/platform/testFramework/src/com/intellij/TestCaseLoader.java
@@ -62,15 +62,24 @@ public class TestCaseLoader {
System.out.println("Using patterns: [" + patterns +"]");
}
else {
- URL excludedStream = StringUtil.isEmpty(classFilterName) ? null : getClass().getClassLoader().getResource(classFilterName);
- if (excludedStream != null) {
- TestClassesFilter filter;
+ List<URL> groupingFileUrls = Collections.emptyList();
+ if (!StringUtil.isEmpty(classFilterName)) {
try {
- List<String> testGroupNames = StringUtil.split(System.getProperty(TARGET_TEST_GROUP, "").trim(), ";");
- InputStreamReader reader = new InputStreamReader(excludedStream.openStream());
+ groupingFileUrls = Collections.list(getClass().getClassLoader().getResources(classFilterName));
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ List<String> testGroupNames = StringUtil.split(System.getProperty(TARGET_TEST_GROUP, "").trim(), ";");
+ Map<String, List<String>> groups = new LinkedHashMap<String, List<String>>();
+
+ for (URL fileUrl : groupingFileUrls) {
+ try {
+ InputStreamReader reader = new InputStreamReader(fileUrl.openStream());
try {
- filter = GroupBasedTestClassFilter.createOn(reader, testGroupNames);
- System.out.println("Using test groups: " + testGroupNames);
+ groups.putAll(GroupBasedTestClassFilter.readGroups(reader));
}
finally {
reader.close();
@@ -78,14 +87,17 @@ public class TestCaseLoader {
}
catch (IOException e) {
e.printStackTrace();
- filter = TestClassesFilter.ALL_CLASSES;
- System.out.println("Using all classes");
+ System.err.println("Failed to load test groups from " + fileUrl);
}
- myTestClassesFilter = filter;
}
- else {
- myTestClassesFilter = TestClassesFilter.ALL_CLASSES;
+
+ if (groups.isEmpty()) {
System.out.println("Using all classes");
+ myTestClassesFilter = TestClassesFilter.ALL_CLASSES;
+ }
+ else {
+ System.out.println("Using test groups: " + testGroupNames);
+ myTestClassesFilter = new GroupBasedTestClassFilter(groups, testGroupNames);
}
}
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
index 24e4074ed4ee..3c1f96113532 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
@@ -35,10 +35,10 @@ import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.editor.impl.DocumentImpl;
import com.intellij.openapi.editor.impl.EditorImpl;
+import com.intellij.openapi.editor.impl.TrailingSpacesStripper;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
-import com.intellij.openapi.fileEditor.impl.TrailingSpacesStripper;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.ThrowableComputable;
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
index 0c46f14b98e0..307fb65e5ef1 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
@@ -44,6 +44,7 @@ import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import com.intellij.util.Alarm;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.ReflectionUtil;
import com.intellij.util.ThrowableRunnable;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
@@ -62,11 +63,8 @@ import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.InvocationEvent;
-import java.io.File;
-import java.io.IOException;
-import java.io.StringWriter;
+import java.io.*;
import java.lang.ref.SoftReference;
-import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
@@ -823,9 +821,24 @@ public class PlatformTestUtil {
}
private static void patchSystemFileEncoding(String encoding) throws NoSuchFieldException, IllegalAccessException {
- Field charset = Charset.class.getDeclaredField("defaultCharset");
- charset.setAccessible(true);
- charset.set(Charset.class, null);
+ ReflectionUtil.resetField(Charset.class, Charset.class, "defaultCharset");
System.setProperty("file.encoding", encoding);
}
+
+ public static void withStdErrSuppressed(@NotNull Runnable r) {
+ PrintStream std = System.err;
+ System.setErr(new PrintStream(NULL));
+ try {
+ r.run();
+ }
+ finally {
+ System.setErr(std);
+ }
+ }
+
+ @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
+ private static final OutputStream NULL = new OutputStream() {
+ @Override
+ public void write(int b) throws IOException { }
+ };
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
index 0f746d43c6ca..3960159e5bb4 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java
@@ -220,11 +220,11 @@ public class PsiTestUtil {
return entry;
}
- public static void removeContentEntry(Module module, final ContentEntry e) {
+ public static void removeContentEntry(Module module, final VirtualFile contentRoot) {
ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
- model.removeContentEntry(e);
+ model.removeContentEntry(findContentEntryWithAssertion(model, contentRoot));
}
});
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
index fa752b4643b0..6deda3d4b70a 100644
--- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
@@ -570,8 +570,12 @@ public abstract class UsefulTestCase extends TestCase {
public static <T> T assertOneElement(Collection<T> collection) {
Assert.assertNotNull(collection);
- Assert.assertEquals(toString(collection), 1, collection.size());
- return collection.iterator().next();
+ Iterator<T> iterator = collection.iterator();
+ String toString = toString(collection);
+ Assert.assertTrue(toString, iterator.hasNext());
+ T t = iterator.next();
+ Assert.assertFalse(toString, iterator.hasNext());
+ return t;
}
public static <T> T assertOneElement(T[] ts) {
diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java
index e721401a82ba..a309f9acda8f 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java
@@ -463,7 +463,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
void type(final char c);
- void type(final String s);
+ void type(@NotNull String s);
void performEditorAction(@NotNull String actionId);
diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/HeavyIdeaTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/HeavyIdeaTestFixture.java
index 490d2c3ff05b..57e78061cc3c 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/HeavyIdeaTestFixture.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/HeavyIdeaTestFixture.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package com.intellij.testFramework.fixtures;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@@ -25,5 +26,5 @@ import java.io.IOException;
* @author peter
*/
public interface HeavyIdeaTestFixture extends IdeaProjectTestFixture {
- PsiFile addFileToProject(@NonNls String rootPath, @NonNls String relativePath, @NonNls String fileText) throws IOException;
+ PsiFile addFileToProject(@NonNls @NotNull String rootPath, @NonNls @NotNull String relativePath, @NonNls @NotNull String fileText) throws IOException;
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
index 4857acd2d328..449b1bacf8e9 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
@@ -146,7 +146,6 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
private final TempDirTestFixture myTempDirFixture;
protected final IdeaProjectTestFixture myProjectFixture;
- @NonNls private static final String XXX = "XXX";
private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
private boolean myAllowDirt;
private boolean myCaresAboutInjection = true;
@@ -369,7 +368,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
private long collectAndCheckHighlightings(final boolean checkWarnings,
final boolean checkInfos,
final boolean checkWeakWarnings,
- final VirtualFile[] files) {
+ @NotNull VirtualFile[] files) {
final List<Trinity<PsiFile, Editor, ExpectedHighlightingData>> datas =
ContainerUtil.map2List(files, new Function<VirtualFile, Trinity<PsiFile, Editor, ExpectedHighlightingData>>() {
@Override
@@ -787,12 +786,13 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
});
}
+ @NotNull
private DataContext getEditorDataContext() {
return ((EditorEx)myEditor).getDataContext();
}
@Override
- public void type(String s) {
+ public void type(@NotNull String s) {
for (int i = 0; i < s.length(); i++) {
type(s.charAt(i));
}
@@ -804,7 +804,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
_performEditorAction(actionId);
}
- private boolean _performEditorAction(String actionId) {
+ private boolean _performEditorAction(@NotNull String actionId) {
final DataContext dataContext = getEditorDataContext();
final ActionManagerEx managerEx = ActionManagerEx.getInstanceEx();
@@ -948,7 +948,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
private static void addGutterIconRenderer(final GutterMark renderer,
final int offset,
- SortedMap<Integer, List<GutterMark>> result) {
+ @NotNull SortedMap<Integer, List<GutterMark>> result) {
if (renderer == null) return;
List<GutterMark> renderers = result.get(offset);
@@ -965,7 +965,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
return addFileToProject(getTempDirPath(), relativePath, fileText);
}
- protected PsiFile addFileToProject(final String rootPath, final String relativePath, final String fileText) {
+ protected PsiFile addFileToProject(@NotNull final String rootPath, @NotNull final String relativePath, @NotNull final String fileText) {
return new WriteCommandAction<PsiFile>(getProject()) {
@Override
protected void run(@NotNull Result<PsiFile> result) throws Throwable {
@@ -1377,7 +1377,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
return PsiDocumentManager.getInstance(getProject()).getDocument(file);
}
- private PsiFile configureByFileInner(@NonNls String filePath) {
+ private PsiFile configureByFileInner(@NonNls @NotNull String filePath) {
assertInitialized();
final VirtualFile file = copyFileToProject(filePath);
return configureByFileInner(file);
@@ -1401,7 +1401,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy));
}
- private PsiFile configureInner(@NotNull final VirtualFile copy, final SelectionAndCaretMarkupLoader loader) {
+ private PsiFile configureInner(@NotNull final VirtualFile copy, @NotNull final SelectionAndCaretMarkupLoader loader) {
assertInitialized();
new WriteCommandAction.Simple(getProject()) {
@Override
@@ -1459,13 +1459,17 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
}
@Nullable
- private Editor createEditor(VirtualFile file) {
+ private Editor createEditor(@NotNull VirtualFile file) {
final Project project = getProject();
final FileEditorManager instance = FileEditorManager.getInstance(project);
if (file.getFileType().isBinary()) {
return null;
}
- return instance.openTextEditor(new OpenFileDescriptor(project, file, 0), false);
+ Editor editor = instance.openTextEditor(new OpenFileDescriptor(project, file), false);
+ if (editor != null) {
+ editor.getCaretModel().moveToOffset(0);
+ }
+ return editor;
}
private long collectAndCheckHighlighting(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings) throws Exception {
@@ -1487,14 +1491,14 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
//to initialize caches
if (!DumbService.isDumb(project)) {
- CacheManager.SERVICE.getInstance(project).getFilesWithWord(XXX, UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(project), true);
+ CacheManager.SERVICE.getInstance(project).getFilesWithWord("XXX", UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(project), true);
}
- List<HighlightInfo> infos;
final long start = System.currentTimeMillis();
((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(myJavaFilesFilter, myTestRootDisposable);
// ProfilingUtil.startCPUProfiling();
+ List<HighlightInfo> infos;
try {
infos = doHighlighting();
removeDuplicatedRangesForInjected(infos);
@@ -1510,7 +1514,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
return elapsed;
}
- private static void removeDuplicatedRangesForInjected(List<HighlightInfo> infos) {
+ private static void removeDuplicatedRangesForInjected(@NotNull List<HighlightInfo> infos) {
Collections.sort(infos, new Comparator<HighlightInfo>() {
@Override
public int compare(HighlightInfo o1, HighlightInfo o2) {
@@ -1582,7 +1586,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
throw exception;
}
- public static void ensureIndexesUpToDate(Project project) {
+ public static void ensureIndexesUpToDate(@NotNull Project project) {
if (!DumbService.isDumb(project)) {
FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, null);
FileBasedIndex.getInstance().ensureUpToDate(TodoIndex.NAME, project, null);
@@ -1625,6 +1629,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
});
}
+ @NotNull
public static List<IntentionAction> getAvailableIntentions(@NotNull final Editor editor, @NotNull final PsiFile file) {
return ApplicationManager.getApplication().runReadAction(new Computable<List<IntentionAction>>() {
@Override
@@ -1634,6 +1639,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
});
}
+ @NotNull
private static List<IntentionAction> doGetAvailableIntentions(@NotNull Editor editor, @NotNull PsiFile file) {
ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
ShowIntentionsPass.getActionsToShow(editor, file, intentions, -1);
@@ -1681,15 +1687,17 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
myJavaFilesFilter.allowTreeAccessForAllFiles();
}
- static class SelectionAndCaretMarkupLoader {
+ private static class SelectionAndCaretMarkupLoader {
final String filePath;
final String newFileText;
final EditorTestUtil.CaretAndSelectionState caretState;
- static SelectionAndCaretMarkupLoader fromFile(String path, String charset) throws IOException {
+ @NotNull
+ static SelectionAndCaretMarkupLoader fromFile(@NotNull String path, String charset) throws IOException {
return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(FileUtil.loadFile(new File(path), charset)), path);
}
+ @NotNull
static SelectionAndCaretMarkupLoader fromFile(@NotNull VirtualFile file) {
final String text;
try {
@@ -1701,11 +1709,12 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(text), file.getPath());
}
- static SelectionAndCaretMarkupLoader fromText(String text) {
+ @NotNull
+ static SelectionAndCaretMarkupLoader fromText(@NotNull String text) {
return new SelectionAndCaretMarkupLoader(text, null);
}
- private SelectionAndCaretMarkupLoader(String fileText, String filePath) {
+ private SelectionAndCaretMarkupLoader(@NotNull String fileText, String filePath) {
this.filePath = filePath;
final Document document = EditorFactory.getInstance().createDocument(fileText);
caretState = EditorTestUtil.extractCaretAndSelectionMarkers(document);
@@ -1735,11 +1744,10 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
}
- @SuppressWarnings("ConstantConditions")
private void checkResult(@NotNull String expectedFile,
final boolean stripTrailingSpaces,
- final SelectionAndCaretMarkupLoader loader,
- String actualText) {
+ @NotNull SelectionAndCaretMarkupLoader loader,
+ @NotNull String actualText) {
assertInitialized();
Project project = getProject();
Editor editor = getEditor();
@@ -1773,7 +1781,8 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
EditorTestUtil.verifyCaretAndSelectionState(editor, loader.caretState, expectedFile);
}
- private String stripTrailingSpaces(String actualText) {
+ @NotNull
+ private String stripTrailingSpaces(@NotNull String actualText) {
final Document document = EditorFactory.getInstance().createDocument(actualText);
((DocumentImpl)document).stripTrailingSpaces(getProject());
actualText = document.getText();
@@ -1824,6 +1833,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
}
}
+ @NotNull
public String getFoldingDescription(boolean withCollapseStatus) {
CodeFoldingManager.getInstance(getProject()).buildInitialFoldings(myEditor);
@@ -1849,7 +1859,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
return result.toString();
}
- private void testFoldingRegions(final String verificationFileName, boolean doCheckCollapseStatus) {
+ private void testFoldingRegions(@NotNull String verificationFileName, boolean doCheckCollapseStatus) {
String expectedContent;
try {
expectedContent = FileUtil.loadFile(new File(verificationFileName));
diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java
index 4adc2aa57cef..27a45cbfe99e 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/HeavyIdeaTestFixtureImpl.java
@@ -235,7 +235,7 @@ class HeavyIdeaTestFixtureImpl extends BaseFixture implements HeavyIdeaTestFixtu
}
@Override
- public PsiFile addFileToProject(@NonNls String rootPath, @NonNls final String relativePath, @NonNls final String fileText) throws IOException {
+ public PsiFile addFileToProject(@NotNull @NonNls String rootPath, @NotNull @NonNls final String relativePath, @NotNull @NonNls final String fileText) throws IOException {
final VirtualFile dir = VfsUtil.createDirectories(rootPath + "/" + PathUtil.getParentPath(relativePath));
final VirtualFile[] virtualFile = new VirtualFile[1];
diff --git a/platform/testFramework/src/com/intellij/util/io/TestFileSystemBuilder.java b/platform/testFramework/src/com/intellij/util/io/TestFileSystemBuilder.java
index da7dc5cfa162..9ee314d52b8d 100644
--- a/platform/testFramework/src/com/intellij/util/io/TestFileSystemBuilder.java
+++ b/platform/testFramework/src/com/intellij/util/io/TestFileSystemBuilder.java
@@ -1,5 +1,7 @@
package com.intellij.util.io;
+import org.jetbrains.annotations.NotNull;
+
/**
* @author nik
*/
@@ -12,6 +14,7 @@ public class TestFileSystemBuilder {
myParent = parent;
}
+ @NotNull
public TestFileSystemItem build() {
TestFileSystemBuilder builder = this;
while (builder.myParent != null) {
@@ -20,23 +23,27 @@ public class TestFileSystemBuilder {
return builder.myItem;
}
+ @NotNull
public TestFileSystemBuilder dir(String name) {
final TestFileSystemItem item = new TestFileSystemItem(name, false, true);
myItem.addChild(item);
return new TestFileSystemBuilder(item, this);
}
+ @NotNull
public TestFileSystemBuilder archive(String name) {
final TestFileSystemItem item = new TestFileSystemItem(name, true, false);
myItem.addChild(item);
return new TestFileSystemBuilder(item, this);
}
+ @NotNull
public TestFileSystemBuilder file(String name) {
myItem.addChild(new TestFileSystemItem(name, false, false));
return this;
}
+ @NotNull
public TestFileSystemBuilder file(String name, String content) {
myItem.addChild(new TestFileSystemItem(name, false, false, content));
return this;
@@ -46,6 +53,7 @@ public class TestFileSystemBuilder {
return myParent;
}
+ @NotNull
public static TestFileSystemBuilder fs() {
return new TestFileSystemBuilder(new TestFileSystemItem("root", false, true), null);
}
diff --git a/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java b/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java
index 86958eee3461..4375701bc62c 100644
--- a/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java
+++ b/platform/testFramework/testSrc/com/intellij/openapi/keymap/KeymapsTestCase.java
@@ -82,6 +82,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "alt DOWN", "ShowContent", "MethodDown"},
{ "alt F1", "SelectIn", "ProjectViewChangeView"},
{ "alt INSERT", "FileChooser.NewFolder", "Generate", "NewElement"},
+ { "control F10", "javaee.UpdateRunningApplication", "liveedit.UpdateRunningApplication"},
{ "control 1", "FileChooser.GotoHome", "GotoBookmark1", "DuplicatesForm.SendToLeft"},
{ "control 2", "FileChooser.GotoProject", "GotoBookmark2", "DuplicatesForm.SendToRight"},
{ "control 3", "GotoBookmark3", "FileChooser.GotoModule"},
@@ -238,7 +239,7 @@ public abstract class KeymapsTestCase extends PlatformTestCase {
{ "TAB", "EditorChooseLookupItemReplace", "NextTemplateVariable", "NextParameter", "EditorIndentSelection", "EditorTab", "NextTemplateParameter"},
{ "alt DOWN", "ShowContent", "MoveStatementDown"},
{ "alt HOME", "ViewNavigationBar", "ShowNavBar"},
- { "control F10", "ShowPopupMenu", "javaee.UpdateRunningApplication"},
+ { "control F10", "ShowPopupMenu", "javaee.UpdateRunningApplication", "liveedit.UpdateRunningApplication"},
{ "control F11", "Rerun", "ToggleBookmarkWithMnemonic"},
{ "control D", "CompareDirs", "EditorDeleteLine", "CompareTwoFiles", "SendEOF", "FileChooser.GotoDesktop"},
{ "control N", "ShowPopupMenu", "FileChooser.NewFolder"},
diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java b/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java
index b3557238124f..263c25b184b8 100644
--- a/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java
+++ b/platform/testFramework/testSrc/com/intellij/testFramework/vcs/MockChangeListManager.java
@@ -271,6 +271,11 @@ public class MockChangeListManager extends ChangeListManagerEx {
}
@Override
+ public void addDirectoryToIgnoreImplicitly(@NotNull String path) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public void setFilesToIgnore(IgnoredFileBean... ignoredFiles) {
throw new UnsupportedOperationException();
}
diff --git a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java
index 930321fc61d5..dbbaeb48b72f 100644
--- a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java
+++ b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java
@@ -19,9 +19,7 @@ import com.intellij.injected.editor.DocumentWindow;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.HighlighterColors;
-import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
@@ -39,11 +37,14 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.reference.SoftReference;
import com.intellij.usageView.UsageTreeColors;
import com.intellij.usageView.UsageTreeColorsScheme;
+import com.intellij.usages.impl.SyntaxHighlighterOverEditorHighlighter;
+import com.intellij.usages.impl.rules.UsageType;
import com.intellij.util.Processor;
import com.intellij.util.containers.FactoryMap;
import com.intellij.util.text.CharArrayUtil;
import com.intellij.util.text.StringFactory;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.lang.ref.WeakReference;
@@ -64,9 +65,7 @@ public class ChunkExtractor {
private final Document myDocument;
private long myDocumentStamp;
- private final SyntaxHighlighter myHighlighter;
-
- private final Lexer myLexer;
+ private final SyntaxHighlighterOverEditorHighlighter myHighlighter;
private abstract static class WeakFactory<T> {
private WeakReference<T> myRef;
@@ -119,11 +118,10 @@ public class ChunkExtractor {
myDocument = PsiDocumentManager.getInstance(project).getDocument(file);
LOG.assertTrue(myDocument != null);
final FileType fileType = file.getFileType();
- final SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, file.getVirtualFile());
- myHighlighter = highlighter == null ? new PlainSyntaxHighlighter() : highlighter;
- myLexer = myHighlighter.getHighlightingLexer();
- myLexer.start(myDocument.getCharsSequence());
- myDocumentStamp = myDocument.getModificationStamp();
+ SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, file.getVirtualFile());
+ highlighter = highlighter == null ? new PlainSyntaxHighlighter() : highlighter;
+ myHighlighter = new SyntaxHighlighterOverEditorHighlighter(highlighter, file.getVirtualFile(), project);
+ myDocumentStamp = -1;
}
public static int getStartOffset(final List<RangeMarker> rangeMarkers) {
@@ -194,18 +192,21 @@ public class ChunkExtractor {
int end,
boolean selectUsageWithBold,
@NotNull List<TextChunk> result) {
- final Lexer lexer = myLexer;
- final SyntaxHighlighter highlighter = myHighlighter;
+ final Lexer lexer = myHighlighter.getHighlightingLexer();
+ final SyntaxHighlighterOverEditorHighlighter highlighter = myHighlighter;
LOG.assertTrue(start <= end);
int i = StringUtil.indexOf(chars, '\n', start, end);
if (i != -1) end = i;
- if (lexer.getTokenStart() > start || myDocumentStamp != myDocument.getModificationStamp()) {
- lexer.start(chars);
+ if (myDocumentStamp != myDocument.getModificationStamp()) {
+ highlighter.restart(chars);
myDocumentStamp = myDocument.getModificationStamp();
+ } else if(lexer.getTokenStart() > start) {
+ highlighter.resetPosition(0); // todo restart from nearest position with initial state
}
+
boolean isBeginning = true;
for(;lexer.getTokenType() != null; lexer.advance()) {
@@ -218,8 +219,10 @@ public class ChunkExtractor {
hiEnd = Math.min(hiEnd, end);
if (hiStart >= hiEnd) { continue; }
- String text = chars.subSequence(hiStart, hiEnd).toString();
- if (isBeginning && text.trim().isEmpty()) continue;
+ if (isBeginning) {
+ String text = chars.subSequence(hiStart, hiEnd).toString();
+ if(text.trim().isEmpty()) continue;
+ }
isBeginning = false;
IElementType tokenType = lexer.getTokenType();
TextAttributesKey[] tokenHighlights = highlighter.getTokenHighlights(tokenType);
@@ -234,7 +237,7 @@ public class ChunkExtractor {
@NotNull final CharSequence chars,
int hiStart,
final int hiEnd,
- @NotNull TextAttributesKey[] tokenHighlights,
+ @NotNull final TextAttributesKey[] tokenHighlights,
final boolean selectUsageWithBold,
@NotNull final List<TextChunk> result) {
final TextAttributes originalAttrs = convertAttributes(tokenHighlights);
@@ -249,8 +252,12 @@ public class ChunkExtractor {
int usageStart = segment.getStartOffset();
int usageEnd = segment.getEndOffset();
if (rangeIntersect(lastOffset[0], hiEnd, usageStart, usageEnd)) {
- addChunk(chars, lastOffset[0], Math.max(lastOffset[0], usageStart), originalAttrs, false, result);
- addChunk(chars, Math.max(lastOffset[0], usageStart), Math.min(hiEnd, usageEnd), originalAttrs, selectUsageWithBold, result);
+ addChunk(chars, lastOffset[0], Math.max(lastOffset[0], usageStart), originalAttrs, false, null, result);
+
+ UsageType usageType = isHighlightedAsString(tokenHighlights)
+ ? UsageType.LITERAL_USAGE
+ : isHighlightedAsComment(tokenHighlights) ? UsageType.COMMENT_USAGE : null;
+ addChunk(chars, Math.max(lastOffset[0], usageStart), Math.min(hiEnd, usageEnd), originalAttrs, selectUsageWithBold, usageType, result);
lastOffset[0] = usageEnd;
if (usageEnd > hiEnd) {
return false;
@@ -260,8 +267,40 @@ public class ChunkExtractor {
}
});
if (lastOffset[0] < hiEnd) {
- addChunk(chars, lastOffset[0], hiEnd, originalAttrs, false, result);
+ addChunk(chars, lastOffset[0], hiEnd, originalAttrs, false, null, result);
+ }
+ }
+
+ public static boolean isHighlightedAsComment(TextAttributesKey... keys) {
+ for (TextAttributesKey key : keys) {
+ if (key == DefaultLanguageHighlighterColors.DOC_COMMENT ||
+ key == SyntaxHighlighterColors.DOC_COMMENT ||
+ key == DefaultLanguageHighlighterColors.LINE_COMMENT ||
+ key == SyntaxHighlighterColors.LINE_COMMENT ||
+ key == DefaultLanguageHighlighterColors.BLOCK_COMMENT ||
+ key == SyntaxHighlighterColors.JAVA_BLOCK_COMMENT
+ ) {
+ return true;
+ }
+ final TextAttributesKey fallbackAttributeKey = key.getFallbackAttributeKey();
+ if (fallbackAttributeKey != null && isHighlightedAsComment(fallbackAttributeKey)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isHighlightedAsString(TextAttributesKey... keys) {
+ for (TextAttributesKey key : keys) {
+ if (key == DefaultLanguageHighlighterColors.STRING || key == SyntaxHighlighterColors.STRING) {
+ return true;
+ }
+ final TextAttributesKey fallbackAttributeKey = key.getFallbackAttributeKey();
+ if (fallbackAttributeKey != null && isHighlightedAsString(fallbackAttributeKey)) {
+ return true;
+ }
}
+ return false;
}
private static void addChunk(@NotNull CharSequence chars,
@@ -269,13 +308,14 @@ public class ChunkExtractor {
int end,
@NotNull TextAttributes originalAttrs,
boolean bold,
+ @Nullable UsageType usageType,
@NotNull List<TextChunk> result) {
if (start >= end) return;
TextAttributes attrs = bold
? TextAttributes.merge(originalAttrs, new TextAttributes(null, null, null, null, Font.BOLD))
: originalAttrs;
- result.add(new TextChunk(attrs, StringFactory.createShared(CharArrayUtil.fromSequence(chars, start, end))));
+ result.add(new TextChunk(attrs, StringFactory.createShared(CharArrayUtil.fromSequence(chars, start, end)), usageType));
}
private static boolean rangeIntersect(int s1, int e1, int s2, int e2) {
diff --git a/platform/usageView/src/com/intellij/usages/FindUsagesProcessPresentation.java b/platform/usageView/src/com/intellij/usages/FindUsagesProcessPresentation.java
index d608303eec09..2248182a3c5c 100644
--- a/platform/usageView/src/com/intellij/usages/FindUsagesProcessPresentation.java
+++ b/platform/usageView/src/com/intellij/usages/FindUsagesProcessPresentation.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Factory;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
@@ -41,6 +42,7 @@ public class FindUsagesProcessPresentation {
private Factory<ProgressIndicator> myProgressIndicatorFactory;
private Collection<PsiFile> myLargeFiles;
private boolean myShowFindOptionsPrompt = true;
+ private Runnable mySearchWithProjectFiles;
public FindUsagesProcessPresentation(@NotNull UsageViewPresentation presentation) {
myUsageViewPresentation = presentation;
@@ -80,6 +82,15 @@ public class FindUsagesProcessPresentation {
myProgressIndicatorFactory = progressIndicatorFactory;
}
+ @Nullable
+ public Runnable searchIncludingProjectFileUsages() {
+ return mySearchWithProjectFiles;
+ }
+
+ public void projectFileUsagesFound(@NotNull Runnable searchWithProjectFiles) {
+ mySearchWithProjectFiles = searchWithProjectFiles;
+ }
+
public void setLargeFilesWereNotScanned(@NotNull Collection<PsiFile> largeFiles) {
myLargeFiles = largeFiles;
}
diff --git a/platform/usageView/src/com/intellij/usages/TextChunk.java b/platform/usageView/src/com/intellij/usages/TextChunk.java
index e1c3345d41da..e74debdb97fb 100644
--- a/platform/usageView/src/com/intellij/usages/TextChunk.java
+++ b/platform/usageView/src/com/intellij/usages/TextChunk.java
@@ -18,17 +18,25 @@ package com.intellij.usages;
import com.intellij.openapi.editor.markup.AttributesFlyweight;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.usages.impl.rules.UsageType;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
public class TextChunk {
public static final TextChunk[] EMPTY_ARRAY = new TextChunk[0];
private final AttributesFlyweight myAttributes;
private final String myText;
+ private final UsageType myType;
public TextChunk(@NotNull TextAttributes attributes, @NotNull String text) {
+ this(attributes, text, null);
+ }
+
+ public TextChunk(@NotNull TextAttributes attributes, @NotNull String text, @Nullable UsageType type) {
myAttributes = attributes.getFlyweight();
myText = text;
+ myType = type;
}
@NotNull
@@ -45,6 +53,10 @@ public class TextChunk {
return getText();
}
+ public @Nullable UsageType getType() {
+ return myType;
+ }
+
@NotNull
public SimpleTextAttributes getSimpleAttributesIgnoreBackground() {
SimpleTextAttributes simples = SimpleTextAttributes.fromTextAttributes(getAttributes());
diff --git a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java
index aaccbfffbe18..418890ce17d9 100644
--- a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java
+++ b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java
@@ -38,11 +38,9 @@ import com.intellij.reference.SoftReference;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewBundle;
+import com.intellij.usages.impl.rules.UsageType;
import com.intellij.usages.rules.*;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.NotNullFunction;
-import com.intellij.util.Processor;
+import com.intellij.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -79,7 +77,8 @@ public class UsageInfo2UsageAdapter implements UsageInModule,
private final int myLineNumber;
private final int myOffset;
protected Icon myIcon;
- private Reference<TextChunk[]> myTextChunks; // allow to be gced and recreated on-demand because it requires a lot of memory
+ private volatile Reference<TextChunk[]> myTextChunks; // allow to be gced and recreated on-demand because it requires a lot of memory
+ private volatile UsageType myUsageType;
public UsageInfo2UsageAdapter(@NotNull final UsageInfo usageInfo) {
myUsageInfo = usageInfo;
@@ -336,7 +335,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule,
UsageInfo[] merged = ArrayUtil.mergeArrays(getMergedInfos(), u2.getMergedInfos());
myMergedUsageInfos = merged.length == 1 ? merged[0] : merged;
Arrays.sort(getMergedInfos(), BY_NAVIGATION_OFFSET);
- initChunks();
+ myTextChunks = null; // chunks will be rebuilt lazily (IDEA-126048)
return true;
}
@@ -493,4 +492,44 @@ public class UsageInfo2UsageAdapter implements UsageInModule,
public String getTooltipText() {
return myUsageInfo.getTooltipText();
}
+
+ public @Nullable UsageType getUsageType() {
+ UsageType usageType = myUsageType;
+
+ if (usageType == null) {
+ usageType = UsageType.UNCLASSIFIED;
+ PsiFile file = getPsiFile();
+
+ if (file != null) {
+ ChunkExtractor extractor = ChunkExtractor.getExtractor(file);
+ Segment segment = getFirstSegment();
+
+ if (segment != null) {
+ Document document = PsiDocumentManager.getInstance(getProject()).getDocument(file);
+
+ if (document != null) {
+ SmartList<TextChunk> chunks = new SmartList<TextChunk>();
+ extractor.createTextChunks(
+ this,
+ document.getCharsSequence(),
+ segment.getStartOffset(),
+ segment.getEndOffset(),
+ false,
+ chunks
+ );
+
+ for(TextChunk chunk:chunks) {
+ UsageType chunkUsageType = chunk.getType();
+ if (chunkUsageType != null) {
+ usageType = chunkUsageType;
+ break;
+ }
+ }
+ }
+ }
+ }
+ myUsageType = usageType;
+ }
+ return usageType;
+ }
}
diff --git a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
index 8b065b30d167..170d1802eee4 100644
--- a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
+++ b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
@@ -19,6 +19,7 @@ import com.intellij.find.FindManager;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.CodeInsightColors;
@@ -71,6 +72,7 @@ class SearchForUsagesRunnable implements Runnable {
@NonNls private static final String FIND_OPTIONS_HREF_TARGET = "FindOptions";
@NonNls private static final String SEARCH_IN_PROJECT_HREF_TARGET = "SearchInProject";
@NonNls private static final String LARGE_FILES_HREF_TARGET = "LargeFiles";
+ @NonNls private static final String SHOW_PROJECT_FILE_OCCURRENCES_HREF_TARGET = "SHOW_PROJECT_FILE_OCCURRENCES";
private final AtomicInteger myUsageCountWithoutDefinition = new AtomicInteger(0);
private final AtomicReference<Usage> myFirstUsage = new AtomicReference<Usage>();
@NotNull
@@ -80,7 +82,7 @@ class SearchForUsagesRunnable implements Runnable {
private final UsageTarget[] mySearchFor;
private final Factory<UsageSearcher> mySearcherFactory;
private final FindUsagesProcessPresentation myProcessPresentation;
- @NotNull private final SearchScope mySearchScope;
+ @NotNull private final SearchScope mySearchScopeToWarnOfFallingOutOf;
private final UsageViewManager.UsageViewStateListener myListener;
private final UsageViewManagerImpl myUsageViewManager;
private final AtomicInteger myOutOfScopeUsages = new AtomicInteger();
@@ -92,7 +94,7 @@ class SearchForUsagesRunnable implements Runnable {
@NotNull UsageTarget[] searchFor,
@NotNull Factory<UsageSearcher> searcherFactory,
@NotNull FindUsagesProcessPresentation processPresentation,
- @NotNull SearchScope scope,
+ @NotNull SearchScope searchScopeToWarnOfFallingOutOf,
@Nullable UsageViewManager.UsageViewStateListener listener) {
myProject = project;
myUsageViewRef = usageViewRef;
@@ -100,7 +102,7 @@ class SearchForUsagesRunnable implements Runnable {
mySearchFor = searchFor;
mySearcherFactory = searcherFactory;
myProcessPresentation = processPresentation;
- mySearchScope = scope;
+ mySearchScopeToWarnOfFallingOutOf = searchScopeToWarnOfFallingOutOf;
myListener = listener;
myUsageViewManager = usageViewManager;
}
@@ -135,25 +137,43 @@ class SearchForUsagesRunnable implements Runnable {
+ UsageViewBundle.message("large.files.were.ignored", largeFiles.size()) + "</a>)";
resultLines.add(shortMessage);
- resultListener = new HyperlinkAdapter(){
- @Override
- protected void hyperlinkActivated(HyperlinkEvent e) {
- if (e.getDescription().equals(LARGE_FILES_HREF_TARGET)) {
- String detailedMessage = detailedLargeFilesMessage(largeFiles);
- List<String> strings = new ArrayList<String>(lines);
- strings.add(detailedMessage);
- ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(strings), AllIcons.Actions.Find, listener);
- }
- else if (listener != null) {
- listener.hyperlinkUpdate(e);
- }
+ resultListener = addHrefHandling(resultListener, LARGE_FILES_HREF_TARGET, new Runnable() {
+ public void run() {
+ String detailedMessage = detailedLargeFilesMessage(largeFiles);
+ List<String> strings = new ArrayList<String>(lines);
+ strings.add(detailedMessage);
+ //noinspection SSBasedInspection
+ ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(strings), AllIcons.Actions.Find, listener);
}
- };
+ });
}
+ Runnable searchIncludingProjectFileUsages = processPresentation.searchIncludingProjectFileUsages();
+ if (searchIncludingProjectFileUsages != null) {
+ resultLines.add("Occurrences in " + ApplicationNamesInfo.getInstance().getProductName() + " project files are skipped. " +
+ "<a href='" + SHOW_PROJECT_FILE_OCCURRENCES_HREF_TARGET + "'>Include them</a>");
+ resultListener = addHrefHandling(resultListener, SHOW_PROJECT_FILE_OCCURRENCES_HREF_TARGET, searchIncludingProjectFileUsages);
+ }
+
+ //noinspection SSBasedInspection
ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.FIND, info, wrapInHtml(resultLines), AllIcons.Actions.Find, resultListener);
}
+ private static HyperlinkListener addHrefHandling(@Nullable final HyperlinkListener listener,
+ @NotNull final String hrefTarget, @NotNull final Runnable handler) {
+ return new HyperlinkAdapter() {
+ @Override
+ protected void hyperlinkActivated(HyperlinkEvent e) {
+ if (e.getDescription().equals(hrefTarget)) {
+ handler.run();
+ }
+ else if (listener != null) {
+ listener.hyperlinkUpdate(e);
+ }
+ }
+ };
+ }
+
@NotNull
private static String wrapInHtml(@NotNull List<String> strings) {
return XmlStringUtil.wrapInHtml(StringUtil.join(strings, "<br>"));
@@ -319,7 +339,7 @@ class SearchForUsagesRunnable implements Runnable {
ProgressIndicator indicator = ProgressWrapper.unwrap(ProgressManager.getInstance().getProgressIndicator());
if (indicator != null && indicator.isCanceled()) return false;
- if (!UsageViewManagerImpl.isInScope(usage, mySearchScope)) {
+ if (!UsageViewManagerImpl.isInScope(usage, mySearchScopeToWarnOfFallingOutOf)) {
myOutOfScopeUsages.incrementAndGet();
return true;
}
@@ -389,7 +409,7 @@ class SearchForUsagesRunnable implements Runnable {
List<String> lines = new ArrayList<String>();
lines.add(StringUtil.escapeXml(message));
if (myOutOfScopeUsages.get() != 0) {
- lines.add(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope));
+ lines.add(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScopeToWarnOfFallingOutOf));
}
if (myProcessPresentation.isShowFindOptionsPrompt()) {
lines.add(createOptionsHtml(mySearchFor));
@@ -432,7 +452,7 @@ class SearchForUsagesRunnable implements Runnable {
lines.add("Only one usage found.");
if (myOutOfScopeUsages.get() != 0) {
- lines.add(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope));
+ lines.add(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScopeToWarnOfFallingOutOf));
}
lines.add(createOptionsHtml(mySearchFor));
MessageType type = myOutOfScopeUsages.get() == 0 ? MessageType.INFO : MessageType.WARNING;
@@ -456,11 +476,13 @@ class SearchForUsagesRunnable implements Runnable {
hyperlinkListener = null;
}
else {
- lines = Arrays.asList(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScope), createSearchInProjectHtml());
+ lines = Arrays.asList(UsageViewManagerImpl.outOfScopeMessage(myOutOfScopeUsages.get(), mySearchScopeToWarnOfFallingOutOf), createSearchInProjectHtml());
hyperlinkListener = createSearchInProjectListener();
}
- if (!myProcessPresentation.getLargeFiles().isEmpty() || myOutOfScopeUsages.get() != 0) {
+ if (!myProcessPresentation.getLargeFiles().isEmpty() ||
+ myOutOfScopeUsages.get() != 0 ||
+ myProcessPresentation.searchIncludingProjectFileUsages() != null) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
diff --git a/platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java b/platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java
new file mode 100644
index 000000000000..04690cc6fa20
--- /dev/null
+++ b/platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.usages.impl;
+
+import com.intellij.lexer.LayeredLexer;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.editor.ex.util.LayeredHighlighterIterator;
+import com.intellij.openapi.editor.ex.util.LayeredLexerEditorHighlighter;
+import com.intellij.openapi.editor.highlighter.EditorHighlighter;
+import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
+import com.intellij.openapi.editor.highlighter.HighlighterIterator;
+import com.intellij.openapi.fileTypes.PlainSyntaxHighlighter;
+import com.intellij.openapi.fileTypes.PlainTextFileType;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.impl.search.LexerEditorHighlighterLexer;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+
+/**
+* Created by Maxim.Mossienko on 7/31/2014.
+*/
+public class SyntaxHighlighterOverEditorHighlighter implements SyntaxHighlighter {
+ private final Lexer lexer;
+ private LayeredHighlighterIterator layeredHighlighterIterator = null;
+ private final SyntaxHighlighter highlighter;
+
+ public SyntaxHighlighterOverEditorHighlighter(SyntaxHighlighter _highlighter, VirtualFile file, Project project) {
+ if (file.getFileType() == PlainTextFileType.INSTANCE) { // optimization for large files, PlainTextSyntaxHighlighterFactory is slow
+ highlighter = new PlainSyntaxHighlighter();
+ lexer = highlighter.getHighlightingLexer();
+ } else {
+ highlighter = _highlighter;
+ LayeredLexer.ourDisableLayersFlag.set(Boolean.TRUE);
+ EditorHighlighter editorHighlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(project, file);
+
+ try {
+ if (editorHighlighter instanceof LayeredLexerEditorHighlighter) {
+ lexer = new LexerEditorHighlighterLexer(editorHighlighter, false);
+ }
+ else {
+ lexer = highlighter.getHighlightingLexer();
+ }
+ }
+ finally {
+ LayeredLexer.ourDisableLayersFlag.set(null);
+ }
+ }
+ }
+
+ @NotNull
+ @Override
+ public Lexer getHighlightingLexer() {
+ return lexer;
+ }
+
+ @NotNull
+ @Override
+ public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
+ final SyntaxHighlighter activeSyntaxHighlighter =
+ layeredHighlighterIterator != null ? layeredHighlighterIterator.getActiveSyntaxHighlighter() : highlighter;
+ return activeSyntaxHighlighter.getTokenHighlights(tokenType);
+ }
+
+ public void restart(@NotNull CharSequence text) {
+ lexer.start(text);
+
+ if (lexer instanceof LexerEditorHighlighterLexer) {
+ HighlighterIterator iterator = ((LexerEditorHighlighterLexer)lexer).getHighlighterIterator();
+ if (iterator instanceof LayeredHighlighterIterator) {
+ layeredHighlighterIterator = (LayeredHighlighterIterator)iterator;
+ } else {
+ layeredHighlighterIterator = null;
+ }
+ }
+ }
+
+ public void resetPosition(int startOffset) {
+ if (lexer instanceof LexerEditorHighlighterLexer) {
+ ((LexerEditorHighlighterLexer)lexer).resetPosition(startOffset);
+
+ HighlighterIterator iterator = ((LexerEditorHighlighterLexer)lexer).getHighlighterIterator();
+ if (iterator instanceof LayeredHighlighterIterator) {
+ layeredHighlighterIterator = (LayeredHighlighterIterator)iterator;
+ } else {
+ layeredHighlighterIterator = null;
+ }
+ } else {
+ CharSequence text = lexer.getBufferSequence();
+ lexer.start(text, startOffset, text.length());
+ }
+ }
+}
diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
index 6d7ce9c07a14..b9fc77295d62 100644
--- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
+++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
@@ -33,9 +33,8 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.LocalSearchScope;
-import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.search.*;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.content.Content;
import com.intellij.usageView.UsageViewBundle;
@@ -122,23 +121,23 @@ public class UsageViewManagerImpl extends UsageViewManager {
@NotNull final UsageViewPresentation presentation,
@NotNull final FindUsagesProcessPresentation processPresentation,
@Nullable final UsageViewStateListener listener) {
- final SearchScope searchScope = getSearchScope(searchFor);
+ final SearchScope searchScope = getMaxSearchScopeToWarnOfFallingOutOf(searchFor);
return doSearchAndShow(searchFor, searcherFactory, presentation, processPresentation, listener, searchScope);
}
- UsageView doSearchAndShow(@NotNull final UsageTarget[] searchFor,
+ private UsageView doSearchAndShow(@NotNull final UsageTarget[] searchFor,
@NotNull final Factory<UsageSearcher> searcherFactory,
@NotNull final UsageViewPresentation presentation,
@NotNull final FindUsagesProcessPresentation processPresentation,
@Nullable final UsageViewStateListener listener,
- @NotNull final SearchScope searchScope) {
+ @NotNull final SearchScope searchScopeToWarnOfFallingOutOf) {
final AtomicReference<UsageViewImpl> usageViewRef = new AtomicReference<UsageViewImpl>();
Task.Backgroundable task = new Task.Backgroundable(myProject, getProgressTitle(presentation), true, new SearchInBackgroundOption()) {
@Override
public void run(@NotNull final ProgressIndicator indicator) {
new SearchForUsagesRunnable(UsageViewManagerImpl.this, UsageViewManagerImpl.this.myProject, usageViewRef, presentation, searchFor, searcherFactory,
- processPresentation, searchScope, listener).run();
+ processPresentation, searchScopeToWarnOfFallingOutOf, listener).run();
}
@NotNull
@@ -159,7 +158,7 @@ public class UsageViewManagerImpl extends UsageViewManager {
}
@NotNull
- private SearchScope getSearchScope(@NotNull UsageTarget[] searchFor) {
+ private SearchScope getMaxSearchScopeToWarnOfFallingOutOf(@NotNull UsageTarget[] searchFor) {
UsageTarget target = searchFor[0];
if (target instanceof TypeSafeDataProvider) {
final SearchScope[] scope = new SearchScope[1];
@@ -171,7 +170,7 @@ public class UsageViewManagerImpl extends UsageViewManager {
});
return scope[0];
}
- return GlobalSearchScope.projectScope(myProject);
+ return GlobalSearchScope.allScope(myProject); // by default do not warn of falling out of scope
}
@Override
@@ -262,10 +261,27 @@ public class UsageViewManagerImpl extends UsageViewManager {
}
public static boolean isInScope(@NotNull Usage usage, @NotNull SearchScope searchScope) {
- VirtualFile file = usage instanceof UsageInFile ? ((UsageInFile)usage).getFile() : usage instanceof PsiElementUsage ? PsiUtilCore
- .getVirtualFile(((PsiElementUsage)usage).getElement()) : null;
- return file != null && (searchScope instanceof LocalSearchScope
- ? ((LocalSearchScope)searchScope).isInScope(file) : ((GlobalSearchScope)searchScope).contains(file));
+ PsiElement element = null;
+ VirtualFile file = usage instanceof UsageInFile ? ((UsageInFile)usage).getFile() :
+ usage instanceof PsiElementUsage ? PsiUtilCore.getVirtualFile(element = ((PsiElementUsage)usage).getElement()) : null;
+ if (file != null) {
+ return isFileInScope(file, searchScope);
+ }
+ else if(element != null) {
+ return searchScope instanceof EverythingGlobalScope ||
+ searchScope instanceof ProjectScopeImpl ||
+ searchScope instanceof ProjectAndLibrariesScope;
+ }
+ return false;
+ }
+
+ private static boolean isFileInScope(@NotNull VirtualFile file, @NotNull SearchScope searchScope) {
+ if (searchScope instanceof LocalSearchScope) {
+ return ((LocalSearchScope)searchScope).isInScope(file);
+ }
+ else {
+ return ((GlobalSearchScope)searchScope).contains(file);
+ }
}
@NotNull
diff --git a/platform/usageView/src/com/intellij/usages/impl/rules/UsageTypeGroupingRule.java b/platform/usageView/src/com/intellij/usages/impl/rules/UsageTypeGroupingRule.java
index b182bc31bceb..8d1de0bc06e3 100644
--- a/platform/usageView/src/com/intellij/usages/impl/rules/UsageTypeGroupingRule.java
+++ b/platform/usageView/src/com/intellij/usages/impl/rules/UsageTypeGroupingRule.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.usages.*;
import com.intellij.usages.rules.PsiElementUsage;
@@ -42,7 +43,13 @@ public class UsageTypeGroupingRule implements UsageGroupingRuleEx {
if (usage instanceof PsiElementUsage) {
PsiElementUsage elementUsage = (PsiElementUsage)usage;
- UsageType usageType = getUsageType(elementUsage.getElement(), targets);
+ PsiElement element = elementUsage.getElement();
+ UsageType usageType = getUsageType(element, targets);
+
+ if (usageType == null && element instanceof PsiFile && elementUsage instanceof UsageInfo2UsageAdapter) {
+ usageType = ((UsageInfo2UsageAdapter)elementUsage).getUsageType();
+ }
+
if (usageType != null) return new UsageTypeGroup(usageType);
if (usage instanceof ReadWriteAccessUsage) {
diff --git a/platform/usageView/usageView.iml b/platform/usageView/usageView.iml
index e3943e442779..d69cf73e8a0c 100644
--- a/platform/usageView/usageView.iml
+++ b/platform/usageView/usageView.iml
@@ -9,6 +9,7 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="lang-api" />
<orderEntry type="module" module-name="core-impl" />
+ <orderEntry type="module" module-name="editor-ui-ex" />
</component>
</module>
diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/util/resources/misc/registry.properties
index 0f430e0fee58..bbda04a2461a 100644
--- a/platform/platform-resources-en/src/misc/registry.properties
+++ b/platform/util/resources/misc/registry.properties
@@ -316,6 +316,7 @@ diff.patience.alg=false
svn.use.terminal=false
svn.use.incoming.optimization=false
+svn.executable.locale=C.UTF-8
completion.enable.relevant.method.chain.suggestions=false
ide.mac.message.sheets.java.emulation=false
@@ -366,6 +367,12 @@ editor.richcopy.strip.indents=true
allow.dialog.based.popups=true
allow.dialog.based.popups.description=Allows to use a JDialog as popup toplevel
+popup.fix.ide.frame.owner=false
+popup.fix.ide.frame.owner.description=Uses correct owner for IdeFrame, but can break some popups
+
+our.heavy.weight.popup=false
+our.heavy.weight.popup.description=Disables HeavyWeightPopup cache in Swing
+
focus.fix.lost.cursor=true
focus.fix.lost.cursor.description=See IDEA-79312
@@ -384,7 +391,7 @@ console.too.much.text.buffer.ratio.description=Used for disabling of console pro
when there is too much of text to process.\n\
The ratio is used against the console cycle buffer size (idea.cycle.buffer.size/theRatio=maxTextLength).
ide.file.settings.order.new=false
-ide.new.project.settings=false
+ide.new.project.settings=true
ide.new.project.settings.description=Temporary key for new project settings dialog UI
commonjs.complete.required.filename.with.extension=false
@@ -392,4 +399,10 @@ commonjs.complete.required.filename.with.extension.description=If checked, requi
fix.jdk7.alt.shortcuts=true
-fix.jdk7.alt.shortcuts.description=Allow to use alt for shortcuts on MacOSX with jdk7+ \ No newline at end of file
+fix.jdk7.alt.shortcuts.description=Allow to use alt for shortcuts on MacOSX with jdk7+
+
+ide.new.markup.markers=true
+ide.new.markup.markers.description=New error stripe markers
+
+spy.js.realtime.evaluation=false
+spy.js.realtime.evaluation.description=Enables spy-js autocomplete and realtime evaluation
diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java
index db897fd8c52d..be3f4f212072 100644
--- a/platform/util/src/com/intellij/icons/AllIcons.java
+++ b/platform/util/src/com/intellij/icons/AllIcons.java
@@ -74,6 +74,7 @@ public class AllIcons {
public static final Icon Forward = IconLoader.getIcon("/actions/forward.png"); // 16x16
public static final Icon GC = IconLoader.getIcon("/actions/gc.png"); // 16x16
public static final Icon Get = IconLoader.getIcon("/actions/get.png"); // 16x16
+ public static final Icon GroupByFile = IconLoader.getIcon("/actions/GroupByFile.png"); // 16x16
public static final Icon GroupByMethod = IconLoader.getIcon("/actions/groupByMethod.png"); // 16x16
public static final Icon GroupByModule = IconLoader.getIcon("/actions/GroupByModule.png"); // 16x16
public static final Icon GroupByModuleGroup = IconLoader.getIcon("/actions/GroupByModuleGroup.png"); // 16x16
@@ -459,6 +460,8 @@ public class AllIcons {
public static final Icon PluginManager = IconLoader.getIcon("/general/pluginManager.png"); // 32x32
public static final Icon Progress = IconLoader.getIcon("/general/progress.png"); // 8x10
public static final Icon ProjectConfigurable = IconLoader.getIcon("/general/projectConfigurable.png"); // 9x9
+ public static final Icon ProjectConfigurableBanner = IconLoader.getIcon("/general/projectConfigurableBanner.png"); // 9x9
+ public static final Icon ProjectConfigurableSelected = IconLoader.getIcon("/general/projectConfigurableSelected.png"); // 9x9
public static final Icon ProjectSettings = IconLoader.getIcon("/general/projectSettings.png"); // 16x16
public static final Icon ProjectStructure = IconLoader.getIcon("/general/projectStructure.png"); // 16x16
public static final Icon ProjectTab = IconLoader.getIcon("/general/projectTab.png"); // 16x16
diff --git a/platform/util/src/com/intellij/openapi/ui/Divider.java b/platform/util/src/com/intellij/openapi/ui/Divider.java
new file mode 100644
index 000000000000..1b2b6b1a3d6a
--- /dev/null
+++ b/platform/util/src/com/intellij/openapi/ui/Divider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.ui;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public abstract class Divider extends JPanel {
+ public Divider(LayoutManager layout) {
+ super(layout);
+ }
+
+ public abstract void setResizeEnabled(boolean resizeEnabled);
+
+ public abstract void setSwitchOrientationEnabled(boolean switchOrientationEnabled);
+
+ public abstract void setOrientation(boolean vertical);
+}
diff --git a/platform/util/src/com/intellij/openapi/ui/Splitter.java b/platform/util/src/com/intellij/openapi/ui/Splitter.java
index 44d2317088c6..71a026702563 100644
--- a/platform/util/src/com/intellij/openapi/ui/Splitter.java
+++ b/platform/util/src/com/intellij/openapi/ui/Splitter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -177,7 +177,7 @@ public class Splitter extends JPanel {
}
protected Divider createDivider() {
- return new Divider();
+ return new DividerImpl();
}
@Override
@@ -481,12 +481,12 @@ public class Splitter extends JPanel {
return myDivider;
}
- public class Divider extends JPanel {
+ public class DividerImpl extends Divider {
private boolean myResizeEnabled;
private boolean mySwitchOrientationEnabled;
protected Point myPoint;
- public Divider() {
+ public DividerImpl() {
super(new GridBagLayout());
myResizeEnabled = true;
mySwitchOrientationEnabled = false;
@@ -496,7 +496,7 @@ public class Splitter extends JPanel {
setOrientation(myVerticalSplit);
}
- private void setOrientation(boolean isVerticalSplit) {
+ public void setOrientation(boolean isVerticalSplit) {
removeAll();
setCursor(isVertical() ?
diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
index 0f95577cf2b5..cfcbe7967d35 100644
--- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
@@ -1255,10 +1255,15 @@ public class FileUtil extends FileUtilRt {
}
@Contract("null -> null")
- public static String getLocationRelativeToUserHome(@Nullable final String path) {
+ public static String getLocationRelativeToUserHome(@Nullable String path) {
+ return getLocationRelativeToUserHome(path, true);
+ }
+
+ @Contract("null,_ -> null")
+ public static String getLocationRelativeToUserHome(@Nullable String path, boolean unixOnly) {
if (path == null) return null;
- if (SystemInfo.isUnix) {
+ if (SystemInfo.isUnix || !unixOnly) {
final File projectDir = new File(path);
final File userHomeDir = new File(SystemProperties.getUserHome());
if (isAncestor(userHomeDir, projectDir, true)) {
diff --git a/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java b/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java
index 3484d0625d37..586668af3864 100644
--- a/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java
+++ b/platform/util/src/com/intellij/openapi/util/io/win32/IdeaWin32.java
@@ -35,7 +35,7 @@ public class IdeaWin32 {
static {
IdeaWin32 instance = null;
- if (SystemInfo.isWin2kOrNewer) {
+ if (SystemInfo.isWin2kOrNewer && Boolean.parseBoolean(System.getProperty("idea.use.native.fs.for.win", "true"))) {
try {
UrlClassLoader.loadPlatformLibrary("IdeaWin32");
instance = new IdeaWin32();
diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
index 7ee904c1f344..bc37f673bb03 100644
--- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
@@ -923,6 +923,10 @@ public class StringUtil extends StringUtilRt {
}
}
+ public static String defaultIfEmpty(@Nullable String value, String defaultValue) {
+ return isEmpty(value) ? defaultValue : value;
+ }
+
@Contract("null -> false")
public static boolean isNotEmpty(@Nullable String s) {
return s != null && !s.isEmpty();
@@ -2513,10 +2517,9 @@ public class StringUtil extends StringUtilRt {
public static String shortenTextWithEllipsis(@NotNull final String text,
final int maxLength,
final int suffixLength,
- boolean useEllipsisSymbol) {
+ @NotNull String symbol) {
final int textLength = text.length();
if (textLength > maxLength) {
- String symbol = useEllipsisSymbol ? "\u2026" : "...";
final int prefixLength = maxLength - suffixLength - symbol.length();
assert prefixLength > 0;
return text.substring(0, prefixLength) + symbol + text.substring(textLength - suffixLength);
@@ -2527,6 +2530,15 @@ public class StringUtil extends StringUtilRt {
}
@NotNull
+ public static String shortenTextWithEllipsis(@NotNull final String text,
+ final int maxLength,
+ final int suffixLength,
+ boolean useEllipsisSymbol) {
+ String symbol = useEllipsisSymbol ? "\u2026" : "...";
+ return shortenTextWithEllipsis(text, maxLength, suffixLength, symbol);
+ }
+
+ @NotNull
public static String shortenPathWithEllipsis(@NotNull final String path, final int maxLength, boolean useEllipsisSymbol) {
return shortenTextWithEllipsis(path, maxLength, (int)(maxLength * 0.7), useEllipsisSymbol);
}
@@ -2650,6 +2662,63 @@ public class StringUtil extends StringUtilRt {
return s.startsWith(smallPart.toLowerCase()) && bigPart.toLowerCase().startsWith(s);
}
+ public static String getShortened(String s, int maxWidth) {
+ int length = s.length();
+ if (isEmpty(s) || length <= maxWidth) return s;
+ ArrayList<String> words = new ArrayList<String>();
+
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < length; i++) {
+ char ch = s.charAt(i);
+
+ if (i == length - 1) {
+ builder.append(ch);
+ words.add(builder.toString());
+ builder.delete(0, builder.length());
+ continue;
+ }
+
+ if (i > 0 && (ch == '/' || ch == '\\' || ch == '.' || Character.isUpperCase(ch))) {
+ words.add(builder.toString());
+ builder.delete(0, builder.length());
+ }
+ builder.append(ch);
+ }
+ for (int i = 0; i < words.size(); i++) {
+ String word = words.get(i);
+ if (i < words.size() - 1 && word.length() == 1) {
+ words.remove(i);
+ words.set(i, word + words.get(i));
+ }
+ }
+
+ int removedLength = 0;
+
+ String toPaste = "...";
+ int index;
+ while (true) {
+ index = Math.max(0, (words.size() - 1) / 2);
+ String aWord = words.get(index);
+ words.remove(index);
+ int toCut = length - removedLength - maxWidth + 3;
+ if (words.size() < 2 || (toCut < aWord.length() - 2 && removedLength == 0)) {
+ int pos = (aWord.length() - toCut) / 2;
+ toPaste = aWord.substring(0, pos) + "..." + aWord.substring(pos+toCut);
+ break;
+ }
+ removedLength += aWord.length();
+ if (length - removedLength <= maxWidth - 3) {
+ break;
+ }
+ }
+ for (int i = 0; i < words.size(); i++) {
+ String word = words.get(i);
+ if (i == index || words.size() == 1) builder.append(toPaste);
+ builder.append(word);
+ }
+ return builder.toString().replaceAll("\\.{4,}", "...");
+ }
+
/**
* Expirable CharSequence. Very useful to control external library execution time,
* i.e. when java.util.regex.Pattern match goes out of control.
diff --git a/platform/util/src/com/intellij/ui/JBColor.java b/platform/util/src/com/intellij/ui/JBColor.java
index d2b4a3bd7623..3669e725610d 100644
--- a/platform/util/src/com/intellij/ui/JBColor.java
+++ b/platform/util/src/com/intellij/ui/JBColor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,9 @@
*/
package com.intellij.ui;
+import com.intellij.util.NotNullProducer;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.awt.color.ColorSpace;
@@ -32,6 +34,7 @@ public class JBColor extends Color {
private static volatile boolean DARK = UIUtil.isUnderDarcula();
private final Color darkColor;
+ private final NotNullProducer<Color> func;
public JBColor(int rgb, int darkRGB) {
this(new Color(rgb), new Color(darkRGB));
@@ -42,6 +45,13 @@ public class JBColor extends Color {
darkColor = dark;
//noinspection AssignmentToStaticFieldFromInstanceMethod
DARK = UIUtil.isUnderDarcula(); //Double check. Sometimes DARK != isDarcula() after dialogs appear on splash screen
+ func = null;
+ }
+
+ public JBColor(NotNullProducer<Color> function) {
+ super(0);
+ darkColor = null;
+ func = function;
}
public static void setDark(boolean dark) {
@@ -52,99 +62,142 @@ public class JBColor extends Color {
return darkColor;
}
+ Color getColor() {
+ if (func != null) {
+ return func.produce();
+ } else {
+ return DARK ? getDarkVariant() : this;
+ }
+ }
+
@Override
public int getRed() {
- return DARK ? getDarkVariant().getRed() : super.getRed();
+ final Color c = getColor();
+ return c == this ? super.getRed() : c.getRed();
}
@Override
public int getGreen() {
- return DARK ? getDarkVariant().getGreen() : super.getGreen();
+ final Color c = getColor();
+ return c == this ? super.getGreen() : c.getGreen();
}
@Override
public int getBlue() {
- return DARK ? getDarkVariant().getBlue() : super.getBlue();
+ final Color c = getColor();
+ return c == this ? super.getBlue() : c.getBlue();
}
@Override
public int getAlpha() {
- return DARK ? getDarkVariant().getAlpha() : super.getAlpha();
+ final Color c = getColor();
+ return c == this ? super.getAlpha() : c.getAlpha();
}
@Override
public int getRGB() {
- return DARK ? getDarkVariant().getRGB() : super.getRGB();
+ final Color c = getColor();
+ return c == this ? super.getRGB() : c.getRGB();
}
@Override
public Color brighter() {
+ if (func != null) {
+ return new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ return func.produce().brighter();
+ }
+ });
+ }
return new JBColor(super.brighter(), getDarkVariant().brighter());
}
@Override
public Color darker() {
+ if (func != null) {
+ return new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ return func.produce().darker();
+ }
+ });
+ }
return new JBColor(super.darker(), getDarkVariant().darker());
}
@Override
public int hashCode() {
- return DARK ? getDarkVariant().hashCode() : super.hashCode();
+ final Color c = getColor();
+ return c == this ? super.hashCode() : c.hashCode();
}
@Override
public boolean equals(Object obj) {
- return DARK ? getDarkVariant().equals(obj) : super.equals(obj);
+ final Color c = getColor();
+ return c == this ? super.equals(obj) : c.equals(obj);
}
@Override
public String toString() {
- return DARK ? getDarkVariant().toString() : super.toString();
+ final Color c = getColor();
+ return c == this ? super.toString() : c.toString();
}
@Override
public float[] getRGBComponents(float[] compArray) {
- return DARK ? getDarkVariant().getRGBComponents(compArray) : super.getRGBComponents(compArray);
+ final Color c = getColor();
+ return c == this ? super.getRGBComponents(compArray) : c.getRGBComponents(compArray);
}
@Override
public float[] getRGBColorComponents(float[] compArray) {
- return DARK ? getDarkVariant().getRGBColorComponents(compArray) : super.getRGBComponents(compArray);
+ final Color c = getColor();
+ return c == this ? super.getRGBComponents(compArray) : c.getRGBColorComponents(compArray);
}
@Override
public float[] getComponents(float[] compArray) {
- return DARK ? getDarkVariant().getComponents(compArray) : super.getComponents(compArray);
+ final Color c = getColor();
+ return c == this ? super.getComponents(compArray) : c.getComponents(compArray);
}
@Override
public float[] getColorComponents(float[] compArray) {
- return DARK ? getDarkVariant().getColorComponents(compArray) : super.getColorComponents(compArray);
+ final Color c = getColor();
+ return c == this ? super.getColorComponents(compArray) : c.getColorComponents(compArray);
}
@Override
public float[] getComponents(ColorSpace cspace, float[] compArray) {
- return DARK ? getDarkVariant().getComponents(cspace, compArray) : super.getComponents(cspace, compArray);
+ final Color c = getColor();
+ return c == this ? super.getComponents(cspace, compArray) : c.getComponents(cspace, compArray);
}
@Override
public float[] getColorComponents(ColorSpace cspace, float[] compArray) {
- return DARK ? getDarkVariant().getColorComponents(cspace, compArray) : super.getColorComponents(cspace, compArray);
+ final Color c = getColor();
+ return c == this ? super.getColorComponents(cspace, compArray) : c.getColorComponents(cspace, compArray);
}
@Override
public ColorSpace getColorSpace() {
- return DARK ? getDarkVariant().getColorSpace() : super.getColorSpace();
+ final Color c = getColor();
+ return c == this ? super.getColorSpace() : c.getColorSpace();
}
@Override
public synchronized PaintContext createContext(ColorModel cm, Rectangle r, Rectangle2D r2d, AffineTransform xform, RenderingHints hints) {
- return DARK ? getDarkVariant().createContext(cm, r, r2d, xform, hints) : super.createContext(cm, r, r2d, xform, hints);
+ final Color c = getColor();
+ return c == this ? super.createContext(cm, r, r2d, xform, hints) : c.createContext(cm, r, r2d, xform, hints);
}
@Override
public int getTransparency() {
- return DARK ? getDarkVariant().getTransparency() : super.getTransparency();
+ final Color c = getColor();
+ return c == this ? super.getTransparency() : c.getTransparency();
}
public static final JBColor red = new JBColor(Color.red, DarculaColors.RED);
@@ -196,7 +249,34 @@ public class JBColor extends Color {
public static final Color cyan = new JBColor(Color.cyan, new Color(0, 137, 137));
public static final Color CYAN = cyan;
- public static Color foreground() {return UIUtil.getLabelForeground();}
+ public static Color foreground() {
+ return new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ return UIUtil.getLabelForeground();
+ }
+ });
+ }
- public static Color background() {return UIUtil.getListBackground();}
+ public static Color background() {
+ return new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ return UIUtil.getListBackground();
+ }
+ });
+ }
+
+ public static Color border() {
+ return new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ //noinspection deprecation
+ return UIUtil.getBorderColor();
+ }
+ });
+ }
}
diff --git a/platform/util/src/com/intellij/util/EventDispatcher.java b/platform/util/src/com/intellij/util/EventDispatcher.java
index 34361a8ff31b..e17c6e46e5f3 100644
--- a/platform/util/src/com/intellij/util/EventDispatcher.java
+++ b/platform/util/src/com/intellij/util/EventDispatcher.java
@@ -43,6 +43,7 @@ public class EventDispatcher<T extends EventListener> {
}
private EventDispatcher(@NotNull Class<T> listenerClass) {
+ LOG.assertTrue(listenerClass.isInterface(), "listenerClass must be an interface");
InvocationHandler handler = new InvocationHandler() {
@Override
@NonNls
@@ -71,10 +72,7 @@ public class EventDispatcher<T extends EventListener> {
};
//noinspection unchecked
- myMulticaster = (T)Proxy.newProxyInstance(listenerClass.getClassLoader(),
- new Class[]{listenerClass},
- handler
- );
+ myMulticaster = (T)Proxy.newProxyInstance(listenerClass.getClassLoader(), new Class[]{listenerClass}, handler);
}
@NotNull
@@ -82,7 +80,7 @@ public class EventDispatcher<T extends EventListener> {
return myMulticaster;
}
- private void dispatch(final Method method, final Object[] args) {
+ private void dispatch(@NotNull Method method, Object[] args) {
method.setAccessible(true);
for (T listener : myListeners) {
diff --git a/platform/util/src/com/intellij/util/PatternUtil.java b/platform/util/src/com/intellij/util/PatternUtil.java
index 7159a90d1601..0b683dddc1e6 100644
--- a/platform/util/src/com/intellij/util/PatternUtil.java
+++ b/platform/util/src/com/intellij/util/PatternUtil.java
@@ -17,8 +17,9 @@ package com.intellij.util;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.containers.HashMap;
-import org.jetbrains.annotations.NonNls;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -29,30 +30,22 @@ import java.util.regex.PatternSyntaxException;
public class PatternUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.util.PatternUtil");
- private static final HashMap<String, String> ourEscapeRules = new HashMap<String, String>();
+
+ public static final Pattern NOTHING = Pattern.compile("(a\\A)");
+
+ private static final Map<String, String> ourEscapeRules = ContainerUtil.newLinkedHashMap();
static {
// '.' should be escaped first
ourEscapeRules.put("*", ".*");
ourEscapeRules.put("?", ".");
- escape2('+');
- escape2('(');
- escape2(')');
- escape2('[');
- escape2(']');
- escape2('/');
- escape2('^');
- escape2('$');
- escape2('{');
- escape2('}');
- escape2('|');
- }
-
- private static void escape2(char symbol) {
- ourEscapeRules.put(String.valueOf(symbol), "\\" + symbol);
+ for (char c : "+()[]/^${}|".toCharArray()) {
+ ourEscapeRules.put(String.valueOf(c), "\\" + c);
+ }
}
- public static String convertToRegex(String mask) {
+ @NotNull
+ public static String convertToRegex(@NotNull String mask) {
List<String> strings = StringUtil.split(mask, "\\");
StringBuilder pattern = new StringBuilder();
String separator = "";
@@ -69,17 +62,26 @@ public class PatternUtil {
return pattern.toString();
}
- public static Pattern fromMask(@NonNls String mask) {
-// String pattern = mask.replaceAll("\\.", "\\.").replaceAll("\\*", ".*").replaceAll("\\?", ".");
+ @NotNull
+ public static Pattern fromMask(@NotNull String mask) {
try {
return Pattern.compile(convertToRegex(mask));
}
catch (PatternSyntaxException e) {
LOG.error(mask, e);
- return Pattern.compile("");
+ return NOTHING;
}
}
+ @Contract("_, !null->!null")
+ public static Pattern compileSafe(String pattern, Pattern def) {
+ try {
+ return Pattern.compile(pattern);
+ }
+ catch (Exception e) {
+ return def;
+ }
+ }
/**
* Finds the first match in a list os Strings.
*
diff --git a/platform/util/src/com/intellij/util/ReflectionUtil.java b/platform/util/src/com/intellij/util/ReflectionUtil.java
index a4bf4318a76e..df33a80d4cba 100644
--- a/platform/util/src/com/intellij/util/ReflectionUtil.java
+++ b/platform/util/src/com/intellij/util/ReflectionUtil.java
@@ -426,6 +426,26 @@ public class ReflectionUtil {
}
}
+ /**
+ * {@link Class#newInstance()} cannot instantiate private classes
+ */
+ @NotNull
+ public static <T> T newInstance(@NotNull Class<T> aClass, @NotNull Class... parameterTypes) {
+ try {
+ Constructor<T> constructor = aClass.getDeclaredConstructor(parameterTypes);
+ try {
+ constructor.setAccessible(true);
+ }
+ catch (SecurityException e) {
+ return aClass.newInstance();
+ }
+ return constructor.newInstance();
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
@NotNull
public static <T> T createInstance(@NotNull Constructor<T> constructor, @NotNull Object... args) {
try {
diff --git a/platform/util/src/com/intellij/util/Restarter.java b/platform/util/src/com/intellij/util/Restarter.java
index 7f1584dc73dc..01e7fc494f5b 100644
--- a/platform/util/src/com/intellij/util/Restarter.java
+++ b/platform/util/src/com/intellij/util/Restarter.java
@@ -153,12 +153,11 @@ public class Restarter {
}
public static File createTempExecutable(File executable) throws IOException {
- String ext = FileUtilRt.getExtension(executable.getName());
- File copy = FileUtilRt.createTempFile(FileUtilRt.getNameWithoutExtension(executable.getName()),
- StringUtil.isEmptyOrSpaces(ext) ? ".tmp" : ("." + ext),
- false);
- FileUtilRt.copy(executable, copy);
- if (!copy.setExecutable(executable.canExecute())) throw new IOException("Cannot make file executable: " + copy);
+ File copy = new File(System.getProperty("user.home") + "/." + System.getProperty("idea.paths.selector") + "/restart/" + executable.getName());
+ if (FileUtilRt.ensureCanCreateFile(copy)) {
+ FileUtilRt.copy(executable, copy);
+ if (!copy.setExecutable(executable.canExecute())) throw new IOException("Cannot make file executable: " + copy);
+ }
return copy;
}
diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
index 6052df2b701e..171cfababfa9 100644
--- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java
+++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
@@ -828,6 +828,7 @@ public class ContainerUtil extends ContainerUtilRt {
@NotNull
public static <T> List<T> findAll(@NotNull Collection<? extends T> collection, @NotNull Condition<? super T> condition) {
+ if (collection.isEmpty()) return emptyList();
final List<T> result = new SmartList<T>();
for (final T t : collection) {
if (condition.value(t)) {
diff --git a/platform/util/src/com/intellij/util/containers/LongStack.java b/platform/util/src/com/intellij/util/containers/LongStack.java
new file mode 100644
index 000000000000..8e1005bd0af2
--- /dev/null
+++ b/platform/util/src/com/intellij/util/containers/LongStack.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.containers;
+
+/**
+ * @author lambdamix
+ */
+import java.util.EmptyStackException;
+
+public class LongStack {
+ private long[] data;
+ private int size;
+ public LongStack(int initialCapacity) {
+ data = new long[initialCapacity];
+ size = 0;
+ }
+
+ public LongStack() {
+ this(5);
+ }
+
+ public void push(long t) {
+ if (size >= data.length) {
+ long[] newdata = new long[data.length * 3 / 2];
+ System.arraycopy(data, 0, newdata, 0, size);
+ data = newdata;
+ }
+ data[size++] = t;
+ }
+
+ public long peek() {
+ if (size == 0) throw new EmptyStackException();
+ return data[size - 1];
+ }
+
+ public long pop() {
+ if (size == 0) throw new EmptyStackException();
+ return data[--size];
+ }
+
+ public boolean empty() {
+ return size == 0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof LongStack) {
+ LongStack otherStack = (LongStack)o;
+ if (size != otherStack.size) return false;
+ for (int i = 0; i < otherStack.size; i++) {
+ if (data[i] != otherStack.data[i]) return false;
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public void clear() {
+ size = 0;
+ }
+}
diff --git a/platform/util/src/com/intellij/util/diff/DiffTree.java b/platform/util/src/com/intellij/util/diff/DiffTree.java
index 0bab60dc87da..680b15b7d1de 100644
--- a/platform/util/src/com/intellij/util/diff/DiffTree.java
+++ b/platform/util/src/com/intellij/util/diff/DiffTree.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.intellij.util.diff;
import com.intellij.openapi.util.Ref;
@@ -39,7 +38,6 @@ public class DiffTree<OT, NT> {
final FlyweightCapableTreeStructure<NT> newTree,
final ShallowNodeComparator<OT, NT> comparator,
final DiffTreeChangeBuilder<OT, NT> consumer) {
-
myOldTree = oldTree;
myNewTree = newTree;
myComparator = comparator;
@@ -53,7 +51,7 @@ public class DiffTree<OT, NT> {
new DiffTree<OT, NT>(oldTree, newTree, comparator, consumer).build(oldTree.getRoot(), newTree.getRoot(), 0);
}
- private static enum CompareResult {
+ private enum CompareResult {
EQUAL, // 100% equal
DRILL_DOWN_NEEDED, // element types are equal, but elements are composite
TYPE_ONLY, // only element types are equal
@@ -146,6 +144,7 @@ public class DiffTree<OT, NT> {
newIndex++;
continue;
}
+
CompareResult c12 = looksEqual(comparator, oldChild1, newChild2);
if (c12 == CompareResult.EQUAL || c12 == CompareResult.DRILL_DOWN_NEEDED || c12 == CompareResult.TYPE_ONLY) {
myConsumer.nodeInserted(oldNode, newChild1, newIndex);
@@ -170,6 +169,7 @@ public class DiffTree<OT, NT> {
oldIndex++;
continue;
}
+
myConsumer.nodeReplaced(oldChild1, newChild1);
oldIndex++;
newIndex++;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurable.java b/platform/util/src/com/intellij/util/io/LongInlineKeyDescriptor.java
index 466279bce977..78f1fdd02f78 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurable.java
+++ b/platform/util/src/com/intellij/util/io/LongInlineKeyDescriptor.java
@@ -13,39 +13,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.xdebugger.impl.settings;
+package com.intellij.util.io;
-import com.intellij.openapi.options.ConfigurableBase;
-import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-class GeneralConfigurable extends ConfigurableBase<GeneralConfigurableUi, XDebuggerGeneralSettings> {
- @Override
- protected XDebuggerGeneralSettings getSettings() {
- return XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings();
- }
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * @author lambdamix
+ */
+public class LongInlineKeyDescriptor implements KeyDescriptor<Long> {
+ public static LongInlineKeyDescriptor INSTANCE = new LongInlineKeyDescriptor();
@Override
- protected GeneralConfigurableUi createUi() {
- return new GeneralConfigurableUi();
+ public final int getHashCode(Long value) {
+ return value.hashCode();
}
- @NotNull
@Override
- public String getId() {
- return "debugger.general";
+ public final boolean isEqual(Long val1, Long val2) {
+ return val1.longValue() == val2.longValue();
}
- @Nls
@Override
- public String getDisplayName() {
- return "";
+ public final void save(@NotNull DataOutput out, Long value) throws IOException {
+ out.writeLong(value.longValue());
}
- @Nullable
@Override
- public String getHelpTopic() {
- return null;
+ public final Long read(@NotNull DataInput in) throws IOException {
+ return in.readLong();
}
-} \ No newline at end of file
+
+}
diff --git a/platform/util/src/com/intellij/util/text/StringSearcher.java b/platform/util/src/com/intellij/util/text/StringSearcher.java
index 22e9db2d9428..d5bc95f99cef 100644
--- a/platform/util/src/com/intellij/util/text/StringSearcher.java
+++ b/platform/util/src/com/intellij/util/text/StringSearcher.java
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
+import java.util.Locale;
public class StringSearcher {
private static final Logger LOG = Logger.getInstance("#com.intellij.util.text.StringSearcher");
@@ -48,7 +49,7 @@ public class StringSearcher {
myPattern = pattern;
myCaseSensitive = caseSensitive;
myForwardDirection = forwardDirection;
- myPatternArray = myCaseSensitive ? myPattern.toCharArray() : myPattern.toLowerCase().toCharArray();
+ myPatternArray = myCaseSensitive ? myPattern.toCharArray() : myPattern.toLowerCase(Locale.US).toCharArray();
myPatternLength = myPatternArray.length;
Arrays.fill(mySearchTable, -1);
myJavaIdentifier = pattern.isEmpty() ||
diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java
index 7ed8021bd94b..aec2a356ded0 100644
--- a/platform/util/src/com/intellij/util/ui/UIUtil.java
+++ b/platform/util/src/com/intellij/util/ui/UIUtil.java
@@ -1586,7 +1586,7 @@ public class UIUtil {
@NotNull Graphics g,
boolean useRetinaCondition,
Consumer<Graphics2D> paintRoutine) {
- if (!useRetinaCondition || !isRetina() || Registry.is("ide.mac.retina.disableDrawingFix", false)) {
+ if (!useRetinaCondition || !isRetina() || Registry.is("ide.mac.retina.disableDrawingFix")) {
paintRoutine.consume((Graphics2D)g);
}
else {
@@ -1904,6 +1904,10 @@ public class UIUtil {
return INACTIVE_HEADER_COLOR;
}
+ /**
+ * @deprecated
+ * @use JBColor.border()
+ */
public static Color getBorderColor() {
return isUnderDarcula() ? Gray._50 : BORDER_COLOR;
}
@@ -2769,7 +2773,7 @@ public class UIUtil {
@NotNull
public static Paint getGradientPaint(float x1, float y1, @NotNull Color c1, float x2, float y2, @NotNull Color c2) {
- return (Registry.is("ui.no.bangs.and.whistles", false)) ? ColorUtil.mix(c1, c2, .5) : new GradientPaint(x1, y1, c1, x2, y2, c2);
+ return (Registry.is("ui.no.bangs.and.whistles")) ? ColorUtil.mix(c1, c2, .5) : new GradientPaint(x1, y1, c1, x2, y2, c2);
}
@Nullable
diff --git a/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java b/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java
index c25ea4eda084..6cc2124c695a 100644
--- a/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java
+++ b/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java
@@ -16,13 +16,13 @@
package com.intellij.util.xmlb;
import com.intellij.openapi.util.Pair;
+import com.intellij.util.ReflectionUtil;
import org.jdom.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.Annotation;
import java.lang.ref.SoftReference;
-import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
@@ -184,16 +184,9 @@ class XmlSerializerImpl {
/**
* {@link Class#newInstance()} cannot instantiate private classes
*/
- static <T> T newInstance(Class<T> aClass) {
+ static <T> T newInstance(@NotNull Class<T> aClass) {
try {
- Constructor<T> constructor = aClass.getDeclaredConstructor();
- try {
- constructor.setAccessible(true);
- }
- catch (SecurityException e) {
- return aClass.newInstance();
- }
- return constructor.newInstance();
+ return ReflectionUtil.newInstance(aClass);
}
catch (Exception e) {
throw new XmlSerializationException(e);
diff --git a/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java b/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java
index 2f31dc4f4e61..383c07f2a87e 100644
--- a/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java
+++ b/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java
@@ -195,4 +195,23 @@ public class StringUtilTest extends TestCase {
assertEquals(Arrays.asList("\n", "\r\n", "\n", "\r\n", "\r", "\r", "aa\r", "bb\r\n", "cc\n", "\r", "dd\n", "\n", "\r\n", "\r"),
Arrays.asList(StringUtil.splitByLinesKeepSeparators("\n\r\n\n\r\n\r\raa\rbb\r\ncc\n\rdd\n\n\r\n\r")));
}
+
+ public void testShortened() {
+ String[] names = {"AVeryVeeryLongClassName.java", "com.test.SomeJAVAClassName.java", "strangelowercaseclassname.java", "PrefixPostfix.java", "SomeJAVAClassName.java"};
+ for (String name : names) {
+ for (int i = name.length() + 1; i > 15; i--) {
+ String shortened = StringUtil.getShortened(name, i);
+ assertTrue(shortened.length() <= i);
+ assertTrue(!shortened.contains("...."));
+ int pos = shortened.indexOf("...");
+ if (pos != -1) {
+ assertTrue(name.startsWith(shortened.substring(0, pos)));
+ assertTrue(name.endsWith(shortened.substring(pos + 3)));
+ }
+ else {
+ assertEquals(shortened, name);
+ }
+ }
+ }
+ }
}
diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
index 377abeba5b18..9a3fcb9d7066 100644
--- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
+++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
@@ -495,6 +495,22 @@ public class XmlSerializerTest extends TestCase {
"</BeanWithFieldWithTagAnnotation>", bean);
}
+ public void testEscapeCharsInTagText() {
+ BeanWithFieldWithTagAnnotation bean = new BeanWithFieldWithTagAnnotation();
+ bean.STRING_V = "a\nb\"<";
+
+ doSerializerTest(
+ "<BeanWithFieldWithTagAnnotation>\n" +
+ " <name>a\nb&quot;&lt;</name>\n" +
+ "</BeanWithFieldWithTagAnnotation>", bean);
+ }
+
+ public void testEscapeCharsInAttributeValue() {
+ final BeanWithPropertiesBoundToAttribute bean = new BeanWithPropertiesBoundToAttribute();
+ bean.name = "a\nb\"<";
+ doSerializerTest("<BeanWithPropertiesBoundToAttribute count=\"3\" name=\"a&#10;b&quot;&lt;\" />", bean);
+ }
+
public void testShuffledDeserialize() {
BeanWithPublicFields bean = new BeanWithPublicFields();
bean.INT_V = 987;
diff --git a/platform/util/util.iml b/platform/util/util.iml
index d0155fd9b0b0..c015e73f13b3 100644
--- a/platform/util/util.iml
+++ b/platform/util/util.iml
@@ -5,6 +5,7 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
</content>
<orderEntry type="library" scope="PROVIDED" name="Mac" level="project" />
<orderEntry type="inheritedJdk" />
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java b/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java
index 04ce78be1601..c6b0daa0852d 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/ProjectLevelVcsManager.java
@@ -272,6 +272,7 @@ public abstract class ProjectLevelVcsManager {
public abstract VcsHistoryCache getVcsHistoryCache();
public abstract ContentRevisionCache getContentRevisionCache();
public abstract boolean isFileInContent(final VirtualFile vf);
+ public abstract boolean isIgnored(VirtualFile vf);
public abstract boolean dvcsUsedInProject();
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManager.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManager.java
index 006276b42739..9834ef5b0d9e 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManager.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManager.java
@@ -134,6 +134,7 @@ public abstract class ChangeListManager implements ChangeListModification {
public abstract List<CommitExecutor> getRegisteredExecutors();
public abstract void addFilesToIgnore(final IgnoredFileBean... ignoredFiles);
+ public abstract void addDirectoryToIgnoreImplicitly(@NotNull String path);
public abstract void setFilesToIgnore(final IgnoredFileBean... ignoredFiles);
public abstract IgnoredFileBean[] getFilesToIgnore();
public abstract boolean isIgnoredFile(@NotNull VirtualFile file);
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/IgnoredFileBean.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/IgnoredFileBean.java
index c09ce973634f..1091f908b600 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/IgnoredFileBean.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/IgnoredFileBean.java
@@ -26,7 +26,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.impl.NullVirtualFile;
import com.intellij.util.PatternUtil;
@@ -49,7 +49,8 @@ public class IgnoredFileBean {
myType = type;
if (IgnoreSettingsType.FILE.equals(type)) {
myFilenameIfFile = new File(path).getName();
- } else {
+ }
+ else {
myFilenameIfFile = null;
}
myProject = project;
@@ -115,9 +116,10 @@ public class IgnoredFileBean {
if (myType == IgnoreSettingsType.MASK) {
myMatcher.reset(file.getName());
return myMatcher.matches();
- } else {
+ }
+ else {
// quick check for 'file' == exact match pattern
- if (IgnoreSettingsType.FILE.equals(myType) && ! myFilenameIfFile.equals(file.getName())) return false;
+ if (IgnoreSettingsType.FILE.equals(myType) && !myFilenameIfFile.equals(file.getName())) return false;
VirtualFile selector = resolve();
if (Comparing.equal(selector, NullVirtualFile.INSTANCE)) return false;
@@ -130,7 +132,7 @@ public class IgnoredFileBean {
// special case for ignoring the project base dir (IDEADEV-16056)
return !file.isDirectory() && Comparing.equal(file.getParent(), selector);
}
- return VfsUtil.isAncestor(selector, file, false);
+ return VfsUtilCore.isAncestor(selector, file, false);
}
}
}
@@ -146,7 +148,9 @@ public class IgnoredFileBean {
@Nullable
private VirtualFile doResolve() {
- if (myProject == null || myProject.isDisposed()) { return null; }
+ if (myProject == null || myProject.isDisposed()) {
+ return null;
+ }
VirtualFile baseDir = myProject.getBaseDir();
String path = FileUtil.toSystemIndependentName(myPath);
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeModifier.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeModifier.java
index b97305c1a0a3..c8a8eda7a436 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeModifier.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeModifier.java
@@ -17,7 +17,7 @@ package com.intellij.openapi.vcs.changes;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Iterator;
@@ -28,7 +28,7 @@ import java.util.Iterator;
public interface VcsDirtyScopeModifier {
Iterator<FilePath> getDirtyFilesIterator();
Collection<VirtualFile> getAffectedVcsRoots();
- @Nullable
+ @NotNull
Iterator<FilePath> getDirtyDirectoriesIterator(VirtualFile root);
void recheckDirtyKeys();
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
index b9f0855c175c..5e01feada2f3 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
@@ -23,15 +23,20 @@ import com.intellij.openapi.application.RuntimeInterruptedException;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.impl.DirectoryIndexExcludePolicy;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.conflicts.ChangelistConflictTracker;
@@ -43,6 +48,7 @@ import com.intellij.openapi.vcs.readOnlyHandler.ReadonlyStatusHandlerImpl;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotifications;
import com.intellij.util.*;
@@ -68,8 +74,10 @@ import java.util.concurrent.atomic.AtomicReference;
/**
* @author max
*/
-public class ChangeListManagerImpl extends ChangeListManagerEx implements ProjectComponent, ChangeListOwner, JDOMExternalizable, RoamingTypeDisabled {
+public class ChangeListManagerImpl extends ChangeListManagerEx implements ProjectComponent, ChangeListOwner, JDOMExternalizable,
+ RoamingTypeDisabled {
public static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.ChangeListManagerImpl");
+ private static final String EXCLUDED_CONVERTED_TO_IGNORED_OPTION = "EXCLUDED_CONVERTED_TO_IGNORED";
private final Project myProject;
private final VcsConfiguration myConfig;
@@ -101,6 +109,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
private final List<CommitExecutor> myExecutors = new ArrayList<CommitExecutor>();
private final IgnoredFilesComponent myIgnoredIdeaLevel;
+ private boolean myExcludedConvertedToIgnored;
private ProgressIndicator myUpdateChangesProgressIndicator;
public static final Topic<LocalChangeListsLoadedListener> LISTS_LOADED = new Topic<LocalChangeListsLoadedListener>(
@@ -191,6 +200,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
/**
* Shows the proposal to delete one or more changelists that were default and became empty.
+ *
* @return true if the changelists have to be deleted, false if not.
*/
private boolean showRemoveEmptyChangeListsProposal(@NotNull final VcsConfiguration config, @NotNull Collection<LocalChangeList> lists) {
@@ -242,7 +252,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
public void unblockModalNotifications() {
myModalNotificationsBlocked = false;
if (myListsToBeDeleted.isEmpty()) {
- return ;
+ return;
}
if (showRemoveEmptyChangeListsProposal(myConfig, myListsToBeDeleted)) {
for (LocalChangeList list : myListsToBeDeleted) {
@@ -261,14 +271,14 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
vcsManager.addVcsListener(myVcsListener);
}
else {
- ((ProjectLevelVcsManagerImpl) vcsManager).addInitializationRequest(
+ ((ProjectLevelVcsManagerImpl)vcsManager).addInitializationRequest(
VcsInitObject.CHANGE_LIST_MANAGER, new DumbAwareRunnable() {
- public void run() {
- myUpdater.initialized();
- broadcastStateAfterLoad();
- vcsManager.addVcsListener(myVcsListener);
- }
- });
+ public void run() {
+ myUpdater.initialized();
+ broadcastStateAfterLoad();
+ vcsManager.addVcsListener(myVcsListener);
+ }
+ });
}
myConflictTracker.startTracking();
@@ -279,7 +289,9 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
synchronized (myDataLock) {
listCopy = getChangeListsCopy();
}
- myProject.getMessageBus().syncPublisher(LISTS_LOADED).processLoadedLists(listCopy);
+ if (!myProject.isDisposed()) {
+ myProject.getMessageBus().syncPublisher(LISTS_LOADED).processLoadedLists(listCopy);
+ }
}
private void initializeForNewProject() {
@@ -297,11 +309,29 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
myIgnoredIdeaLevel.add(IgnoredBeanFactory.ignoreFile(Project.DIRECTORY_STORE_FOLDER + "/workspace.xml", myProject));
}
}
+ if (!Registry.is("ide.hide.excluded.files") && !myExcludedConvertedToIgnored) {
+ convertExcludedToIgnored();
+ myExcludedConvertedToIgnored = true;
+ }
}
}
});
}
+ void convertExcludedToIgnored() {
+ for (DirectoryIndexExcludePolicy policy : DirectoryIndexExcludePolicy.EP_NAME.getExtensions(myProject)) {
+ for (VirtualFile file : policy.getExcludeRootsForProject()) {
+ addDirectoryToIgnoreImplicitly(file.getPath());
+ }
+ }
+
+ for (Module module : ModuleManager.getInstance(myProject).getModules()) {
+ for (String url : ModuleRootManager.getInstance(module).getExcludeRootUrls()) {
+ addDirectoryToIgnoreImplicitly(VfsUtilCore.urlToPath(url));
+ }
+ }
+ }
+
public void projectClosed() {
ProjectLevelVcsManager.getInstance(myProject).removeVcsListener(myVcsListener);
@@ -328,11 +358,12 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
/**
* update itself might produce actions done on AWT thread (invoked-after),
- * so waiting for its completion on AWT thread is not good
- *
- * runnable is invoked on AWT thread
+ * so waiting for its completion on AWT thread is not good runnable is invoked on AWT thread
*/
- public void invokeAfterUpdate(final Runnable afterUpdate, final InvokeAfterUpdateMode mode, @Nullable final String title, @Nullable final ModalityState state) {
+ public void invokeAfterUpdate(final Runnable afterUpdate,
+ final InvokeAfterUpdateMode mode,
+ @Nullable final String title,
+ @Nullable final ModalityState state) {
myUpdater.invokeAfterUpdate(afterUpdate, mode, title, null, state);
}
@@ -394,13 +425,13 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
synchronized (myDataLock) {
final IgnoredFilesHolder fileHolder = (IgnoredFilesHolder)myComposite.get(FileHolder.HolderType.IGNORED);
- for (Iterator<VcsDirtyScope> iterator = scopes.iterator(); iterator.hasNext();) {
- final VcsModifiableDirtyScope scope = (VcsModifiableDirtyScope) iterator.next();
+ for (Iterator<VcsDirtyScope> iterator = scopes.iterator(); iterator.hasNext(); ) {
+ final VcsModifiableDirtyScope scope = (VcsModifiableDirtyScope)iterator.next();
final VcsDirtyScopeModifier modifier = scope.getModifier();
if (modifier != null) {
fileHolder.notifyVcsStarted(scope.getVcs());
final Iterator<FilePath> filesIterator = modifier.getDirtyFilesIterator();
- for (; filesIterator.hasNext();) {
+ while (filesIterator.hasNext()) {
final FilePath dirtyFile = filesIterator.next();
if ((dirtyFile.getVirtualFile() != null) && isIgnoredFile(dirtyFile.getVirtualFile())) {
filesIterator.remove();
@@ -411,7 +442,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
final Collection<VirtualFile> roots = modifier.getAffectedVcsRoots();
for (VirtualFile root : roots) {
final Iterator<FilePath> dirIterator = modifier.getDirtyDirectoriesIterator(root);
- for (; dirIterator.hasNext(); ) {
+ while (dirIterator.hasNext()) {
final FilePath dir = dirIterator.next();
if ((dir.getVirtualFile() != null) && isIgnoredFile(dir.getVirtualFile())) {
dirIterator.remove();
@@ -428,10 +459,10 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
}
}
- catch(Exception ex) {
+ catch (Exception ex) {
LOG.error(ex);
}
- catch(AssertionError ex) {
+ catch (AssertionError ex) {
LOG.error(ex);
}
for (VirtualFile file : refreshFiles) {
@@ -443,7 +474,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
final DataHolder dataHolder;
final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject);
- if (! vcsManager.hasActiveVcss()) return;
+ if (!vcsManager.hasActiveVcss()) return;
final VcsInvalidated invalidated = myDirtyScopeManager.retrieveScopes();
if (checkScopeIsEmpty(invalidated)) return;
@@ -458,14 +489,14 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
// mark for "modifier" that update started (it would create duplicates of modification commands done by user during update;
// after update of copies of objects is complete, it would apply the same modifications to copies.)
synchronized (myDataLock) {
- dataHolder = new DataHolder((FileHolderComposite) myComposite.copy(), myWorker.copy(), wasEverythingDirty);
+ dataHolder = new DataHolder((FileHolderComposite)myComposite.copy(), myWorker.copy(), wasEverythingDirty);
myModifier.enterUpdate();
if (wasEverythingDirty) {
myUpdateException = null;
myAdditionalInfo = null;
}
}
- final String scopeInString = (! LOG.isDebugEnabled()) ? "" : StringUtil.join(scopes, new Function<VcsDirtyScope, String>() {
+ final String scopeInString = (!LOG.isDebugEnabled()) ? "" : StringUtil.join(scopes, new Function<VcsDirtyScope, String>() {
@Override
public String fun(VcsDirtyScope scope) {
return scope.toString();
@@ -504,7 +535,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
myWorker.onAfterWorkerSwitch(oldWorker);
myModifier.setWorker(myWorker);
LOG.debug("refresh procedure finished, unversioned size: " +
- dataHolder.getComposite().getVFHolder(FileHolder.HolderType.UNVERSIONED).getSize() + "\n changes: " + myWorker);
+ dataHolder.getComposite().getVFHolder(FileHolder.HolderType.UNVERSIONED).getSize() + "\n changes: " + myWorker);
final boolean statusChanged = !myComposite.equals(dataHolder.getComposite());
myComposite = dataHolder.getComposite();
if (statusChanged) {
@@ -535,19 +566,20 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
catch (DisposedException e) {
// OK, we're finishing all the stuff now.
}
- catch(ProcessCanceledException e) {
+ catch (ProcessCanceledException e) {
// OK, we're finishing all the stuff now.
- } catch (RuntimeInterruptedException ignore) {
}
- catch(Exception ex) {
+ catch (RuntimeInterruptedException ignore) {
+ }
+ catch (Exception ex) {
LOG.error(ex);
}
- catch(AssertionError ex) {
+ catch (AssertionError ex) {
LOG.error(ex);
}
finally {
myDirtyScopeManager.changesProcessed();
-
+
synchronized (myDataLock) {
myDelayedNotificator.getProxyDispatcher().changeListUpdateDone();
myChangesViewManager.scheduleRefresh();
@@ -556,7 +588,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
private boolean checkScopeIsAllIgnored(VcsInvalidated invalidated) {
- if (! invalidated.isEverythingDirty()) {
+ if (!invalidated.isEverythingDirty()) {
filterOutIgnoredFiles(invalidated.getScopes());
if (invalidated.isEmpty()) {
return true;
@@ -586,7 +618,8 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
};
final UpdatingChangeListBuilder builder = new UpdatingChangeListBuilder(dataHolder.getChangeListWorker(),
- dataHolder.getComposite(), disposedGetter, myIgnoredIdeaLevel, gate);
+ dataHolder.getComposite(), disposedGetter, myIgnoredIdeaLevel,
+ gate);
for (final VcsDirtyScope scope : scopes) {
myUpdateChangesProgressIndicator.checkCanceled();
@@ -594,7 +627,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
final AbstractVcs vcs = scope.getVcs();
if (vcs == null) continue;
scope.setWasEverythingDirty(wasEverythingDirty);
- final VcsModifiableDirtyScope adjustedScope = vcs.adjustDirtyScope((VcsModifiableDirtyScope) scope);
+ final VcsModifiableDirtyScope adjustedScope = vcs.adjustDirtyScope((VcsModifiableDirtyScope)scope);
myChangesViewManager.setBusy(true);
dataHolder.notifyStartProcessingChanges(adjustedScope);
@@ -614,7 +647,8 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
final ContentRevisionCache cache = ProjectLevelVcsManager.getInstance(myProject).getContentRevisionCache();
if (invalidated.isEverythingDirty()) {
cache.clearAllCurrent();
- } else {
+ }
+ else {
cache.clearScope(invalidated.getScopes());
}
}
@@ -625,6 +659,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
public boolean isCanceled() {
return myUpdater.isStopped();
}
+
@Override
public void checkCanceled() {
checkIfDisposed();
@@ -651,7 +686,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
public void notifyStartProcessingChanges(@NotNull final VcsModifiableDirtyScope scope) {
- if (! myWasEverythingDirty) {
+ if (!myWasEverythingDirty) {
myComposite.cleanAndAdjustScope(scope);
myChangeListWorker.notifyStartProcessingChanges(scope);
}
@@ -661,7 +696,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
public void notifyDoneProcessingChanges() {
- if (! myWasEverythingDirty) {
+ if (!myWasEverythingDirty) {
myChangeListWorker.notifyDoneProcessingChanges(myDelayedNotificator.getProxyDispatcher());
}
}
@@ -695,11 +730,14 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
handleUpdateException(e);
}
}
- } catch (ProcessCanceledException ignore) {
- } catch (Throwable t) {
+ }
+ catch (ProcessCanceledException ignore) {
+ }
+ catch (Throwable t) {
LOG.debug(t);
Rethrow.reThrowRuntime(t);
- } finally {
+ }
+ finally {
if (!myUpdater.isStopped()) {
dataHolder.notifyDoneProcessingChanges();
}
@@ -748,8 +786,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
/**
- * @deprecated
- * this method made equivalent to {@link #getChangeListsCopy()} so to don't be confused by method name,
+ * @deprecated this method made equivalent to {@link #getChangeListsCopy()} so to don't be confused by method name,
* better use {@link #getChangeListsCopy()}
*/
@NotNull
@@ -816,13 +853,14 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
Map<VirtualFile, LogicalLock> getLogicallyLockedFolders() {
synchronized (myDataLock) {
- return new HashMap<VirtualFile, LogicalLock>(((LogicallyLockedHolder) myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).getMap());
+ return new HashMap<VirtualFile, LogicalLock>(
+ ((LogicallyLockedHolder)myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).getMap());
}
}
public boolean isLogicallyLocked(final VirtualFile file) {
synchronized (myDataLock) {
- return ((LogicallyLockedHolder) myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).containsKey(file);
+ return ((LogicallyLockedHolder)myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).containsKey(file);
}
}
@@ -847,7 +885,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
@Nullable
Map<VirtualFile, String> getSwitchedRoots() {
synchronized (myDataLock) {
- return ((SwitchedFileHolder) myComposite.get(FileHolder.HolderType.ROOT_SWITCH)).getFilesMapCopy();
+ return ((SwitchedFileHolder)myComposite.get(FileHolder.HolderType.ROOT_SWITCH)).getFilesMapCopy();
}
}
@@ -856,7 +894,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
return myUpdateException;
}
}
-
+
public Factory<JComponent> getAdditionalUpdateInfo() {
synchronized (myDataLock) {
return myAdditionalInfo;
@@ -937,7 +975,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
synchronized (myDataLock) {
for (Map.Entry<String, List<Change>> entry : map.entrySet()) {
final List<Change> changes = entry.getValue();
- for (Iterator<Change> iterator = changes.iterator(); iterator.hasNext();) {
+ for (Iterator<Change> iterator = changes.iterator(); iterator.hasNext(); ) {
final Change change = iterator.next();
if (getChangeList(change) != null) {
// was not actually rolled back
@@ -948,7 +986,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
for (String listName : map.keySet()) {
final LocalChangeList byName = myWorker.getCopyByName(listName);
- if (byName != null && byName.getChanges().isEmpty() && ! byName.isDefault() && ! byName.isReadOnly()) {
+ if (byName != null && byName.getChanges().isEmpty() && !byName.isDefault() && !byName.isReadOnly()) {
myWorker.removeChangeList(listName);
}
}
@@ -1005,15 +1043,14 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
/**
- * @deprecated
- * better use normal comparison, with equals
+ * @deprecated better use normal comparison, with equals
*/
@Nullable
public LocalChangeList getIdentityChangeList(Change change) {
synchronized (myDataLock) {
final List<LocalChangeList> lists = myWorker.getListsCopy();
for (LocalChangeList list : lists) {
- for(Change oldChange: list.getChanges()) {
+ for (Change oldChange : list.getChanges()) {
if (oldChange == change) {
return list;
}
@@ -1168,7 +1205,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
if (exceptions.size() > 0) {
StringBuilder message = new StringBuilder(VcsBundle.message("error.adding.files.prompt"));
- for(VcsException ex: exceptions) {
+ for (VcsException ex : exceptions) {
message.append("\n").append(ex.getMessage());
}
Messages.showErrorDialog(myProject, message.toString(), VcsBundle.message("error.adding.files.title"));
@@ -1189,7 +1226,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
synchronized (myDataLock) {
List<Change> changesToMove = new ArrayList<Change>();
final LocalChangeList defaultList = getDefaultChangeList();
- for(Change change: defaultList.getChanges()) {
+ for (Change change : defaultList.getChanges()) {
final ContentRevision afterRevision = change.getAfterRevision();
if (afterRevision != null) {
VirtualFile vFile = afterRevision.getFile().getVirtualFile();
@@ -1208,8 +1245,9 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
myChangesViewManager.scheduleRefresh();
}
- }, InvokeAfterUpdateMode.BACKGROUND_NOT_CANCELLABLE_NOT_AWT, VcsBundle.message("change.lists.manager.add.unversioned"), null);
- } else {
+ }, InvokeAfterUpdateMode.BACKGROUND_NOT_CANCELLABLE_NOT_AWT, VcsBundle.message("change.lists.manager.add.unversioned"), null);
+ }
+ else {
myChangesViewManager.scheduleRefresh();
}
}
@@ -1238,8 +1276,8 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
private boolean doCommit(final LocalChangeList changeList, final List<Change> changes, final boolean synchronously) {
FileDocumentManager.getInstance().saveAllDocuments();
return new CommitHelper(myProject, changeList, changes, changeList.getName(),
- StringUtil.isEmpty(changeList.getComment()) ? changeList.getName() : changeList.getComment(),
- new ArrayList<CheckinHandler>(), false, synchronously, NullableFunction.NULL, null).doCommit();
+ StringUtil.isEmpty(changeList.getComment()) ? changeList.getName() : changeList.getComment(),
+ new ArrayList<CheckinHandler>(), false, synchronously, NullableFunction.NULL, null).doCommit();
}
public void commitChangesSynchronously(LocalChangeList changeList, List<Change> changes) {
@@ -1252,20 +1290,21 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
@SuppressWarnings({"unchecked"})
public void readExternal(Element element) throws InvalidDataException {
- if (! myProject.isDefault()) {
+ if (!myProject.isDefault()) {
synchronized (myDataLock) {
myIgnoredIdeaLevel.clear();
new ChangeListManagerSerialization(myIgnoredIdeaLevel, myWorker).readExternal(element);
- if ((! myWorker.isEmpty()) && getDefaultChangeList() == null) {
+ if ((!myWorker.isEmpty()) && getDefaultChangeList() == null) {
setDefaultChangeList(myWorker.getListsCopy().get(0));
}
}
+ myExcludedConvertedToIgnored = Boolean.parseBoolean(JDOMExternalizerUtil.readField(element, EXCLUDED_CONVERTED_TO_IGNORED_OPTION));
myConflictTracker.loadState(element);
}
}
public void writeExternal(Element element) throws WriteExternalException {
- if (! myProject.isDefault()) {
+ if (!myProject.isDefault()) {
final IgnoredFilesComponent ignoredFilesComponent;
final ChangeListWorker worker;
synchronized (myDataLock) {
@@ -1273,6 +1312,9 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
worker = myWorker.copy();
}
new ChangeListManagerSerialization(ignoredFilesComponent, worker).writeExternal(element);
+ if (myExcludedConvertedToIgnored) {
+ JDOMExternalizerUtil.writeField(element, EXCLUDED_CONVERTED_TO_IGNORED_OPTION, String.valueOf(true));
+ }
myConflictTracker.saveState(element);
}
}
@@ -1316,10 +1358,11 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
if (vf.isDirectory()) {
myDirs.add(vf);
- } else {
+ }
+ else {
myFiles.add(vf);
}
- ++ myCnt;
+ ++myCnt;
}
}
@@ -1327,7 +1370,8 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
final VcsDirtyScopeManager vcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject);
if (myEveryThing) {
vcsDirtyScopeManager.markEverythingDirty();
- } else {
+ }
+ else {
vcsDirtyScopeManager.filesDirty(myFiles, myDirs);
}
}
@@ -1338,12 +1382,21 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
scheduleUnversionedUpdate();
}
+ @Override
+ public void addDirectoryToIgnoreImplicitly(@NotNull String path) {
+ myIgnoredIdeaLevel.addIgnoredDirectoryImplicitly(path, myProject);
+ }
+
+ public IgnoredFilesComponent getIgnoredFilesComponent() {
+ return myIgnoredIdeaLevel;
+ }
+
private void scheduleUnversionedUpdate() {
final MyDirtyFilesScheduler scheduler = new MyDirtyFilesScheduler(myProject);
synchronized (myDataLock) {
final VirtualFileHolder unversionedHolder = myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED);
- final IgnoredFilesHolder ignoredHolder = (IgnoredFilesHolder) myComposite.get(FileHolder.HolderType.IGNORED);
+ final IgnoredFilesHolder ignoredHolder = (IgnoredFilesHolder)myComposite.get(FileHolder.HolderType.IGNORED);
scheduler.accept(unversionedHolder.getFiles());
scheduler.accept(ignoredHolder.values());
@@ -1368,7 +1421,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
private void exchangeWithIgnored(FileHolderComposite composite, VirtualFileHolder vfHolder, List<VirtualFile> unversionedFiles) {
- for(VirtualFile file: unversionedFiles) {
+ for (VirtualFile file : unversionedFiles) {
if (isIgnoredFile(file)) {
vfHolder.removeFile(file);
composite.getIgnoredFileHolder().addFile(file);
@@ -1594,11 +1647,11 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
if (freezeReason != null) {
if (modalTitle != null) {
Messages.showErrorDialog(myProject, freezeReason, modalTitle);
- } else {
+ }
+ else {
VcsBalloonProblemNotifier.showOverChangesView(myProject, freezeReason, MessageType.WARNING);
}
}
return freezeReason != null;
}
-
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerSerialization.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerSerialization.java
index a4c30e62bda5..0e20b4140b56 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerSerialization.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerSerialization.java
@@ -22,12 +22,10 @@ import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
+import java.util.*;
class ChangeListManagerSerialization {
@NonNls static final String ATT_ID = "id";
@@ -44,6 +42,8 @@ class ChangeListManagerSerialization {
@NonNls static final String NODE_LIST = "list";
@NonNls static final String NODE_IGNORED = "ignored";
@NonNls static final String NODE_CHANGE = "change";
+ @NonNls static final String MANUALLY_REMOVED_FROM_IGNORED = "manually-removed-from-ignored";
+ @NonNls static final String DIRECTORY_TAG = "directory";
private final IgnoredFilesComponent myIgnoredIdeaLevel;
private final ChangeListWorker myWorker;
@@ -60,9 +60,17 @@ class ChangeListManagerSerialization {
readChangeList(listNode);
}
final List<Element> ignoredNodes = element.getChildren(NODE_IGNORED);
- for (Element ignoredNode: ignoredNodes) {
+ for (Element ignoredNode : ignoredNodes) {
readFileToIgnore(ignoredNode);
}
+ Element manuallyRemovedFromIgnoredTag = element.getChild(MANUALLY_REMOVED_FROM_IGNORED);
+ Set<String> manuallyRemovedFromIgnoredPaths = new HashSet<String>();
+ if (manuallyRemovedFromIgnoredTag != null) {
+ for (Element tag : manuallyRemovedFromIgnoredTag.getChildren(DIRECTORY_TAG)) {
+ manuallyRemovedFromIgnoredPaths.add(tag.getAttributeValue(ATT_PATH));
+ }
+ }
+ myIgnoredIdeaLevel.setDirectoriesManuallyRemovedFromIgnored(manuallyRemovedFromIgnoredPaths);
}
private void readChangeList(final Element listNode) {
@@ -90,7 +98,6 @@ class ChangeListManagerSerialization {
if (ATT_VALUE_TRUE.equals(listNode.getAttributeValue(ATT_READONLY))) {
list.setReadOnly(true);
}
-
}
private void readFileToIgnore(final Element ignoredNode) {
@@ -123,7 +130,10 @@ class ChangeListManagerSerialization {
listNode.setAttribute(ATT_ID, list.getId());
listNode.setAttribute(ATT_NAME, list.getName());
- listNode.setAttribute(ATT_COMMENT, list.getComment());
+ String comment = list.getComment();
+ if (comment != null) {
+ listNode.setAttribute(ATT_COMMENT, comment);
+ }
List<Change> changes = new ArrayList<Change>(list.getChanges());
Collections.sort(changes, new ChangeComparator());
for (Change change : changes) {
@@ -131,26 +141,35 @@ class ChangeListManagerSerialization {
}
}
final IgnoredFileBean[] filesToIgnore = myIgnoredIdeaLevel.getFilesToIgnore();
- for(IgnoredFileBean bean: filesToIgnore) {
- Element fileNode = new Element(NODE_IGNORED);
- element.addContent(fileNode);
- String path = bean.getPath();
- if (path != null) {
- fileNode.setAttribute("path", path);
- }
- String mask = bean.getMask();
- if (mask != null) {
- fileNode.setAttribute("mask", mask);
- }
+ for (IgnoredFileBean bean : filesToIgnore) {
+ Element fileNode = new Element(NODE_IGNORED);
+ element.addContent(fileNode);
+ String path = bean.getPath();
+ if (path != null) {
+ fileNode.setAttribute("path", path);
+ }
+ String mask = bean.getMask();
+ if (mask != null) {
+ fileNode.setAttribute("mask", mask);
}
+ }
+ Set<String> manuallyRemovedFromIgnored = myIgnoredIdeaLevel.getDirectoriesManuallyRemovedFromIgnored();
+ if (!manuallyRemovedFromIgnored.isEmpty()) {
+ Element list = new Element(MANUALLY_REMOVED_FROM_IGNORED);
+ for (String path : manuallyRemovedFromIgnored) {
+ list.addContent(new Element(DIRECTORY_TAG).setAttribute(ATT_PATH, path));
+ }
+ element.addContent(list);
+ }
}
private static class ChangeComparator implements Comparator<Change> {
@Override
- public int compare(Change o1, Change o2) {
+ public int compare(@NotNull Change o1, @NotNull Change o2) {
return Comparing.compare(o1.toString(), o2.toString());
}
}
+
private static void writeChange(final Element listNode, final Change change) {
Element changeNode = new Element(NODE_CHANGE);
listNode.addContent(changeNode);
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedContent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedContent.java
index 6d13d21a996c..f81c5069718b 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedContent.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedContent.java
@@ -16,7 +16,10 @@
package com.intellij.openapi.vcs.changes;
import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vcs.FileStatus;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.BeforeAfter;
import java.util.List;
@@ -30,13 +33,41 @@ public class FragmentedContent {
private final Document myBefore;
private final Document myAfter;
private final List<BeforeAfter<TextRange>> myRanges;
- private boolean myOneSide;
- private boolean myIsAddition;
- public FragmentedContent(Document before, Document after, List<BeforeAfter<TextRange>> ranges) {
+ private final boolean myOneSide;
+ private final boolean myIsAddition;
+
+ private final VirtualFile myFileBefore;
+ private final VirtualFile myFileAfter;
+ private final FileType myFileTypeBefore;
+ private final FileType myFileTypeAfter;
+
+ public FragmentedContent(Document before, Document after, List<BeforeAfter<TextRange>> ranges, Change change) {
myBefore = before;
myAfter = after;
myRanges = ranges;
+
+ final FileStatus fs = change.getFileStatus();
+ myIsAddition = FileStatus.ADDED.equals(fs);
+ myOneSide = FileStatus.ADDED.equals(fs) || FileStatus.DELETED.equals(fs);
+
+ if (change.getBeforeRevision() != null) {
+ myFileBefore = change.getBeforeRevision().getFile().getVirtualFile();
+ myFileTypeBefore = change.getBeforeRevision().getFile().getFileType();
+ }
+ else {
+ myFileBefore = null;
+ myFileTypeBefore = null;
+ }
+
+ if (change.getAfterRevision() != null) {
+ myFileAfter = change.getAfterRevision().getFile().getVirtualFile();
+ myFileTypeAfter = change.getAfterRevision().getFile().getFileType();
+ }
+ else {
+ myFileAfter = null;
+ myFileTypeAfter = null;
+ }
}
public Document getBefore() {
@@ -50,7 +81,7 @@ public class FragmentedContent {
public List<BeforeAfter<TextRange>> getRanges() {
return myRanges;
}
-
+
public int getSize() {
return myRanges.size();
}
@@ -59,15 +90,23 @@ public class FragmentedContent {
return myOneSide;
}
- public void setOneSide(boolean oneSide) {
- myOneSide = oneSide;
- }
-
public boolean isAddition() {
return myIsAddition;
}
- public void setIsAddition(boolean isAddition) {
- myIsAddition = isAddition;
+ public VirtualFile getFileBefore() {
+ return myFileBefore;
+ }
+
+ public VirtualFile getFileAfter() {
+ return myFileAfter;
+ }
+
+ public FileType getFileTypeBefore() {
+ return myFileTypeBefore;
+ }
+
+ public FileType getFileTypeAfter() {
+ return myFileTypeAfter;
}
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java
index 2f3788ae509c..77dd9b3f42b3 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/FragmentedDiffRequestFromChange.java
@@ -81,10 +81,7 @@ public class FragmentedDiffRequestFromChange {
}
List<BeforeAfter<TextRange>> ranges = calculator.getRanges();
if (ranges == null || ranges.isEmpty()) return null;
- FragmentedContent fragmentedContent = new FragmentedContent(calculator.getOldDocument(), calculator.getDocument(), ranges);
- final FileStatus fs = change.getFileStatus();
- fragmentedContent.setIsAddition(FileStatus.ADDED.equals(fs));
- fragmentedContent.setOneSide(FileStatus.ADDED.equals(fs) || FileStatus.DELETED.equals(fs));
+ FragmentedContent fragmentedContent = new FragmentedContent(calculator.getOldDocument(), calculator.getDocument(), ranges, change);
VirtualFile file = filePath.getVirtualFile();
if (file == null) {
filePath.hardRefresh();
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java
index 5c8ac2a6b623..b2eaa1f2e6e3 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesComponent.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.vcs.changes;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
@@ -27,6 +28,7 @@ import java.util.*;
public class IgnoredFilesComponent {
private final Set<IgnoredFileBean> myFilesToIgnore;
private final Map<String, IgnoredFileBean> myFilesMap;
+ private final Set<String> myDirectoriesManuallyRemovedFromIgnored;
public IgnoredFilesComponent(final Project project, final boolean registerListener) {
myFilesToIgnore = new LinkedHashSet<IgnoredFileBean>();
@@ -40,20 +42,53 @@ public class IgnoredFilesComponent {
}
});
}
+ myDirectoriesManuallyRemovedFromIgnored = new HashSet<String>();
}
public IgnoredFilesComponent(final IgnoredFilesComponent other) {
myFilesToIgnore = new LinkedHashSet<IgnoredFileBean>(other.myFilesToIgnore);
myFilesMap = new HashMap<String, IgnoredFileBean>(other.myFilesMap);
+ myDirectoriesManuallyRemovedFromIgnored = new HashSet<String>(other.myDirectoriesManuallyRemovedFromIgnored);
}
public void add(final IgnoredFileBean... filesToIgnore) {
- synchronized(myFilesToIgnore) {
+ synchronized (myFilesToIgnore) {
Collections.addAll(myFilesToIgnore, filesToIgnore);
addIgnoredFiles(filesToIgnore);
}
}
+ public Set<String> getDirectoriesManuallyRemovedFromIgnored() {
+ return Collections.unmodifiableSet(myDirectoriesManuallyRemovedFromIgnored);
+ }
+
+ public void setDirectoriesManuallyRemovedFromIgnored(Set<String> directories) {
+ myDirectoriesManuallyRemovedFromIgnored.clear();
+ myDirectoriesManuallyRemovedFromIgnored.addAll(directories);
+ }
+
+ public void addIgnoredDirectoryImplicitly(@NotNull String path, @NotNull Project project) {
+ synchronized (myFilesToIgnore) {
+ if (myDirectoriesManuallyRemovedFromIgnored.contains(path) || myDirectoriesManuallyRemovedFromIgnored.contains(path + "/")) {
+ return;
+ }
+ for (IgnoredFileBean bean : myFilesToIgnore) {
+ if (bean.getType() == IgnoreSettingsType.UNDER_DIR && FileUtil.isAncestor(bean.getPath(), path, false)) {
+ return;
+ }
+ }
+ List<IgnoredFileBean> toRemove = new ArrayList<IgnoredFileBean>();
+ for (IgnoredFileBean bean : myFilesToIgnore) {
+ if ((bean.getType() == IgnoreSettingsType.UNDER_DIR || bean.getType() == IgnoreSettingsType.FILE) &&
+ FileUtil.isAncestor(path, bean.getPath(), false)) {
+ toRemove.add(bean);
+ }
+ }
+ myFilesToIgnore.removeAll(toRemove);
+ myFilesToIgnore.add(IgnoredBeanFactory.ignoreUnderDirectory(path, project));
+ }
+ }
+
private void addIgnoredFiles(final IgnoredFileBean... filesToIgnore) {
for (IgnoredFileBean bean : filesToIgnore) {
if (IgnoreSettingsType.FILE.equals(bean.getType())) {
@@ -73,6 +108,7 @@ public class IgnoredFilesComponent {
myFilesMap.clear();
}
}
+
public boolean isEmpty() {
synchronized (myFilesToIgnore) {
return myFilesToIgnore.isEmpty();
@@ -80,7 +116,7 @@ public class IgnoredFilesComponent {
}
public void set(final IgnoredFileBean... filesToIgnore) {
- synchronized(myFilesToIgnore) {
+ synchronized (myFilesToIgnore) {
myFilesToIgnore.clear();
Collections.addAll(myFilesToIgnore, filesToIgnore);
myFilesMap.clear();
@@ -89,7 +125,7 @@ public class IgnoredFilesComponent {
}
public IgnoredFileBean[] getFilesToIgnore() {
- synchronized(myFilesToIgnore) {
+ synchronized (myFilesToIgnore) {
return myFilesToIgnore.toArray(new IgnoredFileBean[myFilesToIgnore.size()]);
}
}
@@ -103,14 +139,14 @@ public class IgnoredFilesComponent {
}
public boolean isIgnoredFile(@NotNull VirtualFile file) {
- synchronized(myFilesToIgnore) {
+ synchronized (myFilesToIgnore) {
if (myFilesToIgnore.size() == 0) return false;
final String path = FilePathsHelper.convertPath(file);
final IgnoredFileBean fileBean = myFilesMap.get(path);
if (fileBean != null && fileBean.matchesFile(file)) return true;
- for(IgnoredFileBean bean: myFilesToIgnore) {
+ for (IgnoredFileBean bean : myFilesToIgnore) {
if (bean.matchesFile(file)) return true;
}
return false;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LocalChangeListImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LocalChangeListImpl.java
index c413cca246c3..1d310d5a023a 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LocalChangeListImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/LocalChangeListImpl.java
@@ -1,14 +1,13 @@
package com.intellij.openapi.vcs.changes;
-import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.OpenTHashSet;
@@ -147,12 +146,11 @@ public class LocalChangeListImpl extends LocalChangeList {
createReadChangesCache();
final Collection<Change> result = new ArrayList<Change>();
myChangesBeforeUpdate = new OpenTHashSet<Change>(myChanges);
- final FileIndexFacade fileIndex = PeriodicalTasksCloser.getInstance().safeGetService(project, FileIndexFacade.class);
for (Change oldBoy : myChangesBeforeUpdate) {
final ContentRevision before = oldBoy.getBeforeRevision();
final ContentRevision after = oldBoy.getAfterRevision();
if (scope == null || before != null && scope.belongsTo(before.getFile()) || after != null && scope.belongsTo(after.getFile())
- || isIgnoredChange(oldBoy, fileIndex)) {
+ || isIgnoredChange(oldBoy, project)) {
result.add(oldBoy);
myChanges.remove(oldBoy);
myReadChangesCache = null;
@@ -161,18 +159,21 @@ public class LocalChangeListImpl extends LocalChangeList {
return result;
}
- private static boolean isIgnoredChange(final Change change, final FileIndexFacade fileIndex) {
- boolean beforeRevIgnored = change.getBeforeRevision() == null || isIgnoredRevision(change.getBeforeRevision(), fileIndex);
- boolean afterRevIgnored = change.getAfterRevision() == null || isIgnoredRevision(change.getAfterRevision(), fileIndex);
+ private static boolean isIgnoredChange(@NotNull Change change, @NotNull Project project) {
+ boolean beforeRevIgnored = change.getBeforeRevision() == null || isIgnoredRevision(change.getBeforeRevision(), project);
+ boolean afterRevIgnored = change.getAfterRevision() == null || isIgnoredRevision(change.getAfterRevision(), project);
return beforeRevIgnored && afterRevIgnored;
}
- private static boolean isIgnoredRevision(final ContentRevision revision, final FileIndexFacade fileIndex) {
+ private static boolean isIgnoredRevision(final @NotNull ContentRevision revision, final @NotNull Project project) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
+ if (project.isDisposed()) {
+ return false;
+ }
VirtualFile vFile = revision.getFile().getVirtualFile();
- return vFile != null && fileIndex.isExcludedFile(vFile);
+ return vFile != null && ProjectLevelVcsManager.getInstance(project).isIgnored(vFile);
}
});
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java
index 2c2d0634b709..6e8a1a04d135 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java
@@ -18,6 +18,8 @@ package com.intellij.openapi.vcs.changes;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.SimpleContent;
+import com.intellij.openapi.diff.impl.DiffHighlighterFactory;
+import com.intellij.openapi.diff.impl.DiffHighlighterFactoryImpl;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.highlighter.*;
@@ -35,6 +37,7 @@ import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.impl.ContentRevisionCache;
+import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.BeforeAfter;
import com.intellij.util.Consumer;
@@ -140,6 +143,9 @@ public class PreparedFragmentedContent {
fragmentedContent.getBefore(), fragmentedContent.getAfter());
// add "artificial" empty lines
+ final Document document = fragmentedContent.getBefore();
+ final Document document1 = fragmentedContent.getAfter();
+
// line starts
BeforeAfter<Integer> lines = new BeforeAfter<Integer>(0, 0);
for (BeforeAfter<TextRange> lineNumbers : expandedRanges) {
@@ -155,7 +161,6 @@ public class PreparedFragmentedContent {
oldConvertor.put(lines.getBefore(), lineNumbers.getBefore().getStartOffset());
newConvertor.put(lines.getAfter(), lineNumbers.getAfter().getStartOffset());
- final Document document = fragmentedContent.getBefore();
if (sbOld.length() > 0) {
sbOld.append('\n');
}
@@ -164,7 +169,6 @@ public class PreparedFragmentedContent {
myBeforeFragments.add(beforeRange);
sbOld.append(document.getText(beforeRange));
- final Document document1 = fragmentedContent.getAfter();
if (sbNew.length() > 0) {
sbNew.append('\n');
}
@@ -180,7 +184,23 @@ public class PreparedFragmentedContent {
myLineRanges.add(new BeforeAfter<Integer>(lines.getBefore() == 0 ? 0 : lines.getBefore() - 1,
lines.getAfter() == 0 ? 0 : lines.getAfter() - 1));
- setHighlighters(fragmentedContent.getBefore(), fragmentedContent.getAfter(), expandedRanges);
+ if (!expandedRanges.isEmpty()) {
+ BeforeAfter<TextRange> last = expandedRanges.get(expandedRanges.size() - 1);
+ if (sbOld.length() > 0) {
+ if (document.getLineEndOffset(last.getBefore().getEndOffset()) != document.getTextLength()) {
+ sbOld.append('\n');
+ oldConvertor.emptyLine(lines.getBefore());
+ }
+ }
+ if (sbNew.length() > 0) {
+ if (document1.getLineEndOffset(last.getAfter().getEndOffset()) != document1.getTextLength()) {
+ sbNew.append('\n');
+ newConvertor.emptyLine(lines.getAfter());
+ }
+ }
+ }
+
+ setHighlighters(fragmentedContent.getBefore(), fragmentedContent.getAfter(), expandedRanges, fragmentedContent);
setTodoHighlighting(fragmentedContent.getBefore(), fragmentedContent.getAfter());
}
});
@@ -323,29 +343,37 @@ public class PreparedFragmentedContent {
}
private void setHighlighters(final Document oldDocument, final Document document,
- List<BeforeAfter<TextRange>> ranges) {
- EditorHighlighterFactory editorHighlighterFactory = EditorHighlighterFactory.getInstance();
- final SyntaxHighlighter syntaxHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(myFileType, myProject, null);
- final EditorHighlighter highlighter =
- editorHighlighterFactory.createEditorHighlighter(syntaxHighlighter, EditorColorsManager.getInstance().getGlobalScheme());
-
+ List<BeforeAfter<TextRange>> ranges, FragmentedContent fragmentedContent) {
+ EditorHighlighter highlighter = createHighlighter(fragmentedContent.getFileTypeBefore(),
+ fragmentedContent.getFileBefore(),
+ fragmentedContent.getFileAfter(), myProject).createHighlighter();
highlighter.setEditor(new LightHighlighterClient(oldDocument, myProject));
highlighter.setText(oldDocument.getText());
HighlighterIterator iterator = highlighter.createIterator(ranges.get(0).getBefore().getStartOffset());
- FragmentedEditorHighlighter beforeHighlighter =
- new FragmentedEditorHighlighter(iterator, getBeforeFragments(), 1, true);
+ FragmentedEditorHighlighter beforeHighlighter = new FragmentedEditorHighlighter(iterator, getBeforeFragments(), 1, true);
setBeforeHighlighter(beforeHighlighter);
- final EditorHighlighter highlighter1 =
- editorHighlighterFactory.createEditorHighlighter(syntaxHighlighter, EditorColorsManager.getInstance().getGlobalScheme());
+ EditorHighlighter highlighter1 = createHighlighter(fragmentedContent.getFileTypeAfter(),
+ fragmentedContent.getFileAfter(),
+ fragmentedContent.getFileBefore(), myProject).createHighlighter();
highlighter1.setEditor(new LightHighlighterClient(document, myProject));
highlighter1.setText(document.getText());
HighlighterIterator iterator1 = highlighter1.createIterator(ranges.get(0).getAfter().getStartOffset());
- FragmentedEditorHighlighter afterHighlighter =
- new FragmentedEditorHighlighter(iterator1, getAfterFragments(), 1, true);
+ FragmentedEditorHighlighter afterHighlighter = new FragmentedEditorHighlighter(iterator1, getAfterFragments(), 1, true);
setAfterHighlighter(afterHighlighter);
}
+ private DiffHighlighterFactory createHighlighter(FileType contentType,
+ VirtualFile file,
+ VirtualFile otherFile,
+ Project project) {
+ VirtualFile baseFile = file;
+ if (baseFile == null) baseFile = otherFile;
+ if (contentType == null) contentType = myFileType;
+
+ return new DiffHighlighterFactoryImpl(contentType, baseFile, project);
+ }
+
private void setTodoHighlighting(final Document oldDocument, final Document document) {
final ContentRevisionCache cache = ProjectLevelVcsManager.getInstance(myProject).getContentRevisionCache();
final List<Pair<TextRange,TextAttributes>> beforeTodoRanges = myBeforeNumber == null ? Collections.<Pair<TextRange,TextAttributes>>emptyList() :
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java
index fdc079641b68..d06c8f888ad7 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdatingChangeListBuilder.java
@@ -15,16 +15,15 @@
*/
package com.intellij.openapi.vcs.changes;
-import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypeManager;
-import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FilePathImpl;
+import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.Nullable;
@@ -40,7 +39,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
private VcsDirtyScope myScope;
private FoldersCutDownWorker myFoldersCutDownWorker;
private final IgnoredFilesComponent myIgnoredFilesComponent;
- private final FileIndexFacade myIndex;
+ private final ProjectLevelVcsManager myVcsManager;
private final ChangeListManagerGate myGate;
private Factory<JComponent> myAdditionalInfo;
@@ -53,7 +52,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
myDisposedGetter = disposedGetter;
myIgnoredFilesComponent = ignoredFilesComponent;
myGate = gate;
- myIndex = PeriodicalTasksCloser.getInstance().safeGetService(changeListWorker.getProject(), FileIndexFacade.class);
+ myVcsManager = ProjectLevelVcsManager.getInstance(changeListWorker.getProject());
}
private void checkIfDisposed() {
@@ -117,12 +116,12 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
myChangeListWorker.removeRegisteredChangeFor(path);
}
- private boolean isExcluded(final VirtualFile file) {
+ private boolean isIgnoredByVcs(final VirtualFile file) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
checkIfDisposed();
- return myIndex.isExcludedFile(file);
+ return myVcsManager.isIgnored(file);
}
});
}
@@ -133,7 +132,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
}
if (file == null) return;
checkIfDisposed();
- if (isExcluded(file)) return;
+ if (isIgnoredByVcs(file)) return;
if (myScope.belongsTo(new FilePathImpl(file))) {
if (myIgnoredFilesComponent.isIgnoredFile(file)) {
myComposite.getIgnoredFileHolder().addFile(file);
@@ -165,7 +164,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
public void processModifiedWithoutCheckout(final VirtualFile file) {
if (file == null) return;
checkIfDisposed();
- if (isExcluded(file)) return;
+ if (isIgnoredByVcs(file)) return;
if (myScope.belongsTo(new FilePathImpl(file))) {
if (LOG.isDebugEnabled()) {
LOG.debug("processModifiedWithoutCheckout " + file);
@@ -177,7 +176,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
public void processIgnoredFile(final VirtualFile file) {
if (file == null) return;
checkIfDisposed();
- if (isExcluded(file)) return;
+ if (isIgnoredByVcs(file)) return;
if (myScope.belongsTo(new FilePathImpl(file))) {
IgnoredFilesHolder ignoredFilesHolder = myComposite.getIgnoredFileHolder();
if (ignoredFilesHolder instanceof IgnoredFilesCompositeHolder) {
@@ -212,7 +211,7 @@ class UpdatingChangeListBuilder implements ChangelistBuilder {
public void processSwitchedFile(final VirtualFile file, final String branch, final boolean recursive) {
if (file == null) return;
checkIfDisposed();
- if (isExcluded(file)) return;
+ if (isIgnoredByVcs(file)) return;
if (myScope.belongsTo(new FilePathImpl(file))) {
myChangeListWorker.addSwitched(file, branch, recursive);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java
index eb44d591d605..c8617dc5f347 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeImpl.java
@@ -34,6 +34,7 @@ import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.MultiMap;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -75,14 +76,14 @@ public class VcsDirtyScopeImpl extends VcsModifiableDirtyScope {
return ContainerUtil.concatIterators(iteratorList);
}
- @Nullable
+ @NotNull
@Override
public Iterator<FilePath> getDirtyDirectoriesIterator(final VirtualFile root) {
final THashSet<FilePath> filePaths = myDirtyDirectoriesRecursively.get(root);
if (filePaths != null) {
return filePaths.iterator();
}
- return null;
+ return ContainerUtil.emptyIterator();
}
@Override
@@ -338,10 +339,8 @@ public class VcsDirtyScopeImpl extends VcsModifiableDirtyScope {
}
/**
- * Add dirty file to the scope. Note that file is not added
- * if its ancestor was added as dirty recursively or if its parent
- * is in already in the dirty scope. Also immendiate non-directory
- * children are removed from the set of dirty files.
+ * Add dirty file to the scope. Note that file is not added if its ancestor was added as dirty recursively or if its parent is in already
+ * in the dirty scope. Also immediate non-directory children are removed from the set of dirty files.
*
* @param newcomer a file or directory added to the dirty scope.
*/
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsGuess.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsGuess.java
index 00ca9f2ebf4f..112caa4a40b4 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsGuess.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsGuess.java
@@ -73,7 +73,7 @@ public class VcsGuess {
final boolean inContent = myVcsManager.isFileInContent(validParent);
if (inContent) return true;
if (filePath != null) {
- return isFileInBaseDir(filePath, myProject.getBaseDir()) && !myExcludedFileIndex.isExcludedFile(validParent);
+ return isFileInBaseDir(filePath, myProject.getBaseDir()) && !myVcsManager.isIgnored(validParent);
}
return false;
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ConflictedDiffRequestPresentable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ConflictedDiffRequestPresentable.java
index 02586bba5e78..f70c84405c2d 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ConflictedDiffRequestPresentable.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/ConflictedDiffRequestPresentable.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.DiffRequestFactory;
import com.intellij.openapi.diff.MergeRequest;
import com.intellij.openapi.diff.SimpleDiffRequest;
+import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.io.FileUtil;
@@ -60,6 +61,7 @@ public class ConflictedDiffRequestPresentable implements DiffRequestPresentable
public MyResult step(DiffChainContext context) {
if (myChange.getAfterRevision() == null) return createErrorResult();
final Getter<MergeTexts> mergeProvider = myChange.getMergeProvider();
+ FileType type = myChange.getVirtualFile() != null ? myChange.getVirtualFile().getFileType() : null;
if (mergeProvider != null) {
// guaranteed text
final MergeTexts texts = mergeProvider.get();
@@ -67,7 +69,7 @@ public class ConflictedDiffRequestPresentable implements DiffRequestPresentable
return createErrorResult();
}
final MergeRequest request = DiffRequestFactory.getInstance()
- .create3WayDiffRequest(texts.getLeft(), texts.getRight(), texts.getBase(), myProject, null, null);
+ .create3WayDiffRequest(texts.getLeft(), texts.getRight(), texts.getBase(), type, myProject, null, null);
request.setWindowTitle(FileUtil.toSystemDependentName(myFile.getPresentableUrl()));
// todo titles?
request.setVersionTitles(new String[] {myChange.getAfterRevision().getRevisionNumber().asString(),
@@ -95,7 +97,8 @@ public class ConflictedDiffRequestPresentable implements DiffRequestPresentable
final MergeRequest request = DiffRequestFactory.getInstance()
.create3WayDiffRequest(CharsetToolkit.bytesToString(mergeData.CURRENT, charset),
CharsetToolkit.bytesToString(mergeData.LAST, charset),
- CharsetToolkit.bytesToString(mergeData.ORIGINAL, charset), myProject, null, null);
+ CharsetToolkit.bytesToString(mergeData.ORIGINAL, charset),
+ type, myProject, null, null);
request.setWindowTitle(FileUtil.toSystemDependentName(myFile.getPresentableUrl()));
// todo titles?
VcsRevisionNumber lastRevisionNumber = mergeData.LAST_REVISION_NUMBER;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java
index 6b4a3fb2c390..f7fbe4c9980d 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java
@@ -325,7 +325,7 @@ public class ApplyPatchAction extends DumbAwareAction {
MergeRequest request;
if (myReadOnly) {
request = DiffRequestFactory.getInstance()
- .create3WayDiffRequest(leftText, rightText, originalContent, project, null, null);
+ .create3WayDiffRequest(leftText, rightText, originalContent, file.getFileType(), project, null, null);
} else {
request = DiffRequestFactory.getInstance().createMergeRequest(reverse ? rightText : leftText,
reverse ? leftText : rightText, originalContent,
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java
index 05b4e95b8672..a3ddc2ba450d 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/MergedDiffRequestPresentable.java
@@ -58,7 +58,10 @@ public class MergedDiffRequestPresentable implements DiffRequestPresentable {
return new MyResult(badDiffRequest, DiffPresentationReturnValue.useRequest);
}
final MergeRequest request = DiffRequestFactory.getInstance()
- .create3WayDiffRequest(revisionTexts.getLocal().toString(), revisionTexts.getPatched(), revisionTexts.getBase().toString(), myProject, null, null);
+ .create3WayDiffRequest(revisionTexts.getLocal().toString(),
+ revisionTexts.getPatched(),
+ revisionTexts.getBase().toString(),
+ filePath.getFileType(), myProject, null, null);
request.setWindowTitle(VcsBundle.message("patch.apply.conflict.title", FileUtil.toSystemDependentName(myFile.getPresentableUrl())));
request.setVersionTitles(new String[] {"Current Version", "Base Version", FileUtil.toSystemDependentName(myAfterTitle)});
return new MyResult(request, DiffPresentationReturnValue.useRequest);
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java
index fe9c12036596..ee3390390f06 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/FilePathChangesTreeList.java
@@ -24,13 +24,11 @@ import javax.swing.tree.DefaultTreeModel;
import java.util.List;
public class FilePathChangesTreeList extends ChangesTreeList<FilePath> {
- private final Project myProject;
public FilePathChangesTreeList(@NotNull Project project, @NotNull List<FilePath> originalFiles,
boolean showCheckboxes, boolean highlightProblems,
@Nullable Runnable inclusionListener, @Nullable ChangeNodeDecorator nodeDecorator) {
super(project, originalFiles, showCheckboxes, highlightProblems, inclusionListener, nodeDecorator);
- myProject = project;
}
protected DefaultTreeModel buildTreeModel(final List<FilePath> changes, ChangeNodeDecorator changeNodeDecorator) {
@@ -43,10 +41,7 @@ public class FilePathChangesTreeList extends ChangesTreeList<FilePath> {
@Nullable
protected FilePath getLeadSelectedObject(final ChangesBrowserNode node) {
- final Object userObject = node.getUserObject();
- if (userObject instanceof FilePath) {
- return (FilePath) userObject;
- }
- return null;
+ Object userObject = node.getUserObject();
+ return userObject instanceof FilePath ? (FilePath)userObject : null;
}
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/IgnoredSettingsPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/IgnoredSettingsPanel.java
index 82b676a8834d..6edfbb96c848 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/IgnoredSettingsPanel.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/IgnoredSettingsPanel.java
@@ -27,7 +27,8 @@ import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vcs.VcsBundle;
-import com.intellij.openapi.vcs.changes.ChangeListManager;
+import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
+import com.intellij.openapi.vcs.changes.IgnoreSettingsType;
import com.intellij.openapi.vcs.changes.IgnoredFileBean;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
@@ -37,13 +38,16 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
+import java.util.HashSet;
+import java.util.Set;
public class IgnoredSettingsPanel implements SearchableConfigurable, Configurable.NoScroll {
private JBList myList;
private JPanel myPanel;
private final Project myProject;
private DefaultListModel myModel;
- private final ChangeListManager myChangeListManager;
+ private final ChangeListManagerImpl myChangeListManager;
+ private final Set<String> myDirectoriesManuallyRemovedFromIgnored = new HashSet<String>();
public IgnoredSettingsPanel(Project project) {
myList = new JBList();
@@ -51,7 +55,7 @@ public class IgnoredSettingsPanel implements SearchableConfigurable, Configurabl
myList.getEmptyText().setText(VcsBundle.message("no.ignored.files"));
myProject = project;
- myChangeListManager = ChangeListManager.getInstance(myProject);
+ myChangeListManager = ChangeListManagerImpl.getInstanceImpl(myProject);
}
private void setItems(final IgnoredFileBean[] filesToIgnore) {
@@ -97,32 +101,30 @@ public class IgnoredSettingsPanel implements SearchableConfigurable, Configurabl
}
private void deleteItems() {
- boolean contigiousSelection = true;
- int minSelectionIndex = myList.getSelectionModel().getMinSelectionIndex();
- int maxSelectionIndex = myList.getSelectionModel().getMaxSelectionIndex();
- for (int i = minSelectionIndex; i <= maxSelectionIndex; i++) {
- if (!myList.getSelectionModel().isSelectedIndex(i)) {
- contigiousSelection = false;
- break;
- }
- }
- if (contigiousSelection) {
- myModel.removeRange(minSelectionIndex, maxSelectionIndex);
- }
- else {
- final Object[] selection = myList.getSelectedValues();
- for (Object item : selection) {
- myModel.removeElement(item);
+ for (Object o : myList.getSelectedValues()) {
+ IgnoredFileBean bean = (IgnoredFileBean)o;
+ if (bean.getType() == IgnoreSettingsType.UNDER_DIR) {
+ myDirectoriesManuallyRemovedFromIgnored.add(bean.getPath());
}
}
+ ListUtil.removeSelectedItems(myList);
}
public void reset() {
setItems(myChangeListManager.getFilesToIgnore());
+ myDirectoriesManuallyRemovedFromIgnored.clear();
+ myDirectoriesManuallyRemovedFromIgnored.addAll(myChangeListManager.getIgnoredFilesComponent().getDirectoriesManuallyRemovedFromIgnored());
}
public void apply() {
- myChangeListManager.setFilesToIgnore(getItems());
+ IgnoredFileBean[] toIgnore = getItems();
+ myChangeListManager.setFilesToIgnore(toIgnore);
+ for (IgnoredFileBean bean : toIgnore) {
+ if (bean.getType() == IgnoreSettingsType.UNDER_DIR) {
+ myDirectoriesManuallyRemovedFromIgnored.remove(bean.getPath());
+ }
+ }
+ myChangeListManager.getIgnoredFilesComponent().setDirectoriesManuallyRemovedFromIgnored(myDirectoriesManuallyRemovedFromIgnored);
}
public boolean isModified() {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java
index 6f1cd15ef018..d332d1faa792 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java
@@ -160,11 +160,16 @@ public class LineStatusTrackerDrawing {
localShowPrevAction.copyFrom(globalShowPrevAction);
final RollbackLineStatusRangeAction rollback = new RollbackLineStatusRangeAction(tracker, range, editor);
- EmptyAction.setupAction(rollback, IdeActions.SELECTED_CHANGES_ROLLBACK, editorComponent);
+ final ShowLineStatusRangeDiffAction showDiff = new ShowLineStatusRangeDiffAction(tracker, range, editor);
+ final CopyLineStatusRangeAction copyRange = new CopyLineStatusRangeAction(tracker, range);
+
group.add(rollback);
+ group.add(showDiff);
+ group.add(copyRange);
- group.add(new ShowLineStatusRangeDiffAction(tracker, range, editor));
- group.add(new CopyLineStatusRangeAction(tracker, range));
+ EmptyAction.setupAction(rollback, IdeActions.SELECTED_CHANGES_ROLLBACK, editorComponent);
+ EmptyAction.setupAction(showDiff, "ChangesView.Diff", editorComponent);
+ EmptyAction.setupAction(copyRange, IdeActions.ACTION_COPY, editorComponent);
final JComponent toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.FILEHISTORY_VIEW_TOOLBAR, group, true).getComponent();
@@ -221,6 +226,8 @@ public class LineStatusTrackerDrawing {
HintListener closeListener = new HintListener() {
public void hintHidden(final EventObject event) {
actionList.remove(rollback);
+ actionList.remove(showDiff);
+ actionList.remove(copyRange);
actionList.remove(localShowPrevAction);
actionList.remove(localShowNextAction);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusAction.java
index 59697f1222dd..6e08d90a3b5d 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusAction.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RollbackLineStatusAction.java
@@ -13,6 +13,7 @@
package com.intellij.openapi.vcs.ex;
import com.intellij.icons.AllIcons;
+import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationManager;
@@ -32,7 +33,9 @@ import java.util.List;
public class RollbackLineStatusAction extends DumbAwareAction {
public RollbackLineStatusAction() {
- super("Rollback", "Rollback selected changes", AllIcons.Actions.Reset);
+ super(ActionsBundle.actionText("Vcs.RollbackChangedLines"),
+ ActionsBundle.actionDescription("Vcs.RollbackChangedLines"),
+ AllIcons.Actions.Reset);
}
@Override
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/BaseDiffFromHistoryHandler.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/BaseDiffFromHistoryHandler.java
new file mode 100644
index 000000000000..8a16ba6a481f
--- /dev/null
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/BaseDiffFromHistoryHandler.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.vcs.history;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogBuilder;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vcs.changes.ui.ChangesBrowser;
+import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public abstract class BaseDiffFromHistoryHandler<T extends VcsFileRevision> implements DiffFromHistoryHandler {
+
+ private static final Logger LOG = Logger.getInstance(BaseDiffFromHistoryHandler.class);
+
+ @NotNull protected final Project myProject;
+
+ protected BaseDiffFromHistoryHandler(@NotNull Project project) {
+ myProject = project;
+ }
+
+ @Override
+ public void showDiffForOne(@NotNull AnActionEvent e,
+ @NotNull FilePath filePath,
+ @NotNull VcsFileRevision previousRevision,
+ @NotNull VcsFileRevision revision) {
+ doShowDiff(filePath, previousRevision, revision, false);
+ }
+
+ @Override
+ public void showDiffForTwo(@NotNull FilePath filePath, @NotNull VcsFileRevision revision1, @NotNull VcsFileRevision revision2) {
+ doShowDiff(filePath, revision1, revision2, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void doShowDiff(@NotNull FilePath filePath,
+ @NotNull VcsFileRevision revision1,
+ @NotNull VcsFileRevision revision2,
+ boolean autoSort) {
+ if (!filePath.isDirectory()) {
+ VcsHistoryUtil.showDifferencesInBackground(myProject, filePath, revision1, revision2, autoSort);
+ }
+ else if (revision1.equals(VcsFileRevision.NULL)) {
+ T right = (T)revision2;
+ showAffectedChanges(filePath, right);
+ }
+ else if (revision2 instanceof CurrentRevision) {
+ T left = (T)revision1;
+ showChangesBetweenRevisions(filePath, left, null);
+ }
+ else {
+ T left = (T)revision1;
+ T right = (T)revision2;
+ if (autoSort) {
+ Couple<VcsFileRevision> pair = VcsHistoryUtil.sortRevisions(revision1, revision2);
+ left = (T)pair.first;
+ right = (T)pair.second;
+ }
+ showChangesBetweenRevisions(filePath, left, right);
+ }
+ }
+
+ protected void showChangesBetweenRevisions(@NotNull final FilePath path, @NotNull final T rev1, @Nullable final T rev2) {
+ new CollectChangesTask("Comparing revisions...") {
+
+ @NotNull
+ @Override
+ public List<Change> getChanges() throws VcsException {
+ return getChangesBetweenRevisions(path, rev1, rev2);
+ }
+
+ @NotNull
+ @Override
+ public String getDialogTitle() {
+ return getChangesBetweenRevisionsDialogTitle(path, rev1, rev2);
+ }
+ }.queue();
+ }
+
+ protected void showAffectedChanges(@NotNull final FilePath path, @NotNull final T rev) {
+ new CollectChangesTask("Collecting affected changes...") {
+
+ @NotNull
+ @Override
+ public List<Change> getChanges() throws VcsException {
+ return getAffectedChanges(path, rev);
+ }
+
+ @NotNull
+ @Override
+ public String getDialogTitle() {
+ return getAffectedChangesDialogTitle(path, rev);
+ }
+ }.queue();
+ }
+
+ // rev2 == null -> compare rev1 with local
+ // rev2 != null -> compare rev1 with rev2
+ @NotNull
+ protected abstract List<Change> getChangesBetweenRevisions(@NotNull final FilePath path, @NotNull final T rev1, @Nullable final T rev2)
+ throws VcsException;
+
+ @NotNull
+ protected abstract List<Change> getAffectedChanges(@NotNull final FilePath path, @NotNull final T rev) throws VcsException;
+
+ @NotNull
+ protected abstract String getPresentableName(@NotNull T revision);
+
+ protected void showChangesDialog(@NotNull String title, @NotNull List<Change> changes) {
+ DialogBuilder dialogBuilder = new DialogBuilder(myProject);
+
+ dialogBuilder.setTitle(title);
+ dialogBuilder.setActionDescriptors(new DialogBuilder.ActionDescriptor[]{new DialogBuilder.CloseDialogAction()});
+ final ChangesBrowser changesBrowser =
+ new ChangesBrowser(myProject, null, changes, null, false, true, null, ChangesBrowser.MyUseCase.COMMITTED_CHANGES, null);
+ changesBrowser.setChangesToDisplay(changes);
+ dialogBuilder.setCenterPanel(changesBrowser);
+ dialogBuilder.showNotModal();
+ }
+
+ protected void showError(@NotNull VcsException e, @NotNull String logMessage) {
+ LOG.info(logMessage, e);
+ VcsBalloonProblemNotifier.showOverVersionControlView(myProject, e.getMessage(), MessageType.ERROR);
+ }
+
+ @NotNull
+ protected String getChangesBetweenRevisionsDialogTitle(@NotNull final FilePath path, @NotNull final T rev1, @Nullable final T rev2) {
+ String rev1Title = getPresentableName(rev1);
+
+ return rev2 != null
+ ? String.format("Difference between %s and %s in %s", rev1Title, getPresentableName(rev2), path.getName())
+ : String.format("Difference between %s and local version in %s", rev1Title, path.getName());
+ }
+
+ @NotNull
+ protected String getAffectedChangesDialogTitle(@NotNull final FilePath path, @NotNull final T rev) {
+ return String.format("Initial commit %s in %s", getPresentableName(rev), path.getName());
+ }
+
+ protected abstract class CollectChangesTask extends Task.Backgroundable {
+
+ private List<Change> myChanges;
+
+ public CollectChangesTask(@NotNull String title) {
+ super(BaseDiffFromHistoryHandler.this.myProject, title);
+ }
+
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ try {
+ myChanges = getChanges();
+ }
+ catch (VcsException e) {
+ showError(e, "Error during task: " + getDialogTitle());
+ }
+ }
+
+ @NotNull
+ public abstract List<Change> getChanges() throws VcsException;
+
+ @NotNull
+ public abstract String getDialogTitle();
+
+ @Override
+ public void onSuccess() {
+ showChangesDialog(getDialogTitle(), ContainerUtil.notNullize(myChanges));
+ }
+ }
+}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultFileIndexFacade.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultFileIndexFacade.java
index a63bbdbf0a69..d4063478d373 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultFileIndexFacade.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultFileIndexFacade.java
@@ -66,6 +66,11 @@ public class DefaultFileIndexFacade extends FileIndexFacade {
}
@Override
+ public boolean isUnderIgnored(@NotNull VirtualFile file) {
+ return false;
+ }
+
+ @Override
public Module getModuleForFile(@NotNull VirtualFile file) {
return null;
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java
index 5cc3a8a9ca92..e699383321ae 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/ProjectLevelVcsManagerImpl.java
@@ -132,7 +132,7 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme
myBackgroundableActionHandlerMap = new EnumMap<VcsBackgroundableActions, BackgroundableActionEnabledHandler>(VcsBackgroundableActions.class);
myInitialization = new VcsInitialization(myProject);
- myMappings = new NewMappings(myProject, myMessageBus, this, manager, excludedFileIndex);
+ myMappings = new NewMappings(myProject, myMessageBus, this, manager);
myMappingsToRoots = new MappingsToRoots(myMappings, myProject);
if (!myProject.isDefault()) {
@@ -843,12 +843,24 @@ public class ProjectLevelVcsManagerImpl extends ProjectLevelVcsManagerEx impleme
@Override
public Boolean compute() {
return vf != null && (myExcludedIndex.isInContent(vf) || isFileInBaseDir(vf) || vf.equals(myProject.getBaseDir()) ||
- hasExplicitMapping(vf) || isInDirectoryBasedRoot(vf)) && !myExcludedIndex.isExcludedFile(vf);
+ hasExplicitMapping(vf) || isInDirectoryBasedRoot(vf)
+ || !Registry.is("ide.hide.excluded.files") && myExcludedIndex.isExcludedFile(vf))
+ && !isIgnored(vf);
}
});
}
@Override
+ public boolean isIgnored(VirtualFile vf) {
+ if (Registry.is("ide.hide.excluded.files")) {
+ return myExcludedIndex.isExcludedFile(vf);
+ }
+ else {
+ return myExcludedIndex.isUnderIgnored(vf);
+ }
+ }
+
+ @Override
public boolean dvcsUsedInProject() {
AbstractVcs[] allActiveVcss = getAllActiveVcss();
for (AbstractVcs activeVcs : allActiveVcss) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java
index 122988896cb2..cfddcaa3e65d 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/VcsRootIterator.java
@@ -36,14 +36,17 @@ public class VcsRootIterator {
// folder path to files to be excluded
private final Map<String, MyRootFilter> myOtherVcsFolders;
private final FileIndexFacade myExcludedFileIndex;
+ private final ProjectLevelVcsManager myVcsManager;
+ private final Project myProject;
public VcsRootIterator(final Project project, final AbstractVcs vcs) {
- final ProjectLevelVcsManager plVcsManager = ProjectLevelVcsManager.getInstance(project);
+ myProject = project;
+ myVcsManager = ProjectLevelVcsManager.getInstance(project);
myOtherVcsFolders = new HashMap<String, MyRootFilter>();
myExcludedFileIndex = PeriodicalTasksCloser.getInstance().safeGetService(project, FileIndexFacade.class);
- final VcsRoot[] allRoots = plVcsManager.getAllVcsRoots();
- final VirtualFile[] roots = plVcsManager.getRootsUnderVcs(vcs);
+ final VcsRoot[] allRoots = myVcsManager.getAllVcsRoots();
+ final VirtualFile[] roots = myVcsManager.getRootsUnderVcs(vcs);
for (VirtualFile root : roots) {
final MyRootFilter rootPresentFilter = new MyRootFilter(root, vcs.getName());
rootPresentFilter.init(allRoots);
@@ -57,14 +60,14 @@ public class VcsRootIterator {
if ((rootFilter != null) && (!rootFilter.accept(file))) {
return false;
}
- return !isExcluded(myExcludedFileIndex, file);
+ return !isIgnoredByVcs(myVcsManager, myProject, file);
}
- private static boolean isExcluded(final FileIndexFacade indexFacade, final VirtualFile file) {
+ private static boolean isIgnoredByVcs(final ProjectLevelVcsManager vcsManager, final Project project, final VirtualFile file) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
- return indexFacade.isExcludedFile(file);
+ return !project.isDisposed() && vcsManager.isIgnored(file);
}
});
}
@@ -140,7 +143,7 @@ public class VcsRootIterator {
@Nullable private final VirtualFileFilter myDirectoryFilter;
private final VirtualFile myRoot;
private final MyRootFilter myRootPresentFilter;
- private final FileIndexFacade myExcludedFileIndex;
+ private final ProjectLevelVcsManager myVcsManager;
private MyRootIterator(final Project project,
final VirtualFile root,
@@ -153,13 +156,12 @@ public class VcsRootIterator {
myDirectoryFilter = directoryFilter;
myRoot = root;
- final ProjectLevelVcsManager plVcsManager = ProjectLevelVcsManager.getInstance(project);
- final AbstractVcs vcs = plVcsManager.getVcsFor(root);
- myRootPresentFilter = (vcs == null) ? null : new MyRootFilter(root, vcs.getName());
+ myVcsManager = ProjectLevelVcsManager.getInstance(project);
+ final AbstractVcs vcs = myVcsManager.getVcsFor(root);
+ myRootPresentFilter = vcs == null ? null : new MyRootFilter(root, vcs.getName());
if (myRootPresentFilter != null) {
- myRootPresentFilter.init(ProjectLevelVcsManager.getInstance(myProject).getAllVcsRoots());
+ myRootPresentFilter.init(myVcsManager.getAllVcsRoots());
}
- myExcludedFileIndex = PeriodicalTasksCloser.getInstance().safeGetService(project, FileIndexFacade.class);
}
public void iterate() {
@@ -174,7 +176,7 @@ public class VcsRootIterator {
@NotNull
@Override
public Result visitFileEx(@NotNull VirtualFile file) {
- if (isExcluded(myExcludedFileIndex, file)) return SKIP_CHILDREN;
+ if (isIgnoredByVcs(myVcsManager, myProject, file)) return SKIP_CHILDREN;
if (myRootPresentFilter != null && !myRootPresentFilter.accept(file)) return SKIP_CHILDREN;
if (myProject.isDisposed() || !process(file)) return skipTo(myRoot);
if (myDirectoryFilter != null && file.isDirectory() && !myDirectoryFilter.shouldGoIntoDirectory(file)) return SKIP_CHILDREN;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java
index 32fe920fc4db..5ff541ebc67d 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/projectlevelman/NewMappings.java
@@ -19,7 +19,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.Pair;
@@ -52,18 +51,18 @@ public class NewMappings {
private final DefaultVcsRootPolicy myDefaultVcsRootPolicy;
private final MessageBus myMessageBus;
+ private final ProjectLevelVcsManager myVcsManager;
private final FileStatusManager myFileStatusManager;
- private final FileIndexFacade myFileIndexFacade;
private final Project myProject;
private boolean myActivated;
- public NewMappings(final Project project, final MessageBus messageBus,
- final ProjectLevelVcsManagerImpl vcsManager, FileStatusManager fileStatusManager, FileIndexFacade fileIndexFacade) {
+ public NewMappings(final Project project, final MessageBus messageBus, final ProjectLevelVcsManagerImpl vcsManager,
+ FileStatusManager fileStatusManager) {
myProject = project;
myMessageBus = messageBus;
+ myVcsManager = vcsManager;
myFileStatusManager = fileStatusManager;
- myFileIndexFacade = fileIndexFacade;
myLock = new Object();
myVcsToPaths = new HashMap<String, List<VcsDirectoryMapping>>();
myFileWatchRequestsManager = new FileWatchRequestsManager(myProject, this, LocalFileSystem.getInstance());
@@ -235,7 +234,7 @@ public class NewMappings {
@Nullable
public VcsDirectoryMapping getMappingFor(final VirtualFile file, final Object parentModule) {
// if parentModule is not null it means that file belongs to the module so it isn't excluded
- if (parentModule == null && myFileIndexFacade.isExcludedFile(file)) {
+ if (parentModule == null && myVcsManager.isIgnored(file)) {
return null;
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootErrorsFinder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootErrorsFinder.java
index 2769b3ca84cb..bb88f3dc3260 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootErrorsFinder.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootErrorsFinder.java
@@ -16,23 +16,21 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-/**
- * @author Nadya Zabrodina
- */
public class VcsRootErrorsFinder {
- private final @NotNull Project myProject;
- private final @NotNull ProjectLevelVcsManager myVcsManager;
+ @NotNull private final Project myProject;
+ @NotNull private final ProjectLevelVcsManager myVcsManager;
+ @NotNull private final VcsRootDetector myRootDetector;
public VcsRootErrorsFinder(@NotNull Project project) {
myProject = project;
myVcsManager = ProjectLevelVcsManager.getInstance(project);
+ myRootDetector = ServiceManager.getService(myProject, VcsRootDetector.class);
}
@NotNull
public Collection<VcsRootError> find() {
List<VcsDirectoryMapping> mappings = myVcsManager.getDirectoryMappings();
- Collection<VcsRoot> vcsRoots = ServiceManager.getService(myProject, VcsRootDetector.class).detect();
-
+ Collection<VcsRoot> vcsRoots = myRootDetector.detect();
Collection<VcsRootError> errors = new ArrayList<VcsRootError>();
errors.addAll(findExtraMappings(mappings));
errors.addAll(findUnregisteredRoots(mappings, vcsRoots));
diff --git a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java
index 1eebb80e8004..388b9e05fe56 100644
--- a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java
+++ b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/Executor.java
@@ -156,9 +156,10 @@ public class Executor {
}
}
- protected static String run(@NotNull List<String> params, boolean ignoreNonZeroExitCode) throws ExecutionException {
+ protected static String run(@NotNull File workingDir, @NotNull List<String> params,
+ boolean ignoreNonZeroExitCode) throws ExecutionException {
final ProcessBuilder builder = new ProcessBuilder().command(params);
- builder.directory(ourCurrentDir());
+ builder.directory(workingDir);
builder.redirectErrorStream(true);
Process clientProcess;
try {
@@ -279,7 +280,8 @@ public class Executor {
return new File(ourCurrentDir, fileName);
}
- private static File ourCurrentDir() {
+ @NotNull
+ protected static File ourCurrentDir() {
assert ourCurrentDir != null : "Current dir hasn't been initialized yet. Call cd at least once before any other command.";
return new File(ourCurrentDir);
}
diff --git a/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/ConvertExcludedToIgnoredTest.java b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/ConvertExcludedToIgnoredTest.java
new file mode 100644
index 000000000000..4ec5ea4bcdad
--- /dev/null
+++ b/platform/vcs-impl/testSrc/com/intellij/openapi/vcs/changes/ConvertExcludedToIgnoredTest.java
@@ -0,0 +1,94 @@
+package com.intellij.openapi.vcs.changes;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerProjectExtension;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.testFramework.PlatformTestCase;
+import com.intellij.testFramework.PsiTestUtil;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ConvertExcludedToIgnoredTest extends PlatformTestCase {
+ private VirtualFile myContentRoot;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ myContentRoot = getVirtualFile(createTempDirectory());
+ PsiTestUtil.addContentRoot(myModule, myContentRoot);
+ }
+
+ public void testExcludedFolder() throws IOException {
+ VirtualFile excluded = createChildDirectory(myContentRoot, "exc");
+ PsiTestUtil.addExcludedRoot(myModule, excluded);
+ getChangeListManager().convertExcludedToIgnored();
+ assertFalse(getChangeListManager().isIgnoredFile(myContentRoot));
+ assertTrue(getChangeListManager().isIgnoredFile(excluded));
+ assertIgnored(excluded);
+ }
+
+ public void testModuleOutput() throws IOException {
+ VirtualFile output = createChildDirectory(myContentRoot, "out");
+ PsiTestUtil.setCompilerOutputPath(myModule, output.getUrl(), false);
+ getChangeListManager().convertExcludedToIgnored();
+ assertFalse(getChangeListManager().isIgnoredFile(myContentRoot));
+ assertTrue(getChangeListManager().isIgnoredFile(output));
+ assertIgnored(output);
+ }
+
+ public void testProjectOutput() throws IOException {
+ VirtualFile output = getVirtualFile(createTempDir("projectOutput"));
+ CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(output.getUrl());
+ getChangeListManager().convertExcludedToIgnored();
+ assertTrue(getChangeListManager().isIgnoredFile(output));
+ assertIgnored(output);
+ }
+
+ public void testModuleOutputUnderProjectOutput() throws IOException {
+ VirtualFile output = getVirtualFile(createTempDir("projectOutput"));
+ CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(output.getUrl());
+ VirtualFile moduleOutput = createChildDirectory(output, "module");
+ PsiTestUtil.setCompilerOutputPath(myModule, moduleOutput.getUrl(), false);
+ getChangeListManager().convertExcludedToIgnored();
+ assertTrue(getChangeListManager().isIgnoredFile(output));
+ assertTrue(getChangeListManager().isIgnoredFile(moduleOutput));
+ assertIgnored(output);
+ }
+
+ public void testModuleOutputUnderExcluded() throws IOException {
+ VirtualFile excluded = createChildDirectory(myContentRoot, "target");
+ PsiTestUtil.addExcludedRoot(myModule, excluded);
+ VirtualFile moduleOutput = createChildDirectory(excluded, "classes");
+ PsiTestUtil.setCompilerOutputPath(myModule, moduleOutput.getUrl(), false);
+ getChangeListManager().convertExcludedToIgnored();
+ assertTrue(getChangeListManager().isIgnoredFile(excluded));
+ assertTrue(getChangeListManager().isIgnoredFile(moduleOutput));
+ assertIgnored(excluded);
+ }
+
+ private void assertIgnored(VirtualFile... ignoredDirs) {
+ assertIgnoredDirectories(getProject(), ignoredDirs);
+ }
+
+ public static void assertIgnoredDirectories(final Project project, VirtualFile... ignoredDirs) {
+ List<String> expectedIgnoredPaths = new ArrayList<String>();
+ for (VirtualFile dir : ignoredDirs) {
+ expectedIgnoredPaths.add(dir.getPath() + "/");
+ }
+ List<String> actualIgnoredPaths = new ArrayList<String>();
+ for (IgnoredFileBean fileBean : ChangeListManagerImpl.getInstanceImpl(project).getFilesToIgnore()) {
+ assertEquals("Unexpected ignore: " + fileBean, IgnoreSettingsType.UNDER_DIR, fileBean.getType());
+ actualIgnoredPaths.add(fileBean.getPath());
+ }
+ assertSameElements(expectedIgnoredPaths, actualIgnoredPaths);
+ }
+
+ private ChangeListManagerImpl getChangeListManager() {
+ return ChangeListManagerImpl.getInstanceImpl(getProject());
+ }
+}
diff --git a/platform/vcs-impl/vcs-impl.iml b/platform/vcs-impl/vcs-impl.iml
index d5e517397bb9..9492e1b4205c 100644
--- a/platform/vcs-impl/vcs-impl.iml
+++ b/platform/vcs-impl/vcs-impl.iml
@@ -18,6 +18,7 @@
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="spellchecker" />
<orderEntry type="library" name="JUnit4" level="project" />
+ <orderEntry type="module" module-name="testFramework" scope="TEST" />
</component>
</module>
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/TimedVcsCommit.java b/platform/vcs-log/api/src/com/intellij/vcs/log/TimedVcsCommit.java
index c7b7ef9a7300..54f7ba19b187 100644
--- a/platform/vcs-log/api/src/com/intellij/vcs/log/TimedVcsCommit.java
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/TimedVcsCommit.java
@@ -20,7 +20,7 @@ import com.intellij.vcs.log.graph.GraphCommit;
import java.util.List;
/**
- * A {@link GraphCommit} with information about date & time when this commit was made.
+ * A typified {@link GraphCommit}.
* <p/>
* An instance of this object can be obtained via
* {@link VcsLogObjectsFactory#createTimedCommit(Hash, List, long) VcsLogObjectsFactory#createTimedCommit}.
@@ -31,12 +31,4 @@ import java.util.List;
*/
public interface TimedVcsCommit extends GraphCommit<Hash> {
- /**
- * <p>Returns the timestamp indicating the date & time when this commit was made.</p>
- * <p>This time is displayed in the table by default;
- * is used for joining commits from different repositories;
- * is used for ordering commits in a single repository (keeping the preference of the topological ordering of course).</p>
- */
- long getTimestamp();
-
}
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java
index 5d4f1fb83cad..89805947869c 100644
--- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java
@@ -29,8 +29,8 @@ public interface VcsLogProvider {
* <p>Reads the whole history, but only hashes & parents.</p>
* <p>Also reports authors/committers of this repository to the given user registry.</p>
*/
- @NotNull
- List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException;
+ void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
+ @NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException;
/**
* Reads those details of the given commits, which are necessary to be shown in the log table.
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsShortCommitDetails.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsShortCommitDetails.java
index 3069f3f6d967..9f6cecee49fb 100644
--- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsShortCommitDetails.java
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsShortCommitDetails.java
@@ -21,20 +21,9 @@ import java.util.List;
*/
public interface VcsShortCommitDetails extends TimedVcsCommit {
- @Override
- @NotNull
- Hash getId();
-
@NotNull
VirtualFile getRoot();
- @Override
- @NotNull
- List<Hash> getParents();
-
- @Override
- long getTimestamp();
-
@NotNull
String getSubject();
diff --git a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/GraphCommit.java b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/GraphCommit.java
index 6a414853da45..02b337804f5c 100644
--- a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/GraphCommit.java
+++ b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/GraphCommit.java
@@ -29,6 +29,12 @@ public interface GraphCommit<CommitId> {
@NotNull
List<CommitId> getParents();
+ /**
+ * <p>Returns the timestamp indicating the date & time when this commit was made.</p>
+ * <p>This time is displayed in the table by default;
+ * it is used for joining commits from different repositories;
+ * it is used for ordering commits in a single repository (keeping the preference of the topological ordering of course).</p>
+ */
long getTimestamp();
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java
index 6ed592f10939..fc51742b5318 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogJoiner.java
@@ -30,9 +30,7 @@ import java.util.*;
* @author Kirill Likhodedov
*/
public class VcsLogJoiner<CommitId, Commit extends GraphCommit<CommitId>> {
- private final static int BOUND_SAVED_LOG = 10000;
- public final static String NOT_ENOUGH_FIRST_BLOCK = "Not enough first block";
public final static String ILLEGAL_DATA_RELOAD_ALL = "All data is illegal - request reload all";
/**
@@ -100,12 +98,10 @@ public class VcsLogJoiner<CommitId, Commit extends GraphCommit<CommitId>> {
Commit commit = commits.get(lastIndex);
if (searchHashes.size() == 0)
return lastIndex;
- if (lastIndex > BOUND_SAVED_LOG)
- throw new IllegalStateException(ILLEGAL_DATA_RELOAD_ALL);
searchHashes.remove(commit.getId());
}
if (searchHashes.size() != 0)
- throw new IllegalStateException(ILLEGAL_DATA_RELOAD_ALL);
+ throw new VcsLogRefreshNotEnoughDataException();
return lastIndex;
}
@@ -157,16 +153,13 @@ public class VcsLogJoiner<CommitId, Commit extends GraphCommit<CommitId>> {
private void markRealRedNode(@NotNull CommitId node) {
if (!currentRed.remove(node))
- throw new IllegalStateException(NOT_ENOUGH_FIRST_BLOCK);
+ throw new IllegalStateException(ILLEGAL_DATA_RELOAD_ALL); // never happened
allRedCommit.add(node);
}
private int getFirstSaveIndex() {
for (int lastIndex = 0; lastIndex < savedLog.size(); lastIndex++) {
Commit commit = savedLog.get(lastIndex);
- if (lastIndex > BOUND_SAVED_LOG)
- throw new IllegalStateException(ILLEGAL_DATA_RELOAD_ALL);
-
boolean isGreen = currentGreen.contains(commit.getId());
if (isGreen) {
currentRed.remove(commit.getId());
@@ -180,7 +173,7 @@ public class VcsLogJoiner<CommitId, Commit extends GraphCommit<CommitId>> {
if (currentRed.isEmpty())
return lastIndex + 1;
}
- throw new IllegalStateException(ILLEGAL_DATA_RELOAD_ALL);
+ throw new IllegalStateException(ILLEGAL_DATA_RELOAD_ALL); // see VcsLogJoinerTest#illegalStateExceptionTest
}
public Set<CommitId> getAllRedCommit() {
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java
index 7006408943a8..072e0e26ace1 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java
@@ -1,36 +1,36 @@
package com.intellij.vcs.log.data;
import com.intellij.util.containers.ContainerUtil;
-import com.intellij.vcs.log.TimedVcsCommit;
+import com.intellij.vcs.log.graph.GraphCommit;
import org.jetbrains.annotations.NotNull;
import java.util.*;
-public class VcsLogMultiRepoJoiner {
+public class VcsLogMultiRepoJoiner<CommitId> {
@NotNull
- public List<? extends TimedVcsCommit> join(@NotNull Collection<List<? extends TimedVcsCommit>> logsFromRepos) {
+ public List<? extends GraphCommit<CommitId>> join(@NotNull Collection<List<? extends GraphCommit<CommitId>>> logsFromRepos) {
if (logsFromRepos.size() == 1) {
return logsFromRepos.iterator().next();
}
int size = 0;
- for (List<? extends TimedVcsCommit> repo : logsFromRepos) {
+ for (List<? extends GraphCommit<CommitId>> repo : logsFromRepos) {
size += repo.size();
}
- List<TimedVcsCommit> result = new ArrayList<TimedVcsCommit>(size);
+ List<GraphCommit<CommitId>> result = new ArrayList<GraphCommit<CommitId>>(size);
- Map<TimedVcsCommit, Iterator<? extends TimedVcsCommit>> nextCommits = ContainerUtil.newHashMap();
- for (List<? extends TimedVcsCommit> log : logsFromRepos) {
- Iterator<? extends TimedVcsCommit> iterator = log.iterator();
+ Map<GraphCommit<CommitId>, Iterator<? extends GraphCommit<CommitId>>> nextCommits = ContainerUtil.newHashMap();
+ for (List<? extends GraphCommit<CommitId>> log : logsFromRepos) {
+ Iterator<? extends GraphCommit<CommitId>> iterator = log.iterator();
if (iterator.hasNext()) {
nextCommits.put(iterator.next(), iterator);
}
}
while (!nextCommits.isEmpty()) {
- TimedVcsCommit lastCommit = findLatestCommit(nextCommits.keySet());
- Iterator<? extends TimedVcsCommit> iterator = nextCommits.get(lastCommit);
+ GraphCommit<CommitId> lastCommit = findLatestCommit(nextCommits.keySet());
+ Iterator<? extends GraphCommit<CommitId>> iterator = nextCommits.get(lastCommit);
result.add(lastCommit);
nextCommits.remove(lastCommit);
@@ -43,10 +43,10 @@ public class VcsLogMultiRepoJoiner {
}
@NotNull
- private static TimedVcsCommit findLatestCommit(@NotNull Set<TimedVcsCommit> commits) {
+ private GraphCommit<CommitId> findLatestCommit(@NotNull Set<GraphCommit<CommitId>> commits) {
long maxTimeStamp = Long.MIN_VALUE;
- TimedVcsCommit lastCommit = null;
- for (TimedVcsCommit commit : commits) {
+ GraphCommit<CommitId> lastCommit = null;
+ for (GraphCommit<CommitId> commit : commits) {
if (commit.getTimestamp() >= maxTimeStamp) {
maxTimeStamp = commit.getTimestamp();
lastCommit = commit;
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefreshNotEnoughDataException.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefreshNotEnoughDataException.java
new file mode 100644
index 000000000000..9863be8d0304
--- /dev/null
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefreshNotEnoughDataException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log.data;
+
+public class VcsLogRefreshNotEnoughDataException extends RuntimeException {
+
+ private final static String NOT_ENOUGH_FIRST_BLOCK = "Not enough first block";
+
+ public VcsLogRefreshNotEnoughDataException() {
+ super(NOT_ENOUGH_FIRST_BLOCK);
+ }
+}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java
index 0c25d7f5709d..12996f91c116 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java
@@ -96,11 +96,11 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
Map<VirtualFile, Collection<VcsRef>> refs = loadRefsFromVcs(myProviders);
Set<VirtualFile> roots = myProviders.keySet();
Map<VirtualFile, VcsLogProvider.Requirements> requirements = prepareSimpleRequirements(roots, myRecentCommitCount);
- Map<VirtualFile, List<? extends TimedVcsCommit>> commits = loadRecentCommitsFromVcs(myProviders, requirements,
- myUserRegistry, myTopCommitsDetailsCache);
- List<? extends TimedVcsCommit> compoundLog = compound(commits.values());
- List<GraphCommit<Integer>> compactedLog = compactCommits(compoundLog, myHashMap);
- DataPack dataPack = DataPack.build(compactedLog, new RefsModel(refs, myHashMap.asIndexGetter()),
+ Map<VirtualFile, List<? extends GraphCommit<Integer>>> commits = loadRecentCommitsFromVcs(myProviders, requirements,
+ myUserRegistry, myTopCommitsDetailsCache,
+ myHashMap);
+ List<? extends GraphCommit<Integer>> compoundLog = compound(commits.values());
+ DataPack dataPack = DataPack.build(compoundLog, new RefsModel(refs, myHashMap.asIndexGetter()),
myHashMap.asIndexGetter(), myHashMap.asHashGetter(), myProviders, false);
mySingleTaskController.request(RefreshRequest.RELOAD_ALL); // build/rebuild the full log in bg
return dataPack;
@@ -152,19 +152,21 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
}
@NotNull
- private static Map<VirtualFile, List<? extends TimedVcsCommit>> loadRecentCommitsFromVcs(@NotNull Map<VirtualFile, VcsLogProvider> providers,
- @NotNull final Map<VirtualFile, VcsLogProvider.Requirements> requirements,
- @NotNull final VcsUserRegistryImpl userRegistry,
- @NotNull final Map<Hash, VcsCommitMetadata> topCommitsDetailsCache)
- throws VcsException {
+ private static Map<VirtualFile, List<? extends GraphCommit<Integer>>> loadRecentCommitsFromVcs(
+ @NotNull Map<VirtualFile, VcsLogProvider> providers,
+ @NotNull final Map<VirtualFile, VcsLogProvider.Requirements> requirements,
+ @NotNull final VcsUserRegistryImpl userRegistry,
+ @NotNull final Map<Hash, VcsCommitMetadata> topCommitsDetailsCache,
+ @NotNull final VcsLogHashMap hashMap) throws VcsException
+ {
final StopWatch sw = StopWatch.start("loading commits");
- final Map<VirtualFile, List<? extends TimedVcsCommit>> commits = ContainerUtil.newHashMap();
+ final Map<VirtualFile, List<? extends GraphCommit<Integer>>> commits = ContainerUtil.newHashMap();
new ProviderIterator() {
@Override
public void each(@NotNull VirtualFile root, @NotNull VcsLogProvider provider) throws VcsException {
List<? extends VcsCommitMetadata> metadatas = provider.readFirstBlock(root, requirements.get(root));
storeUsersAndDetails(metadatas, userRegistry, topCommitsDetailsCache);
- commits.put(root, metadatas);
+ commits.put(root, compactCommits(metadatas, hashMap));
sw.rootCompleted(root);
}
}.iterate(providers);
@@ -177,9 +179,9 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
* Compounds logs from different repositories into a single multi-repository log.
*/
@NotNull
- private static List<? extends TimedVcsCommit> compound(@NotNull Collection<List<? extends TimedVcsCommit>> commits) {
+ private static List<? extends GraphCommit<Integer>> compound(@NotNull Collection<List<? extends GraphCommit<Integer>>> commits) {
StopWatch sw = StopWatch.start("multi-repo join");
- List<? extends TimedVcsCommit> joined = new VcsLogMultiRepoJoiner().join(commits);
+ List<? extends GraphCommit<Integer>> joined = new VcsLogMultiRepoJoiner<Integer>().join(commits);
sw.report();
return joined;
}
@@ -192,8 +194,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
@NotNull
@Override
public GraphCommit<Integer> fun(@NotNull TimedVcsCommit commit) {
- return new GraphCommitImpl<Integer>(hashMap.getCommitIndex(commit.getId()),
- ContainerUtil.map(commit.getParents(), hashMap.asIndexGetter()), commit.getTimestamp());
+ return compactCommit(commit, hashMap);
}
});
hashMap.flush();
@@ -201,6 +202,12 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
return map;
}
+ @NotNull
+ private static GraphCommitImpl<Integer> compactCommit(@NotNull TimedVcsCommit commit, @NotNull VcsLogHashMap hashMap) {
+ return new GraphCommitImpl<Integer>(hashMap.getCommitIndex(commit.getId()),
+ ContainerUtil.map(commit.getParents(), hashMap.asIndexGetter()), commit.getTimestamp());
+ }
+
private static void storeUsersAndDetails(@NotNull List<? extends VcsCommitMetadata> metadatas, @NotNull VcsUserRegistryImpl userRegistry,
@NotNull Map<Hash, VcsCommitMetadata> topCommitsDetailsCache) {
for (VcsCommitMetadata detail : metadatas) {
@@ -218,9 +225,9 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
private final Map<VirtualFile, LogAndRefs> myLoadedInfos = ContainerUtil.newHashMap();
private class LogAndRefs {
- List<? extends TimedVcsCommit> log;
+ List<? extends GraphCommit<Integer>> log;
Collection<VcsRef> refs;
- LogAndRefs(Collection<VcsRef> refs, List<? extends TimedVcsCommit> commits) {
+ LogAndRefs(Collection<VcsRef> refs, List<? extends GraphCommit<Integer>> commits) {
this.refs = refs;
this.log = commits;
}
@@ -266,16 +273,16 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
try {
if (permanentGraph != null) {
loadLogAndRefs(roots, currentRefs, myRecentCommitCount);
- List<? extends TimedVcsCommit> compoundLog = compound(ContainerUtil.map(myLoadedInfos.values(),
- new Function<LogAndRefs, List<? extends TimedVcsCommit>>() {
+ List<? extends GraphCommit<Integer>> compoundLog = compound(ContainerUtil.map(myLoadedInfos.values(),
+ new Function<LogAndRefs, List<? extends GraphCommit<Integer>>>() {
@Override
- public List<? extends TimedVcsCommit> fun(LogAndRefs refs) {
+ public List<? extends GraphCommit<Integer>> fun(
+ LogAndRefs refs) {
return refs.log;
}
}));
- List<GraphCommit<Integer>> preparedLog = compactCommits(compoundLog, myHashMap);
Map<VirtualFile, Collection<VcsRef>> allNewRefs = getAllNewRefs(myLoadedInfos, currentRefs);
- List<GraphCommit<Integer>> joinedFullLog = join(preparedLog, permanentGraph.getAllCommits(), currentRefs, allNewRefs);
+ List<GraphCommit<Integer>> joinedFullLog = join(compoundLog, permanentGraph.getAllCommits(), currentRefs, allNewRefs);
if (joinedFullLog != null) {
return DataPack.build(joinedFullLog, new RefsModel(allNewRefs, myHashMap.asIndexGetter()),
myHashMap.asIndexGetter(), myHashMap.asHashGetter(), myProviders, true);
@@ -310,8 +317,9 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
Map<VirtualFile, VcsLogProvider> providers = getProviders(roots);
Map<VirtualFile, Collection<VcsRef>> refs = loadRefsFromVcs(providers);
Map<VirtualFile, VcsLogProvider.Requirements> requirements = prepareRequirements(roots, commitCount, prevRefs, refs);
- Map<VirtualFile, List<? extends TimedVcsCommit>> commits = loadRecentCommitsFromVcs(providers, requirements,
- myUserRegistry, myTopCommitsDetailsCache);
+ Map<VirtualFile, List<? extends GraphCommit<Integer>>> commits = loadRecentCommitsFromVcs(providers, requirements,
+ myUserRegistry, myTopCommitsDetailsCache,
+ myHashMap);
for (VirtualFile root : roots) {
myLoadedInfos.put(root, new LogAndRefs(refs.get(root), commits.get(root)));
}
@@ -345,7 +353,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
}
@Nullable
- private List<GraphCommit<Integer>> join(@NotNull List<GraphCommit<Integer>> recentCommits, @NotNull List<GraphCommit<Integer>> fullLog,
+ private List<GraphCommit<Integer>> join(@NotNull List<? extends GraphCommit<Integer>> recentCommits, @NotNull List<GraphCommit<Integer>> fullLog,
@NotNull Map<VirtualFile, Collection<VcsRef>> previousRefs,
@NotNull Map<VirtualFile, Collection<VcsRef>> newRefs) {
StopWatch sw = StopWatch.start("joining new commits");
@@ -365,18 +373,20 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
sw.report();
return commits;
}
+ catch (VcsLogRefreshNotEnoughDataException e) {
+ LOG.error(e); // collecting information : how often this situation happens, do we need to try to load more or can safely reload all
+ }
catch (IllegalStateException e) {
- LOG.info(e);
- return null;
+ LOG.error(e);
}
+ return null;
}
@NotNull
private Pair<PermanentGraph<Integer>, Map<VirtualFile, Collection<VcsRef>>> loadFullLog() throws VcsException {
StopWatch sw = StopWatch.start("full log reload");
- Collection<List<? extends TimedVcsCommit>> commits = readFullLogFromVcs();
- List<? extends TimedVcsCommit> compoundLog = compound(commits);
- List<GraphCommit<Integer>> graphCommits = compactCommits(compoundLog, myHashMap);
+ Collection<List<? extends GraphCommit<Integer>>> commits = readFullLogFromVcs();
+ List<? extends GraphCommit<Integer>> graphCommits = compound(commits);
Map<VirtualFile, Collection<VcsRef>> refMap = loadRefsFromVcs(myProviders);
PermanentGraph<Integer> permanentGraph = DataPack.buildPermanentGraph(graphCommits, new RefsModel(refMap, myHashMap.asIndexGetter()),
myHashMap.asIndexGetter(),
@@ -386,24 +396,31 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
}
@NotNull
- private Collection<List<? extends TimedVcsCommit>> readFullLogFromVcs() throws VcsException {
+ private Collection<List<? extends GraphCommit<Integer>>> readFullLogFromVcs() throws VcsException {
final StopWatch sw = StopWatch.start("read full log from VCS");
- final Collection<List<? extends TimedVcsCommit>> commits = ContainerUtil.newArrayList();
+ final Collection<List<? extends GraphCommit<Integer>>> logs = ContainerUtil.newArrayList();
new ProviderIterator() {
@Override
void each(@NotNull VirtualFile root, @NotNull VcsLogProvider provider) throws VcsException {
- commits.add(provider.readAllHashes(root, new Consumer<VcsUser>() {
+ final List<GraphCommit<Integer>> graphCommits = ContainerUtil.newArrayList();
+ provider.readAllHashes(root, new Consumer<VcsUser>() {
@Override
public void consume(@NotNull VcsUser user) {
myUserRegistry.addUser(user);
}
- }));
+ }, new Consumer<TimedVcsCommit>() {
+ @Override
+ public void consume(TimedVcsCommit commit) {
+ graphCommits.add(compactCommit(commit, myHashMap));
+ }
+ });
+ logs.add(graphCommits);
sw.rootCompleted(root);
}
}.iterate(myProviders);
myUserRegistry.flush();
sw.report();
- return commits;
+ return logs;
}
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/graph/GraphColorManagerImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/graph/GraphColorManagerImpl.java
index ec74038a66e4..4f0e44cbd3d2 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/graph/GraphColorManagerImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/graph/GraphColorManagerImpl.java
@@ -58,7 +58,7 @@ public class GraphColorManagerImpl implements GraphColorManager<Integer> {
if (isEmptyRefs(refs, headCommit)) {
return DEFAULT_COLOR;
}
- VcsRef firstRef = ContainerUtil.sorted(refs, getRefManager(refs).getComparator()).get(0);
+ VcsRef firstRef = Collections.min(refs, getRefManager(refs).getComparator());
// TODO dark variant
return firstRef.getName().hashCode();
}
@@ -67,7 +67,7 @@ public class GraphColorManagerImpl implements GraphColorManager<Integer> {
if (refs.isEmpty()) {
if (!myErrorWasReported.containsKey(head)) {
myErrorWasReported.put(head, head);
- LOG.error("No references found at head " + head + " which corresponds to hash " + myHashGetter.fun(head));
+ LOG.warn("No references found at head " + head + " which corresponds to hash " + myHashGetter.fun(head));
}
return true;
}
diff --git a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogJoinerTest.java b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogJoinerTest.java
deleted file mode 100644
index 63e54b910bfc..000000000000
--- a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogJoinerTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package com.intellij.vcs.log.data;
-
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.Function;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.vcs.log.Hash;
-import com.intellij.vcs.log.TimedCommitParser;
-import com.intellij.vcs.log.TimedVcsCommit;
-import com.intellij.vcs.log.impl.HashImpl;
-import org.junit.Test;
-
-import java.util.Collection;
-import java.util.List;
-
-import static java.util.Arrays.asList;
-import static org.junit.Assert.assertEquals;
-
-/**
- * @author Kirill Likhodedov
- */
-public class VcsLogJoinerTest {
-
- public void runTest(List<String> initial, List<String> updateBlock, List<String> oldRefs, List<String> newRefs, String expected) {
- List<TimedVcsCommit> savedLog = TimedCommitParser.log(ArrayUtil.toStringArray(initial));
- List<? extends TimedVcsCommit> firstBlock = TimedCommitParser.log(ArrayUtil.toStringArray(updateBlock));
- Collection<Hash> vcsOldRefs = ContainerUtil.map(oldRefs, new Function<String, Hash>() {
- @Override
- public Hash fun(String s) {
- return HashImpl.build(s);
- }
- });
- Collection<Hash> vcsNewRefs = ContainerUtil.map(newRefs, new Function<String, Hash>() {
- @Override
- public Hash fun(String s) {
- return HashImpl.build(s);
- }
- });
-
- List<? extends TimedVcsCommit> result = new VcsLogJoiner<Hash, TimedVcsCommit>().addCommits(savedLog, vcsOldRefs, firstBlock, vcsNewRefs).getFirst();
- assertEquals(expected, toStr(result));
- }
-
- @Test
- public void simpleTest() {
- runTest(
- asList("4|-a2|-a1", "3|-b1|-a", "2|-a1|-a", "1|-a|-"),
- asList("5|-f|-b1", "6|-e|-a2"),
- asList("a2", "b1"),
- asList("f", "e"),
- "e, f, a2, b1, a1, a"
- );
- }
-
- @Test
- public void oneNodeTest() {
- runTest(
- asList("3|-a1|-"),
- asList("3|-a1|-"),
- asList("a1"),
- asList("a1"),
- "a1"
- );
- }
-
- @Test
- public void oneNodeResetTest() {
- runTest(
- asList("3|-a1|-a2", "2|-a2|-"),
- asList("2|-a2|-"),
- asList("a2", "a1"),
- asList("a2"),
- "a2"
- );
- }
-
- @Test
- public void oneNodeReset2Test() {
- runTest(
- asList("3|-a1|-a2", "2|-a2|-"),
- asList("2|-a2|-"),
- asList("a1"),
- asList("a2"),
- "a2"
- );
- }
-
- @Test
- public void simpleRemoveCommitsTest() {
- runTest(
- asList("4|-a2|-a1", "3|-b1|-a", "2|-a1|-a", "1|-a|-"),
- asList("5|-f|-b1", "6|-e|-a1"),
- asList("a2"),
- asList("f", "e"),
- "e, f, b1, a1, a"
- );
- }
-
- @Test
- public void removeCommitsTest() {
- runTest(
- asList("5|-a5|-a4", "4|-a4|-a2 a3", "3|-a3|-a1", "2|-a2|-a1", "1|-a1|-"),
- asList("6|-a6|-a3"),
- asList("a5"),
- asList("a6"),
- "a6, a3, a1"
- );
- }
-
- @Test
- public void removeCommitsTest2() {
- runTest(
- asList("2|-a2|-a1", "1|-a1|-"),
- asList("5|-a5|-a4", "3|-a3|-a2", "4|-a4|-a3"),
- asList("a2"),
- asList("a5"),
- "a5, a4, a3, a2, a1"
- );
- }
-
- @Test
- public void removeCommitsTest3() {
- runTest(
- asList("3|-a3|-a2", "2|-a2|-a1", "1|-a1|-"),
- asList("2|-a2|-a1"),
- asList("a3"),
- asList("a2"),
- "a2, a1"
- );
- }
-
- private static String toStr(List<? extends TimedVcsCommit> commits) {
- StringBuilder s = new StringBuilder();
- for (TimedVcsCommit commit : commits) {
- if (s.length() != 0) {
- s.append(", ");
- }
- s.append(commit.getId().asString());
- }
- return s.toString();
- }
-}
diff --git a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogJoinerTest.kt b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogJoinerTest.kt
new file mode 100644
index 000000000000..ed4218473984
--- /dev/null
+++ b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogJoinerTest.kt
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log.data
+
+import org.junit.Test
+import java.util.ArrayList
+import com.intellij.vcs.log.TimedCommitParser
+import com.intellij.util.ArrayUtil
+import com.intellij.vcs.log.impl.HashImpl
+import com.intellij.vcs.log.TimedVcsCommit
+import com.intellij.vcs.log.Hash
+import org.junit.Assert.*
+
+
+class VcsLogJoinerTest {
+
+ class StringArrayBuilder() {
+ val result = ArrayList<String>()
+
+ fun String.plus() = result.add(this)
+
+ fun Collection<String>.plus() = result.addAll(this)
+ }
+
+ class TestRunner() {
+ private var fullLog: List<String>? = null
+ private var recentCommits: List<String>? = null
+ private var oldRefs: List<String>? = null
+ private var newRefs: List<String>? = null
+ private var expected: String? = null
+
+ private fun build(f: StringArrayBuilder.() -> Unit): List<String> {
+ val stringArrayBuilder = StringArrayBuilder()
+ stringArrayBuilder.f()
+ return stringArrayBuilder.result
+ }
+
+ fun fullLog(f: StringArrayBuilder.() -> Unit) {fullLog = build(f)}
+
+ fun recentCommits(f: StringArrayBuilder.() -> Unit) {recentCommits = build(f)}
+
+ fun oldRefs(f: StringArrayBuilder.() -> Unit) {oldRefs = build(f)}
+
+ fun newRefs(f: StringArrayBuilder.() -> Unit) {newRefs = build(f)}
+
+ fun expected(f: StringArrayBuilder.() -> Unit) {expected = build(f).join(separator = "\n")}
+
+ fun run() {
+ val vcsFullLog = TimedCommitParser.log(fullLog!!)
+ val vcsRecentCommits = TimedCommitParser.log(recentCommits!!)
+ val vcsOldRefs = oldRefs!!.map { HashImpl.build(it) }
+ val vcsNewRefs = newRefs!!.map { HashImpl.build(it) }
+
+ val result = VcsLogJoiner<Hash, TimedVcsCommit>().addCommits(vcsFullLog, vcsOldRefs, vcsRecentCommits, vcsNewRefs).getFirst()!!
+ val actual = result.map { it.getId().asString() }.join(separator = "\n")
+ assertEquals(expected, actual)
+ }
+ }
+
+ fun runTest(f: TestRunner.() -> Unit) {
+ val testRunner = TestRunner()
+ testRunner.f()
+ testRunner.run()
+ }
+
+ val BIG_TIME = 100000000
+
+ Test fun simple() {
+ runTest {
+ fullLog {
+ +"4|-a2|-a1"
+ +"3|-b1|-a"
+ +"2|-a1|-a"
+ +"1|-a|-"
+ }
+ recentCommits {
+ +"5|-f|-b1"
+ +"6|-e|-a2"
+ }
+ oldRefs {
+ +"a2"
+ +"b1"
+ }
+ newRefs {
+ +"f"
+ +"e"
+ }
+ expected {
+ +"e"
+ +"f"
+ +"a2"
+ +"b1"
+ +"a1"
+ +"a"
+ }
+ }
+ }
+
+ Test fun oneNode() {
+ runTest {
+ fullLog {
+ +"3|-a1|-"
+ }
+ recentCommits {
+ +"3|-a1|-"
+ }
+ oldRefs {
+ +"a1"
+ }
+ newRefs {
+ +"a1"
+ }
+ expected {
+ +"a1"
+ }
+ }
+ }
+
+ Test fun oneNodeReset() {
+ runTest {
+ fullLog {
+ +"3|-a1|-a2"
+ +"2|-a2|-"
+ }
+ recentCommits {
+ +"2|-a2|-"
+ }
+ oldRefs {
+ +"a2"
+ +"a1"
+ }
+ newRefs {
+ +"a2"
+ }
+ expected {
+ +"a2"
+ }
+ }
+ }
+
+ Test fun oneNodeReset2() {
+ runTest {
+ fullLog {
+ +"3|-a1|-a2"
+ +"2|-a2|-"
+ }
+ recentCommits {
+ +"2|-a2|-"
+ }
+ oldRefs {
+ +"a1"
+ }
+ newRefs {
+ +"a2"
+ }
+ expected {
+ +"a2"
+ }
+ }
+ }
+
+ Test fun simpleRemoveCommits() {
+ runTest {
+ fullLog {
+ +"4|-a2|-a1"
+ +"3|-b1|-a"
+ +"2|-a1|-a"
+ +"1|-a|-"
+ }
+ recentCommits {
+ +"5|-f|-b1"
+ +"6|-e|-a1"
+ }
+ oldRefs {
+ +"a2"
+ }
+ newRefs {
+ +"f"
+ +"e"
+ }
+ expected {
+ +"e"
+ +"f"
+ +"b1"
+ +"a1"
+ +"a"
+ }
+ }
+ }
+
+ Test fun removeCommits() {
+ runTest {
+ fullLog {
+ +"5|-a5|-a4"
+ +"4|-a4|-a2 a3"
+ +"3|-a3|-a1"
+ +"2|-a2|-a1"
+ +"1|-a1|-"
+ }
+ recentCommits {
+ +"6|-a6|-a3"
+ }
+ oldRefs {
+ +"a5"
+ }
+ newRefs {
+ +"a6"
+ }
+ expected {
+ +"a6"
+ +"a3"
+ +"a1"
+ }
+ }
+ }
+
+ Test fun removeCommits2() {
+ runTest {
+ fullLog {
+ +"2|-a2|-a1"
+ +"1|-a1|-"
+ }
+ recentCommits {
+ +"5|-a5|-a4"
+ +"3|-a3|-a2"
+ +"4|-a4|-a3"
+ }
+ oldRefs {
+ +"a2"
+ }
+ newRefs {
+ +"a5"
+ }
+ expected {
+ +"a5"
+ +"a4"
+ +"a3"
+ +"a2"
+ +"a1"
+ }
+ }
+ }
+
+ Test fun removeCommits3() {
+ runTest {
+ fullLog {
+ +"3|-a3|-a2"
+ +"2|-a2|-a1"
+ +"1|-a1|-"
+ }
+ recentCommits {
+ +"2|-a2|-a1"
+ }
+ oldRefs {
+ +"a3"
+ }
+ newRefs {
+ +"a2"
+ }
+ expected {
+ +"a2"
+ +"a1"
+ }
+ }
+ }
+
+ Test fun removeOldBranch() {
+ runTest {
+ fullLog {
+ +"100|-e1|-e10"
+ +(10..100000).map { "${BIG_TIME - it}|-e${it}|-e${it + 1}" }
+ +"5|-e100001|-a1"
+ +"4|-b2|-b1"
+ +"3|-b1|-a1"
+ +"1|-a1|-"
+ }
+ recentCommits {
+ +"100|-e1|-e10"
+ }
+ oldRefs {
+ +"e1"
+ +"b2"
+ }
+ newRefs {
+ "e1"
+ }
+ expected {
+ +"e1"
+ +(10..100000).map { "e$it" }
+ +"e100001"
+ +"a1"
+ }
+ }
+ }
+
+ Test fun addToOldBranch() {
+ runTest {
+ fullLog {
+ +"100|-e1|-e10"
+ +(10..100000).map { "${BIG_TIME - it}|-e${it}|-e${it + 1}" }
+ +"5|-e100001|-a1"
+ +"4|-b2|-b1"
+ +"3|-b1|-a1"
+ +"1|-a1|-"
+ }
+ recentCommits {
+ +"50|-b4|-b3"
+ +"49|-b3|-b2"
+ }
+ oldRefs {
+ +"e1"
+ +"b2"
+ }
+ newRefs {
+ +"e1"
+ +"b4"
+ }
+ expected {
+ +"e1"
+ +(10..100000).map { "e$it" }
+ +"b4"
+ +"b3"
+ +"e100001"
+ +"b2"
+ +"b1"
+ +"a1"
+ }
+ }
+ }
+
+ Test fun removeLongBranch() {
+ runTest {
+ fullLog {
+ +"100|-e1|-e10"
+ +(10..100000).map { "${BIG_TIME - it}|-e${it}|-e${it + 1}" }
+ +"5|-e100001|-a1"
+ +"4|-b2|-b1"
+ +"3|-b1|-a1"
+ +"1|-a1|-"
+ }
+ recentCommits {
+ +"50|-b4|-b3"
+ +"49|-b3|-b2"
+ }
+ oldRefs {
+ +"e1"
+ +"b2"
+ }
+ newRefs {
+ +"b4"
+ }
+ expected {
+ +"b4"
+ +"b3"
+ +"b2"
+ +"b1"
+ +"a1"
+ }
+ }
+ }
+
+ Test fun notEnoughDataExceptionTest() {
+ try {
+ runTest {
+ fullLog {
+ +"1|-a1|-"
+ }
+ recentCommits {
+ +"3|-a3|-a2"
+ }
+ oldRefs {
+ +"a1"
+ }
+ newRefs {
+ +"a3"
+ }
+ }
+ } catch (e: VcsLogRefreshNotEnoughDataException) {
+ return
+ }
+ fail()
+ }
+
+ Test fun illegalStateExceptionTest() {
+ try {
+ runTest {
+ fullLog {
+ +"1|-a1|-"
+ }
+ recentCommits {
+ +"1|-a1|-"
+ }
+ oldRefs {
+ +"a1"
+ +"a2"
+ }
+ newRefs {
+ +"a1"
+ }
+ }
+ } catch (e: IllegalStateException) {
+ return
+ }
+ fail()
+ }
+
+ Test fun removeParallelBranch() {
+ runTest {
+ fullLog {
+ +"4|-a4|-a1"
+ +"3|-a3|-a2"
+ +"2|-a2|-"
+ +"1|-a1|-"
+ }
+ recentCommits {
+
+ }
+ oldRefs {
+ +"a4"
+ +"a3"
+ }
+ newRefs {
+ +"a3"
+ }
+ expected {
+ +"a3"
+ +"a2"
+ }
+ }
+ }
+
+ Test fun removeAll() {
+ runTest {
+ fullLog {
+ +"4|-a4|-a1"
+ +"3|-a3|-a2"
+ +"2|-a2|-"
+ +"1|-a1|-"
+ }
+ recentCommits {
+
+ }
+ oldRefs {
+ +"a4"
+ +"a3"
+ }
+ newRefs {
+
+ }
+ expected {
+
+ }
+ }
+ }
+}
diff --git a/platform/vcs-log/impl/test/com/intellij/vcs/log/impl/TestVcsLogProvider.java b/platform/vcs-log/impl/test/com/intellij/vcs/log/impl/TestVcsLogProvider.java
index d3709b2d8f55..850478b048dc 100644
--- a/platform/vcs-log/impl/test/com/intellij/vcs/log/impl/TestVcsLogProvider.java
+++ b/platform/vcs-log/impl/test/com/intellij/vcs/log/impl/TestVcsLogProvider.java
@@ -93,9 +93,9 @@ public class TestVcsLogProvider implements VcsLogProvider {
return ContainerUtil.map(myCommits.subList(0, requirements.getCommitCount()), myCommitToMetadataConvertor);
}
- @NotNull
@Override
- public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException {
+ public void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
+ @NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
try {
myFullLogSemaphore.acquire();
}
@@ -103,7 +103,9 @@ public class TestVcsLogProvider implements VcsLogProvider {
throw new RuntimeException(e);
}
assertRoot(root);
- return myCommits;
+ for (TimedVcsCommit commit : myCommits) {
+ commitConsumer.consume(commit);
+ }
}
private void assertRoot(@NotNull VirtualFile root) {
diff --git a/platform/vcs-log/impl/vcs-log-impl.iml b/platform/vcs-log/impl/vcs-log-impl.iml
index 5668888806ac..304affc03123 100644
--- a/platform/vcs-log/impl/vcs-log-impl.iml
+++ b/platform/vcs-log/impl/vcs-log-impl.iml
@@ -21,6 +21,7 @@
<orderEntry type="module" module-name="spellchecker" />
<orderEntry type="module" module-name="vcs-log-graph-api" />
<orderEntry type="module" module-name="testFramework" scope="TEST" />
+ <orderEntry type="library" scope="TEST" name="KotlinJavaRuntime" level="project" />
</component>
</module>
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java
index 098501af7489..6109e9a41598 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java
@@ -164,8 +164,10 @@ public abstract class XDebuggerEvaluator {
return text;
}
+ @Deprecated
/**
* @return delay before showing value tooltip (in ms)
+ * @deprecated Since IDEA 14 it is a platform setting
*/
public int getValuePopupDelay() {
return XDebuggerSettingsManager.getInstance().getDataViewSettings().getValueLookupDelay();
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/settings/DebuggerConfigurableProvider.java b/platform/xdebugger-api/src/com/intellij/xdebugger/settings/DebuggerConfigurableProvider.java
new file mode 100644
index 000000000000..6cc25bd87f5f
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/settings/DebuggerConfigurableProvider.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.xdebugger.settings;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.options.Configurable;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public abstract class DebuggerConfigurableProvider {
+ public static final ExtensionPointName<DebuggerConfigurableProvider> EXTENSION_POINT = ExtensionPointName.create("com.intellij.xdebugger.configurableProvider");
+
+ @NotNull
+ public Collection<? extends Configurable> getConfigurables(@NotNull DebuggerSettingsCategory category) {
+ return Collections.emptyList();
+ }
+
+ /**
+ * General settings of category were applied
+ */
+ public void generalApplied(@NotNull DebuggerSettingsCategory category) {
+ }
+
+ public boolean isTargetedToProduct(@NotNull Configurable configurable) {
+ return false;
+ }
+} \ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/settings/DebuggerSettingsCategory.java b/platform/xdebugger-api/src/com/intellij/xdebugger/settings/DebuggerSettingsCategory.java
new file mode 100644
index 000000000000..fab630fe751c
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/settings/DebuggerSettingsCategory.java
@@ -0,0 +1,6 @@
+package com.intellij.xdebugger.settings;
+
+public enum DebuggerSettingsCategory {
+ ROOT /* will be placed under root "Debugger" node, use it with care */,
+ GENERAL, DATA_VIEWS, STEPPING, HOTSWAP
+} \ No newline at end of file
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java b/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java
index 52049f76ae72..367601db12aa 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java
@@ -23,6 +23,9 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Collection;
+import java.util.Collections;
+
/**
* Implement this class to provide settings page for debugger. Settings page will be placed under 'Debugger' node in the 'Settings' dialog.
* An implementation should be registered in plugin.xml:
@@ -34,10 +37,6 @@ import org.jetbrains.annotations.Nullable;
* @author nik
*/
public abstract class XDebuggerSettings<T> implements PersistentStateComponent<T> {
- public enum Category {
- ROOT, DATA_VIEWS, STEPPING
- }
-
public static final ExtensionPointName<XDebuggerSettings> EXTENSION_POINT = ExtensionPointName.create("com.intellij.xdebugger.settings");
private final String myId;
@@ -55,15 +54,23 @@ public abstract class XDebuggerSettings<T> implements PersistentStateComponent<T
}
@Nullable
+ @Deprecated
+ /**
+ * @deprecated Please use {@link #createConfigurables(DebuggerSettingsCategory)}
+ */
public Configurable createConfigurable() {
return null;
}
- @Nullable
- public Configurable createConfigurable(@NotNull Category category) {
- return null;
+ @NotNull
+ public Collection<? extends Configurable> createConfigurables(@NotNull DebuggerSettingsCategory category) {
+ return Collections.emptyList();
+ }
+
+ public void generalApplied(@NotNull DebuggerSettingsCategory category) {
}
- public void generalApplied(@NotNull Category category) {
+ public boolean isTargetedToProduct(@NotNull Configurable configurable) {
+ return false;
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java
index 840163bb9e43..b09c7388748f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/DebuggerSupport.java
@@ -36,6 +36,7 @@ import org.jetbrains.annotations.Nullable;
public abstract class DebuggerSupport {
private static final ExtensionPointName<DebuggerSupport> EXTENSION_POINT = ExtensionPointName.create("com.intellij.xdebugger.debuggerSupport");
+ @SuppressWarnings("deprecation")
private static final DebuggerSettingsPanelProvider EMPTY_SETTINGS_PANEL_PROVIDER = new DebuggerSettingsPanelProvider() {
};
@@ -60,6 +61,11 @@ public abstract class DebuggerSupport {
@NotNull
public abstract BreakpointPanelProvider<?> getBreakpointPanelProvider();
+ /**
+ * @deprecated Use {@link com.intellij.xdebugger.settings.DebuggerConfigurableProvider}
+ */
+ @Deprecated
+ @SuppressWarnings("deprecation")
@NotNull
public DebuggerSettingsPanelProvider getSettingsPanelProvider() {
return EMPTY_SETTINGS_PANEL_PROVIDER;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
index 9ab13ba0ae74..762855510a1e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
@@ -46,7 +46,6 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.ui.AppUIUtil;
@@ -91,7 +90,7 @@ public class XDebugSessionImpl implements XDebugSession {
private XDebugProcess myDebugProcess;
private final Map<XBreakpoint<?>, CustomizedBreakpointPresentation> myRegisteredBreakpoints =
new THashMap<XBreakpoint<?>, CustomizedBreakpointPresentation>();
- private final Set<XBreakpoint<?>> myInactiveSlaveBreakpoints = new SmartHashSet<XBreakpoint<?>>();
+ private final Set<XBreakpoint<?>> myInactiveSlaveBreakpoints = Collections.synchronizedSet(new SmartHashSet<XBreakpoint<?>>());
private boolean myBreakpointsDisabled;
private final XDebuggerManagerImpl myDebuggerManager;
private MyBreakpointListener myBreakpointListener;
@@ -103,7 +102,7 @@ public class XDebugSessionImpl implements XDebugSession {
private MyDependentBreakpointListener myDependentBreakpointListener;
private XValueMarkers<?, ?> myValueMarkers;
private final String mySessionName;
- private XDebugSessionTab mySessionTab;
+ private @Nullable XDebugSessionTab mySessionTab;
private XDebugSessionData mySessionData;
private XBreakpoint<?> myActiveNonLineBreakpoint;
private final EventDispatcher<XDebugSessionListener> myDispatcher = EventDispatcher.create(XDebugSessionListener.class);
@@ -289,6 +288,7 @@ public class XDebugSessionImpl implements XDebugSession {
@Override
public void initBreakpoints() {
+ ApplicationManager.getApplication().assertReadAccessAllowed();
LOG.assertTrue(!breakpointsInitialized);
breakpointsInitialized = true;
@@ -308,12 +308,14 @@ public class XDebugSessionImpl implements XDebugSession {
return myConsoleView;
}
+ @Nullable
public XDebugSessionTab getSessionTab() {
return mySessionTab;
}
@Override
public RunnerLayoutUi getUI() {
+ assertSessionTabInitialized();
return mySessionTab.getUi();
}
@@ -368,12 +370,7 @@ public class XDebugSessionImpl implements XDebugSession {
private <B extends XBreakpoint<?>> void processBreakpoints(final XBreakpointHandler<B> handler,
boolean register,
final boolean temporary) {
- Collection<? extends B> breakpoints = ApplicationManager.getApplication().runReadAction(new Computable<Collection<? extends B>>() {
- @Override
- public Collection<? extends B> compute() {
- return myDebuggerManager.getBreakpointManager().getBreakpoints(handler.getBreakpointTypeClass());
- }
- });
+ Collection<? extends B> breakpoints = myDebuggerManager.getBreakpointManager().getBreakpoints(handler.getBreakpointTypeClass());
for (B b : breakpoints) {
handleBreakpoint(handler, b, register, temporary);
}
@@ -422,8 +419,9 @@ public class XDebugSessionImpl implements XDebugSession {
}
}
- private boolean isBreakpointActive(final XBreakpoint<?> b) {
- return !areBreakpointsMuted() && b.isEnabled() && !myInactiveSlaveBreakpoints.contains(b);
+ public boolean isBreakpointActive(final XBreakpoint<?> b) {
+ ApplicationManager.getApplication().assertReadAccessAllowed();
+ return !areBreakpointsMuted() && b.isEnabled() && !isInactiveSlaveBreakpoint(b);
}
@Override
@@ -448,6 +446,7 @@ public class XDebugSessionImpl implements XDebugSession {
@Override
public void setBreakpointMuted(boolean muted) {
+ ApplicationManager.getApplication().assertReadAccessAllowed();
if (areBreakpointsMuted() == muted) return;
mySessionData.setBreakpointsMuted(muted);
processAllBreakpoints(!muted, muted);
@@ -714,8 +713,10 @@ public class XDebugSessionImpl implements XDebugSession {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
- mySessionTab.toFront();
- mySessionTab.getUi().attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
+ if (mySessionTab != null) {
+ mySessionTab.toFront(true);
+ mySessionTab.getUi().attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
+ }
}
});
@@ -847,7 +848,9 @@ public class XDebugSessionImpl implements XDebugSession {
if (myStopped) return;
myDebugProcess.stop();
- myProject.getMessageBus().syncPublisher(XDebuggerManager.TOPIC).processStopped(myDebugProcess);
+ if (!myProject.isDisposed()) {
+ myProject.getMessageBus().syncPublisher(XDebuggerManager.TOPIC).processStopped(myDebugProcess);
+ }
myCurrentPosition = null;
myCurrentExecutionStack = null;
myCurrentStackFrame = null;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java
index fbfe184a5f3f..7f8eda2a347f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,8 +26,6 @@ import com.intellij.xdebugger.impl.breakpoints.XBreakpointPanelProvider;
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider;
import com.intellij.xdebugger.impl.evaluate.quick.XQuickEvaluateHandler;
import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
-import com.intellij.xdebugger.impl.settings.DebuggerSettingsPanelProvider;
-import com.intellij.xdebugger.impl.settings.XDebuggerSettingsPanelProviderImpl;
import org.jetbrains.annotations.NotNull;
/**
@@ -49,7 +47,6 @@ public class XDebuggerSupport extends DebuggerSupport {
private final XDebuggerSuspendedActionHandler myShowExecutionPointHandler;
private final XDebuggerEvaluateActionHandler myEvaluateHandler;
private final XQuickEvaluateHandler myQuickEvaluateHandler;
- private final XDebuggerSettingsPanelProviderImpl mySettingsPanelProvider;
private final XAddToWatchesFromEditorActionHandler myAddToWatchesActionHandler;
private final DebuggerActionHandler myEvaluateInConsoleActionHandler = new XEvaluateInConsoleFromEditorActionHandler();
@@ -118,7 +115,6 @@ public class XDebuggerSupport extends DebuggerSupport {
myMuteBreakpointsHandler = new XDebuggerMuteBreakpointsHandler();
myEvaluateHandler = new XDebuggerEvaluateActionHandler();
myQuickEvaluateHandler = new XQuickEvaluateHandler();
- mySettingsPanelProvider = new XDebuggerSettingsPanelProviderImpl();
myMarkObjectActionHandler = new XMarkObjectActionHandler();
myEditBreakpointActionHandler = new XDebuggerEditBreakpointActionHandler();
}
@@ -253,10 +249,4 @@ public class XDebuggerSupport extends DebuggerSupport {
public EditBreakpointActionHandler getEditBreakpointAction() {
return myEditBreakpointActionHandler;
}
-
- @Override
- @NotNull
- public DebuggerSettingsPanelProvider getSettingsPanelProvider() {
- return mySettingsPanelProvider;
- }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ForceStepIntoAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ForceStepIntoAction.java
index e7c9cae4db92..e5620e20011b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ForceStepIntoAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/ForceStepIntoAction.java
@@ -15,13 +15,14 @@
*/
package com.intellij.xdebugger.impl.actions;
-import org.jetbrains.annotations.NotNull;
import com.intellij.xdebugger.impl.DebuggerSupport;
+import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class ForceStepIntoAction extends XDebuggerActionBase {
+ @Override
@NotNull
protected DebuggerActionHandler getHandler(@NotNull final DebuggerSupport debuggerSupport) {
return debuggerSupport.getForceStepIntoHandler();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java
index 364353c2ac63..8631b8fc901b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java
@@ -156,11 +156,11 @@ public class BreakpointState<B extends XBreakpoint<P>, P extends XBreakpointProp
}
public boolean isLogExpressionEnabled() {
- return myLogExpression != null && !myLogExpression.myDisabled;
+ return myLogExpression == null || !myLogExpression.myDisabled;
}
public boolean isConditionEnabled() {
- return myCondition != null && !myCondition.myDisabled;
+ return myCondition == null || !myCondition.myDisabled;
}
@Property(surroundWithTag = false)
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java
index ddf673fe2504..4ee505afec81 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java
@@ -62,9 +62,9 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
private final XBreakpointManagerImpl myBreakpointManager;
private Icon myIcon;
private CustomizedBreakpointPresentation myCustomizedPresentation;
- private boolean myConditionEnabled;
+ private boolean myConditionEnabled = true;
private XExpression myCondition;
- private boolean myLogExpressionEnabled;
+ private boolean myLogExpressionEnabled = true;
private XExpression myLogExpression;
public XBreakpointBase(final XBreakpointType<Self, P> type, XBreakpointManagerImpl breakpointManager, final @Nullable P properties, final S state) {
@@ -192,7 +192,6 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
@Override
public void setLogExpression(@Nullable final String expression) {
- setLogExpressionEnabled(true);
if (!Comparing.equal(getLogExpression(), expression)) {
myLogExpression = XExpressionImpl.fromText(expression);
fireBreakpointChanged();
@@ -211,7 +210,6 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
@Override
public void setLogExpressionObject(@Nullable XExpression expression) {
- setLogExpressionEnabled(true);
if (!Comparing.equal(myLogExpression, expression)) {
myLogExpression = expression;
fireBreakpointChanged();
@@ -226,7 +224,6 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
@Override
public void setCondition(@Nullable final String condition) {
- setConditionEnabled(true);
if (!Comparing.equal(condition, getCondition())) {
myCondition = XExpressionImpl.fromText(condition);
fireBreakpointChanged();
@@ -245,7 +242,6 @@ public class XBreakpointBase<Self extends XBreakpoint<P>, P extends XBreakpointP
@Override
public void setConditionExpression(@Nullable XExpression condition) {
- setConditionEnabled(true);
if (!Comparing.equal(condition, myCondition)) {
myCondition = condition;
fireBreakpointChanged();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
index 6ee8eadbe0ad..36584d1105d4 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
@@ -116,7 +116,7 @@ public class XBreakpointActionsPanel<B extends XBreakpointBase<?,?,?>> extends X
if (myLogExpressionComboBox != null) {
XExpression expression = myLogExpressionComboBox.getExpression();
XExpression logExpression = !XDebuggerUtilImpl.isEmptyExpression(expression) ? expression : null;
- myBreakpoint.setLogExpressionEnabled(myLogExpressionCheckBox.isSelected() && logExpression != null);
+ myBreakpoint.setLogExpressionEnabled(logExpression == null || myLogExpressionCheckBox.isSelected());
myBreakpoint.setLogExpressionObject(logExpression);
myLogExpressionComboBox.saveTextInHistory();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form
index 64239d330fd1..4ce06a6b52da 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.form
@@ -83,7 +83,7 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
- <font size="11" style="1"/>
+ <font style="1"/>
<text value="Enabled"/>
</properties>
</component>
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
index 0e847d7db05d..75cbb569ddfd 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
@@ -208,7 +208,7 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpointBase<?,?,?>> i
if (myConditionComboBox != null) {
XExpression expression = myConditionComboBox.getExpression();
XExpression condition = !XDebuggerUtilImpl.isEmptyExpression(expression) ? expression : null;
- myBreakpoint.setConditionEnabled(myConditionEnabledCheckbox.isSelected() && condition != null);
+ myBreakpoint.setConditionEnabled(condition == null || myConditionEnabledCheckbox.isSelected());
myBreakpoint.setConditionExpression(condition);
myConditionComboBox.saveTextInHistory();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java
index b0b5998ef71f..994e51f2bbc4 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/grouping/XBreakpointFileGroupingRule.java
@@ -62,6 +62,6 @@ public class XBreakpointFileGroupingRule<B> extends XBreakpointGroupingRule<B, X
@Nullable
@Override
public Icon getIcon() {
- return AllIcons.FileTypes.Text;
+ return AllIcons.Actions.GroupByFile;
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
index 2273ab698768..bee9b3d91fd7 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
@@ -33,6 +33,7 @@ import com.intellij.xdebugger.impl.XDebuggerUtilImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager;
+import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
@@ -138,7 +139,11 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
// add to watches
XExpression expression = myInputComponent.getInputEditor().getExpression();
if (!XDebuggerUtilImpl.isEmptyExpression(expression)) {
- ((XDebugSessionImpl)mySession).getSessionTab().getWatchesView().addWatchExpression(expression, -1, false);
+ XDebugSessionTab tab = ((XDebugSessionImpl)mySession).getSessionTab();
+ if (tab != null) {
+ tab.getWatchesView().addWatchExpression(expression, -1, true);
+ requestFocusInEditor();
+ }
}
}
}
@@ -195,7 +200,11 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
setTitle(myInputComponent.getTitle());
mySwitchModeAction.putValue(Action.NAME, getSwitchButtonText(mode));
- final JComponent preferredFocusedComponent = myInputComponent.getInputEditor().getPreferredFocusedComponent();
+ requestFocusInEditor();
+ }
+
+ private void requestFocusInEditor() {
+ JComponent preferredFocusedComponent = myInputComponent.getInputEditor().getPreferredFocusedComponent();
if (preferredFocusedComponent != null) {
IdeFocusManager.getInstance(mySession.getProject()).requestFocus(preferredFocusedComponent, true);
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java
index bf3e0010e6cf..0ccd488e9f9b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java
@@ -100,14 +100,7 @@ public class XQuickEvaluateHandler extends QuickEvaluateHandler {
}
@Override
- public int getValueLookupDelay(final Project project) {
- XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
- if (session != null) {
- XDebuggerEvaluator evaluator = session.getDebugProcess().getEvaluator();
- if (evaluator != null) {
- return evaluator.getValuePopupDelay();
- }
- }
+ public int getValueLookupDelay(Project project) {
return XDebuggerSettingsManager.getInstance().getDataViewSettings().getValueLookupDelay();
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
index cdfcad27354c..ca78932701d2 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java
@@ -104,6 +104,7 @@ public class XValueHint extends AbstractValueHint {
public void evaluated(@NotNull final XValue result) {
result.computePresentation(new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
private XFullValueEvaluator myFullValueEvaluator;
+ private boolean myShown = false;
@Override
public void applyPresentation(@Nullable Icon icon,
@@ -131,7 +132,7 @@ public class XValueHint extends AbstractValueHint {
}
showHint(component);
}
- else if (getType() == ValueHintType.MOUSE_CLICK_HINT) {
+ else if (getType() == ValueHintType.MOUSE_CLICK_HINT && !myShown) {
showTree(result);
}
else {
@@ -143,6 +144,7 @@ public class XValueHint extends AbstractValueHint {
});
showHint(component);
}
+ myShown = true;
}
@Override
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
index 5183877b2a9a..6216c1312349 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java
@@ -15,6 +15,8 @@
*/
package com.intellij.xdebugger.impl.frame;
+import com.intellij.debugger.ui.DebuggerContentInfo;
+import com.intellij.execution.ui.layout.impl.RunnerContentUi;
import com.intellij.ide.DataManager;
import com.intellij.ide.dnd.DnDEvent;
import com.intellij.ide.dnd.DnDManager;
@@ -22,6 +24,7 @@ import com.intellij.ide.dnd.DnDNativeTarget;
import com.intellij.openapi.CompositeDisposable;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.SystemInfo;
@@ -36,6 +39,7 @@ import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
+import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
@@ -68,6 +72,7 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi
@NotNull private final XDebugSessionImpl mySession;
private final JPanel myDecoratedPanel;
private final CompositeDisposable myDisposables = new CompositeDisposable();
+ private boolean myRebuildNeeded;
public XWatchesViewImpl(@NotNull final XDebugSessionImpl session) {
mySession = session;
@@ -216,10 +221,40 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi
public void addWatchExpression(@NotNull XExpression expression, int index, final boolean navigateToWatchNode) {
myRootNode.addWatchExpression(mySession.getDebugProcess().getEvaluator(), expression, index, navigateToWatchNode);
updateSessionData();
+ if (navigateToWatchNode) {
+ showWatchesTab();
+ }
+ }
+
+ private void showWatchesTab() {
+ XDebugSessionTab tab = mySession.getSessionTab();
+ if (tab != null) {
+ tab.toFront(false);
+ // restore watches tab if minimized
+ JComponent component = tab.getUi().getComponent();
+ if (component instanceof DataProvider) {
+ RunnerContentUi ui = RunnerContentUi.KEY.getData(((DataProvider)component));
+ if (ui != null) {
+ ui.restoreContent(DebuggerContentInfo.WATCHES_CONTENT);
+ }
+ }
+ }
+ }
+
+ public boolean rebuildNeeded() {
+ return myRebuildNeeded;
}
@Override
public void processSessionEvent(@NotNull final SessionEvent event) {
+ if (getMainPanel().isShowing() || ApplicationManager.getApplication().isUnitTestMode()) {
+ myRebuildNeeded = false;
+ }
+ else {
+ myRebuildNeeded = true;
+ return;
+ }
+
XStackFrame stackFrame = mySession.getCurrentStackFrame();
XDebuggerTree tree = myTreePanel.getTree();
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java
index d140a74f35c8..6ee307cfa573 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java
@@ -17,7 +17,7 @@ package com.intellij.xdebugger.impl.settings;
import com.intellij.openapi.options.Configurable;
import com.intellij.xdebugger.XDebuggerBundle;
-import com.intellij.xdebugger.settings.XDebuggerSettings;
+import com.intellij.xdebugger.settings.DebuggerSettingsCategory;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -41,8 +41,8 @@ class DataViewsConfigurable extends SubCompositeConfigurable implements Configur
@NotNull
@Override
- protected XDebuggerSettings.Category getCategory() {
- return XDebuggerSettings.Category.DATA_VIEWS;
+ protected DebuggerSettingsCategory getCategory() {
+ return DebuggerSettingsCategory.DATA_VIEWS;
}
@NotNull
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java
index a3f4e847288c..58896a87f596 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java
@@ -20,26 +20,23 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.impl.DebuggerSupport;
-import com.intellij.xdebugger.settings.XDebuggerSettings;
-import org.jetbrains.annotations.Nls;
+import com.intellij.xdebugger.settings.DebuggerConfigurableProvider;
+import com.intellij.xdebugger.settings.DebuggerSettingsCategory;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
+import java.util.*;
-/**
- * @author Eugene Belyaev & Eugene Zhuravlev
- */
public class DebuggerConfigurable implements SearchableConfigurable.Parent {
public static final String DISPLAY_NAME = XDebuggerBundle.message("debugger.configurable.display.name");
static final Configurable[] EMPTY_CONFIGURABLES = new Configurable[0];
+ private static final DebuggerSettingsCategory[] MERGED_CATEGORIES = {DebuggerSettingsCategory.STEPPING, DebuggerSettingsCategory.HOTSWAP};
private Configurable myRootConfigurable;
private Configurable[] myChildren;
@@ -71,89 +68,84 @@ public class DebuggerConfigurable implements SearchableConfigurable.Parent {
return;
}
- List<DebuggerSettingsPanelProvider> providers = DebuggerConfigurableProvider.getSortedProviders();
-
List<Configurable> configurables = new SmartList<Configurable>();
configurables.add(new DataViewsConfigurable());
- List<Configurable> steppingConfigurables = DebuggerConfigurableProvider.getConfigurables(XDebuggerSettings.Category.STEPPING, providers);
- if (!steppingConfigurables.isEmpty()) {
- configurables.add(new SteppingConfigurable(steppingConfigurables));
+ DebuggerConfigurableProvider[] providers = DebuggerConfigurableProvider.EXTENSION_POINT.getExtensions();
+ computeMergedConfigurables(providers, configurables);
+
+ //noinspection deprecation
+ for (DebuggerSettingsPanelProvider provider : getSortedProviders()) {
+ configurables.addAll(provider.getConfigurables());
+ @SuppressWarnings("deprecation")
+ Configurable providerRootConfigurable = provider.getRootConfigurable();
+ if (providerRootConfigurable != null) {
+ configurables.add(providerRootConfigurable);
+ }
}
- Configurable rootConfigurable = computeRootConfigurable(providers, configurables);
+ for (DebuggerConfigurableProvider provider : providers) {
+ configurables.addAll(provider.getConfigurables(DebuggerSettingsCategory.ROOT));
+ }
- if (configurables.isEmpty() && rootConfigurable == null) {
+ MergedCompositeConfigurable mergedGeneralConfigurable = computeGeneralConfigurables(providers);
+ if (configurables.isEmpty() && mergedGeneralConfigurable == null) {
+ myRootConfigurable = null;
myChildren = EMPTY_CONFIGURABLES;
}
- else if (rootConfigurable == null && configurables.size() == 1) {
- myRootConfigurable = configurables.get(0);
- myChildren = EMPTY_CONFIGURABLES;
+ else if (configurables.size() == 1) {
+ Configurable firstConfigurable = configurables.get(0);
+ if (mergedGeneralConfigurable == null) {
+ myRootConfigurable = firstConfigurable;
+ myChildren = EMPTY_CONFIGURABLES;
+ }
+ else {
+ Configurable[] generalConfigurables = mergedGeneralConfigurable.children;
+ Configurable[] mergedArray = new Configurable[generalConfigurables.length + 1];
+ System.arraycopy(generalConfigurables, 0, mergedArray, 0, generalConfigurables.length);
+ mergedArray[generalConfigurables.length] = firstConfigurable;
+ myRootConfigurable = new MergedCompositeConfigurable("", "", mergedArray);
+ myChildren = firstConfigurable instanceof SearchableConfigurable.Parent ? ((Parent)firstConfigurable).getConfigurables() : EMPTY_CONFIGURABLES;
+ }
}
else {
myChildren = configurables.toArray(new Configurable[configurables.size()]);
- myRootConfigurable = rootConfigurable;
+ myRootConfigurable = mergedGeneralConfigurable;
}
}
- @Nullable
- private static Configurable computeRootConfigurable(@NotNull List<DebuggerSettingsPanelProvider> providers, @NotNull List<Configurable> configurables) {
- Configurable deprecatedRootConfigurable = null;
- for (DebuggerSettingsPanelProvider provider : providers) {
- configurables.addAll(provider.getConfigurables());
- @SuppressWarnings("deprecation")
- Configurable providerRootConfigurable = provider.getRootConfigurable();
- if (providerRootConfigurable != null) {
- if (deprecatedRootConfigurable == null) {
- deprecatedRootConfigurable = providerRootConfigurable;
- }
- else {
- configurables.add(providerRootConfigurable);
- }
+ private static void computeMergedConfigurables(@NotNull DebuggerConfigurableProvider[] providers, @NotNull List<Configurable> result) {
+ for (DebuggerSettingsCategory category : MERGED_CATEGORIES) {
+ List<Configurable> configurables = getConfigurables(category, providers);
+ if (!configurables.isEmpty()) {
+ String id = category.name().toLowerCase(Locale.ENGLISH);
+ result.add(new MergedCompositeConfigurable("debugger." + id, XDebuggerBundle.message("debugger." + id + ".display.name"),
+ configurables.toArray(new Configurable[configurables.size()])));
}
}
+ }
- List<Configurable> rootConfigurables = DebuggerConfigurableProvider.getConfigurables(XDebuggerSettings.Category.ROOT, providers);
+ @Nullable
+ private static MergedCompositeConfigurable computeGeneralConfigurables(@NotNull DebuggerConfigurableProvider[] providers) {
+ List<Configurable> rootConfigurables = getConfigurables(DebuggerSettingsCategory.GENERAL, providers);
if (rootConfigurables.isEmpty()) {
- return deprecatedRootConfigurable;
+ return null;
}
- else {
- Configurable[] mergedRootConfigurables = new Configurable[rootConfigurables.size() + (deprecatedRootConfigurable == null ? 0 : 1)];
- rootConfigurables.toArray(mergedRootConfigurables);
- if (deprecatedRootConfigurable != null) {
- mergedRootConfigurables[rootConfigurables.size()] = deprecatedRootConfigurable;
- }
-
- // move unnamed to top
- Arrays.sort(mergedRootConfigurables, new Comparator<Configurable>() {
- @Override
- public int compare(Configurable o1, Configurable o2) {
- boolean c1e = StringUtil.isEmpty(o1.getDisplayName());
- return c1e == StringUtil.isEmpty(o2.getDisplayName()) ? 0 : (c1e ? -1 : 1);
- }
- });
-
- return new MergedCompositeConfigurable(mergedRootConfigurables) {
- @NotNull
- @Override
- public String getId() {
- throw new UnsupportedOperationException();
- }
- @Nls
- @Override
- public String getDisplayName() {
- throw new UnsupportedOperationException();
- }
- };
- }
+ Configurable[] mergedRootConfigurables = rootConfigurables.toArray(new Configurable[rootConfigurables.size()]);
+ // move unnamed to top
+ Arrays.sort(mergedRootConfigurables, new Comparator<Configurable>() {
+ @Override
+ public int compare(@NotNull Configurable o1, @NotNull Configurable o2) {
+ boolean c1e = StringUtil.isEmpty(o1.getDisplayName());
+ return c1e == StringUtil.isEmpty(o2.getDisplayName()) ? 0 : (c1e ? -1 : 1);
+ }
+ });
+ return new MergedCompositeConfigurable("", "", mergedRootConfigurables);
}
@Override
public void apply() throws ConfigurationException {
- for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) {
- support.getSettingsPanelProvider().apply();
- }
if (myRootConfigurable != null) {
myRootConfigurable.apply();
}
@@ -206,4 +198,51 @@ public class DebuggerConfigurable implements SearchableConfigurable.Parent {
public String getId() {
return "project.propDebugger";
}
+
+ @SuppressWarnings("deprecation")
+ @NotNull
+ private static List<DebuggerSettingsPanelProvider> getSortedProviders() {
+ List<DebuggerSettingsPanelProvider> providers = null;
+ for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) {
+ DebuggerSettingsPanelProvider provider = support.getSettingsPanelProvider();
+ if (providers == null) {
+ providers = new SmartList<DebuggerSettingsPanelProvider>();
+ }
+ providers.add(provider);
+ }
+
+ if (ContainerUtil.isEmpty(providers)) {
+ return Collections.emptyList();
+ }
+
+ if (providers.size() > 1) {
+ Collections.sort(providers, new Comparator<DebuggerSettingsPanelProvider>() {
+ @Override
+ public int compare(@NotNull DebuggerSettingsPanelProvider o1, @NotNull DebuggerSettingsPanelProvider o2) {
+ return o2.getPriority() - o1.getPriority();
+ }
+ });
+ }
+ return providers;
+ }
+
+ @NotNull
+ static List<Configurable> getConfigurables(@NotNull DebuggerSettingsCategory category) {
+ return getConfigurables(category, DebuggerConfigurableProvider.EXTENSION_POINT.getExtensions());
+ }
+
+ @NotNull
+ private static List<Configurable> getConfigurables(@NotNull DebuggerSettingsCategory category, @NotNull DebuggerConfigurableProvider[] providers) {
+ List<Configurable> configurables = null;
+ for (DebuggerConfigurableProvider provider : providers) {
+ Collection<? extends Configurable> providerConfigurables = provider.getConfigurables(category);
+ if (!providerConfigurables.isEmpty()) {
+ if (configurables == null) {
+ configurables = new SmartList<Configurable>();
+ }
+ configurables.addAll(providerConfigurables);
+ }
+ }
+ return ContainerUtil.notNullize(configurables);
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java
deleted file mode 100644
index 80651cadc830..000000000000
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2000-2010 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.xdebugger.impl.settings;
-
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.ConfigurableProvider;
-import com.intellij.util.SmartList;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.xdebugger.impl.DebuggerSupport;
-import com.intellij.xdebugger.settings.XDebuggerSettings;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * @author nik
- */
-public class DebuggerConfigurableProvider extends ConfigurableProvider {
- @NotNull
- static List<DebuggerSettingsPanelProvider> getSortedProviders() {
- List<DebuggerSettingsPanelProvider> providers = null;
- for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) {
- DebuggerSettingsPanelProvider provider = support.getSettingsPanelProvider();
- if (providers == null) {
- providers = new SmartList<DebuggerSettingsPanelProvider>();
- }
- providers.add(provider);
- }
-
- if (ContainerUtil.isEmpty(providers)) {
- return Collections.emptyList();
- }
-
- if (providers.size() > 1) {
- Collections.sort(providers, new Comparator<DebuggerSettingsPanelProvider>() {
- @Override
- public int compare(DebuggerSettingsPanelProvider o1, DebuggerSettingsPanelProvider o2) {
- return o2.getPriority() - o1.getPriority();
- }
- });
- }
- return providers;
- }
-
- @Override
- public Configurable createConfigurable() {
- return new DebuggerConfigurable();
- }
-
- @NotNull
- static List<Configurable> getConfigurables(@NotNull XDebuggerSettings.Category category) {
- List<DebuggerSettingsPanelProvider> providers = getSortedProviders();
- return providers.isEmpty() ? Collections.<Configurable>emptyList() : getConfigurables(category, providers);
- }
-
- @NotNull
- static List<Configurable> getConfigurables(@NotNull XDebuggerSettings.Category category, @NotNull List<DebuggerSettingsPanelProvider> providers) {
- List<Configurable> configurables = null;
- for (DebuggerSettingsPanelProvider provider : providers) {
- Collection<? extends Configurable> providerConfigurables = provider.getConfigurable(category);
- if (!providerConfigurables.isEmpty()) {
- if (configurables == null) {
- configurables = new SmartList<Configurable>();
- }
- configurables.addAll(providerConfigurables);
- }
- }
- return ContainerUtil.notNullize(configurables);
- }
-}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerSettingsPanelProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerSettingsPanelProvider.java
index 68e6de064b9a..5b0dde609e0c 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerSettingsPanelProvider.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerSettingsPanelProvider.java
@@ -16,15 +16,15 @@
package com.intellij.xdebugger.impl.settings;
import com.intellij.openapi.options.Configurable;
-import com.intellij.xdebugger.settings.XDebuggerSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
+@Deprecated
/**
- * @author nik
+ * @deprecated Use {@link com.intellij.xdebugger.settings.DebuggerConfigurableProvider}
*/
public abstract class DebuggerSettingsPanelProvider {
public int getPriority() {
@@ -36,23 +36,20 @@ public abstract class DebuggerSettingsPanelProvider {
return Collections.emptyList();
}
+ @Deprecated
+ /**
+ * @deprecated Please use {@link com.intellij.xdebugger.settings.DebuggerConfigurableProvider#generalApplied(com.intellij.xdebugger.settings.DebuggerSettingsCategory)}
+ */
public void apply() {
}
@Nullable
@Deprecated
- public Configurable getRootConfigurable() {
- return null;
- }
-
- @NotNull
- public Collection<? extends Configurable> getConfigurable(@NotNull XDebuggerSettings.Category category) {
- return Collections.emptyList();
- }
-
/**
- * General settings of category were applied
+ * @deprecated Please use {@link com.intellij.xdebugger.settings.DebuggerConfigurableProvider#getConfigurables(com.intellij.xdebugger.settings.DebuggerSettingsCategory)} and
+ * check {@link com.intellij.xdebugger.settings.DebuggerSettingsCategory#GENERAL}
*/
- public void generalApplied(@NotNull XDebuggerSettings.Category category) {
+ public Configurable getRootConfigurable() {
+ return null;
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/MergedCompositeConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/MergedCompositeConfigurable.java
index be0bdbf0ab2f..ccfc2708cb9e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/MergedCompositeConfigurable.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/MergedCompositeConfigurable.java
@@ -7,6 +7,8 @@ import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.TitledSeparator;
+import com.intellij.xdebugger.settings.DebuggerConfigurableProvider;
+import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -14,18 +16,34 @@ import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
-abstract class MergedCompositeConfigurable implements SearchableConfigurable {
+class MergedCompositeConfigurable implements SearchableConfigurable {
static final EmptyBorder BOTTOM_INSETS = new EmptyBorder(0, 0, IdeBorderFactory.TITLED_BORDER_BOTTOM_INSET, 0);
+ private static final Insets FIRST_COMPONENT_INSETS = new Insets(0, 0, IdeBorderFactory.TITLED_BORDER_BOTTOM_INSET, 0);
+ private static final Insets N_COMPONENT_INSETS = new Insets(IdeBorderFactory.TITLED_BORDER_TOP_INSET, 0, IdeBorderFactory.TITLED_BORDER_BOTTOM_INSET, 0);
+
protected final Configurable[] children;
protected JComponent rootComponent;
- protected MergedCompositeConfigurable(@NotNull Configurable[] children) {
+ private final String id;
+ private final String displayName;
+
+ public MergedCompositeConfigurable(@NotNull String id, @NotNull String displayName, @NotNull Configurable[] children) {
this.children = children;
+ this.id = id;
+ this.displayName = displayName;
}
- protected boolean isUseTitledBorder() {
- return true;
+ @NotNull
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Nls
+ @Override
+ public String getDisplayName() {
+ return displayName;
}
@Nullable
@@ -40,26 +58,47 @@ abstract class MergedCompositeConfigurable implements SearchableConfigurable {
return children.length == 1 ? children[0].getHelpTopic() : null;
}
+ /**
+ * false by default.
+ *
+ * If Ruby general settings will be without titled border in RubyMine, user could think that all other debugger categories also about Ruby.
+ */
+ protected boolean isUseTargetedProductPolicyIfSeveralChildren() {
+ return false;
+ }
+
@Nullable
@Override
public JComponent createComponent() {
if (rootComponent == null) {
+ Configurable firstConfigurable = children[0];
if (children.length == 1) {
- rootComponent = children[0].createComponent();
+ rootComponent = firstConfigurable.createComponent();
+ String rootComponentDisplayName = firstConfigurable.getDisplayName();
+ if (!StringUtil.isEmpty(rootComponentDisplayName) && !isTargetedToProduct(firstConfigurable)) {
+ rootComponent.setBorder(IdeBorderFactory.createTitledBorder(rootComponentDisplayName, false, FIRST_COMPONENT_INSETS));
+ }
}
else {
- JPanel panel = createPanel(isUseTitledBorder());
- for (Configurable child : children) {
- JComponent component = child.createComponent();
+ boolean isFirstNamed = true;
+ JPanel panel = createPanel(true);
+ for (Configurable configurable : children) {
+ JComponent component = configurable.createComponent();
assert component != null;
- if (isUseTitledBorder()) {
- String displayName = child.getDisplayName();
- if (StringUtil.isEmpty(displayName)) {
- component.setBorder(BOTTOM_INSETS);
+ String displayName = configurable.getDisplayName();
+ if (StringUtil.isEmpty(displayName)) {
+ component.setBorder(BOTTOM_INSETS);
+ }
+ else {
+ boolean addBorder = true;
+ if (isUseTargetedProductPolicyIfSeveralChildren() && isFirstNamed) {
+ isFirstNamed = false;
+ if (isTargetedToProduct(configurable)) {
+ addBorder = false;
+ }
}
- else {
- Insets insets = new Insets(children[0] == child ? 0 : IdeBorderFactory.TITLED_BORDER_TOP_INSET, 0, IdeBorderFactory.TITLED_BORDER_BOTTOM_INSET, 0);
- component.setBorder(IdeBorderFactory.createTitledBorder(displayName, false, insets));
+ if (addBorder) {
+ component.setBorder(IdeBorderFactory.createTitledBorder(displayName, false, firstConfigurable == configurable ? FIRST_COMPONENT_INSETS : N_COMPONENT_INSETS));
}
}
panel.add(component);
@@ -70,6 +109,15 @@ abstract class MergedCompositeConfigurable implements SearchableConfigurable {
return rootComponent;
}
+ static boolean isTargetedToProduct(@NotNull Configurable configurable) {
+ for (DebuggerConfigurableProvider provider : DebuggerConfigurableProvider.EXTENSION_POINT.getExtensions()) {
+ if (provider.isTargetedToProduct(configurable)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@NotNull
static JPanel createPanel(boolean isUseTitledBorder) {
int verticalGap = TitledSeparator.TOP_INSET;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java
index 489e4bd80307..f06b6bcc1107 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java
@@ -20,8 +20,8 @@ import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.ui.IdeBorderFactory;
-import com.intellij.xdebugger.impl.DebuggerSupport;
-import com.intellij.xdebugger.settings.XDebuggerSettings;
+import com.intellij.xdebugger.settings.DebuggerConfigurableProvider;
+import com.intellij.xdebugger.settings.DebuggerSettingsCategory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -77,7 +77,7 @@ abstract class SubCompositeConfigurable implements SearchableConfigurable.Parent
protected abstract DataViewsConfigurableUi createRootUi();
@NotNull
- protected abstract XDebuggerSettings.Category getCategory();
+ protected abstract DebuggerSettingsCategory getCategory();
private boolean isChildrenMerged() {
return children != null && children.length == 1;
@@ -86,7 +86,7 @@ abstract class SubCompositeConfigurable implements SearchableConfigurable.Parent
@Override
public final Configurable[] getConfigurables() {
if (children == null) {
- List<Configurable> configurables = DebuggerConfigurableProvider.getConfigurables(getCategory());
+ List<Configurable> configurables = DebuggerConfigurable.getConfigurables(getCategory());
children = configurables.toArray(new Configurable[configurables.size()]);
}
return isChildrenMerged() ? DebuggerConfigurable.EMPTY_CONFIGURABLES : children;
@@ -115,10 +115,12 @@ abstract class SubCompositeConfigurable implements SearchableConfigurable.Parent
c.setBorder(MergedCompositeConfigurable.BOTTOM_INSETS);
panel.add(c);
}
- for (Configurable child : children) {
- JComponent component = child.createComponent();
+ for (Configurable configurable : children) {
+ JComponent component = configurable.createComponent();
if (component != null) {
- component.setBorder(IdeBorderFactory.createTitledBorder(child.getDisplayName(), false));
+ if (children[0] != configurable || !MergedCompositeConfigurable.isTargetedToProduct(configurable)) {
+ component.setBorder(IdeBorderFactory.createTitledBorder(configurable.getDisplayName(), false));
+ }
panel.add(component);
}
}
@@ -164,8 +166,8 @@ abstract class SubCompositeConfigurable implements SearchableConfigurable.Parent
public final void apply() throws ConfigurationException {
if (root != null) {
root.apply(getSettings());
- for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) {
- support.getSettingsPanelProvider().generalApplied(getCategory());
+ for (DebuggerConfigurableProvider provider : DebuggerConfigurableProvider.EXTENSION_POINT.getExtensions()) {
+ provider.generalApplied(getCategory());
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerConfigurableProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerConfigurableProvider.java
new file mode 100644
index 000000000000..2a7f636784c4
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerConfigurableProvider.java
@@ -0,0 +1,74 @@
+package com.intellij.xdebugger.impl.settings;
+
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.SimpleConfigurable;
+import com.intellij.openapi.util.Getter;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.xdebugger.settings.DebuggerConfigurableProvider;
+import com.intellij.xdebugger.settings.DebuggerSettingsCategory;
+import com.intellij.xdebugger.settings.XDebuggerSettings;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.List;
+
+class XDebuggerConfigurableProvider extends DebuggerConfigurableProvider {
+ @NotNull
+ @Override
+ public Collection<? extends Configurable> getConfigurables(@NotNull DebuggerSettingsCategory category) {
+ List<Configurable> list;
+ if (category == DebuggerSettingsCategory.GENERAL) {
+ list = new SmartList<Configurable>(SimpleConfigurable.create("debugger.general", "", GeneralConfigurableUi.class, new Getter<XDebuggerGeneralSettings>() {
+ @Override
+ public XDebuggerGeneralSettings get() {
+ return XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings();
+ }
+ }));
+ }
+ else {
+ list = null;
+ }
+
+ for (XDebuggerSettings<?> settings : XDebuggerSettingsManager.getInstanceImpl().getSettingsList()) {
+ Collection<? extends Configurable> configurables = settings.createConfigurables(category);
+ if (!configurables.isEmpty()) {
+ if (list == null) {
+ list = new SmartList<Configurable>();
+ }
+ list.addAll(configurables);
+ }
+ }
+
+ if (category == DebuggerSettingsCategory.ROOT) {
+ for (XDebuggerSettings settings : XDebuggerSettingsManager.getInstanceImpl().getSettingsList()) {
+ @SuppressWarnings("deprecation")
+ Configurable configurable = settings.createConfigurable();
+ if (configurable != null) {
+ if (list == null) {
+ list = new SmartList<Configurable>();
+ }
+ list.add(configurable);
+ }
+ }
+ }
+ return ContainerUtil.notNullize(list);
+ }
+
+ @Override
+ public void generalApplied(@NotNull DebuggerSettingsCategory category) {
+ for (XDebuggerSettings<?> settings : XDebuggerSettingsManager.getInstanceImpl().getSettingsList()) {
+ settings.generalApplied(category);
+ }
+ }
+
+ @Override
+ public boolean isTargetedToProduct(@NotNull Configurable configurable) {
+ for (XDebuggerSettings<?> settings : XDebuggerSettingsManager.getInstanceImpl().getSettingsList()) {
+ if (settings.isTargetedToProduct(configurable)) {
+ return true;
+ }
+ }
+ return super.isTargetedToProduct(configurable);
+ }
+} \ No newline at end of file
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsPanelProviderImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsPanelProviderImpl.java
deleted file mode 100644
index 2e20230198c6..000000000000
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsPanelProviderImpl.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2000-2014 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.xdebugger.impl.settings;
-
-import com.intellij.openapi.options.Configurable;
-import com.intellij.util.SmartList;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.xdebugger.settings.XDebuggerSettings;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * @author nik
- */
-public class XDebuggerSettingsPanelProviderImpl extends DebuggerSettingsPanelProvider {
- @NotNull
- @Override
- public Collection<? extends Configurable> getConfigurables() {
- List<Configurable> list = new SmartList<Configurable>();
- for (XDebuggerSettings settings : XDebuggerSettingsManager.getInstanceImpl().getSettingsList()) {
- ContainerUtil.addIfNotNull(list, settings.createConfigurable());
- }
- return list;
- }
-
- @NotNull
- @Override
- public Collection<? extends Configurable> getConfigurable(@NotNull XDebuggerSettings.Category category) {
- List<Configurable> list;
- if (category == XDebuggerSettings.Category.ROOT) {
- list = new SmartList<Configurable>(new GeneralConfigurable());
- }
- else {
- list = null;
- }
-
- for (XDebuggerSettings settings : XDebuggerSettingsManager.getInstanceImpl().getSettingsList()) {
- Configurable configurable = settings.createConfigurable(category);
- if (configurable != null) {
- if (list == null) {
- list = new SmartList<Configurable>();
- }
- list.add(configurable);
- }
- }
- return ContainerUtil.notNullize(list);
- }
-
- @Override
- public void generalApplied(@NotNull XDebuggerSettings.Category category) {
- for (XDebuggerSettings settings : XDebuggerSettingsManager.getInstanceImpl().getSettingsList()) {
- settings.generalApplied(category);
- }
- }
-}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java
index 57b2e9d505e1..2134c0c8d4e1 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java
@@ -151,19 +151,21 @@ public abstract class DebuggerSessionTabBase extends LogConsoleManagerBase imple
return environment != null ? environment.getRunProfile() : null;
}
- public void toFront() {
+ public void toFront(boolean focus) {
if (!ApplicationManager.getApplication().isUnitTestMode()) {
ExecutionManager.getInstance(getProject()).getContentManager().toFrontRunContent(DefaultDebugExecutor.getDebugExecutorInstance(), myRunContentDescriptor);
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- @Override
- public void run() {
- boolean focusWnd = Registry.is("debugger.mayBringFrameToFrontOnBreakpoint");
- ProjectUtil.focusProjectWindow(getProject(), focusWnd);
- if (!focusWnd) {
- AppIcon.getInstance().requestAttention(getProject(), true);
+ if (focus) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ boolean focusWnd = Registry.is("debugger.mayBringFrameToFrontOnBreakpoint");
+ ProjectUtil.focusProjectWindow(getProject(), focusWnd);
+ if (!focusWnd) {
+ AppIcon.getInstance().requestAttention(getProject(), true);
+ }
}
- }
- });
+ });
+ }
}
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
index 2e5f8a337385..4b6bea217c54 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
@@ -27,6 +27,7 @@ import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.execution.ui.actions.CloseAction;
import com.intellij.execution.ui.layout.PlaceInGrid;
+import com.intellij.execution.ui.layout.impl.ViewImpl;
import com.intellij.icons.AllIcons;
import com.intellij.ide.actions.ContextHelpAction;
import com.intellij.idea.ActionsBundle;
@@ -37,6 +38,8 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.AppUIUtil;
import com.intellij.ui.content.Content;
+import com.intellij.ui.content.ContentManagerAdapter;
+import com.intellij.ui.content.ContentManagerEvent;
import com.intellij.ui.content.tabs.PinToolwindowTabAction;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugSession;
@@ -242,6 +245,18 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
focus.add(ActionManager.getInstance().getAction(XDebuggerActions.FOCUS_ON_BREAKPOINT));
myUi.getOptions().setAdditionalFocusActions(focus);
+ myUi.addListener(new ContentManagerAdapter() {
+ @Override
+ public void selectionChanged(ContentManagerEvent event) {
+ Content content = event.getContent();
+ if (content.isSelected() && DebuggerContentInfo.WATCHES_CONTENT.equals(content.getUserData(ViewImpl.ID))) {
+ if (myWatchesView.rebuildNeeded()) {
+ myWatchesView.processSessionEvent(XDebugView.SessionEvent.SETTINGS_CHANGED);
+ }
+ }
+ }
+ }, this);
+
rebuildViews();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
index d097b09ac3ac..fe32920a7ac6 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTree.java
@@ -35,10 +35,7 @@ import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
-import com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode;
-import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
-import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode;
+import com.intellij.xdebugger.impl.ui.tree.nodes.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -254,6 +251,12 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
if (XDEBUGGER_TREE_KEY.is(dataId)) {
return this;
}
+ if (PlatformDataKeys.PREDEFINED_TEXT.is(dataId)) {
+ XValueNodeImpl[] selectedNodes = getSelectedNodes(XValueNodeImpl.class, null);
+ if (selectedNodes.length == 1 && selectedNodes[0].getFullValueEvaluator() == null) {
+ return selectedNodes[0].getRawValue();
+ }
+ }
return null;
}
diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerSettingsTest.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerSettingsTest.java
index a4b7431d276f..942e73495f69 100644
--- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerSettingsTest.java
+++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerSettingsTest.java
@@ -15,7 +15,6 @@
*/
package com.intellij.xdebugger;
-import com.intellij.openapi.options.Configurable;
import com.intellij.testFramework.PlatformLiteFixture;
import com.intellij.util.xmlb.XmlSerializer;
import com.intellij.util.xmlb.annotations.Attribute;
@@ -23,7 +22,6 @@ import com.intellij.xdebugger.impl.XDebuggerUtilImpl;
import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager;
import com.intellij.xdebugger.settings.XDebuggerSettings;
import org.jdom.Element;
-import org.jetbrains.annotations.NotNull;
/**
* @author nik
@@ -79,11 +77,5 @@ public class XDebuggerSettingsTest extends PlatformLiteFixture {
public void loadState(final MyDebuggerSettings state) {
myOption = state.myOption;
}
-
- @Override
- @NotNull
- public Configurable createConfigurable() {
- throw new UnsupportedOperationException("'createConfigurable' not implemented in " + getClass().getName());
- }
}
}