summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java33
-rw-r--r--platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionManager.java8
-rw-r--r--platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java13
-rw-r--r--platform/analysis-api/src/com/intellij/profile/ProfileChangeAdapter.java2
-rw-r--r--platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java5
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java59
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java4
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java139
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/SmartHashMap.java (renamed from platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SmartHashMap.java)4
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java39
-rw-r--r--platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java5
-rw-r--r--platform/analysis-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java3
-rw-r--r--platform/annotations/src/org/intellij/lang/annotations/Flow.java6
-rw-r--r--platform/annotations/src/org/intellij/lang/annotations/MagicConstant.java25
-rw-r--r--platform/annotations/src/org/jetbrains/annotations/Contract.java8
-rw-r--r--platform/core-api/src/com/intellij/lang/ASTNode.java5
-rw-r--r--platform/core-api/src/com/intellij/openapi/options/SchemesManagerFactory.java10
-rw-r--r--platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java3
-rw-r--r--platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java4
-rw-r--r--platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java2
-rw-r--r--platform/core-api/src/com/intellij/openapi/util/ExecutionCallback.java3
-rw-r--r--platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java11
-rw-r--r--platform/core-api/src/com/intellij/usageView/UsageInfo.java9
-rw-r--r--platform/core-api/src/com/intellij/util/PlatformUtilsCore.java6
-rw-r--r--platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.java27
-rw-r--r--platform/core-impl/src/com/intellij/mock/MockApplicationEx.java3
-rw-r--r--platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java3
-rw-r--r--platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java3
-rw-r--r--platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java4
-rw-r--r--platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java2
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java16
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java24
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java21
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java7
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java12
-rw-r--r--platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java8
-rw-r--r--platform/core-impl/src/com/intellij/util/DocumentUtil.java4
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/OutgoingCommitsProvider.java17
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/PushSpec.java22
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java31
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/PushTarget.java1
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/Pusher.java17
-rw-r--r--platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java4
-rw-r--r--platform/dvcs-impl/dvcs-impl.iml2
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java184
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java4
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java53
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java53
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java30
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java9
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java12
-rw-r--r--platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java25
-rw-r--r--platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProject.java171
-rw-r--r--platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java109
-rw-r--r--platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVcsHelper.java228
-rw-r--r--platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVirtualFile.java191
-rw-r--r--platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java3
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java17
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java32
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java16
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/colors/FontPreferences.java7
-rw-r--r--platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java6
-rw-r--r--platform/extensions/src/com/intellij/openapi/extensions/Extensions.java11
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java6
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java8
-rw-r--r--platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java7
-rw-r--r--platform/icons/src/actions/GroupByClass.pngbin494 -> 366 bytes
-rw-r--r--platform/icons/src/actions/GroupByFile.pngbin266 -> 176 bytes
-rw-r--r--platform/icons/src/general/projectConfigurable.pngbin1076 -> 988 bytes
-rw-r--r--platform/icons/src/general/projectConfigurable@2x.pngbin1098 -> 1093 bytes
-rw-r--r--platform/icons/src/gutter/extAnnotation.pngbin322 -> 224 bytes
-rw-r--r--platform/icons/src/nodes/nativeLibrariesFolder.pngbin0 -> 295 bytes
-rw-r--r--platform/icons/src/nodes/nativeLibrariesFolder@2x.pngbin0 -> 690 bytes
-rw-r--r--platform/icons/src/nodes/nativeLibrariesFolder@2x_dark.pngbin0 -> 677 bytes
-rw-r--r--platform/icons/src/nodes/nativeLibrariesFolder_dark.pngbin0 -> 410 bytes
-rw-r--r--platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java5
-rw-r--r--platform/lang-api/src/com/intellij/execution/RunProfileStarter.java17
-rw-r--r--platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java3
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java3
-rw-r--r--platform/lang-api/src/com/intellij/execution/configurations/SimpleProgramParameters.java4
-rw-r--r--platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java41
-rw-r--r--platform/lang-api/src/com/intellij/execution/runners/BaseProgramRunner.java7
-rw-r--r--platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java17
-rw-r--r--platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java31
-rw-r--r--platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java14
-rw-r--r--platform/lang-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java9
-rw-r--r--platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java86
-rw-r--r--platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java6
-rw-r--r--platform/lang-api/src/com/intellij/lexer/CompositeLexer.java12
-rw-r--r--platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java2
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/LegacyCodeStyleSettingsManager.java1
-rw-r--r--platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementSectionRule.java12
-rw-r--r--platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java2
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/CodeStyleSchemesConfigurable.java46
-rw-r--r--platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form6
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java5
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java51
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java16
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java16
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorTracker.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java32
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java95
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java13
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java108
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java75
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java96
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java248
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java72
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java13
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java59
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/generation/GenerateByPatternDialog.java22
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactoryBase.java40
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java44
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java28
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java33
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java18
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java3
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java8
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElementImpl.java4
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java23
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java68
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java2
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixDescriptionPanel.form15
-rw-r--r--platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java7
-rw-r--r--platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java (renamed from platform/analysis-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java)11
-rw-r--r--platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java17
-rw-r--r--platform/lang-impl/src/com/intellij/conversion/impl/ui/ConvertProjectDialog.java8
-rw-r--r--platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java128
-rw-r--r--platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java (renamed from platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java)22
-rw-r--r--platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java (renamed from platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java)34
-rw-r--r--platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java11
-rw-r--r--platform/lang-impl/src/com/intellij/execution/impl/EditConfigurationsDialog.java7
-rw-r--r--platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java10
-rw-r--r--platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java10
-rw-r--r--platform/lang-impl/src/com/intellij/execution/runners/DefaultProgramRunner.java10
-rw-r--r--platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java25
-rw-r--r--platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java3
-rw-r--r--platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java10
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java2
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java31
-rw-r--r--platform/lang-impl/src/com/intellij/find/impl/livePreview/ReplacementView.java20
-rw-r--r--platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java31
-rw-r--r--platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentStrategy.java17
-rw-r--r--platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ExportableFileTemplateSettings.java15
-rw-r--r--platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java69
-rw-r--r--platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModel.java7
-rw-r--r--platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java7
-rw-r--r--platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java23
-rw-r--r--platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java81
-rw-r--r--platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java33
-rw-r--r--platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java129
-rw-r--r--platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeBuilder.java5
-rw-r--r--platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeStructure.java25
-rw-r--r--platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java15
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java2
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java22
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java9
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java12
-rw-r--r--platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeDescriptorProvider.java1
-rw-r--r--platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java13
-rw-r--r--platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java12
-rw-r--r--platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java2
-rw-r--r--platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java106
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java1
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java86
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java31
-rw-r--r--platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CheckinHandlerUtil.java12
-rw-r--r--platform/lang-impl/src/com/intellij/packageDependencies/actions/AnalyzeDependenciesOnSpecifiedTargetHandler.java2
-rw-r--r--platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeRenderer.java32
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java18
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java6
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java61
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java3
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java13
-rw-r--r--platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java22
-rw-r--r--platform/lang-impl/src/com/intellij/psi/stubs/StubIndexState.java6
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java10
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java23
-rw-r--r--platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java9
-rw-r--r--platform/lang-impl/src/com/intellij/semantic/SemServiceImpl.java12
-rw-r--r--platform/lang-impl/src/com/intellij/tools/ToolConfigurable.java16
-rw-r--r--platform/lang-impl/src/com/intellij/tools/ToolManager.java3
-rw-r--r--platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java67
-rw-r--r--platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java64
-rw-r--r--platform/lang-impl/src/com/intellij/ui/popup/PopupUpdateProcessor.java17
-rw-r--r--platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java4
-rw-r--r--platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java2
-rw-r--r--platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java2
-rw-r--r--platform/platform-api/platform-api.iml2
-rw-r--r--platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java8
-rw-r--r--platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java50
-rw-r--r--platform/platform-api/src/com/intellij/execution/configurations/PtyCommandLine.java1
-rw-r--r--platform/platform-api/src/com/intellij/execution/process/AnsiEscapeDecoder.java52
-rw-r--r--platform/platform-api/src/com/intellij/ide/UiActivity.java8
-rw-r--r--platform/platform-api/src/com/intellij/ide/UiActivityMonitor.java9
-rw-r--r--platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java25
-rw-r--r--platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java70
-rw-r--r--platform/platform-api/src/com/intellij/mock/MockProgressIndicator.java98
-rw-r--r--platform/platform-api/src/com/intellij/notification/NotificationGroup.java4
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java3
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/ActionStub.java7
-rw-r--r--platform/platform-api/src/com/intellij/openapi/actionSystem/CommonShortcuts.java12
-rw-r--r--platform/platform-api/src/com/intellij/openapi/application/ApplicationStarter.java27
-rw-r--r--platform/platform-api/src/com/intellij/openapi/application/ApplicationStarterEx.java18
-rw-r--r--platform/platform-api/src/com/intellij/openapi/diff/ActionButtonPresentation.java2
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java54
-rw-r--r--platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java89
-rw-r--r--platform/platform-api/src/com/intellij/openapi/options/ConfigurableBase.java (renamed from platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java)0
-rw-r--r--platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java3
-rw-r--r--platform/platform-api/src/com/intellij/openapi/options/ConfigurableUi.java (renamed from platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java)0
-rw-r--r--platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java8
-rw-r--r--platform/platform-api/src/com/intellij/openapi/options/SimpleConfigurable.java (renamed from platform/platform-impl/src/com/intellij/openapi/options/SimpleConfigurable.java)0
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/Banner.java3
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java88
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java38
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java8
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java21
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/MessageDialogBuilder.java1
-rw-r--r--platform/platform-api/src/com/intellij/openapi/ui/Messages.java9
-rw-r--r--platform/platform-api/src/com/intellij/openapi/util/PasswordUtil.java14
-rw-r--r--platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java14
-rw-r--r--platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java1
-rw-r--r--platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java11
-rw-r--r--platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java8
-rw-r--r--platform/platform-api/src/com/intellij/ui/GuiUtils.java32
-rw-r--r--platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java25
-rw-r--r--platform/platform-api/src/com/intellij/ui/InplaceButton.java6
-rw-r--r--platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java64
-rw-r--r--platform/platform-api/src/com/intellij/ui/ScreenUtil.java124
-rw-r--r--platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java4
-rw-r--r--platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java156
-rw-r--r--platform/platform-api/src/com/intellij/ui/table/JBTable.java4
-rw-r--r--platform/platform-api/src/com/intellij/util/PlatformUtils.java8
-rw-r--r--platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java12
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java31
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java389
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java296
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java44
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form (renamed from platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form)47
-rw-r--r--platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java386
-rw-r--r--platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java22
-rw-r--r--platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java24
-rw-r--r--platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java4
-rw-r--r--platform/platform-api/src/com/intellij/util/net/NetUtils.java2
-rw-r--r--platform/platform-api/src/com/intellij/util/proxy/CommonProxy.java45
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java14
-rw-r--r--platform/platform-api/src/com/intellij/util/ui/StatusText.java3
-rw-r--r--platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java29
-rw-r--r--platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java28
-rw-r--r--platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java6
-rw-r--r--platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java63
-rw-r--r--platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java170
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java37
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java21
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java41
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java11
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java117
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java87
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java115
-rw-r--r--platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java108
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java17
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java22
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java4
-rw-r--r--platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ide/passwordSafe/impl/providers/masterKey/MasterKeyPasswordSafe.java65
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java24
-rw-r--r--platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java57
-rw-r--r--platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form43
-rw-r--r--platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java2
-rw-r--r--platform/platform-impl/src/com/intellij/idea/IdeaApplication.java18
-rw-r--r--platform/platform-impl/src/com/intellij/notification/impl/actions/ShowDelayedMessageInternalAction.java58
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/ex/QuickListsManager.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java786
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ChameleonAction.java68
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/config/ActionBean.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java47
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java23
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java40
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java7
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java25
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/ApplicationStarterBase.java (renamed from platform/platform-api/src/com/intellij/openapi/diff/ApplicationStarterBase.java)14
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/DiffApplication.java (renamed from platform/platform-api/src/com/intellij/openapi/diff/DiffApplication.java)2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/MergeApplication.java (renamed from platform/platform-api/src/com/intellij/openapi/diff/MergeApplication.java)2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelOptions.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BaseExternalTool.java26
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtMergeFiles.java54
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java66
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java26
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java22
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java13
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java25
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java15
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java55
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorMarkupModelImpl.java34
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java37
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java13
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileDocumentManagerImpl.java19
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java54
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java244
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorProvider.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java3
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java2
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/CompositeConfigurable.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerFactoryImpl.java20
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java54
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/GlassPanel.java52
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java75
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/NodeConfigurable.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java16
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/IdeSettingsDialog.java330
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditor.java442
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsTree.java78
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.form41
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.java159
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java211
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java182
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java6
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java134
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java12
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java24
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java9
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java8
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java16
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java5
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java13
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.form4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java5
-rw-r--r--platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java1
-rw-r--r--platform/platform-impl/src/com/intellij/ui/AppUIUtil.java8
-rw-r--r--platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ui/EditorTextField.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ui/FocusTrackback.java10
-rw-r--r--platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java15
-rw-r--r--platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java10
-rwxr-xr-xplatform/platform-impl/src/com/intellij/ui/messages/SheetController.java4
-rwxr-xr-xplatform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java12
-rw-r--r--platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java6
-rw-r--r--platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java182
-rw-r--r--platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java5
-rw-r--r--platform/platform-resources-en/src/messages/ActionsBundle.properties2
-rw-r--r--platform/platform-resources-en/src/messages/IdeBundle.properties7
-rw-r--r--platform/platform-resources-en/src/messages/InspectionsBundle.properties2
-rw-r--r--platform/platform-resources-en/src/messages/OptionsBundle.properties16
-rw-r--r--platform/platform-resources-en/src/messages/UIBundle.properties2
-rw-r--r--platform/platform-resources-en/src/messages/XDebuggerBundle.properties3
-rw-r--r--platform/platform-resources/src/META-INF/LangExtensions.xml16
-rw-r--r--platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml3
-rw-r--r--platform/platform-resources/src/META-INF/PlatformExtensions.xml15
-rw-r--r--platform/platform-resources/src/META-INF/PlatformLangPlugin.xml2
-rw-r--r--platform/platform-resources/src/META-INF/VcsExtensions.xml2
-rw-r--r--platform/platform-resources/src/META-INF/XmlPlugin.xml3
-rw-r--r--platform/platform-resources/src/META-INF/mime.types4
-rw-r--r--platform/platform-resources/src/META-INF/xdebugger.xml2
-rw-r--r--platform/platform-resources/src/brokenPlugins.txt14
-rw-r--r--platform/platform-resources/src/idea/LangActions.xml3
-rw-r--r--platform/platform-resources/src/idea/PlatformActions.xml2
-rw-r--r--platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java22
-rw-r--r--platform/platform-tests/testSrc/com/intellij/execution/process/AnsiEscapeDecoderTest.java35
-rw-r--r--platform/platform-tests/testSrc/com/intellij/ide/ActivityMonitorTest.java67
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ApplicationStoreTest.java153
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java2
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/HeavyFileEditorManagerTestCase.java7
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandlerTest.java9
-rw-r--r--platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java4
-rw-r--r--platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java68
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java2
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/project/DefaultProjectTypeProvider.java35
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/project/ProjectType.java59
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/project/ProjectTypeService.java61
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java5
-rw-r--r--platform/projectModel-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java8
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java7
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java21
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerImpl.java120
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java14
-rw-r--r--platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java15
-rw-r--r--platform/projectModel-impl/src/messages/ProjectBundle.properties2
-rw-r--r--platform/remote-servers/impl/src/META-INF/RemoteServers.xml2
-rw-r--r--platform/remote-servers/impl/src/com/intellij/remoteServer/util/CloudAccountSelectionEditor.java9
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMapDecoder.java40
-rw-r--r--platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceResolver.java23
-rw-r--r--platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeStructure.java14
-rw-r--r--platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestComparisionFailedState.java21
-rw-r--r--platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java4
-rw-r--r--platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java19
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java16
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java7
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java152
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java22
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java7
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java3
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java18
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java16
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java34
-rw-r--r--platform/structuralsearch/source/messages/SSRBundle.properties6
-rw-r--r--platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java11
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/MockSchemesManagerFactory.java9
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java2
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java13
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/PlatformUltraLiteTestFixture.java14
-rw-r--r--platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java3
-rw-r--r--platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java4
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/GroupNode.java6
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java2
-rw-r--r--platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java3
-rw-r--r--platform/util-rt/src/com/intellij/openapi/util/Conditions.java10
-rw-r--r--platform/util/resources/misc/registry.properties18
-rw-r--r--platform/util/src/com/intellij/diagnostic/ThreadDumper.java27
-rw-r--r--platform/util/src/com/intellij/icons/AllIcons.java3
-rw-r--r--platform/util/src/com/intellij/openapi/application/PathManager.java2
-rw-r--r--platform/util/src/com/intellij/openapi/diagnostic/Logger.java1
-rw-r--r--platform/util/src/com/intellij/openapi/util/JDOMUtil.java42
-rw-r--r--platform/util/src/com/intellij/openapi/util/LowMemoryWatcher.java20
-rw-r--r--platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java1
-rw-r--r--platform/util/src/com/intellij/openapi/util/Ref.java2
-rw-r--r--platform/util/src/com/intellij/openapi/util/io/FileUtil.java3
-rw-r--r--platform/util/src/com/intellij/openapi/util/text/StringUtil.java14
-rw-r--r--platform/util/src/com/intellij/util/ArrayUtil.java2
-rw-r--r--platform/util/src/com/intellij/util/EnvironmentUtil.java18
-rw-r--r--platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java13
-rw-r--r--platform/util/src/com/intellij/util/concurrency/SequentialTaskExecutor.java7
-rw-r--r--platform/util/src/com/intellij/util/containers/ConcurrentInstanceMap.java4
-rw-r--r--platform/util/src/com/intellij/util/containers/ContainerUtil.java22
-rw-r--r--platform/util/src/com/intellij/util/containers/FilteringIterator.java17
-rw-r--r--platform/util/src/com/intellij/util/containers/InternalIterator.java4
-rw-r--r--platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java9
-rw-r--r--platform/util/src/com/intellij/util/xmlb/MapBinding.java8
-rw-r--r--platform/util/src/com/intellij/util/xmlb/XmlSerializer.java1
-rw-r--r--platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java21
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java17
-rw-r--r--platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManagerGate.java8
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotifier.java2
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CallbackData.java6
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java185
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/PreparedFragmentedContent.java4
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/CompoundShelfFileProcessor.java20
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelfManagerConfigurationMerger.java2
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java14
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeCleanupCheckinHandlerFactory.java5
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java6
-rw-r--r--platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java2
-rw-r--r--platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java3
-rw-r--r--platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java5
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java2
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementsManager.java8
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/FilterPrintElementsManager.java6
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdges.java73
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdgesComputer.java129
-rw-r--r--platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/FilterGraphWithHiddenNodes.java21
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java22
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java67
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java9
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java36
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java5
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java41
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java18
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/frame/XNearestSourcePosition.java22
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java23
-rw-r--r--platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java5
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java47
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java3
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java7
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java11
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java187
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java40
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java43
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java4
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java95
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form14
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java6
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java9
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java47
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java17
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java26
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java51
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java11
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java37
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java8
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java66
517 files changed, 9182 insertions, 6505 deletions
diff --git a/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java b/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java
index 893a7f3d30da..f7c4ca1bf274 100644
--- a/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.java
+++ b/platform/analysis-api/src/com/intellij/analysis/AnalysisScope.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.
@@ -80,8 +80,8 @@ public class AnalysisScope {
private boolean mySearchInLibraries = false;
@Type protected int myType;
- private Set<VirtualFile> myVFiles;
- protected Set<VirtualFile> myFilesSet;
+ private final Set<VirtualFile> myVFiles; // initial files and directories the scope is configured on
+ protected Set<VirtualFile> myFilesSet; // set of files (not directories) this scope consists of. calculated in initFilesSet()
protected boolean myIncludeTestSource = true;
@@ -92,6 +92,7 @@ public class AnalysisScope {
myModule = null;
myScope = null;
myType = PROJECT;
+ myVFiles = null;
}
public AnalysisScope(@NotNull Module module) {
@@ -101,6 +102,7 @@ public class AnalysisScope {
myScope = null;
myModule = module;
myType = MODULE;
+ myVFiles = null;
}
public AnalysisScope(@NotNull Module[] modules) {
@@ -110,6 +112,7 @@ public class AnalysisScope {
myElement = null;
myScope = null;
myType = MODULES;
+ myVFiles = null;
}
public AnalysisScope(@NotNull PsiDirectory psiDirectory) {
@@ -119,6 +122,7 @@ public class AnalysisScope {
myScope = null;
myElement = psiDirectory;
myType = DIRECTORY;
+ myVFiles = null;
}
public AnalysisScope(@NotNull PsiFile psiFile) {
@@ -128,6 +132,7 @@ public class AnalysisScope {
myModules = null;
myScope = null;
myType = FILE;
+ myVFiles = null;
}
public AnalysisScope(@NotNull SearchScope scope, @NotNull Project project) {
@@ -138,6 +143,7 @@ public class AnalysisScope {
myScope = scope;
myType = CUSTOM;
mySearchInLibraries = scope instanceof GlobalSearchScope && ((GlobalSearchScope)scope).isSearchInLibraries();
+ myVFiles = null;
}
public AnalysisScope(@NotNull Project project, @NotNull Collection<VirtualFile> virtualFiles) {
@@ -212,10 +218,11 @@ public class AnalysisScope {
}
public boolean contains(@NotNull PsiElement psiElement) {
- return contains(psiElement.getContainingFile().getVirtualFile());
+ VirtualFile file = psiElement.getContainingFile().getVirtualFile();
+ return file != null && contains(file);
}
- public boolean contains(VirtualFile file) {
+ public boolean contains(@NotNull VirtualFile file) {
if (myFilesSet == null) {
if (myType == CUSTOM) {
// optimization
@@ -289,6 +296,7 @@ public class AnalysisScope {
@Override
public Boolean compute() {
if (!myIncludeTestSource && projectFileIndex.isInTestSourceContent(fileOrDir)) return false;
+ if (isInGeneratedSources(fileOrDir, myProject)) return false;
return ((GlobalSearchScope)myScope).contains(fileOrDir);
}
}).booleanValue();
@@ -424,7 +432,7 @@ public class AnalysisScope {
return indicator == null || !indicator.isCanceled();
}
- protected static boolean shouldHighlightFile(PsiFile file) {
+ protected static boolean shouldHighlightFile(@NotNull PsiFile file) {
return ProblemHighlightFilter.shouldProcessFileInBatch(file);
}
@@ -451,11 +459,14 @@ public class AnalysisScope {
final Project project = dir.getProject();
final PsiManager psiManager = PsiManager.getInstance(project);
final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
+ //we should analyze generated source files only if the action is explicitly invoked for a directory located under generated roots
+ final boolean processGeneratedFiles = isInGeneratedSources(dir.getVirtualFile(), project);
VfsUtilCore.iterateChildrenRecursively(dir.getVirtualFile(), VirtualFileFilter.ALL, new ContentIterator() {
@Override
@SuppressWarnings({"SimplifiableIfStatement"})
public boolean processFile(@NotNull final VirtualFile fileOrDir) {
if (!myIncludeTestSource && index.isInTestSourceContent(fileOrDir)) return true;
+ if (!processGeneratedFiles && isInGeneratedSources(fileOrDir, project)) return true;
if (!fileOrDir.isDirectory()) {
return AnalysisScope.processFile(fileOrDir, visitor, psiManager, needReadAction);
}
@@ -481,6 +492,7 @@ public class AnalysisScope {
return myType;
}
+ @NotNull
public String getDisplayName() {
switch (myType) {
case CUSTOM:
@@ -515,12 +527,14 @@ public class AnalysisScope {
return "";
}
+ @NotNull
private static String getPresentableUrl(@NotNull final PsiFileSystemItem element) {
final VirtualFile virtualFile = element.getVirtualFile();
assert virtualFile != null : element;
return virtualFile.getPresentableUrl();
}
+ @NotNull
public String getShortenName(){
switch (myType) {
case CUSTOM:
@@ -589,9 +603,7 @@ public class AnalysisScope {
}
public void invalidate(){
- if (myType != VIRTUAL_FILES) {
- myFilesSet = null;
- } else {
+ if (myType == VIRTUAL_FILES) {
for (Iterator<VirtualFile> i = myVFiles.iterator(); i.hasNext();) {
final VirtualFile virtualFile = i.next();
if (virtualFile == null || !virtualFile.isValid()) {
@@ -599,6 +611,9 @@ public class AnalysisScope {
}
}
}
+ else {
+ myFilesSet = null;
+ }
}
public boolean containsSources(boolean isTest) {
diff --git a/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionManager.java b/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionManager.java
index aeb671df1e84..8aea24650b22 100644
--- a/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionManager.java
+++ b/platform/analysis-api/src/com/intellij/codeInsight/intention/IntentionManager.java
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.intention;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
@@ -24,6 +25,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -126,6 +128,12 @@ public abstract class IntentionManager {
public abstract List<IntentionAction> getStandardIntentionOptions(@NotNull HighlightDisplayKey displayKey, @NotNull PsiElement context);
/**
+ * @return "Fix all '' inspections problems for a file" intention if toolWrapper is local inspection or simple global one
+ */
+ @Nullable
+ public abstract IntentionAction createFixAllIntention(InspectionToolWrapper toolWrapper, IntentionAction action);
+
+ /**
* Wraps given action in a LocalQuickFix object.
* @param action action to convert.
* @return quick fix instance.
diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
index 43d80faad886..450b4c2a4418 100644
--- a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
+++ b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java
@@ -71,7 +71,7 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
public boolean isSuppressedFor(@NotNull PsiElement element) {
Set<InspectionSuppressor> suppressors = getSuppressors(element);
for (InspectionSuppressor suppressor : suppressors) {
- if (suppressor != null && isSuppressed(suppressor, element)) {
+ if (isSuppressed(suppressor, element)) {
return true;
}
}
@@ -99,10 +99,8 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
});
Set<InspectionSuppressor> suppressors = getSuppressors(element);
for (InspectionSuppressor suppressor : suppressors) {
- if (suppressor != null) {
- SuppressQuickFix[] actions = suppressor.getSuppressActions(element, getShortName());
- fixes.addAll(Arrays.asList(actions));
- }
+ SuppressQuickFix[] actions = suppressor.getSuppressActions(element, getShortName());
+ fixes.addAll(Arrays.asList(actions));
}
return fixes.toArray(new SuppressQuickFix[fixes.size()]);
}
@@ -121,16 +119,17 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool{
public static Set<InspectionSuppressor> getSuppressors(@NotNull PsiElement element) {
FileViewProvider viewProvider = element.getContainingFile().getViewProvider();
+ final InspectionSuppressor elementLanguageSuppressor = LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage());
if (viewProvider instanceof TemplateLanguageFileViewProvider) {
LinkedHashSet<InspectionSuppressor> suppressors = new LinkedHashSet<InspectionSuppressor>();
ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(viewProvider.getBaseLanguage()));
for (Language language : viewProvider.getLanguages()) {
ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(language));
}
- ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage()));
+ ContainerUtil.addIfNotNull(suppressors, elementLanguageSuppressor);
return suppressors;
}
- return Collections.singleton(LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage()));
+ return elementLanguageSuppressor != null ? Collections.singleton(elementLanguageSuppressor) : Collections.<InspectionSuppressor>emptySet();
}
public void cleanup(Project project) {
diff --git a/platform/analysis-api/src/com/intellij/profile/ProfileChangeAdapter.java b/platform/analysis-api/src/com/intellij/profile/ProfileChangeAdapter.java
index 7e77e3de44ac..514c18766d40 100644
--- a/platform/analysis-api/src/com/intellij/profile/ProfileChangeAdapter.java
+++ b/platform/analysis-api/src/com/intellij/profile/ProfileChangeAdapter.java
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
*/
public abstract class ProfileChangeAdapter {
public void profileChanged(Profile profile){}
- public void profileActivated(@NotNull Profile oldProfile, Profile profile){}
+ public void profileActivated(Profile oldProfile, Profile profile){}
public void profilesInitialized() {}
public void profilesShutdown(){}
}
diff --git a/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java b/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java
index 7f01ead5359f..4fed9ea06538 100644
--- a/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java
+++ b/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java
@@ -79,11 +79,14 @@ public class FilePatternPackageSet extends PatternBasedPackageSet {
matchesModule(myModuleGroupPattern, myModulePattern, file, fileIndex);
}
- private boolean fileMatcher(VirtualFile virtualFile, ProjectFileIndex fileIndex, VirtualFile projectBaseDir){
+ private boolean fileMatcher(@NotNull VirtualFile virtualFile, ProjectFileIndex fileIndex, VirtualFile projectBaseDir){
final String relativePath = getRelativePath(virtualFile, fileIndex, true, projectBaseDir);
if (relativePath == null) {
LOG.error("vFile: " + virtualFile + "; projectBaseDir: " + projectBaseDir + "; content File: "+fileIndex.getContentRootForFile(virtualFile));
}
+ if (StringUtil.isEmptyOrSpaces(relativePath) && !virtualFile.equals(projectBaseDir)) {
+ return false;
+ }
return myFilePattern.matcher(relativePath).matches();
}
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
index 483f3c5b2839..88f230f8f2d3 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
@@ -21,11 +21,9 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.IntentionManager;
import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.actions.CleanupInspectionIntention;
import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper;
import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
-import com.intellij.codeInspection.ex.QuickFixWrapper;
import com.intellij.lang.ASTNode;
import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.HighlightSeverity;
@@ -114,8 +112,7 @@ public class HighlightInfo implements Segment {
String description = this.description;
if (toolTip == null || description == null || !toolTip.contains(DESCRIPTION_PLACEHOLDER)) return toolTip;
String decoded = StringUtil.replace(toolTip, DESCRIPTION_PLACEHOLDER, XmlStringUtil.escapeString(description));
- String niceTooltip = XmlStringUtil.wrapInHtml(decoded);
- return niceTooltip;
+ return XmlStringUtil.wrapInHtml(decoded);
}
private static String encodeTooltip(String toolTip, String description) {
@@ -177,10 +174,7 @@ public class HighlightInfo implements Segment {
return forcedTextAttributes;
}
- final EditorColorsScheme colorsScheme = getColorsScheme(editorColorsScheme);
- if (colorsScheme == null) {
- return null;
- }
+ EditorColorsScheme colorsScheme = getColorsScheme(editorColorsScheme);
if (forcedTextAttributesKey != null) {
return colorsScheme.getAttributes(forcedTextAttributesKey);
@@ -208,10 +202,7 @@ public class HighlightInfo implements Segment {
if (forcedTextAttributes != null && forcedTextAttributes.getErrorStripeColor() != null) {
return forcedTextAttributes.getErrorStripeColor();
}
- final EditorColorsScheme scheme = getColorsScheme(colorsScheme);
- if (scheme == null) {
- return null;
- }
+ EditorColorsScheme scheme = getColorsScheme(colorsScheme);
if (forcedTextAttributesKey != null) {
TextAttributes forcedTextAttributes = scheme.getAttributes(forcedTextAttributesKey);
if (forcedTextAttributes != null) {
@@ -244,7 +235,7 @@ public class HighlightInfo implements Segment {
}
- @Nullable
+ @NotNull
private static EditorColorsScheme getColorsScheme(@Nullable final EditorColorsScheme customScheme) {
if (customScheme != null) {
return customScheme;
@@ -325,6 +316,7 @@ public class HighlightInfo implements Segment {
return true;
}
+ @Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof HighlightInfo)) return false;
@@ -340,7 +332,7 @@ public class HighlightInfo implements Segment {
Comparing.strEqual(info.getDescription(), getDescription());
}
- public boolean equalsByActualOffset(HighlightInfo info) {
+ public boolean equalsByActualOffset(@NotNull HighlightInfo info) {
if (info == this) return true;
return info.getSeverity() == getSeverity() &&
@@ -353,10 +345,12 @@ public class HighlightInfo implements Segment {
Comparing.strEqual(info.getDescription(), getDescription());
}
+ @Override
public int hashCode() {
return startOffset;
}
+ @Override
@NonNls
public String toString() {
return getDescription() != null ? getDescription() : "";
@@ -658,7 +652,7 @@ public class HighlightInfo implements Segment {
public static final String ANNOTATOR_INSPECTION_SHORT_NAME = "Annotator";
- private static void appendFixes(@Nullable TextRange fixedRange, @NotNull HighlightInfo info, List<Annotation.QuickFixInfo> fixes) {
+ private static void appendFixes(@Nullable TextRange fixedRange, @NotNull HighlightInfo info, @Nullable List<Annotation.QuickFixInfo> fixes) {
if (fixes != null) {
for (final Annotation.QuickFixInfo quickFixInfo : fixes) {
TextRange range = fixedRange != null ? fixedRange : quickFixInfo.textRange;
@@ -670,6 +664,7 @@ public class HighlightInfo implements Segment {
}
}
+ @NotNull
public static HighlightInfoType convertType(@NotNull Annotation annotation) {
ProblemHighlightType type = annotation.getHighlightType();
if (type == ProblemHighlightType.LIKE_UNUSED_SYMBOL) return HighlightInfoType.UNUSED_SYMBOL;
@@ -688,6 +683,7 @@ public class HighlightInfo implements Segment {
HighlightInfoType.INFORMATION;
}
+ @NotNull
public static ProblemHighlightType convertType(HighlightInfoType infoType) {
if (infoType == HighlightInfoType.ERROR || infoType == HighlightInfoType.WRONG_REF) return ProblemHighlightType.ERROR;
if (infoType == HighlightInfoType.WARNING) return ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
@@ -695,6 +691,7 @@ public class HighlightInfo implements Segment {
return ProblemHighlightType.WEAK_WARNING;
}
+ @NotNull
public static ProblemHighlightType convertSeverityToProblemHighlight(HighlightSeverity severity) {
return severity == HighlightSeverity.ERROR ? ProblemHighlightType.ERROR :
severity == HighlightSeverity.WARNING ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING :
@@ -763,7 +760,7 @@ public class HighlightInfo implements Segment {
return myAction;
}
- public boolean canCleanup(PsiElement element) {
+ public boolean canCleanup(@NotNull PsiElement element) {
if (myCanCleanup == null) {
InspectionProfile profile = InspectionProjectProfileManager.getInstance(element.getProject()).getInspectionProfile();
final HighlightDisplayKey key = myKey;
@@ -794,7 +791,8 @@ public class HighlightInfo implements Segment {
if (options != null || key == null) {
return options;
}
- List<IntentionAction> newOptions = IntentionManager.getInstance().getStandardIntentionOptions(key, element);
+ IntentionManager intentionManager = IntentionManager.getInstance();
+ List<IntentionAction> newOptions = intentionManager.getStandardIntentionOptions(key, element);
InspectionProfile profile = InspectionProjectProfileManager.getInstance(element.getProject()).getInspectionProfile();
InspectionToolWrapper toolWrapper = profile.getInspectionTool(key.toString(), element);
if (!(toolWrapper instanceof LocalInspectionToolWrapper)) {
@@ -807,29 +805,9 @@ public class HighlightInfo implements Segment {
myCanCleanup = toolWrapper.isCleanupTool();
- InspectionProfileEntry wrappedTool;
- if (toolWrapper instanceof LocalInspectionToolWrapper) {
- wrappedTool = ((LocalInspectionToolWrapper)toolWrapper).getTool();
- Class aClass = myAction.getClass();
- if (myAction instanceof QuickFixWrapper) {
- aClass = ((QuickFixWrapper)myAction).getFix().getClass();
- }
- newOptions.add(new CleanupInspectionIntention(toolWrapper, aClass));
- }
- else if (toolWrapper instanceof GlobalInspectionToolWrapper) {
- wrappedTool = ((GlobalInspectionToolWrapper)toolWrapper).getTool();
- if (wrappedTool instanceof GlobalSimpleInspectionTool && (myAction instanceof LocalQuickFix || myAction instanceof QuickFixWrapper)) {
- Class aClass = myAction.getClass();
- if (myAction instanceof QuickFixWrapper) {
- aClass = ((QuickFixWrapper)myAction).getFix().getClass();
- }
- newOptions.add(new CleanupInspectionIntention(toolWrapper, aClass));
- }
- }
- else {
- throw new AssertionError("unknown tool: " + toolWrapper+"; key: "+myKey);
- }
-
+ ContainerUtil.addIfNotNull(newOptions, intentionManager.createFixAllIntention(toolWrapper, myAction));
+ InspectionProfileEntry wrappedTool = toolWrapper instanceof LocalInspectionToolWrapper ? ((LocalInspectionToolWrapper)toolWrapper).getTool()
+ : ((GlobalInspectionToolWrapper)toolWrapper).getTool();
if (wrappedTool instanceof CustomSuppressableInspectionTool) {
final IntentionAction[] suppressActions = ((CustomSuppressableInspectionTool)wrappedTool).getSuppressActions(element);
if (suppressActions != null) {
@@ -868,6 +846,7 @@ public class HighlightInfo implements Segment {
return myDisplayName;
}
+ @Override
@NonNls
public String toString() {
String text = getAction().getText();
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java
index 90116ea84f5b..d1615b93bce6 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java
@@ -131,6 +131,7 @@ public interface HighlightInfoType {
return myAttributesKey;
}
+ @Override
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
return "HighlightInfoTypeImpl[severity=" + mySeverity + ", key=" + myAttributesKey + "]";
@@ -141,6 +142,7 @@ public interface HighlightInfoType {
myAttributesKey.writeExternal(element);
}
+ @Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -153,6 +155,7 @@ public interface HighlightInfoType {
return true;
}
+ @Override
public int hashCode() {
int result = mySeverity.hashCode();
result = 29 * result + myAttributesKey.hashCode();
@@ -187,6 +190,7 @@ public interface HighlightInfoType {
return myAttributesKey;
}
+ @Override
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
return "HighlightInfoTypeSeverityByKey[severity=" + myToolKey + ", key=" + myAttributesKey + "]";
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
index ab9581f1d7d9..713b545c6247 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/InspectionEngine.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.
@@ -25,16 +25,21 @@ import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.reference.RefManagerImpl;
import com.intellij.codeInspection.reference.RefVisitor;
import com.intellij.concurrency.JobLauncher;
+import com.intellij.lang.Language;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.ProperTextRange;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.containers.SmartHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -78,29 +83,30 @@ public class InspectionEngine {
}
@NotNull
- public static List<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionTool> tools,
+ public static List<ProblemDescriptor> inspect(@NotNull final List<LocalInspectionToolWrapper> toolWrappers,
@NotNull final PsiFile file,
@NotNull final InspectionManager iManager,
final boolean isOnTheFly,
boolean failFastOnAcquireReadAction,
@NotNull final ProgressIndicator indicator) {
- final Map<String, List<ProblemDescriptor>> problemDescriptors = inspectEx(tools, file, iManager, isOnTheFly, failFastOnAcquireReadAction, indicator);
+ final Map<String, List<ProblemDescriptor>> problemDescriptors = inspectEx(toolWrappers, file, iManager, isOnTheFly, failFastOnAcquireReadAction, indicator);
final List<ProblemDescriptor> result = new ArrayList<ProblemDescriptor>();
- for (List<ProblemDescriptor> group : problemDescriptors.values())
+ for (List<ProblemDescriptor> group : problemDescriptors.values()) {
result.addAll(group);
+ }
return result;
}
// public accessibility for Upsource
@NotNull
- public static Map<String, List<ProblemDescriptor>> inspectEx(@NotNull final List<LocalInspectionTool> tools,
+ public static Map<String, List<ProblemDescriptor>> inspectEx(@NotNull final List<LocalInspectionToolWrapper> toolWrappers,
@NotNull final PsiFile file,
@NotNull final InspectionManager iManager,
final boolean isOnTheFly,
boolean failFastOnAcquireReadAction,
@NotNull final ProgressIndicator indicator) {
- if (tools.isEmpty()) return Collections.emptyMap();
+ if (toolWrappers.isEmpty()) return Collections.emptyMap();
final Map<String, List<ProblemDescriptor>> resultDescriptors = new ConcurrentHashMap<String, List<ProblemDescriptor>>();
final List<PsiElement> elements = new ArrayList<PsiElement>();
@@ -109,32 +115,32 @@ public class InspectionEngine {
Divider.divideInsideAndOutside(file, range.getStartOffset(), range.getEndOffset(), range, elements, new ArrayList<ProperTextRange>(),
Collections.<PsiElement>emptyList(), Collections.<ProperTextRange>emptyList(), true, Condition.TRUE);
- boolean result = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(
- tools, indicator, failFastOnAcquireReadAction,
- new Processor<LocalInspectionTool>() {
- @Override
- public boolean process(final LocalInspectionTool tool) {
- ProblemsHolder holder = new ProblemsHolder(iManager, file, isOnTheFly);
- createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements, null);
-
- tool.inspectionFinished(session, holder);
-
- if (holder.hasResults()) {
- resultDescriptors.put(tool.getShortName(), ContainerUtil.filter(holder.getResults(), new Condition<ProblemDescriptor>() {
- @Override
- public boolean value(ProblemDescriptor descriptor) {
- PsiElement element = descriptor.getPsiElement();
- if (element != null) {
- return !SuppressionUtil.inspectionResultSuppressed(element, tool);
- }
- return true;
- }
- }));
- }
+ MultiMap<LocalInspectionToolWrapper, String> toolToLanguages = getToolsForElements(toolWrappers, DumbService.isDumb(file.getProject()), elements, Collections.<PsiElement>emptyList());
+ List<Map.Entry<LocalInspectionToolWrapper, Collection<String>>> entries = new ArrayList<Map.Entry<LocalInspectionToolWrapper, Collection<String>>>(toolToLanguages.entrySet());
+ Processor<Map.Entry<LocalInspectionToolWrapper, Collection<String>>> processor = new Processor<Map.Entry<LocalInspectionToolWrapper, Collection<String>>>() {
+ @Override
+ public boolean process(final Map.Entry<LocalInspectionToolWrapper, Collection<String>> entry) {
+ ProblemsHolder holder = new ProblemsHolder(iManager, file, isOnTheFly);
+ final LocalInspectionTool tool = entry.getKey().getTool();
+ Collection<String> languages = entry.getValue();
+ createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements, languages);
- return true;
+ tool.inspectionFinished(session, holder);
+
+ if (holder.hasResults()) {
+ resultDescriptors.put(tool.getShortName(), ContainerUtil.filter(holder.getResults(), new Condition<ProblemDescriptor>() {
+ @Override
+ public boolean value(ProblemDescriptor descriptor) {
+ PsiElement element = descriptor.getPsiElement();
+ return element == null || !SuppressionUtil.inspectionResultSuppressed(element, tool);
+ }
+ }));
}
- });
+
+ return true;
+ }
+ };
+ JobLauncher.getInstance().invokeConcurrentlyUnderProgress(entries, indicator, failFastOnAcquireReadAction, processor);
return resultDescriptors;
}
@@ -149,8 +155,7 @@ public class InspectionEngine {
refManager.inspectionReadActionStarted();
try {
if (toolWrapper instanceof LocalInspectionToolWrapper) {
- LocalInspectionTool localTool = ((LocalInspectionToolWrapper)toolWrapper).getTool();
- return inspect(Collections.singletonList(localTool), file, inspectionManager, false, false, new EmptyProgressIndicator());
+ return inspect(Collections.singletonList((LocalInspectionToolWrapper)toolWrapper), file, inspectionManager, false, false, new EmptyProgressIndicator());
}
if (toolWrapper instanceof GlobalInspectionToolWrapper) {
final GlobalInspectionTool globalTool = ((GlobalInspectionToolWrapper)toolWrapper).getTool();
@@ -226,4 +231,74 @@ public class InspectionEngine {
}
}
}
+
+ @NotNull
+ public static <T extends InspectionToolWrapper> MultiMap<T, String> getToolsForElements(@NotNull List<T> toolWrappers,
+ boolean checkDumbAwareness,
+ @NotNull List<PsiElement> inside,
+ @NotNull List<PsiElement> outside) {
+ Set<Language> languages = new SmartHashSet<Language>();
+ Map<String, Language> langIds = new SmartHashMap<String, Language>();
+ Set<String> dialects = new SmartHashSet<String>();
+ calculateDialects(inside, languages, langIds, dialects);
+ calculateDialects(outside, languages, langIds, dialects);
+ MultiMap<T, String> toolToLanguages = new MultiMap<T, String>() {
+ @NotNull
+ @Override
+ protected Collection<String> createCollection() {
+ return new SmartHashSet<String>();
+ }
+
+ @NotNull
+ @Override
+ protected Collection<String> createEmptyCollection() {
+ return Collections.emptySet();
+ }
+ };
+ for (T wrapper : toolWrappers) {
+ ProgressManager.checkCanceled();
+ String language = wrapper.getLanguage();
+ if (language == null) {
+ InspectionProfileEntry tool = wrapper.getTool();
+ if (!checkDumbAwareness || tool instanceof DumbAware) {
+ toolToLanguages.put(wrapper, null);
+ }
+ continue;
+ }
+ Language lang = langIds.get(language);
+ if (lang != null) {
+ InspectionProfileEntry tool = wrapper.getTool();
+ if (!checkDumbAwareness || tool instanceof DumbAware) {
+ toolToLanguages.putValue(wrapper, language);
+ if (wrapper.applyToDialects()) {
+ for (Language dialect : lang.getDialects()) {
+ toolToLanguages.putValue(wrapper, dialect.getID());
+ }
+ }
+ }
+ }
+ else if (wrapper.applyToDialects() && dialects.contains(language)) {
+ InspectionProfileEntry tool = wrapper.getTool();
+ if (!checkDumbAwareness || tool instanceof DumbAware) {
+ toolToLanguages.putValue(wrapper, language);
+ }
+ }
+ }
+ return toolToLanguages;
+ }
+
+ private static void calculateDialects(@NotNull List<PsiElement> inside,
+ @NotNull Set<Language> languages,
+ @NotNull Map<String, Language> langIds,
+ @NotNull Set<String> dialects) {
+ for (PsiElement element : inside) {
+ Language language = element.getLanguage();
+ if (languages.add(language)) {
+ langIds.put(language.getID(), language);
+ for (Language dialect : language.getDialects()) {
+ dialects.add(dialect.getID());
+ }
+ }
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SmartHashMap.java b/platform/analysis-impl/src/com/intellij/codeInspection/SmartHashMap.java
index 861df82d5d43..e66ae1ee379f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SmartHashMap.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/SmartHashMap.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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.intellij.codeInsight.daemon.impl;
+package com.intellij.codeInspection;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.IncorrectOperationException;
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java
index 35f1e4c520ad..2c230254f188 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextBase.java
@@ -21,6 +21,7 @@ import com.intellij.codeInspection.*;
import com.intellij.codeInspection.lang.GlobalInspectionContextExtension;
import com.intellij.codeInspection.lang.InspectionExtensionsFactory;
import com.intellij.codeInspection.reference.*;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
@@ -35,10 +36,7 @@ import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.profile.Profile;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiManager;
+import com.intellij.psi.*;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.util.Function;
@@ -419,10 +417,35 @@ public class GlobalInspectionContextBase extends UserDataHolderBase implements G
globalContext.codeCleanup(project, scope, profile, null, runnable, false);
}
- public static void cleanupElements(Project project, Runnable runnable, PsiElement... scope) {
- GlobalInspectionContextBase globalContext = (GlobalInspectionContextBase)InspectionManager.getInstance(project).createNewGlobalContext(false);
- final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
- globalContext.codeCleanup(project, new AnalysisScope(new LocalSearchScope(scope), project), profile, null, runnable, true);
+ public static void cleanupElements(final Project project, final Runnable runnable, final PsiElement... scope) {
+ final List<SmartPsiElementPointer<PsiElement>> elements = new ArrayList<SmartPsiElementPointer<PsiElement>>();
+ final SmartPointerManager manager = SmartPointerManager.getInstance(project);
+ for (PsiElement element : scope) {
+ elements.add(manager.createSmartPsiElementPointer(element));
+ }
+
+ Runnable cleanupRunnable = new Runnable() {
+ public void run() {
+ final List<PsiElement> psiElements = new ArrayList<PsiElement>();
+ for (SmartPsiElementPointer<PsiElement> element : elements) {
+ PsiElement psiElement = element.getElement();
+ if (psiElement != null) {
+ psiElements.add(psiElement);
+ }
+ }
+ GlobalInspectionContextBase globalContext = (GlobalInspectionContextBase)InspectionManager.getInstance(project).createNewGlobalContext(false);
+ final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
+ AnalysisScope analysisScope = new AnalysisScope(new LocalSearchScope(psiElements.toArray(new PsiElement[psiElements.size()])), project);
+ globalContext.codeCleanup(project, analysisScope, profile, null, runnable, true);
+ }
+ };
+
+ Application application = ApplicationManager.getApplication();
+ if (application.isUnitTestMode() || !application.isWriteAccessAllowed()) {
+ cleanupRunnable.run();
+ } else {
+ application.invokeLater(cleanupRunnable);
+ }
}
public void close(boolean noSuspisiousCodeFound) {
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 f31e44e96e2c..f5ef75f8197b 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java
@@ -102,10 +102,7 @@ public class RefManagerImpl extends RefManager {
}
if (scope != null) {
for (Module module : ModuleManager.getInstance(getProject()).getModules()) {
- //init all ref modules in scope
- if (scope.containsModule(module)) {
- getRefModule(module);
- }
+ getRefModule(module);
}
}
}
diff --git a/platform/analysis-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java b/platform/analysis-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java
index 7d0f203e94df..41f3c9b8e6b9 100644
--- a/platform/analysis-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java
+++ b/platform/analysis-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.NamedComponent;
import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.profile.ApplicationProfileManager;
import com.intellij.profile.Profile;
@@ -41,7 +42,7 @@ import java.util.List;
*/
public abstract class InspectionProfileManager extends ApplicationProfileManager implements SeverityProvider, NamedComponent {
@NonNls protected static final String INSPECTION_DIR = "inspection";
- @NonNls protected static final String FILE_SPEC = "$ROOT_CONFIG$/" + INSPECTION_DIR;
+ @NonNls protected static final String FILE_SPEC = StoragePathMacros.ROOT_CONFIG + '/' + INSPECTION_DIR;
private final List<ProfileChangeAdapter> myProfileChangeAdapters = ContainerUtil.createLockFreeCopyOnWriteList();
diff --git a/platform/annotations/src/org/intellij/lang/annotations/Flow.java b/platform/annotations/src/org/intellij/lang/annotations/Flow.java
index c73fa57bf9f4..212103e904c9 100644
--- a/platform/annotations/src/org/intellij/lang/annotations/Flow.java
+++ b/platform/annotations/src/org/intellij/lang/annotations/Flow.java
@@ -19,14 +19,14 @@ import org.jetbrains.annotations.NonNls;
import java.lang.annotation.*;
-@Retention(RetentionPolicy.CLASS)
-@Target({ElementType.PARAMETER, ElementType.METHOD})
/**
* This annotation assists the 'Data flow to this' feature by describing data flow
* from the method parameter to the corresponding container (e.g. <code>ArrayList.add(item)</code>)
* or from the container to the method return value (e.g. <code>Set.toArray()</code>)
* or between method parameters (e.g. <code>System.arraycopy(array1, 0, array2, length)</code>)
*/
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.PARAMETER, ElementType.METHOD})
public @interface Flow {
/**
* Denotes the source of the data flow.<br>
@@ -66,7 +66,7 @@ public @interface Flow {
/**
* true if the data source is container and we should track not the expression but its contents.<br>
* E.g. the java.util.ArrayList constructor takes the collection and stores its contents:<br>
- * {@code ArrayList(@Flow(sourceIsContainer=true, targetIsContainer=true) Collection<? extends E> collection)}<br>
+ * ArrayList(<tt><pre>{@code @Flow(sourceIsContainer=true, targetIsContainer=true) Collection<? extends E> collection }</pre></tt>) <br>
* By default it's false.
*/
boolean sourceIsContainer() default false;
diff --git a/platform/annotations/src/org/intellij/lang/annotations/MagicConstant.java b/platform/annotations/src/org/intellij/lang/annotations/MagicConstant.java
index 93f11fb116e5..c13cd9db3362 100644
--- a/platform/annotations/src/org/intellij/lang/annotations/MagicConstant.java
+++ b/platform/annotations/src/org/intellij/lang/annotations/MagicConstant.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.
@@ -84,10 +84,11 @@ public @interface MagicConstant {
/**
* @return int values (typically named constants) which are allowed here.
* E.g.
- * <tt>
+ * <tt><pre>
+ * {@code
* void setConfirmOpenNewProject(@MagicConstant(intValues = {OPEN_PROJECT_ASK, OPEN_PROJECT_NEW_WINDOW, OPEN_PROJECT_SAME_WINDOW})
* int confirmOpenNewProject);
- * </tt>
+ * }</pre></tt>
*/
long[] intValues() default {};
@@ -100,13 +101,13 @@ public @interface MagicConstant {
* @return allowed int flags (i.e. values (typically named constants) which can be combined with bitwise or operator (|).
* Also 0 and -1 are considered allowed.
* E.g.
- * <tt>
- * @MagicConstant(flags = {HierarchyEvent.PARENT_CHANGED,HierarchyEvent.DISPLAYABILITY_CHANGED,HierarchyEvent.SHOWING_CHANGED})
+ * <tt><pre>
+ * {@code @MagicConstant(flags = {HierarchyEvent.PARENT_CHANGED,HierarchyEvent.DISPLAYABILITY_CHANGED,HierarchyEvent.SHOWING_CHANGED})
* int hFlags;
*
* hFlags = 3; // not allowed
* if (hFlags & (HierarchyEvent.PARENT_CHANGED | HierarchyEvent.SHOWING_CHANGED) != 0); // OK
- * </tt>
+ * }</pre></tt>
*/
long[] flags() default {};
@@ -114,27 +115,27 @@ public @interface MagicConstant {
* @return allowed values which are defined in the specified class public static final constants.
*
* E.g.
- * <tt>
- * @MagicConstant(valuesFromClass = Cursor.class)
+ * <tt><pre>
+ * {@code @MagicConstant(valuesFromClass = Cursor.class)
* int cursorType;
*
* cursorType = 11; // not allowed;
* cursorType = Cursor.E_RESIZE_CURSOR; // OK
- * </tt>
+ * }</pre></tt>
*/
Class valuesFromClass() default void.class;
-
/**
* @return allowed int flags which are defined in the specified class public static final constants.
*
* E.g.
- * <tt>@MagicConstant(flagsFromClass = java.awt.InputEvent.class)
+ * <tt><pre>
+ * {@code @MagicConstant(flagsFromClass = java.awt.InputEvent.class)
* int eventMask;
*
* eventMask = 10; // not allowed;
* eventMask = InputEvent.CTRL_MASK | InputEvent.ALT_MASK; // OK
- * </tt>
+ * }</pre></tt>
*/
Class flagsFromClass() default void.class;
}
diff --git a/platform/annotations/src/org/jetbrains/annotations/Contract.java b/platform/annotations/src/org/jetbrains/annotations/Contract.java
index 360bf5923d91..c1d08c483f74 100644
--- a/platform/annotations/src/org/jetbrains/annotations/Contract.java
+++ b/platform/annotations/src/org/jetbrains/annotations/Contract.java
@@ -54,7 +54,13 @@ public @interface Contract {
String value() default "";
/**
- * Specifies if this method is pure, i.e. has no visible side effects. This may be used for more precise data flow analysis, and
+ * Specifies that the annotated method has no visible side effects, in the following sense.
+ * If its return value is not used, removing its invocation won't
+ * affect program state and change the semantics. Such methods shouldn't throw exceptions by design, as exceptions affect semantics.<br><br>
+ *
+ * "Invisible" side effects (such as logging) that don't affect the "important" program semantics are allowed.<br><br>
+ *
+ * This annotation may be used for more precise data flow analysis, and
* to check that the method's return value is actually used in the call place.
*/
boolean pure() default false;
diff --git a/platform/core-api/src/com/intellij/lang/ASTNode.java b/platform/core-api/src/com/intellij/lang/ASTNode.java
index fe603470ad3a..0b8be360b6a1 100644
--- a/platform/core-api/src/com/intellij/lang/ASTNode.java
+++ b/platform/core-api/src/com/intellij/lang/ASTNode.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.
@@ -291,6 +291,5 @@ public interface ASTNode extends UserDataHolder {
* @param clazz expected psi class
* @return the PSI element.
*/
- @Nullable
- <T extends PsiElement> T getPsi(Class<T> clazz);
+ <T extends PsiElement> T getPsi(@NotNull Class<T> clazz);
}
diff --git a/platform/core-api/src/com/intellij/openapi/options/SchemesManagerFactory.java b/platform/core-api/src/com/intellij/openapi/options/SchemesManagerFactory.java
index f1a090359b68..a0c0ee7dad62 100644
--- a/platform/core-api/src/com/intellij/openapi/options/SchemesManagerFactory.java
+++ b/platform/core-api/src/com/intellij/openapi/options/SchemesManagerFactory.java
@@ -19,14 +19,16 @@ import com.intellij.openapi.components.RoamingType;
import com.intellij.openapi.components.ServiceBean;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
public abstract class SchemesManagerFactory {
- public static ExtensionPointName<ServiceBean> SCHEME_OWNER = ExtensionPointName.create("com.intellij.schemeOwner");
+ public static final ExtensionPointName<ServiceBean> SCHEME_OWNER = ExtensionPointName.create("com.intellij.schemeOwner");
- public abstract <T extends Scheme, E extends ExternalizableScheme> SchemesManager<T,E> createSchemesManager(String fileSpec, SchemeProcessor<E> processor,
- RoamingType roamingType);
+ public abstract <T extends Scheme, E extends ExternalizableScheme> SchemesManager<T, E> createSchemesManager(@NotNull String fileSpec,
+ @NotNull SchemeProcessor<E> processor,
+ @NotNull RoamingType roamingType);
- public static SchemesManagerFactory getInstance(){
+ public static SchemesManagerFactory getInstance() {
return ServiceManager.getService(SchemesManagerFactory.class);
}
diff --git a/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java b/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java
index d5603b2a28ae..4225270ed4b4 100644
--- a/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.java
+++ b/platform/core-api/src/com/intellij/openapi/progress/EmptyProgressIndicator.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.
@@ -42,6 +42,7 @@ public class EmptyProgressIndicator implements ProgressIndicator {
@Override
public void cancel() {
myIsCanceled = true;
+ ProgressIndicatorProvider.canceled();
}
@Override
diff --git a/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java b/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java
index afe440b8588f..89ff2fcd48a1 100644
--- a/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java
+++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java
@@ -54,4 +54,8 @@ public abstract class ProgressIndicatorProvider {
ourInstance.doCheckCanceled();
}
}
+
+ public static void canceled() {
+ ourNeedToCheckCancel = true;
+ }
}
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 4b4ace28cd37..3f0601ba951b 100644
--- a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java
+++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java
@@ -184,7 +184,7 @@ public abstract class ProgressManager extends ProgressIndicatorProvider {
throws ProcessCanceledException {
ProgressIndicator oldIndicator = null;
- boolean set = progress != null && progress != (oldIndicator = myThreadIndicator.get());
+ boolean set = progress != null && progress != (oldIndicator = getProgressIndicator());
if (set) {
myThreadIndicator.set(progress);
}
diff --git a/platform/core-api/src/com/intellij/openapi/util/ExecutionCallback.java b/platform/core-api/src/com/intellij/openapi/util/ExecutionCallback.java
index 40572e9f6a8e..5c72eb06def3 100644
--- a/platform/core-api/src/com/intellij/openapi/util/ExecutionCallback.java
+++ b/platform/core-api/src/com/intellij/openapi/util/ExecutionCallback.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.
@@ -34,6 +34,7 @@ class ExecutionCallback {
ExecutionCallback(int executedCount) {
myCountToExecution = executedCount;
+ assert executedCount >= 1 : executedCount;
}
/**
diff --git a/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java b/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java
index 8977da50f0ec..a33cf43573e4 100644
--- a/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java
+++ b/platform/core-api/src/com/intellij/psi/util/PsiUtilCore.java
@@ -17,9 +17,11 @@ package com.intellij.psi.util;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
@@ -516,4 +518,13 @@ public class PsiUtilCore {
}
return findLanguageFromElement(elt);
}
+
+ public static Project getProjectInReadAction(@NotNull final PsiElement element) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<Project>() {
+ @Override
+ public Project compute() {
+ return element.getProject();
+ }
+ });
+ }
}
diff --git a/platform/core-api/src/com/intellij/usageView/UsageInfo.java b/platform/core-api/src/com/intellij/usageView/UsageInfo.java
index 2d3cecc3628b..e67958a21faf 100644
--- a/platform/core-api/src/com/intellij/usageView/UsageInfo.java
+++ b/platform/core-api/src/com/intellij/usageView/UsageInfo.java
@@ -246,6 +246,15 @@ public class UsageInfo {
return result;
}
+ @Override
+ public String toString() {
+ PsiReference reference = getReference();
+ if (reference == null) {
+ return super.toString();
+ }
+ return reference.getCanonicalText() + " (" + reference.getClass() + ")";
+ }
+
@Nullable
public PsiFile getFile() {
return mySmartPointer.getContainingFile();
diff --git a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
index 7e4ff81b69a1..0ea0b5a6eb60 100644
--- a/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
+++ b/platform/core-api/src/com/intellij/util/PlatformUtilsCore.java
@@ -22,7 +22,7 @@ public class PlatformUtilsCore {
public static final String IDEA_PREFIX = "idea";
public static final String COMMUNITY_PREFIX = "Idea";
public static final String APPCODE_PREFIX = "AppCode";
- public static final String CPP_PREFIX = "CppIde";
+ public static final String CLION_PREFIX = "CLion";
public static final String PYCHARM_PREFIX = "Python";
public static final String PYCHARM_PREFIX2 = "PyCharmCore";
public static final String RUBY_PREFIX = "Ruby";
@@ -59,8 +59,8 @@ public class PlatformUtilsCore {
return APPCODE_PREFIX.equals(getPlatformPrefix());
}
- public static boolean isCppIde() {
- return CPP_PREFIX.equals(getPlatformPrefix());
+ public static boolean isCLion() {
+ return CLION_PREFIX.equals(getPlatformPrefix());
}
public static boolean isPyCharm() {
diff --git a/platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.java b/platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.java
index 5889dbf48c63..2a89f73f9704 100644
--- a/platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.java
+++ b/platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.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.
@@ -54,7 +54,7 @@ public class CoreProjectEnvironment {
protected final MockProject myProject;
protected final MessageBus myMessageBus;
- public CoreProjectEnvironment(Disposable parentDisposable, CoreApplicationEnvironment applicationEnvironment) {
+ public CoreProjectEnvironment(@NotNull Disposable parentDisposable, @NotNull CoreApplicationEnvironment applicationEnvironment) {
myParentDisposable = parentDisposable;
myEnvironment = applicationEnvironment;
myProject = createProject(myEnvironment.getApplication().getPicoContainer(), myParentDisposable);
@@ -87,10 +87,13 @@ public class CoreProjectEnvironment {
myProject.registerService(DumbService.class, new MockDumbService(myProject));
}
- protected MockProject createProject(PicoContainer parent, @NotNull Disposable parentDisposable) {
+ @SuppressWarnings("MethodMayBeStatic")
+ @NotNull
+ protected MockProject createProject(@NotNull PicoContainer parent, @NotNull Disposable parentDisposable) {
return new MockProject(parent, parentDisposable);
}
+ @NotNull
protected ProjectScopeBuilder createProjectScopeBuilder() {
return new CoreProjectScopeBuilder(myProject, myFileIndexFacade);
}
@@ -99,20 +102,23 @@ public class CoreProjectEnvironment {
}
+ @NotNull
protected FileIndexFacade createFileIndexFacade() {
return new MockFileIndexFacade(myProject);
}
- protected ResolveScopeManager createResolveScopeManager(PsiManager psiManager) {
- return new MockResolveScopeManager(myProject);
+ @SuppressWarnings("MethodMayBeStatic")
+ @NotNull
+ protected ResolveScopeManager createResolveScopeManager(@NotNull PsiManager psiManager) {
+ return new MockResolveScopeManager(psiManager.getProject());
}
- public <T> void registerProjectExtensionPoint(final ExtensionPointName<T> extensionPointName,
- final Class<? extends T> aClass) {
+ public <T> void registerProjectExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName,
+ @NotNull Class<? extends T> aClass) {
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getArea(myProject), extensionPointName, aClass);
}
- public <T> void addProjectExtension(final ExtensionPointName<T> name, final T extension) {
+ public <T> void addProjectExtension(@NotNull ExtensionPointName<T> name, @NotNull final T extension) {
final ExtensionPoint<T> extensionPoint = Extensions.getArea(myProject).getExtensionPoint(name);
extensionPoint.registerExtension(extension);
Disposer.register(myParentDisposable, new Disposable() {
@@ -124,18 +130,21 @@ public class CoreProjectEnvironment {
}
- public <T> void registerProjectComponent(final Class<T> interfaceClass, final T implementation) {
+ public <T> void registerProjectComponent(@NotNull Class<T> interfaceClass, @NotNull T implementation) {
CoreApplicationEnvironment.registerComponentInstance(myProject.getPicoContainer(), interfaceClass, implementation);
}
+ @NotNull
public Disposable getParentDisposable() {
return myParentDisposable;
}
+ @NotNull
public CoreApplicationEnvironment getEnvironment() {
return myEnvironment;
}
+ @NotNull
public MockProject getProject() {
return myProject;
}
diff --git a/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java b/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java
index 7415e0d66fad..3a3ea6e8e0d7 100644
--- a/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java
+++ b/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java
@@ -20,7 +20,6 @@ import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.InvalidDataException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,7 +43,7 @@ public class MockApplicationEx extends MockApplication implements ApplicationEx
}
@Override
- public void load(String path) throws IOException, InvalidDataException {
+ public void load(String path) throws IOException {
}
@Override
diff --git a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java
index bf84725f7910..90506c071f35 100644
--- a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java
+++ b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java
@@ -38,7 +38,8 @@ public interface ApplicationEx extends Application {
* @throws IOException
* @throws InvalidDataException
*/
- void load(String optionsPath) throws IOException, InvalidDataException;
+ void load(@Nullable String optionsPath) throws IOException;
+
boolean isLoaded();
@NotNull
diff --git a/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java b/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java
index d1ed93f3a2be..ebb2896d2a8e 100644
--- a/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java
+++ b/platform/core-impl/src/com/intellij/openapi/options/AbstractSchemesManager.java
@@ -29,8 +29,7 @@ import java.util.*;
public abstract class AbstractSchemesManager<T extends Scheme, E extends ExternalizableScheme> implements SchemesManager<T,E> {
-
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.options.AbstractSchemesManager");
+ private static final Logger LOG = Logger.getInstance(AbstractSchemesManager.class);
protected final List<T> mySchemes = new ArrayList<T>();
private volatile T myCurrentScheme;
diff --git a/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java b/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java
index d548fd2412b2..132dd5b30ee4 100644
--- a/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.java
+++ b/platform/core-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorBase.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.
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.impl.ModalityStateEx;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.util.containers.ConcurrentHashSet;
import com.intellij.util.containers.DoubleArrayList;
@@ -89,6 +90,7 @@ public class AbstractProgressIndicatorBase extends UserDataHolderBase implements
@Override
public void cancel() {
myCanceled = true;
+ ProgressIndicatorProvider.canceled();
}
@Override
diff --git a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java
index 9dbd8ee9ea07..bed56c25292d 100644
--- a/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java
+++ b/platform/core-impl/src/com/intellij/psi/SingleRootFileViewProvider.java
@@ -383,7 +383,7 @@ public class SingleRootFileViewProvider extends UserDataHolderBase implements Fi
@Override
public PsiReference findReferenceAt(final int offset) {
- final PsiFileImpl psiFile = (PsiFileImpl)getPsi(getBaseLanguage());
+ final PsiFile psiFile = getPsi(getBaseLanguage());
return findReferenceAt(psiFile, offset);
}
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 13c43571decb..60bae75fbe23 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiToDocumentSynchronizer.java
@@ -69,12 +69,14 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
void syncDocument(@NotNull Document document, @NotNull PsiTreeChangeEventImpl event);
}
- private void checkPsiModificationAllowed(@NotNull final PsiTreeChangeEvent event, boolean force) {
+ private void checkPsiModificationAllowed(@NotNull final PsiTreeChangeEvent event) {
if (!toProcessPsiEvent()) return;
final PsiFile psiFile = event.getFile();
if (psiFile == null || psiFile.getNode() == null) return;
- final Document document = myPsiDocumentManager.getCachedDocument(psiFile);
+ boolean forceDocument = !psiFile.getViewProvider().isPhysical();
+ final Document document = forceDocument ? myPsiDocumentManager.getDocument(psiFile)
+ : myPsiDocumentManager.getCachedDocument(psiFile);
if (document != null && myPsiDocumentManager.isUncommited(document)) {
throw new IllegalStateException("Attempt to modify PSI for non-committed Document!");
}
@@ -132,22 +134,22 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
@Override
public void beforeChildAddition(@NotNull PsiTreeChangeEvent event) {
- checkPsiModificationAllowed(event, false);
+ checkPsiModificationAllowed(event);
}
@Override
public void beforeChildRemoval(@NotNull PsiTreeChangeEvent event) {
- checkPsiModificationAllowed(event, false);
+ checkPsiModificationAllowed(event);
}
@Override
public void beforeChildReplacement(@NotNull PsiTreeChangeEvent event) {
- checkPsiModificationAllowed(event, false);
+ checkPsiModificationAllowed(event);
}
@Override
public void beforeChildrenChange(@NotNull PsiTreeChangeEvent event) {
- checkPsiModificationAllowed(event, false);
+ checkPsiModificationAllowed(event);
}
@Override
@@ -255,7 +257,7 @@ public class PsiToDocumentSynchronizer extends PsiTreeChangeAdapter {
final PsiTreeChangeEventImpl fakeEvent = new PsiTreeChangeEventImpl(changeScope.getManager());
fakeEvent.setParent(changeScope);
fakeEvent.setFile(changeScope.getContainingFile());
- checkPsiModificationAllowed(fakeEvent, true);
+ checkPsiModificationAllowed(fakeEvent);
doSync(fakeEvent, true, new DocSyncAction() {
@Override
public void syncDocument(@NotNull Document document, @NotNull PsiTreeChangeEventImpl event) {
diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java
index 7b4e9ec210ac..6b2877d83351 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java
@@ -26,7 +26,6 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.ContentBasedFileSubstitutor;
import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypeRegistry;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
@@ -71,13 +70,6 @@ public class FileManagerImpl implements FileManager {
private final FileDocumentManager myFileDocumentManager;
private final MessageBusConnection myConnection;
- @SuppressWarnings("UnusedDeclaration")
- private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
- @Override
- public void run() {
- processQueue();
- }
- });
public FileManagerImpl(PsiManagerImpl manager, FileDocumentManager fileDocumentManager, FileIndexFacade fileIndex) {
myManager = manager;
@@ -98,6 +90,12 @@ public class FileManagerImpl implements FileManager {
}
});
Disposer.register(manager.getProject(), this);
+ LowMemoryWatcher.register(new Runnable() {
+ @Override
+ public void run() {
+ processQueue();
+ }
+ }, this);
}
private static final VirtualFile NULL = new LightVirtualFile();
@@ -412,7 +410,7 @@ public class FileManagerImpl implements FileManager {
if (myFileIndex.isExcludedFile(vFile)) return null;
}
else {
- if (FileTypeRegistry.getInstance().isFileIgnored(vFile)) return null;
+ if (myFileIndex.isUnderIgnored(vFile)) return null;
}
VirtualFile parent = vFile.getParent();
@@ -538,7 +536,13 @@ public class FileManagerImpl implements FileManager {
if (document != null && !ignoreDocument){
fileDocumentManager.reloadFromDisk(document);
}
- else{
+ else {
+ FileViewProvider latestProvider = createFileViewProvider(vFile, false);
+ if (latestProvider.getPsi(latestProvider.getBaseLanguage()) instanceof PsiBinaryFile) {
+ forceReload(vFile);
+ return;
+ }
+
PsiTreeChangeEventImpl event = new PsiTreeChangeEventImpl(myManager);
event.setParent(file);
event.setFile(file);
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
index 1d96d820328a..dabb45cd7667 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java
@@ -74,7 +74,6 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
protected PsiFile myOriginalFile = null;
private final FileViewProvider myViewProvider;
- private static final Key<Document> HARD_REFERENCE_TO_DOCUMENT = new Key<Document>("HARD_REFERENCE_TO_DOCUMENT");
private volatile Reference<StubTree> myStub;
protected final PsiManagerEx myManager;
private volatile Getter<FileElement> myTreeElementPointer; // SoftReference/WeakReference to ASTNode or a strong reference to a tree if the file is a DummyHolder
@@ -188,11 +187,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
Document cachedDocument = FileDocumentManager.getInstance().getCachedDocument(getViewProvider().getVirtualFile());
- final Document document = viewProvider.isEventSystemEnabled() ? viewProvider.getDocument() : null;
FileElement treeElement = createFileElement(viewProvider.getContents());
- if (document != null) {
- treeElement.putUserData(HARD_REFERENCE_TO_DOCUMENT, document);
- }
treeElement.setPsi(this);
List<Pair<StubBasedPsiElementBase, CompositeElement>> bindings = calcStubAstBindings(treeElement, cachedDocument);
@@ -375,12 +370,22 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
public void unloadContent() {
ApplicationManager.getApplication().assertWriteAccessAllowed();
- LOG.assertTrue(getTreeElement() != null);
clearCaches();
myViewProvider.beforeContentsSynchronized();
synchronized (PsiLock.LOCK) {
- myTreeElementPointer = null;
- clearStub("unloadContent");
+ FileElement treeElement = derefTreeElement();
+ DebugUtil.startPsiModification("unloadContent");
+ try {
+ if (treeElement != null) {
+ myTreeElementPointer = null;
+ treeElement.detachFromFile();
+ DebugUtil.onInvalidated(treeElement);
+ }
+ clearStub("unloadContent");
+ }
+ finally {
+ DebugUtil.finishPsiModification();
+ }
}
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java
index f00c15220d57..c73d0bd485ce 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java
@@ -771,8 +771,7 @@ public class CompositeElement extends TreeElement {
}
@Override
- @Nullable
- public <T extends PsiElement> T getPsi(Class<T> clazz) {
+ public <T extends PsiElement> T getPsi(@NotNull Class<T> clazz) {
return LeafElement.getPsi(clazz, getPsi(), LOG);
}
@@ -797,6 +796,10 @@ public class CompositeElement extends TreeElement {
myWrapper = psi;
}
+ protected void clearPsi() {
+ myWrapper = null;
+ }
+
public final void rawAddChildren(@NotNull TreeElement first) {
rawAddChildrenWithoutNotifications(first);
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java
index f025de75b820..76d5c421094d 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java
@@ -19,6 +19,7 @@ package com.intellij.psi.impl.source.tree;
import com.intellij.lang.ASTNode;
import com.intellij.lang.FileASTNode;
import com.intellij.openapi.util.Getter;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.source.CharTableImpl;
import com.intellij.psi.impl.source.PsiFileImpl;
@@ -28,6 +29,17 @@ import org.jetbrains.annotations.NotNull;
public class FileElement extends LazyParseableElement implements FileASTNode, Getter<FileElement> {
private volatile CharTable myCharTable = new CharTableImpl();
+ private volatile boolean myDetached;
+
+ @Override
+ protected PsiElement createPsiNoLock() {
+ return myDetached ? null : super.createPsiNoLock();
+ }
+
+ public void detachFromFile() {
+ myDetached = true;
+ clearPsi();
+ }
@Override
@NotNull
diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java
index 929737177052..011cad8a8450 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java
@@ -290,16 +290,14 @@ public abstract class LeafElement extends TreeElement {
}
@Override
- @Nullable
- public <T extends PsiElement> T getPsi(Class<T> clazz) {
+ public <T extends PsiElement> T getPsi(@NotNull Class<T> clazz) {
return getPsi(clazz, getPsi(), LOG);
}
- @Nullable
- static <T extends PsiElement> T getPsi(Class<T> clazz, PsiElement element, Logger log) {
+ static <T extends PsiElement> T getPsi(@NotNull Class<T> clazz, PsiElement element, Logger log) {
log.assertTrue(clazz.isInstance(element), "unexpected psi class. expected: " + clazz
+ " got: " + (element == null ? null : element.getClass()));
+ //noinspection unchecked
return (T)element;
}
-
}
diff --git a/platform/core-impl/src/com/intellij/util/DocumentUtil.java b/platform/core-impl/src/com/intellij/util/DocumentUtil.java
index e2c78be69a3e..df9d26c6e690 100644
--- a/platform/core-impl/src/com/intellij/util/DocumentUtil.java
+++ b/platform/core-impl/src/com/intellij/util/DocumentUtil.java
@@ -82,4 +82,8 @@ public final class DocumentUtil {
}
return startOffset;
}
+
+ public static boolean isValidOffset(int offset, @NotNull Document document) {
+ return offset >= 0 && offset <= document.getTextLength();
+ }
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/OutgoingCommitsProvider.java b/platform/dvcs-api/src/com/intellij/dvcs/push/OutgoingCommitsProvider.java
index 4532146f9b4a..33053ffe4ecf 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/OutgoingCommitsProvider.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/OutgoingCommitsProvider.java
@@ -21,15 +21,20 @@ import org.jetbrains.annotations.NotNull;
/**
* Provider for outgoing commits
*/
-public abstract class OutgoingCommitsProvider {
+public abstract class OutgoingCommitsProvider<Repo extends Repository, Source extends PushSource, Target extends PushTarget> {
/**
- * Collect outgoing commits or errors for selected repo for specified {@link PushSpec} and store to {@link OutgoingResult}
+ * Collect either outgoing commits or errors for the given repository and {@link PushSpec}.
*
- * @param initial true for first commits loading, which identify that all inside actions should be silent
- * and do not ask user about smth, a.e authorization request
+ * @param initial true for the first attempt to load commits, which happens when the push dialog just appears on the screen.
+ * If later the user modifies the push target, commits are reloaded, and {@code initial} is false.
+ * <br/>
+ * Implementations should make sure that if {@code initial} is true, no user interaction is allowed
+ * (to avoid suddenly throwing dialogs into user's face).
+ * E.g. if authentication is needed to collect outgoing changes, then the method should silently show the corresponding
+ * request in the error field of the OutgoingResult.
*/
@NotNull
- public abstract OutgoingResult getOutgoingCommits(@NotNull Repository repository,
- @NotNull PushSpec pushSpec, boolean initial);
+ public abstract OutgoingResult getOutgoingCommits(@NotNull Repo repository, @NotNull PushSpec<Source, Target> pushSpec, boolean initial);
+
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSpec.java b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSpec.java
index 81ff874979bd..e205009a4c0d 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSpec.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSpec.java
@@ -16,28 +16,32 @@
package com.intellij.dvcs.push;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
- * Specified a push from-to settings for one repository
+ * For a single repository, specifies what is pushed and where.
*/
-public class PushSpec {
+public class PushSpec<S extends PushSource, T extends PushTarget> {
- @NotNull private PushSource mySource;
- @Nullable private PushTarget myTarget;
+ @NotNull private S mySource;
+ @NotNull private T myTarget;
- public PushSpec(@NotNull PushSource source, @Nullable PushTarget target) {
+ public PushSpec(@NotNull S source, @NotNull T target) {
mySource = source;
myTarget = target;
}
@NotNull
- public PushSource getSource() {
+ public S getSource() {
return mySource;
}
- @Nullable
- public PushTarget getTarget() {
+ @NotNull
+ public T getTarget() {
return myTarget;
}
+
+ @Override
+ public String toString() {
+ return mySource + "->" + myTarget;
+ }
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java
index d6af8eec1088..fbf6f148c3b1 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/PushSupport.java
@@ -19,55 +19,56 @@ import com.intellij.dvcs.repo.Repository;
import com.intellij.dvcs.repo.RepositoryManager;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.vcs.AbstractVcs;
+import com.intellij.ui.SimpleColoredText;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Collection;
+import java.util.List;
/**
* Base class to provide vcs-specific info
*/
-public abstract class PushSupport<Repo extends Repository> {
+public abstract class PushSupport<Repo extends Repository, Source extends PushSource, Target extends PushTarget> {
- public static final ExtensionPointName<PushSupport<? extends Repository>> PUSH_SUPPORT_EP =
+ public static final ExtensionPointName<PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget>> PUSH_SUPPORT_EP =
ExtensionPointName.create("com.intellij.pushSupport");
@NotNull
public abstract AbstractVcs getVcs();
@NotNull
- public abstract Pusher getPusher();
+ public abstract Pusher<Repo, Source, Target> getPusher();
@NotNull
- public abstract OutgoingCommitsProvider getOutgoingCommitsProvider();
+ public abstract OutgoingCommitsProvider<Repo, Source, Target> getOutgoingCommitsProvider();
/**
* @return Default push destination
*/
@Nullable
- public abstract PushTarget getDefaultTarget(@NotNull Repo repository);
+ public abstract Target getDefaultTarget(@NotNull Repo repository);
/**
- * @return All remembered remote destinations used for completion
+ * @return All remote destinations which will be proposed to user in the target field completion.
+ * They will be shown in the same order as they appear in the returned list.
*/
@NotNull
- public abstract Collection<String> getTargetNames(@NotNull Repo repository);
+ public abstract List<String> getTargetNames(@NotNull Repo repository);
/**
* @return current source(branch) for repository
*/
@NotNull
- public abstract PushSource getSource(@NotNull Repo repository);
+ public abstract Source getSource(@NotNull Repo repository);
/**
- * Parse user input string, and create the valid target for push,
- * or return <code><b>null</b></code> if the target name is not valid.
+ * Parse user input string, and create the VALID target for push
*
* @see #validateSpec(Repository, PushSpec)
*/
- @Nullable
- public abstract PushTarget createTarget(@NotNull Repo repository, @NotNull String targetName);
+ @NotNull
+ public abstract Target createTarget(@NotNull Repo repository, @NotNull String targetName);
/**
* @return RepositoryManager for vcs
@@ -84,5 +85,7 @@ public abstract class PushSupport<Repo extends Repository> {
* @return null if target is valid for selected repository
*/
@Nullable
- public abstract VcsError validate(@NotNull Repository repository, @Nullable String targetToValidate);
+ public abstract VcsError validate(@NotNull Repo repository, @Nullable String targetToValidate);
+
+ public abstract SimpleColoredText renderTarget(@Nullable Target target);
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/PushTarget.java b/platform/dvcs-api/src/com/intellij/dvcs/push/PushTarget.java
index 87c7244bd77c..d7ed69d0875c 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/PushTarget.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/PushTarget.java
@@ -24,5 +24,6 @@ import org.jetbrains.annotations.NotNull;
public interface PushTarget {
@NotNull
+ //todo rename - > getName or smth
String getPresentation();
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/Pusher.java b/platform/dvcs-api/src/com/intellij/dvcs/push/Pusher.java
index 6d5fc1611030..306122537660 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/Pusher.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/Pusher.java
@@ -24,16 +24,19 @@ import java.util.Map;
/**
* Base class to execute push command.
*/
-public abstract class Pusher {
+public abstract class Pusher<Repo extends Repository, Source extends PushSource, Target extends PushTarget> {
+
/**
- * Perform push command for all repositories belonged to one vcs.
+ * Perform push for all given repositories.
*
- * @param pushSpecs specify push from and to params
- * @param vcsPushOptionValue specify additional options to push, null if not supported
- * @param force if true then execute force push
+ * @param pushSpecs push specs for each repository telling what to push and where.
+ * @param additionalOption some additional push option(s), which are received from
+ * {@link PushSupport#getVcsPushOptionsPanel() the additional panel} if the plugin has one.
+ * @param force if true then force push should be performed.
*/
- public abstract void push(@NotNull Map<Repository, PushSpec> pushSpecs,
- @Nullable VcsPushOptionValue vcsPushOptionValue,
+ public abstract void push(@NotNull Map<Repo, PushSpec<Source, Target>> pushSpecs,
+ @Nullable VcsPushOptionValue additionalOption,
boolean force);
+
}
diff --git a/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java b/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java
index de2c640d12b1..b76095629ccd 100644
--- a/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java
+++ b/platform/dvcs-api/src/com/intellij/dvcs/push/VcsError.java
@@ -40,4 +40,8 @@ public class VcsError {
myErrorHandleListener.handleError(loader);
}
}
+
+ public static VcsError createEmptyTargetError(@NotNull String name) {
+ return new VcsError("Please, specify remote push path for repository " + name + ".");
+ }
}
diff --git a/platform/dvcs-impl/dvcs-impl.iml b/platform/dvcs-impl/dvcs-impl.iml
index 43dd32b785b4..f47efef84148 100644
--- a/platform/dvcs-impl/dvcs-impl.iml
+++ b/platform/dvcs-impl/dvcs-impl.iml
@@ -4,13 +4,11 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/testFramework" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/resources" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="core-api" />
- <orderEntry type="module" module-name="testFramework" scope="TEST" />
<orderEntry type="module" module-name="vcs-impl" />
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="module" module-name="core-impl" />
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java
index 2a409e12c854..45f5c68e1d0a 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/PushController.java
@@ -29,8 +29,11 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.ui.CheckedTreeNode;
+import com.intellij.ui.SimpleColoredText;
+import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.hash.HashMap;
@@ -38,7 +41,6 @@ import com.intellij.vcs.log.VcsFullCommitDetails;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -48,15 +50,15 @@ import java.util.concurrent.atomic.AtomicReference;
public class PushController implements Disposable {
@NotNull private final Project myProject;
- @NotNull private final List<PushSupport<? extends Repository>> myPushSupports;
+ @NotNull private final List<PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget>> myPushSupports;
@NotNull private final PushLog myPushLog;
@NotNull private final VcsPushDialog myDialog;
private boolean mySingleRepoProject;
private static final int DEFAULT_CHILDREN_PRESENTATION_NUMBER = 20;
private final Map<PushSupport, MyPushOptionValueModel> myAdditionalValuesMap;
- private final Map<RepositoryNode, MyRepoModel> myView2Model = new HashMap<RepositoryNode, MyRepoModel>();
-
+ private final Map<RepositoryNode, MyRepoModel> myView2Model = new TreeMap<RepositoryNode, MyRepoModel>();
+ //todo need to sort repositories in ui tree using natural order
public PushController(@NotNull Project project,
@NotNull VcsPushDialog dialog,
@@ -72,6 +74,20 @@ public class PushController implements Disposable {
myDialog.updateButtons();
startLoadingCommits();
Disposer.register(dialog.getDisposable(), this);
+ selectFirstChecked();
+ }
+
+ private void selectFirstChecked() {
+ Map.Entry<RepositoryNode, MyRepoModel> selected =
+ ContainerUtil.find(myView2Model.entrySet(), new Condition<Map.Entry<RepositoryNode, MyRepoModel>>() {
+ @Override
+ public boolean value(Map.Entry<RepositoryNode, MyRepoModel> entry) {
+ return entry.getValue().isSelected();
+ }
+ });
+ if (selected != null) {
+ myPushLog.selectNode(selected.getKey());
+ }
}
@Nullable
@@ -80,16 +96,8 @@ public class PushController implements Disposable {
for (Map.Entry<RepositoryNode, MyRepoModel> entry : myView2Model.entrySet()) {
MyRepoModel model = entry.getValue();
if (model.isSelected()) {
- //has one or more selected roots
+ if (model.hasError()) return new ValidationInfo(model.getError().getText());
validInfo = null;
- RepositoryNode node = entry.getKey();
- PushTarget target = model.getSpec().getTarget();
- //todo add validation for model -> hasErrors, too
- if (target == null) {
- JComponent editingComponent = myPushLog.startEditNode(node);
- return new ValidationInfo("Invalid remote for repository " + DvcsUtil.getShortRepositoryName(model.getRepository()),
- editingComponent);
- }
}
}
return validInfo;
@@ -123,36 +131,44 @@ public class PushController implements Disposable {
private boolean createTreeModel(@NotNull CheckedTreeNode rootNode, @NotNull List<? extends Repository> preselectedRepositories) {
if (myPushSupports.isEmpty()) return true;
int repoCount = 0;
- for (PushSupport<? extends Repository> support : myPushSupports) {
+ for (PushSupport<? extends Repository, ? extends PushSource, ? extends PushTarget> support : myPushSupports) {
repoCount += createNodesForVcs(support, rootNode, preselectedRepositories);
}
return repoCount == 1;
}
- private <T extends Repository> int createNodesForVcs(@NotNull PushSupport<T> pushSupport,
- @NotNull CheckedTreeNode rootNode,
- @NotNull List<? extends Repository> preselectedRepositories) {
- RepositoryManager<T> repositoryManager = pushSupport.getRepositoryManager();
- List<T> repositories = repositoryManager.getRepositories();
- for (T repository : repositories) {
+ private <R extends Repository, S extends PushSource, T extends PushTarget> int createNodesForVcs(
+ @NotNull PushSupport<R, S, T> pushSupport,
+ @NotNull CheckedTreeNode rootNode,
+ @NotNull List<? extends Repository> preselectedRepositories) {
+ RepositoryManager<R> repositoryManager = pushSupport.getRepositoryManager();
+ List<R> repositories = repositoryManager.getRepositories();
+ for (R repository : repositories) {
createRepoNode(pushSupport, repository, rootNode, preselectedRepositories.contains(repository), repositories.size() == 1);
}
return repositories.size();
}
- private <T extends Repository> void createRepoNode(@NotNull final PushSupport<T> support,
- @NotNull final T repository,
- @NotNull CheckedTreeNode rootNode,
- boolean isSelected,
- boolean isSingleRepositoryProject) {
- PushTarget target = support.getDefaultTarget(repository);
- final MyRepoModel model = new MyRepoModel(repository, support, isSelected, new PushSpec(support.getSource(repository), target),
- DEFAULT_CHILDREN_PRESENTATION_NUMBER);
- RepositoryWithBranchPanel repoPanel = new RepositoryWithBranchPanel(myProject, DvcsUtil.getShortRepositoryName(repository),
+ private <R extends Repository, S extends PushSource, T extends PushTarget> void createRepoNode(@NotNull final PushSupport<R, S, T> support,
+ @NotNull final R repository,
+ @NotNull CheckedTreeNode rootNode,
+ boolean isSelected,
+ boolean isSingleRepositoryProject) {
+ T target = support.getDefaultTarget(repository);
+ String repoName = DvcsUtil.getShortRepositoryName(repository);
+ final MyRepoModel<R, S, T> model = new MyRepoModel<R, S, T>(repository, support, isSingleRepositoryProject || isSelected,
+ support.getSource(repository), target,
+ DEFAULT_CHILDREN_PRESENTATION_NUMBER);
+ if (target == null) {
+ model.setError(VcsError.createEmptyTargetError(repoName));
+ }
+ RepositoryWithBranchPanel repoPanel = new RepositoryWithBranchPanel(myProject, repoName,
support.getSource(repository).getPresentation(),
target == null ? "" : target.getPresentation(),
support.getTargetNames(repository));
- final RepositoryNode repoNode = isSingleRepositoryProject ? new SingleRepositoryNode(repoPanel) : new RepositoryNode(repoPanel);
+ final RepositoryNode repoNode = isSingleRepositoryProject
+ ? new SingleRepositoryNode(repoPanel, support.renderTarget(target))
+ : new RepositoryNode(repoPanel, support.renderTarget(target));
myView2Model.put(repoNode, model);
repoNode.setChecked(model.isSelected());
repoPanel.addRepoNodeListener(new RepositoryNodeListener() {
@@ -160,19 +176,25 @@ public class PushController implements Disposable {
public void onTargetChanged(String newValue) {
VcsError validationError = support.validate(model.getRepository(), newValue);
if (validationError == null) {
- myView2Model.get(repoNode).setSpec(new PushSpec(model.getSpec().getSource(), support.createTarget(repository, newValue)));
+ T newTarget = support.createTarget(repository, newValue);
+ repoNode.setTargetPresentation(support.renderTarget(newTarget));
+ model.setTarget(newTarget);
+ model.clearErrors();
loadCommits(model, repoNode, false);
}
else {
- //todo may be should store validation errors in model and get errors during dialog validation
- myView2Model.get(repoNode).setSpec(new PushSpec(model.getSpec().getSource(), null));
+ repoNode.setTargetPresentation(StringUtil.isEmptyOrSpaces(newValue)
+ ? support.renderTarget(null)
+ : new SimpleColoredText(newValue, SimpleTextAttributes.ERROR_ATTRIBUTES));
+ model.setError(validationError); // todo may be should accept and store errors collection, now store one major target error
+ model.setTarget(null);
}
myDialog.updateButtons();
}
@Override
public void onSelectionChanged(boolean isSelected) {
- myView2Model.get(repoNode).setSelected(isSelected);
+ model.setSelected(isSelected);
repoNode.setChecked(isSelected);
myDialog.updateButtons();
}
@@ -180,13 +202,15 @@ public class PushController implements Disposable {
rootNode.add(repoNode);
}
- private void loadCommits(@NotNull final MyRepoModel model,
- @NotNull final RepositoryNode node,
- final boolean initial) {
+ private <R extends Repository, S extends PushSource, T extends PushTarget> void loadCommits(@NotNull final MyRepoModel<R, S, T> model,
+ @NotNull final RepositoryNode node,
+ final boolean initial) {
node.stopLoading();
+ final T target = model.getTarget();
+ if (target == null) return; //todo should be removed when commit loader executor will be modified
myPushLog.startLoading(node);
final ProgressIndicator indicator = node.startLoading();
- final PushSupport support = model.getSupport();
+ final PushSupport<R, S, T> support = model.getSupport();
final AtomicReference<OutgoingResult> result = new AtomicReference<OutgoingResult>();
Task.Backgroundable task = new Task.Backgroundable(myProject, "Loading Commits", true) {
@@ -229,7 +253,7 @@ public class PushController implements Disposable {
@Override
public void run(@NotNull ProgressIndicator indicator) {
OutgoingResult outgoing = support.getOutgoingCommitsProvider()
- .getOutgoingCommits(model.getRepository(), model.getSpec(), initial);
+ .getOutgoingCommits(model.getRepository(), new PushSpec<S, T>(model.getSource(), model.getTarget()), initial);
result.compareAndSet(null, outgoing);
}
};
@@ -237,8 +261,7 @@ public class PushController implements Disposable {
ProgressManagerImpl.runProcessWithProgressAsynchronously(task, indicator, null, ModalityState.any());
}
-
- public PushLog getPushPanelInfo() {
+ public PushLog getPushPanelLog() {
return myPushLog;
}
@@ -247,22 +270,32 @@ public class PushController implements Disposable {
@Override
public void run(@NotNull ProgressIndicator indicator) {
for (PushSupport support : myPushSupports) {
- MyPushOptionValueModel additionalOptionsModel = myAdditionalValuesMap.get(support);
- support.getPusher()
- .push(collectPushInfoForVcs(support), additionalOptionsModel == null ? null : additionalOptionsModel.getCurrentValue(), force);
+ doPush(support, force);
}
}
};
task.queue();
}
+ private <R extends Repository, S extends PushSource, T extends PushTarget> void doPush(@NotNull PushSupport<R, S, T> support,
+ boolean force) {
+ MyPushOptionValueModel additionalOptionsModel = myAdditionalValuesMap.get(support);
+ VcsPushOptionValue options = additionalOptionsModel == null ? null : additionalOptionsModel.getCurrentValue();
+ Pusher<R, S, T> pusher = support.getPusher();
+ pusher.push(collectPushSpecsForVcs(support), options, force);
+ }
+
@NotNull
- private Map<Repository, PushSpec> collectPushInfoForVcs(@NotNull final PushSupport pushSupport) {
- Map<Repository, PushSpec> pushSpecs = new HashMap<Repository, PushSpec>();
+ private <R extends Repository, S extends PushSource, T extends PushTarget> Map<R, PushSpec<S, T>> collectPushSpecsForVcs(@NotNull PushSupport<R, S, T> pushSupport) {
+ Map<R, PushSpec<S, T>> pushSpecs = ContainerUtil.newHashMap();
Collection<MyRepoModel> repositoriesInformation = getSelectedRepoNode();
for (MyRepoModel repoModel : repositoriesInformation) {
if (pushSupport.equals(repoModel.getSupport())) {
- pushSpecs.put(repoModel.getRepository(), repoModel.getSpec());
+ //todo improve generics: unchecked casts
+ T target = (T)repoModel.getTarget();
+ if (target != null) {
+ pushSpecs.put((R)repoModel.getRepository(), new PushSpec<S, T>((S)repoModel.getSource(), target));
+ }
}
}
return pushSpecs;
@@ -356,38 +389,53 @@ public class PushController implements Disposable {
});
}
- private static class MyRepoModel {
- @NotNull final Repository myRepository;
- @NotNull private PushSupport mySupport;
+ private static class MyRepoModel<Repo extends Repository, S extends PushSource, T extends PushTarget> {
+ @NotNull final Repo myRepository;
+ @NotNull private PushSupport<Repo, S, T> mySupport;
+ @NotNull private final S mySource;
+ @Nullable private T myTarget;
+ @Nullable VcsError myTargetError;
- @NotNull PushSpec mySpec;
int myNumberOfShownCommits;
-
List<? extends VcsFullCommitDetails> myLoadedCommits;
boolean myIsSelected;
- public MyRepoModel(@NotNull Repository repository,
- @NotNull PushSupport supportForRepo,
- boolean isSelected,
- @NotNull PushSpec spec,
+ public MyRepoModel(@NotNull Repo repository,
+ @NotNull PushSupport<Repo, S, T> supportForRepo,
+ boolean isSelected, @NotNull S source, @Nullable T target,
int num) {
myRepository = repository;
mySupport = supportForRepo;
myIsSelected = isSelected;
- mySpec = spec;
+ mySource = source;
+ myTarget = target;
myNumberOfShownCommits = num;
}
@NotNull
- public Repository getRepository() {
+ public Repo getRepository() {
return myRepository;
}
@NotNull
- public PushSupport getSupport() {
+ public PushSupport<Repo, S, T> getSupport() {
return mySupport;
}
+ @NotNull
+ public S getSource() {
+ return mySource;
+ }
+
+ @Nullable
+ public T getTarget() {
+ return myTarget;
+ }
+
+ public void setTarget(@Nullable T target) {
+ myTarget = target;
+ }
+
public boolean isSelected() {
return myIsSelected;
}
@@ -396,13 +444,21 @@ public class PushController implements Disposable {
return myRepository.getVcs();
}
- @NotNull
- public PushSpec getSpec() {
- return mySpec;
+ @Nullable
+ public VcsError getError() {
+ return myTargetError;
+ }
+
+ public void setError(@Nullable VcsError error) {
+ myTargetError = error;
+ }
+
+ public void clearErrors() {
+ myTargetError = null;
}
- public void setSpec(@NotNull PushSpec spec) {
- mySpec = spec;
+ public boolean hasError() {
+ return myTargetError != null;
}
public void setSelected(boolean isSelected) {
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java
index 5d0d20cdc4c0..b5747de91bf7 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/EditableTreeNode.java
@@ -20,7 +20,9 @@ import org.jetbrains.annotations.NotNull;
public interface EditableTreeNode extends CustomRenderedTreeNode {
- void fireOnChange(@NotNull String value);
+ void fireOnChange();
+
+ void fireOnCancel();
void fireOnSelectionChange(boolean isSelected);
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java
index b07bf9243f8a..0b4bcb0fbef0 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/PushLog.java
@@ -31,7 +31,6 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.vcs.log.VcsFullCommitDetails;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.CellEditorListener;
@@ -56,6 +55,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
private final ChangesBrowser myChangesBrowser;
private final CheckboxTree myTree;
private final MyTreeCellRenderer myTreeCellRenderer;
+ //private final AtomicBoolean myIgnoreStopEditing = new AtomicBoolean(false);
public PushLog(Project project, CheckedTreeNode root) {
DefaultTreeModel treeModel = new DefaultTreeModel(root);
@@ -96,14 +96,17 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
treeCellEditor.addCellEditorListener(new CellEditorListener() {
@Override
public void editingStopped(ChangeEvent e) {
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode)myTree.getLastSelectedPathComponent();
+ if (node != null && node instanceof EditableTreeNode) {
+ ((EditableTreeNode)node).fireOnChange();
+ }
}
@Override
public void editingCanceled(ChangeEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)myTree.getLastSelectedPathComponent();
if (node != null && node instanceof EditableTreeNode) {
- //todo restore from appropriate editor
- ((EditableTreeNode)node).fireOnChange(((EditableTreeNode)node).getValue());
+ ((EditableTreeNode)node).fireOnCancel();
}
}
});
@@ -119,10 +122,13 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
TreePath[] nodes = myTree.getSelectionPaths();
if (nodes != null) {
ArrayList<Change> changes = new ArrayList<Change>();
- for (TreePath node : nodes) {
- Object nodeInfo = ((DefaultMutableTreeNode)node.getLastPathComponent()).getUserObject();
- if (nodeInfo instanceof VcsFullCommitDetails) {
- changes.addAll(((VcsFullCommitDetails)nodeInfo).getChanges());
+ for (TreePath path : nodes) {
+ if (path.getLastPathComponent() instanceof VcsFullCommitDetailsNode) {
+ VcsFullCommitDetailsNode commitDetailsNode = (VcsFullCommitDetailsNode)path.getLastPathComponent();
+ changes.addAll(commitDetailsNode.getUserObject().getChanges());
+ }
+ else if (path.getLastPathComponent() instanceof RepositoryNode) {
+ changes.addAll(collectAllChanges((RepositoryNode)path.getLastPathComponent()));
}
}
myChangesBrowser.getViewer().setEmptyText("No differences");
@@ -151,10 +157,29 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
add(splitter);
}
+ @NotNull
+ private static Collection<? extends Change> collectAllChanges(@NotNull RepositoryNode rootNode) {
+ ArrayList<Change> changes = new ArrayList<Change>();
+ if (rootNode.getChildCount() <= 0) return changes;
+ for (DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)rootNode.getFirstChild();
+ childNode != null;
+ childNode = (DefaultMutableTreeNode)rootNode.getChildAfter(childNode)) {
+ if (childNode instanceof VcsFullCommitDetailsNode) {
+ changes.addAll(((VcsFullCommitDetailsNode)childNode).getUserObject().getChanges());
+ }
+ }
+ return changes;
+ }
+
private void setDefaultEmptyText() {
myChangesBrowser.getViewer().setEmptyText("No commits selected");
}
+ public void selectNode(@NotNull DefaultMutableTreeNode node) {
+ TreePath selectionPath = new TreePath(node.getPath());
+ myTree.addSelectionPath(selectionPath);
+ }
+
// Make changes available for diff action
@Override
public void calcData(DataKey key, DataSink sink) {
@@ -173,7 +198,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
@Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
if (e.getKeyCode() == KeyEvent.VK_ENTER && myTree.isEditing()) {
- myTree.cancelEditing();
+ myTree.stopEditing();
return true;
}
return super.processKeyBinding(ks, e, condition, pressed);
@@ -185,6 +210,10 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
setChildren(parentNode, Collections.singleton(loading));
}
+ public JComponent getPreferredFocusedComponent() {
+ return myTree;
+ }
+
private class MyTreeCellEditor extends DefaultCellEditor {
public MyTreeCellEditor(JTextField field) {
@@ -265,6 +294,7 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
final DefaultTreeModel model = ((DefaultTreeModel)myTree.getModel());
model.nodeStructureChanged(parentNode);
TreePath path = TreeUtil.getPathFromRoot(parentNode);
+ //myIgnoreStopEditing.set(true);
if (shouldExpand) {
myTree.expandPath(path);
}
@@ -274,16 +304,15 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
}
finally {
TREE_CONSTRUCTION_LOCK.writeLock().unlock();
+ //myIgnoreStopEditing.set(false);
}
}
- @Nullable
- public JComponent startEditNode(@NotNull TreeNode node) {
+ public void startEditNode(@NotNull TreeNode node) {
TreePath path = TreeUtil.getPathFromRoot(node);
if (!myTree.isEditing()) {
+ myTree.setSelectionPath(path);
myTree.startEditingAtPath(path);
}
- return (JComponent)myTree.getCellEditor()
- .getTreeCellEditorComponent(myTree, node, false, false, false, myTree.getRowForPath(path));
}
}
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java
index 24a26ece96d9..05e752c4be85 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryNode.java
@@ -17,26 +17,27 @@ package com.intellij.dvcs.push.ui;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.ui.CheckedTreeNode;
-import com.intellij.ui.ColoredTreeCellRenderer;
-import com.intellij.ui.EditorTextField;
-import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.ui.*;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
+import java.util.ArrayList;
-public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode {
- protected final static String ENTER_REMOTE = "Enter Remote";
+public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode, Comparable<RepositoryNode> {
@NotNull private final RepositoryWithBranchPanel myRepositoryPanel;
-
+ @NotNull protected SimpleColoredText myTargetPresentation;
private ProgressIndicator myCurrentIndicator;
- public RepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel) {
+ public RepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel, @NotNull SimpleColoredText targetPresentation) {
super(repositoryPanel);
myRepositoryPanel = repositoryPanel;
+ myTargetPresentation = targetPresentation;
+ }
+
+ public void setTargetPresentation(@NotNull SimpleColoredText targetPresentation) {
+ myTargetPresentation = targetPresentation;
}
public boolean isCheckboxVisible() {
@@ -51,30 +52,38 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode
renderer.append(myRepositoryPanel.getSourceName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
renderer.append(myRepositoryPanel.getArrow(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
EditorTextField textField = myRepositoryPanel.getRemoteTextFiled();
- renderTargetName(renderer, textField, myRepositoryPanel.getRemoteTargetName());
+ renderTargetName(renderer, textField);
Insets insets = BorderFactory.createEmptyBorder().getBorderInsets(textField);
renderer.setBorder(new EmptyBorder(insets));
}
- protected void renderTargetName(@NotNull ColoredTreeCellRenderer renderer, @NotNull EditorTextField textField,
- @NotNull String targetName) {
- if (StringUtil.isEmptyOrSpaces(targetName)) {
- renderer.append(ENTER_REMOTE, SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES, textField);
- }
- else {
- renderer.append(targetName, SimpleTextAttributes.SYNTHETIC_ATTRIBUTES, textField);
+ protected void renderTargetName(@NotNull ColoredTreeCellRenderer renderer, @NotNull EditorTextField textField) {
+ ArrayList<String> strings = myTargetPresentation.getTexts();
+ ArrayList<SimpleTextAttributes> attributes = myTargetPresentation.getAttributes();
+ for (int i = 0; i < strings.size(); i++) {
+ renderer.append(strings.get(i), attributes.get(i), textField);
}
}
@Override
+ public Object getUserObject() {
+ return myRepositoryPanel;
+ }
+
+ @Override
@NotNull
public String getValue() {
return myRepositoryPanel.getRemoteTargetName();
}
@Override
- public void fireOnChange(@NotNull String value) {
- myRepositoryPanel.fireOnChange(value);
+ public void fireOnChange() {
+ myRepositoryPanel.fireOnChange();
+ }
+
+ @Override
+ public void fireOnCancel() {
+ myRepositoryPanel.fireOnCancel();
}
@Override
@@ -94,4 +103,10 @@ public class RepositoryNode extends CheckedTreeNode implements EditableTreeNode
public ProgressIndicator startLoading() {
return myCurrentIndicator = new EmptyProgressIndicator();
}
+
+ public int compareTo(@NotNull RepositoryNode repositoryNode) {
+ String name = myRepositoryPanel.getRepositoryName();
+ RepositoryWithBranchPanel panel = (RepositoryWithBranchPanel)repositoryNode.getUserObject();
+ return name.compareTo(panel.getRepositoryName());
+ }
}
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java
index c1afcdd52839..cd93d0653c36 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/RepositoryWithBranchPanel.java
@@ -36,7 +36,6 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
-import java.util.Collection;
import java.util.List;
public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCellRenderer {
@@ -48,12 +47,14 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
private final JLabel myRepositoryLabel;
private final ColoredTreeCellRenderer myTextRenderer;
@NotNull private final List<RepositoryNodeListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private String myOldDestination;
public RepositoryWithBranchPanel(Project project, @NotNull String repoName,
- @NotNull String sourceName, String targetName, @NotNull Collection<String> targetVariants) {
+ @NotNull String sourceName, String targetName, @NotNull final List<String> targetVariants) {
super();
setLayout(new BorderLayout());
myRepositoryCheckbox = new JBCheckBox();
+ myRepositoryCheckbox.setFocusable(false);
myRepositoryCheckbox.setOpaque(false);
myRepositoryCheckbox.addActionListener(new ActionListener() {
@Override
@@ -64,8 +65,14 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
myRepositoryLabel = new JLabel(repoName);
myLocalBranch = new JBLabel(sourceName);
myArrowLabel = new JLabel(" -> ");
+ myOldDestination = targetName;
TextFieldWithAutoCompletionListProvider<String> provider =
- new TextFieldWithAutoCompletion.StringsCompletionProvider(targetVariants, null);
+ new TextFieldWithAutoCompletion.StringsCompletionProvider(targetVariants, null) {
+ @Override
+ public int compare(String item1, String item2) {
+ return Integer.valueOf(ContainerUtil.indexOf(targetVariants, item1)).compareTo(ContainerUtil.indexOf(targetVariants, item2));
+ }
+ };
myDestBranchTextField = new TextFieldWithAutoCompletion<String>(project, provider, true, targetName) {
@Override
@@ -77,15 +84,17 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
protected void updateBorder(@NotNull final EditorEx editor) {
}
};
- myDestBranchTextField.setBorder(UIUtil.getTableFocusCellHighlightBorder());//getTextFieldBorder());
+ myDestBranchTextField.setBorder(UIUtil.getTableFocusCellHighlightBorder());
myDestBranchTextField.setOneLineMode(true);
myDestBranchTextField.setOpaque(true);
- myDestBranchTextField.addFocusListener(new FocusAdapter() {
+ FocusAdapter focusListener = new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
myDestBranchTextField.selectAll();
}
- });
+ };
+ myDestBranchTextField.addFocusListener(focusListener);
+ addFocusListener(focusListener);
myTextRenderer = new ColoredTreeCellRenderer() {
public void customizeCellRenderer(@NotNull JTree tree,
@@ -169,9 +178,10 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
myListeners.add(listener);
}
- public void fireOnChange(@NotNull String newValue) {
+ public void fireOnChange() {
+ myOldDestination = myDestBranchTextField.getText();
for (RepositoryNodeListener listener : myListeners) {
- listener.onTargetChanged(newValue);
+ listener.onTargetChanged(myOldDestination);
}
}
@@ -180,6 +190,10 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
listener.onSelectionChanged(isSelected);
}
}
+
+ public void fireOnCancel() {
+ myDestBranchTextField.setText(myOldDestination);
+ }
}
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java
index c566dd6f2867..81fb2bd1a9d0 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/SingleRepositoryNode.java
@@ -17,6 +17,7 @@ package com.intellij.dvcs.push.ui;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.EditorTextField;
+import com.intellij.ui.SimpleColoredText;
import com.intellij.ui.SimpleTextAttributes;
import org.jetbrains.annotations.NotNull;
@@ -28,8 +29,8 @@ public class SingleRepositoryNode extends RepositoryNode {
@NotNull private final RepositoryWithBranchPanel myRepositoryPanel;
- public SingleRepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel) {
- super(repositoryPanel);
+ public SingleRepositoryNode(@NotNull RepositoryWithBranchPanel repositoryPanel, @NotNull SimpleColoredText customTargetPresentation) {
+ super(repositoryPanel, customTargetPresentation);
myRepositoryPanel = repositoryPanel;
}
@@ -43,10 +44,8 @@ public class SingleRepositoryNode extends RepositoryNode {
renderer.append(myRepositoryPanel.getSourceName(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
renderer.append(myRepositoryPanel.getArrow(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
EditorTextField textField = myRepositoryPanel.getRemoteTextFiled();
- String targetName = myRepositoryPanel.getRemoteTargetName();
- renderTargetName(renderer, textField, targetName);
+ renderTargetName(renderer, textField);
Insets insets = BorderFactory.createEmptyBorder().getBorderInsets(textField);
renderer.setBorder(new EmptyBorder(insets));
}
-
}
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java
index 0df7af05d496..51e8aaf3e9db 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsFullCommitDetailsNode.java
@@ -17,6 +17,7 @@ package com.intellij.dvcs.push.ui;
import com.intellij.dvcs.DvcsUtil;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkHtmlRenderer;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
@@ -30,16 +31,21 @@ public class VcsFullCommitDetailsNode extends DefaultMutableTreeNode implements
@NotNull private final Project myProject;
private final VcsFullCommitDetails myCommit;
- public VcsFullCommitDetailsNode(@NotNull Project project, VcsFullCommitDetails commit) {
+ public VcsFullCommitDetailsNode(@NotNull Project project, @NotNull VcsFullCommitDetails commit) {
super(commit, false);
myProject = project;
myCommit = commit;
}
@Override
+ public VcsFullCommitDetails getUserObject() {
+ return myCommit;
+ }
+
+ @Override
public void render(@NotNull ColoredTreeCellRenderer renderer) {
- renderer
- .append(myCommit.getSubject(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_SMALLER, renderer.getForeground()));
+ String subject = StringUtil.shortenTextWithEllipsis(myCommit.getSubject(), 80, 0);
+ renderer.append(subject, new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, renderer.getForeground()));
}
public String getTooltip() {
diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java
index b441952f7a43..22f1e74abbbd 100644
--- a/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java
+++ b/platform/dvcs-impl/src/com/intellij/dvcs/push/ui/VcsPushDialog.java
@@ -15,11 +15,13 @@
*/
package com.intellij.dvcs.push.ui;
+import com.intellij.CommonBundle;
import com.intellij.dvcs.push.PushController;
import com.intellij.dvcs.push.VcsPushOptionsPanel;
import com.intellij.dvcs.repo.Repository;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.OptionAction;
import com.intellij.openapi.ui.ValidationInfo;
import net.miginfocom.swing.MigLayout;
@@ -32,8 +34,11 @@ import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
+import static com.intellij.openapi.ui.Messages.OK;
+
public class VcsPushDialog extends DialogWrapper {
+ @NotNull private final Project myProject;
private final PushLog myListPanel;
private final PushController myController;
private final Action[] myExecutorActions = {new DvcsPushAction("&Force Push", true)};
@@ -43,8 +48,9 @@ public class VcsPushDialog extends DialogWrapper {
public VcsPushDialog(@NotNull Project project, @NotNull List<? extends Repository> selectedRepositories) {
super(project);
+ myProject = project;
myController = new PushController(project, this, selectedRepositories);
- myListPanel = myController.getPushPanelInfo();
+ myListPanel = myController.getPushPanelLog();
myAdditionalOptionsFromVcsPanel = new JPanel(new MigLayout("ins 0 0, flowx"));
init();
setOKButtonText("Push");
@@ -82,6 +88,12 @@ public class VcsPushDialog extends DialogWrapper {
return actions.toArray(new Action[actions.size()]);
}
+ @Nullable
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myListPanel.getPreferredFocusedComponent();
+ }
+
@NotNull
@Override
protected Action getOKAction() {
@@ -127,6 +139,12 @@ public class VcsPushDialog extends DialogWrapper {
@Override
public void actionPerformed(ActionEvent e) {
+ if (myForce) {
+ int answer = Messages.showOkCancelDialog(myProject, getConfirmationMessage(),
+ "Force Push",
+ "&Force Push", CommonBundle.getCancelButtonText(), Messages.getWarningIcon());
+ if (answer != OK) return;
+ }
myController.push(myForce);
close(OK_EXIT_CODE);
}
@@ -141,4 +159,9 @@ public class VcsPushDialog extends DialogWrapper {
myOptions = actions;
}
}
+
+ @NotNull
+ private static String getConfirmationMessage() {
+ return "You're going to force push. It will overwrite commits at the remote. Are you sure you want to proceed?";
+ }
}
diff --git a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProject.java b/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProject.java
deleted file mode 100644
index a8dc262d7be1..000000000000
--- a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProject.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright 2000-2013 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.test;
-
-import com.intellij.openapi.components.BaseComponent;
-import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.messages.MessageBus;
-import org.jetbrains.annotations.NotNull;
-import org.picocontainer.PicoContainer;
-
-/**
- *
- * @author Kirill Likhodedov
- */
-public class MockProject implements Project {
-
- private final String myProjectDir;
-
- public MockProject(String projectDir) {
- myProjectDir = projectDir;
- }
-
- @NotNull
- @Override
- public String getName() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public VirtualFile getBaseDir() {
- return new MockVirtualFile(myProjectDir);
- }
-
- @Override
- public String getBasePath() {
- return myProjectDir;
- }
-
- @Override
- public VirtualFile getProjectFile() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public String getProjectFilePath() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getPresentableUrl() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public VirtualFile getWorkspaceFile() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public String getLocationHash() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void save() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isOpen() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isInitialized() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isDefault() {
- return false;
- }
-
- @Override
- public BaseComponent getComponent(@NotNull String name) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <T> T getComponent(@NotNull Class<T> interfaceClass) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <T> T getComponent(@NotNull Class<T> interfaceClass, T defaultImplementationIfAbsent) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean hasComponent(@NotNull Class interfaceClass) {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public <T> T[] getComponents(@NotNull Class<T> baseClass) {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public PicoContainer getPicoContainer() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public MessageBus getMessageBus() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isDisposed() {
- return false;
- }
-
- @NotNull
- @Override
- public <T> T[] getExtensions(@NotNull ExtensionPointName<T> extensionPointName) {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public Condition getDisposed() {
- return Condition.FALSE;
- }
-
- @Override
- public void dispose() {
- }
-
- @Override
- public <T> T getUserData(@NotNull Key<T> key) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <T> void putUserData(@NotNull Key<T> key, T value) {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java b/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java
deleted file mode 100644
index d89b92878f54..000000000000
--- a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockProjectRootManager.java
+++ /dev/null
@@ -1,109 +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.dvcs.test;
-
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.roots.OrderEnumerator;
-import com.intellij.openapi.roots.ProjectFileIndex;
-import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-/**
- *
- * @author Kirill Likhodedov
- */
-public class MockProjectRootManager extends ProjectRootManager {
- private final List<VirtualFile> myContentRoots = new ArrayList<VirtualFile>();
-
- @NotNull
- @Override
- public VirtualFile[] getContentRoots() {
- VirtualFile[] roots = new VirtualFile[myContentRoots.size()];
- for (int i = 0; i < myContentRoots.size(); i++) {
- roots[i] = myContentRoots.get(i);
- }
- return roots;
- }
-
- @NotNull
- @Override
- public ProjectFileIndex getFileIndex() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public OrderEnumerator orderEntries() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public OrderEnumerator orderEntries(@NotNull Collection<? extends Module> modules) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public VirtualFile[] getContentRootsFromAllModules() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public List<String> getContentRootUrls() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public VirtualFile[] getContentSourceRoots() {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public List<VirtualFile> getModuleSourceRoots(@NotNull Set<? extends JpsModuleSourceRootType<?>> rootTypes) {
- throw new UnsupportedOperationException("'getContentSourceRoots' not implemented in " + getClass().getName());
- }
-
- @Override
- public Sdk getProjectSdk() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getProjectSdkName() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setProjectSdk(Sdk sdk) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setProjectSdkName(String name) {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVcsHelper.java b/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVcsHelper.java
deleted file mode 100644
index 55e0a0e68b17..000000000000
--- a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVcsHelper.java
+++ /dev/null
@@ -1,228 +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.dvcs.test;
-
-import com.intellij.ide.errorTreeView.HotfixData;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vcs.*;
-import com.intellij.openapi.vcs.annotate.AnnotationProvider;
-import com.intellij.openapi.vcs.annotate.FileAnnotation;
-import com.intellij.openapi.vcs.changes.Change;
-import com.intellij.openapi.vcs.changes.CommitResultHandler;
-import com.intellij.openapi.vcs.changes.LocalChangeList;
-import com.intellij.openapi.vcs.history.VcsFileRevision;
-import com.intellij.openapi.vcs.history.VcsHistoryProvider;
-import com.intellij.openapi.vcs.merge.MergeDialogCustomizer;
-import com.intellij.openapi.vcs.merge.MergeProvider;
-import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
-import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.Nls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.awt.*;
-import java.io.File;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Kirill Likhodedov
- */
-public class MockVcsHelper extends AbstractVcsHelper {
- private volatile boolean myCommitDialogShown;
- private volatile boolean myMergeDialogShown;
-
- private CommitHandler myCommitHandler;
- private MergeHandler myMergeHandler;
-
- public MockVcsHelper(@NotNull Project project) {
- super(project);
- }
-
- @Override
- public void showErrors(List<VcsException> abstractVcsExceptions, @NotNull String tabDisplayName) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void showErrors(Map<HotfixData, List<VcsException>> exceptionGroups, @NotNull String tabDisplayName) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public List<VcsException> runTransactionRunnable(AbstractVcs vcs, TransactionRunnable runnable, Object vcsParameters) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void showAnnotation(FileAnnotation annotation, VirtualFile file, AbstractVcs vcs) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void showDifferences(VcsFileRevision cvsVersionOn, VcsFileRevision cvsVersionOn1, File file) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void showChangesListBrowser(CommittedChangeList changelist, @Nls String title) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void showChangesBrowser(List<CommittedChangeList> changelists) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void showChangesBrowser(List<CommittedChangeList> changelists, @Nls String title) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void showChangesBrowser(CommittedChangesProvider provider,
- RepositoryLocation location,
- @Nls String title,
- @Nullable Component parent) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void showWhatDiffersBrowser(@Nullable Component parent, Collection<Change> changes, @Nls String title) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <T extends CommittedChangeList, U extends ChangeBrowserSettings> T chooseCommittedChangeList(@NotNull CommittedChangesProvider<T, U> provider,
- RepositoryLocation location) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void openCommittedChangesTab(AbstractVcs vcs, VirtualFile root, ChangeBrowserSettings settings, int maxCount, String title) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void openCommittedChangesTab(CommittedChangesProvider provider,
- RepositoryLocation location,
- ChangeBrowserSettings settings,
- int maxCount,
- String title) {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public List<VirtualFile> showMergeDialog(List<VirtualFile> files,
- MergeProvider provider,
- @NotNull MergeDialogCustomizer mergeDialogCustomizer) {
- myMergeDialogShown = true;
- if (myMergeHandler != null) {
- myMergeHandler.showMergeDialog();
- }
- return Collections.emptyList();
- }
-
- public boolean mergeDialogWasShown() {
- return myMergeDialogShown;
- }
-
- @Override
- public void showFileHistory(VcsHistoryProvider vcsHistoryProvider, FilePath path, AbstractVcs vcs, String repositoryPath) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void showFileHistory(VcsHistoryProvider vcsHistoryProvider,
- AnnotationProvider annotationProvider,
- FilePath path,
- String repositoryPath,
- AbstractVcs vcs) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void showRollbackChangesDialog(List<Change> changes) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Collection<VirtualFile> selectFilesToProcess(List<VirtualFile> files,
- String title,
- @Nullable String prompt,
- String singleFileTitle,
- String singleFilePromptTemplate,
- VcsShowConfirmationOption confirmationOption) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Collection<FilePath> selectFilePathsToProcess(List<FilePath> files,
- String title,
- @Nullable String prompt,
- String singleFileTitle,
- String singleFilePromptTemplate,
- VcsShowConfirmationOption confirmationOption) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean commitChanges(@NotNull Collection<Change> changes, @NotNull LocalChangeList initialChangeList,
- @NotNull String commitMessage, @Nullable CommitResultHandler customResultHandler) {
- myCommitDialogShown = true;
- if (myCommitHandler != null) {
- boolean success = myCommitHandler.commit(commitMessage);
- if (customResultHandler != null) {
- if (success) {
- customResultHandler.onSuccess(commitMessage);
- }
- else {
- customResultHandler.onFailure();
- }
- }
- return success;
- }
- if (customResultHandler != null) {
- customResultHandler.onFailure();
- }
- return false;
- }
-
- public void registerHandler(CommitHandler handler) {
- myCommitHandler = handler;
- }
-
- public void registerHandler(MergeHandler handler) {
- myMergeHandler = handler;
- }
-
- public boolean commitDialogWasShown() {
- return myCommitDialogShown;
- }
-
- public interface CommitHandler {
- boolean commit(String commitMessage);
- }
-
- public interface MergeHandler {
- void showMergeDialog();
- }
-
-}
diff --git a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVirtualFile.java b/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVirtualFile.java
deleted file mode 100644
index 3b36381dcf85..000000000000
--- a/platform/dvcs-impl/testFramework/com/intellij/dvcs/test/MockVirtualFile.java
+++ /dev/null
@@ -1,191 +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.dvcs.test;
-
-import com.intellij.mock.MockVirtualFileSystem;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.FileTypes;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileSystem;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * VirtualFile implementation for tests based on {@link java.io.File}.
- * Not reusing {@link com.intellij.mock.MockVirtualFile}, because the latter holds everything in memory, which is fast, but requires
- * synchronization with the real file system.
- *
- * @author Kirill Likhodedov
- */
-public class MockVirtualFile extends VirtualFile {
-
- private static final VirtualFileSystem ourFileSystem = new MockVirtualFileSystem();
-
- private final String myPath;
-
- @NotNull
- static VirtualFile fromPath(@NotNull String absolutePath) {
- return new MockVirtualFile(FileUtil.toSystemIndependentName(absolutePath));
- }
-
- @NotNull
- static VirtualFile fromPath(@NotNull String relativePath, @NotNull Project project) {
- try {
- return fromPath(new File(project.getBaseDir().getPath() + "/" + relativePath).getCanonicalPath());
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @NotNull
- static VirtualFile fromPath(@NotNull String relativePath, @NotNull String basePath) {
- try {
- return fromPath(new File(basePath + "/" + relativePath).getCanonicalPath());
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- public MockVirtualFile(@NotNull String path) {
- myPath = FileUtil.toSystemIndependentName(path);
- }
-
- @NotNull
- @Override
- public String getName() {
- return new File(myPath).getName();
- }
-
- @NotNull
- @Override
- public VirtualFileSystem getFileSystem() {
- return ourFileSystem;
- }
-
- @NotNull
- @Override
- public String getPath() {
- return myPath;
- }
-
- @Override
- public boolean isWritable() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isDirectory() {
- return new File(myPath).isDirectory();
- }
-
- @Override
- public boolean isValid() {
- return new File(myPath).exists();
- }
-
- @Override
- @Nullable
- public VirtualFile getParent() {
- File parentFile = FileUtil.getParentFile(new File(myPath));
- return parentFile != null ? new MockVirtualFile(parentFile.getPath()) : null;
- }
-
- @Override
- public VirtualFile[] getChildren() {
- String[] list = new File(myPath).list();
- if (list == null) {
- return EMPTY_ARRAY;
- }
- VirtualFile[] files = new VirtualFile[list.length];
- for (int i = 0; i < list.length; i++) {
- files[i] = new MockVirtualFile(myPath + "/" + list[i]);
- }
- return files;
- }
-
- @NotNull
- @Override
- public OutputStream getOutputStream(Object requestor, long newModificationStamp, long newTimeStamp) {
- throw new UnsupportedOperationException();
- }
-
- @NotNull
- @Override
- public byte[] contentsToByteArray() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long getTimeStamp() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long getLength() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void refresh(boolean asynchronous, boolean recursive, Runnable postRunnable) {
- }
-
- @Override
- public InputStream getInputStream() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String toString() {
- return myPath;
- }
-
- @NotNull
- @Override
- public String getUrl() {
- return myPath;
- }
-
- @NotNull
- @Override
- public FileType getFileType() {
- return FileTypes.PLAIN_TEXT;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- MockVirtualFile file = (MockVirtualFile)o;
-
- return myPath.equals(file.myPath);
- }
-
- @Override
- public int hashCode() {
- return myPath.hashCode();
- }
-
-}
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 aff6216c3dba..9f5f5d5720da 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
@@ -64,7 +64,8 @@ public class UISettings extends SimpleModificationTracker implements PersistentS
*/
public static UISettings getShadowInstance() {
Application application = ApplicationManager.getApplication();
- return application != null ? getInstance() : new UISettings();
+ UISettings settings = application == null ? null : application.getComponent(UISettings.class);
+ return settings == null ? new UISettings() : settings;
}
@Property(filter = FontFilter.class) public String FONT_FACE;
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java
index 5577664bf9f7..ee850c3fe060 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/ActionManager.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.project.ProjectType;
import com.intellij.openapi.util.ActionCallback;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -80,7 +81,7 @@ public abstract class ActionManager implements ApplicationComponent {
* @param actionId Id of the registered action
*
* @return Action associated with the specified actionId, <code>null</code> if
- * there is no actions associated with the speicified actionId
+ * there is no actions associated with the specified actionId
*
* @exception java.lang.IllegalArgumentException if <code>actionId</code> is <code>null</code>
*
@@ -89,6 +90,20 @@ public abstract class ActionManager implements ApplicationComponent {
public abstract AnAction getAction(@NonNls @NotNull String actionId);
/**
+ * Returns action associated with the specified actionId.
+ *
+ * @param actionId Id of the registered action
+ *
+ * @return Action associated with the specified actionId, <code>null</code> if
+ * there is no actions associated with the specified actionId
+ *
+ * @exception java.lang.IllegalArgumentException if <code>actionId</code> is <code>null</code>
+ *
+ * @see com.intellij.openapi.actionSystem.IdeActions
+ */
+ public abstract AnAction getAction(@NonNls @NotNull String actionId, @Nullable ProjectType projectType);
+
+ /**
* Returns actionId associated with the specified action.
*
* @return id associated with the specified action, <code>null</code> if action
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java
index ba0743b4cfb0..fc824844be6e 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/Caret.java
@@ -198,6 +198,8 @@ public interface Caret extends UserDataHolderEx, Disposable {
/**
* Selects the specified range of text.
+ * <p>
+ * System selection will be updated, if such feature is supported by current editor.
*
* @param startOffset the start offset of the text range to select.
* @param endOffset the end offset of the text range to select.
@@ -205,11 +207,22 @@ public interface Caret extends UserDataHolderEx, Disposable {
void setSelection(int startOffset, int endOffset);
/**
+ * Selects the specified range of text.
+ *
+ * @param startOffset the start offset of the text range to select.
+ * @param endOffset the end offset of the text range to select.
+ * @param updateSystemSelection whether system selection should be updated (might not have any effect if current editor doesn't support such a feature)
+ */
+ void setSelection(int startOffset, int endOffset, boolean updateSystemSelection);
+
+ /**
* Selects target range providing information about visual boundary of selection end.
* <p/>
* That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
* <p/>
* Also, in column mode this method allows to create selection spanning virtual space after the line end.
+ * <p>
+ * System selection will be updated, if such feature is supported by current editor.
*
* @param startOffset start selection offset
* @param endPosition end visual position of the text range to select (<code>null</code> argument means that
@@ -224,6 +237,8 @@ public interface Caret extends UserDataHolderEx, Disposable {
* That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
* <p/>
* Also, in column mode this method allows to create selection spanning virtual space after the line end.
+ * <p>
+ * System selection will be updated, if such feature is supported by current editor.
*
* @param startPosition start visual position of the text range to select (<code>null</code> argument means that
* no specific visual position should be used)
@@ -235,6 +250,23 @@ public interface Caret extends UserDataHolderEx, Disposable {
void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset);
/**
+ * Selects target range based on its visual boundaries.
+ * <p/>
+ * That is the case for soft wraps-aware processing where the whole soft wraps virtual space is matched to the same offset.
+ * <p/>
+ * Also, in column mode this method allows to create selection spanning virtual space after the line end.
+ *
+ * @param startPosition start visual position of the text range to select (<code>null</code> argument means that
+ * no specific visual position should be used)
+ * @param endPosition end visual position of the text range to select (<code>null</code> argument means that
+ * no specific visual position should be used)
+ * @param startOffset start selection offset
+ * @param endOffset end selection offset
+ * @param updateSystemSelection whether system selection should be updated (might not have any effect if current editor doesn't support such a feature)
+ */
+ void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset, boolean updateSystemSelection);
+
+ /**
* Removes the selection in the editor.
*/
void removeSelection();
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java
index df247d5be401..a5053923fa31 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/CaretModel.java
@@ -222,6 +222,8 @@ public interface CaretModel {
* selection boundaries will mean that corresponding caret's position and/or selection won't be changed.
* <p>
* If multiple carets are not supported, the behaviour is unspecified.
+ * <p>
+ * System selection will be updated, if such feature is supported by current editor.
*
* @see #supportsMultipleCarets()
* @see #getCaretsAndSelections()
@@ -229,6 +231,20 @@ public interface CaretModel {
void setCaretsAndSelections(@NotNull List<CaretState> caretStates);
/**
+ * Sets the number of carets, their positions and selection ranges according to the provided data. Null values for caret position or
+ * selection boundaries will mean that corresponding caret's position and/or selection won't be changed.
+ * <p>
+ * If multiple carets are not supported, the behaviour is unspecified.
+ * <p>
+ * System selection will be updated, if such feature is supported by current editor
+ * and corresponding invocation parameter is set to <code>true</code>.
+ *
+ * @see #supportsMultipleCarets()
+ * @see #getCaretsAndSelections()
+ */
+ void setCaretsAndSelections(@NotNull List<CaretState> caretStates, boolean updateSystemSelection);
+
+ /**
* Returns the current positions of all carets and their selections. The order of entries in the returned list does not necessarily
* correspond to the order of {@link #getAllCarets()} method results. Passing the result of this method to
* {@link #setCaretsAndSelections(java.util.List)} will restore the state of carets, including the internal caret order, in particular,
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/FontPreferences.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/FontPreferences.java
index 557d41435878..5d2038d171ea 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/FontPreferences.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/FontPreferences.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.
@@ -226,4 +226,9 @@ public class FontPreferences {
}
return null;
}
+
+ @Override
+ public String toString() {
+ return "Effective font families: " + myEffectiveFontFamilies;
+ }
}
diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java
index b8bd41980b7c..1d8ddcc2930b 100644
--- a/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java
+++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java
@@ -23,7 +23,13 @@ import java.util.EventListener;
* @see {@link com.intellij.openapi.editor.EditorFactory#addEditorFactoryListener(com.intellij.openapi.editor.event.EditorFactoryListener, com.intellij.openapi.Disposable)}
*/
public interface EditorFactoryListener extends EventListener {
+ /**
+ * Called after {@link com.intellij.openapi.editor.Editor} instance has been created.
+ */
void editorCreated(@NotNull EditorFactoryEvent event);
+ /**
+ * Called before {@link com.intellij.openapi.editor.Editor} instance will be released.
+ */
void editorReleased(@NotNull EditorFactoryEvent event);
}
diff --git a/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java b/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java
index 1c0152514e33..bf61094015f0 100644
--- a/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java
+++ b/platform/extensions/src/com/intellij/openapi/extensions/Extensions.java
@@ -28,15 +28,16 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Extensions {
- private static LogProvider ourLogger = new SimpleLogProvider();
-
public static final ExtensionPointName<AreaListener> AREA_LISTENER_EXTENSION_POINT = new ExtensionPointName<AreaListener>("com.intellij.arealistener");
-
+ private static LogProvider ourLogger = new SimpleLogProvider();
private static Map<AreaInstance,ExtensionsAreaImpl> ourAreaInstance2area = new THashMap<AreaInstance, ExtensionsAreaImpl>();
private static Map<String,AreaClassConfiguration> ourAreaClass2Configuration = new THashMap<String, AreaClassConfiguration>();
@NotNull private static ExtensionsAreaImpl ourRootArea = createRootArea();
+ private Extensions() {
+ }
+
@NotNull
private static ExtensionsAreaImpl createRootArea() {
ExtensionsAreaImpl rootArea = new ExtensionsAreaImpl(null, null, null, ourLogger);
@@ -44,9 +45,6 @@ public class Extensions {
return rootArea;
}
- private Extensions() {
- }
-
public static void setSynchronized() {
assert ourAreaInstance2area.isEmpty();
assert ourAreaClass2Configuration.isEmpty();
@@ -101,6 +99,7 @@ public class Extensions {
@NotNull
@SuppressWarnings({"unchecked"})
public static <T> T[] getExtensions(@NotNull ExtensionPointName<T> extensionPointName, AreaInstance areaInstance) {
+ // keep it until 1.7 JDK
return Extensions.<T>getExtensions(extensionPointName.getName(), areaInstance);
}
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java
index 2cc4b2eb5cca..e17d2443da61 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.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.
@@ -30,9 +30,9 @@ import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessTerminatedListener;
import com.intellij.execution.rmi.RemoteProcessSupport;
import com.intellij.execution.runners.ProgramRunner;
-import com.intellij.ide.actions.OpenProjectFileChooserDescriptor;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.components.impl.stores.StorageUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
@@ -136,7 +136,7 @@ public class RemoteExternalSystemCommunicationManager implements ExternalSystemC
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(Alarm.class), classPath);
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(DependencyScope.class), classPath);
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(ExtensionPointName.class), classPath);
- ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(OpenProjectFileChooserDescriptor.class), classPath);
+ ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(StorageUtil.class), classPath);
ContainerUtil.addIfNotNull(PathUtil.getJarPathForClass(ExternalSystemTaskNotificationListener.class), classPath);
// External system module jars
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java
index d45be42bbbd9..4fc22b2e517b 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemTaskRunner.java
@@ -25,7 +25,6 @@ import com.intellij.execution.runners.GenericProgramRunner;
import com.intellij.execution.runners.RunContentBuilder;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
-import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -48,11 +47,8 @@ public class ExternalSystemTaskRunner extends GenericProgramRunner {
@Nullable
@Override
- protected RunContentDescriptor doExecute(@NotNull Project project,
- @NotNull RunProfileState state,
- RunContentDescriptor contentToReuse,
- @NotNull ExecutionEnvironment env) throws ExecutionException {
+ protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment env) throws ExecutionException {
ExecutionResult executionResult = state.execute(env.getExecutor(), this);
- return executionResult == null ? null : new RunContentBuilder(executionResult, env).showRunContent(contentToReuse);
+ return executionResult == null ? null : new RunContentBuilder(executionResult, env).showRunContent(env.getContentToReuse());
}
}
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java
index 1e08045faeea..a5bf2827ef26 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/task/ui/AbstractExternalSystemToolWindowFactory.java
@@ -28,6 +28,8 @@ import com.intellij.ui.content.ContentManager;
import com.intellij.ui.content.impl.ContentImpl;
import org.jetbrains.annotations.NotNull;
+import java.util.Locale;
+
/**
* @author Denis Zhdanov
* @since 5/13/13 4:15 PM
@@ -39,9 +41,8 @@ public abstract class AbstractExternalSystemToolWindowFactory implements ToolWin
protected AbstractExternalSystemToolWindowFactory(@NotNull ProjectSystemId id) {
myExternalSystemId = id;
- myNotificationGroup = NotificationGroup.toolWindowGroup("notification.group.id." + id.toString().toLowerCase(),
- myExternalSystemId.getReadableName(),
- true);
+ myNotificationGroup = NotificationGroup.toolWindowGroup("notification.group.id." + id.toString().toLowerCase(Locale.ENGLISH),
+ myExternalSystemId.getReadableName());
}
@Override
diff --git a/platform/icons/src/actions/GroupByClass.png b/platform/icons/src/actions/GroupByClass.png
index dddca942c295..8370b26019d1 100644
--- a/platform/icons/src/actions/GroupByClass.png
+++ b/platform/icons/src/actions/GroupByClass.png
Binary files differ
diff --git a/platform/icons/src/actions/GroupByFile.png b/platform/icons/src/actions/GroupByFile.png
index b79988d3f0ed..56a2d76c9e0f 100644
--- a/platform/icons/src/actions/GroupByFile.png
+++ b/platform/icons/src/actions/GroupByFile.png
Binary files differ
diff --git a/platform/icons/src/general/projectConfigurable.png b/platform/icons/src/general/projectConfigurable.png
index d04d56ca4983..450c1863c231 100644
--- a/platform/icons/src/general/projectConfigurable.png
+++ b/platform/icons/src/general/projectConfigurable.png
Binary files differ
diff --git a/platform/icons/src/general/projectConfigurable@2x.png b/platform/icons/src/general/projectConfigurable@2x.png
index 3550d5fbf390..a6a92d5e6a66 100644
--- a/platform/icons/src/general/projectConfigurable@2x.png
+++ b/platform/icons/src/general/projectConfigurable@2x.png
Binary files differ
diff --git a/platform/icons/src/gutter/extAnnotation.png b/platform/icons/src/gutter/extAnnotation.png
index 83bfdd350f5c..456eb7171faa 100644
--- a/platform/icons/src/gutter/extAnnotation.png
+++ b/platform/icons/src/gutter/extAnnotation.png
Binary files differ
diff --git a/platform/icons/src/nodes/nativeLibrariesFolder.png b/platform/icons/src/nodes/nativeLibrariesFolder.png
new file mode 100644
index 000000000000..b70cec57b9e2
--- /dev/null
+++ b/platform/icons/src/nodes/nativeLibrariesFolder.png
Binary files differ
diff --git a/platform/icons/src/nodes/nativeLibrariesFolder@2x.png b/platform/icons/src/nodes/nativeLibrariesFolder@2x.png
new file mode 100644
index 000000000000..532896bb9b4d
--- /dev/null
+++ b/platform/icons/src/nodes/nativeLibrariesFolder@2x.png
Binary files differ
diff --git a/platform/icons/src/nodes/nativeLibrariesFolder@2x_dark.png b/platform/icons/src/nodes/nativeLibrariesFolder@2x_dark.png
new file mode 100644
index 000000000000..ac966a7a35bb
--- /dev/null
+++ b/platform/icons/src/nodes/nativeLibrariesFolder@2x_dark.png
Binary files differ
diff --git a/platform/icons/src/nodes/nativeLibrariesFolder_dark.png b/platform/icons/src/nodes/nativeLibrariesFolder_dark.png
new file mode 100644
index 000000000000..fd74984620bc
--- /dev/null
+++ b/platform/icons/src/nodes/nativeLibrariesFolder_dark.png
Binary files differ
diff --git a/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java b/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
index aafb85d529bc..1820de4b2336 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.*;
+import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -88,7 +89,7 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
@NotNull
public static Query<PsiReference> search(@NotNull PsiElement element) {
- return search(element, GlobalSearchScope.allScope(element.getProject()), false);
+ return search(element, GlobalSearchScope.allScope(PsiUtilCore.getProjectInReadAction(element)), false);
}
@NotNull
@@ -112,7 +113,7 @@ public class ReferencesSearch extends ExtensibleQueryFactory<PsiReference, Refer
final PsiElement element = parameters.getElementToSearch();
- return uniqueResults(new MergeQuery<PsiReference>(result, new SearchRequestQuery(element.getProject(), requests)));
+ return uniqueResults(new MergeQuery<PsiReference>(result, new SearchRequestQuery(PsiUtilCore.getProjectInReadAction(element), requests)));
}
@NotNull
diff --git a/platform/lang-api/src/com/intellij/execution/RunProfileStarter.java b/platform/lang-api/src/com/intellij/execution/RunProfileStarter.java
index 163031f956f9..00c87576ecfd 100644
--- a/platform/lang-api/src/com/intellij/execution/RunProfileStarter.java
+++ b/platform/lang-api/src/com/intellij/execution/RunProfileStarter.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.
@@ -28,8 +28,19 @@ import org.jetbrains.annotations.Nullable;
* @author nik
*/
public abstract class RunProfileStarter {
+ @SuppressWarnings("UnusedParameters")
+ @Deprecated
@Nullable
- public abstract RunContentDescriptor execute(@NotNull Project project, @NotNull Executor executor, @NotNull RunProfileState state,
- @Nullable RunContentDescriptor contentToReuse, @NotNull ExecutionEnvironment environment) throws ExecutionException;
+ /**
+ * @deprecated to remove in IDEA 15
+ */
+ public RunContentDescriptor execute(@NotNull Project project, @NotNull Executor executor, @NotNull RunProfileState state,
+ @Nullable RunContentDescriptor contentToReuse, @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ return execute(state, environment);
+ }
+ @Nullable
+ public RunContentDescriptor execute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ throw new AbstractMethodError();
+ }
}
diff --git a/platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java b/platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java
index c52f6c9da729..b42cd249ca8e 100644
--- a/platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java
+++ b/platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java
@@ -16,6 +16,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.StringInterner;
+import com.intellij.util.containers.WeakStringInterner;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,7 +34,7 @@ public class RunConfigurationExtensionsManager<U extends RunConfigurationBase, T
private static final String EXT_ID_ATTR = "ID";
private static final String EXTENSION_ROOT_ATTR = "EXTENSION";
protected final ExtensionPointName<T> myExtensionPointName;
- private final StringInterner myInterner = new StringInterner();
+ private final StringInterner myInterner = new WeakStringInterner();
public RunConfigurationExtensionsManager(ExtensionPointName<T> extensionPointName) {
myExtensionPointName = extensionPointName;
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java
index 732976cf73a7..259fd4e7484c 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java
@@ -17,11 +17,12 @@ package com.intellij.execution.configurations;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.options.UnnamedConfigurable;
+import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
public interface RunConfigurationsSettings {
ExtensionPointName<RunConfigurationsSettings> EXTENSION_POINT = ExtensionPointName.create("com.intellij.runConfigurationsSettings");
@NotNull
- UnnamedConfigurable createConfigurable();
+ UnnamedConfigurable createConfigurable(@NotNull Project project);
} \ No newline at end of file
diff --git a/platform/lang-api/src/com/intellij/execution/configurations/SimpleProgramParameters.java b/platform/lang-api/src/com/intellij/execution/configurations/SimpleProgramParameters.java
index 15bd92cfcf8c..b157d6ba7852 100644
--- a/platform/lang-api/src/com/intellij/execution/configurations/SimpleProgramParameters.java
+++ b/platform/lang-api/src/com/intellij/execution/configurations/SimpleProgramParameters.java
@@ -16,7 +16,7 @@
package com.intellij.execution.configurations;
-import com.intellij.execution.configuration.EnvironmentVariablesComponent;
+import com.intellij.util.EnvironmentUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
@@ -70,7 +70,7 @@ public class SimpleProgramParameters {
public void setupEnvs(Map<String, String> envs, boolean passDefault) {
if (!envs.isEmpty()) {
final HashMap<String, String> map = new HashMap<String, String>(envs);
- EnvironmentVariablesComponent.inlineParentOccurrences(map);
+ EnvironmentUtil.inlineParentOccurrences(map);
setEnv(map);
setPassParentEnvs(passDefault);
}
diff --git a/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java
index aeaaf58eda65..ce7145adeaf9 100644
--- a/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java
+++ b/platform/lang-api/src/com/intellij/execution/runners/AsyncGenericProgramRunner.java
@@ -17,16 +17,12 @@ package com.intellij.execution.runners;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionManager;
-import com.intellij.execution.Executor;
import com.intellij.execution.RunProfileStarter;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.ui.RunContentDescriptor;
-import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.util.Consumer;
-import com.intellij.util.NullableConsumer;
-import com.intellij.util.ObjectUtils;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,30 +34,19 @@ public abstract class AsyncGenericProgramRunner<Settings extends RunnerSettings>
@Override
protected final void execute(@NotNull final ExecutionEnvironment environment,
@Nullable final Callback callback,
- @NotNull final Project project,
@NotNull final RunProfileState state) throws ExecutionException {
- prepare(project, environment, state).doWhenDone(new Consumer<RunProfileStarter>() {
+ prepare(environment, state).doWhenDone(new Consumer<RunProfileStarter>() {
@Override
public void consume(@Nullable final RunProfileStarter result) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
- if (!project.isDisposed()) {
- startRunProfile(project, environment, state, callback, result);
+ if (!environment.getProject().isDisposed()) {
+ startRunProfile(environment, state, callback, result);
}
}
});
}
- }).doWhenRejected(new NullableConsumer<String>() {
- @Override
- public void consume(@Nullable String errorMessage) {
- if (project.isDisposed()) {
- return;
- }
-
- ExecutionUtil.handleExecutionError(project, environment.getExecutor().getToolWindowId(), environment.getRunProfile(),
- new ExecutionException(ObjectUtils.chooseNotNull(errorMessage, "Internal error")));
- }
});
}
@@ -69,29 +54,23 @@ public abstract class AsyncGenericProgramRunner<Settings extends RunnerSettings>
* Makes all the needed preparations for the further execution. Although this method is called in EDT,
* these preparations can be performed in a background thread.
*
- * @param project Project instance
+ * You must call {@link ExecutionUtil#handleExecutionError} in case of error
+ *
* @param environment ExecutionEnvironment instance
* @param state RunProfileState instance
* @return RunProfileStarter async result
*/
@NotNull
- protected abstract AsyncResult<RunProfileStarter> prepare(@NotNull Project project,
- @NotNull ExecutionEnvironment environment,
- @NotNull RunProfileState state) throws ExecutionException;
+ protected abstract AsyncResult<RunProfileStarter> prepare(@NotNull ExecutionEnvironment environment, @NotNull RunProfileState state) throws ExecutionException;
- private static void startRunProfile(@NotNull Project project,
- @NotNull ExecutionEnvironment environment,
+ private static void startRunProfile(@NotNull ExecutionEnvironment environment,
@NotNull RunProfileState state,
@Nullable final Callback callback,
@Nullable final RunProfileStarter starter) {
- ExecutionManager.getInstance(project).startRunProfile(new RunProfileStarter() {
+ ExecutionManager.getInstance(environment.getProject()).startRunProfile(new RunProfileStarter() {
@Override
- public RunContentDescriptor execute(@NotNull Project project,
- @NotNull Executor executor,
- @NotNull RunProfileState state,
- @Nullable RunContentDescriptor contentToReuse,
- @NotNull ExecutionEnvironment environment) throws ExecutionException {
- return postProcess(environment, starter == null ? null : starter.execute(project, executor, state, contentToReuse, environment), callback);
+ public RunContentDescriptor execute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ return postProcess(environment, starter == null ? null : starter.execute(state, environment), callback);
}
}, state, environment);
}
diff --git a/platform/lang-api/src/com/intellij/execution/runners/BaseProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/BaseProgramRunner.java
index 29c9e5be0767..a2028185089b 100644
--- a/platform/lang-api/src/com/intellij/execution/runners/BaseProgramRunner.java
+++ b/platform/lang-api/src/com/intellij/execution/runners/BaseProgramRunner.java
@@ -23,7 +23,6 @@ import com.intellij.execution.RunManager;
import com.intellij.execution.configurations.*;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.options.SettingsEditor;
-import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -61,14 +60,12 @@ abstract class BaseProgramRunner<Settings extends RunnerSettings> implements Pro
return;
}
- Project project = environment.getProject();
- RunManager.getInstance(project).refreshUsagesList(environment.getRunProfile());
- execute(environment, callback, project, state);
+ RunManager.getInstance(environment.getProject()).refreshUsagesList(environment.getRunProfile());
+ execute(environment, callback, state);
}
protected abstract void execute(@NotNull ExecutionEnvironment environment,
@Nullable Callback callback,
- @NotNull Project project,
@NotNull RunProfileState state) throws ExecutionException;
@Nullable
diff --git a/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java b/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java
index 0d15a272498c..b6c300c3f7e2 100644
--- a/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java
+++ b/platform/lang-api/src/com/intellij/execution/runners/ExecutionUtil.java
@@ -31,6 +31,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.content.Content;
import com.intellij.util.ObjectUtils;
@@ -65,18 +66,19 @@ public class ExecutionUtil {
@NotNull final String toolWindowId,
@NotNull String taskName,
@NotNull ExecutionException e) {
- if (e instanceof RunCanceledByUserException) return;
+ if (e instanceof RunCanceledByUserException) {
+ return;
+ }
LOG.debug(e);
String description = e.getMessage();
- HyperlinkListener listener = null;
-
if (description == null) {
LOG.warn("Execution error without description", e);
description = "Unknown error";
}
+ HyperlinkListener listener = null;
if ((description.contains("87") || description.contains("111") || description.contains("206")) &&
e instanceof ProcessNotCreatedException &&
!PropertiesComponent.getInstance(project).isTrueValue("dynamic.classpath")) {
@@ -110,7 +112,14 @@ public class ExecutionUtil {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
- ToolWindowManager.getInstance(project).notifyByBalloon(toolWindowId, MessageType.ERROR, fullMessage, null, finalListener);
+ ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project);
+ if (toolWindowManager.canShowNotification(toolWindowId)) {
+ //noinspection SSBasedInspection
+ toolWindowManager.notifyByBalloon(toolWindowId, MessageType.ERROR, fullMessage, null, finalListener);
+ }
+ else {
+ Messages.showErrorDialog(project, fullMessage, "");
+ }
NotificationListener notificationListener = ObjectUtils.tryCast(finalListener, NotificationListener.class);
ourNotificationGroup.createNotification(title, finalDescription, NotificationType.ERROR, notificationListener).notify(project);
}
diff --git a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java
index adbd04e822e6..3c59227eb85a 100644
--- a/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java
+++ b/platform/lang-api/src/com/intellij/execution/runners/GenericProgramRunner.java
@@ -18,7 +18,6 @@ package com.intellij.execution.runners;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionManager;
-import com.intellij.execution.Executor;
import com.intellij.execution.RunProfileStarter;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RunnerSettings;
@@ -36,24 +35,30 @@ public abstract class GenericProgramRunner<Settings extends RunnerSettings> exte
public static final String CONTENT_TO_REUSE = CONTENT_TO_REUSE_DATA_KEY.getName();
@Override
- protected void execute(@NotNull ExecutionEnvironment environment, @Nullable final Callback callback, @NotNull Project project, @NotNull RunProfileState state)
+ protected void execute(@NotNull ExecutionEnvironment environment, @Nullable final Callback callback, @NotNull RunProfileState state)
throws ExecutionException {
- ExecutionManager.getInstance(project).startRunProfile(new RunProfileStarter() {
+ ExecutionManager.getInstance(environment.getProject()).startRunProfile(new RunProfileStarter() {
@Override
- public RunContentDescriptor execute(@NotNull Project project,
- @NotNull Executor executor,
- @NotNull RunProfileState state,
- @Nullable RunContentDescriptor contentToReuse,
- @NotNull ExecutionEnvironment environment) throws ExecutionException {
- return postProcess(environment, doExecute(project, state, contentToReuse, environment), callback);
+ public RunContentDescriptor execute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ return postProcess(environment, doExecute(state, environment), callback);
}
}, state, environment);
}
@Nullable
- protected abstract RunContentDescriptor doExecute(@NotNull Project project,
- @NotNull RunProfileState state,
- @Nullable RunContentDescriptor contentToReuse,
- @NotNull ExecutionEnvironment environment) throws ExecutionException;
+ protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ return doExecute(environment.getProject(), state, environment.getContentToReuse(), environment);
+ }
+ @Deprecated
+ @Nullable
+ /**
+ * @deprecated to remove in IDEA 16
+ */
+ protected RunContentDescriptor doExecute(@NotNull Project project,
+ @NotNull RunProfileState state,
+ @Nullable RunContentDescriptor contentToReuse,
+ @NotNull ExecutionEnvironment environment) throws ExecutionException {
+ throw new AbstractMethodError();
+ }
}
diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
index d72a0640c595..fddb2b2f50b7 100644
--- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
+++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/ModuleBuilder.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.io.FileUtil;
@@ -39,6 +40,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.EventDispatcher;
+import com.intellij.util.containers.ContainerUtil;
import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -70,7 +72,17 @@ public abstract class ModuleBuilder extends AbstractModuleBuilder {
for (ModuleBuilderFactory factory : EP_NAME.getExtensions()) {
result.add(factory.createBuilder());
}
- return result;
+ return ContainerUtil.filter(result, new Condition<ModuleBuilder>() {
+
+ @Override
+ public boolean value(ModuleBuilder moduleBuilder) {
+ return moduleBuilder.isAvailable();
+ }
+ });
+ }
+
+ protected boolean isAvailable() {
+ return true;
}
@Nullable
diff --git a/platform/lang-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java b/platform/lang-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java
index f57190e5725e..9a80bf72ed6d 100644
--- a/platform/lang-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java
+++ b/platform/lang-api/src/com/intellij/lang/documentation/AbstractDocumentationProvider.java
@@ -15,15 +15,6 @@
*/
package com.intellij.lang.documentation;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiManager;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-
/**
* @author Dmitry Avdeev
*/
diff --git a/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java b/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java
index 17bc66f8ada2..14a7c4b99a94 100644
--- a/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java
+++ b/platform/lang-api/src/com/intellij/lang/documentation/CompositeDocumentationProvider.java
@@ -22,13 +22,11 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
public class CompositeDocumentationProvider extends DocumentationProviderEx implements ExternalDocumentationProvider, ExternalDocumentationHandler {
@@ -53,14 +51,21 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
myProviders = providers;
}
+ @NotNull
+ public List<DocumentationProvider> getAllProviders() {
+ return ContainerUtil.concat(getProviders(), Arrays.asList(Extensions.getExtensions(EP_NAME)));
+ }
+
+ @NotNull
public List<DocumentationProvider> getProviders() {
return myProviders;
}
@Override
public boolean handleExternal(PsiElement element, PsiElement originalElement) {
- for (DocumentationProvider provider : myProviders) {
- if (provider instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)provider).handleExternal(element, originalElement)) {
+ for (DocumentationProvider provider : getAllProviders()) {
+ if (provider instanceof ExternalDocumentationHandler &&
+ ((ExternalDocumentationHandler)provider).handleExternal(element, originalElement)) {
return true;
}
}
@@ -70,8 +75,9 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public boolean handleExternalLink(PsiManager psiManager, String link, PsiElement context) {
- for (DocumentationProvider provider : myProviders) {
- if (provider instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)provider).handleExternalLink(psiManager, link, context)) {
+ for (DocumentationProvider provider : getAllProviders()) {
+ if (provider instanceof ExternalDocumentationHandler &&
+ ((ExternalDocumentationHandler)provider).handleExternalLink(psiManager, link, context)) {
return true;
}
}
@@ -81,7 +87,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public boolean canFetchDocumentationLink(String link) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)provider).canFetchDocumentationLink(link)) {
return true;
}
@@ -93,7 +99,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@NotNull
@Override
public String fetchExternalDocumentation(@NotNull String link, @Nullable PsiElement element) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)provider).canFetchDocumentationLink(link)) {
return ((ExternalDocumentationHandler)provider).fetchExternalDocumentation(link, element);
}
@@ -104,12 +110,8 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
- for ( DocumentationProvider provider : myProviders ) {
+ for (DocumentationProvider provider : getAllProviders()) {
String result = provider.getQuickNavigateInfo(element, originalElement);
- if ( result != null ) return result;
- }
- for (DocumentationProvider provider : Extensions.getExtensions(EP_NAME)) {
- final String result = provider.getQuickNavigateInfo(element, originalElement);
if (result != null) return result;
}
return null;
@@ -117,14 +119,8 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public List<String> getUrlFor(PsiElement element, PsiElement originalElement) {
- for ( DocumentationProvider provider : myProviders ) {
- List<String> result = provider.getUrlFor(element,originalElement);
- if ( result != null ) {
- return result;
- }
- }
- for (DocumentationProvider provider : Extensions.getExtensions(EP_NAME)) {
- final List<String> result = provider.getUrlFor(element, originalElement);
+ for (DocumentationProvider provider : getAllProviders()) {
+ List<String> result = provider.getUrlFor(element, originalElement);
if (result != null) {
return result;
}
@@ -134,14 +130,8 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public String generateDoc(PsiElement element, PsiElement originalElement) {
- for ( DocumentationProvider provider : myProviders ) {
- String result = provider.generateDoc(element,originalElement);
- if ( result != null ) {
- return result;
- }
- }
- for (DocumentationProvider provider : Extensions.getExtensions(EP_NAME)) {
- final String result = provider.generateDoc(element, originalElement);
+ for (DocumentationProvider provider : getAllProviders()) {
+ String result = provider.generateDoc(element, originalElement);
if (result != null) {
return result;
}
@@ -151,14 +141,8 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element) {
- for ( DocumentationProvider provider : myProviders ) {
- PsiElement result = provider.getDocumentationElementForLookupItem(psiManager,object,element);
- if ( result != null ) {
- return result;
- }
- }
- for (DocumentationProvider provider : Extensions.getExtensions(EP_NAME)) {
- final PsiElement result = provider.getDocumentationElementForLookupItem(psiManager, object, element);
+ for (DocumentationProvider provider : getAllProviders()) {
+ PsiElement result = provider.getDocumentationElementForLookupItem(psiManager, object, element);
if (result != null) {
return result;
}
@@ -168,12 +152,8 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) {
- for ( DocumentationProvider provider : myProviders ) {
- PsiElement result = provider.getDocumentationElementForLink(psiManager,link,context);
- if ( result != null ) return result;
- }
- for (DocumentationProvider provider : Extensions.getExtensions(EP_NAME)) {
- final PsiElement result = provider.getDocumentationElementForLink(psiManager, link, context);
+ for (DocumentationProvider provider : getAllProviders()) {
+ PsiElement result = provider.getDocumentationElementForLink(psiManager, link, context);
if (result != null) return result;
}
return null;
@@ -182,7 +162,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Nullable
public CodeDocumentationProvider getFirstCodeDocumentationProvider() {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof CodeDocumentationProvider) {
return (CodeDocumentationProvider)provider;
}
@@ -192,7 +172,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public String fetchExternalDocumentation(Project project, PsiElement element, List<String> docUrls) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationProvider) {
final String doc = ((ExternalDocumentationProvider)provider).fetchExternalDocumentation(project, element, docUrls);
if (doc != null) {
@@ -205,9 +185,9 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public boolean hasDocumentationFor(PsiElement element, PsiElement originalElement) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationProvider) {
- if (((ExternalDocumentationProvider) provider).hasDocumentationFor(element, originalElement)) return true;
+ if (((ExternalDocumentationProvider)provider).hasDocumentationFor(element, originalElement)) return true;
}
else {
if (hasUrlsFor(provider, element, originalElement)) return true;
@@ -218,7 +198,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public boolean canPromptToConfigureDocumentation(PsiElement element) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationProvider &&
((ExternalDocumentationProvider)provider).canPromptToConfigureDocumentation(element)) {
return true;
@@ -229,7 +209,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public void promptToConfigureDocumentation(PsiElement element) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof ExternalDocumentationProvider &&
((ExternalDocumentationProvider)provider).canPromptToConfigureDocumentation(element)) {
((ExternalDocumentationProvider)provider).promptToConfigureDocumentation(element);
@@ -249,7 +229,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
public PsiElement getCustomDocumentationElement(@NotNull Editor editor,
@NotNull PsiFile file,
@Nullable PsiElement contextElement) {
- for (DocumentationProvider provider : myProviders) {
+ for (DocumentationProvider provider : getAllProviders()) {
if (provider instanceof DocumentationProviderEx) {
PsiElement element = ((DocumentationProviderEx)provider).getCustomDocumentationElement(editor, file, contextElement);
if (element != null) {
@@ -262,6 +242,6 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
@Override
public String toString() {
- return myProviders.toString();
+ return getProviders().toString();
}
}
diff --git a/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java b/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java
index 5ae5af91bac0..8b9143a0d995 100644
--- a/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java
+++ b/platform/lang-api/src/com/intellij/lang/documentation/DocumentationProviderEx.java
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.awt.*;
import java.util.List;
/**
@@ -57,4 +58,9 @@ public class DocumentationProviderEx implements DocumentationProvider {
public PsiElement getCustomDocumentationElement(@NotNull final Editor editor, @NotNull final PsiFile file, @Nullable PsiElement contextElement) {
return null;
}
+
+ @Nullable
+ public Image getLocalImageForElement(@NotNull PsiElement element, @NotNull String imageSpec) {
+ return null;
+ }
}
diff --git a/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java b/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java
index d728aff0e823..af456e0074ac 100644
--- a/platform/lang-api/src/com/intellij/lexer/CompositeLexer.java
+++ b/platform/lang-api/src/com/intellij/lexer/CompositeLexer.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,16 @@ package com.intellij.lexer;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
+/**
+ * Naive implementation of lexer that able to combine element types of two other lexers.
+ *
+ * The implementation doesn't give any guarantees about valid points of 'incremental relexing',
+ * because it returns start/end-offsets not for token that was used but for the shortest one.
+ *
+ * Also it reduces state size to 16 bits for nested lexer.
+ *
+ * @deprecated use {@link com.intellij.psi.templateLanguages.TemplateBlackAndWhiteLexer} or {@link com.intellij.lexer.LayeredLexer} instead
+ */
public abstract class CompositeLexer extends LexerBase {
private final Lexer myLexer1;
private final Lexer myLexer2;
diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
index 021c055dd70f..c9a0053619ce 100644
--- a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
+++ b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.projectRoots.ui.SdkPathEditor;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.util.KeyedExtensionFactory;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -41,6 +42,7 @@ public interface OrderRootTypeUIFactory {
}
};
+ @Nullable
SdkPathEditor createPathEditor(Sdk sdk);
Icon getIcon();
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/LegacyCodeStyleSettingsManager.java b/platform/lang-api/src/com/intellij/psi/codeStyle/LegacyCodeStyleSettingsManager.java
index c6d4c738c1fd..fdc9a662df1d 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/LegacyCodeStyleSettingsManager.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/LegacyCodeStyleSettingsManager.java
@@ -31,7 +31,6 @@ import org.jdom.Element;
}
)
public class LegacyCodeStyleSettingsManager implements PersistentStateComponent<Element> {
-
private Element myState;
@Override
diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementSectionRule.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementSectionRule.java
index 9e9e9c0caa0f..2f7249f9d22d 100644
--- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementSectionRule.java
+++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/match/ArrangementSectionRule.java
@@ -53,7 +53,7 @@ public class ArrangementSectionRule implements Cloneable {
}
public static ArrangementSectionRule create(@Nullable String start, @Nullable String end, @NotNull StdArrangementMatchRule... rules) {
- return create(start, end, ContainerUtil.newArrayList(rules));
+ return create(start, end, rules.length == 0 ? ContainerUtil.<StdArrangementMatchRule>emptyList() : ContainerUtil.newArrayList(rules));
}
public static ArrangementSectionRule create(@Nullable String start, @Nullable String end, @NotNull List<StdArrangementMatchRule> rules) {
@@ -68,14 +68,10 @@ public class ArrangementSectionRule implements Cloneable {
return new ArrangementSectionRule(start, end, matchRules);
}
- @Nullable
- private static StdArrangementMatchRule createSectionRule(@Nullable String comment, @NotNull ArrangementSettingsToken token) {
- if (StringUtil.isEmpty(comment)) {
- return null;
- }
- final ArrangementAtomMatchCondition type = new ArrangementAtomMatchCondition(token);
+ @NotNull
+ private static StdArrangementMatchRule createSectionRule(@NotNull String comment, @NotNull ArrangementSettingsToken token) {
final ArrangementAtomMatchCondition text = new ArrangementAtomMatchCondition(StdArrangementTokens.Regexp.TEXT, comment);
- final ArrangementMatchCondition condition = ArrangementUtil.combine(type, text);
+ final ArrangementMatchCondition condition = ArrangementUtil.combine(new ArrangementAtomMatchCondition(token), text);
return new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition));
}
diff --git a/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java b/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java
index 13f84cb1dc4f..4565832c310b 100644
--- a/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java
+++ b/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java
@@ -46,7 +46,7 @@ public class PsiUtilBase extends PsiUtilCore implements PsiEditorUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.util.PsiUtilBase");
public static final Comparator<Language> LANGUAGE_COMPARATOR = new Comparator<Language>() {
@Override
- public int compare(Language o1, Language o2) {
+ public int compare(@NotNull Language o1, @NotNull Language o2) {
return o1.getID().compareTo(o2.getID());
}
};
diff --git a/platform/lang-impl/src/com/intellij/application/options/CodeStyleSchemesConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/CodeStyleSchemesConfigurable.java
index b07c7a62bc47..760d17e67d24 100644
--- a/platform/lang-impl/src/com/intellij/application/options/CodeStyleSchemesConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/application/options/CodeStyleSchemesConfigurable.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.
@@ -56,7 +56,7 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
public JComponent createComponent() {
myModel = ensureModel();
- if (Registry.is("ide.file.settings.order.new")) {
+ if (Registry.is("ide.new.settings.dialog")) {
return myPanels == null || myPanels.isEmpty() ? null : myPanels.get(0).createComponent();
}
return myRootSchemesPanel.getPanel();
@@ -236,7 +236,7 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
}
}
- if (Registry.is("ide.file.settings.order.new")) {
+ if (Registry.is("ide.new.settings.dialog")) {
int size = myPanels.size();
Configurable[] result = new Configurable[size > 0 ? size - 1 : 0];
for (int i = 0; i < result.length; i++) {
@@ -346,34 +346,31 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
String displayName = myProvider.getConfigurableDisplayName();
if (displayName != null) return displayName;
- return ensurePanel().getDisplayName(); // fallback for 8.0 API compatibility
+ return myPanel != null ? myPanel.getDisplayName() : null; // fallback for 8.0 API compatibility
}
@Override
public String getHelpTopic() {
- return ensurePanel().getHelpTopic();
- }
-
- private CodeStyleMainPanel ensurePanel() {
- if (myPanel == null) {
- myPanel = new CodeStyleMainPanel(ensureModel(), myLangSelector, myFactory);
- }
- return myPanel;
+ return myPanel != null ? myPanel.getHelpTopic() : null;
}
@Override
public JComponent createComponent() {
- return ensurePanel();
+ myPanel = new CodeStyleMainPanel(ensureModel(), myLangSelector, myFactory);
+ return myPanel;
}
@Override
public boolean isModified() {
- boolean someSchemeModified = ensurePanel().isModified();
- if (someSchemeModified) {
- myApplyCompleted = false;
- myRevertCompleted = false;
+ if (myPanel != null) {
+ boolean someSchemeModified = myPanel.isModified();
+ if (someSchemeModified) {
+ myApplyCompleted = false;
+ myRevertCompleted = false;
+ }
+ return someSchemeModified;
}
- return someSchemeModified;
+ return false;
}
@Override
@@ -428,20 +425,25 @@ public class CodeStyleSchemesConfigurable extends SearchableConfigurable.Parent.
}
public boolean isPanelModified(CodeStyleScheme scheme) {
- return ensurePanel().isModified(scheme);
+ return myPanel != null && myPanel.isModified(scheme);
}
public boolean isPanelModified() {
- return ensurePanel().isModified();
+ return myPanel != null && myPanel.isModified();
}
public void applyPanel() throws ConfigurationException {
- ensurePanel().apply();
+ if (myPanel != null) {
+ myPanel.apply();
+ }
}
@Override
public Set<String> processListOptions() {
- return ensurePanel().processListOptions();
+ if (myPanel == null) {
+ myPanel = new CodeStyleMainPanel(ensureModel(), myLangSelector, myFactory);
+ }
+ return myPanel.processListOptions();
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form
index 586f9b48779e..3ce71602fe06 100644
--- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form
+++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form
@@ -259,7 +259,7 @@
<component id="25b75" class="javax.swing.JTextField" binding="myClipboardContentLimitTextField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="8" fill="0" indent="0" use-parent-layout="false">
- <preferred-size width="35" height="-1"/>
+ <preferred-size width="50" height="-1"/>
</grid>
</constraints>
<properties>
@@ -285,7 +285,7 @@
<component id="695ab" class="javax.swing.JTextField" binding="myRecentFilesLimitField">
<constraints>
<grid row="1" 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="35" height="-1"/>
+ <preferred-size width="50" height="-1"/>
</grid>
</constraints>
<properties>
@@ -295,7 +295,7 @@
<component id="8f324" class="javax.swing.JTextField" binding="myCommandsHistoryLimitField">
<constraints>
<grid row="2" 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="35" height="-1"/>
+ <preferred-size width="50" height="-1"/>
</grid>
</constraints>
<properties>
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 0bc36c17325d..3b51cc9ad976 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/FormatChangedTextUtil.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
+import com.intellij.openapi.editor.impl.EditorFactoryImpl;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
@@ -281,7 +282,7 @@ public class FormatChangedTextUtil {
@NotNull
private static List<TextRange> calculateChangedTextRanges(@NotNull Project project, @NotNull PsiFile file, @NotNull String contentFromVcs) {
- Document documentFromVcs = EditorFactory.getInstance().createDocument(contentFromVcs);
+ Document documentFromVcs = ((EditorFactoryImpl)EditorFactory.getInstance()).createDocument(contentFromVcs, true, false);
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
if (document == null) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java
index ed254aec1e8b..6cdb063c0434 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsProcessor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/OptimizeImportsProcessor.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.
@@ -82,8 +82,9 @@ public class OptimizeImportsProcessor extends AbstractLayoutCodeProcessor {
public void run() {
CodeStyleManagerImpl.setSequentialProcessingAllowed(false);
try {
- for (Runnable runnable : runnables)
+ for (Runnable runnable : runnables) {
runnable.run();
+ }
}
finally {
CodeStyleManagerImpl.setSequentialProcessingAllowed(true);
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 fcb080dcd277..3bdd05f58a40 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java
@@ -316,7 +316,6 @@ public class CodeCompletionHandlerBase {
final LookupElement[] allItems = data.get();
if (allItems != null && !indicator.isRunning() && !indicator.isCanceled()) { // the completion is really finished, now we may auto-insert or show lookup
completionFinished(initContext.getStartOffset(), initContext.getSelectionEndOffset(), indicator, allItems, hasModifiers);
- checkNotSync(indicator, allItems);
return;
}
}
@@ -424,18 +423,18 @@ public class CodeCompletionHandlerBase {
LOG.assertTrue(!indicator.isRunning(), "running");
LOG.assertTrue(!indicator.isCanceled(), "canceled");
- indicator.getLookup().refreshUi(true, false);
- final AutoCompletionDecision decision = shouldAutoComplete(indicator, items);
- if (decision == AutoCompletionDecision.SHOW_LOOKUP) {
- CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated(indicator));
- indicator.getLookup().setCalculating(false);
- indicator.showLookup();
- }
- else if (decision instanceof AutoCompletionDecision.InsertItem) {
- final Runnable restorePrefix = rememberDocumentState(indicator.getEditor());
+ try {
+ indicator.getLookup().refreshUi(true, false);
+ final AutoCompletionDecision decision = shouldAutoComplete(indicator, items);
+ if (decision == AutoCompletionDecision.SHOW_LOOKUP) {
+ CompletionServiceImpl.setCompletionPhase(new CompletionPhase.ItemsCalculated(indicator));
+ indicator.getLookup().setCalculating(false);
+ indicator.showLookup();
+ }
+ else if (decision instanceof AutoCompletionDecision.InsertItem) {
+ final Runnable restorePrefix = rememberDocumentState(indicator.getEditor());
- final LookupElement item = ((AutoCompletionDecision.InsertItem)decision).getElement();
- try {
+ final LookupElement item = ((AutoCompletionDecision.InsertItem)decision).getElement();
CommandProcessor.getInstance().executeCommand(indicator.getProject(), new Runnable() {
@Override
public void run() {
@@ -443,22 +442,22 @@ public class CodeCompletionHandlerBase {
indicator.getLookup().finishLookup(Lookup.AUTO_INSERT_SELECT_CHAR, item);
}
}, "Autocompletion", null);
- }
- catch (Throwable e) {
- CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
- LOG.error(e);
- return;
- }
- // the insert handler may have started a live template with completion
- if (CompletionService.getCompletionService().getCurrentCompletion() == null &&
- // ...or scheduled another autopopup
- !CompletionServiceImpl.isPhase(CompletionPhase.CommittingDocuments.class)) {
- CompletionServiceImpl.setCompletionPhase(hasModifiers? new CompletionPhase.InsertedSingleItem(indicator, restorePrefix) : CompletionPhase.NoCompletion);
+ // the insert handler may have started a live template with completion
+ if (CompletionService.getCompletionService().getCurrentCompletion() == null &&
+ // ...or scheduled another autopopup
+ !CompletionServiceImpl.isPhase(CompletionPhase.CommittingDocuments.class)) {
+ CompletionServiceImpl.setCompletionPhase(hasModifiers? new CompletionPhase.InsertedSingleItem(indicator, restorePrefix) : CompletionPhase.NoCompletion);
+ }
+ } else if (decision == AutoCompletionDecision.CLOSE_LOOKUP) {
+ LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
}
- checkNotSync(indicator, items);
- } else if (decision == AutoCompletionDecision.CLOSE_LOOKUP) {
- LookupManager.getInstance(indicator.getProject()).hideActiveLookup();
+ }
+ catch (Throwable e) {
+ CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
+ LOG.error(e);
+ }
+ finally {
checkNotSync(indicator, items);
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
index e25f050c8d7b..8ca94d80463c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
@@ -193,9 +193,10 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
if (!CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS) {
myLookup.setFocusDegree(LookupImpl.FocusDegree.SEMI_FOCUSED);
if (FeatureUsageTracker.getInstance().isToBeAdvertisedInLookup(CodeCompletionFeatures.EDITING_COMPLETION_FINISH_BY_CONTROL_DOT, getProject())) {
- addAdvertisement("Press " +
- CompletionContributor.getActionShortcut(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_DOT) +
- " to choose the selected (or first) suggestion and insert a dot afterwards", null);
+ String dotShortcut = CompletionContributor.getActionShortcut(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_DOT);
+ if (StringUtil.isNotEmpty(dotShortcut)) {
+ addAdvertisement("Press " + dotShortcut + " to choose the selected (or first) suggestion and insert a dot afterwards", null);
+ }
}
} else {
myLookup.setFocusDegree(LookupImpl.FocusDegree.FOCUSED);
@@ -204,9 +205,11 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
if (!myEditor.isOneLineMode() &&
FeatureUsageTracker.getInstance()
.isToBeAdvertisedInLookup(CodeCompletionFeatures.EDITING_COMPLETION_CONTROL_ARROWS, getProject())) {
- addAdvertisement(CompletionContributor.getActionShortcut(IdeActions.ACTION_LOOKUP_DOWN) + " and " +
- CompletionContributor.getActionShortcut(IdeActions.ACTION_LOOKUP_UP) +
- " will move caret down and up in the editor", null);
+ String downShortcut = CompletionContributor.getActionShortcut(IdeActions.ACTION_LOOKUP_DOWN);
+ String upShortcut = CompletionContributor.getActionShortcut(IdeActions.ACTION_LOOKUP_UP);
+ if (StringUtil.isNotEmpty(downShortcut) && StringUtil.isNotEmpty(upShortcut)) {
+ addAdvertisement(downShortcut + " and " + upShortcut + " will move caret down and up in the editor", null);
+ }
}
} else if (DumbService.isDumb(getProject())) {
addAdvertisement("The results might be incomplete while indexing is in progress", MessageType.WARNING.getPopupBackground());
@@ -759,6 +762,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
data.set(calculateItems(initContext, weigher));
}
catch (ProcessCanceledException ignore) {
+ cancel(); // some contributor may just throw PCE; if indicator is not canceled everything will hang
}
catch (Throwable t) {
cancel();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
index d8fd3ab40508..4ac5e686c5bc 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
@@ -709,11 +709,20 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements JDOM
return new Runnable() {
@Override
public void run() {
- if (myDisposed || !myProject.isInitialized()) return;
- if (PowerSaveMode.isEnabled()) return;
- Editor activeEditor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ if (myDisposed || !myProject.isInitialized() || PowerSaveMode.isEnabled()) {
+ return;
+ }
+ if (HeavyProcessLatch.INSTANCE.isRunning()) {
+ if (myAlarm.isEmpty()) {
+ myAlarm.addRequest(myUpdateRunnable, mySettings.AUTOREPARSE_DELAY);
+ }
+ return;
+ }
+ Editor activeEditor = FileEditorManager.getInstance(myProject).getSelectedTextEditor();
final PsiDocumentManagerImpl documentManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(myProject);
+
Runnable runnable = new Runnable() {
@Override
public void run() {
@@ -728,7 +737,6 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements JDOM
final Collection<FileEditor> activeEditors = getSelectedEditors();
if (activeEditors.isEmpty()) return;
- ApplicationManager.getApplication().assertIsDispatchThread();
if (ApplicationManager.getApplication().isWriteAccessAllowed()) {
// makes no sense to start from within write action, will cancel anyway
// we'll restart when write action finish
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
index c8d5ec4b8ddb..760029d689db 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java
@@ -507,7 +507,7 @@ public class DaemonListeners implements Disposable {
}
@Override
- public void profileActivated(@NotNull Profile oldProfile, Profile profile) {
+ public void profileActivated(Profile oldProfile, Profile profile) {
stopDaemonAndRestartAllFiles();
}
@@ -530,6 +530,7 @@ public class DaemonListeners implements Disposable {
StatusBarEx statusBar = (StatusBarEx)WindowManager.getInstance().getStatusBar(myProject);
myTogglePopupHintsPanel = new TogglePopupHintsPanel(myProject);
statusBar.addWidget(myTogglePopupHintsPanel, myProject);
+ updateStatusBar();
stopDaemonAndRestartAllFiles();
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorTracker.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorTracker.java
index cfa7c029d8fc..c88ac636243a 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorTracker.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/EditorTracker.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.
@@ -209,7 +209,7 @@ public class EditorTracker extends AbstractProjectComponent {
return filtered;
}
- private void setActiveEditors(@NotNull List<Editor> editors) {
+ void setActiveEditors(@NotNull List<Editor> editors) {
myActiveEditors = editors;
if (LOG.isDebugEnabled()) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java
index 2c44451ef260..72b0a4471e9c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java
@@ -34,6 +34,7 @@ import com.intellij.openapi.editor.markup.MarkupModel;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
@@ -115,33 +116,50 @@ public class IdentifierHighlighterPass extends TextEditorHighlightingPass {
}
}
- private void highlightTargetUsages(@NotNull PsiElement target) {
+ /**
+ * Returns read and write usages of psi element inside single file
+ *
+ * @param target target psi element
+ * @param psiFile psi file for element
+ * @return a pair where first element is read usages and second is write usages
+ */
+ public static Couple<Collection<TextRange>> getHighlightUsages(@NotNull PsiElement target, PsiFile psiFile) {
+ Collection<TextRange> readRanges = new ArrayList<TextRange>();
+ Collection<TextRange> writeRanges = new ArrayList<TextRange>();
final ReadWriteAccessDetector detector = ReadWriteAccessDetector.findDetector(target);
final FindUsagesManager findUsagesManager = ((FindManagerImpl)FindManager.getInstance(target.getProject())).getFindUsagesManager();
final FindUsagesHandler findUsagesHandler = findUsagesManager.getFindUsagesHandler(target, true);
- final LocalSearchScope scope = new LocalSearchScope(myFile);
+ final LocalSearchScope scope = new LocalSearchScope(psiFile);
Collection<PsiReference> refs = findUsagesHandler != null
? findUsagesHandler.findReferencesToHighlight(target, scope)
: ReferencesSearch.search(target, scope).findAll();
for (PsiReference psiReference : refs) {
final List<TextRange> textRanges = HighlightUsagesHandler.getRangesToHighlight(psiReference);
if (detector == null || detector.getReferenceAccess(target, psiReference) == ReadWriteAccessDetector.Access.Read) {
- myReadAccessRanges.addAll(textRanges);
+ readRanges.addAll(textRanges);
}
else {
- myWriteAccessRanges.addAll(textRanges);
+ writeRanges.addAll(textRanges);
}
}
- final TextRange declRange = HighlightUsagesHandler.getNameIdentifierRange(myFile, target);
+ final TextRange declRange = HighlightUsagesHandler.getNameIdentifierRange(psiFile, target);
if (declRange != null) {
if (detector != null && detector.isDeclarationWriteAccess(target)) {
- myWriteAccessRanges.add(declRange);
+ writeRanges.add(declRange);
}
else {
- myReadAccessRanges.add(declRange);
+ readRanges.add(declRange);
}
}
+
+ return Couple.of(readRanges, writeRanges);
+ }
+
+ private void highlightTargetUsages(@NotNull PsiElement target) {
+ final Couple<Collection<TextRange>> usages = getHighlightUsages(target, myFile);
+ myReadAccessRanges.addAll(usages.first);
+ myWriteAccessRanges.addAll(usages.second);
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
index 207b66be6112..0761379652ac 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java
@@ -223,7 +223,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
Divider.divideInsideAndOutside(myFile, myStartOffset, myEndOffset, myPriorityRange, inside, new ArrayList<ProperTextRange>(), outside, new ArrayList<ProperTextRange>(),
true, FILE_FILTER);
- MultiMap<LocalInspectionToolWrapper, String> toolToLanguages = getToolsForElements(toolWrappers, checkDumbAwareness, inside, outside);
+ MultiMap<LocalInspectionToolWrapper, String> toolToLanguages = InspectionEngine.getToolsForElements(toolWrappers, checkDumbAwareness, inside, outside);
setProgressLimit(toolToLanguages.size() * 2L);
final LocalInspectionToolSession session = new LocalInspectionToolSession(myFile, myStartOffset, myEndOffset);
@@ -240,76 +240,6 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
}
@NotNull
- private static MultiMap<LocalInspectionToolWrapper, String> getToolsForElements(@NotNull List<LocalInspectionToolWrapper> toolWrappers,
- boolean checkDumbAwareness,
- @NotNull List<PsiElement> inside,
- @NotNull List<PsiElement> outside) {
- Set<Language> languages = new SmartHashSet<Language>();
- Map<String, Language> langIds = new SmartHashMap<String, Language>();
- Set<String> dialects = new SmartHashSet<String>();
- calculateDialects(inside, languages, langIds, dialects);
- calculateDialects(outside, languages, langIds, dialects);
- MultiMap<LocalInspectionToolWrapper, String> toolToLanguages = new MultiMap<LocalInspectionToolWrapper, String>() {
- @NotNull
- @Override
- protected Collection<String> createCollection() {
- return new SmartHashSet<String>();
- }
-
- @NotNull
- @Override
- protected Collection<String> createEmptyCollection() {
- return Collections.emptySet();
- }
- };
- for (LocalInspectionToolWrapper wrapper : toolWrappers) {
- ProgressManager.checkCanceled();
- String language = wrapper.getLanguage();
- if (language == null) {
- LocalInspectionTool tool = wrapper.getTool();
- if (!checkDumbAwareness || tool instanceof DumbAware) {
- toolToLanguages.put(wrapper, null);
- }
- continue;
- }
- Language lang = langIds.get(language);
- if (lang != null) {
- LocalInspectionTool tool = wrapper.getTool();
- if (!checkDumbAwareness || tool instanceof DumbAware) {
- toolToLanguages.putValue(wrapper, language);
- if (wrapper.applyToDialects()) {
- for (Language dialect : lang.getDialects()) {
- toolToLanguages.putValue(wrapper, dialect.getID());
- }
- }
- }
- }
- else if (wrapper.applyToDialects() && dialects.contains(language)) {
- LocalInspectionTool tool = wrapper.getTool();
- if (!checkDumbAwareness || tool instanceof DumbAware) {
- toolToLanguages.putValue(wrapper, language);
- }
- }
- }
- return toolToLanguages;
- }
-
- private static void calculateDialects(@NotNull List<PsiElement> inside,
- @NotNull Set<Language> languages,
- @NotNull Map<String, Language> langIds,
- @NotNull Set<String> dialects) {
- for (PsiElement element : inside) {
- Language language = element.getLanguage();
- if (languages.add(language)) {
- langIds.put(language.getID(), language);
- for (Language dialect : language.getDialects()) {
- dialects.add(dialect.getID());
- }
- }
- }
- }
-
- @NotNull
private List<InspectionContext> visitPriorityElementsAndInit(@NotNull MultiMap<LocalInspectionToolWrapper, String> toolToLanguages,
@NotNull final InspectionManagerEx iManager,
final boolean isOnTheFly,
@@ -412,17 +342,16 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
});
}
if (injected.isEmpty()) return;
- if (!JobLauncher.getInstance().invokeConcurrentlyUnderProgress(new ArrayList<PsiFile>(injected), indicator,
- myFailFastOnAcquireReadAction,
- new Processor<PsiFile>() {
- @Override
- public boolean process(final PsiFile injectedPsi) {
- doInspectInjectedPsi(injectedPsi, onTheFly, indicator, iManager,
- inVisibleRange,
- wrappers, checkDumbAwareness);
- return true;
- }
- })) throw new ProcessCanceledException();
+ Processor<PsiFile> processor = new Processor<PsiFile>() {
+ @Override
+ public boolean process(final PsiFile injectedPsi) {
+ doInspectInjectedPsi(injectedPsi, onTheFly, indicator, iManager, inVisibleRange, wrappers, checkDumbAwareness);
+ return true;
+ }
+ };
+ if (!JobLauncher.getInstance().invokeConcurrentlyUnderProgress(new ArrayList<PsiFile>(injected), indicator, myFailFastOnAcquireReadAction, processor)) {
+ throw new ProcessCanceledException();
+ }
}
@Nullable
@@ -740,7 +669,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
return;
}
MultiMap<LocalInspectionToolWrapper, String> toolToLanguages =
- getToolsForElements(wrappers, checkDumbAwareness, elements, Collections.<PsiElement>emptyList());
+ InspectionEngine.getToolsForElements(wrappers, checkDumbAwareness, elements, Collections.<PsiElement>emptyList());
for (final Map.Entry<LocalInspectionToolWrapper, Collection<String>> pair : toolToLanguages.entrySet()) {
indicator.checkCanceled();
final LocalInspectionToolWrapper wrapper = pair.getKey();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java
index 1f47f5c5c69a..57f65283fd2f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiElementListNavigator.java
@@ -33,6 +33,7 @@ import com.intellij.ui.CollectionListModel;
import com.intellij.ui.JBListWithHintProvider;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.popup.AbstractPopup;
+import com.intellij.ui.popup.HintUpdateSupply;
import com.intellij.usages.UsageView;
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
@@ -147,8 +148,7 @@ public class PsiElementListNavigator {
setCancelCallback(new Computable<Boolean>() {
@Override
public Boolean compute() {
- list.hideHint();
-
+ HintUpdateSupply.hideHint(list);
return true;
}
});
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java
index 9c4404a21d58..c67af24d8cdc 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficLightRenderer.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.
@@ -42,7 +42,6 @@ import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiFile;
import com.intellij.ui.LayeredIcon;
import com.intellij.util.ArrayUtil;
-import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.UIUtil;
import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.NonNls;
@@ -57,9 +56,7 @@ import java.util.List;
import java.util.Set;
public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
- private static final Icon IN_PROGRESS_ICON = AllIcons.General.ErrorsInProgress;
private static final Icon NO_ANALYSIS_ICON = AllIcons.General.NoAnalysis;
- private static final Icon NO_ICON = new EmptyIcon(IN_PROGRESS_ICON.getIconWidth(), IN_PROGRESS_ICON.getIconHeight());
private static final Icon STARING_EYE_ICON = AllIcons.General.InspectionInProgress;
private final Project myProject;
@@ -162,6 +159,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
public boolean enabled = true;
public int rootsNumber;
+ @Override
public String toString() {
@NonNls String s = "DS: finished=" + errorAnalyzingFinished;
s += "; pass statuses: " + passStati.size() + "; ";
@@ -175,7 +173,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
@Nullable
protected DaemonCodeAnalyzerStatus getDaemonCodeAnalyzerStatus(boolean fillErrorsCount, SeverityRegistrar severityRegistrar) {
- if (myFile == null || myProject.isDisposed() || !myDaemonCodeAnalyzer.isHighlightingAvailable(myFile)) return null;
+ if (myFile == null || myProject != null && myProject.isDisposed() || !myDaemonCodeAnalyzer.isHighlightingAvailable(myFile)) return null;
List<String> noInspectionRoots = new ArrayList<String>();
List<String> noHighlightingRoots = new ArrayList<String>();
@@ -243,10 +241,7 @@ public class TrafficLightRenderer implements ErrorStripeRenderer, Disposable {
}
private Icon getIcon(DaemonCodeAnalyzerStatus status) {
- if (status == null) {
- return NO_ICON;
- }
- if (status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
+ if (status == null || status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
return NO_ANALYSIS_ICON;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java
index 19a958a8bd71..74cfdd9f434e 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java
@@ -137,31 +137,33 @@ public class TrafficProgressPanel extends JPanel {
}
}
- private void rebuildPassesPanel(@NotNull TrafficLightRenderer.DaemonCodeAnalyzerStatus status) {
+ private void rebuildPassesPanel(@Nullable TrafficLightRenderer.DaemonCodeAnalyzerStatus status) {
myPassStatuses.removeAll();
myPassStatuses.setLayout(new GridBagLayout());
passes.clear();
GridBagConstraints c = new GridBagConstraints();
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
- for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
- JLabel label = new JLabel(pass.getPresentableName() + ": ");
- label.setHorizontalTextPosition(SwingConstants.RIGHT);
+ if (status != null) {
+ for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
+ JLabel label = new JLabel(pass.getPresentableName() + ": ");
+ label.setHorizontalTextPosition(SwingConstants.RIGHT);
- JProgressBar progressBar = new JProgressBar(0, MAX);
- progressBar.putClientProperty("JComponent.sizeVariant", "mini");
- JLabel percLabel = new JLabel();
- passes.put(pass, Pair.create(progressBar, percLabel));
- myProgressToText.put(progressBar, percLabel);
- c.gridx = 0;
- myPassStatuses.add(label, c);
- c.gridx = 1;
- myPassStatuses.add(progressBar, c);
- c.gridx = 2;
- c.weightx = 1;
- myPassStatuses.add(percLabel, c);
+ JProgressBar progressBar = new JProgressBar(0, MAX);
+ progressBar.putClientProperty("JComponent.sizeVariant", "mini");
+ JLabel percLabel = new JLabel();
+ passes.put(pass, Pair.create(progressBar, percLabel));
+ myProgressToText.put(progressBar, percLabel);
+ c.gridx = 0;
+ myPassStatuses.add(label, c);
+ c.gridx = 1;
+ myPassStatuses.add(progressBar, c);
+ c.gridx = 2;
+ c.weightx = 1;
+ myPassStatuses.add(percLabel, c);
- c.gridy++;
+ c.gridy++;
+ }
}
myHintHint.initStyle(myPassStatuses, true);
@@ -169,7 +171,6 @@ public class TrafficProgressPanel extends JPanel {
}
public void updatePanel(@Nullable TrafficLightRenderer.DaemonCodeAnalyzerStatus status, boolean isFake) {
- if (status == null) return;
boolean isDumb = DumbService.isDumb(myTrafficLightRenderer.getProject());
dumbLabel.setVisible(isDumb);
try {
@@ -178,6 +179,12 @@ public class TrafficProgressPanel extends JPanel {
myPassStatuses.setVisible(false);
statistics.setText("");
}
+ else if (status == null || status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
+ statusLabel.setText(DaemonBundle.message("analysis.hasnot.been.run"));
+ myPassStatuses.setVisible(true);
+ setPassesEnabled(false, Boolean.FALSE);
+ statistics.setText("");
+ }
else if (status.errorAnalyzingFinished) {
if (isDumb) {
statusLabel.setText("Shallow analysis completed");
@@ -194,12 +201,6 @@ public class TrafficProgressPanel extends JPanel {
setPassesEnabled(false, Boolean.FALSE);
statistics.setText("");
}
- else if (status.noHighlightingRoots != null && status.noHighlightingRoots.length == status.rootsNumber) {
- statusLabel.setText(DaemonBundle.message("analysis.hasnot.been.run"));
- myPassStatuses.setVisible(true);
- setPassesEnabled(false, Boolean.FALSE);
- statistics.setText("");
- }
else {
statusLabel.setText(DaemonBundle.message("performing.code.analysis"));
myPassStatuses.setVisible(true);
@@ -207,42 +208,45 @@ public class TrafficProgressPanel extends JPanel {
}
- if (!status.passStati.equals(new ArrayList<ProgressableTextEditorHighlightingPass>(passes.keySet()))) {
+ if (status == null ||
+ !status.passStati.equals(new ArrayList<ProgressableTextEditorHighlightingPass>(passes.keySet()))) {
// passes set has changed
rebuildPassesPanel(status);
}
- for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
- double progress = pass.getProgress();
- Pair<JProgressBar, JLabel> pair = passes.get(pass);
- JProgressBar progressBar = pair.first;
- int percent = (int)Math.round(progress * MAX);
- progressBar.setValue(percent);
- JLabel percentage = pair.second;
- percentage.setText(percent + "%");
- }
+ if (status != null) {
+ for (ProgressableTextEditorHighlightingPass pass : status.passStati) {
+ double progress = pass.getProgress();
+ Pair<JProgressBar, JLabel> pair = passes.get(pass);
+ JProgressBar progressBar = pair.first;
+ int percent = (int)Math.round(progress * MAX);
+ progressBar.setValue(percent);
+ JLabel percentage = pair.second;
+ percentage.setText(percent + "%");
+ }
- int currentSeverityErrors = 0;
- @Language("HTML")
- String text = "";
- for (int i = status.errorCount.length - 1; i >= 0; i--) {
- if (status.errorCount[i] > 0) {
- final HighlightSeverity severity = SeverityRegistrar.getSeverityRegistrar(myTrafficLightRenderer.getProject()).getSeverityByIndex(i);
- String name =
- status.errorCount[i] > 1 ? StringUtil.pluralize(severity.getName().toLowerCase()) : severity.getName().toLowerCase();
+ int currentSeverityErrors = 0;
+ @Language("HTML")
+ String text = "";
+ for (int i = status.errorCount.length - 1; i >= 0; i--) {
+ if (status.errorCount[i] > 0) {
+ final HighlightSeverity severity = SeverityRegistrar.getSeverityRegistrar(myTrafficLightRenderer.getProject()).getSeverityByIndex(i);
+ String name =
+ status.errorCount[i] > 1 ? StringUtil.pluralize(severity.getName().toLowerCase()) : severity.getName().toLowerCase();
+ text += status.errorAnalyzingFinished
+ ? DaemonBundle.message("errors.found", status.errorCount[i], name)
+ : DaemonBundle.message("errors.found.so.far", status.errorCount[i], name);
+ text += "<br>";
+ currentSeverityErrors += status.errorCount[i];
+ }
+ }
+ if (currentSeverityErrors == 0) {
text += status.errorAnalyzingFinished
- ? DaemonBundle.message("errors.found", status.errorCount[i], name)
- : DaemonBundle.message("errors.found.so.far", status.errorCount[i], name);
- text += "<br>";
- currentSeverityErrors += status.errorCount[i];
+ ? DaemonBundle.message("no.errors.or.warnings.found")
+ : DaemonBundle.message("no.errors.or.warnings.found.so.far") + "<br>";
}
+ statistics.setText(XmlStringUtil.wrapInHtml(text));
}
- if (currentSeverityErrors == 0) {
- text += status.errorAnalyzingFinished
- ? DaemonBundle.message("no.errors.or.warnings.found")
- : DaemonBundle.message("no.errors.or.warnings.found.so.far") + "<br>";
- }
- statistics.setText(XmlStringUtil.wrapInHtml(text));
}
finally {
if (isFake) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java
index 40a798c6af48..a1d95d51d7b4 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/WholeFileLocalInspectionsPassFactory.java
@@ -76,7 +76,7 @@ public class WholeFileLocalInspectionsPassFactory extends AbstractProjectCompone
}
@Override
- public void profileActivated(@NotNull Profile oldProfile, Profile profile) {
+ public void profileActivated(Profile oldProfile, Profile profile) {
myFileTools.clear();
}
};
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java
index 83f17299987b..e0d17d3c164b 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java
@@ -23,7 +23,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.AsyncResult;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowType;
@@ -34,6 +34,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.content.*;
+import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
@@ -136,30 +137,33 @@ public abstract class DockablePopupManager<T extends JComponent & Disposable> {
protected AnAction[] createActions() {
- return new AnAction[]{
- new ToggleAction(getAutoUpdateTitle(), getAutoUpdateDescription(),
- AllIcons.General.AutoscrollFromSource) {
- @Override
- public boolean isSelected(AnActionEvent e) {
- return myAutoUpdateDocumentation;
- }
-
- @Override
- public void setSelected(AnActionEvent e, boolean state) {
- PropertiesComponent.getInstance().setValue(getAutoUpdateEnabledProperty(), String.valueOf(state));
- myAutoUpdateDocumentation = state;
- restartAutoUpdate(state);
- }
- },
- new AnAction("Restore Popup", getRestorePopupDescription(), AllIcons.Actions.Cancel) {
- @Override
- public void actionPerformed(AnActionEvent e) {
- restorePopupBehavior();
- }
- }};
+ ToggleAction toggleAutoUpdateAction = new ToggleAction(getAutoUpdateTitle(), getAutoUpdateDescription(),
+ AllIcons.General.AutoscrollFromSource) {
+ @Override
+ public boolean isSelected(AnActionEvent e) {
+ return myAutoUpdateDocumentation;
+ }
+
+ @Override
+ public void setSelected(AnActionEvent e, boolean state) {
+ PropertiesComponent.getInstance().setValue(getAutoUpdateEnabledProperty(), String.valueOf(state));
+ myAutoUpdateDocumentation = state;
+ restartAutoUpdate(state);
+ }
+ };
+ return new AnAction[]{toggleAutoUpdateAction, createRestorePopupAction()};
+ }
+
+ @NotNull
+ protected AnAction createRestorePopupAction() {
+ return new AnAction("Restore Popup", getRestorePopupDescription(), AllIcons.Actions.Cancel) {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ restorePopupBehavior();
+ }
+ };
}
-
protected void restartAutoUpdate(final boolean state) {
if (state && myToolWindow != null) {
if (myAutoUpdateRequest == null) {
@@ -189,12 +193,16 @@ public abstract class DockablePopupManager<T extends JComponent & Disposable> {
public void updateComponent() {
if (myProject.isDisposed()) return;
- AsyncResult<DataContext> asyncResult = DataManager.getInstance().getDataContextFromFocus();
- DataContext dataContext = asyncResult.getResult();
- if (dataContext == null) {
- return;
- }
+ DataManager.getInstance().getDataContextFromFocus().doWhenDone(new Consumer<DataContext>() {
+ @Override
+ public void consume(@NotNull DataContext dataContext) {
+ if (!myProject.isOpen()) return;
+ updateComponentInner(dataContext);
+ }
+ });
+ }
+ private void updateComponentInner(@NotNull DataContext dataContext) {
if (CommonDataKeys.PROJECT.getData(dataContext) != myProject) {
return;
}
@@ -228,13 +236,10 @@ public abstract class DockablePopupManager<T extends JComponent & Disposable> {
protected void restorePopupBehavior() {
if (myToolWindow != null) {
PropertiesComponent.getInstance().setValue(getShowInToolWindowProperty(), Boolean.FALSE.toString());
-
- final Content[] contents = myToolWindow.getContentManager().getContents();
- for (final Content content : contents) {
- myToolWindow.getContentManager().removeContent(content, true);
- }
-
- ToolWindowManagerEx.getInstanceEx(myProject).unregisterToolWindow(getToolwindowId());
+ ToolWindowManagerEx toolWindowManagerEx = ToolWindowManagerEx.getInstanceEx(myProject);
+ toolWindowManagerEx.hideToolWindow(getToolwindowId(), false);
+ toolWindowManagerEx.unregisterToolWindow(getToolwindowId());
+ Disposer.dispose(myToolWindow.getContentManager());
myToolWindow = null;
restartAutoUpdate(false);
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
index cf9b5ad22798..50f69088033b 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.impl.ActionButton;
import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
@@ -47,6 +48,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.SmartPointerManager;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.JBColor;
import com.intellij.ui.SideBorder;
import com.intellij.ui.components.JBLayeredPane;
import com.intellij.ui.components.JBScrollPane;
@@ -66,10 +68,9 @@ import javax.swing.event.HyperlinkListener;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
-import java.util.Collections;
+import java.net.URL;
+import java.util.*;
import java.util.List;
-import java.util.Map;
-import java.util.Stack;
public class DocumentationComponent extends JPanel implements Disposable, DataProvider {
@@ -92,7 +93,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
private final Stack<Context> myBackStack = new Stack<Context>();
private final Stack<Context> myForwardStack = new Stack<Context>();
private final ActionToolbar myToolBar;
- private boolean myIsEmpty;
+ private volatile boolean myIsEmpty;
private boolean myIsShown;
private final JLabel myElementLabel;
private Style myFontSizeStyle;
@@ -101,6 +102,13 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
private final MyShowSettingsButton myShowSettingsButton;
private boolean myIgnoreFontSizeSliderChange;
private String myEffectiveExternalUrl;
+ private final MyDictionary<String, Image> myImageProvider = new MyDictionary<String, Image>() {
+ @Override
+ public Image get(Object key) {
+ PsiElement element = getElement();
+ return element == null ? null : myManager.getElementImage(element, ((URL)key).toExternalForm());
+ }
+ };
private static class Context {
final SmartPsiElementPointer element;
@@ -178,6 +186,14 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
GraphicsUtil.setupAntialiasing(g);
super.paintComponent(g);
}
+
+ @Override
+ public void setDocument(Document doc) {
+ super.setDocument(doc);
+ if (doc instanceof StyledDocument) {
+ doc.putProperty("imageCache", myImageProvider);
+ }
+ }
};
DataProvider helpDataProvider = new DataProvider() {
@Override
@@ -308,6 +324,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
if (additionalActions != null) {
for (final AnAction action : additionalActions) {
actions.add(action);
+ ShortcutSet shortcutSet = action.getShortcutSet();
+ if (shortcutSet != null) {
+ action.registerCustomShortcutSet(shortcutSet, this);
+ }
}
}
@@ -378,7 +398,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
myFontSizeSlider.setSnapToTicks(true);
UIUtil.setSliderIsFilled(myFontSizeSlider, true);
result.add(myFontSizeSlider);
- result.setBorder(BorderFactory.createLineBorder(UIUtil.getBorderColor(), 1));
+ result.setBorder(BorderFactory.createLineBorder(JBColor.border(), 1));
myFontSizeSlider.addChangeListener(new ChangeListener() {
@Override
@@ -418,11 +438,11 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
}
- public synchronized boolean isEmpty() {
+ public boolean isEmpty() {
return myIsEmpty;
}
- public synchronized void startWait() {
+ public void startWait() {
myIsEmpty = true;
}
@@ -473,7 +493,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
}
public void replaceText(String text, PsiElement element) {
- if (element == null || getElement() != element) return;
+ PsiElement current = getElement();
+ if (current == null || !current.getManager().areElementsEquivalent(current, element)) return;
setText(text, element, false);
if (!myBackStack.empty()) myBackStack.pop();
}
@@ -530,6 +551,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
myText = text;
}
+ //noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
@@ -544,7 +566,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
return;
}
- StyledDocument styledDocument = (StyledDocument)document;
+ final StyledDocument styledDocument = (StyledDocument)document;
if (myFontSizeStyle == null) {
myFontSizeStyle = styledDocument.addStyle("active", null);
}
@@ -555,7 +577,14 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
if (Registry.is("documentation.component.editor.font")) {
StyleConstants.setFontFamily(myFontSizeStyle, scheme.getEditorFontName());
}
- styledDocument.setCharacterAttributes(0, document.getLength(), myFontSizeStyle, false);
+
+ final Style sizeStyle = myFontSizeStyle;
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ styledDocument.setCharacterAttributes(0, styledDocument.getLength(), sizeStyle, false);
+ }
+ });
}
private void goBack() {
@@ -631,15 +660,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
private class EditDocumentationSourceAction extends BaseNavigateToSourceAction {
- protected EditDocumentationSourceAction() {
+ EditDocumentationSourceAction() {
super(true);
- }
-
- @Override
- public void update(AnActionEvent event) {
- super.update(event);
- event.getPresentation().setIcon(AllIcons.Actions.EditSource);
- event.getPresentation().setText("Edit Source");
+ getTemplatePresentation().setIcon(AllIcons.Actions.EditSource);
+ getTemplatePresentation().setText("Edit Source");
}
@Override
@@ -678,8 +702,8 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
final PsiElement originalElement = DocumentationManager.getOriginalElement(element);
boolean processed = false;
if (provider instanceof CompositeDocumentationProvider) {
- for (final DocumentationProvider documentationProvider : ((CompositeDocumentationProvider)provider).getProviders()) {
- if (documentationProvider instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)documentationProvider).handleExternal(element, originalElement)) {
+ for (DocumentationProvider p : ((CompositeDocumentationProvider)provider).getAllProviders()) {
+ if (p instanceof ExternalDocumentationHandler && ((ExternalDocumentationHandler)p).handleExternal(element, originalElement)) {
processed = true;
break;
}
@@ -874,4 +898,36 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
mySettingsPanel.setVisible(true);
}
}
+
+ private static abstract class MyDictionary<K, V> extends Dictionary<K, V> {
+ @Override
+ public int size() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<K> keys() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<V> elements() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+ }
}
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 05a1e01c6aa1..63484f890225 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java
@@ -36,9 +36,11 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderEntry;
@@ -58,13 +60,13 @@ import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.ListScrollingUtil;
import com.intellij.ui.content.Content;
import com.intellij.ui.popup.AbstractPopup;
-import com.intellij.ui.popup.NotLookupOrSearchCondition;
import com.intellij.ui.popup.PopupPositionManager;
import com.intellij.ui.popup.PopupUpdateProcessor;
import com.intellij.util.Alarm;
import com.intellij.util.BooleanFunction;
import com.intellij.util.Consumer;
import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -125,6 +127,24 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return "Auto Show Documentation for Selected Element";
}
+ @NotNull
+ @Override
+ protected AnAction createRestorePopupAction() {
+ AnAction restorePopupAction = super.createRestorePopupAction();
+ ShortcutSet quickDocShortcut = ActionManager.getInstance().getAction(IdeActions.ACTION_QUICK_JAVADOC).getShortcutSet();
+ restorePopupAction.registerCustomShortcutSet(quickDocShortcut, null);
+ return restorePopupAction;
+ }
+
+ @Override
+ protected void restorePopupBehavior() {
+ if (myPreviouslyFocused != null) {
+ IdeFocusManager.getInstance(myProject).requestFocus(myPreviouslyFocused, true);
+ }
+ super.restorePopupBehavior();
+ updateComponent();
+ }
+
/**
* @return <code>true</code> if quick doc control is configured to not prevent user-IDE interaction (e.g. should be closed if
* the user presses a key);
@@ -165,7 +185,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Override
public void beforeEditorTyping(char c, DataContext dataContext) {
final JBPopup hint = getDocInfoHint();
- if (hint != null) {
+ if (hint != null && LookupManager.getActiveLookup(myEditor) == null) {
hint.cancel();
}
}
@@ -213,7 +233,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
public void showJavaDocInfo(@NotNull final PsiElement element, final PsiElement original) {
- showJavaDocInfo(element, original, false, null);
+ showJavaDocInfo(element, original, null);
}
/**
@@ -229,35 +249,31 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
* two possible situations - the quick doc is shown automatically on mouse over element; the quick doc is shown
* on explicit action call (Ctrl+Q). We want to close the doc on, say, editor viewport position change
* at the first situation but don't want to do that at the second
- * @param allowReuse defines whether currently requested documentation should reuse existing doc control (if any)
*/
public void showJavaDocInfo(@NotNull Editor editor,
@NotNull final PsiElement element,
@NotNull final PsiElement original,
@Nullable Runnable closeCallback,
- boolean closeOnSneeze,
- boolean allowReuse)
+ boolean closeOnSneeze)
{
myEditor = editor;
myCloseOnSneeze = closeOnSneeze;
- showJavaDocInfo(element, original, allowReuse, closeCallback);
+ showJavaDocInfo(element, original, closeCallback);
}
public void showJavaDocInfo(@NotNull final PsiElement element,
final PsiElement original,
- boolean allowReuse,
- @Nullable Runnable closeCallback)
- {
+ @Nullable Runnable closeCallback) {
PopupUpdateProcessor updateProcessor = new PopupUpdateProcessor(element.getProject()) {
@Override
public void updatePopup(Object lookupItemObject) {
if (lookupItemObject instanceof PsiElement) {
- doShowJavaDocInfo((PsiElement)lookupItemObject, false, this, original, false);
+ doShowJavaDocInfo((PsiElement)lookupItemObject, false, this, original, null);
}
}
};
- doShowJavaDocInfo(element, false, updateProcessor, original, allowReuse, closeCallback);
+ doShowJavaDocInfo(element, false, updateProcessor, original, closeCallback);
}
public void showJavaDocInfo(final Editor editor, @Nullable final PsiFile file, boolean requestFocus) {
@@ -267,14 +283,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
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) {
+ @Nullable final Runnable closeCallback) {
myEditor = editor;
final Project project = getProject(file);
PsiDocumentManager.getInstance(project).commitAllDocuments();
@@ -324,7 +333,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return;
}
if (lookupIteObject instanceof PsiElement) {
- doShowJavaDocInfo((PsiElement)lookupIteObject, false, this, originalElement, autoupdate, closeCallback);
+ doShowJavaDocInfo((PsiElement)lookupIteObject, false, this, originalElement, closeCallback);
return;
}
@@ -347,12 +356,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
}
else {
- doShowJavaDocInfo(element, false, this, originalElement, autoupdate, closeCallback);
+ doShowJavaDocInfo(element, false, this, originalElement, closeCallback);
}
}
};
- doShowJavaDocInfo(element, requestFocus, updateProcessor, originalElement, autoupdate, closeCallback);
+ doShowJavaDocInfo(element, requestFocus, updateProcessor, originalElement, closeCallback);
}
public PsiElement findTargetElement(Editor editor, PsiFile file) {
@@ -363,54 +372,56 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return file != null ? file.findElementAt(editor.getCaretModel().getOffset()) : null;
}
- private void doShowJavaDocInfo(final PsiElement element, boolean requestFocus, PopupUpdateProcessor updateProcessor,
- final PsiElement originalElement, final boolean autoupdate)
- {
- doShowJavaDocInfo(element, requestFocus, updateProcessor, originalElement, autoupdate, null);
- }
-
private void doShowJavaDocInfo(@NotNull final PsiElement element,
boolean requestFocus,
PopupUpdateProcessor updateProcessor,
final PsiElement originalElement,
- final boolean allowReuse,
- @Nullable final Runnable closeCallback)
- {
+ @Nullable final Runnable closeCallback) {
Project project = getProject(element);
storeOriginalElement(project, originalElement, element);
+ myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(project);
+
+ JBPopup _oldHint = getDocInfoHint();
if (myToolWindow == null && PropertiesComponent.getInstance().isTrueValue(SHOW_DOCUMENTATION_IN_TOOL_WINDOW)) {
createToolWindow(element, originalElement);
- return;
}
else if (myToolWindow != null) {
- if (allowReuse && !myToolWindow.isAutoHide()) {
- final Content content = myToolWindow.getContentManager().getSelectedContent();
- if (content != null) {
- final DocumentationComponent component = (DocumentationComponent)content.getComponent();
- if (component.getElement() != element) {
- content.setDisplayName(getTitle(element, true));
- fetchDocInfo(getDefaultCollector(element, originalElement), component, true);
+ Content content = myToolWindow.getContentManager().getSelectedContent();
+ if (content != null) {
+ DocumentationComponent component = (DocumentationComponent)content.getComponent();
+ if (element.getManager().areElementsEquivalent(component.getElement(), element)) {
+ JComponent preferredFocusableComponent = content.getPreferredFocusableComponent();
+ // focus toolwindow on the second actionPerformed
+ boolean focus = requestFocus || CommandProcessor.getInstance().getCurrentCommand() != null;
+ if (preferredFocusableComponent != null && focus) {
+ IdeFocusManager.getInstance(myProject).requestFocus(preferredFocusableComponent, true);
}
}
-
- if (!myToolWindow.isVisible()) {
- myToolWindow.show(null);
+ else {
+ content.setDisplayName(getTitle(element, true));
+ fetchDocInfo(getDefaultCollector(element, originalElement), component, true);
}
- return;
}
- else {
- restorePopupBehavior();
+
+ if (!myToolWindow.isVisible()) {
+ myToolWindow.show(null);
}
}
-
- final JBPopup _oldHint = getDocInfoHint();
- if (_oldHint != null && _oldHint.isVisible() && _oldHint instanceof AbstractPopup) {
- final DocumentationComponent oldComponent = (DocumentationComponent)((AbstractPopup)_oldHint).getComponent();
+ else if (_oldHint != null && _oldHint.isVisible() && _oldHint instanceof AbstractPopup) {
+ DocumentationComponent oldComponent = (DocumentationComponent)((AbstractPopup)_oldHint).getComponent();
fetchDocInfo(getDefaultCollector(element, originalElement), oldComponent);
- return;
}
+ else {
+ showInPopup(element, requestFocus, updateProcessor, originalElement, closeCallback);
+ }
+ }
+ private void showInPopup(@NotNull final PsiElement element,
+ boolean requestFocus,
+ PopupUpdateProcessor updateProcessor,
+ final PsiElement originalElement,
+ @Nullable final Runnable closeCallback) {
final DocumentationComponent component = new DocumentationComponent(this);
component.setNavigateCallback(new Consumer<PsiElement>() {
@Override
@@ -426,26 +437,30 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Override
public boolean process(JBPopup popup) {
createToolWindow(element, originalElement);
+ myToolWindow.setAutoHide(false);
popup.cancel();
return false;
}
};
- final KeyboardShortcut keyboardShortcut = ActionManagerEx.getInstanceEx().getKeyboardShortcut("QuickJavaDoc");
- final List<Pair<ActionListener, KeyStroke>> actions =
- Collections.singletonList(Pair.<ActionListener, KeyStroke>create(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- createToolWindow(element, originalElement);
- final JBPopup hint = getDocInfoHint();
- if (hint != null && hint.isVisible()) hint.cancel();
- }
- }, keyboardShortcut != null ? keyboardShortcut.getFirstKeyStroke() : null)); // Null keyStroke is ok here
+ ActionListener actionListener = new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ createToolWindow(element, originalElement);
+ final JBPopup hint = getDocInfoHint();
+ if (hint != null && hint.isVisible()) hint.cancel();
+ }
+ };
+ List<Pair<ActionListener, KeyStroke>> actions = ContainerUtil.newSmartList();
+ AnAction quickDocAction = ActionManagerEx.getInstanceEx().getAction(IdeActions.ACTION_QUICK_JAVADOC);
+ for (Shortcut shortcut : quickDocAction.getShortcutSet().getShortcuts()) {
+ if (!(shortcut instanceof KeyboardShortcut)) continue;
+ actions.add(Pair.create(actionListener, ((KeyboardShortcut)shortcut).getFirstKeyStroke()));
+ }
boolean hasLookup = LookupManager.getActiveLookup(myEditor) != null;
final JBPopup hint = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component)
- .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
- .setProject(project)
+ .setProject(element.getProject())
.addListener(updateProcessor)
.addUserData(updateProcessor)
.setKeyboardActions(actions)
@@ -490,20 +505,6 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
})
.createPopup();
-
- AbstractPopup oldHint = (AbstractPopup)getDocInfoHint();
- if (oldHint != null) {
- DocumentationComponent oldComponent = (DocumentationComponent)oldHint.getComponent();
- PsiElement element1 = oldComponent.getElement();
- if (Comparing.equal(element, element1)) {
- if (requestFocus) {
- component.getComponent().requestFocus();
- }
- return;
- }
- oldHint.cancel();
- }
-
component.setHint(hint);
if (myEditor == null) {
@@ -515,7 +516,6 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
fetchDocInfo(getDefaultCollector(element, originalElement), component);
myDocInfoHintRef = new WeakReference<JBPopup>(hint);
- myPreviouslyFocused = WindowManagerEx.getInstanceEx().getFocusedComponent(project);
if (fromQuickSearch() && myPreviouslyFocused != null) {
((ChooseByNameBase.JPanelProvider)myPreviouslyFocused.getParent()).registerHint(hint);
@@ -666,11 +666,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
private ActionCallback doFetchDocInfo(final DocumentationComponent component, final DocumentationCollector provider, final boolean cancelRequests, final boolean clearHistory) {
final ActionCallback callback = new ActionCallback();
+ boolean wasEmpty = component.isEmpty();
component.startWait();
if (cancelRequests) {
myUpdateDocAlarm.cancelAllRequests();
}
- if (component.isEmpty()) {
+ if (wasEmpty) {
component.setText(CodeInsightBundle.message("javadoc.fetching.progress"), null, clearHistory);
final AbstractPopup jbPopup = (AbstractPopup)getDocInfoHint();
if (jbPopup != null) {
@@ -845,7 +846,26 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
} else if (url.startsWith(PSI_ELEMENT_PROTOCOL)) {
final String refText = url.substring(PSI_ELEMENT_PROTOCOL.length());
DocumentationProvider provider = getProviderFromElement(psiElement);
- final PsiElement targetElement = provider.getDocumentationElementForLink(manager, refText, psiElement);
+ PsiElement targetElement = provider.getDocumentationElementForLink(manager, refText, psiElement);
+ if (targetElement == null) {
+ for (DocumentationProvider documentationProvider : Extensions.getExtensions(DocumentationProvider.EP_NAME)) {
+ targetElement = documentationProvider.getDocumentationElementForLink(manager, refText, psiElement);
+ if (targetElement != null) {
+ break;
+ }
+ }
+ }
+ if (targetElement == null) {
+ for (Language language : Language.getRegisteredLanguages()) {
+ DocumentationProvider documentationProvider = LanguageDocumentation.INSTANCE.forLanguage(language);
+ if (documentationProvider != null) {
+ targetElement = documentationProvider.getDocumentationElementForLink(manager, refText, psiElement);
+ if (targetElement != null) {
+ break;
+ }
+ }
+ }
+ }
if (targetElement != null) {
fetchDocInfo(getDefaultCollector(targetElement, null), component);
}
@@ -854,33 +874,33 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
final DocumentationProvider provider = getProviderFromElement(psiElement);
boolean processed = false;
if (provider instanceof CompositeDocumentationProvider) {
- for (DocumentationProvider documentationProvider : ((CompositeDocumentationProvider)provider).getProviders()) {
- if (documentationProvider instanceof ExternalDocumentationHandler) {
- final ExternalDocumentationHandler externalDocumentationHandler = (ExternalDocumentationHandler)documentationProvider;
- if (externalDocumentationHandler.canFetchDocumentationLink(url)) {
- fetchDocInfo(new DocumentationCollector() {
- @Override
- public String getDocumentation() throws Exception {
- return externalDocumentationHandler.fetchExternalDocumentation(url, psiElement);
- }
+ for (DocumentationProvider p : ((CompositeDocumentationProvider)provider).getAllProviders()) {
+ if (!(p instanceof ExternalDocumentationHandler)) continue;
- @Override
- public PsiElement getElement() {
- return psiElement;
- }
+ final ExternalDocumentationHandler externalHandler = (ExternalDocumentationHandler)p;
+ if (externalHandler.canFetchDocumentationLink(url)) {
+ fetchDocInfo(new DocumentationCollector() {
+ @Override
+ public String getDocumentation() throws Exception {
+ return externalHandler.fetchExternalDocumentation(url, psiElement);
+ }
- @Nullable
- @Override
- public String getEffectiveExternalUrl() {
- return url;
- }
- }, component);
- processed = true;
- }
- else if (externalDocumentationHandler.handleExternalLink(manager, url, psiElement)) {
- processed = true;
- break;
- }
+ @Override
+ public PsiElement getElement() {
+ return psiElement;
+ }
+
+ @Nullable
+ @Override
+ public String getEffectiveExternalUrl() {
+ return url;
+ }
+ }, component);
+ processed = true;
+ }
+ else if (externalHandler.handleExternalLink(manager, url, psiElement)) {
+ processed = true;
+ break;
}
}
}
@@ -979,12 +999,12 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
@Override
protected void doUpdateComponent(Editor editor, PsiFile psiFile) {
- showJavaDocInfo(editor, psiFile, false, true, null);
+ showJavaDocInfo(editor, psiFile, false, null);
}
@Override
protected void doUpdateComponent(@NotNull PsiElement element) {
- showJavaDocInfo(element, element, true, null);
+ showJavaDocInfo(element, element, null);
}
@Override
@@ -992,6 +1012,20 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
return getTitle(element, true);
}
+ @Nullable
+ public Image getElementImage(@NotNull PsiElement element, @NotNull String imageSpec) {
+ DocumentationProvider provider = getProviderFromElement(element);
+ if (provider instanceof CompositeDocumentationProvider) {
+ for (DocumentationProvider p : ((CompositeDocumentationProvider)provider).getAllProviders()) {
+ if (p instanceof DocumentationProviderEx) {
+ Image image = ((DocumentationProviderEx)p).getLocalImageForElement(element, imageSpec);
+ if (image != null) return image;
+ }
+ }
+ }
+ return null;
+ }
+
private interface DocumentationCollector {
@Nullable
String getDocumentation() throws Exception;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
index 47bf01f2e7c8..0cd18020ad54 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocOnMouseOverManager.java
@@ -301,7 +301,7 @@ public class QuickDocOnMouseOverManager {
info.editor.putUserData(PopupFactoryImpl.ANCHOR_POPUP_POSITION,
info.editor.offsetToVisualPosition(info.originalElement.getTextRange().getStartOffset()));
try {
- info.docManager.showJavaDocInfo(info.editor, info.targetElement, info.originalElement, myHintCloseCallback, true, true);
+ info.docManager.showJavaDocInfo(info.editor, info.targetElement, info.originalElement, myHintCloseCallback, true);
myDocumentationManager = new WeakReference<DocumentationManager>(info.docManager);
}
finally {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java
new file mode 100644
index 000000000000..064bd020183b
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/QuickDocUtil.java
@@ -0,0 +1,72 @@
+/*
+ * 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.documentation;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.ui.content.Content;
+import com.intellij.ui.popup.AbstractPopup;
+import com.intellij.util.Producer;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author gregsh
+ */
+public class QuickDocUtil {
+
+ public static void updateQuickDocAsync(@NotNull final PsiElement element, @NotNull final Producer<String> docProducer) {
+ final Project project = element.getProject();
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ final String documentation = docProducer.produce();
+ if (StringUtil.isEmpty(documentation)) return;
+ // modal dialogs with fragment editors fix: can't guess proper modality state here
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ DocumentationManager documentationManager = DocumentationManager.getInstance(project);
+ DocumentationComponent component;
+ JBPopup hint = documentationManager.getDocInfoHint();
+ if (hint != null) {
+ component = (DocumentationComponent)((AbstractPopup)hint).getComponent();
+ }
+ else if (documentationManager.hasActiveDockedDocWindow()) {
+ ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.DOCUMENTATION);
+ Content selectedContent = toolWindow == null ? null : toolWindow.getContentManager().getSelectedContent();
+ component = selectedContent == null ? null : (DocumentationComponent)selectedContent.getComponent();
+ }
+ else {
+ component = null;
+ }
+ if (component != null) {
+ component.replaceText(documentation, element);
+ }
+ }
+ });
+ }
+ });
+ }
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java
index eb163245d23b..8010e76335bb 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java
@@ -44,13 +44,15 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
@Override
public Result checkAutoPopup(char charTyped, final Project project, final Editor editor, final PsiFile file) {
- CompletionPhase oldPhase = CompletionServiceImpl.getCompletionPhase();
+ LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor);
- if (oldPhase instanceof CompletionPhase.CommittingDocuments && ((CompletionPhase.CommittingDocuments)oldPhase).isRestartingCompletion()) {
- return Result.STOP;
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("checkAutoPopup: character=" + charTyped + ";");
+ LOG.debug("phase=" + CompletionServiceImpl.getCompletionPhase());
+ LOG.debug("lookup=" + lookup);
+ LOG.debug("currentCompletion=" + CompletionServiceImpl.getCompletionService().getCurrentCompletion());
}
- LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor);
if (lookup != null) {
if (editor.getSelectionModel().hasSelection()) {
lookup.performGuardedChange(new Runnable() {
@@ -68,9 +70,6 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate {
return Result.STOP;
}
- if (CompletionServiceImpl.isPhase(CompletionPhase.CommittingDocuments.class)) {
- CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
- }
return Result.CONTINUE;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java
index 5f416dd307c4..1149576e4806 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/JoinLinesHandler.java
@@ -29,6 +29,7 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.editor.ScrollType;
@@ -49,6 +50,7 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NotNullFunction;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import static com.intellij.codeInsight.editorActions.JoinLinesHandlerDelegate.CANNOT_JOIN;
@@ -61,66 +63,65 @@ public class JoinLinesHandler extends EditorWriteActionHandler {
myOriginalHandler = originalHandler;
}
- private static TextRange findStartAndEnd(CharSequence text, int start, int end, int maxoffset) {
+ @NotNull
+ private static TextRange findStartAndEnd(@NotNull CharSequence text, int start, int end, int maxoffset) {
while (start > 0 && (text.charAt(start) == ' ' || text.charAt(start) == '\t')) start--;
while (end < maxoffset && (text.charAt(end) == ' ' || text.charAt(end) == '\t')) end++;
return new TextRange(start, end);
}
@Override
- public void executeWriteAction(final Editor editor, final DataContext dataContext) {
+ public void executeWriteAction(@NotNull final Editor editor, @Nullable Caret caret, final DataContext dataContext) {
+ assert caret != null;
if (!(editor.getDocument() instanceof DocumentEx)) {
- myOriginalHandler.execute(editor, dataContext);
+ myOriginalHandler.execute(editor, caret, dataContext);
return;
}
final DocumentEx doc = (DocumentEx)editor.getDocument();
final Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(editor.getContentComponent()));
- if (project == null) {
- return;
- }
-
- LogicalPosition caretPosition = editor.getCaretModel().getLogicalPosition();
+ if (project == null) return;
final PsiDocumentManager docManager = PsiDocumentManager.getInstance(project);
PsiFile psiFile = docManager.getPsiFile(doc);
if (psiFile == null) {
- myOriginalHandler.execute(editor, dataContext);
+ myOriginalHandler.execute(editor, caret, dataContext);
return;
}
+ LogicalPosition caretPosition = caret.getLogicalPosition();
int startLine = caretPosition.line;
int endLine = startLine + 1;
- if (editor.getSelectionModel().hasSelection()) {
- startLine = doc.getLineNumber(editor.getSelectionModel().getSelectionStart());
- endLine = doc.getLineNumber(editor.getSelectionModel().getSelectionEnd());
- if (doc.getLineStartOffset(endLine) == editor.getSelectionModel().getSelectionEnd()) endLine--;
+ if (caret.hasSelection()) {
+ startLine = doc.getLineNumber(caret.getSelectionStart());
+ endLine = doc.getLineNumber(caret.getSelectionEnd());
+ if (doc.getLineStartOffset(endLine) == caret.getSelectionEnd()) endLine--;
}
final int startReformatOffset = CharArrayUtil.shiftBackward(doc.getCharsSequence(), doc.getLineEndOffset(startLine), " \t");
CodeEditUtil.setNodeReformatStrategy(new NotNullFunction<ASTNode, Boolean>() {
@NotNull
@Override
- public Boolean fun(ASTNode node) {
+ public Boolean fun(@NotNull ASTNode node) {
return node.getTextRange().getStartOffset() >= startReformatOffset;
}
});
try {
- doJob(editor, doc, project, docManager, psiFile, startLine, endLine);
+ doJob(editor, doc, caret, project, docManager, psiFile, startLine, endLine);
}
finally {
CodeEditUtil.setNodeReformatStrategy(null);
}
}
- private static void doJob(Editor editor,
- DocumentEx doc,
- Project project,
- PsiDocumentManager docManager,
- PsiFile psiFile,
+ private static void doJob(@NotNull Editor editor,
+ @NotNull DocumentEx doc,
+ @NotNull Caret caret,
+ @NotNull Project project,
+ @NotNull PsiDocumentManager docManager,
+ @NotNull PsiFile psiFile,
int startLine,
- int endLine)
- {
+ int endLine) {
int caretRestoreOffset = -1;
// joining lines, several times if selection is multiline
for (int i = startLine; i < endLine; i++) {
@@ -262,17 +263,19 @@ public class JoinLinesHandler extends EditorWriteActionHandler {
}
docManager.commitDocument(doc); // cheap on an already-committed doc
- if (editor.getSelectionModel().hasSelection()) {
- editor.getCaretModel().moveToOffset(editor.getSelectionModel().getSelectionEnd());
+ if (caret.hasSelection()) {
+ caret.moveToOffset(caret.getSelectionEnd());
}
else if (caretRestoreOffset != CANNOT_JOIN) {
- editor.getCaretModel().moveToOffset(caretRestoreOffset);
- editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
- editor.getSelectionModel().removeSelection();
+ caret.moveToOffset(caretRestoreOffset);
+ if (caret == editor.getCaretModel().getPrimaryCaret()) { // performance
+ editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
+ }
+ caret.removeSelection();
}
}
- private static boolean isCommentElement(final PsiElement element) {
+ private static boolean isCommentElement(@Nullable final PsiElement element) {
return element != null && PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null;
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/GenerateByPatternDialog.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/GenerateByPatternDialog.java
index abdcf6c44047..f736a02d83bf 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/generation/GenerateByPatternDialog.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/GenerateByPatternDialog.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.codeInsight.generation;
import com.intellij.codeInsight.template.Template;
@@ -13,6 +28,7 @@ import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.treeStructure.SimpleTree;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -55,8 +71,9 @@ public class GenerateByPatternDialog extends DialogWrapper {
};
myTree.setRootVisible(false);
myTree.setCellRenderer(new DefaultTreeCellRenderer() {
+ @NotNull
@Override
- public Component getTreeCellRendererComponent(JTree tree,
+ public Component getTreeCellRendererComponent(@NotNull JTree tree,
Object value,
boolean sel,
boolean expanded,
@@ -78,7 +95,7 @@ public class GenerateByPatternDialog extends DialogWrapper {
myTree.setModel(new DefaultTreeModel(root));
myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
@Override
- public void valueChanged(TreeSelectionEvent e) {
+ public void valueChanged(@NotNull TreeSelectionEvent e) {
update();
}
});
@@ -141,6 +158,7 @@ public class GenerateByPatternDialog extends DialogWrapper {
private DefaultMutableTreeNode createNode(@Nullable PatternDescriptor descriptor) {
DefaultMutableTreeNode root = new DefaultMutableTreeNode(descriptor) {
+ @NotNull
@Override
public String toString() {
Object object = getUserObject();
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java
index 786c14b68201..2de362f14074 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactory.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.
@@ -23,6 +23,8 @@ import org.jetbrains.annotations.Nullable;
/**
* @author yole
+ *
+ * @see com.intellij.codeInsight.highlighting.HighlightUsagesHandlerFactoryBase
*/
public interface HighlightUsagesHandlerFactory {
ExtensionPointName<HighlightUsagesHandlerFactory> EP_NAME = ExtensionPointName.create("com.intellij.highlightUsagesHandlerFactory");
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactoryBase.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactoryBase.java
new file mode 100644
index 000000000000..83c6cf35c57e
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandlerFactoryBase.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.codeInsight.highlighting;
+
+import com.intellij.codeInsight.TargetElementUtilBase;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public abstract class HighlightUsagesHandlerFactoryBase implements HighlightUsagesHandlerFactory {
+ @Nullable
+ @Override
+ public final HighlightUsagesHandlerBase createHighlightUsagesHandler(Editor editor, PsiFile file) {
+ int offset = TargetElementUtilBase.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset());
+ PsiElement target = file.findElementAt(offset);
+ if (target == null) return null;
+ return createHighlightUsagesHandler(editor, file, target);
+ }
+
+ @Nullable
+ public abstract HighlightUsagesHandlerBase createHighlightUsagesHandler(@NotNull Editor editor, @NotNull PsiFile file, @NotNull PsiElement target);
+}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
index 4e1a8e958d91..b1ad07f906d2 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java
@@ -22,7 +22,6 @@ import com.intellij.lang.parameterInfo.ParameterInfoUIContextEx;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
@@ -296,47 +295,50 @@ public class ParameterInfoComponent extends JPanel {
public String setup(final String[] texts, final EnumSet<ParameterInfoUIContextEx.Flag>[] flags, final Color background) {
StringBuilder buf = new StringBuilder();
removeAll();
- final String[] lines = UIUtil.splitText(StringUtil.join(texts), getFontMetrics(BOLD_FONT), myWidthLimit, ',');
-
+ setBackground(background);
int index = 0;
int curOffset = 0;
-
- myOneLineComponents = new OneLineComponent[lines.length];
+ final ArrayList<OneLineComponent> components = new ArrayList<OneLineComponent>();
Map<TextRange, ParameterInfoUIContextEx.Flag> flagsMap = new TreeMap<TextRange, ParameterInfoUIContextEx.Flag>(TEXT_RANGE_COMPARATOR);
- int added = 0;
+ String line = "";
for (int i = 0; i < texts.length; i++) {
- String line = escapeString(texts[i]);
- if (lines.length <= index) break;
- String text = lines[index];
- final int paramCount = StringUtil.split(text, ", ").size();
+ String paramText = escapeString(texts[i]);
+ if (paramText == null) break;
+ line += texts[i];
final EnumSet<ParameterInfoUIContextEx.Flag> flag = flags[i];
if (flag.contains(ParameterInfoUIContextEx.Flag.HIGHLIGHT)) {
- flagsMap.put(TextRange.create(curOffset, curOffset + line.trim().length()), ParameterInfoUIContextEx.Flag.HIGHLIGHT);
+ flagsMap.put(TextRange.create(curOffset, curOffset + paramText.trim().length()), ParameterInfoUIContextEx.Flag.HIGHLIGHT);
}
if (flag.contains(ParameterInfoUIContextEx.Flag.DISABLE)) {
- flagsMap.put(TextRange.create(curOffset, curOffset + line.trim().length()), ParameterInfoUIContextEx.Flag.DISABLE);
+ flagsMap.put(TextRange.create(curOffset, curOffset + paramText.trim().length()), ParameterInfoUIContextEx.Flag.DISABLE);
}
if (flag.contains(ParameterInfoUIContextEx.Flag.STRIKEOUT)) {
- flagsMap.put(TextRange.create(curOffset, curOffset + line.trim().length()), ParameterInfoUIContextEx.Flag.STRIKEOUT);
+ flagsMap.put(TextRange.create(curOffset, curOffset + paramText.trim().length()), ParameterInfoUIContextEx.Flag.STRIKEOUT);
}
- curOffset += line.length();
- if (i == paramCount + added - 1) {
- myOneLineComponents[index] = new OneLineComponent();
- setBackground(background);
- buf.append(myOneLineComponents[index].setup(escapeString(text), flagsMap, background));
- add(myOneLineComponents[index], new GridBagConstraints(0, index, 1, 1, 1, 0, GridBagConstraints.WEST,
+ curOffset += paramText.length();
+ if (line.length() >= 50) {
+ final OneLineComponent component = new OneLineComponent();
+ buf.append(component.setup(escapeString(line), flagsMap, background));
+ add(component, new GridBagConstraints(0, index, 1, 1, 1, 0, GridBagConstraints.WEST,
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
index += 1;
flagsMap.clear();
- curOffset = 1;
- added += paramCount;
+ curOffset = 0;
+ line = "";
+ components.add(component);
}
}
+ final OneLineComponent component = new OneLineComponent();
+ buf.append(component.setup(escapeString(line), flagsMap, background));
+ add(component, new GridBagConstraints(0, index, 1, 1, 1, 0, GridBagConstraints.WEST,
+ GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ components.add(component);
+ myOneLineComponents = components.toArray(new OneLineComponent[components.size()]);
return buf.toString();
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java
index 4a7abe355380..afd7b230621c 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java
@@ -37,7 +37,6 @@ import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
@@ -48,7 +47,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.reference.SoftReference;
import com.intellij.ui.popup.AbstractPopup;
-import com.intellij.ui.popup.NotLookupOrSearchCondition;
import com.intellij.ui.popup.PopupPositionManager;
import com.intellij.ui.popup.PopupUpdateProcessor;
import com.intellij.usages.UsageView;
@@ -274,7 +272,6 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
};
popup = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component.getPreferredFocusableComponent())
- .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE)
.setProject(project)
.addListener(updateProcessor)
.addUserData(updateProcessor)
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java
index 62e3bcba3a22..d168002f97a7 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditAction.java
@@ -30,11 +30,15 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.*;
+import com.intellij.psi.ElementManipulators;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.impl.source.tree.injected.Place;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -93,14 +97,17 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
}
public QuickEditHandler invokeImpl(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException {
- final int offset = editor.getCaretModel().getOffset();
- final Pair<PsiElement, TextRange> pair = getRangePair(file, editor);
- assert pair != null;
- final PsiFile injectedFile = (PsiFile)pair.first;
- final int injectedOffset = ((DocumentWindow)PsiDocumentManager.getInstance(project).getDocument(injectedFile)).hostToInjected(offset);
+ int offset = editor.getCaretModel().getOffset();
+ Pair<PsiElement, TextRange> pair = ObjectUtils.assertNotNull(getRangePair(file, editor));
+
+ PsiFile injectedFile = (PsiFile)pair.first;
QuickEditHandler handler = getHandler(project, injectedFile, editor, file);
+
if (!ApplicationManager.getApplication().isUnitTestMode()) {
- handler.navigate(injectedOffset);
+ DocumentWindow documentWindow = InjectedLanguageUtil.getDocumentWindow(injectedFile);
+ if (documentWindow != null) {
+ handler.navigate(documentWindow.hostToInjected(offset));
+ }
}
return handler;
}
@@ -124,12 +131,15 @@ public class QuickEditAction implements IntentionAction, LowPriorityAction {
return handler;
}
- public static QuickEditHandler getExistingHandler(PsiFile injectedFile) {
+ public static QuickEditHandler getExistingHandler(@NotNull PsiFile injectedFile) {
Place shreds = InjectedLanguageUtil.getShreds(injectedFile);
- if (shreds == null) return null;
+ DocumentWindow documentWindow = InjectedLanguageUtil.getDocumentWindow(injectedFile);
+ if (shreds == null || documentWindow == null) return null;
+
TextRange hostRange = TextRange.create(shreds.get(0).getHostRangeMarker().getStartOffset(),
shreds.get(shreds.size() - 1).getHostRangeMarker().getEndOffset());
for (Editor editor : EditorFactory.getInstance().getAllEditors()) {
+ if (editor.getDocument() != documentWindow.getDelegate()) continue;
QuickEditHandler handler = editor.getUserData(QUICK_EDIT_HANDLER);
if (handler != null && handler.changesRange(hostRange)) return handler;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
index 2c5d8642e46d..517f23c5a198 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/QuickEditHandler.java
@@ -360,7 +360,7 @@ public class QuickEditHandler extends DocumentAdapter implements Disposable {
private void commitToOriginal() {
if (!isValid()) return;
- VirtualFile origVirtualFile = PsiUtilCore.getVirtualFile(ObjectUtils.assertNotNull(myNewFile.getContext()));
+ VirtualFile origVirtualFile = PsiUtilCore.getVirtualFile(myNewFile.getContext());
myCommittingToOriginal = true;
try {
if (origVirtualFile == null || !ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(origVirtualFile).hasReadonlyFiles()) {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java
index 46842af23c34..ca0a51112f98 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerImpl.java
@@ -20,12 +20,13 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.IntentionActionBean;
import com.intellij.codeInsight.intention.IntentionManager;
+import com.intellij.codeInspection.GlobalInspectionTool;
+import com.intellij.codeInspection.GlobalSimpleInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.actions.CleanupInspectionIntention;
import com.intellij.codeInspection.actions.RunInspectionIntention;
-import com.intellij.codeInspection.ex.DisableInspectionToolAction;
-import com.intellij.codeInspection.ex.EditInspectionToolsSettingsAction;
-import com.intellij.codeInspection.ex.EditInspectionToolsSettingsInSuppressedPlaceIntention;
+import com.intellij.codeInspection.ex.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPoint;
@@ -181,6 +182,32 @@ public class IntentionManagerImpl extends IntentionManager {
return options;
}
+ @Nullable
+ @Override
+ public IntentionAction createFixAllIntention(InspectionToolWrapper toolWrapper, IntentionAction action) {
+ if (toolWrapper instanceof LocalInspectionToolWrapper) {
+ Class aClass = action.getClass();
+ if (action instanceof QuickFixWrapper) {
+ aClass = ((QuickFixWrapper)action).getFix().getClass();
+ }
+ return new CleanupInspectionIntention(toolWrapper, aClass, action.getText());
+ }
+ else if (toolWrapper instanceof GlobalInspectionToolWrapper) {
+ GlobalInspectionTool wrappedTool = ((GlobalInspectionToolWrapper)toolWrapper).getTool();
+ if (wrappedTool instanceof GlobalSimpleInspectionTool && (action instanceof LocalQuickFix || action instanceof QuickFixWrapper)) {
+ Class aClass = action.getClass();
+ if (action instanceof QuickFixWrapper) {
+ aClass = ((QuickFixWrapper)action).getFix().getClass();
+ }
+ return new CleanupInspectionIntention(toolWrapper, aClass, action.getText());
+ }
+ }
+ else {
+ throw new AssertionError("unknown tool: " + toolWrapper);
+ }
+ return null;
+ }
+
@Override
@NotNull
public LocalQuickFix convertToFix(@NotNull final IntentionAction action) {
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 9a71909fcca8..869886d26523 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
@@ -776,15 +776,13 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
@Override
public void valueChanged(@NotNull ListSelectionEvent e){
- final LookupElement item = getCurrentItem();
- if (oldItem != item && !myList.isEmpty()) { // do not update on temporary model wipe
- fireCurrentItemChanged(item);
- if (myDisposed) { //a listener may have decided to close us, what can we do?
- return;
- }
+ if (!myUpdating) {
+ final LookupElement item = getCurrentItem();
+ fireCurrentItemChanged(oldItem, item);
oldItem = item;
}
}
+
});
new ClickListener() {
@@ -876,9 +874,9 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
}
}
- void fireCurrentItemChanged(LookupElement item){
- if (!myListeners.isEmpty()){
- LookupEvent event = new LookupEvent(this, item, (char)0);
+ private void fireCurrentItemChanged(@Nullable LookupElement oldItem, @Nullable LookupElement currentItem) {
+ if (oldItem != currentItem && !myListeners.isEmpty()) {
+ LookupEvent event = new LookupEvent(this, currentItem, (char)0);
for (LookupListener listener : myListeners) {
listener.currentItemChanged(event);
}
@@ -1088,6 +1086,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
public void refreshUi(boolean mayCheckReused, boolean onExplicitAction) {
assert !myUpdating;
+ LookupElement prevItem = getCurrentItem();
myUpdating = true;
try {
final boolean reused = mayCheckReused && checkReused();
@@ -1100,6 +1099,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable,
}
finally {
myUpdating = false;
+ fireCurrentItemChanged(prevItem, getCurrentItem());
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
index 2f56d3714943..5486a07f6f18 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
@@ -455,7 +455,7 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
@Override
public void showDocInfo(@NotNull DocumentationManager docManager) {
- docManager.showJavaDocInfo(myTargetElement, myElementAtPointer, true, null);
+ docManager.showJavaDocInfo(myTargetElement, myElementAtPointer, null);
docManager.setAllowContentUpdateFromContext(false);
}
}
@@ -1115,7 +1115,7 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
if (hint != null) {
hint.hide(true);
}
- myDocumentationManager.showJavaDocInfo(targetElement, myContext, true, null);
+ myDocumentationManager.showJavaDocInfo(targetElement, myContext, null);
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java
index 6ef571f62a03..0d49a89d9c43 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java
@@ -42,6 +42,7 @@ import com.intellij.psi.PsiNamedElement;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.JBListWithHintProvider;
import com.intellij.ui.popup.AbstractPopup;
+import com.intellij.ui.popup.HintUpdateSupply;
import com.intellij.usages.UsageView;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
@@ -179,7 +180,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler {
setCancelCallback(new Computable<Boolean>() {
@Override
public Boolean compute() {
- list.hideHint();
+ HintUpdateSupply.hideHint(list);
return true;
}
}).
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java
index 504ec1b13c41..a3fbbc62dd85 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java
@@ -125,13 +125,12 @@ public class ImplementationSearcher {
public static class FirstImplementationsSearcher extends ImplementationSearcher {
@Override
protected PsiElement[] searchDefinitions(final PsiElement element, final Editor editor) {
- final PsiElement[][] result = new PsiElement[1][];
-
if (canShowPopupWithOneItem(element)) {
return new PsiElement[]{element};
}
final PsiElementProcessor.CollectElementsWithLimit<PsiElement> collectProcessor = new PsiElementProcessor.CollectElementsWithLimit<PsiElement>(2, new THashSet<PsiElement>());
+ final PsiElement[][] result = new PsiElement[1][];
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
@Override
public void run() {
@@ -139,8 +138,7 @@ public class ImplementationSearcher {
DefinitionsScopedSearch.search(element, getSearchScope(element, editor)).forEach(new PsiElementProcessorAdapter<PsiElement>(collectProcessor){
@Override
public boolean processInReadAction(PsiElement element) {
- if (!accept(element)) return true;
- return super.processInReadAction(element);
+ return !accept(element) || super.processInReadAction(element);
}
});
result[0] = collectProcessor.toArray();
@@ -165,7 +163,7 @@ public class ImplementationSearcher {
}
}
- public static abstract class BackgroundableImplementationSearcher extends ImplementationSearcher {
+ public abstract static class BackgroundableImplementationSearcher extends ImplementationSearcher {
@Override
protected PsiElement[] searchDefinitions(final PsiElement element, Editor editor) {
final CommonProcessors.CollectProcessor<PsiElement> processor = new CommonProcessors.CollectProcessor<PsiElement>() {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElementImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElementImpl.java
index 9ce023727820..2ddf92cfe1ff 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElementImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateLookupElementImpl.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,7 +24,7 @@ public class LiveTemplateLookupElementImpl extends LiveTemplateLookupElement {
private final TemplateImpl myTemplate;
public LiveTemplateLookupElementImpl(@NotNull TemplateImpl template, boolean sudden) {
- super(template.getKey(), StringUtil.notNullize(template.getDescription()), sudden, false);
+ super(template.getKey(), StringUtil.notNullize(template.getDescription()), sudden, LiveTemplateCompletionContributor.shouldShowAllTemplates());
myTemplate = template;
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
index 1988c9d1d8a4..c14eca966e5f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.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,7 +28,6 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.popup.JBPopup;
@@ -52,7 +51,6 @@ import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
@@ -182,7 +180,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
myEditVariablesButton.addActionListener(
new ActionListener(){
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
editVariables();
}
}
@@ -201,7 +199,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
myTemplate.parseSegments();
}
- @Nullable
+ @NotNull
private JComponent createNorthPanel() {
JPanel panel = new JPanel(new GridBagLayout());
@@ -240,7 +238,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
myExpandByCombo = new ComboBox(new String[]{myDefaultShortcutItem, SPACE, TAB, ENTER});
myExpandByCombo.addItemListener(new ItemListener() {
@Override
- public void itemStateChanged(ItemEvent e) {
+ public void itemStateChanged(@NotNull ItemEvent e) {
Object selectedItem = myExpandByCombo.getSelectedItem();
if(myDefaultShortcutItem.equals(selectedItem)) {
myTemplate.setShortcutChar(TemplateSettings.DEFAULT_CHAR);
@@ -278,7 +276,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
cb.setSelected(myOptions.get(processor).booleanValue());
cb.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
myOptions.put(processor, cb.isSelected());
}
});
@@ -469,14 +467,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
}
private void updateHighlighter() {
- List<TemplateContextType> applicableContexts = getApplicableContexts();
- if (!applicableContexts.isEmpty()) {
- TemplateContext contextByType = new TemplateContext();
- contextByType.setEnabled(applicableContexts.get(0), true);
- TemplateEditorUtil.setHighlighter(myTemplateEditor, contextByType);
- return;
- }
- ((EditorEx) myTemplateEditor).repaint(0, myTemplateEditor.getDocument().getTextLength());
+ TemplateEditorUtil.setHighlighter(myTemplateEditor, ContainerUtil.getFirstItem(getApplicableContexts()));
}
private void validateEditVariablesButton() {
@@ -520,7 +511,7 @@ public class LiveTemplateSettingsEditor extends JPanel {
myCbReformat.setSelected(myTemplate.isToReformat());
myCbReformat.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
myTemplate.setToReformat(myCbReformat.isSelected());
}
});
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java
index 1570bb18c040..dd30df23a493 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.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,7 +18,6 @@ package com.intellij.codeInsight.template.impl;
import com.intellij.codeInsight.template.TemplateContextType;
import com.intellij.ide.DataManager;
-import com.intellij.lexer.CompositeLexer;
import com.intellij.lexer.Lexer;
import com.intellij.lexer.MergingLexerAdapter;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -31,7 +30,8 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.ex.EditorEx;
-import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
+import com.intellij.openapi.editor.ex.util.LayerDescriptor;
+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.fileEditor.FileDocumentManager;
@@ -42,6 +42,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -87,54 +88,41 @@ public class TemplateEditorUtil {
if (file != null) {
EditorHighlighter highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(file, scheme, project);
((EditorEx) editor).setHighlighter(highlighter);
+
}
return editor;
}
- public static void setHighlighter(Editor editor, TemplateContext templateContext) {
- SyntaxHighlighter baseHighlighter = null;
- for(TemplateContextType type: TemplateManagerImpl.getAllContextTypes()) {
- if (templateContext.isEnabled(type)) {
- baseHighlighter = type.createHighlighter();
- if (baseHighlighter != null) break;
+ public static void setHighlighter(Editor editor, @Nullable TemplateContext templateContext) {
+ SyntaxHighlighter highlighter = null;
+ if (templateContext != null) {
+ for(TemplateContextType type: TemplateManagerImpl.getAllContextTypes()) {
+ if (templateContext.isEnabled(type)) {
+ highlighter = type.createHighlighter();
+ if (highlighter != null) break;
+ }
}
}
- if (baseHighlighter == null) {
- baseHighlighter = new PlainSyntaxHighlighter();
- }
-
- SyntaxHighlighter highlighter = createTemplateTextHighlighter(baseHighlighter);
- ((EditorEx)editor).setHighlighter(new LexerEditorHighlighter(highlighter, EditorColorsManager.getInstance().getGlobalScheme()));
+ setHighlighter((EditorEx)editor, highlighter);
}
- private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(TemplateTokenType.TEXT);
+ public static void setHighlighter(@NotNull Editor editor, @Nullable TemplateContextType templateContextType) {
+ setHighlighter((EditorEx)editor, templateContextType != null ? templateContextType.createHighlighter() : null);
+ }
- private static SyntaxHighlighter createTemplateTextHighlighter(final SyntaxHighlighter original) {
- return new TemplateHighlighter(original);
+ private static void setHighlighter(EditorEx editor, @Nullable SyntaxHighlighter highlighter) {
+ EditorColorsScheme editorColorsScheme = EditorColorsManager.getInstance().getGlobalScheme();
+ LayeredLexerEditorHighlighter layeredHighlighter = new LayeredLexerEditorHighlighter(new TemplateHighlighter(), editorColorsScheme);
+ layeredHighlighter.registerLayer(TemplateTokenType.TEXT, new LayerDescriptor(ObjectUtils.notNull(highlighter, new PlainSyntaxHighlighter()), ""));
+ editor.setHighlighter(layeredHighlighter);
}
private static class TemplateHighlighter extends SyntaxHighlighterBase {
private final Lexer myLexer;
- private final SyntaxHighlighter myOriginalHighlighter;
-
- public TemplateHighlighter(SyntaxHighlighter original) {
- myOriginalHighlighter = original;
- Lexer originalLexer = original.getHighlightingLexer();
- Lexer templateLexer = new TemplateTextLexer();
- templateLexer = new MergingLexerAdapter(templateLexer, TOKENS_TO_MERGE);
-
- myLexer = new CompositeLexer(originalLexer, templateLexer) {
- @Override
- protected IElementType getCompositeTokenType(IElementType type1, IElementType type2) {
- if (type2 == TemplateTokenType.VARIABLE) {
- return type2;
- }
- else {
- return type1;
- }
- }
- };
+
+ public TemplateHighlighter() {
+ myLexer = new MergingLexerAdapter(new TemplateTextLexer(), TokenSet.create(TemplateTokenType.TEXT));
}
@Override
@@ -146,11 +134,7 @@ public class TemplateEditorUtil {
@Override
@NotNull
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
- if (tokenType == TemplateTokenType.VARIABLE) {
- return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
- }
-
- return myOriginalHighlighter.getTokenHighlights(tokenType);
+ return tokenType == TemplateTokenType.VARIABLE ? pack(TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES) : EMPTY;
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java
index e5f2fd4ae23d..abf28256aaef 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java
@@ -105,7 +105,7 @@ public class TemplateSettings implements PersistentStateComponent<Element>, Expo
private int myMaxKeyLength = 0;
private char myDefaultShortcutChar = TAB_CHAR;
private final SchemesManager<TemplateGroup, TemplateGroup> mySchemesManager;
- private static final String FILE_SPEC = "$ROOT_CONFIG$/templates";
+ private static final String FILE_SPEC = StoragePathMacros.ROOT_CONFIG + "/templates";
public static class TemplateKey {
private String groupName;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixDescriptionPanel.form b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixDescriptionPanel.form
index cd60a7de70f4..519481484dc7 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixDescriptionPanel.form
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/settings/PostfixDescriptionPanel.form
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.codeInsight.template.postfix.settings.PostfixDescriptionPanel">
- <grid id="d0bf1" binding="myPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="d0bf1" binding="myPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="26" y="23" width="498" height="354"/>
@@ -19,7 +19,9 @@
<xy id="a6fdd" binding="myAfterPanel" layout-manager="XYLayout" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="5" 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="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
+ <minimum-size width="-1" height="125"/>
+ </grid>
</constraints>
<properties/>
<border type="none"/>
@@ -28,7 +30,9 @@
<xy id="fa495" binding="myBeforePanel" layout-manager="XYLayout" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <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"/>
+ <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">
+ <minimum-size width="-1" height="125"/>
+ </grid>
</constraints>
<properties/>
<border type="none"/>
@@ -77,6 +81,11 @@
</component>
</children>
</grid>
+ <vspacer id="53ca7">
+ <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>
</children>
</grid>
</form>
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java
index 5cd822130538..0190fadbcf02 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/template/postfix/templates/PostfixLiveTemplate.java
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.template.impl.CustomLiveTemplateLookupElement;
import com.intellij.codeInsight.template.impl.TemplateSettings;
import com.intellij.codeInsight.template.postfix.completion.PostfixTemplateLookupElement;
import com.intellij.codeInsight.template.postfix.settings.PostfixTemplatesSettings;
+import com.intellij.diagnostic.AttachmentFactory;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationManager;
@@ -137,7 +138,8 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
}
// don't care about errors in multiCaret mode
else if (editor.getCaretModel().getAllCarets().size() == 1) {
- LOG.error("Template not found by key: " + key);
+ LOG.error("Template not found by key: " + key + "; offset = " + callback.getOffset(),
+ AttachmentFactory.createAttachment(callback.getFile().getVirtualFile()));
}
return;
}
@@ -145,7 +147,8 @@ public class PostfixLiveTemplate extends CustomLiveTemplateBase {
// don't care about errors in multiCaret mode
if (editor.getCaretModel().getAllCarets().size() == 1) {
- LOG.error("Template not found by key: " + key);
+ LOG.error("Template not found by key: " + key + "; offset = " + callback.getOffset(),
+ AttachmentFactory.createAttachment(callback.getFile().getVirtualFile()));
}
}
diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java b/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java
index d28c9a3874f5..b6a68ef88fb0 100644
--- a/platform/analysis-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/actions/CleanupInspectionIntention.java
@@ -17,6 +17,7 @@
package com.intellij.codeInspection.actions;
import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.intention.EmptyIntentionAction;
import com.intellij.codeInsight.intention.HighPriorityAction;
import com.intellij.codeInsight.intention.IntentionAction;
@@ -46,10 +47,12 @@ import java.util.List;
public class CleanupInspectionIntention implements IntentionAction, HighPriorityAction {
private final InspectionToolWrapper myToolWrapper;
private final Class myQuickfixClass;
+ private final String myText;
- public CleanupInspectionIntention(@NotNull InspectionToolWrapper toolWrapper, @NotNull Class quickFixClass) {
+ public CleanupInspectionIntention(@NotNull InspectionToolWrapper toolWrapper, @NotNull Class quickFixClass, String text) {
myToolWrapper = toolWrapper;
myQuickfixClass = quickFixClass;
+ myText = text;
}
@Override
@@ -84,6 +87,7 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
return d2.getTextRange().getStartOffset() - d1.getTextRange().getStartOffset();
}
});
+ boolean applicableFixFound = false;
for (final ProblemDescriptor descriptor : descriptions) {
final QuickFix[] fixes = descriptor.getFixes();
if (fixes != null && fixes.length > 0) {
@@ -91,6 +95,7 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
if (fix != null && fix.getClass().isAssignableFrom(myQuickfixClass)) {
final PsiElement element = descriptor.getPsiElement();
if (element != null && element.isValid()) {
+ applicableFixFound = true;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -104,6 +109,10 @@ public class CleanupInspectionIntention implements IntentionAction, HighPriority
}
}
}
+
+ if (!applicableFixFound) {
+ HintManager.getInstance().showErrorHint(editor, "Unfortunately '" + myText + "' is currently not available for batch mode");
+ }
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
index 090d83389b6c..695c2a72d200 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.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,7 +58,6 @@ import com.intellij.psi.*;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.content.*;
import com.intellij.util.Processor;
import com.intellij.util.SequentialModalProgressTask;
@@ -81,7 +80,7 @@ import java.util.*;
public class GlobalInspectionContextImpl extends GlobalInspectionContextBase implements GlobalInspectionContext {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.GlobalInspectionContextImpl");
- private static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("Inspection Results", ToolWindowId.INSPECTION, true);
+ private static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("Inspection Results", ToolWindowId.INSPECTION);
private final NotNullLazyValue<ContentManager> myContentManager;
private InspectionResultsView myView = null;
private Content myContent = null;
@@ -641,6 +640,8 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
final Project project,
final Runnable postRunnable,
final String commandName) {
+ final int fileCount = scope.getFileCount();
+ final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
final List<LocalInspectionToolWrapper> lTools = new ArrayList<LocalInspectionToolWrapper>();
final LinkedHashMap<PsiFile, List<HighlightInfo>> results = new LinkedHashMap<PsiFile, List<HighlightInfo>>();
@@ -655,8 +656,12 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
range = null;
}
scope.accept(new PsiElementVisitor() {
+ private int myCount = 0;
@Override
public void visitFile(PsiFile file) {
+ if (progressIndicator != null) {
+ progressIndicator.setFraction(((double)++ myCount)/fileCount);
+ }
if (isBinary(file)) return;
for (final Tools tools : profile.getAllEnabledInspectionTools(project)) {
if (tools.getTool().getTool() instanceof CleanupLocalInspectionTool) {
@@ -704,7 +709,9 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
public void run() {
- CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
+ if (commandName != null) {
+ CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
+ }
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -718,7 +725,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
}, commandName, null);
}
};
- if (ApplicationManager.getApplication().isUnitTestMode()) {
+ if (ApplicationManager.getApplication().isDispatchThread()) {
runnable.run();
} else {
ApplicationManager.getApplication().invokeLater(runnable);
diff --git a/platform/lang-impl/src/com/intellij/conversion/impl/ui/ConvertProjectDialog.java b/platform/lang-impl/src/com/intellij/conversion/impl/ui/ConvertProjectDialog.java
index e59d2d566698..cf73dba84a3a 100644
--- a/platform/lang-impl/src/com/intellij/conversion/impl/ui/ConvertProjectDialog.java
+++ b/platform/lang-impl/src/com/intellij/conversion/impl/ui/ConvertProjectDialog.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.
@@ -106,10 +106,8 @@ public class ConvertProjectDialog extends DialogWrapper {
final List<File> nonexistentFiles = myContext.getNonExistingModuleFiles();
if (!nonexistentFiles.isEmpty() && !myNonExistingFilesMessageShown) {
final String filesString = getFilesString(nonexistentFiles);
- final int res = Messages.showYesNoDialog(getContentPane(), IdeBundle.message("message.files.doesn.t.exists.0.so.the.corresponding.modules.won.t.be.converted.do.you.want.to.continue",
- filesString),
- IdeBundle.message("dialog.title.convert.project"),
- Messages.getQuestionIcon());
+ final String message = IdeBundle.message("message.text.files.do.not.exist", filesString);
+ final int res = Messages.showYesNoDialog(getContentPane(), message, IdeBundle.message("dialog.title.convert.project"), Messages.getQuestionIcon());
if (res != Messages.YES) {
super.doOKAction();
return;
diff --git a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java
index a4764dae0036..0c11e71e5886 100644
--- a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java
+++ b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java
@@ -30,6 +30,7 @@ import com.intellij.ide.util.PropertiesComponent;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.ListPopupStep;
@@ -919,35 +920,77 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider {
}
}
- public static ItemWrapper[] createSettingsList(@NotNull final Project project, @NotNull ExecutorProvider executorProvider, boolean createEditAction) {
- final RunManagerEx manager = RunManagerEx.getInstanceEx(project);
+ public static ItemWrapper[] createSettingsList(@NotNull Project project, @NotNull ExecutorProvider executorProvider, boolean createEditAction) {
+ List<ItemWrapper> result = new ArrayList<ItemWrapper>();
- final List<ItemWrapper> result = new ArrayList<ItemWrapper>();
+ if (createEditAction) {
+ ItemWrapper<Void> edit = new ItemWrapper<Void>(null) {
+ @Override
+ public Icon getIcon() {
+ return AllIcons.Actions.EditSource;
+ }
- final RunnerAndConfigurationSettings selectedConfiguration = manager.getSelectedConfiguration();
+ @Override
+ public String getText() {
+ return UIUtil.removeMnemonic(ActionsBundle.message("action.editRunConfigurations.text"));
+ }
+ @Override
+ public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) {
+ if (new EditConfigurationsDialog(project) {
+ @Override
+ protected void init() {
+ setOKButtonText(executor.getStartActionText());
+ setOKButtonIcon(executor.getIcon());
+ myExecutor = executor;
+ super.init();
+ }
+ }.showAndGet()) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ RunnerAndConfigurationSettings configuration = RunManager.getInstance(project).getSelectedConfiguration();
+ if (configuration != null) {
+ ExecutionUtil.runConfiguration(configuration, executor);
+ }
+ }
+ }, project.getDisposed());
+ }
+ }
+
+ @Override
+ public boolean available(Executor executor) {
+ return true;
+ }
+ };
+ edit.setMnemonic(0);
+ result.add(edit);
+ }
+
+ RunManagerEx manager = RunManagerEx.getInstanceEx(project);
+ final RunnerAndConfigurationSettings selectedConfiguration = manager.getSelectedConfiguration();
if (selectedConfiguration != null) {
boolean isFirst = true;
final ExecutionTarget activeTarget = ExecutionTargetManager.getActiveTarget(project);
- for (final ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, selectedConfiguration)) {
+ for (ExecutionTarget eachTarget : ExecutionTargetManager.getTargetsToChooseFor(project, selectedConfiguration)) {
result.add(new ItemWrapper<ExecutionTarget>(eachTarget, isFirst) {
{
- setChecked(eachTarget.equals(activeTarget));
+ setChecked(getValue().equals(activeTarget));
}
@Override
public Icon getIcon() {
- return eachTarget.getIcon();
+ return getValue().getIcon();
}
@Override
public String getText() {
- return eachTarget.getDisplayName();
+ return getValue().getDisplayName();
}
@Override
public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) {
- ExecutionTargetManager.setActiveTarget(project, eachTarget);
+ ExecutionTargetManager.setActiveTarget(project, getValue());
ExecutionUtil.runConfiguration(selectedConfiguration, executor);
}
@@ -960,18 +1003,24 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider {
}
}
- final Map<RunnerAndConfigurationSettings, ItemWrapper> wrappedExisting = new LinkedHashMap<RunnerAndConfigurationSettings, ItemWrapper>();
- final ConfigurationType[] types = manager.getConfigurationFactories();
- for (final ConfigurationType type : types) {
+ Map<RunnerAndConfigurationSettings, ItemWrapper> wrappedExisting = new LinkedHashMap<RunnerAndConfigurationSettings, ItemWrapper>();
+ for (ConfigurationType type : manager.getConfigurationFactories()) {
if (!(type instanceof UnknownConfigurationType)) {
Map<String, List<RunnerAndConfigurationSettings>> structure = manager.getStructure(type);
- for (final Map.Entry<String, List<RunnerAndConfigurationSettings>> entry : structure.entrySet()) {
- if (entry.getValue().isEmpty())
+ for (Map.Entry<String, List<RunnerAndConfigurationSettings>> entry : structure.entrySet()) {
+ if (entry.getValue().isEmpty()) {
continue;
+ }
+
final String key = entry.getKey();
- if (key != null){
+ if (key != null) {
boolean isSelected = entry.getValue().contains(selectedConfiguration);
- FolderWrapper folderWrapper = new FolderWrapper(project, executorProvider, key + (isSelected ? " (mnemonic is to \"" + selectedConfiguration.getName()+"\")" : ""), entry.getValue());
+ if (isSelected) {
+ assert selectedConfiguration != null;
+ }
+ FolderWrapper folderWrapper = new FolderWrapper(project, executorProvider,
+ key + (isSelected ? " (mnemonic is to \"" + selectedConfiguration.getName() + "\")" : ""),
+ entry.getValue());
if (isSelected) {
folderWrapper.setMnemonic(1);
}
@@ -992,53 +1041,6 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider {
populateWithDynamicRunners(result, wrappedExisting, project, manager, selectedConfiguration);
result.addAll(wrappedExisting.values());
-
- //noinspection unchecked
- final ItemWrapper edit = new ItemWrapper(null) {
- @Override
- public Icon getIcon() {
- return AllIcons.Actions.EditSource;
- }
-
- @Override
- public String getText() {
- return UIUtil.removeMnemonic(ActionsBundle.message("action.editRunConfigurations.text"));
- }
-
- @Override
- public void perform(@NotNull final Project project, @NotNull final Executor executor, @NotNull DataContext context) {
- final EditConfigurationsDialog dialog = new EditConfigurationsDialog(project) {
- @Override
- protected void init() {
- setOKButtonText(executor.getStartActionText());
- setOKButtonIcon(executor.getIcon());
- myExecutor = executor;
- super.init();
- }
- };
-
- dialog.show();
- if (dialog.isOK()) {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- ExecutionUtil.runConfiguration(RunManager.getInstance(project).getSelectedConfiguration(), executor);
- }
- });
- }
- }
-
- @Override
- public boolean available(Executor executor) {
- return true;
- }
- };
-
- edit.setMnemonic(0);
- if (createEditAction) {
- result.add(0, edit);
- }
-
return result.toArray(new ItemWrapper[result.size()]);
}
diff --git a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java
index 21c7deabff9f..4375e164fed4 100644
--- a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java
+++ b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesComponent.java
@@ -26,13 +26,13 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Comparing;
import com.intellij.ui.UserActivityProviderComponent;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.EnvironmentUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.event.ChangeListener;
import java.io.File;
-import java.util.HashMap;
import java.util.Map;
public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWithBrowseButton> implements UserActivityProviderComponent {
@@ -113,19 +113,19 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
element.addContent(envsElement);
}
+ /**
+ * To be removed in IDEA 15
+ * @deprecated use {@link com.intellij.util.EnvironmentUtil#inlineParentOccurrences(java.util.Map)} instead
+ */
+ @Deprecated
public static void inlineParentOccurrences(final Map<String, String> envs) {
- final Map<String, String> parentParams = new HashMap<String, String>(System.getenv());
- for (String envKey : envs.keySet()) {
- final String val = envs.get(envKey);
- if (val != null) {
- final String parentVal = parentParams.get(envKey);
- if (parentVal != null && containsEnvKeySubstitution(envKey, val)) {
- envs.put(envKey, val.replace("$" + envKey + "$", parentVal));
- }
- }
- }
+ EnvironmentUtil.inlineParentOccurrences(envs);
}
+ /**
+ * To be removed in IDEA 15
+ */
+ @Deprecated
public static boolean containsEnvKeySubstitution(final String envKey, final String val) {
return ArrayUtil.find(val.split(File.pathSeparator), "$" + envKey + "$") != -1;
}
diff --git a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java
index 0fe445371186..5f3785f1de66 100644
--- a/platform/lang-api/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java
+++ b/platform/lang-impl/src/com/intellij/execution/configuration/EnvironmentVariablesTextFieldWithBrowseButton.java
@@ -15,13 +15,15 @@
*/
package com.intellij.execution.configuration;
+import com.google.common.collect.ImmutableMap;
import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.util.EnvVariablesTable;
import com.intellij.execution.util.EnvironmentVariable;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.ui.UserActivityProviderComponent;
+import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
-import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,12 +33,14 @@ import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.*;
+import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
-public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWithBrowseButton {
+public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWithBrowseButton implements UserActivityProviderComponent {
- private final Map<String, String> myEnvs = new THashMap<String, String>();
+ private Map<String, String> myEnvs = Collections.emptyMap();
private boolean myPassParentEnvs;
private final List<ChangeListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
@@ -51,14 +55,20 @@ public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWith
});
}
+ /**
+ * @return unmodifiable Map instance, use {@link #setEnvs(java.util.Map)} to update env vars
+ */
@NotNull
public Map<String, String> getEnvs() {
return myEnvs;
}
+ /**
+ * @param envs Map instance with reliable user-specified iteration order,
+ * like {@link java.util.LinkedHashMap} or {@link com.google.common.collect.ImmutableMap}
+ */
public void setEnvs(@NotNull Map<String, String> envs) {
- myEnvs.clear();
- myEnvs.putAll(envs);
+ myEnvs = ImmutableMap.copyOf(envs);
String envsStr = stringifyEnvs(myEnvs);
setText(envsStr);
}
@@ -89,10 +99,12 @@ public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWith
}
}
+ @Override
public void addChangeListener(ChangeListener changeListener) {
myListeners.add(changeListener);
}
+ @Override
public void removeChangeListener(ChangeListener changeListener) {
myListeners.remove(changeListener);
}
@@ -111,10 +123,12 @@ public class EnvironmentVariablesTextFieldWithBrowseButton extends TextFieldWith
protected MyEnvironmentVariablesDialog() {
super(EnvironmentVariablesTextFieldWithBrowseButton.this, true);
myEnvVariablesTable = new EnvVariablesTable();
- List<EnvironmentVariable> envVariables = ContainerUtil.newArrayList();
- for (Map.Entry<String, String> entry : myEnvs.entrySet()) {
- envVariables.add(new EnvironmentVariable(entry.getKey(), entry.getValue(), false));
- }
+ List<EnvironmentVariable> envVariables = ContainerUtil.map(myEnvs.entrySet(), new Function<Map.Entry<String, String>, EnvironmentVariable>() {
+ @Override
+ public EnvironmentVariable fun(Map.Entry<String, String> entry) {
+ return new EnvironmentVariable(entry.getKey(), entry.getValue(), false);
+ }
+ });
myEnvVariablesTable.setValues(envVariables);
myUseDefaultCb.setSelected(isPassParentEnvs());
myWholePanel.add(myEnvVariablesTable.getComponent(), BorderLayout.CENTER);
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
index 605d073945b5..3fce510e725e 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
@@ -674,7 +674,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
final Document document = myEditor.getDocument();
final RangeMarker lastProcessedOutput = document.createRangeMarker(document.getTextLength(), document.getTextLength());
final int caretOffset = myEditor.getCaretModel().getOffset();
- final boolean isAtLastLine = document.getLineNumber(caretOffset) >= document.getLineCount() - 1;
+ final boolean isAtLastLine = isCaretAtLastLine();
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
@Override
@@ -1078,6 +1078,9 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
};
if (immediately) {
model.runBatchFoldingOperation(operation);
+ if (isCaretAtLastLine()) {
+ EditorUtil.scrollToTheEnd(myEditor);
+ }
}
else {
model.runBatchFoldingOperationDoNotCollapseCaret(operation);
@@ -1092,6 +1095,12 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
}
}
+ private boolean isCaretAtLastLine() {
+ final Document document = myEditor.getDocument();
+ final int caretOffset = myEditor.getCaretModel().getOffset();
+ return document.getLineNumber(caretOffset) >= document.getLineCount() - 1;
+ }
+
private void addFolding(Document document, CharSequence chars, int line, List<FoldRegion> toAdd) {
String commandLinePlaceholder = myCommandLineFolding.getPlaceholder(line);
if (commandLinePlaceholder != null) {
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/EditConfigurationsDialog.java b/platform/lang-impl/src/com/intellij/execution/impl/EditConfigurationsDialog.java
index d206283375e2..265d9c3f7410 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/EditConfigurationsDialog.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/EditConfigurationsDialog.java
@@ -26,7 +26,7 @@ public class EditConfigurationsDialog extends SingleConfigurableEditor implement
protected Executor myExecutor;
public EditConfigurationsDialog(final Project project) {
- super(project, new RunConfigurable(project), IdeModalityType.PROJECT);
+ super(project, new RunConfigurable(project), "#com.intellij.execution.impl.EditConfigurationsDialog", IdeModalityType.PROJECT);
((RunConfigurable)getConfigurable()).setRunDialog(this);
setTitle(ExecutionBundle.message("run.debug.dialog.title"));
setHorizontalStretch(1.3F);
@@ -42,11 +42,6 @@ public class EditConfigurationsDialog extends SingleConfigurableEditor implement
}
}
- @Override
- protected String getDimensionServiceKey() {
- return "#com.intellij.execution.impl.EditConfigurationsDialog";
- }
-
@Nullable
@Override
public Executor getExecutor() {
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java
index 3645439db470..95d4db09c297 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java
@@ -589,8 +589,14 @@ class RunConfigurable extends BaseConfigurable {
@Override
public JComponent createComponent() {
for (RunConfigurationsSettings each : Extensions.getExtensions(RunConfigurationsSettings.EXTENSION_POINT)) {
- UnnamedConfigurable configurable = each.createConfigurable();
- myAdditionalSettings.add(Pair.create(configurable, configurable.createComponent()));
+ try {
+ UnnamedConfigurable configurable = each.createConfigurable(myProject);
+ myAdditionalSettings.add(Pair.create(configurable, configurable.createComponent()));
+ }
+ catch (NoSuchMethodError e) {
+ // in case someone has already implemented old RunConfigurationsSettings.createConfigurable()
+ LOG.error(e);
+ }
}
myWholePanel = new JPanel(new BorderLayout());
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 7bcabebf256a..d1c3c4877493 100644
--- a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java
+++ b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java
@@ -104,6 +104,13 @@ public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsole
myConsoleView.attachToProcess(myProcessHandler);
// Runner creating
+ createContentDescriptorAndActions();
+
+ // Run
+ myProcessHandler.startNotify();
+ }
+
+ protected void createContentDescriptorAndActions() {
final Executor defaultExecutor = DefaultRunExecutor.getRunExecutorInstance();
final DefaultActionGroup toolbarActions = new DefaultActionGroup();
final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false);
@@ -134,9 +141,6 @@ public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsole
panel.updateUI();
showConsole(defaultExecutor, contentDescriptor);
-
- // Run
- myProcessHandler.startNotify();
}
protected String constructConsoleTitle(final @NotNull String consoleTitle) {
diff --git a/platform/lang-impl/src/com/intellij/execution/runners/DefaultProgramRunner.java b/platform/lang-impl/src/com/intellij/execution/runners/DefaultProgramRunner.java
index 5f7321aa8068..f4cae36d1ffe 100644
--- a/platform/lang-impl/src/com/intellij/execution/runners/DefaultProgramRunner.java
+++ b/platform/lang-impl/src/com/intellij/execution/runners/DefaultProgramRunner.java
@@ -21,25 +21,19 @@ import com.intellij.execution.ExecutionResult;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
/**
* @author spleaner
*/
public abstract class DefaultProgramRunner extends GenericProgramRunner {
-
@Override
- protected RunContentDescriptor doExecute(@NotNull final Project project,
- @NotNull final RunProfileState state,
- final RunContentDescriptor contentToReuse,
- @NotNull final ExecutionEnvironment env) throws ExecutionException {
+ protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment env) throws ExecutionException {
FileDocumentManager.getInstance().saveAllDocuments();
ExecutionResult executionResult = state.execute(env.getExecutor(), this);
if (executionResult == null) {
return null;
}
- return new RunContentBuilder(executionResult, env).showRunContent(contentToReuse);
+ return new RunContentBuilder(executionResult, env).showRunContent(env.getContentToReuse());
}
-
}
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 b8225b0c238b..5384ea06de23 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
@@ -290,7 +290,8 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
final ContentManager manager = ContentFactory.SERVICE.getInstance().createContentManager(this, false, myProject);
Disposer.register((Disposable)myRunnerUi, manager);
manager.getComponent();
- } else {
+ }
+ else {
final DockManager dockManager = DockManager.getInstance(myProject);
if (dockManager != null) { //default project
dockManager.register(this);
@@ -518,13 +519,15 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
@Override
public void closeAll() {
final Content[] contents = myManager.getContents();
- for (Content content : contents) {
- getStateFor(content).setWindow(0);
- }
if (myOriginal != null) {
for (Content content : contents) {
+ getStateFor(content).setWindow(0);
myOriginal.myManager.addContent(content);
- myOriginal.findCellFor(content).minimize(content);
+ GridCell cell = myOriginal.findCellFor(content);
+ if (cell != null) {
+ myOriginal.restoreContent(content.getUserData(ViewImpl.ID));
+ cell.minimize(content);
+ }
}
}
myManager.removeAllContents(false);
@@ -1373,7 +1376,6 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
}
private class MyComponent extends Wrapper.FocusHolder implements DataProvider, QuickActionProvider {
-
private boolean myWasEverAdded;
public MyComponent() {
@@ -1388,9 +1390,13 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
if (KEY.is(dataId)) {
return RunnerContentUi.this;
}
- else {
- return null;
+
+ ContentManager originalContentManager = myOriginal == null ? null : myOriginal.getContentManager();
+ JComponent originalContentComponent = originalContentManager == null ? null : originalContentManager.getComponent();
+ if (originalContentComponent instanceof DataProvider) {
+ return ((DataProvider)originalContentComponent).getData(dataId);
}
+ return null;
}
@SuppressWarnings("NullableProblems")
@@ -1839,9 +1845,6 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
public void dragOutFinished(MouseEvent event, TabInfo source) {
final Component component = event.getComponent();
final IdeFrame window = UIUtil.getParentOfType(IdeFrame.class, component);
- if (window != null) {
-
- }
mySession.process(event);
mySession = null;
}
diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
index 84776f4bf7ff..98975c8529dc 100644
--- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
+++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java
@@ -45,6 +45,7 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.pom.Navigatable;
@@ -859,7 +860,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction {
}
data.addAll(visibleNodes);
if (data.isEmpty()) {
- String progressText = UsageViewManagerImpl.getProgressTitle(presentation);
+ String progressText = StringUtil.escapeXml(UsageViewManagerImpl.getProgressTitle(presentation));
data.add(createStringNode(progressText));
}
Collections.sort(data, USAGE_NODE_COMPARATOR);
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 b78ce2c7ead7..87d0b78acf39 100644
--- a/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
+++ b/platform/lang-impl/src/com/intellij/find/findInProject/FindInProjectManager.java
@@ -52,14 +52,14 @@ public class FindInProjectManager {
public void findInProject(@NotNull DataContext dataContext) {
final boolean isOpenInNewTabEnabled;
- final boolean[] toOpenInNewTab = new boolean[1];
+ final boolean toOpenInNewTab;
Content selectedContent = UsageViewManager.getInstance(myProject).getSelectedContent(true);
if (selectedContent != null && selectedContent.isPinned()) {
- toOpenInNewTab[0] = true;
+ toOpenInNewTab = true;
isOpenInNewTabEnabled = false;
}
else {
- toOpenInNewTab[0] = FindSettings.getInstance().isShowResultsInSeparateView();
+ toOpenInNewTab = FindSettings.getInstance().isShowResultsInSeparateView();
isOpenInNewTabEnabled = UsageViewManager.getInstance(myProject).getReusableContentsCount() > 0;
}
@@ -68,7 +68,7 @@ public class FindInProjectManager {
findModel.setReplaceState(false);
findModel.setOpenInNewTabVisible(true);
findModel.setOpenInNewTabEnabled(isOpenInNewTabEnabled);
- findModel.setOpenInNewTab(toOpenInNewTab[0]);
+ findModel.setOpenInNewTab(toOpenInNewTab);
FindInProjectUtil.setDirectoryName(findModel, dataContext);
String text = PlatformDataKeys.PREDEFINED_TEXT.getData(dataContext);
@@ -85,7 +85,7 @@ public class FindInProjectManager {
public void run() {
findModel.setOpenInNewTabVisible(false);
if (isOpenInNewTabEnabled) {
- FindSettings.getInstance().setShowResultsInSeparateView(toOpenInNewTab[0] = findModel.isOpenInNewTab());
+ FindSettings.getInstance().setShowResultsInSeparateView(findModel.isOpenInNewTab());
}
startFindInProject(findModel);
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 7e9e71d7a94d..7dfdbbce16d7 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectTask.java
@@ -421,7 +421,7 @@ class FindInProjectTask {
SearchScope customScope = myFindModel.getCustomScope();
GlobalSearchScope scope = myPsiDirectory != null
- ? GlobalSearchScopesCore.directoryScope(myPsiDirectory, true)
+ ? GlobalSearchScopesCore.directoryScope(myPsiDirectory, myFindModel.isWithSubdirectories())
: myModule != null
? myModule.getModuleContentScope()
: customScope instanceof GlobalSearchScope
diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java
index 4ba97e0151e5..995a67ecafa1 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/LivePreview.java
@@ -21,7 +21,10 @@ import com.intellij.find.FindModel;
import com.intellij.find.FindResult;
import com.intellij.ide.IdeTooltipManager;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.editor.*;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.event.*;
@@ -46,7 +49,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
-import java.io.*;
+import java.io.PrintStream;
import java.util.*;
import java.util.List;
@@ -95,11 +98,8 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
private RangeHighlighter myCursorHighlighter;
private final List<VisibleAreaListener> myVisibleAreaListenersToRemove = new ArrayList<VisibleAreaListener>();
- private static TextAttributes strikout(TextAttributes attributes) {
- TextAttributes textAttributes = attributes.clone();
- textAttributes.setEffectColor(Color.BLACK);
- textAttributes.setEffectType(EffectType.STRIKEOUT);
- return textAttributes;
+ private static TextAttributes strikout() {
+ return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.DEPRECATED_ATTRIBUTES).clone();
}
private Delegate myDelegate;
@@ -161,7 +161,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
ranges.add(new Pair<Integer, Character>(editor.getDocument().getTextLength()+1, '\n'));
ContainerUtil.sort(ranges, new Comparator<Pair<Integer, Character>>() {
@Override
- public int compare(Pair<Integer, Character> pair, Pair<Integer, Character> pair2) {
+ public int compare(@NotNull Pair<Integer, Character> pair, @NotNull Pair<Integer, Character> pair2) {
int res = pair.first - pair2.first;
if (res == 0) {
@@ -210,7 +210,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
}
myHighlighters.removeAll(unused);
Project project = mySearchResults.getProject();
- if (!project.isDisposed()) {
+ if (project != null && !project.isDisposed()) {
for (RangeHighlighter highlighter : unused) {
HighlightManager.getInstance(project).removeSegmentHighlighter(mySearchResults.getEditor(), highlighter);
}
@@ -240,7 +240,8 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
Editor editor = mySearchResults.getEditor();
if (cursor != null) {
Set<RangeHighlighter> dummy = new HashSet<RangeHighlighter>();
- highlightRange(cursor, new TextAttributes(null, null, Color.BLACK, EffectType.ROUNDED_BOX, 0), dummy);
+ Color color = editor.getColorsScheme().getColor(EditorColors.CARET_COLOR);
+ highlightRange(cursor, new TextAttributes(null, null, color, EffectType.ROUNDED_BOX, 0), dummy);
if (!dummy.isEmpty()) {
myCursorHighlighter = dummy.iterator().next();
}
@@ -322,7 +323,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
attributes.setEffectColor(attributes.getBackgroundColor());
}
if (mySearchResults.isExcluded(range)) {
- highlightRange(range, strikout(attributes), myHighlighters);
+ highlightRange(range, strikout(), myHighlighters);
} else {
highlightRange(range, attributes, myHighlighters);
}
@@ -389,18 +390,18 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
final FindModel findModel = mySearchResults.getFindModel();
if (findModel.isRegularExpressions() && findModel.isReplaceState()) {
- showBalloon(cursor, editor, replacementPreviewText);
+ showBalloon(editor, replacementPreviewText);
}
}
}
- private void showBalloon(FindResult cursor, Editor editor, String replacementPreviewText) {
+ private void showBalloon(Editor editor, String replacementPreviewText) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
myReplacementPreviewText = replacementPreviewText;
return;
}
- ReplacementView replacementView = new ReplacementView(replacementPreviewText, cursor);
+ ReplacementView replacementView = new ReplacementView(replacementPreviewText);
BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(replacementView);
balloonBuilder.setFadeoutTime(0);
@@ -546,7 +547,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
}
}
- private void requestBalloonHiding(final Balloon object) {
+ private static void requestBalloonHiding(final Balloon object) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
diff --git a/platform/lang-impl/src/com/intellij/find/impl/livePreview/ReplacementView.java b/platform/lang-impl/src/com/intellij/find/impl/livePreview/ReplacementView.java
index 4f87efd8c970..b9b01667a656 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/livePreview/ReplacementView.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/livePreview/ReplacementView.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,30 +15,28 @@
*/
package com.intellij.find.impl.livePreview;
-import com.intellij.find.FindResult;
+import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
public class ReplacementView extends JPanel {
-
private static final String MALFORMED_REPLACEMENT_STRING = "Malformed replacement string";
- private final String myReplacement;
@Override
- protected void paintComponent(Graphics graphics) {
-
+ protected void paintComponent(@NotNull Graphics graphics) {
}
- public ReplacementView(final String replacement, final FindResult occurrence) {
- myReplacement = replacement;
- String textToShow = myReplacement;
- if (myReplacement == null) {
+ public ReplacementView(@Nullable String replacement) {
+ String textToShow = replacement;
+ if (replacement == null) {
textToShow = MALFORMED_REPLACEMENT_STRING;
}
JLabel jLabel = new JLabel(textToShow);
- jLabel.setForeground(myReplacement != null ? Color.WHITE : JBColor.RED);
+ jLabel.setForeground(replacement != null ? new JBColor(Gray._240, Gray._200) : JBColor.RED);
add(jLabel);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java
index 7e220c149369..0c6a3766342d 100644
--- a/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java
+++ b/platform/lang-impl/src/com/intellij/find/replaceInProject/ReplaceInProjectManager.java
@@ -20,6 +20,7 @@ import com.intellij.find.*;
import com.intellij.find.actions.FindInPathAction;
import com.intellij.find.findInProject.FindInProjectManager;
import com.intellij.find.impl.FindInProjectUtil;
+import com.intellij.find.impl.FindManagerImpl;
import com.intellij.ide.DataManager;
import com.intellij.notification.NotificationGroup;
import com.intellij.openapi.actionSystem.ActionManager;
@@ -38,6 +39,7 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.Segment;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -48,9 +50,8 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.ui.content.Content;
-import com.intellij.usageView.*;
+import com.intellij.usageView.UsageInfo;
import com.intellij.usages.*;
-import com.intellij.usages.UsageViewManager;
import com.intellij.usages.impl.UsageViewImpl;
import com.intellij.usages.rules.UsageInFile;
import com.intellij.util.AdapterProcessor;
@@ -115,9 +116,23 @@ public class ReplaceInProjectManager {
}
public void replaceInProject(@NotNull DataContext dataContext) {
+ final boolean isOpenInNewTabEnabled;
+ final boolean toOpenInNewTab;
+ final Content selectedContent = com.intellij.usageView.UsageViewManager.getInstance(myProject).getSelectedContent(true);
+ if (selectedContent != null && selectedContent.isPinned()) {
+ toOpenInNewTab = true;
+ isOpenInNewTabEnabled = false;
+ }
+ else {
+ toOpenInNewTab = FindSettings.getInstance().isShowResultsInSeparateView();
+ isOpenInNewTabEnabled = com.intellij.usageView.UsageViewManager.getInstance(myProject).getReusableContentsCount() > 0;
+ }
final FindManager findManager = FindManager.getInstance(myProject);
- final FindModel findModel = (FindModel)findManager.getFindInProjectModel().clone();
+ final FindModel findModel = findManager.getFindInProjectModel().clone();
findModel.setReplaceState(true);
+ findModel.setOpenInNewTabVisible(true);
+ findModel.setOpenInNewTabEnabled(isOpenInNewTabEnabled);
+ findModel.setOpenInNewTab(toOpenInNewTab);
FindInProjectUtil.setDirectoryName(findModel, dataContext);
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
@@ -138,9 +153,9 @@ public class ReplaceInProjectManager {
if (manager == null) return;
findManager.getFindInProjectModel().copyFrom(findModel);
- final FindModel findModelCopy = (FindModel)findModel.clone();
+ final FindModel findModelCopy = findModel.clone();
- final UsageViewPresentation presentation = FindInProjectUtil.setupViewPresentation(true, findModelCopy);
+ final UsageViewPresentation presentation = FindInProjectUtil.setupViewPresentation(findModel.isOpenInNewTab(), findModelCopy);
final FindUsagesProcessPresentation processPresentation = FindInProjectUtil.setupProcessPresentation(myProject, true, presentation);
UsageSearcherFactory factory = new UsageSearcherFactory(findModelCopy, psiDirectory, processPresentation);
@@ -168,7 +183,7 @@ public class ReplaceInProjectManager {
@Override
public String getLongDescriptiveName() {
UsageViewPresentation presentation = FindInProjectUtil.setupViewPresentation(false, myFindModel);
- return "Replace "+presentation.getToolwindowTitle()+" with '"+ myFindModel.getStringToReplace()+"'";
+ return "Replace "+ StringUtil.decapitalize(presentation.getToolwindowTitle())+" with '"+ myFindModel.getStringToReplace()+"'";
}
@Override
@@ -193,7 +208,9 @@ public class ReplaceInProjectManager {
final FindManager findManager) {
presentation.setMergeDupLinesAvailable(false);
final ReplaceContext[] context = new ReplaceContext[1];
- manager.searchAndShowUsages(new UsageTarget[]{new ReplaceInProjectTarget(myProject, findModelCopy)},
+ final ReplaceInProjectTarget target = new ReplaceInProjectTarget(myProject, findModelCopy);
+ ((FindManagerImpl)FindManager.getInstance(myProject)).getFindUsagesManager().addToHistory(target);
+ manager.searchAndShowUsages(new UsageTarget[]{target},
usageSearcherFactory, processPresentation, presentation, new UsageViewManager.UsageViewStateListener() {
@Override
public void usageViewCreated(@NotNull UsageView usageView) {
diff --git a/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentStrategy.java b/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentStrategy.java
index 1844a0a217d2..0be9a469a03e 100644
--- a/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentStrategy.java
+++ b/platform/lang-impl/src/com/intellij/formatting/alignment/AlignmentStrategy.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.
@@ -69,8 +69,7 @@ public abstract class AlignmentStrategy {
* @return alignment strategy for the given arguments
*/
public static AlignmentPerTypeStrategy createAlignmentPerTypeStrategy(@NotNull Collection<IElementType> targetTypes,
- boolean allowBackwardShift)
- {
+ boolean allowBackwardShift) {
return new AlignmentPerTypeStrategy(targetTypes, null, allowBackwardShift, Alignment.Anchor.LEFT);
}
@@ -85,8 +84,7 @@ public abstract class AlignmentStrategy {
* @return alignment retrieval strategy that follows the rules described above
*/
public static AlignmentPerTypeStrategy createAlignmentPerTypeStrategy(
- @NotNull Collection<IElementType> targetTypes, @Nullable IElementType parentType, boolean allowBackwardShift)
- {
+ @NotNull Collection<IElementType> targetTypes, @Nullable IElementType parentType, boolean allowBackwardShift) {
return createAlignmentPerTypeStrategy(targetTypes, parentType, allowBackwardShift, Alignment.Anchor.LEFT);
}
@@ -115,8 +113,7 @@ public abstract class AlignmentStrategy {
*/
public static AlignmentPerTypeStrategy createAlignmentPerTypeStrategy(
@NotNull Collection<IElementType> targetTypes, @Nullable IElementType parentType, boolean allowBackwardShift,
- @NotNull Alignment.Anchor anchor)
- {
+ @NotNull Alignment.Anchor anchor) {
return new AlignmentPerTypeStrategy(targetTypes, parentType, allowBackwardShift, anchor);
}
@@ -162,7 +159,7 @@ public abstract class AlignmentStrategy {
@Override
@Nullable
public Alignment getAlignment(@Nullable IElementType parentType, @Nullable IElementType childType) {
- return (myFilterElementTypes.contains(childType) ^ myIgnoreFilterTypes) ? myAlignment : null;
+ return myFilterElementTypes.contains(childType) ^ myIgnoreFilterTypes ? myAlignment : null;
}
}
@@ -171,7 +168,6 @@ public abstract class AlignmentStrategy {
* same types.
*/
public static class AlignmentPerTypeStrategy extends AlignmentStrategy {
-
private final Map<IElementType, Alignment> myAlignments = new HashMap<IElementType, Alignment>();
private final IElementType myParentType;
@@ -180,8 +176,7 @@ public abstract class AlignmentStrategy {
AlignmentPerTypeStrategy(Collection<IElementType> targetElementTypes,
IElementType parentType,
boolean allowBackwardShift,
- Alignment.Anchor anchor)
- {
+ Alignment.Anchor anchor) {
myParentType = parentType;
myAllowBackwardShift = allowBackwardShift;
for (IElementType elementType : targetElementTypes) {
diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ExportableFileTemplateSettings.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ExportableFileTemplateSettings.java
index b601f0542dab..29cf1b18644a 100644
--- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ExportableFileTemplateSettings.java
+++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/ExportableFileTemplateSettings.java
@@ -40,7 +40,6 @@ import java.util.Locale;
)}
)
public class ExportableFileTemplateSettings extends FileTemplatesLoader implements PersistentStateComponent<Element>, ExportableComponent {
-
public final static String EXPORTABLE_SETTINGS_FILE = "file.template.settings.xml";
static final String ELEMENT_TEMPLATE = "template";
@@ -58,7 +57,6 @@ public class ExportableFileTemplateSettings extends FileTemplatesLoader implemen
return ServiceManager.getService(ExportableFileTemplateSettings.class);
}
-
@NotNull
@Override
public File[] getExportFiles() {
@@ -76,10 +74,9 @@ public class ExportableFileTemplateSettings extends FileTemplatesLoader implemen
@Nullable
@Override
public Element getState() {
- Element element = new Element("fileTemplateSettings");
+ Element element = null;
for (FTManager manager : getAllManagers()) {
- final Element templatesGroup = new Element(getXmlElementGroupName(manager));
- element.addContent(templatesGroup);
+ Element templatesGroup = null;
for (FileTemplateBase template : manager.getAllTemplates(true)) {
// save only those settings that differ from defaults
boolean shouldSave = template.isReformatCode() != FileTemplateBase.DEFAULT_REFORMAT_CODE_VALUE;
@@ -95,6 +92,14 @@ public class ExportableFileTemplateSettings extends FileTemplatesLoader implemen
if (template instanceof BundledFileTemplate) {
templateElement.setAttribute(ATTRIBUTE_ENABLED, Boolean.toString(((BundledFileTemplate)template).isEnabled()));
}
+
+ if (templatesGroup == null) {
+ templatesGroup = new Element(getXmlElementGroupName(manager));
+ if (element == null) {
+ element = new Element("fileTemplateSettings");
+ }
+ element.addContent(templatesGroup);
+ }
templatesGroup.addContent(templateElement);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java
index be3be30fc247..21702dc68f4f 100644
--- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.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.
@@ -21,7 +21,6 @@ import com.intellij.ide.DataManager;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
-import com.intellij.lexer.CompositeLexer;
import com.intellij.lexer.FlexAdapter;
import com.intellij.lexer.Lexer;
import com.intellij.lexer.MergingLexerAdapter;
@@ -38,7 +37,8 @@ import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.ex.EditorEx;
-import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter;
+import com.intellij.openapi.editor.ex.util.LayerDescriptor;
+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.fileTypes.*;
@@ -99,7 +99,7 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
private URL myDefaultDescriptionUrl;
private final Project myProject;
- private final List<ChangeListener> myChangeListeners = ContainerUtil.createLockFreeCopyOnWriteList();;
+ private final List<ChangeListener> myChangeListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private Splitter mySplitter;
private final FileType myVelocityFileType = FileTypeManager.getInstance().getFileTypeByExtension("ft");
private JPanel myDescriptionPanel;
@@ -205,13 +205,13 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
myNameField.addFocusListener(new FocusAdapter() {
@Override
- public void focusLost(FocusEvent e) {
+ public void focusLost(@NotNull FocusEvent e) {
onNameChanged();
}
});
myExtensionField.addFocusListener(new FocusAdapter() {
@Override
- public void focusLost(FocusEvent e) {
+ public void focusLost(@NotNull FocusEvent e) {
onNameChanged();
}
});
@@ -221,8 +221,11 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
private Editor createEditor() {
EditorFactory editorFactory = EditorFactory.getInstance();
- Document doc = myFile == null ? editorFactory.createDocument(myTemplate == null ? "" : myTemplate.getText()) : PsiDocumentManager.getInstance(myFile.getProject()).getDocument(myFile);
- Editor editor = myProject == null ? editorFactory.createEditor(doc) : editorFactory.createEditor(doc, myProject);
+ Document doc = myFile == null
+ ? editorFactory.createDocument(myTemplate == null ? "" : myTemplate.getText())
+ : PsiDocumentManager.getInstance(myFile.getProject()).getDocument(myFile);
+ assert doc != null;
+ Editor editor = editorFactory.createEditor(doc, myProject);
EditorSettings editorSettings = editor.getSettings();
editorSettings.setVirtualSpace(false);
@@ -367,7 +370,7 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
@Nullable
private PsiFile createFile(final String text, final String name) {
- if (myTemplate == null || myProject == null) return null;
+ if (myTemplate == null) return null;
final FileType fileType = myVelocityFileType;
if (fileType == FileTypes.UNKNOWN) return null;
@@ -388,7 +391,7 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
}
private EditorHighlighter createHighlighter() {
- if (myTemplate != null && myProject != null && myVelocityFileType != FileTypes.UNKNOWN) {
+ if (myTemplate != null && myVelocityFileType != FileTypes.UNKNOWN) {
return EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, new LightVirtualFile("aaa." + myTemplate.getExtension() + ".ft"));
}
@@ -399,38 +402,27 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
if (fileType == null) {
fileType = FileTypes.PLAIN_TEXT;
}
+
SyntaxHighlighter originalHighlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, null, null);
- if (originalHighlighter == null) originalHighlighter = new PlainSyntaxHighlighter();
- return new LexerEditorHighlighter(new TemplateHighlighter(originalHighlighter), EditorColorsManager.getInstance().getGlobalScheme());
+ if (originalHighlighter == null) {
+ originalHighlighter = new PlainSyntaxHighlighter();
+ }
+
+ final EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
+ LayeredLexerEditorHighlighter highlighter = new LayeredLexerEditorHighlighter(new TemplateHighlighter(), scheme);
+ highlighter.registerLayer(FileTemplateTokenType.TEXT, new LayerDescriptor(originalHighlighter, ""));
+ return highlighter;
}
- private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(FileTemplateTokenType.TEXT);
-
private static class TemplateHighlighter extends SyntaxHighlighterBase {
private final Lexer myLexer;
- private final SyntaxHighlighter myOriginalHighlighter;
-
- public TemplateHighlighter(SyntaxHighlighter original) {
- myOriginalHighlighter = original;
- Lexer originalLexer = original.getHighlightingLexer();
- Lexer templateLexer = new FlexAdapter(new FileTemplateTextLexer());
- templateLexer = new MergingLexerAdapter(templateLexer, TOKENS_TO_MERGE);
-
- myLexer = new CompositeLexer(originalLexer, templateLexer) {
- @Override
- protected IElementType getCompositeTokenType(IElementType type1, IElementType type2) {
- if (type2 == FileTemplateTokenType.MACRO || type2 == FileTemplateTokenType.DIRECTIVE) {
- return type2;
- }
- else {
- return type1;
- }
- }
- };
+
+ public TemplateHighlighter() {
+ myLexer = new MergingLexerAdapter(new FlexAdapter(new FileTemplateTextLexer()), TokenSet.create(FileTemplateTokenType.TEXT));
}
- @Override
@NotNull
+ @Override
public Lexer getHighlightingLexer() {
return myLexer;
}
@@ -438,14 +430,11 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
@Override
@NotNull
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
- if (tokenType == FileTemplateTokenType.MACRO) {
- return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
- }
- else if (tokenType == FileTemplateTokenType.DIRECTIVE) {
- return pack(myOriginalHighlighter.getTokenHighlights(tokenType), TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
+ if (tokenType == FileTemplateTokenType.MACRO || tokenType == FileTemplateTokenType.DIRECTIVE) {
+ return pack(TemplateColors.TEMPLATE_VARIABLE_ATTRIBUTES);
}
- return myOriginalHighlighter.getTokenHighlights(tokenType);
+ return EMPTY;
}
}
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModel.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModel.java
index a27ad87f70e4..9a80f455e4e1 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModel.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarModel.java
@@ -222,9 +222,8 @@ public class NavBarModel {
psiElement = getOriginalElement(psiElement);
PsiElement resultElement = psiElement;
- for (final NavBarModelExtension modelExtension : Extensions.getExtensions(NavBarModelExtension.EP_NAME)) {
- resultElement = modelExtension.adjustElement(resultElement);
- }
+ resultElement = normalize(resultElement);
+ if (resultElement == null) return;
boolean foundByExtension = false;
for (final NavBarModelExtension modelExtension : Extensions.getExtensions(NavBarModelExtension.EP_NAME)) {
@@ -326,7 +325,7 @@ public class NavBarModel {
}
@Nullable
- private static PsiElement normalize(PsiElement child) {
+ private static PsiElement normalize(@Nullable PsiElement child) {
if (child == null) return null;
for (NavBarModelExtension modelExtension : Extensions.getExtensions(NavBarModelExtension.EP_NAME)) {
child = modelExtension.adjustElement(child);
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java
index d565c69f9df4..6c0374a5d744 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarPopup.java
@@ -27,6 +27,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBList;
+import com.intellij.ui.popup.HintUpdateSupply;
import com.intellij.ui.speedSearch.ListWithFilter;
import com.intellij.util.Function;
import com.intellij.util.NotNullFunction;
@@ -92,10 +93,8 @@ public class NavBarPopup extends LightweightHint implements Disposable{
protected void onPopupCancel() {
final JComponent component = getComponent();
if (component != null) {
- final Object o = component.getClientProperty(JBLIST_KEY);
- if (o instanceof JBListWithHintProvider) {
- ((JBListWithHintProvider)o).hideHint();
- }
+ Object o = component.getClientProperty(JBLIST_KEY);
+ if (o instanceof JComponent) HintUpdateSupply.hideHint((JComponent)o);
}
//noinspection unchecked
for (Disposable disposable : ((List<Disposable>)getList().getClientProperty(DISPOSED_OBJECTS))) {
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java
new file mode 100644
index 000000000000..64e374097635
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/ProjectViewSettings.java
@@ -0,0 +1,23 @@
+/*
+ * 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.projectView;
+
+/**
+ * @author nik
+ */
+public interface ProjectViewSettings extends ViewSettings {
+ boolean isShowExcludedFiles();
+}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java
index 52e79d208147..bc2e509e085a 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewPane.java
@@ -23,15 +23,25 @@ import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.SelectInTarget;
import com.intellij.ide.impl.ProjectPaneSelectInTarget;
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.ide.projectView.ProjectViewSettings;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.ProjectViewDirectoryHelper;
import com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.AbstractTreeUpdater;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizerUtil;
+import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.PsiDirectory;
+import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -42,6 +52,8 @@ import java.awt.*;
public class ProjectViewPane extends AbstractProjectViewPSIPane {
@NonNls public static final String ID = "ProjectPane";
+ public static final String SHOW_EXCLUDED_FILES_OPTION = "show-excluded-files";
+ private boolean myShowExcludedFiles = true;
public ProjectViewPane(Project project) {
super(project);
@@ -76,12 +88,7 @@ public class ProjectViewPane extends AbstractProjectViewPSIPane {
@Override
protected ProjectAbstractTreeStructureBase createStructure() {
- return new ProjectTreeStructure(myProject, ID){
- @Override
- protected AbstractTreeNode createRoot(final Project project, ViewSettings settings) {
- return new ProjectViewProjectNode(project, settings);
- }
- };
+ return new ProjectViewPaneTreeStructure();
}
@Override
@@ -111,6 +118,25 @@ public class ProjectViewPane extends AbstractProjectViewPSIPane {
return "ProjectPane";
}
+ @Override
+ public void readExternal(Element element) throws InvalidDataException {
+ super.readExternal(element);
+ String showExcludedOption = JDOMExternalizerUtil.readField(element, SHOW_EXCLUDED_FILES_OPTION);
+ myShowExcludedFiles = showExcludedOption == null || Boolean.parseBoolean(showExcludedOption);
+ }
+
+ @Override
+ public void writeExternal(Element element) throws WriteExternalException {
+ super.writeExternal(element);
+ if (!myShowExcludedFiles) {
+ JDOMExternalizerUtil.writeField(element, SHOW_EXCLUDED_FILES_OPTION, String.valueOf(false));
+ }
+ }
+
+ @Override
+ public void addToolbarActions(DefaultActionGroup actionGroup) {
+ actionGroup.addAction(new ShowExcludedFilesAction()).setAsSecondary(true);
+ }
// should be first
@Override
@@ -148,4 +174,47 @@ public class ProjectViewPane extends AbstractProjectViewPSIPane {
return super.addSubtreeToUpdateByElement(element);
}
}
+
+ private class ProjectViewPaneTreeStructure extends ProjectTreeStructure implements ProjectViewSettings {
+ public ProjectViewPaneTreeStructure() {
+ super(ProjectViewPane.this.myProject, ID);
+ }
+
+ @Override
+ protected AbstractTreeNode createRoot(final Project project, ViewSettings settings) {
+ return new ProjectViewProjectNode(project, settings);
+ }
+
+ @Override
+ public boolean isShowExcludedFiles() {
+ return myShowExcludedFiles;
+ }
+ }
+
+ private final class ShowExcludedFilesAction extends ToggleAction {
+ private ShowExcludedFilesAction() {
+ super(IdeBundle.message("action.show.excluded.files"), IdeBundle.message("action.show.hide.excluded.files"), null);
+ }
+
+ @Override
+ public boolean isSelected(AnActionEvent event) {
+ return myShowExcludedFiles;
+ }
+
+ @Override
+ public void setSelected(AnActionEvent event, boolean flag) {
+ if (myShowExcludedFiles != flag) {
+ myShowExcludedFiles = flag;
+ updateFromRoot(true);
+ }
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ final Presentation presentation = e.getPresentation();
+ final ProjectView projectView = ProjectView.getInstance(myProject);
+ presentation.setVisible(projectView.getCurrentProjectViewPane() == ProjectViewPane.this);
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java
index 13ba91900521..36c09aff2218 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java
@@ -21,6 +21,7 @@
package com.intellij.ide.projectView.impl.nodes;
import com.intellij.ide.projectView.ProjectViewNode;
+import com.intellij.ide.projectView.ProjectViewSettings;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.components.ServiceManager;
@@ -37,10 +38,8 @@ import com.intellij.openapi.roots.impl.DirectoryInfo;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiManager;
+import com.intellij.psi.*;
+import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.util.PsiUtilCore;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
@@ -126,7 +125,7 @@ public class ProjectViewDirectoryHelper {
final Module module = fileIndex.getModuleForFile(psiDirectory.getVirtualFile());
final ModuleFileIndex moduleFileIndex = module == null ? null : ModuleRootManager.getInstance(module).getFileIndex();
if (!settings.isFlattenPackages() || skipDirectory(psiDirectory)) {
- processPsiDirectoryChildren(psiDirectory, directoryChildrenInProject(fileIndex, psiDirectory),
+ processPsiDirectoryChildren(psiDirectory, directoryChildrenInProject(psiDirectory, settings),
children, fileIndex, null, settings, withSubDirectories);
}
else { // source directory in "flatten packages" mode
@@ -172,10 +171,20 @@ public class ProjectViewDirectoryHelper {
return topLevelContentRoots;
}
- private PsiElement[] directoryChildrenInProject(ProjectFileIndex fileIndex, PsiDirectory psiDirectory) {
- VirtualFile dir = psiDirectory.getVirtualFile();
- if (isInProject(dir)) {
- return psiDirectory.getChildren();
+ private PsiElement[] directoryChildrenInProject(PsiDirectory psiDirectory, final ViewSettings settings) {
+ final VirtualFile dir = psiDirectory.getVirtualFile();
+ if (shouldBeShown(dir, settings)) {
+ final List<PsiElement> children = new ArrayList<PsiElement>();
+ psiDirectory.processChildren(new PsiElementProcessor<PsiFileSystemItem>() {
+ @Override
+ public boolean execute(@NotNull PsiFileSystemItem element) {
+ if (shouldBeShown(element.getVirtualFile(), settings)) {
+ children.add(element);
+ }
+ return true;
+ }
+ });
+ return PsiUtilCore.toPsiElementArray(children);
}
PsiManager manager = psiDirectory.getManager();
@@ -198,11 +207,11 @@ public class ProjectViewDirectoryHelper {
return PsiUtilCore.toPsiElementArray(directoriesOnTheWayToContentRoots);
}
- private boolean isInProject(VirtualFile dir) {
+ private boolean shouldBeShown(VirtualFile dir, ViewSettings settings) {
DirectoryInfo directoryInfo = myIndex.getInfoForFile(dir);
if (directoryInfo.isInProject()) return true;
- if (!Registry.is("ide.hide.excluded.files")) {
+ if (!Registry.is("ide.hide.excluded.files") && settings instanceof ProjectViewSettings && ((ProjectViewSettings)settings).isShowExcludedFiles()) {
return directoryInfo.isExcluded();
}
return false;
@@ -230,7 +239,7 @@ public class ProjectViewDirectoryHelper {
vFile = dir.getVirtualFile();
if (!vFile.equals(projectFileIndex.getSourceRootForFile(vFile))) { // if is not a source root
if (viewSettings.isHideEmptyMiddlePackages() && !skipDirectory(psiDir) && isEmptyMiddleDirectory(dir, true)) {
- processPsiDirectoryChildren(dir, directoryChildrenInProject(projectFileIndex, dir),
+ processPsiDirectoryChildren(dir, directoryChildrenInProject(dir, viewSettings),
container, projectFileIndex, moduleFileIndex, viewSettings, withSubDirectories); // expand it recursively
continue;
}
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java
index 97b3f8720f60..057082105eeb 100644
--- a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java
+++ b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosPanel.java
@@ -22,6 +22,7 @@ package com.intellij.ide.todo;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.scopeChooser.IgnoringComboBox;
+import com.intellij.ide.util.scopeChooser.ScopeChooserCombo;
import com.intellij.openapi.project.Project;
import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.search.scope.NonProjectFilesScope;
@@ -44,47 +45,18 @@ import java.util.List;
public class ScopeBasedTodosPanel extends TodoPanel {
private static final String SELECTED_SCOPE = "TODO_SCOPE";
private final Alarm myAlarm;
- private JComboBox myScopes;
- private final NamedScopesHolder.ScopeListener myScopeListener;
- private final NamedScopeManager myNamedScopeManager;
- private final DependencyValidationManager myValidationManager;
+ private ScopeChooserCombo myScopes;
public ScopeBasedTodosPanel(final Project project, TodoPanelSettings settings, Content content){
super(project,settings,false,content);
myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, project);
- final String scopeName = PropertiesComponent.getInstance(project).getValue(SELECTED_SCOPE);
- rebuildModel(project, scopeName);
-
- myScopeListener = new NamedScopesHolder.ScopeListener() {
- @Override
- public void scopesChanged() {
- final ScopeWrapper scope = (ScopeWrapper)myScopes.getSelectedItem();
- rebuildModel(project, scope != null ? scope.getName() : null);
- }
- };
-
- myNamedScopeManager = NamedScopeManager.getInstance(project);
- myNamedScopeManager.addScopeListener(myScopeListener);
-
- myValidationManager = DependencyValidationManager.getInstance(project);
- myValidationManager.addScopeListener(myScopeListener);
-
- myScopes.setRenderer(new ListCellRendererWrapper<ScopeWrapper>(){
- @Override
- public void customize(JList list, ScopeWrapper value, int index, boolean selected, boolean hasFocus) {
- setText(value.getName());
- if (value.isSeparator()) {
- setSeparator();
- }
- }
- });
- myScopes.addActionListener(new ActionListener() {
+ myScopes.getChildComponent().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
rebuildWithAlarm(ScopeBasedTodosPanel.this.myAlarm);
- final ScopeWrapper selectedItem = (ScopeWrapper)myScopes.getSelectedItem();
- if (selectedItem != null) {
- PropertiesComponent.getInstance(myProject).setValue(SELECTED_SCOPE, selectedItem.getName());
+ final String selectedItemName = myScopes.getSelectedScopeName();
+ if (selectedItemName != null) {
+ PropertiesComponent.getInstance(myProject).setValue(SELECTED_SCOPE, selectedItemName);
}
}
});
@@ -92,67 +64,14 @@ public class ScopeBasedTodosPanel extends TodoPanel {
}
@Override
- public void dispose() {
- myNamedScopeManager.removeScopeListener(myScopeListener);
- myValidationManager.removeScopeListener(myScopeListener);
- super.dispose();
- }
-
- private void rebuildModel(Project project, String scopeName) {
- final ArrayList<ScopeWrapper> scopes = new ArrayList<ScopeWrapper>();
- final DependencyValidationManager manager = DependencyValidationManager.getInstance(project);
-
- scopes.add(new ScopeWrapper("Predefined Scopes"));
- List<NamedScope> predefinedScopesList = manager.getPredefinedScopes();
- NamedScope[] predefinedScopes = predefinedScopesList.toArray(new NamedScope[predefinedScopesList.size()]);
- predefinedScopes = NonProjectFilesScope.removeFromList(predefinedScopes);
- for (NamedScope predefinedScope : predefinedScopes) {
- scopes.add(new ScopeWrapper(predefinedScope));
- }
-
- collectEditableScopes(scopes, manager, "Custom Project Scopes");
- collectEditableScopes(scopes, NamedScopeManager.getInstance(project), "Custom Local Scopes");
-
- myScopes.setModel(new DefaultComboBoxModel(scopes.toArray(new ScopeWrapper[scopes.size()])));
- setSelection(scopeName, scopes);
- }
-
- private void setSelection(@Nullable String scopeName, ArrayList<ScopeWrapper> scopes) {
- boolean hasNonSeparators = false;
- for (ScopeWrapper scope : scopes) {
- if (!scope.isSeparator()) {
- hasNonSeparators = true;
- if (scopeName == null || scopeName.equals(scope.getName())) {
- myScopes.setSelectedItem(scope);
- return;
- }
- }
- }
- assert hasNonSeparators;
- setSelection(null, scopes);
- }
-
- private static void collectEditableScopes(ArrayList<ScopeWrapper> scopes, NamedScopesHolder manager, String separatorTitle) {
- NamedScope[] editableScopes = manager.getEditableScopes();
- if (editableScopes.length > 0) {
- scopes.add(new ScopeWrapper(separatorTitle));
- for (NamedScope scope : editableScopes) {
- scopes.add(new ScopeWrapper(scope));
- }
- }
- }
-
- @Override
protected JComponent createCenterComponent() {
JPanel panel = new JPanel(new BorderLayout());
final JComponent component = super.createCenterComponent();
panel.add(component, BorderLayout.CENTER);
- myScopes = new IgnoringComboBox() {
- @Override
- protected boolean isIgnored(Object item) {
- return item instanceof ScopeWrapper && ((ScopeWrapper)item).isSeparator();
- }
- };
+ String preselect = PropertiesComponent.getInstance(myProject).getValue(SELECTED_SCOPE);
+ myScopes = new ScopeChooserCombo(myProject, false, true, preselect);
+ myScopes.setCurrentSelection(false);
+ myScopes.setUsageView(false);
JPanel chooserPanel = new JPanel(new GridBagLayout());
final JLabel scopesLabel = new JLabel("Scope:");
@@ -177,32 +96,4 @@ public class ScopeBasedTodosPanel extends TodoPanel {
builder.init();
return builder;
}
-
- public static class ScopeWrapper {
- private final String myName;
- private final boolean mySeparator;
- private NamedScope myNamedScope;
-
- private ScopeWrapper(NamedScope namedScope) {
- mySeparator = false;
- myNamedScope = namedScope;
- myName = myNamedScope.getName();
- }
- private ScopeWrapper(String name) {
- mySeparator = true;
- myName = name;
- }
-
- public String getName() {
- return myName;
- }
-
- public NamedScope getNamedScope() {
- return myNamedScope;
- }
-
- public boolean isSeparator() {
- return mySeparator;
- }
- }
} \ No newline at end of file
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeBuilder.java b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeBuilder.java
index 2d7163a0d5b1..0dc79f911852 100644
--- a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeBuilder.java
+++ b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeBuilder.java
@@ -19,6 +19,7 @@
*/
package com.intellij.ide.todo;
+import com.intellij.ide.util.scopeChooser.ScopeChooserCombo;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
@@ -26,9 +27,9 @@ import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
public class ScopeBasedTodosTreeBuilder extends TodoTreeBuilder{
- private final JComboBox myScopes;
+ private final ScopeChooserCombo myScopes;
- public ScopeBasedTodosTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project, JComboBox scopes){
+ public ScopeBasedTodosTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project, ScopeChooserCombo scopes){
super(tree,treeModel,project);
myScopes = scopes;
}
diff --git a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeStructure.java b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeStructure.java
index 322cc44bc99c..500e17b56534 100644
--- a/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeStructure.java
+++ b/platform/lang-impl/src/com/intellij/ide/todo/ScopeBasedTodosTreeStructure.java
@@ -24,22 +24,14 @@ import com.intellij.ide.todo.nodes.ToDoRootNode;
import com.intellij.ide.util.scopeChooser.ScopeChooserCombo;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vcs.changes.Change;
-import com.intellij.openapi.vcs.changes.ChangeListManager;
-import com.intellij.openapi.vfs.VfsUtil;
-import com.intellij.packageDependencies.DependencyValidationManager;
import com.intellij.psi.PsiFile;
-import com.intellij.psi.search.scope.packageSet.NamedScope;
-import com.intellij.psi.search.scope.packageSet.NamedScopesHolder;
-import com.intellij.psi.search.scope.packageSet.PackageSet;
-
-import javax.swing.*;
-import java.util.Collection;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
public class ScopeBasedTodosTreeStructure extends TodoTreeStructure {
- private final JComboBox myScopes;
+ private final ScopeChooserCombo myScopes;
- public ScopeBasedTodosTreeStructure(Project project, JComboBox scopes) {
+ public ScopeBasedTodosTreeStructure(Project project, ScopeChooserCombo scopes) {
super(project);
myScopes = scopes;
}
@@ -48,12 +40,9 @@ public class ScopeBasedTodosTreeStructure extends TodoTreeStructure {
public boolean accept(final PsiFile psiFile) {
if (!psiFile.isValid()) return false;
boolean isAffected = false;
- final ScopeBasedTodosPanel.ScopeWrapper scope = (ScopeBasedTodosPanel.ScopeWrapper)myScopes.getSelectedItem();
- if (scope != null) {
- final PackageSet value = scope.getNamedScope().getValue();
- if (value != null) {
- isAffected = value.contains(psiFile, NamedScopesHolder.getHolder(myProject, scope.getName(), DependencyValidationManager.getInstance(myProject)));
- }
+ SearchScope scope = myScopes.getSelectedScope();
+ if (scope instanceof GlobalSearchScope) {
+ isAffected = ((GlobalSearchScope)scope).contains(psiFile.getVirtualFile());
}
return isAffected && (myTodoFilter != null && myTodoFilter.accept(mySearchHelper, psiFile) ||
(myTodoFilter == null && mySearchHelper.getTodoItemsCount(psiFile) > 0));
diff --git a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
index eb22b72eb810..37248fe8a909 100644
--- a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
+++ b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.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,7 +26,7 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.impl.ActionManagerImpl;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ApplicationStarter;
+import com.intellij.openapi.application.ApplicationStarterEx;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.keymap.impl.ui.KeymapPanel;
import com.intellij.openapi.options.SearchableConfigurable;
@@ -50,8 +50,7 @@ import java.util.TreeSet;
* Pass corresponding -Didea.platform.prefix=YOUR_IDE_PREFIX to vm options and choose main_YOUR_IDE module
*/
@SuppressWarnings({"CallToPrintStackTrace", "SynchronizeOnThis"})
-public class TraverseUIStarter implements ApplicationStarter {
- private String OUTPUT_PATH;
+public class TraverseUIStarter extends ApplicationStarterEx {
@NonNls private static final String OPTIONS = "options";
@NonNls private static final String CONFIGURABLE = "configurable";
@NonNls private static final String ID = "id";
@@ -61,13 +60,19 @@ public class TraverseUIStarter implements ApplicationStarter {
@NonNls private static final String PATH = "path";
@NonNls private static final String HIT = "hit";
+ private String OUTPUT_PATH;
+
+ @Override
+ public boolean isHeadless() {
+ return true;
+ }
+
@Override
@NonNls
public String getCommandName() {
return "traverseUI";
}
-
@Override
public void premain(String[] args) {
OUTPUT_PATH = args[1];
diff --git a/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java b/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java
index f51ec554485a..d0a0648285d6 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java
@@ -102,7 +102,7 @@ public abstract class PsiElementListCellRenderer<T extends PsiElement> extends J
setPaintFocusBorder(hasFocus && UIUtil.isToUseDottedCellBorder() && myFocusBorderEnabled);
if (value instanceof PsiElement) {
T element = (T)value;
- String name = getElementText(element);
+ String name = element.isValid() ? getElementText(element) : "INVALID";
PsiFile psiFile = element.isValid() ? element.getContainingFile() : null;
boolean isProblemFile = 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 3e90f2310884..53d71d9794fa 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
@@ -54,6 +54,8 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.psi.PsiElement;
@@ -518,23 +520,33 @@ public abstract class ChooseByNameBase {
else {
Component oppositeComponent = e.getOppositeComponent();
if (oppositeComponent == myCheckBox) {
- myTextField.requestFocus();
+ IdeFocusManager.getInstance(myProject).requestFocus(myTextField, true);
return;
}
if (oppositeComponent != null && !(oppositeComponent instanceof JFrame) &&
myList.isShowing() &&
(oppositeComponent == myList || SwingUtilities.isDescendingFrom(myList, oppositeComponent))) {
- myTextField.requestFocus();// Otherwise me may skip some KeyEvents
+ IdeFocusManager.getInstance(myProject).requestFocus(myTextField, true);// Otherwise me may skip some KeyEvents
return;
}
+ if (oppositeComponent != null) {
+ ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(myProject);
+ ToolWindow toolWindow = toolWindowManager.getToolWindow(toolWindowManager.getActiveToolWindowId());
+ if (toolWindow != null) {
+ JComponent toolWindowComponent = toolWindow.getComponent();
+ if (SwingUtilities.isDescendingFrom(oppositeComponent, toolWindowComponent)) {
+ return; // Allow toolwindows to gain focus (used by QuickDoc shown in a toolwindow)
+ }
+ }
+ }
+
EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
if (queue instanceof IdeEventQueue) {
if (!((IdeEventQueue)queue).wasRootRecentlyClicked(oppositeComponent)) {
Component root = SwingUtilities.getRoot(myTextField);
if (root != null && root.isShowing()) {
- root.requestFocus();
- myTextField.requestFocus();
+ IdeFocusManager.getInstance(myProject).requestFocus(myTextField, true);
return;
}
}
@@ -641,7 +653,7 @@ public abstract class ChooseByNameBase {
@Override
public boolean onClick(@NotNull MouseEvent e, int clickCount) {
if (!myTextField.hasFocus()) {
- myTextField.requestFocus();
+ IdeFocusManager.getInstance(myProject).requestFocus(myTextField, true);
}
if (clickCount == 2) {
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
index c40831d276de..c26bd353de50 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java
@@ -62,6 +62,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModelE
protected ContributorsBasedGotoByModel(@NotNull Project project, @NotNull ChooseByNameContributor[] contributors) {
myProject = project;
myContributors = contributors;
+ assert !Arrays.asList(contributors).contains(null);
}
@Override
@@ -95,7 +96,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModelE
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
Processor<ChooseByNameContributor> processor = new ReadActionProcessor<ChooseByNameContributor>() {
@Override
- public boolean processInReadAction(ChooseByNameContributor contributor) {
+ public boolean processInReadAction(@NotNull ChooseByNameContributor contributor) {
try {
if (!myProject.isDisposed()) {
long contributorStarted = System.currentTimeMillis();
@@ -185,13 +186,15 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModelE
}
@NotNull
- public Object[] getElementsByName(final String name, final FindSymbolParameters parameters, @NotNull final ProgressIndicator canceled) {
+ public Object[] getElementsByName(@NotNull final String name,
+ @NotNull final FindSymbolParameters parameters,
+ @NotNull final ProgressIndicator canceled) {
long elementByNameStarted = System.currentTimeMillis();
final List<NavigationItem> items = Collections.synchronizedList(new ArrayList<NavigationItem>());
Processor<ChooseByNameContributor> processor = new Processor<ChooseByNameContributor>() {
@Override
- public boolean process(ChooseByNameContributor contributor) {
+ public boolean process(@NotNull ChooseByNameContributor contributor) {
if (myProject.isDisposed()) {
return true;
}
diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
index aef7c9a17e74..8297a3db8e1f 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java
@@ -71,6 +71,8 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
private NamedScopesHolder.ScopeListener myScopeListener;
private NamedScopeManager myNamedScopeManager;
private DependencyValidationManager myValidationManager;
+ private boolean myCurrentSelection = true;
+ private boolean myUsageView = true;
public ScopeChooserCombo() {
super(new IgnoringComboBox(){
@@ -118,6 +120,14 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
selectScope(preselect);
}
+ public void setCurrentSelection(boolean currentSelection) {
+ myCurrentSelection = currentSelection;
+ }
+
+ public void setUsageView(boolean usageView) {
+ myUsageView = usageView;
+ }
+
@Override
public void dispose() {
super.dispose();
@@ -220,7 +230,7 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
private void createPredefinedScopeDescriptors(DefaultComboBoxModel model) {
@SuppressWarnings("deprecation") final DataContext context = DataManager.getInstance().getDataContext();
- for (SearchScope scope : getPredefinedScopes(myProject, context, mySuggestSearchInLibs, myPrevSearchFiles, true, true)) {
+ for (SearchScope scope : getPredefinedScopes(myProject, context, mySuggestSearchInLibs, myPrevSearchFiles, myCurrentSelection, myUsageView)) {
model.addElement(new ScopeDescriptor(scope));
}
for (ScopeDescriptorProvider provider : Extensions.getExtensions(ScopeDescriptorProvider.EP_NAME)) {
diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeDescriptorProvider.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeDescriptorProvider.java
index fb879abd2595..44baafa0b86e 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeDescriptorProvider.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeDescriptorProvider.java
@@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
public interface ScopeDescriptorProvider {
+ ScopeDescriptor[] EMPTY = new ScopeDescriptor[0];
ExtensionPointName<ScopeDescriptorProvider> EP_NAME = ExtensionPointName.create("com.intellij.scopeDescriptorProvider");
@NotNull
diff --git a/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
index d0288d71a9a2..da44ae6c123c 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/CaretModelWindow.java
@@ -212,13 +212,24 @@ public class CaretModelWindow implements CaretModel {
@Override
public void setCaretsAndSelections(@NotNull List<CaretState> caretStates) {
+ List<CaretState> convertedStates = convertCaretStates(caretStates);
+ myDelegate.setCaretsAndSelections(convertedStates);
+ }
+
+ @Override
+ public void setCaretsAndSelections(@NotNull List<CaretState> caretStates, boolean updateSystemSelection) {
+ List<CaretState> convertedStates = convertCaretStates(caretStates);
+ myDelegate.setCaretsAndSelections(convertedStates, updateSystemSelection);
+ }
+
+ private List<CaretState> convertCaretStates(List<CaretState> caretStates) {
List<CaretState> convertedStates = new ArrayList<CaretState>(caretStates.size());
for (CaretState state : caretStates) {
convertedStates.add(new CaretState(injectedToHost(state.getCaretPosition()),
injectedToHost(state.getSelectionStart()),
injectedToHost(state.getSelectionEnd())));
}
- myDelegate.setCaretsAndSelections(convertedStates);
+ return convertedStates;
}
private LogicalPosition injectedToHost(@Nullable LogicalPosition position) {
diff --git a/platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java b/platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java
index e52fa66ccefc..ec958fdc557a 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/InjectedCaret.java
@@ -165,6 +165,12 @@ public class InjectedCaret implements Caret {
}
@Override
+ public void setSelection(int startOffset, int endOffset, boolean updateSystemSelection) {
+ TextRange hostRange = myEditorWindow.getDocument().injectedToHost(new ProperTextRange(startOffset, endOffset));
+ myDelegate.setSelection(hostRange.getStartOffset(), hostRange.getEndOffset(), updateSystemSelection);
+ }
+
+ @Override
public void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
TextRange hostRange = myEditorWindow.getDocument().injectedToHost(new ProperTextRange(startOffset, endOffset));
myDelegate.setSelection(hostRange.getStartOffset(), endPosition, hostRange.getEndOffset());
@@ -177,6 +183,12 @@ public class InjectedCaret implements Caret {
}
@Override
+ public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset, boolean updateSystemSelection) {
+ TextRange hostRange = myEditorWindow.getDocument().injectedToHost(new ProperTextRange(startOffset, endOffset));
+ myDelegate.setSelection(startPosition, hostRange.getStartOffset(), endPosition, hostRange.getEndOffset(), updateSystemSelection);
+ }
+
+ @Override
public void removeSelection() {
myDelegate.removeSelection();
}
diff --git a/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java b/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java
index c7c62288c158..53d4a3edd7ef 100644
--- a/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java
+++ b/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java
@@ -39,7 +39,6 @@ import com.intellij.ui.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
-import com.intellij.ui.popup.NotLookupOrSearchCondition;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.Function;
import com.intellij.util.NotNullFunction;
@@ -232,7 +231,6 @@ public class ImageDuplicateResultsDialog extends DialogWrapper {
final JBPopup popup =
JBPopupFactory.getInstance().createComponentPopupBuilder(viewComponent, viewComponent.getPreferredFocusableComponent())
- .setRequestFocusCondition(myProject, NotLookupOrSearchCondition.INSTANCE)
.setProject(myProject)
.setDimensionServiceKey(myProject, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false)
.setResizable(true)
diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
index dfaa6501831b..cd1ec63d1879 100644
--- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
+++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java
@@ -101,7 +101,7 @@ import java.util.regex.Pattern;
*/
public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disposable {
private static final String REFS_CACHE = "References Resolve Cache";
- private static final Color SELECTION_BG_COLOR = new JBColor(new Color(0x009999), new Color(0, 80, 80));
+ private static final Color BOX_COLOR = new JBColor(new Color(0xFC6C00), new Color(0xDE6C01));
private static final Logger LOG = Logger.getInstance("#com.intellij.internal.psiView.PsiViewerDialog");
private final Project myProject;
@@ -133,7 +133,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
@Nullable
private BlockTreeBuilder myBlockTreeBuilder;
private RangeHighlighter myHighlighter;
- private RangeHighlighter myIntersectHighlighter;
private HashMap<PsiElement, BlockTreeNode> myPsiToBlockMap;
private final Set<SourceWrapper> mySourceWrappers = ContainerUtil.newTreeSet();
@@ -163,7 +162,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
@Override
- public int compare(String o1, String o2) {
+ public int compare(@NotNull String o1, @NotNull String o2) {
if (o1.equals(myOnTop)) return -1;
if (o2.equals(myOnTop)) return 1;
return o1.compareToIgnoreCase(o2);
@@ -194,8 +193,8 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
@Override
- public int compareTo(final SourceWrapper o) {
- return o == null ? -1 : getText().compareToIgnoreCase(o.getText());
+ public int compareTo(@NotNull final SourceWrapper o) {
+ return getText().compareToIgnoreCase(o.getText());
}
}
@@ -242,7 +241,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
final TreeCellRenderer renderer = myPsiTree.getCellRenderer();
myPsiTree.setCellRenderer(new TreeCellRenderer() {
@Override
- public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ public Component getTreeCellRendererComponent(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
final Component c = renderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
if (value instanceof DefaultMutableTreeNode) {
final Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
@@ -251,7 +250,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
if (c instanceof NodeRenderer) {
((NodeRenderer)c).setToolTipText(element == null ? null : element.getClass().getName());
}
- if ((element instanceof PsiElement && FileContextUtil.getFileContext(((PsiElement)element).getContainingFile()) != null) ||
+ if (element instanceof PsiElement && FileContextUtil.getFileContext(((PsiElement)element).getContainingFile()) != null ||
element instanceof ViewerTreeStructure.Inject) {
final TextAttributes attr = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.INJECTED_LANGUAGE_FRAGMENT);
c.setBackground(attr.getBackgroundColor());
@@ -271,7 +270,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
myRefs.getSelectionModel().addListSelectionListener(listener);
myRefs.setCellRenderer(new DefaultListCellRenderer() {
@Override
- 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) {
final Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (resolve(index) == null) {
comp.setForeground(JBColor.RED);
@@ -289,7 +288,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
getPeer().getWindow().setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
@Override
- public Component getInitialComponent(Window window) {
+ public Component getInitialComponent(@NotNull Window window) {
return myEditor.getComponent();
}
});
@@ -324,7 +323,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
mySourceWrappers.add(wrapper);
if (lastUsed == null && wrapper.getText().equals(type)) lastUsed = wrapper;
if (myCurrentFile != null && wrapper.myFileType instanceof LanguageFileType &&
- ((LanguageFileType)wrapper.myFileType).equals(curLanguage.getAssociatedFileType())) {
+ wrapper.myFileType.equals(curLanguage.getAssociatedFileType())) {
lastUsed = wrapper;
}
}
@@ -347,7 +346,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
};
myFileTypeComboBox.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
updateDialectsCombo(null);
updateExtensionsCombo();
updateEditor();
@@ -355,7 +354,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
});
myDialectComboBox.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
updateEditor();
}
});
@@ -382,14 +381,14 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
final ViewerTreeStructure psiTreeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
myShowWhiteSpacesBox.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
psiTreeStructure.setShowWhiteSpaces(myShowWhiteSpacesBox.isSelected());
myPsiTreeBuilder.queueUpdate();
}
});
myShowTreeNodesCheckBox.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
psiTreeStructure.setShowTreeNodes(myShowTreeNodesCheckBox.isSelected());
myPsiTreeBuilder.queueUpdate();
}
@@ -402,7 +401,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
myBlockStructurePanel.setVisible(settings.showBlocks);
myShowBlocksCheckBox.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
if (!myShowBlocksCheckBox.isSelected()) {
settings.blockRefDividerLocation = myBlockRefSplitPane.getDividerLocation();
}
@@ -473,14 +472,14 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
registerKeyboardAction(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
focusEditor();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_T, mask));
registerKeyboardAction(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
focusTree();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));
@@ -488,21 +487,21 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
registerKeyboardAction(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
focusBlockTree();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_K, mask));
registerKeyboardAction(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
focusRefs();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_R, mask));
registerKeyboardAction(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
if (myRefs.isFocusOwner()) {
focusBlockTree();
}
@@ -548,26 +547,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
myBlockTreeSeparator.setLabelFor(myBlockTree);
}
- private void updateIntersectHighlighter(int highlightStart, int highlightEnd) {
- if (myIntersectHighlighter != null) {
- myEditor.getMarkupModel().removeHighlighter(myIntersectHighlighter);
- myIntersectHighlighter.dispose();
- }
- if (myEditor.getSelectionModel().hasSelection()) {
- int selectionStart = myEditor.getSelectionModel().getSelectionStart();
- int selectionEnd = myEditor.getSelectionModel().getSelectionEnd();
- TextRange resRange = new TextRange(highlightStart, highlightEnd).intersection(new TextRange(selectionStart, selectionEnd));
- if (resRange != null) {
- TextAttributes attributes = new TextAttributes();
- attributes.setBackgroundColor(Color.LIGHT_GRAY);
- attributes.setForegroundColor(Color.white);
- myIntersectHighlighter = myEditor.getMarkupModel()
- .addRangeHighlighter(resRange.getStartOffset(), resRange.getEndOffset(), HighlighterLayer.LAST + 1, attributes,
- HighlighterTargetArea.EXACT_RANGE);
- }
- }
- }
-
@Nullable
private PsiElement getPsiElement() {
final TreePath path = myPsiTree.getSelectionPath();
@@ -676,7 +655,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
protected Action[] createActions() {
AbstractAction copyPsi = new AbstractAction("Cop&y PSI") {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
PsiElement element = parseText(myEditor.getDocument().getText());
List<PsiElement> allToParse = new ArrayList<PsiElement>();
if (element instanceof PsiFile) {
@@ -735,7 +714,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
myPsiToBlockMap = new HashMap<PsiElement, BlockTreeNode>();
final PsiElement psiFile = ((ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure()).getRootPsiElement();
initMap(rootNode, psiFile);
- PsiElement rootPsi = (rootNode.getBlock() instanceof ASTBlock) ?
+ PsiElement rootPsi = rootNode.getBlock() instanceof ASTBlock ?
((ASTBlock)rootNode.getBlock()).getNode().getPsi() : rootElement;
BlockTreeNode blockNode = myPsiToBlockMap.get(rootPsi);
@@ -856,12 +835,12 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
public MyPsiTreeSelectionListener() {
myAttributes = new TextAttributes();
- myAttributes.setBackgroundColor(SELECTION_BG_COLOR);
- myAttributes.setForegroundColor(Color.white);
+ myAttributes.setEffectColor(BOX_COLOR);
+ myAttributes.setEffectType(EffectType.ROUNDED_BOX);
}
@Override
- public void valueChanged(TreeSelectionEvent e) {
+ public void valueChanged(@NotNull TreeSelectionEvent e) {
if (!myEditor.getDocument().getText().equals(myLastParsedText) || myBlockTree.hasFocus()) return;
TreePath path = myPsiTree.getSelectionPath();
clearSelection();
@@ -887,8 +866,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
final int textLength = myEditor.getDocument().getTextLength();
if (end <= textLength) {
myHighlighter = myEditor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.LAST, myAttributes, HighlighterTargetArea.EXACT_RANGE);
- updateIntersectHighlighter(start, end);
-
if (myPsiTree.hasFocus()) {
myEditor.getCaretModel().moveToOffset(start);
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
@@ -946,12 +923,12 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
public MyBlockTreeSelectionListener() {
myAttributes = new TextAttributes();
- myAttributes.setBackgroundColor(SELECTION_BG_COLOR);
- myAttributes.setForegroundColor(Color.white);
+ myAttributes.setEffectColor(BOX_COLOR);
+ myAttributes.setEffectType(EffectType.ROUNDED_BOX);
}
@Override
- public void valueChanged(TreeSelectionEvent e) {
+ public void valueChanged(@NotNull TreeSelectionEvent e) {
if (myIgnoreBlockTreeSelectionMarker > 0 || myBlockTreeBuilder == null) {
return;
}
@@ -988,7 +965,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
if (end <= textLength) {
myHighlighter = myEditor.getMarkupModel()
.addRangeHighlighter(start, end, HighlighterLayer.LAST, myAttributes, HighlighterTargetArea.EXACT_RANGE);
- updateIntersectHighlighter(start, end);
myEditor.getCaretModel().moveToOffset(start);
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
@@ -1112,7 +1088,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
private class GoToListener implements KeyListener, MouseListener, ListSelectionListener {
private RangeHighlighter myListenerHighlighter;
private final TextAttributes myAttributes =
- new TextAttributes(Color.white, SELECTION_BG_COLOR, JBColor.RED, EffectType.BOXED, Font.PLAIN);
+ new TextAttributes(JBColor.RED, null, null, null, Font.PLAIN);
private void navigate() {
final Object value = myRefs.getSelectedValue();
@@ -1124,21 +1100,21 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
@Override
- public void keyPressed(KeyEvent e) {
+ public void keyPressed(@NotNull KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
navigate();
}
}
@Override
- public void mouseClicked(MouseEvent e) {
+ public void mouseClicked(@NotNull MouseEvent e) {
if (e.getClickCount() > 1) {
navigate();
}
}
@Override
- public void valueChanged(ListSelectionEvent e) {
+ public void valueChanged(@NotNull ListSelectionEvent e) {
clearSelection();
updateDialectsCombo(null);
updateExtensionsCombo();
@@ -1176,17 +1152,17 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
@Override
- public void keyTyped(KeyEvent e) {}
+ public void keyTyped(@NotNull KeyEvent e) {}
@Override
public void keyReleased(KeyEvent e) {}
@Override
- public void mousePressed(MouseEvent e) {}
+ public void mousePressed(@NotNull MouseEvent e) {}
@Override
- public void mouseReleased(MouseEvent e) {}
+ public void mouseReleased(@NotNull MouseEvent e) {}
@Override
- public void mouseEntered(MouseEvent e) {}
+ public void mouseEntered(@NotNull MouseEvent e) {}
@Override
- public void mouseExited(MouseEvent e) {}
+ public void mouseExited(@NotNull MouseEvent e) {}
}
private void updateEditor() {
@@ -1247,7 +1223,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
if (myEditor.getContentComponent().hasFocus()) {
TextRange rangeInHostFile = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
selectBlockNode(findBlockNode(rangeInHostFile, true));
- updateIntersectHighlighter(myHighlighter.getStartOffset(), myHighlighter.getEndOffset());
}
}
myPsiTreeBuilder.select(element);
@@ -1270,13 +1245,6 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
return myLastParsedTextHashCode == myNewDocumentHashCode && myEditor.getContentComponent().hasFocus();
}
- @Nullable
- private PsiFile getPsiFile() {
- ViewerTreeStructure treeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
- final PsiElement root = treeStructure != null ? treeStructure.getRootPsiElement() : null;
- return root instanceof PsiFile ? (PsiFile)root : null;
- }
-
@Override
public void beforeDocumentChange(DocumentEvent event) {
@@ -1297,7 +1265,7 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp
}
@Override
- public void focusGained(final FocusEvent e) {
+ public void focusGained(@NotNull final FocusEvent e) {
final Component from = e.getOppositeComponent();
if (!e.isTemporary() && from != null && !myComboBox.isPopupVisible() && isUnder(from, myParent)) {
myComboBox.setPopupVisible(true);
diff --git a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java
index c62954177884..ea6d2fcc59fc 100644
--- a/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java
+++ b/platform/lang-impl/src/com/intellij/openapi/components/impl/stores/ModuleStateStorageManager.java
@@ -37,6 +37,7 @@ class ModuleStateStorageManager extends StateStorageManagerImpl {
return new ModuleStoreImpl.ModuleFileData(ROOT_TAG_NAME, myModule);
}
+ @Nullable
@Override
protected String getOldStorageSpec(Object component, final String componentName, final StateStorageOperation operation) {
return ModuleStoreImpl.DEFAULT_STATE_STORAGE;
diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java
index a96432e2b64c..962aa81c3e59 100644
--- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java
+++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java
@@ -37,8 +37,12 @@ import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.EmptyRunnable;
-import com.intellij.openapi.vfs.*;
-import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
+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.events.VFileCreateEvent;
+import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
+import com.intellij.openapi.vfs.newvfs.events.VFileMoveEvent;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.file.impl.FileManagerImpl;
@@ -48,8 +52,11 @@ import com.intellij.util.indexing.FileBasedIndexProjectHandler;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -86,33 +93,39 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
}
});
- myConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkVirtualFileListenerAdapter(new VirtualFileAdapter() {
+ myConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() {
@Override
- public void fileCreated(@NotNull final VirtualFileEvent event) {
- final VirtualFile file = event.getFile();
- final FilePropertyPusher[] pushers = file.isDirectory() ? myPushers : myFilePushers;
- if (!event.isFromRefresh() || !file.isDirectory()) {
- // push synchronously to avoid entering dumb mode in the middle of a meaningful write action
- // avoid dumb mode for just one file
- doPushRecursively(file, pushers, ProjectRootManager.getInstance(myProject).getFileIndex());
- }
- else {
- schedulePushRecursively(file, pushers);
- }
- }
+ public void after(@NotNull List<? extends VFileEvent> events) {
+ List<Runnable> delayedTasks = ContainerUtil.newArrayList();
+ for (VFileEvent event : events) {
+ final VirtualFile file = event.getFile();
+ if (file == null) continue;
- @Override
- public void fileMoved(@NotNull final VirtualFileMoveEvent event) {
- final VirtualFile file = event.getFile();
- final FilePropertyPusher[] pushers = file.isDirectory() ? myPushers : myFilePushers;
- if (pushers.length == 0) return;
- for (FilePropertyPusher pusher : pushers) {
- file.putUserData(pusher.getFileDataKey(), null);
+ final FilePropertyPusher[] pushers = file.isDirectory() ? myPushers : myFilePushers;
+ if (pushers.length == 0) continue;
+
+ if (event instanceof VFileCreateEvent) {
+ if (!event.isFromRefresh() || !file.isDirectory()) {
+ // push synchronously to avoid entering dumb mode in the middle of a meaningful write action
+ // avoid dumb mode for just one file
+ doPushRecursively(file, pushers, ProjectRootManager.getInstance(myProject).getFileIndex());
+ }
+ else {
+ ContainerUtil.addIfNotNull(delayedTasks, createRecursivePushTask(file, pushers));
+ }
+ } else if (event instanceof VFileMoveEvent) {
+ for (FilePropertyPusher pusher : pushers) {
+ file.putUserData(pusher.getFileDataKey(), null);
+ }
+ // push synchronously to avoid entering dumb mode in the middle of a meaningful write action
+ doPushRecursively(file, pushers, ProjectRootManager.getInstance(myProject).getFileIndex());
+ }
+ }
+ if (!delayedTasks.isEmpty()) {
+ queueTasks(delayedTasks);
}
- // push synchronously to avoid entering dumb mode in the middle of a meaningful write action
- doPushRecursively(file, pushers, ProjectRootManager.getInstance(myProject).getFileIndex());
}
- }));
+ });
}
});
}
@@ -128,7 +141,7 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
@Override
public void pushRecursively(VirtualFile file, Project project) {
- PushedFilePropertiesUpdaterImpl.this.schedulePushRecursively(file, pusher);
+ queueTasks(ContainerUtil.createMaybeSingletonList(createRecursivePushTask(file, new FilePropertyPusher[]{pusher})));
}
});
}
@@ -140,16 +153,17 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
doPushAll(myPushers);
}
- private void schedulePushRecursively(final VirtualFile dir, final FilePropertyPusher... pushers) {
- if (pushers.length == 0) return;
+ @Nullable
+ private Runnable createRecursivePushTask(final VirtualFile dir, final FilePropertyPusher[] pushers) {
+ if (pushers.length == 0) return null;
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
- if (!fileIndex.isInContent(dir)) return;
- queueTask(new Runnable() {
+ if (!fileIndex.isInContent(dir)) return null;
+ return new Runnable() {
@Override
public void run() {
doPushRecursively(dir, pushers, fileIndex);
}
- });
+ };
}
private void doPushRecursively(VirtualFile dir, final FilePropertyPusher[] pushers, ProjectFileIndex fileIndex) {
@@ -162,8 +176,10 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
});
}
- private void queueTask(Runnable action) {
- myTasks.offer(action);
+ private void queueTasks(List<? extends Runnable> actions) {
+ for (Runnable action : actions) {
+ myTasks.offer(action);
+ }
final DumbModeTask task = new DumbModeTask() {
@Override
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
@@ -221,12 +237,12 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
@Override
public void pushAll(final FilePropertyPusher... pushers) {
- queueTask(new Runnable() {
+ queueTasks(Arrays.asList(new Runnable() {
@Override
public void run() {
doPushAll(pushers);
}
- });
+ }));
}
private void doPushAll(final FilePropertyPusher[] pushers) {
diff --git a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java
index 0978f8f09ec7..65f2d758fcfd 100644
--- a/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java
+++ b/platform/lang-impl/src/com/intellij/openapi/util/registry/RegistryUi.java
@@ -17,6 +17,7 @@
package com.intellij.openapi.util.registry;
import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationInfo;
@@ -27,6 +28,7 @@ import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.ShadowAction;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.ui.table.JBTable;
import com.intellij.util.PlatformIcons;
@@ -54,6 +56,7 @@ import java.util.List;
* @author Konstantin Bulenkov
*/
public class RegistryUi implements Disposable {
+ private static final String RECENT_PROPERTIES_KEY = "RegistryRecentKeys";
private final JBTable myTable;
private final JTextArea myDescriptionLabel;
@@ -143,6 +146,7 @@ public class RegistryUi implements Disposable {
RegistryValue rv = myModel.getRegistryValue(row);
if (rv.isBoolean()) {
rv.setValue(!rv.asBoolean());
+ keyChanged(rv.getKey());
for (int i : new int[]{0, 1, 2}) myModel.fireTableCellUpdated(row, i);
revaliateActions();
if (search.isPopupActive()) search.hidePopup();
@@ -217,10 +221,21 @@ public class RegistryUi implements Disposable {
private MyTableModel() {
myAll = Registry.getAll();
+ final List<String> recent = getRecent();
+
Collections.sort(myAll, new Comparator<RegistryValue>() {
@Override
public int compare(@NotNull RegistryValue o1, @NotNull RegistryValue o2) {
- return o1.getKey().compareTo(o2.getKey());
+ final String key1 = o1.getKey();
+ final String key2 = o2.getKey();
+ final int i1 = recent.indexOf(key1);
+ final int i2 = recent.indexOf(key2);
+ final boolean c1 = i1 != -1;
+ final boolean c2 = i2 != -1;
+ if (c1 && !c2) return -1;
+ if (!c1 && c2) return 1;
+ if (c1 && c2) return i1 - i2;
+ return key1.compareToIgnoreCase(key2);
}
});
}
@@ -264,6 +279,19 @@ public class RegistryUi implements Disposable {
}
}
+ private static List<String> getRecent() {
+ String value = PropertiesComponent.getInstance().getValue(RECENT_PROPERTIES_KEY);
+ return StringUtil.isEmpty(value) ? new ArrayList<String>(0) : StringUtil.split(value, "=");
+ }
+
+ private static void keyChanged(String key) {
+ final List<String> recent = getRecent();
+ recent.remove(key);
+ recent.add(0, key);
+ final String newValue = StringUtil.join(recent, "=");
+ PropertiesComponent.getInstance().setValue(RECENT_PROPERTIES_KEY, newValue);
+ }
+
public boolean show() {
DialogWrapper dialog = new DialogWrapper(true) {
{
@@ -468,6 +496,7 @@ public class RegistryUi implements Disposable {
} else {
myValue.setValue(myField.getText().trim());
}
+ keyChanged(myValue.getKey());
}
revaliateActions();
return super.stopCellEditing();
diff --git a/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CheckinHandlerUtil.java b/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CheckinHandlerUtil.java
index 7a6b61f4722b..4a5a644d4fbe 100644
--- a/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CheckinHandlerUtil.java
+++ b/platform/lang-impl/src/com/intellij/openapi/vcs/checkin/CheckinHandlerUtil.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectEx;
+import com.intellij.openapi.roots.GeneratedSourcesFilter;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -34,11 +35,22 @@ import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
/**
* @author oleg
*/
public class CheckinHandlerUtil {
+ public static List<VirtualFile> filterOutGeneratedAndExcludedFiles(@NotNull Collection<VirtualFile> files, @NotNull Project project) {
+ ProjectFileIndex fileIndex = ProjectFileIndex.SERVICE.getInstance(project);
+ List<VirtualFile> result = new ArrayList<VirtualFile>(files.size());
+ for (VirtualFile file : files) {
+ if (!fileIndex.isExcluded(file) && !GeneratedSourcesFilter.isGeneratedSourceByAnyFilter(file, project)) {
+ result.add(file);
+ }
+ }
+ return result;
+ }
public static PsiFile[] getPsiFiles(final Project project, final Collection<VirtualFile> selectedFiles) {
ArrayList<PsiFile> result = new ArrayList<PsiFile>();
diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/actions/AnalyzeDependenciesOnSpecifiedTargetHandler.java b/platform/lang-impl/src/com/intellij/packageDependencies/actions/AnalyzeDependenciesOnSpecifiedTargetHandler.java
index ffc682269563..7aebba7dfe41 100644
--- a/platform/lang-impl/src/com/intellij/packageDependencies/actions/AnalyzeDependenciesOnSpecifiedTargetHandler.java
+++ b/platform/lang-impl/src/com/intellij/packageDependencies/actions/AnalyzeDependenciesOnSpecifiedTargetHandler.java
@@ -36,7 +36,7 @@ import java.util.*;
*/
public class AnalyzeDependenciesOnSpecifiedTargetHandler extends DependenciesHandlerBase {
private static final NotificationGroup NOTIFICATION_GROUP =
- NotificationGroup.toolWindowGroup("Dependencies", ToolWindowId.DEPENDENCIES, true);
+ NotificationGroup.toolWindowGroup("Dependencies", ToolWindowId.DEPENDENCIES);
private final GlobalSearchScope myTargetScope;
public AnalyzeDependenciesOnSpecifiedTargetHandler(@NotNull Project project, @NotNull AnalysisScope scope, @NotNull GlobalSearchScope targetScope) {
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeRenderer.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeRenderer.java
index 43b791cbe6a2..280f436b7bc5 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeRenderer.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeRenderer.java
@@ -27,35 +27,36 @@ import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.ide.ui.search.SearchUtil;
import com.intellij.profile.codeInspection.ui.ToolDescriptors;
-import com.intellij.ui.ColoredTreeCellRenderer;
+import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.PlatformColors;
import com.intellij.util.ui.UIUtil;
+import org.jdesktop.swingx.renderer.DefaultTreeRenderer;
import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
-public abstract class InspectionsConfigTreeRenderer extends ColoredTreeCellRenderer {
+public abstract class InspectionsConfigTreeRenderer extends DefaultTreeRenderer {
protected abstract String getFilter();
@Override
- public void customizeCellRenderer(@NotNull final JTree tree,
- final Object value,
- final boolean selected,
- final boolean expanded,
- final boolean leaf,
- final int row,
- final boolean hasFocus) {
- if (!(value instanceof InspectionConfigTreeNode)) return;
+ public Component getTreeCellRendererComponent(JTree tree,
+ Object value,
+ boolean selected,
+ boolean expanded,
+ boolean leaf,
+ int row,
+ boolean hasFocus) {
+ final SimpleColoredComponent component = new SimpleColoredComponent();
+ if (!(value instanceof InspectionConfigTreeNode)) return component;
InspectionConfigTreeNode node = (InspectionConfigTreeNode)value;
Object object = node.getUserObject();
final Color background = selected ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeTextBackground();
- UIUtil.changeBackGround(this, background);
+ UIUtil.changeBackGround(component, background);
Color foreground =
selected ? UIUtil.getTreeSelectionForeground() : node.isProperSetting() ? PlatformColors.BLUE : UIUtil.getTreeTextForeground();
@@ -75,12 +76,13 @@ public abstract class InspectionsConfigTreeRenderer extends ColoredTreeCellRende
}
if (text != null) {
- SearchUtil.appendFragments(getFilter(), text, style, foreground, background, this);
+ SearchUtil.appendFragments(getFilter(), text, style, foreground, background, component);
}
if (hint != null) {
- append(" " + hint, selected ? new SimpleTextAttributes(Font.PLAIN, foreground) : SimpleTextAttributes.GRAYED_ATTRIBUTES);
+ component.append(" " + hint, selected ? new SimpleTextAttributes(Font.PLAIN, foreground) : SimpleTextAttributes.GRAYED_ATTRIBUTES);
}
- setForeground(foreground);
+ component.setForeground(foreground);
+ return component;
}
@Nullable
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
index 32a2e38384d9..76377ef6b98e 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
@@ -554,22 +554,4 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
boolean isEnabled() {
return myEnabled;
}
-
- @TestOnly
- public void waitUntilAllCommitted(long timeout) throws InterruptedException {
- if (!myEnabled) {
- throw new IllegalStateException("DocumentCommitThread is disabled");
- }
- int attempts = 0;
- int delay = 100;
- synchronized (documentsToCommit) {
- while(!documentsToCommit.isEmpty() || currentTask != null) {
- documentsToCommit.wait(delay);
- if (delay * attempts > timeout) {
- throw new RuntimeException("timeout");
- }
- attempts++;
- }
- }
- }
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java
index 17dd2bca1f17..8b629875209b 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java
@@ -33,6 +33,7 @@ import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.io.FileUtilRt;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
import com.intellij.psi.*;
@@ -237,7 +238,7 @@ public class PsiVFSListener extends VirtualFileAdapter {
}
}
else {
- if (!isExcludeRoot(vFile) && !myFileTypeManager.isFileIgnored(newName)) {
+ if ((!Registry.is("ide.hide.excluded.files") || !isExcludeRoot(vFile)) && !myFileTypeManager.isFileIgnored(newName)) {
myManager.beforeChildAddition(treeEvent);
}
}
@@ -443,7 +444,8 @@ public class PsiVFSListener extends VirtualFileAdapter {
public void run() {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
- boolean isExcluded = vFile.isDirectory() && myProjectRootManager.getFileIndex().isExcluded(vFile);
+ boolean isExcluded = vFile.isDirectory() &&
+ Registry.is("ide.hide.excluded.files") && myProjectRootManager.getFileIndex().isExcluded(vFile);
if (oldParentDir != null && !isExcluded) {
if (newParentDir != null) {
treeEvent.setOldParent(oldParentDir);
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
index c5b183c3594b..f99d47201a20 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java
@@ -56,20 +56,22 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import java.util.*;
-import java.util.concurrent.atomic.AtomicInteger;
public class PostprocessReformattingAspect implements PomModelAspect {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PostprocessReformattingAspect");
private final Project myProject;
private final PsiManager myPsiManager;
private final TreeAspect myTreeAspect;
- private final Map<FileViewProvider, List<ASTNode>> myReformatElements = new HashMap<FileViewProvider, List<ASTNode>>();
- private volatile int myDisabledCounter = 0;
- private final Set<FileViewProvider> myUpdatedProviders = new HashSet<FileViewProvider>();
- private final AtomicInteger myPostponedCounter = new AtomicInteger();
private static final Key<Throwable> REFORMAT_ORIGINATOR = Key.create("REFORMAT_ORIGINATOR");
private static final boolean STORE_REFORMAT_ORIGINATOR_STACKTRACE = ApplicationManager.getApplication().isInternal();
+ private final ThreadLocal<Context> myContext = new ThreadLocal<Context>() {
+ @Override
+ protected Context initialValue() {
+ return new Context();
+ }
+ };
+
public PostprocessReformattingAspect(Project project, PsiManager psiManager, TreeAspect treeAspect,final CommandProcessor processor) {
myProject = project;
myPsiManager = psiManager;
@@ -113,12 +115,12 @@ public class PostprocessReformattingAspect implements PomModelAspect {
public <T> T disablePostprocessFormattingInside(@NotNull Computable<T> computable) {
try {
- myDisabledCounter++;
+ getContext().myDisabledCounter++;
return computable.compute();
}
finally {
- myDisabledCounter--;
- LOG.assertTrue(myDisabledCounter > 0 || !isDisabled());
+ getContext().myDisabledCounter--;
+ LOG.assertTrue(getContext().myDisabledCounter > 0 || !isDisabled());
}
}
@@ -145,13 +147,13 @@ public class PostprocessReformattingAspect implements PomModelAspect {
}
private void incrementPostponedCounter() {
- myPostponedCounter.incrementAndGet();
+ getContext().myPostponedCounter++;
}
private void decrementPostponedCounter() {
Application application = ApplicationManager.getApplication();
application.assertIsDispatchThread();
- if (myPostponedCounter.decrementAndGet() == 0) {
+ if (--getContext().myPostponedCounter == 0) {
if (application.isWriteAccessAllowed()) {
doPostponedFormatting();
}
@@ -175,7 +177,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
atomic(new Runnable() {
@Override
public void run() {
- if (isDisabled() || myPostponedCounter.get() == 0 && !ApplicationManager.getApplication().isUnitTestMode()) return;
+ if (isDisabled() || getContext().myPostponedCounter == 0 && !ApplicationManager.getApplication().isUnitTestMode()) return;
final TreeChangeEvent changeSet = (TreeChangeEvent)event.getChangeSet(myTreeAspect);
if (changeSet == null) return;
final PsiElement psiElement = changeSet.getRootElement().getPsi();
@@ -184,7 +186,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
final FileViewProvider viewProvider = containingFile.getViewProvider();
if (!viewProvider.isEventSystemEnabled()) return;
- myUpdatedProviders.add(viewProvider);
+ getContext().myUpdatedProviders.add(viewProvider);
for (final ASTNode node : changeSet.getChangedElements()) {
final TreeChange treeChange = changeSet.getChangesByElement(node);
for (final ASTNode affectedChild : treeChange.getAffectedChildren()) {
@@ -221,7 +223,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
public void run() {
if (isDisabled()) return;
try {
- FileViewProvider[] viewProviders = myUpdatedProviders.toArray(new FileViewProvider[myUpdatedProviders.size()]);
+ FileViewProvider[] viewProviders = getContext().myUpdatedProviders.toArray(new FileViewProvider[getContext().myUpdatedProviders.size()]);
for (final FileViewProvider viewProvider : viewProviders) {
doPostponedFormatting(viewProvider);
}
@@ -230,7 +232,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
LOG.error(e);
}
finally {
- LOG.assertTrue(myReformatElements.isEmpty(), myReformatElements);
+ LOG.assertTrue(getContext().myReformatElements.isEmpty(), getContext().myReformatElements);
}
}
});
@@ -248,7 +250,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
atomic(new Runnable() {
@Override
public void run() {
- if (isDisabled() || check && !myUpdatedProviders.contains(viewProvider)) return;
+ if (isDisabled() || check && !getContext().myUpdatedProviders.contains(viewProvider)) return;
try {
disablePostprocessFormattingInside(new Runnable() {
@@ -259,8 +261,8 @@ public class PostprocessReformattingAspect implements PomModelAspect {
});
}
finally {
- myUpdatedProviders.remove(viewProvider);
- myReformatElements.remove(viewProvider);
+ getContext().myUpdatedProviders.remove(viewProvider);
+ getContext().myReformatElements.remove(viewProvider);
viewProvider.putUserData(REFORMAT_ORIGINATOR, null);
}
}
@@ -268,7 +270,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
}
public boolean isViewProviderLocked(@NotNull FileViewProvider fileViewProvider) {
- return myReformatElements.containsKey(fileViewProvider);
+ return getContext().myReformatElements.containsKey(fileViewProvider);
}
public void beforeDocumentChanged(@NotNull FileViewProvider viewProvider) {
@@ -292,10 +294,10 @@ public class PostprocessReformattingAspect implements PomModelAspect {
LOG.assertTrue(oldIndent >= 0,
"for not generated items old indentation must be defined: element=" + child + ", text=" + child.getText());
}
- List<ASTNode> list = myReformatElements.get(viewProvider);
+ List<ASTNode> list = getContext().myReformatElements.get(viewProvider);
if (list == null) {
list = new ArrayList<ASTNode>();
- myReformatElements.put(viewProvider, list);
+ getContext().myReformatElements.put(viewProvider, list);
if (STORE_REFORMAT_ORIGINATOR_STACKTRACE) {
viewProvider.putUserData(REFORMAT_ORIGINATOR, new Throwable());
}
@@ -304,7 +306,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
}
private void doPostponedFormattingInner(@NotNull FileViewProvider key) {
- final List<ASTNode> astNodes = myReformatElements.remove(key);
+ final List<ASTNode> astNodes = getContext().myReformatElements.remove(key);
final Document document = key.getDocument();
// Sort ranges by end offsets so that we won't need any offset adjustment after reformat or reindent
if (document == null) return;
@@ -370,7 +372,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
String expectedPsi = treeDebugBuilder.psiToString(psi);
if (!expectedPsi.equals(actualPsiTree)) {
- myReformatElements.clear();
+ getContext().myReformatElements.clear();
assert expectedPsi.equals(actualPsiTree) : "Refactored psi should be the same as result of parsing";
}
}
@@ -627,7 +629,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
}
public boolean isDisabled() {
- return myDisabledCounter > 0;
+ return getContext().myDisabledCounter > 0;
}
@NotNull
@@ -769,6 +771,17 @@ public class PostprocessReformattingAspect implements PomModelAspect {
@TestOnly
public void clear() {
- myReformatElements.clear();
+ getContext().myReformatElements.clear();
+ }
+
+ private Context getContext() {
+ return myContext.get();
+ }
+
+ private static class Context {
+ private int myPostponedCounter = 0;
+ private int myDisabledCounter = 0;
+ private final Set<FileViewProvider> myUpdatedProviders = new HashSet<FileViewProvider>();
+ private final Map<FileViewProvider, List<ASTNode>> myReformatElements = new HashMap<FileViewProvider, List<ASTNode>>();
}
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
index d51ef1216a59..a9fbe1b4b988 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java
@@ -58,8 +58,7 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
public class CodeStyleManagerImpl extends CodeStyleManager {
-
- private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl");
+ private static final Logger LOG = Logger.getInstance(CodeStyleManagerImpl.class);
private static final ThreadLocal<ProcessingUnderProgressInfo> SEQUENTIAL_PROCESSING_ALLOWED
= new ThreadLocal<ProcessingUnderProgressInfo>()
{
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java
index 40ee4adf70f2..b12dee17e9fd 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleSchemesImpl.java
@@ -13,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.intellij.psi.impl.source.codeStyle;
import com.intellij.openapi.components.ExportableComponent;
import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.options.BaseSchemeProcessor;
import com.intellij.openapi.options.SchemeProcessor;
import com.intellij.openapi.options.SchemesManager;
@@ -44,10 +44,10 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes implements E
public String CURRENT_SCHEME_NAME = DEFAULT_SCHEME_NAME;
private boolean myIsInitialized = false;
- @NonNls static final String CODESTYLES_DIRECTORY = "codestyles";
+ @NonNls static final String CODE_STYLES_DIRECTORY = "codestyles";
private final SchemesManager<CodeStyleScheme, CodeStyleSchemeImpl> mySchemesManager;
- @NonNls private static final String FILE_SPEC = "$ROOT_CONFIG$/" + CODESTYLES_DIRECTORY;
+ @NonNls private static final String FILE_SPEC = StoragePathMacros.ROOT_CONFIG + "/" + CODE_STYLES_DIRECTORY;
public CodeStyleSchemesImpl(SchemesManagerFactory schemesManagerFactory) {
SchemeProcessor<CodeStyleSchemeImpl> processor = new BaseSchemeProcessor<CodeStyleSchemeImpl>() {
@@ -97,6 +97,7 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes implements E
CURRENT_SCHEME_NAME = schemeName;
}
+ @SuppressWarnings("ForLoopThatDoesntUseLoopVariable")
@Override
public CodeStyleScheme createNewScheme(String preferredName, CodeStyleScheme parentScheme) {
String name;
@@ -154,10 +155,6 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes implements E
mySchemesManager.addNewScheme(scheme, true);
}
- protected void removeScheme(CodeStyleScheme scheme) {
- mySchemesManager.removeScheme(scheme);
- }
-
protected void init() {
if (myIsInitialized) return;
myIsInitialized = true;
@@ -173,6 +170,4 @@ public abstract class CodeStyleSchemesImpl extends CodeStyleSchemes implements E
public SchemesManager<CodeStyleScheme, CodeStyleSchemeImpl> getSchemesManager() {
return mySchemesManager;
}
-
-
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java
index 3e2acf553815..e3f4fb760fbf 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/PersistableCodeStyleSchemes.java
@@ -18,8 +18,6 @@ package com.intellij.psi.impl.source.codeStyle;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.options.SchemesManagerFactory;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.psi.PsiBundle;
import com.intellij.psi.codeStyle.CodeStyleScheme;
import com.intellij.util.xmlb.Accessor;
import com.intellij.util.xmlb.SerializationFilter;
@@ -99,23 +97,7 @@ public class PersistableCodeStyleSchemes extends CodeStyleSchemesImpl implements
@Override
@NotNull
public File[] getExportFiles() {
- File schemesFile = new File(PathManager.getOptionsPath() + File.separator + CODE_STYLE_SCHEMES_FILE);
- return new File[]{getDir(true), schemesFile};
+ return new File[]{new File(PathManager.getConfigPath() + File.separator + CODE_STYLES_DIRECTORY),
+ new File(PathManager.getOptionsPath() + File.separator + CODE_STYLE_SCHEMES_FILE)};
}
-
- @Nullable
- private static File getDir(boolean create) {
- String directoryPath = PathManager.getConfigPath() + File.separator + CODESTYLES_DIRECTORY;
- File directory = new File(directoryPath);
- if (!directory.exists()) {
- if (!create) return null;
- if (!directory.mkdir()) {
- Messages.showErrorDialog(PsiBundle.message("codestyle.cannot.save.settings.directory.cant.be.created.message", directoryPath),
- PsiBundle.message("codestyle.cannot.save.settings.directory.cant.be.created.title"));
- return null;
- }
- }
- return directory;
- }
-
}
diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexState.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexState.java
index 53785b7b6fda..2acd63308b48 100644
--- a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexState.java
+++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexState.java
@@ -19,6 +19,8 @@
*/
package com.intellij.psi.stubs;
+import org.jetbrains.annotations.NotNull;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -29,9 +31,9 @@ public class StubIndexState {
public StubIndexState() {
}
- public StubIndexState(Collection<StubIndexKey<?, ?>> keys) {
+ public StubIndexState(@NotNull Collection<StubIndexKey<?, ?>> keys) {
for (StubIndexKey key : keys) {
registeredIndices.add(key.toString());
}
}
-} \ No newline at end of file
+}
diff --git a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
index f83dcfe4788f..93921cd6c1dc 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/BaseRefactoringProcessor.java
@@ -431,8 +431,14 @@ public abstract class BaseRefactoringProcessor implements Runnable {
final Runnable prepareHelpersRunnable = new Runnable() {
@Override
public void run() {
- for (RefactoringHelper helper : Extensions.getExtensions(RefactoringHelper.EP_NAME)) {
- preparedData.put(helper, helper.prepareOperation(writableUsageInfos));
+ for (final RefactoringHelper helper : Extensions.getExtensions(RefactoringHelper.EP_NAME)) {
+ Object operation = ApplicationManager.getApplication().runReadAction(new Computable<Object>() {
+ @Override
+ public Object compute() {
+ return helper.prepareOperation(writableUsageInfos);
+ }
+ });
+ preparedData.put(helper, operation);
}
}
};
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java
index a34d30dc5401..dd20f5a7d3e7 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameProcessor.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.
@@ -25,6 +25,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFrame;
@@ -184,9 +185,14 @@ public class RenameProcessor extends BaseRefactoringProcessor {
final Runnable runnable = new Runnable() {
@Override
public void run() {
- for (Map.Entry<PsiElement, String> entry : renames.entrySet()) {
+ for (final Map.Entry<PsiElement, String> entry : renames.entrySet()) {
final UsageInfo[] usages =
- RenameUtil.findUsages(entry.getKey(), entry.getValue(), mySearchInComments, mySearchTextOccurrences, myAllRenames);
+ ApplicationManager.getApplication().runReadAction(new Computable<UsageInfo[]>() {
+ @Override
+ public UsageInfo[] compute() {
+ return RenameUtil.findUsages(entry.getKey(), entry.getValue(), mySearchInComments, mySearchTextOccurrences, myAllRenames);
+ }
+ });
Collections.addAll(variableUsages, usages);
}
}
@@ -223,9 +229,14 @@ public class RenameProcessor extends BaseRefactoringProcessor {
final Runnable runnable = new Runnable() {
@Override
public void run() {
- for (final AutomaticRenamer renamer : myRenamers) {
- renamer.findUsages(variableUsages, mySearchInComments, mySearchTextOccurrences, mySkippedUsages, myAllRenames);
- }
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ for (final AutomaticRenamer renamer : myRenamers) {
+ renamer.findUsages(variableUsages, mySearchInComments, mySearchTextOccurrences, mySkippedUsages, myAllRenames);
+ }
+ }
+ });
}
};
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java
index 6fa0ed27d8c8..0f9011308533 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.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.
@@ -245,7 +245,12 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
final Runnable runnable = new Runnable() {
@Override
public void run() {
- renamer.findUsages(usages, false, false);
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ renamer.findUsages(usages, false, false);
+ }
+ });
}
};
diff --git a/platform/lang-impl/src/com/intellij/semantic/SemServiceImpl.java b/platform/lang-impl/src/com/intellij/semantic/SemServiceImpl.java
index 102a439e11f8..1624c48f2ae5 100644
--- a/platform/lang-impl/src/com/intellij/semantic/SemServiceImpl.java
+++ b/platform/lang-impl/src/com/intellij/semantic/SemServiceImpl.java
@@ -17,8 +17,6 @@ package com.intellij.semantic;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.project.ProjectManagerAdapter;
import com.intellij.openapi.util.LowMemoryWatcher;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
@@ -83,7 +81,7 @@ public class SemServiceImpl extends SemService{
});
- final LowMemoryWatcher watcher = LowMemoryWatcher.register(new Runnable() {
+ LowMemoryWatcher.register(new Runnable() {
@Override
public void run() {
if (myCreatingSem.get() == 0) {
@@ -91,13 +89,7 @@ public class SemServiceImpl extends SemService{
}
//System.out.println("SemService cache flushed");
}
- });
- ProjectManager.getInstance().addProjectManagerListener(project, new ProjectManagerAdapter() {
- @Override
- public void projectClosing(Project project) {
- watcher.stop();
- }
- });
+ }, project);
}
private static MultiMap<SemKey, SemKey> cacheKeyHierarchy(Collection<SemKey> allKeys) {
diff --git a/platform/lang-impl/src/com/intellij/tools/ToolConfigurable.java b/platform/lang-impl/src/com/intellij/tools/ToolConfigurable.java
index 0f39ab8a176c..e410895b087e 100644
--- a/platform/lang-impl/src/com/intellij/tools/ToolConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/tools/ToolConfigurable.java
@@ -35,14 +35,18 @@ public class ToolConfigurable implements SearchableConfigurable, Configurable.No
@Override
public JComponent createComponent() {
- myPanel = new ToolsPanel();
+ if (myPanel == null) {
+ myPanel = new ToolsPanel();
+ }
return myPanel;
}
@Override
public void apply() throws ConfigurationException {
try {
- myPanel.apply();
+ if (myPanel != null) {
+ myPanel.apply();
+ }
}
catch (IOException e) {
throw new ConfigurationException(e.getMessage());
@@ -51,12 +55,14 @@ public class ToolConfigurable implements SearchableConfigurable, Configurable.No
@Override
public boolean isModified() {
- return myPanel.isModified();
+ return myPanel != null && myPanel.isModified();
}
@Override
public void reset() {
- myPanel.reset();
+ if (myPanel != null) {
+ myPanel.reset();
+ }
}
@Override
@@ -73,7 +79,7 @@ public class ToolConfigurable implements SearchableConfigurable, Configurable.No
@Override
@NotNull
public String getId() {
- return getHelpTopic();
+ return "preferences.externalTools";
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/tools/ToolManager.java b/platform/lang-impl/src/com/intellij/tools/ToolManager.java
index 59a17bea67ed..0722090527bb 100644
--- a/platform/lang-impl/src/com/intellij/tools/ToolManager.java
+++ b/platform/lang-impl/src/com/intellij/tools/ToolManager.java
@@ -17,6 +17,7 @@ package com.intellij.tools;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.options.SchemeProcessor;
import com.intellij.openapi.options.SchemesManagerFactory;
import org.jetbrains.annotations.NotNull;
@@ -32,7 +33,7 @@ public class ToolManager extends BaseToolManager<Tool> {
@Override
protected String getSchemesPath() {
- return "$ROOT_CONFIG$/tools";
+ return StoragePathMacros.ROOT_CONFIG + "/tools";
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java b/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java
index f31de9281ea4..750331f1e49a 100644
--- a/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java
+++ b/platform/lang-impl/src/com/intellij/ui/JBTableWithHintProvider.java
@@ -17,66 +17,53 @@ package com.intellij.ui;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.psi.PsiElement;
-import com.intellij.ui.popup.PopupUpdateProcessor;
+import com.intellij.ui.popup.HintUpdateSupply;
import com.intellij.ui.table.JBTable;
+import com.intellij.util.ObjectUtils;
-import javax.swing.*;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
+import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
+/**
+ * @deprecated
+ * @see com.intellij.ui.popup.HintUpdateSupply
+ */
public abstract class JBTableWithHintProvider extends JBTable {
- private JBPopup myHint;
+
+ {
+ new HintUpdateSupply(this) {
+ @Override
+ protected PsiElement getPsiElementForHint(Object selectedValue) {
+ return JBTableWithHintProvider.this.getPsiElementForHint(selectedValue);
+ }
+ };
+ }
public JBTableWithHintProvider() {
- addSelectionListener();
}
protected JBTableWithHintProvider(TableModel model) {
super(model);
}
- private void addSelectionListener() {
- getSelectionModel().addListSelectionListener(new ListSelectionListener() {
- @Override
- public void valueChanged(final ListSelectionEvent e) {
- if (getClientProperty(ListUtil.SELECTED_BY_MOUSE_EVENT) != Boolean.TRUE) {
-
- final int selected = ((ListSelectionModel)e.getSource()).getLeadSelectionIndex();
- int rowCount = getRowCount();
- if (selected == -1 || rowCount == 0) return;
-
- PsiElement element = getPsiElementForHint(getValueAt(Math.min(selected, rowCount -1), 0));
- if (element != null && element.isValid()) {
- updateHint(element);
- }
- }
- }
- });
+ public JBTableWithHintProvider(TableModel model, TableColumnModel columnModel) {
+ super(model, columnModel);
}
protected abstract PsiElement getPsiElementForHint(final Object selectedValue);
- public void registerHint(final JBPopup hint) {
- hideHint();
- myHint = hint;
+ @Deprecated
+ public void registerHint(JBPopup hint) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).registerHint(hint);
}
-
- public void hideHint() {
- if (myHint != null && myHint.isVisible()) {
- myHint.cancel();
- }
- myHint = null;
+ @Deprecated
+ public void hideHint() {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).hideHint();
}
-
- public void updateHint(PsiElement element) {
- if (myHint == null || !myHint.isVisible()) return;
- final PopupUpdateProcessor updateProcessor = myHint.getUserData(PopupUpdateProcessor.class);
- if (updateProcessor != null) {
- updateProcessor.updatePopup(element);
- }
+ @Deprecated
+ public void updateHint(PsiElement element) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).updateHint(element);
}
-
}
diff --git a/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java b/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java
index c22eeb16127f..023ed3998829 100644
--- a/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java
+++ b/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java
@@ -18,84 +18,58 @@ package com.intellij.ui;
import com.intellij.ide.DataManager;
import com.intellij.ide.dnd.aware.DnDAwareTree;
import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.psi.PsiElement;
-import com.intellij.ui.popup.PopupUpdateProcessor;
+import com.intellij.ui.popup.HintUpdateSupply;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.Nullable;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
/**
* @author Konstantin Bulenkov
+ * @deprecated
+ * @see com.intellij.ui.popup.HintUpdateSupply
*/
public class JBTreeWithHintProvider extends DnDAwareTree {
- private JBPopup myHint;
+ {
+ new HintUpdateSupply(this) {
+ @Override
+ protected PsiElement getPsiElementForHint(Object selectedValue) {
+ return JBTreeWithHintProvider.this.getPsiElementForHint(selectedValue);
+ }
+ };
+ }
public JBTreeWithHintProvider() {
- addSelectionListener();
}
public JBTreeWithHintProvider(TreeModel treemodel) {
super(treemodel);
- addSelectionListener();
}
public JBTreeWithHintProvider(TreeNode root) {
super(root);
- addSelectionListener();
- }
-
- private void addSelectionListener() {
- addTreeSelectionListener(new TreeSelectionListener() {
- @Override
- public void valueChanged(final TreeSelectionEvent e) {
- if (isHintBeingShown() && getClientProperty(ListUtil.SELECTED_BY_MOUSE_EVENT) != Boolean.TRUE) {
- final TreePath path = getSelectionPath();
- if (path != null) {
- final PsiElement psiElement = getPsiElementForHint(path.getLastPathComponent());
- if (psiElement != null && psiElement.isValid()) {
- updateHint(psiElement);
- }
- }
- }
- }
- });
}
@Nullable
protected PsiElement getPsiElementForHint(final Object selectedValue) {
- // default implementation
return CommonDataKeys.PSI_ELEMENT.getData(DataManager.getInstance().getDataContext(this));
}
- public void registerHint(final JBPopup hint) {
- hideHint();
- myHint = hint;
+ @Deprecated
+ public void registerHint(JBPopup hint) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).registerHint(hint);
}
+ @Deprecated
public void hideHint() {
- if (isHintBeingShown()) {
- myHint.cancel();
- }
-
- myHint = null;
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).hideHint();
}
+ @Deprecated
public void updateHint(PsiElement element) {
- if (!isHintBeingShown()) return;
-
- final PopupUpdateProcessor updateProcessor = myHint.getUserData(PopupUpdateProcessor.class);
- if (updateProcessor != null) {
- updateProcessor.updatePopup(element);
- }
- }
-
- private boolean isHintBeingShown() {
- return myHint != null && myHint.isVisible();
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).updateHint(element);
}
}
diff --git a/platform/lang-impl/src/com/intellij/ui/popup/PopupUpdateProcessor.java b/platform/lang-impl/src/com/intellij/ui/popup/PopupUpdateProcessor.java
index f02111c5ee11..d5b5bdf09194 100644
--- a/platform/lang-impl/src/com/intellij/ui/popup/PopupUpdateProcessor.java
+++ b/platform/lang-impl/src/com/intellij/ui/popup/PopupUpdateProcessor.java
@@ -24,10 +24,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.psi.PsiElement;
-import com.intellij.ui.JBListWithHintProvider;
-import com.intellij.ui.JBTableWithHintProvider;
-import com.intellij.ui.JBTreeWithHintProvider;
+import javax.swing.*;
import java.awt.*;
/**
@@ -39,7 +37,6 @@ public abstract class PopupUpdateProcessor extends PopupUpdateProcessorBase {
protected PopupUpdateProcessor(Project project) {
myProject = project;
-
}
@Override
@@ -71,14 +68,10 @@ public abstract class PopupUpdateProcessor extends PopupUpdateProcessorBase {
if (fromQuickSearch) {
ChooseByNameBase.JPanelProvider panelProvider = (ChooseByNameBase.JPanelProvider)focusedComponent.getParent();
panelProvider.registerHint(windowEvent.asPopup());
- } else if (focusedComponent != null) {
- if (focusedComponent instanceof JBListWithHintProvider) {
- ((JBListWithHintProvider)focusedComponent).registerHint(windowEvent.asPopup());
- } else if (focusedComponent instanceof JBTableWithHintProvider) {
- ((JBTableWithHintProvider)focusedComponent).registerHint(windowEvent.asPopup());
- } else if (focusedComponent instanceof JBTreeWithHintProvider) {
- ((JBTreeWithHintProvider)focusedComponent).registerHint(windowEvent.asPopup());
- }
+ }
+ else if (focusedComponent instanceof JComponent) {
+ HintUpdateSupply supply = HintUpdateSupply.getSupply((JComponent)focusedComponent);
+ if (supply != null) supply.registerHint(windowEvent.asPopup());
}
}
}
diff --git a/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java b/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java
index 4dee56707ae0..eb06160d4280 100644
--- a/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java
+++ b/platform/lang-impl/src/com/intellij/usageView/UsageViewUtil.java
@@ -167,7 +167,9 @@ public class UsageViewUtil {
int offset = info.getNavigationOffset();
VirtualFile file = info.getVirtualFile();
Project project = info.getProject();
- FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file, offset), requestFocus);
+ if (file != null) {
+ FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, file, offset), requestFocus);
+ }
}
public static Set<UsageInfo> getNotExcludedUsageInfos(final UsageView usageView) {
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 da85132806e5..019b3172817f 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -1727,7 +1727,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
private static void cleanFileContent(@NotNull FileContentImpl fc, PsiFile psiFile) {
- if (psiFile != null) psiFile.putUserData(PsiFileImpl.BUILDING_STUB, false);
+ if (psiFile != null) psiFile.putUserData(PsiFileImpl.BUILDING_STUB, null);
fc.putUserData(IndexingDataKeys.PSI_FILE, null);
}
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 fcbaa21f330b..f66982282fa0 100644
--- a/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java
+++ b/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java
@@ -419,7 +419,7 @@ public class ManagePackagesDialog extends DialogWrapper {
else {
myFilteredOut.add(repoPackage);
}
- if (StringUtil.equals(packageName, filter)) toSelect = repoPackage;
+ if (StringUtil.equalsIgnoreCase(packageName, filter)) toSelect = repoPackage;
}
filter(filtered, toSelect);
}
diff --git a/platform/platform-api/platform-api.iml b/platform/platform-api/platform-api.iml
index 127cfb114b38..38016f147d1a 100644
--- a/platform/platform-api/platform-api.iml
+++ b/platform/platform-api/platform-api.iml
@@ -14,7 +14,7 @@
<orderEntry type="module" module-name="bootstrap" />
<orderEntry type="library" exported="" name="jgoodies-forms" level="project" />
<orderEntry type="module" module-name="forms_rt" exported="" />
- <orderEntry type="library" exported="" name="commons-codec" level="project" />
+ <orderEntry type="library" name="commons-codec" level="project" />
<orderEntry type="module" module-name="platform-resources-en" exported="" />
<orderEntry type="library" name="OroMatcher" level="project" />
<orderEntry type="module" module-name="icons" />
diff --git a/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java b/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
index 939680ea372a..93a3caf6efd9 100644
--- a/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
+++ b/platform/platform-api/src/com/intellij/execution/configurations/GeneralCommandLine.java
@@ -197,6 +197,10 @@ public class GeneralCommandLine implements UserDataHolder {
* @return single-string representation of this command line.
*/
public String getCommandLineString(@Nullable final String exeName) {
+ return ParametersList.join(getCommandLineList(exeName));
+ }
+
+ public List<String> getCommandLineList(@Nullable final String exeName) {
final List<String> commands = new ArrayList<String>();
if (exeName != null) {
commands.add(exeName);
@@ -208,7 +212,7 @@ public class GeneralCommandLine implements UserDataHolder {
commands.add("<null>");
}
commands.addAll(myProgramParams.getList());
- return ParametersList.join(commands);
+ return commands;
}
/**
@@ -224,6 +228,7 @@ public class GeneralCommandLine implements UserDataHolder {
return StringUtil.join(CommandLineUtil.toCommandLine(exePath, myProgramParams.getList(), platform), "\n");
}
+ @NotNull
public Process createProcess() throws ExecutionException {
if (LOG.isDebugEnabled()) {
LOG.debug("Executing [" + getCommandLineString() + "]");
@@ -253,6 +258,7 @@ public class GeneralCommandLine implements UserDataHolder {
}
}
+ @NotNull
protected Process startProcess(@NotNull List<String> commands) throws IOException {
ProcessBuilder builder = new ProcessBuilder(commands);
setupEnvironment(builder.environment());
diff --git a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
index 7e879f496c1b..bab90cfcd9b5 100644
--- a/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
+++ b/platform/platform-api/src/com/intellij/execution/configurations/PathEnvironmentVariableUtil.java
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
+import java.io.FileFilter;
import java.util.Collections;
import java.util.List;
@@ -51,6 +52,19 @@ public class PathEnvironmentVariableUtil {
/**
* Finds an executable file with the specified base name, that is located in a directory
+ * listed in PATH environment variable and is accepted by filter.
+ *
+ * @param fileBaseName file base name
+ * @param filter exe file filter
+ * @return {@code File} instance or null if not found
+ */
+ @Nullable
+ public static File findInPath(@NotNull String fileBaseName, @Nullable FileFilter filter) {
+ return findInPath(fileBaseName, false, filter);
+ }
+
+ /**
+ * Finds an executable file with the specified base name, that is located in a directory
* listed in PATH environment variable.
*
* @param fileBaseName file base name
@@ -59,7 +73,12 @@ public class PathEnvironmentVariableUtil {
*/
@Nullable
public static File findInPath(@NotNull String fileBaseName, boolean logDetails) {
- List<File> exeFiles = findExeFilesInPath(fileBaseName, true, logDetails);
+ return findInPath(fileBaseName, logDetails, null);
+ }
+
+ @Nullable
+ private static File findInPath(@NotNull String fileBaseName, boolean logDetails, @Nullable FileFilter filter) {
+ List<File> exeFiles = findExeFilesInPath(fileBaseName, true, logDetails, filter);
return exeFiles.size() > 0 ? exeFiles.get(0) : null;
}
@@ -79,7 +98,7 @@ public class PathEnvironmentVariableUtil {
else {
originalPath = EnvironmentUtil.getValue(PATH_ENV_VAR_NAME);
}
- List<File> exeFiles = doFindExeFilesInPath(originalPath, fileBaseName, true, false);
+ List<File> exeFiles = doFindExeFilesInPath(originalPath, fileBaseName, true, false, null);
return exeFiles.size() > 0 ? exeFiles.get(0) : null;
}
@@ -92,22 +111,29 @@ public class PathEnvironmentVariableUtil {
*/
@NotNull
public static List<File> findAllExeFilesInPath(@NotNull String fileBaseName) {
- return findExeFilesInPath(fileBaseName, false, false);
+ return findAllExeFilesInPath(fileBaseName, null);
+ }
+
+ @NotNull
+ public static List<File> findAllExeFilesInPath(@NotNull String fileBaseName, @Nullable FileFilter filter) {
+ return findExeFilesInPath(fileBaseName, false, false, filter);
}
@NotNull
private static List<File> findExeFilesInPath(@NotNull String fileBaseName,
boolean stopAfterFirstMatch,
- boolean logDetails) {
+ boolean logDetails,
+ @Nullable FileFilter filter) {
String systemPath = EnvironmentUtil.getValue(PATH_ENV_VAR_NAME);
- return doFindExeFilesInPath(systemPath, fileBaseName, stopAfterFirstMatch, logDetails);
+ return doFindExeFilesInPath(systemPath, fileBaseName, stopAfterFirstMatch, logDetails, filter);
}
@NotNull
private static List<File> doFindExeFilesInPath(@Nullable String pathEnvVarValue,
@NotNull String fileBaseName,
boolean stopAfterFirstMatch,
- boolean logDetails) {
+ boolean logDetails,
+ @Nullable FileFilter filter) {
if (logDetails) {
LOG.info("Finding files in PATH (base name=" + fileBaseName + ", PATH=" + StringUtil.notNullize(pathEnvVarValue) + ").");
}
@@ -124,11 +150,13 @@ public class PathEnvironmentVariableUtil {
+ ", file.isFile:" + file.isFile() + ", file.canExecute:" + file.canExecute());
}
if (dir.isAbsolute() && dir.isDirectory()) {
- File file = new File(dir, fileBaseName);
- if (file.isFile() && file.canExecute()) {
- result.add(file);
- if (stopAfterFirstMatch) {
- return result;
+ File exeFile = new File(dir, fileBaseName);
+ if (exeFile.isFile() && exeFile.canExecute()) {
+ if (filter == null || filter.accept(exeFile)) {
+ result.add(exeFile);
+ if (stopAfterFirstMatch) {
+ return result;
+ }
}
}
}
diff --git a/platform/platform-api/src/com/intellij/execution/configurations/PtyCommandLine.java b/platform/platform-api/src/com/intellij/execution/configurations/PtyCommandLine.java
index 5e3d74caa1f6..182d347de4c1 100644
--- a/platform/platform-api/src/com/intellij/execution/configurations/PtyCommandLine.java
+++ b/platform/platform-api/src/com/intellij/execution/configurations/PtyCommandLine.java
@@ -37,6 +37,7 @@ public class PtyCommandLine extends GeneralCommandLine {
public PtyCommandLine() { }
+ @NotNull
@Override
protected Process startProcess(@NotNull List<String> commands) throws IOException {
if (SystemInfo.isUnix) {
diff --git a/platform/platform-api/src/com/intellij/execution/process/AnsiEscapeDecoder.java b/platform/platform-api/src/com/intellij/execution/process/AnsiEscapeDecoder.java
index 58a8e40db2d6..67c4af413e74 100644
--- a/platform/platform-api/src/com/intellij/execution/process/AnsiEscapeDecoder.java
+++ b/platform/platform-api/src/com/intellij/execution/process/AnsiEscapeDecoder.java
@@ -17,6 +17,7 @@ package com.intellij.execution.process;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -59,11 +60,13 @@ public class AnsiEscapeDecoder {
if (escSeqEndInd < 0) {
break;
}
- String escSeq = text.substring(escSeqBeginInd, escSeqEndInd);
- // this is a simple fix for RUBY-8996:
- // we replace several consecutive escape sequences with one which contains all these sequences
- String colorAttribute = INNER_PATTERN.matcher(escSeq).replaceAll(";");
- myCurrentTextAttributes = ColoredOutputTypeRegistry.getInstance().getOutputKey(colorAttribute);
+ if (text.charAt(escSeqEndInd - 1) == 'm') {
+ String escSeq = text.substring(escSeqBeginInd, escSeqEndInd);
+ // this is a simple fix for RUBY-8996:
+ // we replace several consecutive escape sequences with one which contains all these sequences
+ String colorAttribute = INNER_PATTERN.matcher(escSeq).replaceAll(";");
+ myCurrentTextAttributes = ColoredOutputTypeRegistry.getInstance().getOutputKey(colorAttribute);
+ }
pos = escSeqEndInd;
}
if (pos < text.length()) {
@@ -78,16 +81,41 @@ public class AnsiEscapeDecoder {
* Selects all consecutive escape sequences and returns escape sequence end index (exclusive).
* If the escape sequence isn't finished, returns -1.
*/
- private static int findEscSeqEndIndex(@NotNull String text, int escSeqBeginInd) {
- escSeqBeginInd = text.indexOf('m', escSeqBeginInd);
- while (escSeqBeginInd >= 0) {
- escSeqBeginInd++;
- if (!text.regionMatches(escSeqBeginInd, CSI, 0, CSI.length())) {
+ private static int findEscSeqEndIndex(@NotNull String text, final int escSeqBeginInd) {
+ int beginInd = escSeqBeginInd;
+ while (true) {
+ int letterInd = findEscSeqLetterIndex(text, beginInd);
+ if (letterInd == -1) {
+ return beginInd == escSeqBeginInd ? -1 : beginInd;
+ }
+ if (text.charAt(letterInd) != 'm') {
+ return beginInd == escSeqBeginInd ? letterInd + 1 : beginInd;
+ }
+ beginInd = letterInd + 1;
+ }
+ }
+
+ private static int findEscSeqLetterIndex(@NotNull String text, int escSeqBeginInd) {
+ if (!text.regionMatches(escSeqBeginInd, CSI, 0, CSI.length())) {
+ return -1;
+ }
+ int parameterEndInd = escSeqBeginInd + 2;
+ while (parameterEndInd < text.length()) {
+ char ch = text.charAt(parameterEndInd);
+ if (Character.isDigit(ch) || ch == ';') {
+ parameterEndInd++;
+ }
+ else {
break;
}
- escSeqBeginInd = text.indexOf('m', escSeqBeginInd);
}
- return escSeqBeginInd;
+ if (parameterEndInd < text.length()) {
+ char letter = text.charAt(parameterEndInd);
+ if (StringUtil.containsChar("ABCDEFGHJKSTfmisu", letter)) {
+ return parameterEndInd;
+ }
+ }
+ return -1;
}
@Nullable
diff --git a/platform/platform-api/src/com/intellij/ide/UiActivity.java b/platform/platform-api/src/com/intellij/ide/UiActivity.java
index 9066837fb0a8..49fcd1a74ada 100644
--- a/platform/platform-api/src/com/intellij/ide/UiActivity.java
+++ b/platform/platform-api/src/com/intellij/ide/UiActivity.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.
@@ -26,13 +26,13 @@ import java.util.List;
public class UiActivity implements ComparableObject{
- private List<String> myElements = new ArrayList<String>();
+ private final List<String> myElements = new ArrayList<String>();
- public UiActivity(String ... elements) {
+ public UiActivity(@NotNull String ... elements) {
this(elements, null);
}
- protected UiActivity(String[] elements1, @Nullable String[] elements2) {
+ protected UiActivity(@NotNull String[] elements1, @Nullable String[] elements2) {
myElements.addAll(Arrays.asList(elements1));
if (elements2 != null) {
myElements.addAll(Arrays.asList(elements2));
diff --git a/platform/platform-api/src/com/intellij/ide/UiActivityMonitor.java b/platform/platform-api/src/com/intellij/ide/UiActivityMonitor.java
index 8591383dc6d5..3ecb5727cc30 100644
--- a/platform/platform-api/src/com/intellij/ide/UiActivityMonitor.java
+++ b/platform/platform-api/src/com/intellij/ide/UiActivityMonitor.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.
@@ -22,10 +22,11 @@ import com.intellij.openapi.util.BusyObject;
import org.jetbrains.annotations.NotNull;
public abstract class UiActivityMonitor {
+ @NotNull
+ public abstract BusyObject getBusy(@NotNull Project project, @NotNull UiActivity ... toWatch);
- public abstract BusyObject getBusy(@NotNull Project project, UiActivity ... toWatch);
-
- public abstract BusyObject getBusy(UiActivity ... toWatch);
+ @NotNull
+ public abstract BusyObject getBusy(@NotNull UiActivity ... toWatch);
public abstract void addActivity(@NotNull Project project, @NotNull UiActivity activity);
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 736dcd8afe22..c5843b3d53c8 100644
--- a/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
+++ b/platform/platform-api/src/com/intellij/ide/browsers/BrowserLauncherAppless.java
@@ -127,6 +127,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
GeneralSettings settings = getGeneralSettingsInstance();
if (settings.isUseDefaultBrowser()) {
+ boolean tryToUseCli = true;
if (isDesktopActionSupported(Desktop.Action.BROWSE)) {
try {
Desktop.getDesktop().browse(uri);
@@ -135,13 +136,17 @@ public class BrowserLauncherAppless extends BrowserLauncher {
}
catch (Exception e) {
LOG.warn("Error while using Desktop API, fallback to CLI", e);
+ // if "No application knows how to open", then we must not try to use OS open
+ tryToUseCli = !e.getMessage().contains("Error code: -10814");
}
}
- List<String> command = getDefaultBrowserCommand();
- if (command != null) {
- doLaunch(uri.toString(), command, null, project, ArrayUtil.EMPTY_STRING_ARRAY, null);
- return;
+ if (tryToUseCli) {
+ List<String> command = getDefaultBrowserCommand();
+ if (command != null) {
+ doLaunch(uri.toString(), command, null, project, ArrayUtil.EMPTY_STRING_ARRAY, null);
+ return;
+ }
}
}
@@ -171,7 +176,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
File file = new File(url);
if (!browse && isDesktopActionSupported(Desktop.Action.OPEN)) {
if (!file.exists()) {
- doShowError(IdeBundle.message("error.file.does.not.exist", file.getPath()), null, null, null, null);
+ showError(IdeBundle.message("error.file.does.not.exist", file.getPath()), null, null, null, null);
return;
}
@@ -189,10 +194,10 @@ public class BrowserLauncherAppless extends BrowserLauncher {
}
if (uri == null) {
- doShowError(IdeBundle.message("error.malformed.url", url), null, project, null, null);
+ showError(IdeBundle.message("error.malformed.url", url), null, project, null, null);
}
else {
- browse(uri);
+ browse(uri, project);
}
}
@@ -438,7 +443,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
String message = browser != null ? browser.getBrowserNotFoundMessage() :
IdeBundle.message("error.please.specify.path.to.web.browser", CommonBundle.settingsActionPath());
- doShowError(message, browser, project, IdeBundle.message("title.browser.not.found"), launchTask);
+ showError(message, browser, project, IdeBundle.message("title.browser.not.found"), launchTask);
return false;
}
@@ -475,7 +480,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
return true;
}
catch (ExecutionException e) {
- doShowError(e.getMessage(), browser, project, null, null);
+ showError(e.getMessage(), browser, project, null, null);
return false;
}
}
@@ -487,7 +492,7 @@ public class BrowserLauncherAppless extends BrowserLauncher {
@Nullable Runnable launchTask) {
}
- protected void doShowError(@Nullable String error, @Nullable WebBrowser browser, @Nullable Project project, String title, @Nullable Runnable launchTask) {
+ protected void showError(@Nullable String error, @Nullable WebBrowser browser, @Nullable Project project, String title, @Nullable Runnable launchTask) {
// Not started yet. Not able to show message up. (Could happen in License panel under Linux).
LOG.warn(error);
}
diff --git a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java
index 202483d0117b..10285d05fbee 100644
--- a/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java
+++ b/platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java
@@ -83,7 +83,7 @@ public class AbstractTreeUi {
}
};
long myOwnComparatorStamp;
- long myLastComparatorStamp;
+ private long myLastComparatorStamp;
private DefaultMutableTreeNode myRootNode;
private final Map<Object, Object> myElementToNodeMap = new HashMap<Object, Object>();
@@ -109,7 +109,7 @@ public class AbstractTreeUi {
private final Map<Object, List<NodeAction>> myNodeChildrenActions = new HashMap<Object, List<NodeAction>>();
private long myClearOnHideDelay = -1;
- private final Map<AbstractTreeUi, Long> ourUi2Countdown = Collections.synchronizedMap(new WeakHashMap<AbstractTreeUi, Long>());
+ private volatile long ourUi2Countdown;
private final Set<Runnable> myDeferredSelections = new HashSet<Runnable>();
private final Set<Runnable> myDeferredExpansions = new HashSet<Runnable>();
@@ -263,7 +263,7 @@ public class AbstractTreeUi {
}
- boolean isNodeActionsPending() {
+ private boolean isNodeActionsPending() {
return !myNodeActions.isEmpty() || !myNodeChildrenActions.isEmpty();
}
@@ -310,28 +310,23 @@ public class AbstractTreeUi {
private void cleanUpAll() {
final long now = System.currentTimeMillis();
- final AbstractTreeUi[] uis = ourUi2Countdown.keySet().toArray(new AbstractTreeUi[ourUi2Countdown.size()]);
- for (AbstractTreeUi eachUi : uis) {
- if (eachUi == null) continue;
- final Long timeToCleanup = ourUi2Countdown.get(eachUi);
- if (timeToCleanup == null) continue;
- if (now >= timeToCleanup.longValue()) {
- ourUi2Countdown.remove(eachUi);
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- if (!canInitiateNewActivity()) return;
+ final long timeToCleanup = ourUi2Countdown;
+ if (timeToCleanup != 0 && now >= timeToCleanup) {
+ ourUi2Countdown = 0;
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ if (!canInitiateNewActivity()) return;
- myCleanupTask = null;
- getBuilder().cleanUp();
- }
- };
- if (isPassthroughMode()) {
- runnable.run();
- }
- else {
- invokeLaterIfNeeded(false, runnable);
+ myCleanupTask = null;
+ getBuilder().cleanUp();
}
+ };
+ if (isPassthroughMode()) {
+ runnable.run();
+ }
+ else {
+ invokeLaterIfNeeded(false, runnable);
}
}
}
@@ -390,7 +385,7 @@ public class AbstractTreeUi {
cancelCurrentCleanupTask();
myCanProcessDeferredSelections = true;
- ourUi2Countdown.remove(this);
+ ourUi2Countdown = 0;
if (!myWasEverShown || myUpdateFromRootRequested || myUpdateIfInactive) {
getBuilder().updateFromRoot();
@@ -408,7 +403,7 @@ public class AbstractTreeUi {
}
}
- public void deactivate() {
+ void deactivate() {
getUpdater().hideNotify();
myBusyAlarm.cancelAllRequests();
@@ -420,7 +415,7 @@ public class AbstractTreeUi {
}
if (getClearOnHideDelay() >= 0) {
- ourUi2Countdown.put(this, System.currentTimeMillis() + getClearOnHideDelay());
+ ourUi2Countdown = System.currentTimeMillis() + getClearOnHideDelay();
scheduleCleanUpAll();
}
}
@@ -687,7 +682,7 @@ public class AbstractTreeUi {
wasCleanedUp = true;
}
- if (myRootNodeWasQueuedToInitialize) return wasCleanedUp;
+ if (myRootNodeWasQueuedToInitialize) return true;
myRootNodeWasQueuedToInitialize = true;
@@ -2878,7 +2873,7 @@ public class AbstractTreeUi {
if (!getBuilder().isSmartExpand()) return false;
boolean smartExpand = !myNotForSmartExpand.contains(node) && canSmartExpand;
- return smartExpand && validateAutoExpand(smartExpand, getElementFor(node));
+ return smartExpand && validateAutoExpand(true, getElementFor(node));
}
private void processSmartExpand(@NotNull final DefaultMutableTreeNode node, final boolean canSmartExpand, boolean forced) {
@@ -3778,7 +3773,7 @@ public class AbstractTreeUi {
final boolean oldCanProcessDeferredSelection = myCanProcessDeferredSelections;
- if (!deferred && wasRootNodeInitialized() && willAffectSelection) {
+ if (!deferred && wasRootNodeInitialized()) {
_getReady().doWhenDone(new Runnable() {
@Override
public void run() {
@@ -4357,12 +4352,13 @@ public class AbstractTreeUi {
Object eachElement = element;
DefaultMutableTreeNode firstVisible = null;
while (true) {
- if (!isValid(eachElement) || eachElement == null) break;
+ if (eachElement == null || !isValid(eachElement)) break;
final int preselected = getRowIfUnderSelection(eachElement);
if (preselected >= 0) {
firstVisible = (DefaultMutableTreeNode)getTree().getPathForRow(preselected).getLastPathComponent();
- } else {
+ }
+ else {
firstVisible = getNodeForElement(eachElement, true);
}
@@ -4371,15 +4367,20 @@ public class AbstractTreeUi {
kidsToExpand.add(eachElement);
}
if (firstVisible != null) break;
- eachElement = eachElement != null ? getTreeStructure().getParentElement(eachElement) : null;
+ eachElement = getTreeStructure().getParentElement(eachElement);
if (eachElement == null) {
firstVisible = null;
break;
}
- if (kidsToExpand.contains(eachElement)) {
+ int i = kidsToExpand.indexOf(eachElement);
+ if (i != -1) {
try {
- LOG.error("Tree path contains equal elements at different levels: element=" + eachElement + " class=" + eachElement.getClass() + " path=" + kidsToExpand + " tree structure=" + myTreeStructure);
+ Object existing = kidsToExpand.get(i);
+ LOG.error("Tree path contains equal elements at different levels:\n" +
+ " element: '" + eachElement + "'; " + eachElement.getClass() + " ("+System.identityHashCode(eachElement)+");\n" +
+ "existing: '" + existing + "'; " + existing.getClass()+ " ("+System.identityHashCode(existing)+"); " +
+ "path='" + kidsToExpand + "'; tree structure=" + myTreeStructure);
}
catch (AssertionError ignored) {
}
@@ -5044,6 +5045,7 @@ public class AbstractTreeUi {
return myUpdateChildren;
}
+ @Override
@NotNull
@NonNls
public synchronized String toString() {
diff --git a/platform/platform-api/src/com/intellij/mock/MockProgressIndicator.java b/platform/platform-api/src/com/intellij/mock/MockProgressIndicator.java
index f69cf9b0b963..bc2fd80a5efa 100644
--- a/platform/platform-api/src/com/intellij/mock/MockProgressIndicator.java
+++ b/platform/platform-api/src/com/intellij/mock/MockProgressIndicator.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.
@@ -15,97 +15,11 @@
*/
package com.intellij.mock;
-import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.progress.ProgressIndicator;
-import org.jetbrains.annotations.NotNull;
+import com.intellij.openapi.progress.EmptyProgressIndicator;
+import org.jetbrains.annotations.TestOnly;
-public class MockProgressIndicator implements ProgressIndicator {
- private boolean myIsRunning = false;
- private boolean myIsCanceled = false;
-
- public void start() {
- myIsRunning = true;
- myIsCanceled = false;
- }
-
- public void stop() {
- myIsRunning = false;
- }
-
- public boolean isRunning() {
- return myIsRunning;
- }
-
- public void cancel() {
- myIsCanceled = true;
- }
-
- public boolean isCanceled() {
- return myIsCanceled;
- }
-
- public void setText(String text) {
- }
-
- public String getText() {
- return "";
- }
-
- public void setText2(String text) {
- }
-
- public String getText2() {
- return "";
- }
-
- public double getFraction() {
- return 1;
- }
-
- public void setFraction(double fraction) {
- }
-
- public void pushState() {
- }
-
- public void popState() {
- }
-
- public void startNonCancelableSection() {
- }
-
- public void finishNonCancelableSection() {
- }
-
- public boolean isModal() {
- return false;
- }
-
- @NotNull
- public ModalityState getModalityState() {
- return ModalityState.NON_MODAL;
- }
-
- public void setModalityProgress(ProgressIndicator modalityProgress) {
- }
-
- public boolean isIndeterminate() {
- return false;
- }
-
- public void setIndeterminate(boolean indeterminate) {
- }
-
- public void checkCanceled() {
- }
-
- @Override
- public boolean isPopupWasShown() {
- return false;
- }
-
- @Override
- public boolean isShowing() {
- return false;
+public class MockProgressIndicator extends EmptyProgressIndicator {
+ @TestOnly
+ public MockProgressIndicator() {
}
}
diff --git a/platform/platform-api/src/com/intellij/notification/NotificationGroup.java b/platform/platform-api/src/com/intellij/notification/NotificationGroup.java
index 7285a8e1ffd6..df68daff1584 100644
--- a/platform/platform-api/src/com/intellij/notification/NotificationGroup.java
+++ b/platform/platform-api/src/com/intellij/notification/NotificationGroup.java
@@ -66,6 +66,10 @@ public final class NotificationGroup {
return new NotificationGroup(displayId, NotificationDisplayType.TOOL_WINDOW, logByDefault, toolWindowId);
}
+ public static NotificationGroup toolWindowGroup(@NotNull String displayId, @NotNull String toolWindowId) {
+ return toolWindowGroup(displayId, toolWindowId, true);
+ }
+
public String getDisplayId() {
return myDisplayId;
}
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java
index e3248b863aba..16a81d2218d2 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java
@@ -76,6 +76,7 @@ public abstract class ActionPlaces {
public static final String ANT_MESSAGES_TOOLBAR = "AntMessagesToolbar";
public static final String ANT_EXPLORER_POPUP = "AntExplorerPopup";
public static final String ANT_EXPLORER_TOOLBAR = "AntExplorerToolbar";
+ public static final String GULP_VIEW_POPUP = "JavaScriptGulpPopup";
//todo: probably these context should be splitted into several contexts
public static final String CODE_INSPECTION = "CodeInspection";
@@ -133,7 +134,7 @@ public abstract class ActionPlaces {
FILEVIEW_POPUP, CHECKOUT_POPUP, LVCS_DIRECTORY_HISTORY_POPUP, GUI_DESIGNER_EDITOR_POPUP, GUI_DESIGNER_COMPONENT_TREE_POPUP,
GUI_DESIGNER_PROPERTY_INSPECTOR_POPUP,
CREATE_EJB_POPUP, CHANGES_VIEW_POPUP, REMOTE_HOST_VIEW_POPUP, REMOTE_HOST_DIALOG_POPUP, TFS_TREE_POPUP,
- ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION, PHING_EXPLORER_POPUP, NAVIGATION_BAR_POPUP
+ ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION, PHING_EXPLORER_POPUP, NAVIGATION_BAR_POPUP, GULP_VIEW_POPUP
};
public static boolean isPopupPlace(@NotNull String place) {
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionStub.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionStub.java
index 09896aaf0da8..c96ce2aa3371 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionStub.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionStub.java
@@ -29,6 +29,7 @@ public class ActionStub extends AnAction{
private static final Logger LOG=Logger.getInstance("#com.intellij.openapi.actionSystem.ActionStub");
private final String myClassName;
+ private final String myProjectType;
private final String myId;
private final String myText;
private final ClassLoader myLoader;
@@ -40,9 +41,10 @@ public class ActionStub extends AnAction{
@NotNull String text,
ClassLoader loader,
PluginId pluginId,
- String iconPath) {
+ String iconPath, String projectType) {
myLoader = loader;
myClassName=actionClass;
+ myProjectType = projectType;
LOG.assertTrue(!id.isEmpty());
myId=id;
myText=text;
@@ -102,4 +104,7 @@ public class ActionStub extends AnAction{
targetAction.setShortcutSet(getShortcutSet());
}
+ public String getProjectType() {
+ return myProjectType;
+ }
}
diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/CommonShortcuts.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/CommonShortcuts.java
index 994dd130c384..a1441565d90b 100644
--- a/platform/platform-api/src/com/intellij/openapi/actionSystem/CommonShortcuts.java
+++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/CommonShortcuts.java
@@ -15,9 +15,11 @@
*/
package com.intellij.openapi.actionSystem;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.util.SystemInfo;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.InputEvent;
@@ -148,9 +150,13 @@ public class CommonShortcuts {
return shortcutsById(IdeActions.ACTION_DELETE);
}
+ @NotNull
private static CustomShortcutSet shortcutsById(String actionId) {
- if (ApplicationManager.getApplication() == null) return new CustomShortcutSet(Shortcut.EMPTY_ARRAY);
-
- return new CustomShortcutSet(KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId));
+ Application application = ApplicationManager.getApplication();
+ KeymapManager keymapManager = application == null ? null : application.getComponent(KeymapManager.class);
+ if (keymapManager == null) {
+ return new CustomShortcutSet(Shortcut.EMPTY_ARRAY);
+ }
+ return new CustomShortcutSet(keymapManager.getActiveKeymap().getShortcuts(actionId));
}
}
diff --git a/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarter.java b/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarter.java
index cd0dd2aef263..ffacf59315cd 100644
--- a/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarter.java
+++ b/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarter.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,8 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import org.jetbrains.annotations.NonNls;
/**
- * Implementors of this interface declared via {@link com.intellij.ExtensionPoints#APPLICATION_STARTER} contribute a
- * command line application based on IDEA platform.
+ * Implementers of the interface declared via {@link com.intellij.ExtensionPoints#APPLICATION_STARTER}
+ * contribute to a command-line processing capability of an application.
*
* @author max
* @see ApplicationStarterEx
@@ -30,25 +30,26 @@ public interface ApplicationStarter {
ExtensionPointName<ApplicationStarter> EP_NAME = ExtensionPointName.create(ExtensionPoints.APPLICATION_STARTER);
/**
- * Command line switch to start with this runner. For example return "inspect" if you'd like to start app with
- * <code>idea.exe inspect</code> cmdline.
- * @return command line selector.
+ * Command-line switch to start with this runner.
+ * For example return {@code "inspect"} if you'd like to start an app with {@code "idea.exe inspect ..."} command).
+ *
+ * @return command-line selector.
*/
@NonNls
String getCommandName();
/**
- * Called before application initialization. Invoked in awt dispatch thread.
- * @param args cmdline arguments including declared selector. For example <code>"idea.exe inspect myproject.ipr"</code>
- * will pass <code>{"inspect", "myproject.ipr"}</code>
+ * Called before application initialization. Invoked in event dispatch thread.
+ *
+ * @param args program arguments (including the selector)
*/
void premain(String[] args);
/**
- * Called when application have been initialized. Invoked in awt dispatch thread. An application starter should take care terminating
- * JVM itself when appropriate by calling {@link java.lang.System#exit}(0);
- * @param args cmdline arguments including declared selector. For example <code>"idea.exe inspect myproject.ipr"</code>
- * will pass <code>{"inspect", "myproject.ipr"}</code>
+ * <p>Called when application has been initialized. Invoked in event dispatch thread.</p>
+ * <p>An application starter should take care of terminating JVM when appropriate by calling {@link System#exit}.</p>
+ *
+ * @param args program arguments (including the selector)
*/
void main(String[] args);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarterEx.java b/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarterEx.java
index f84fc1481547..c4b3a6384f56 100644
--- a/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarterEx.java
+++ b/platform/platform-api/src/com/intellij/openapi/application/ApplicationStarterEx.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,11 +16,17 @@
package com.intellij.openapi.application;
/**
- * Implementors of this interface declared via {@link com.intellij.ExtensionPoints#APPLICATION_STARTER} are also capable of processing
- * an external command line within a running IntelliJ Platform instance.
-
+ * Implementers of the interface declared via {@link com.intellij.ExtensionPoints#APPLICATION_STARTER}
+ * may be capable of processing an external command line within a running IntelliJ Platform instance.
+ *
* @author yole
*/
-public interface ApplicationStarterEx extends ApplicationStarter {
- void processExternalCommandLine(String[] args);
+public abstract class ApplicationStarterEx implements ApplicationStarter {
+ public abstract boolean isHeadless();
+
+ public boolean canProcessExternalCommandLine() {
+ return false;
+ }
+
+ public void processExternalCommandLine(String[] args) { }
}
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/ActionButtonPresentation.java b/platform/platform-api/src/com/intellij/openapi/diff/ActionButtonPresentation.java
index a8dbcdbc45e0..c4ae87fb1e02 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/ActionButtonPresentation.java
+++ b/platform/platform-api/src/com/intellij/openapi/diff/ActionButtonPresentation.java
@@ -29,7 +29,7 @@ public abstract class ActionButtonPresentation {
}
};
- public static ActionButtonPresentation CANCEL_WITH_PROMPT = new ActionButtonPresentation(CommonBundle.getCancelButtonText()) {
+ public static ActionButtonPresentation CANCEL_WITH_PROMPT = new ActionButtonPresentation("Revert") {
@Override
public void run(DialogWrapper dialog) {
if (Messages.showYesNoDialog(dialog.getRootPane(),
diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java
index c19173c7e906..7509394a2368 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.fileChooser;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.FileTypes;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VFileProperty;
@@ -51,6 +52,7 @@ public class FileChooserDescriptor implements Cloneable {
private boolean myShowFileSystemRoots = true;
private boolean myTreeRootVisible = false;
private boolean myShowHiddenFiles = false;
+ private Condition<VirtualFile> myFileFilter = null;
private final Map<String, Object> myUserData = new HashMap<String, Object>();
@@ -218,18 +220,15 @@ public class FileChooserDescriptor implements Cloneable {
}
/**
- * Defines whether file can be chosen or not
+ * Sets simple boolean condition for use in {@link #isFileVisible(VirtualFile, boolean)} and {@link #isFileSelectable(VirtualFile)}.
*/
- public boolean isFileSelectable(VirtualFile file) {
- if (file == null) return false;
- if (file.isDirectory() && myChooseFolders) return true;
- if (acceptAsJarFile(file)) return true;
- if (acceptAsGeneralFile(file)) return true;
- return false;
+ public FileChooserDescriptor withFileFilter(@Nullable Condition<VirtualFile> filter) {
+ myFileFilter = filter;
+ return this;
}
/**
- * Defines whether file is visible in the tree
+ * Defines whether a file is visible in the tree.
*/
public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
if (!file.isDirectory()) {
@@ -238,28 +237,47 @@ public class FileChooserDescriptor implements Cloneable {
return false;
}
}
- else {
- if (!myChooseFiles) {
- return false;
- }
+ else if (!myChooseFiles) {
+ return false;
+ }
+ if (myFileFilter != null && !myFileFilter.value(file)) {
+ return false;
}
}
- // do not include ignored files
if (isHideIgnored() && FileTypeManager.getInstance().isFileIgnored(file)) {
return false;
}
- // do not include hidden files
- if (!showHiddenFiles) {
- if (FileElement.isFileHidden(file)) {
- return false;
- }
+ if (!showHiddenFiles && FileElement.isFileHidden(file)) {
+ return false;
}
return true;
}
+ /**
+ * Defines whether a file can be chosen.
+ */
+ public boolean isFileSelectable(VirtualFile file) {
+ if (file == null) return false;
+
+ if (file.isDirectory() && myChooseFolders) {
+ return true;
+ }
+ if (acceptAsJarFile(file)) {
+ return true;
+ }
+ if (acceptAsGeneralFile(file)) {
+ return true;
+ }
+ if (myFileFilter != null && !file.isDirectory() && myFileFilter.value(file)) {
+ return true;
+ }
+
+ return false;
+ }
+
public Icon getIcon(final VirtualFile file) {
if (file.isDirectory()) {
return dressIcon(file, PlatformIcons.DIRECTORY_CLOSED_ICON);
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 c958dbca878e..2eee60aa3061 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptorFactory.java
@@ -16,14 +16,13 @@
package com.intellij.openapi.fileChooser;
import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Condition;
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);
@@ -45,13 +44,7 @@ public class FileChooserDescriptorFactory {
return new FileChooserDescriptor(true, false, false, false, false, false) {
@Override
public boolean isFileSelectable(VirtualFile file) {
- if (super.isFileSelectable(file)) return true;
-
- if (SystemInfo.isMac && file.isDirectory() && "app".equals(file.getExtension())) {
- return true;
- }
-
- return false;
+ return super.isFileSelectable(file) || SystemInfo.isMac && file.isDirectory() && "app".equals(file.getExtension());
}
};
}
@@ -60,6 +53,24 @@ public class FileChooserDescriptorFactory {
return new FileChooserDescriptor(true, true, true, true, false, false);
}
+ public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType) {
+ return new FileChooserDescriptor(true, false, false, false, false, false).withFileFilter(new Condition<VirtualFile>() {
+ @Override
+ public boolean value(VirtualFile file) {
+ return file.getFileType() == fileType;
+ }
+ });
+ }
+
+ public static FileChooserDescriptor createSingleFileDescriptor(final String extension) {
+ return new FileChooserDescriptor(true, false, false, false, false, false).withFileFilter(new Condition<VirtualFile>() {
+ @Override
+ public boolean value(VirtualFile file) {
+ return Comparing.equal(file.getExtension(), extension, SystemInfo.isFileSystemCaseSensitive);
+ }
+ });
+ }
+
public static FileChooserDescriptor createSingleFolderDescriptor() {
return new FileChooserDescriptor(false, true, false, false, false, false);
}
@@ -72,54 +83,40 @@ public class FileChooserDescriptorFactory {
return new FileChooserDescriptor(true, true, false, false, false, false);
}
- public static FileChooserDescriptor getDirectoryChooserDescriptor(String aSearchedObjectName) {
- final FileChooserDescriptor singleFolderDescriptor = createSingleFolderDescriptor();
- singleFolderDescriptor.setTitle(UIBundle.message("file.chooser.select.object.title", aSearchedObjectName));
- return singleFolderDescriptor;
+ public static FileChooserDescriptor createSingleFileOrFolderDescriptor(final FileType fileType) {
+ return new FileChooserDescriptor(true, true, false, false, false, false).withFileFilter(new Condition<VirtualFile>() {
+ @Override
+ public boolean value(VirtualFile file) {
+ return file.getFileType() == fileType;
+ }
+ });
}
- public static FileChooserDescriptor getFileChooserDescriptor(String aSearchedObjectName) {
- final FileChooserDescriptor fileChooserDescriptor = createSingleFileNoJarsDescriptor();
- fileChooserDescriptor.setTitle(UIBundle.message("file.chooser.select.object.title", aSearchedObjectName));
- return fileChooserDescriptor;
+ /** @deprecated use {@link #createSingleFileDescriptor(FileType)} or {@link #createSingleFileOrFolderDescriptor(FileType)} (to be removed in IDEA 14) */
+ @SuppressWarnings("UnusedDeclaration")
+ public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType, final boolean supportDirectories) {
+ return supportDirectories ? createSingleFileOrFolderDescriptor(fileType) : createSingleFileDescriptor(fileType);
}
- public static FileChooserDescriptor createSingleFileDescriptor(final FileType fileType) {
- return createSingleFileDescriptor(fileType, false);
+ /** @deprecated not very useful (to be removed in IDEA 15) */
+ @SuppressWarnings("UnusedDeclaration")
+ public static FileChooserDescriptor getDirectoryChooserDescriptor(String objectName) {
+ return createSingleFolderDescriptor().withTitle("Select " + objectName);
}
- /**
- * 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;
- }
-
- @Override
- public boolean isFileSelectable(final VirtualFile file) {
- return super.isFileSelectable(file) && (file.getFileType() == fileType || ((file.isDirectory() && supportDirectories)));
- }
- };
+ /** @deprecated not very useful (to be removed in IDEA 15) */
+ @SuppressWarnings("UnusedDeclaration")
+ public static FileChooserDescriptor getFileChooserDescriptor(String objectName) {
+ return createSingleFileNoJarsDescriptor().withTitle("Select " + objectName);
}
- /**
- * @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-impl/src/com/intellij/openapi/options/ConfigurableBase.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableBase.java
index d7c7dca2f19b..d7c7dca2f19b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableBase.java
+++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableBase.java
diff --git a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java
index 11c8bdd90052..78a4c1ece130 100644
--- a/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java
+++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableEP.java
@@ -93,6 +93,9 @@ public class ConfigurableEP<T extends UnnamedConfigurable> extends AbstractExten
@Attribute("groupId")
public String groupId;
+ @Attribute("groupWeight")
+ public int groupWeight;
+
/** Marks project level configurables that do not apply to the default project. */
@Attribute("nonDefaultProject")
public boolean nonDefaultProject;
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableUi.java
index 0ecb19a7ce8e..0ecb19a7ce8e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ConfigurableUi.java
+++ b/platform/platform-api/src/com/intellij/openapi/options/ConfigurableUi.java
diff --git a/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java b/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java
index aa6d9618482a..34eaf920d78d 100644
--- a/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java
@@ -41,21 +41,25 @@ public abstract class ShowSettingsUtil {
public abstract boolean editConfigurable(@Nullable Project project, Configurable configurable, @Nullable Runnable advancedInitialization);
- public abstract boolean editConfigurable(Component parent, Configurable configurable);
+ public abstract boolean editConfigurable(@Nullable Component parent, @NotNull Configurable configurable);
- public abstract boolean editConfigurable(Component parent, Configurable configurable, Runnable advancedInitialization);
+ public abstract boolean editConfigurable(Component parent, Configurable configurable, @NotNull Runnable advancedInitialization);
public abstract boolean editConfigurable(Project project, @NonNls String dimensionServiceKey, Configurable configurable);
+ public abstract boolean editConfigurable(Project project, @NonNls String dimensionServiceKey, Configurable configurable, boolean showApplyButton);
+
public abstract boolean editConfigurable(Component parent, String dimensionServiceKey, Configurable configurable);
/**
* @deprecated create a new instance of configurable instead
+ * to remove in IDEA 15
*/
public abstract <T extends Configurable> T findProjectConfigurable(Project project, Class<T> confClass);
/**
* @deprecated create a new instance of configurable instead
+ * to remove in IDEA 15
*/
public abstract <T extends Configurable> T findApplicationConfigurable(Class<T> confClass);
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SimpleConfigurable.java b/platform/platform-api/src/com/intellij/openapi/options/SimpleConfigurable.java
index 9812165932a2..9812165932a2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/SimpleConfigurable.java
+++ b/platform/platform-api/src/com/intellij/openapi/options/SimpleConfigurable.java
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 8dbe02228bae..59f99ad46a05 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/Banner.java
@@ -18,6 +18,7 @@ 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.openapi.util.registry.Registry;
import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.labels.LinkListener;
import com.intellij.ui.components.panels.NonOpaquePanel;
@@ -45,7 +46,7 @@ class Banner extends NonOpaquePanel implements PropertyChangeListener{
public Banner() {
setLayout(new BorderLayout());
- setBorder(new EmptyBorder(2, 6, 2, 4));
+ setBorder(new EmptyBorder(2, Registry.is("ide.new.settings.dialog") ? 12 : 6, 2, 4));
myProjectIcon.setVisible(false);
myProjectIcon.setBorder(new EmptyBorder(0, 12, 0, 4));
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 463d950ae900..00440b0dd8a6 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DetailsComponent.java
@@ -17,6 +17,7 @@
package com.intellij.openapi.ui;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.util.ArrayUtil;
@@ -65,47 +66,54 @@ public class DetailsComponent {
protected void paintComponent(final Graphics g) {
if (NullableComponent.Check.isNull(myContent) || !myDetailsEnabled) return;
- GraphicsConfig c = new GraphicsConfig(g);
- c.setAntialiasing(true);
-
- Insets insets = getInsets();
- if (insets == null) {
- insets = new Insets(0, 0, 0, 0);
+ GraphicsConfig c = null;
+ Insets insets = null;
+ final int leftX;
+ final int rightX;
+ final int rightY;
+ if (!Registry.is("ide.new.settings.dialog")) {
+ c = new GraphicsConfig(g);
+ c.setAntialiasing(true);
+
+ insets = getInsets();
+ if (insets == null) {
+ insets = new Insets(0, 0, 0, 0);
+ }
+
+ g.setColor(UIUtil.getFocusedFillColor());
+
+ final Rectangle banner = myBanner.getBounds();
+ final GeneralPath header = new GeneralPath();
+
+ leftX = insets.left;
+ final int leftY = insets.top;
+ rightX = insets.left + getWidth() - 1 - insets.right;
+ rightY = banner.y + banner.height;
+
+ header.moveTo(leftX, rightY);
+ int arc = 8;
+ header.lineTo(leftX, leftY + arc);
+ header.quadTo(leftX, leftY, leftX + arc, leftY);
+ header.lineTo(rightX - arc, leftY);
+ header.quadTo(rightX, leftY, rightX, leftY + arc);
+ header.lineTo(rightX, rightY);
+ header.closePath();
+
+ c.getG().fill(header);
+
+ g.setColor(UIUtil.getFocusedBoundsColor());
+
+ c.getG().draw(header);
+
+
+ if (myPaintBorder) {
+ final int down = getHeight() - insets.top - insets.bottom - 1;
+ g.drawLine(leftX, rightY, leftX, down);
+ g.drawLine(rightX, rightY, rightX, down);
+ g.drawLine(leftX, down, rightX, down);
+ }
+ c.restore();
}
-
- g.setColor(UIUtil.getFocusedFillColor());
-
- final Rectangle banner = myBanner.getBounds();
- final GeneralPath header = new GeneralPath();
-
- final int leftX = insets.left;
- final int leftY = insets.top;
- final int rightX = insets.left + getWidth() - 1 - insets.right;
- final int rightY = banner.y + banner.height;
-
- header.moveTo(leftX, rightY);
- int arc = 8;
- header.lineTo(leftX, leftY + arc);
- header.quadTo(leftX, leftY, leftX + arc, leftY);
- header.lineTo(rightX - arc, leftY);
- header.quadTo(rightX, leftY, rightX, leftY + arc);
- header.lineTo(rightX, rightY);
- header.closePath();
-
- c.getG().fill(header);
-
- g.setColor(UIUtil.getFocusedBoundsColor());
-
- c.getG().draw(header);
-
- if (myPaintBorder) {
- final int down = getHeight() - insets.top - insets.bottom - 1;
- g.drawLine(leftX, rightY, leftX, down);
- g.drawLine(rightX, rightY, rightX, down);
- g.drawLine(leftX, down, rightX, down);
- }
-
- c.restore();
}
};
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java
index ed374a905462..e4c8c6852727 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogBuilder.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtil;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NonNls;
@@ -55,26 +56,34 @@ public class DialogBuilder implements Disposable {
return showImpl(true).getExitCode();
}
+ public boolean showAndGet() {
+ return showImpl(true).isOK();
+ }
+
public void showNotModal() {
showImpl(false);
}
- public DialogBuilder(Project project) {
+ public DialogBuilder(@Nullable Project project) {
myDialogWrapper = new MyDialogWrapper(project, true);
Disposer.register(myDialogWrapper.getDisposable(), this);
}
- public DialogBuilder(Component parent) {
+ public DialogBuilder(@Nullable Component parent) {
myDialogWrapper = new MyDialogWrapper(parent, true);
Disposer.register(myDialogWrapper.getDisposable(), this);
}
+ public DialogBuilder() {
+ this(((Project)null));
+ }
+
@Override
public void dispose() {
}
private MyDialogWrapper showImpl(boolean isModal) {
- LOG.assertTrue(myTitle != null && myTitle.trim().length() != 0,
+ LOG.assertTrue(!StringUtil.isEmptyOrSpaces(myTitle),
String.format("Dialog title shouldn't be empty or null: [%s]", myTitle));
myDialogWrapper.setTitle(myTitle);
myDialogWrapper.init();
@@ -91,6 +100,12 @@ public class DialogBuilder implements Disposable {
}
@NotNull
+ public DialogBuilder centerPanel(@NotNull JComponent centerPanel) {
+ myCenterPanel = centerPanel;
+ return this;
+ }
+
+ @NotNull
public DialogBuilder setNorthPanel(@NotNull JComponent northPanel) {
myNorthPanel = northPanel;
return this;
@@ -100,6 +115,7 @@ public class DialogBuilder implements Disposable {
myTitle = title;
}
+ @NotNull
public DialogBuilder title(@NotNull String title) {
myTitle = title;
return this;
@@ -196,6 +212,18 @@ public class DialogBuilder implements Disposable {
myDialogWrapper.setOKActionEnabled(isEnabled);
}
+ @NotNull
+ public DialogBuilder okActionEnabled(boolean isEnabled) {
+ myDialogWrapper.setOKActionEnabled(isEnabled);
+ return this;
+ }
+
+ @NotNull
+ public DialogBuilder resizable(boolean resizable) {
+ myDialogWrapper.setResizable(resizable);
+ return this;
+ }
+
public CustomizableAction getOkAction() {
return get(getActionDescriptors(), OkActionDescriptor.class);
}
@@ -267,7 +295,7 @@ public class DialogBuilder implements Disposable {
protected Action createAction(final DialogWrapper dialogWrapper) {
return new AbstractAction(){
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
dialogWrapper.close(myExitCode);
}
};
@@ -325,7 +353,7 @@ public class DialogBuilder implements Disposable {
private class MyDialogWrapper extends DialogWrapper {
private String myHelpId = null;
- private MyDialogWrapper(Project project, boolean canBeParent) {
+ private MyDialogWrapper(@Nullable Project project, boolean canBeParent) {
super(project, canBeParent);
}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
index 75cb4de7af74..741f67dee2c4 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
@@ -1233,6 +1233,7 @@ public abstract class DialogWrapper {
if (SystemInfo.isWindows) {
installEnterHook(root);
}
+ myErrorTextAlarm.setActivationComponent(root);
}
@NotNull
@@ -1838,15 +1839,14 @@ public abstract class DialogWrapper {
return;
}
myLastErrorText = text;
- if (myActualSize == null && !StringUtil.isEmpty(text)) {
- myActualSize = getSize();
- }
-
myErrorTextAlarm.cancelAllRequests();
myErrorTextAlarm.addRequest(new Runnable() {
@Override
public void run() {
final String text = myLastErrorText;
+ if (myActualSize == null && !StringUtil.isEmpty(text)) {
+ myActualSize = getSize();
+ }
myErrorText.setError(text);
if (text != null && text.length() > myMaxErrorTextLength) {
// during the first update, resize only for growing. during a subsequent update,
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java
index c9515a884f97..c1239e523896 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeerFactory.java
@@ -24,17 +24,24 @@ import org.jetbrains.annotations.Nullable;
import java.awt.*;
public abstract class DialogWrapperPeerFactory {
+ @NotNull
public static DialogWrapperPeerFactory getInstance() {
if (ApplicationManager.getApplication() == null) {
- try {
- return (DialogWrapperPeerFactory)Class.forName("com.intellij.openapi.ui.impl.DialogWrapperPeerFactoryImpl").newInstance();
- }
- catch (Exception e) {
- throw new RuntimeException("Can't instantiate DialogWrapperPeerFactory", e);
- }
+ return getInstanceByName();
}
- return ServiceManager.getService(DialogWrapperPeerFactory.class);
+ DialogWrapperPeerFactory factory = ServiceManager.getService(DialogWrapperPeerFactory.class);
+ return factory == null ? getInstanceByName() : factory;
+ }
+
+ @NotNull
+ private static DialogWrapperPeerFactory getInstanceByName() {
+ try {
+ return (DialogWrapperPeerFactory)Class.forName("com.intellij.openapi.ui.impl.DialogWrapperPeerFactoryImpl").newInstance();
+ }
+ catch (Exception e) {
+ throw new RuntimeException("Can't instantiate DialogWrapperPeerFactory", e);
+ }
}
@NotNull
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/MessageDialogBuilder.java b/platform/platform-api/src/com/intellij/openapi/ui/MessageDialogBuilder.java
index ab193aff20c2..7819ef68a7e5 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/MessageDialogBuilder.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/MessageDialogBuilder.java
@@ -40,6 +40,7 @@ public abstract class MessageDialogBuilder<T extends MessageDialogBuilder> {
myMessage = message;
}
+ @NotNull
public static YesNo yesNo(@NotNull String title, @NotNull String message) {
return new YesNo(title, message).icon(Messages.getQuestionIcon());
}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
index dae35d4b685d..1a07b33d696d 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/Messages.java
@@ -143,9 +143,12 @@ public class Messages {
try {
if (canShowMacSheetPanel()) {
- Window parentWindow = WindowManager.getInstance().suggestParentWindow(project);
- return MacMessages.getInstance()
- .showMessageDialog(title, message, options, false, parentWindow, defaultOptionIndex, defaultOptionIndex, doNotAskOption);
+ WindowManager windowManager = WindowManager.getInstance();
+ if (windowManager != null) {
+ Window parentWindow = windowManager.suggestParentWindow(project);
+ return MacMessages.getInstance()
+ .showMessageDialog(title, message, options, false, parentWindow, defaultOptionIndex, defaultOptionIndex, doNotAskOption);
+ }
}
}
catch (Exception exception) {
diff --git a/platform/platform-api/src/com/intellij/openapi/util/PasswordUtil.java b/platform/platform-api/src/com/intellij/openapi/util/PasswordUtil.java
index 4ba3fa7c1516..c4995a34ac27 100644
--- a/platform/platform-api/src/com/intellij/openapi/util/PasswordUtil.java
+++ b/platform/platform-api/src/com/intellij/openapi/util/PasswordUtil.java
@@ -15,13 +15,17 @@
*/
package com.intellij.openapi.util;
+import org.jetbrains.annotations.Nullable;
+
public class PasswordUtil {
private PasswordUtil() { }
// weak encryption just to avoid plain text passwords in text files
- public static String encodePassword(String password) {
+ public static String encodePassword(@Nullable String password) {
String result = "";
- if (password == null) return result;
+ if (password == null) {
+ return result;
+ }
for (int i = 0; i < password.length(); i++) {
int c = password.charAt(i);
c ^= 0xdfaa;
@@ -30,9 +34,11 @@ public class PasswordUtil {
return result;
}
- public static String decodePassword(String password) throws NumberFormatException {
+ public static String decodePassword(@Nullable String password) throws NumberFormatException {
String result = "";
- if (password == null) return result;
+ if (password == null) {
+ return result;
+ }
for (int i = 0; i < password.length(); i += 4) {
String s = password.substring(i, i + 4);
int c = Integer.parseInt(s, 16);
diff --git a/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java b/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java
index 7a6c15ef495f..cf10656a24ed 100644
--- a/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java
+++ b/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryState.java
@@ -16,9 +16,14 @@
package com.intellij.openapi.util.registry;
import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
@State(
name = "Registry",
storages = {
@@ -26,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
file = StoragePathMacros.APP_CONFIG + "/other.xml")}
)
public class RegistryState implements BaseComponent, PersistentStateComponent<Element> {
+ private static final Logger LOG = Logger.getInstance(RegistryState.class);
public RegistryState() {
}
@@ -36,6 +42,14 @@ public class RegistryState implements BaseComponent, PersistentStateComponent<El
public void loadState(Element state) {
Registry.getInstance().loadState(state);
+ SortedMap<String, String> userProperties = new TreeMap<String, String>(Registry.getInstance().getUserProperties());
+ userProperties.remove("ide.firstStartup");
+ if (!userProperties.isEmpty()) {
+ LOG.info("Registry values changed by user:");
+ for (Map.Entry<String, String> entry : userProperties.entrySet()) {
+ LOG.info(" " + entry.getKey() + " = " + entry.getValue());
+ }
+ }
}
@NotNull
diff --git a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java
index edcf3b87ae2a..7adbfd16b324 100644
--- a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java
+++ b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java
@@ -38,4 +38,5 @@ public interface ToolWindowId {
String DOCUMENTATION = UIBundle.message("tool.window.name.documentation");
String TASKS = UIBundle.message("tool.window.name.tasks");
String DATABASE_VIEW = UIBundle.message("tool.window.name.database");
+ String PREVIEW = UIBundle.message("tool.window.name.preview");
} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java b/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java
index b7ec8556f3d9..67ca238ce077 100644
--- a/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java
@@ -17,6 +17,7 @@ package com.intellij.ui;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -30,8 +31,15 @@ public abstract class ColoredListCellRenderer<T> extends SimpleColoredComponent
protected boolean mySelected;
protected Color myForeground;
protected Color mySelectionForeground;
+ @Nullable
+ private final JComboBox myComboBox;
public ColoredListCellRenderer() {
+ this(null);
+ }
+
+ public ColoredListCellRenderer(@Nullable JComboBox comboBox) {
+ myComboBox = comboBox;
setFocusBorderAroundIcon(true);
getIpad().left = UIUtil.getListCellHPadding();
getIpad().right = UIUtil.getListCellHPadding();
@@ -40,6 +48,9 @@ public abstract class ColoredListCellRenderer<T> extends SimpleColoredComponent
public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected, boolean hasFocus) {
clear();
+ if (myComboBox != null) {
+ setEnabled(myComboBox.isEnabled());
+ }
setFont(list.getFont());
mySelected = selected;
myForeground = list.getForeground();
diff --git a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
index 76bacb9cb452..a2e8aacc046f 100644
--- a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
@@ -165,22 +165,22 @@ public abstract class GroupedElementsRenderer {
}
@Override
- protected final Color getSelectionBackground() {
+ protected Color getSelectionBackground() {
return UIUtil.getTreeSelectionBackground();
}
@Override
- protected final Color getSelectionForeground() {
+ protected Color getSelectionForeground() {
return UIUtil.getTreeSelectionForeground();
}
@Override
- protected final Color getBackground() {
+ protected Color getBackground() {
return UIUtil.getTreeTextBackground();
}
@Override
- protected final Color getForeground() {
+ protected Color getForeground() {
return UIUtil.getTreeTextForeground();
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/GuiUtils.java b/platform/platform-api/src/com/intellij/ui/GuiUtils.java
index ec378977f76e..9d5dcbea7edf 100644
--- a/platform/platform-api/src/com/intellij/ui/GuiUtils.java
+++ b/platform/platform-api/src/com/intellij/ui/GuiUtils.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.
@@ -26,7 +26,7 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.CharFilter;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
@@ -47,11 +47,9 @@ import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
public class GuiUtils {
-
private static final Insets paddingFromDialogBoundaries = new Insets(7, 5, 7, 5);
private static final Insets paddingInsideDialog = new Insets(5, 5, 5, 5);
- public static final int lengthForFileField = 25;
private static final CharFilter NOT_MNEMONIC_CHAR_FILTER = new CharFilter() {
@Override
public boolean accept(char ch) {
@@ -78,33 +76,33 @@ public class GuiUtils {
return result;
}
- public static JPanel constructDirectoryBrowserField(final JTextField aTextField, final String aSearchedObjectName) {
- return constructFieldWithBrowseButton(aTextField, new ActionListener() {
+ public static JPanel constructDirectoryBrowserField(final JTextField field, final String objectName) {
+ return constructFieldWithBrowseButton(field, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- FileChooserDescriptor descriptor = FileChooserDescriptorFactory.getDirectoryChooserDescriptor(aSearchedObjectName);
- VirtualFile file = FileChooser.chooseFile(descriptor, aTextField, null, null);
+ FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle("Select " + objectName);
+ VirtualFile file = FileChooser.chooseFile(descriptor, field, null, null);
if (file != null) {
- aTextField.setText(FileUtil.toSystemDependentName(file.getPath()));
- aTextField.postActionEvent();
+ field.setText(FileUtil.toSystemDependentName(file.getPath()));
+ field.postActionEvent();
}
}
});
}
- public static JPanel constructFileURLBrowserField(final TextFieldWithHistory aFieldWithHistory,
- final String aSearchedObjectName) {
- return constructFieldWithBrowseButton(aFieldWithHistory, new ActionListener() {
+ public static JPanel constructFileURLBrowserField(final TextFieldWithHistory field, final String objectName) {
+ return constructFieldWithBrowseButton(field, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- FileChooserDescriptor descriptor = FileChooserDescriptorFactory.getFileChooserDescriptor(aSearchedObjectName);
- VirtualFile file = FileChooser.chooseFile(descriptor, aFieldWithHistory, null, null);
+ FileChooserDescriptor descriptor =
+ FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor().withTitle("Select " + objectName);
+ VirtualFile file = FileChooser.chooseFile(descriptor, field, null, null);
if (file != null) {
try {
- aFieldWithHistory.setText(VfsUtil.virtualToIoFile(file).toURL().toString());
+ field.setText(VfsUtilCore.virtualToIoFile(file).toURI().toURL().toString());
}
catch (MalformedURLException e1) {
- aFieldWithHistory.setText("");
+ field.setText("");
}
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java b/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java
index 27324c9d9781..6a99624a620b 100644
--- a/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java
+++ b/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.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.
@@ -20,9 +20,11 @@ import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.util.NotNullProducer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.PlatformColors;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -42,7 +44,14 @@ import java.util.List;
* @author Eugene Belyaev
*/
public class HyperlinkLabel extends HighlightableComponent {
- private static final TextAttributes BOLD_ATTRIBUTES = new TextAttributes(UIUtil.getLabelTextForeground(), null, null, null, Font.BOLD);
+ private static final TextAttributes BOLD_ATTRIBUTES = new TextAttributes(new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ final Color foreground = UIUtil.getLabelTextForeground();
+ return foreground == null ? UIUtil.getLabelForeground() : foreground;
+ }
+ }), null, null, null, Font.BOLD);
private static final Logger LOG = Logger.getInstance(HyperlinkLabel.class.getName());
@@ -59,7 +68,13 @@ public class HyperlinkLabel extends HighlightableComponent {
public HyperlinkLabel(String text) {
this(text,
PlatformColors.BLUE,
- UIUtil.getLabelBackground(),
+ new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ return UIUtil.getLabelBackground();
+ }
+ }),
PlatformColors.BLUE);
}
@@ -209,7 +224,9 @@ public class HyperlinkLabel extends HighlightableComponent {
LOG.error(e);
}
highlightedText.applyToComponent(this);
- ((JComponent)getParent()).revalidate();
+ final JComponent parent = (JComponent)getParent();
+ parent.revalidate();
+ parent.repaint();
adjustSize();
}
diff --git a/platform/platform-api/src/com/intellij/ui/InplaceButton.java b/platform/platform-api/src/com/intellij/ui/InplaceButton.java
index 04ea9161f99c..89dd0dfc34e2 100644
--- a/platform/platform-api/src/com/intellij/ui/InplaceButton.java
+++ b/platform/platform-api/src/com/intellij/ui/InplaceButton.java
@@ -101,7 +101,11 @@ public class InplaceButton extends JComponent implements ActiveComponent {
setIcons(source.getRegular(), source.getInactive(), source.getHovered());
}
- public void setIcons(final Icon regular, final Icon inactive, final Icon hovered) {
+ public void setIcons(final Icon regular, Icon inactive, Icon hovered) {
+ if (regular == null) return;
+ if (inactive == null) inactive = regular;
+ if (hovered == null) hovered = regular;
+
int width = Math.max(regular.getIconWidth(), inactive.getIconWidth());
width = Math.max(width, hovered.getIconWidth());
int height = Math.max(regular.getIconHeight(), inactive.getIconHeight());
diff --git a/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java b/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java
index 5ef516210e0d..f859421bbbee 100644
--- a/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java
+++ b/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java
@@ -18,79 +18,59 @@ package com.intellij.ui;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.psi.PsiElement;
import com.intellij.ui.components.JBList;
-import com.intellij.ui.popup.PopupUpdateProcessorBase;
+import com.intellij.ui.popup.HintUpdateSupply;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
import java.util.Collection;
/**
* @author pegov
+ * @deprecated
+ * @see com.intellij.ui.popup.HintUpdateSupply
*/
public abstract class JBListWithHintProvider extends JBList {
- private JBPopup myHint;
+ {
+ new HintUpdateSupply(this) {
+ @Override
+ protected PsiElement getPsiElementForHint(Object selectedValue) {
+ return JBListWithHintProvider.this.getPsiElementForHint(selectedValue);
+ }
+ };
+ }
public JBListWithHintProvider() {
- addSelectionListener();
}
public JBListWithHintProvider(ListModel dataModel) {
super(dataModel);
- addSelectionListener();
}
public JBListWithHintProvider(Object... listData) {
super(listData);
- addSelectionListener();
}
public JBListWithHintProvider(Collection items) {
super(items);
- addSelectionListener();
}
- private void addSelectionListener() {
- addListSelectionListener(new ListSelectionListener() {
- @Override
- public void valueChanged(final ListSelectionEvent e) {
- if (getClientProperty(ListUtil.SELECTED_BY_MOUSE_EVENT) != Boolean.TRUE) {
- final Object[] selectedValues = ((JList)e.getSource()).getSelectedValues();
- if (selectedValues.length != 1) return;
-
- final PsiElement element = getPsiElementForHint(selectedValues[0]);
- if (element != null && element.isValid()) {
- updateHint(element);
- }
- }
- }
- });
- }
-
@Nullable
protected abstract PsiElement getPsiElementForHint(final Object selectedValue);
- public void registerHint(final JBPopup hint) {
- hideHint();
- myHint = hint;
+ @Deprecated
+ public void registerHint(JBPopup hint) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).registerHint(hint);
}
-
- public void hideHint() {
- if (myHint != null && myHint.isVisible()) {
- myHint.cancel();
- }
- myHint = null;
+ @Deprecated
+ public void hideHint() {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).hideHint();
}
-
- public void updateHint(PsiElement element) {
- if (myHint == null || !myHint.isVisible()) return;
- final PopupUpdateProcessorBase updateProcessor = myHint.getUserData(PopupUpdateProcessorBase.class);
- if (updateProcessor != null) {
- updateProcessor.updatePopup(element);
- }
+ @Deprecated
+ public void updateHint(PsiElement element) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).updateHint(element);
}
-
+
}
diff --git a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
index 75769d25c0db..74fe7bb31108 100644
--- a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
+++ b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
@@ -56,22 +56,14 @@ public class ScreenUtil {
}
public static Rectangle getMainScreenBounds() {
- GraphicsConfiguration graphicsConfiguration =
- GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
- Rectangle bounds = graphicsConfiguration.getBounds();
- applyInsets(bounds, getScreenInsets(graphicsConfiguration));
- return bounds;
+ return getScreenRectangle(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice());
}
private static Rectangle[] getAllScreenBounds() {
- final GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
- final GraphicsDevice[] devices = env.getScreenDevices();
+ GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
Rectangle[] result = new Rectangle[devices.length];
for (int i = 0; i < devices.length; i++) {
- GraphicsDevice device = devices[i];
- GraphicsConfiguration configuration = device.getDefaultConfiguration();
- result[i] = new Rectangle(configuration.getBounds());
- applyInsets(result[i], getScreenInsets(configuration));
+ result[i] = getScreenRectangle(devices[i]);
}
return result;
}
@@ -86,27 +78,7 @@ public class ScreenUtil {
}
public static Rectangle getScreenRectangle(@NotNull Point p) {
- double distance = -1;
- Rectangle answer = null;
-
- Rectangle[] allScreenBounds = getAllScreenBounds();
- for (Rectangle rect : allScreenBounds) {
- if (rect.contains(p)) {
- return rect;
- }
-
- final double d = findNearestPointOnBorder(rect, p).distance(p.x, p.y);
- if (answer == null || distance > d) {
- distance = d;
- answer = rect;
- }
- }
-
- if (answer == null) {
- throw new IllegalStateException("It's impossible to determine target graphics environment for point (" + p.x + "," + p.y + ")");
- }
-
- return answer;
+ return getScreenRectangle(p.x, p.y);
}
public static GraphicsDevice getScreenDevice(Rectangle bounds) {
@@ -150,11 +122,12 @@ public class ScreenUtil {
}
private static Rectangle applyInsets(Rectangle rect, Insets i) {
- if (i == null) {
- return rect;
- }
-
- return new Rectangle(rect.x + i.left, rect.y + i.top, rect.width - (i.left + i.right), rect.height - (i.top + i.bottom));
+ return (i == null)
+ ? new Rectangle(rect)
+ : new Rectangle(rect.x + i.left,
+ rect.y + i.top,
+ rect.width - (i.left + i.right),
+ rect.height - (i.top + i.bottom));
}
public static Insets getScreenInsets(final GraphicsConfiguration gc) {
@@ -181,8 +154,83 @@ public class ScreenUtil {
return Toolkit.getDefaultToolkit().getScreenInsets(gc);
}
+ /**
+ * Returns a visible area for the specified graphics device.
+ *
+ * @param device one of available devices
+ * @return a visible area rectangle
+ */
+ private static Rectangle getScreenRectangle(GraphicsDevice device) {
+ GraphicsConfiguration configuration = device.getDefaultConfiguration();
+ return applyInsets(configuration.getBounds(), getScreenInsets(configuration));
+ }
+
+ /**
+ * Finds a device that is the closest to the specified point and
+ * returns its visible area.
+ *
+ * @param x the X coordinate of the specified point
+ * @param y the Y coordinate of the specified point
+ * @return a visible area rectangle
+ */
public static Rectangle getScreenRectangle(int x, int y) {
- return getScreenRectangle(new Point(x, y));
+ GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
+ if (devices.length == 0) {
+ return new Rectangle(x, y, 0, 0);
+ }
+ if (devices.length == 1) {
+ return getScreenRectangle(devices[0]);
+ }
+ Rectangle[] rectangles = new Rectangle[devices.length];
+ for (int i = 0; i < devices.length; i++) {
+ GraphicsConfiguration configuration = devices[i].getDefaultConfiguration();
+ Rectangle bounds = configuration.getBounds();
+ rectangles[i] = applyInsets(bounds, getScreenInsets(configuration));
+ if (bounds.contains(x, y)) {
+ return rectangles[i];
+ }
+ }
+ Rectangle bounds = rectangles[0];
+ int minimum = distance(bounds, x, y);
+ for (int i = 1; i < rectangles.length; i++) {
+ int distance = distance(rectangles[i], x, y);
+ if (minimum > distance) {
+ minimum = distance;
+ bounds = rectangles[i];
+ }
+ }
+ return bounds;
+ }
+
+ /**
+ * Normalizes a specified value in the specified range.
+ * If value less than the minimal value,
+ * the method returns the minimal value.
+ * If value greater than the maximal value,
+ * the method returns the maximal value.
+ *
+ * @param value the value to normalize
+ * @param min the minimal value of the range
+ * @param max the maximal value of the range
+ * @return a normalized value
+ */
+ private static int normalize(int value, int min, int max) {
+ return value < min ? min : value > max ? max : value;
+ }
+
+ /**
+ * Returns a square of the distance from
+ * the specified point to the specified rectangle,
+ * which does not contain the specified point.
+ *
+ * @param x the X coordinate of the specified point
+ * @param y the Y coordinate of the specified point
+ * @return a square of the distance
+ */
+ private static int distance(Rectangle bounds, int x, int y) {
+ x -= normalize(x, bounds.x, bounds.x + bounds.width);
+ y -= normalize(y, bounds.y, bounds.y + bounds.height);
+ return x * x + y * y;
}
public static boolean isOutsideOnTheRightOFScreen(Rectangle rect) {
diff --git a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
index 97a42176a25b..51535b67f9af 100644
--- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
+++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
@@ -235,7 +235,7 @@ public class JBScrollPane extends JScrollPane {
}
if (colHead != null) {
Rectangle headerBounds = colHead.getBounds();
- headerBounds.width = viewportBounds.width - headerBounds.x;
+ headerBounds.width = viewportBounds.width;
colHead.setBounds(headerBounds);
}
hideFromView(layout.getCorner(UPPER_RIGHT_CORNER));
@@ -249,7 +249,7 @@ public class JBScrollPane extends JScrollPane {
}
if (rowHead != null) {
Rectangle headerBounds = rowHead.getBounds();
- headerBounds.height = viewportBounds.height - headerBounds.y;
+ headerBounds.height = viewportBounds.height;
rowHead.setBounds(headerBounds);
}
diff --git a/platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java b/platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java
new file mode 100644
index 000000000000..54b071ab0b94
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java
@@ -0,0 +1,156 @@
+/*
+ * 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.ui.popup.JBPopup;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiElement;
+import com.intellij.ui.ListUtil;
+import com.intellij.ui.components.JBList;
+import com.intellij.ui.table.JBTable;
+import com.intellij.ui.treeStructure.Tree;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.TreePath;
+
+/**
+ * Use this class to make various hints like QuickDocumentation, ShowImplementations, etc.
+ * respond to the selection change in the original component like ProjectView, various GoTo popups, etc.
+ *
+ * @author gregsh
+ */
+public abstract class HintUpdateSupply {
+ private static final Key<HintUpdateSupply> HINT_UPDATE_MARKER = Key.create("HINT_UPDATE_MARKER");
+
+ @Nullable
+ private JBPopup myHint;
+
+ @Nullable
+ public static HintUpdateSupply getSupply(@NotNull JComponent component) {
+ return (HintUpdateSupply)component.getClientProperty(HINT_UPDATE_MARKER);
+ }
+
+ public static void hideHint(@NotNull JComponent component) {
+ HintUpdateSupply supply = getSupply(component);
+ if (supply != null) supply.hideHint();
+ }
+
+ protected HintUpdateSupply(@NotNull JComponent component) {
+ installSupply(component);
+ }
+
+ public HintUpdateSupply(@NotNull final JBTable table) {
+ installSupply(table);
+ ListSelectionListener listener = new ListSelectionListener() {
+ @Override
+ public void valueChanged(final ListSelectionEvent e) {
+ if (!isHintVisible(HintUpdateSupply.this.myHint) || isSelectedByMouse(table)) return;
+
+ int selected = ((ListSelectionModel)e.getSource()).getLeadSelectionIndex();
+ int rowCount = table.getRowCount();
+ if (selected == -1 || rowCount == 0) return;
+
+ PsiElement element = getPsiElementForHint(table.getValueAt(Math.min(selected, rowCount - 1), 0));
+ if (element != null && element.isValid()) {
+ updateHint(element);
+ }
+ }
+ };
+ table.getSelectionModel().addListSelectionListener(listener);
+ table.getColumnModel().getSelectionModel().addListSelectionListener(listener);
+ }
+
+ public HintUpdateSupply(@NotNull final Tree tree) {
+ installSupply(tree);
+ tree.addTreeSelectionListener(new TreeSelectionListener() {
+ @Override
+ public void valueChanged(final TreeSelectionEvent e) {
+ if (!isHintVisible(HintUpdateSupply.this.myHint) || isSelectedByMouse(tree)) return;
+
+ TreePath path = tree.getSelectionPath();
+ if (path != null) {
+ final PsiElement psiElement = getPsiElementForHint(path.getLastPathComponent());
+ if (psiElement != null && psiElement.isValid()) {
+ updateHint(psiElement);
+ }
+ }
+ }
+ });
+ }
+
+ public HintUpdateSupply(@NotNull final JBList list) {
+ installSupply(list);
+ list.addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(final ListSelectionEvent e) {
+ if (!isHintVisible(HintUpdateSupply.this.myHint) || isSelectedByMouse(list)) return;
+
+ Object[] selectedValues = ((JList)e.getSource()).getSelectedValues();
+ if (selectedValues.length != 1) return;
+
+ PsiElement element = getPsiElementForHint(selectedValues[0]);
+ if (element != null && element.isValid()) {
+ updateHint(element);
+ }
+ }
+ });
+ }
+
+ @Nullable
+ protected abstract PsiElement getPsiElementForHint(@Nullable Object selectedValue);
+
+ private void installSupply(@NotNull JComponent component) {
+ component.putClientProperty(HINT_UPDATE_MARKER, this);
+ }
+
+ public void registerHint(JBPopup hint) {
+ hideHint();
+ myHint = hint;
+ }
+
+ public void hideHint() {
+ if (isHintVisible(myHint)) {
+ myHint.cancel();
+ }
+
+ myHint = null;
+ }
+
+ public void updateHint(PsiElement element) {
+ if (!isHintVisible(myHint)) return;
+
+ PopupUpdateProcessorBase updateProcessor = myHint.getUserData(PopupUpdateProcessorBase.class);
+ if (updateProcessor != null) {
+ updateProcessor.updatePopup(element);
+ }
+ }
+
+ @Contract("!null->true")
+ private static boolean isHintVisible(JBPopup hint) {
+ return hint != null && hint.isVisible();
+ }
+
+ private static boolean isSelectedByMouse(@NotNull JComponent c) {
+ return Boolean.TRUE.equals(c.getClientProperty(ListUtil.SELECTED_BY_MOUSE_EVENT));
+ }
+}
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 bda230eb767e..c1146be40aba 100644
--- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java
+++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
@@ -424,7 +424,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
if (e instanceof KeyEvent) {
// do not start editing in autoStartsEdit mode on Ctrl-Z and other non-typed events
- if (!UIUtil.isReallyTypedEvent((KeyEvent)e)) return false;
+ if (!UIUtil.isReallyTypedEvent((KeyEvent)e) || ((KeyEvent)e).getKeyChar() == KeyEvent.CHAR_UNDEFINED) return false;
SpeedSearchSupply supply = SpeedSearchSupply.getSupply(this);
if (supply != null && supply.isPopupActive()) {
@@ -743,7 +743,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
@Override
public void setColor(Color color) {
- if (!UIUtil.isUnderDarcula() || !JBTable.this.getBackground().equals(color)) {
+ if (color != null && (!UIUtil.isUnderDarcula() || !JBTable.this.getBackground().equals(color))) {
//noinspection UseJBColor
color = new Color(UIUtil.getGrayFilter().filterRGB(0, 0, color.getRGB()));
}
diff --git a/platform/platform-api/src/com/intellij/util/PlatformUtils.java b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
index 064b5ccc48b6..dfcb5ccf624f 100644
--- a/platform/platform-api/src/com/intellij/util/PlatformUtils.java
+++ b/platform/platform-api/src/com/intellij/util/PlatformUtils.java
@@ -28,7 +28,7 @@ public class PlatformUtils {
public static final String IDEA_PREFIX = PlatformUtilsCore.IDEA_PREFIX;
public static final String IDEA_CE_PREFIX = PlatformUtilsCore.COMMUNITY_PREFIX;
public static final String APPCODE_PREFIX = PlatformUtilsCore.APPCODE_PREFIX;
- public static final String CPP_PREFIX = PlatformUtilsCore.CPP_PREFIX;
+ public static final String CLION_PREFIX = PlatformUtilsCore.CLION_PREFIX;
public static final String PYCHARM_PREFIX = PlatformUtilsCore.PYCHARM_PREFIX;
public static final String PYCHARM_CE_PREFIX = PlatformUtilsCore.PYCHARM_PREFIX2;
public static final String RUBY_PREFIX = PlatformUtilsCore.RUBY_PREFIX;
@@ -66,12 +66,12 @@ public class PlatformUtils {
return PlatformUtilsCore.isAppCode();
}
- public static boolean isCppIde() {
- return PlatformUtilsCore.isCppIde();
+ public static boolean isCLion() {
+ return PlatformUtilsCore.isCLion();
}
public static boolean isCidr() {
- return isAppCode() || isCppIde();
+ return isAppCode() || isCLion();
}
public static boolean isPyCharm() {
diff --git a/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java b/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java
index 246f1e449d5d..83cca8a039df 100644
--- a/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java
+++ b/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java
@@ -23,13 +23,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
-/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Oct 7, 2003
- * Time: 3:56:25 PM
- * To change this template use Options | File Templates.
- */
public class AuthenticationDialog extends DialogWrapper {
private final AuthenticationPanel panel;
@@ -42,7 +35,7 @@ public class AuthenticationDialog extends DialogWrapper {
final Window window = getWindow();
if (window instanceof JDialog) {
- ((JDialog) window).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ ((JDialog) window).setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
}
init();
@@ -57,7 +50,7 @@ public class AuthenticationDialog extends DialogWrapper {
final Window window = getWindow();
if (window instanceof JDialog) {
- ((JDialog) window).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ ((JDialog) window).setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
}
init();
@@ -69,6 +62,7 @@ public class AuthenticationDialog extends DialogWrapper {
return panel.getPreferredFocusedComponent();
}
+ @Override
@Nullable
protected JComponent createCenterPanel() {
return panel;
diff --git a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java
index 52dfa7e7e5ab..5d7d807095f1 100644
--- a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java
+++ b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.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,43 +22,48 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
+@Deprecated
+@SuppressWarnings("UnusedDeclaration")
/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Oct 21, 2003
- * Time: 4:35:44 PM
- * To change this template use Options | File Templates.
+ * @deprecated Use {@link com.intellij.util.net.HttpConfigurable#editConfigurable(javax.swing.JComponent)}
+ * to remove in IDEA 15
*/
public class HTTPProxySettingsDialog extends DialogWrapper {
- private final HTTPProxySettingsPanel panel;
+ private final HttpProxySettingsUi panel;
private final Action okAction;
private final Action cancelAction;
public HTTPProxySettingsDialog() {
super(false);
+
setTitle(CommonBundle.message("title.http.proxy.settings"));
- panel = new HTTPProxySettingsPanel(HttpConfigurable.getInstance());
- panel.reset();
+ final HttpConfigurable settings = HttpConfigurable.getInstance();
+ panel = new HttpProxySettingsUi(settings);
+ panel.reset(settings);
okAction = new AbstractAction(CommonBundle.getOkButtonText()) {
- public void actionPerformed(ActionEvent e) {
- panel.apply();
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ panel.apply(settings);
close(OK_EXIT_CODE);
}
};
okAction.putValue(DEFAULT_ACTION, Boolean.TRUE.toString());
cancelAction = new AbstractAction(CommonBundle.getCancelButtonText()) {
- public void actionPerformed(ActionEvent e) {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
close(CANCEL_EXIT_CODE);
}
};
init();
}
+ @Override
protected JComponent createCenterPanel() {
- return panel.createComponent();
+ return panel.getComponent();
}
+ @Override
@NotNull
protected Action[] createActions() {
return new Action[]{okAction, cancelAction};
diff --git a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java
index 46ea422a3f69..f53c88f372e5 100644
--- a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java
+++ b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.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,389 +15,18 @@
*/
package com.intellij.util.net;
-import com.intellij.openapi.application.Application;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.SearchableConfigurable;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.ui.MultiLineLabelUI;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.wm.IdeFocusManager;
-import com.intellij.openapi.wm.IdeFrame;
-import com.intellij.ui.components.JBLabel;
-import com.intellij.ui.components.JBRadioButton;
-import com.intellij.util.proxy.CommonProxy;
-import com.intellij.util.proxy.JavaProxyProperty;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
-import javax.swing.*;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.util.concurrent.atomic.AtomicReference;
-
+@SuppressWarnings("UnusedDeclaration")
+@Deprecated
/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Aug 28, 2003
- * Time: 3:52:47 PM
- * To change this template use Options | File Templates.
+ * @deprecated Use {@link HttpProxyConfigurable}
+ * to remove in IDEA 15
*/
-public class HTTPProxySettingsPanel implements SearchableConfigurable, Configurable.NoScroll {
+public class HTTPProxySettingsPanel extends HttpProxyConfigurable {
public static final String NAME = "Proxy";
- private JPanel myMainPanel;
-
- private JTextField myProxyLoginTextField;
- private JPasswordField myProxyPasswordTextField;
- private JCheckBox myProxyAuthCheckBox;
- private JTextField myProxyPortTextField;
- private JTextField myProxyHostTextField;
- private JCheckBox myRememberProxyPasswordCheckBox;
-
- private JLabel myProxyLoginLabel;
- private JLabel myProxyPasswordLabel;
- private JLabel myHostNameLabel;
- private JLabel myPortNumberLabel;
- private JBRadioButton myAutoDetectProxyRb;
- private JBRadioButton myUseHTTPProxyRb;
- private JBLabel mySystemProxyDefined;
- private JBRadioButton myNoProxyRb;
- private JBRadioButton myHTTP;
- private JBRadioButton mySocks;
- private JButton myClearPasswordsButton;
- private JLabel myErrorLabel;
- private JButton myCheckButton;
- private JBLabel myOtherWarning;
- private JLabel myProxyExceptionsLabel;
- private JTextArea myProxyExceptions;
- private JLabel myNoProxyForLabel;
- private JCheckBox myPacUrlCheckBox;
- private JTextField myPacUrlTextField;
- private final HttpConfigurable myHttpConfigurable;
- private volatile boolean myConnectionCheckInProgress;
-
- public boolean isModified() {
- boolean isModified = false;
- HttpConfigurable httpConfigurable = myHttpConfigurable;
- if (! Comparing.equal(myProxyExceptions.getText().trim(), httpConfigurable.PROXY_EXCEPTIONS)) return true;
- isModified |= httpConfigurable.USE_PROXY_PAC != myAutoDetectProxyRb.isSelected();
- isModified |= httpConfigurable.USE_PAC_URL != myPacUrlCheckBox.isSelected();
- isModified |= !Comparing.strEqual(httpConfigurable.PAC_URL, myPacUrlTextField.getText());
- isModified |= httpConfigurable.USE_HTTP_PROXY != myUseHTTPProxyRb.isSelected();
- isModified |= httpConfigurable.PROXY_AUTHENTICATION != myProxyAuthCheckBox.isSelected();
- isModified |= httpConfigurable.KEEP_PROXY_PASSWORD != myRememberProxyPasswordCheckBox.isSelected();
- isModified |= httpConfigurable.PROXY_TYPE_IS_SOCKS != mySocks.isSelected();
-
- isModified |= !Comparing.strEqual(httpConfigurable.PROXY_LOGIN, myProxyLoginTextField.getText());
- isModified |= !Comparing.strEqual(httpConfigurable.getPlainProxyPassword(),new String (myProxyPasswordTextField.getPassword()));
-
- try {
- isModified |= httpConfigurable.PROXY_PORT != Integer.valueOf(myProxyPortTextField.getText()).intValue();
- } catch (NumberFormatException e) {
- isModified = true;
- }
- isModified |= !Comparing.strEqual(httpConfigurable.PROXY_HOST, myProxyHostTextField.getText());
- return isModified;
- }
-
- public HTTPProxySettingsPanel(final HttpConfigurable httpConfigurable) {
- final ButtonGroup group = new ButtonGroup();
- group.add(myUseHTTPProxyRb);
- group.add(myAutoDetectProxyRb);
- group.add(myNoProxyRb);
- myNoProxyRb.setSelected(true);
-
- final ButtonGroup proxyTypeGroup = new ButtonGroup();
- proxyTypeGroup.add(myHTTP);
- proxyTypeGroup.add(mySocks);
- myHTTP.setSelected(true);
-
- myProxyExceptions.setBorder(UIUtil.getTextFieldBorder());
-
- final Boolean property = Boolean.getBoolean(JavaProxyProperty.USE_SYSTEM_PROXY);
- mySystemProxyDefined.setVisible(Boolean.TRUE.equals(property));
- if (Boolean.TRUE.equals(property)) {
- mySystemProxyDefined.setIcon(Messages.getWarningIcon());
- mySystemProxyDefined.setFont(mySystemProxyDefined.getFont().deriveFont(Font.BOLD));
- mySystemProxyDefined.setUI(new MultiLineLabelUI());
- }
-
- myProxyAuthCheckBox.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- enableProxyAuthentication(myProxyAuthCheckBox.isSelected());
- }
- });
- myPacUrlCheckBox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- myPacUrlTextField.setEnabled(myPacUrlCheckBox.isSelected());
- }
- });
-
- final ActionListener listener = new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- enableProxy(myUseHTTPProxyRb.isSelected());
- }
- };
- myUseHTTPProxyRb.addActionListener(listener);
- myAutoDetectProxyRb.addActionListener(listener);
- myNoProxyRb.addActionListener(listener);
- myHttpConfigurable = httpConfigurable;
-
- myClearPasswordsButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- myHttpConfigurable.clearGenericPasswords();
- Messages.showMessageDialog(myMainPanel, "Proxy passwords were cleared.", "Auto-detected proxy", Messages.getInformationIcon());
- }
- });
-
- if (HttpConfigurable.getInstance() != null) {
- myCheckButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- final String title = "Check Proxy Settings";
- final String answer = Messages
- .showInputDialog(myMainPanel, "Warning: your settings will be saved.\n\nEnter any URL to check connection to:",
- title, Messages.getQuestionIcon(), "http://", null);
- if (! StringUtil.isEmptyOrSpaces(answer)) {
- apply();
- final HttpConfigurable instance = HttpConfigurable.getInstance();
- final AtomicReference<IOException> exc = new AtomicReference<IOException>();
- myCheckButton.setEnabled(false);
- myCheckButton.setText("Check connection (in progress...)");
- myConnectionCheckInProgress = true;
- final Application application = ApplicationManager.getApplication();
- application.executeOnPooledThread(new Runnable() {
- @Override
- public void run() {
- HttpURLConnection connection = null;
- try {
- //already checked for null above
- //noinspection ConstantConditions
- connection = instance.openHttpConnection(answer);
- connection.setReadTimeout(3 * 1000);
- connection.setConnectTimeout(3 * 1000);
- connection.connect();
- final int code = connection.getResponseCode();
- if (HttpURLConnection.HTTP_OK != code) {
- exc.set(new IOException("Error code: " + code));
- }
- }
- catch (IOException e1) {
- exc.set(e1);
- }
- finally {
- if (connection != null) {
- connection.disconnect();
- }
- }
- //noinspection SSBasedInspection
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- myConnectionCheckInProgress = false;
- reset(); // since password might have been set
- Component parent = null;
- if (myMainPanel.isShowing()) {
- parent = myMainPanel;
- myCheckButton.setText("Check connection");
- myCheckButton.setEnabled(canEnableConnectionCheck());
- } else {
- final IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame();
- if (frame == null) {
- return;
- }
- parent = frame.getComponent();
- }
- //noinspection ThrowableResultOfMethodCallIgnored
- final IOException exception = exc.get();
- if (exception == null) {
- Messages.showMessageDialog(parent, "Connection successful", title, Messages.getInformationIcon());
- }
- else {
- final String message = exception.getMessage();
- if (instance.USE_HTTP_PROXY) {
- instance.LAST_ERROR = message;
- }
- Messages.showErrorDialog(parent, errorText(message));
- }
- }
- });
- }
- });
- }
- }
- });
- } else {
- myCheckButton.setVisible(false);
- }
- }
-
- private boolean canEnableConnectionCheck() {
- return ! myNoProxyRb.isSelected() && ! myConnectionCheckInProgress;
- }
-
- public void reset() {
- myNoProxyRb.setSelected(true); // default
- HttpConfigurable httpConfigurable = myHttpConfigurable;
- myAutoDetectProxyRb.setSelected(httpConfigurable.USE_PROXY_PAC);
- myPacUrlCheckBox.setSelected(httpConfigurable.USE_PAC_URL);
- myPacUrlTextField.setText(httpConfigurable.PAC_URL);
- myUseHTTPProxyRb.setSelected(httpConfigurable.USE_HTTP_PROXY);
- myProxyAuthCheckBox.setSelected(httpConfigurable.PROXY_AUTHENTICATION);
-
- enableProxy(httpConfigurable.USE_HTTP_PROXY);
-
- myProxyLoginTextField.setText(httpConfigurable.PROXY_LOGIN);
- myProxyPasswordTextField.setText(httpConfigurable.getPlainProxyPassword());
-
- myProxyPortTextField.setText(Integer.toString(httpConfigurable.PROXY_PORT));
- myProxyHostTextField.setText(httpConfigurable.PROXY_HOST);
- myProxyExceptions.setText(httpConfigurable.PROXY_EXCEPTIONS);
-
- myRememberProxyPasswordCheckBox.setSelected(httpConfigurable.KEEP_PROXY_PASSWORD);
- mySocks.setSelected(httpConfigurable.PROXY_TYPE_IS_SOCKS);
- myHTTP.setSelected(!httpConfigurable.PROXY_TYPE_IS_SOCKS);
-
- final boolean showError = !StringUtil.isEmptyOrSpaces(httpConfigurable.LAST_ERROR);
- myErrorLabel.setVisible(showError);
- myErrorLabel.setText(showError ? errorText(httpConfigurable.LAST_ERROR) : "");
-
- final String oldStyleText = CommonProxy.getMessageFromProps(CommonProxy.getOldStyleProperties());
- myOtherWarning.setVisible(oldStyleText != null);
- if (oldStyleText != null) {
- myOtherWarning.setText(oldStyleText);
- myOtherWarning.setUI(new MultiLineLabelUI());
- myOtherWarning.setIcon(Messages.getWarningIcon());
- }
- }
-
- private String errorText(final String s) {
- return "Problem with connection: " + s;
- }
-
- public void apply () {
- HttpConfigurable httpConfigurable = myHttpConfigurable;
- if (isModified()){
- httpConfigurable.AUTHENTICATION_CANCELLED = false;
- }
- httpConfigurable.USE_PROXY_PAC = myAutoDetectProxyRb.isSelected();
- httpConfigurable.USE_PAC_URL = myPacUrlCheckBox.isSelected();
- httpConfigurable.PAC_URL = trimFieldText(myPacUrlTextField);
- httpConfigurable.USE_HTTP_PROXY = myUseHTTPProxyRb.isSelected();
- httpConfigurable.PROXY_TYPE_IS_SOCKS = mySocks.isSelected();
- httpConfigurable.PROXY_AUTHENTICATION = myProxyAuthCheckBox.isSelected();
- httpConfigurable.KEEP_PROXY_PASSWORD = myRememberProxyPasswordCheckBox.isSelected();
-
- httpConfigurable.PROXY_LOGIN = trimFieldText(myProxyLoginTextField);
- httpConfigurable.setPlainProxyPassword(new String(myProxyPasswordTextField.getPassword()));
- httpConfigurable.PROXY_EXCEPTIONS = myProxyExceptions.getText();
-
- try {
- httpConfigurable.PROXY_PORT = Integer.valueOf(trimFieldText(myProxyPortTextField)).intValue();
- } catch (NumberFormatException e) {
- httpConfigurable.PROXY_PORT = 80;
- }
- httpConfigurable.PROXY_HOST = trimFieldText(myProxyHostTextField);
- }
-
- private static String trimFieldText(JTextField field) {
- String trimmed = field.getText().trim();
- field.setText(trimmed);
- return trimmed;
- }
-
- private void enableProxy (boolean enabled) {
- myHostNameLabel.setEnabled(enabled);
- myPortNumberLabel.setEnabled(enabled);
- myProxyHostTextField.setEnabled(enabled);
- myProxyPortTextField.setEnabled(enabled);
- mySocks.setEnabled(enabled);
- myHTTP.setEnabled(enabled);
- myProxyExceptions.setEnabled(enabled);
- myProxyExceptions.setBackground(myProxyPortTextField.getBackground());
- myProxyExceptionsLabel.setEnabled(enabled);
- myNoProxyForLabel.setEnabled(enabled);
-
- myProxyAuthCheckBox.setEnabled(enabled);
- enableProxyAuthentication(enabled && myProxyAuthCheckBox.isSelected());
- myCheckButton.setEnabled(canEnableConnectionCheck());
-
- final boolean autoDetectProxy = myAutoDetectProxyRb.isSelected();
- myPacUrlCheckBox.setEnabled(autoDetectProxy);
- myClearPasswordsButton.setEnabled(autoDetectProxy);
- myPacUrlTextField.setEnabled(autoDetectProxy && myPacUrlCheckBox.isSelected());
- }
-
- private void enableProxyAuthentication (boolean enabled) {
- myProxyPasswordLabel.setEnabled(enabled);
- myProxyLoginLabel.setEnabled(enabled);
-
- myProxyLoginTextField.setEnabled(enabled);
- myProxyPasswordTextField.setEnabled(enabled);
-
- myRememberProxyPasswordCheckBox.setEnabled(enabled);
- }
-
- public JComponent getComponent() {
- return myMainPanel;
- }
-
- public JComponent createComponent() {
- return myMainPanel;
- }
-
- @NotNull
- public String getId() {
- return getHelpTopic();
- }
-
- public Runnable enableSearch(final String option) {
- return null;
- }
-
- @Nls
- public String getDisplayName() {
- return NAME;
- }
-
- public String getHelpTopic() {
- return "http.proxy";
- }
-
- public void addActionListener(final ActionListener actionListener) {
- myProxyLoginTextField.addActionListener(actionListener);
- DocumentListener docListener = new DocumentListener() {
- public void insertUpdate(DocumentEvent e) {
- actionListener.actionPerformed(null);
- }
-
- public void removeUpdate(DocumentEvent e) {
- actionListener.actionPerformed(null);
- }
-
- public void changedUpdate(DocumentEvent e) {
- actionListener.actionPerformed(null);
- }
- };
- myProxyPasswordTextField.getDocument().addDocumentListener(docListener);
- myProxyAuthCheckBox.addActionListener(actionListener);
- myProxyPortTextField.getDocument().addDocumentListener(docListener);
- myProxyHostTextField.getDocument().addDocumentListener(docListener);
- myUseHTTPProxyRb.addActionListener(actionListener);
- myRememberProxyPasswordCheckBox.addActionListener(actionListener);
-
- }
- @Override
- public void disposeUIResources() {
+ public HTTPProxySettingsPanel(@NotNull HttpConfigurable settings) {
+ super(settings);
}
-}
+} \ No newline at end of file
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 d51891a8ffe4..0f9855001b63 100644
--- a/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
+++ b/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java
@@ -21,22 +21,28 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.ShowSettingsUtil;
+import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.util.PopupUtil;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.util.Base64;
import com.intellij.util.SystemProperties;
import com.intellij.util.WaitForProgressToShow;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.proxy.CommonProxy;
import com.intellij.util.proxy.JavaProxyProperty;
import com.intellij.util.xmlb.XmlSerializer;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.intellij.util.xmlb.annotations.Transient;
-import org.apache.commons.codec.binary.Base64;
+import gnu.trove.THashMap;
+import gnu.trove.THashSet;
+import gnu.trove.TObjectObjectProcedure;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -48,75 +54,74 @@ import java.lang.reflect.InvocationTargetException;
import java.net.*;
import java.util.*;
-/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Oct 7, 2003
- * Time: 3:58:23 PM
- * To change this template use Options | File Templates.
- */
@State(
name = "HttpConfigurable",
storages = {
- @Storage( file = StoragePathMacros.APP_CONFIG + "/other.xml" ),
- @Storage( file = StoragePathMacros.APP_CONFIG + "/proxy.settings.xml" )
+ // we use two storages due to backward compatibility, see http://crucible.labs.intellij.net/cru/CR-IC-5142
+ @Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml"),
+ @Storage(file = StoragePathMacros.APP_CONFIG + "/proxy.settings.xml")
},
storageChooser = HttpConfigurable.StorageChooser.class
)
-public class HttpConfigurable implements PersistentStateComponent<HttpConfigurable>, ApplicationComponent,
- ExportableApplicationComponent {
+public class HttpConfigurable implements PersistentStateComponent<HttpConfigurable>, ExportableApplicationComponent {
public static final int CONNECTION_TIMEOUT = SystemProperties.getIntProperty("idea.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;
- public boolean USE_PROXY_PAC = false;
- public volatile transient boolean AUTHENTICATION_CANCELLED = false;
- public String PROXY_HOST = "";
+ private static final Logger LOG = Logger.getInstance(HttpConfigurable.class);
+
+ public boolean PROXY_TYPE_IS_SOCKS;
+ public boolean USE_HTTP_PROXY;
+ public boolean USE_PROXY_PAC;
+ public volatile transient boolean AUTHENTICATION_CANCELLED;
+ public String PROXY_HOST;
public int PROXY_PORT = 80;
- public volatile boolean PROXY_AUTHENTICATION = false;
- public volatile String PROXY_LOGIN = "";
- public volatile String PROXY_PASSWORD_CRYPT = "";
- public boolean KEEP_PROXY_PASSWORD = false;
+ public volatile boolean PROXY_AUTHENTICATION;
+ public volatile String PROXY_LOGIN;
+ public volatile String PROXY_PASSWORD_CRYPT;
+ public boolean KEEP_PROXY_PASSWORD;
public transient String LAST_ERROR;
- public Map<CommonProxy.HostInfo, ProxyInfo> myGenericPasswords = new HashMap<CommonProxy.HostInfo, ProxyInfo>();
- public Set<CommonProxy.HostInfo> myGenericCancelled = new HashSet<CommonProxy.HostInfo>();
+
+ private final THashMap<CommonProxy.HostInfo, ProxyInfo> myGenericPasswords = new THashMap<CommonProxy.HostInfo, ProxyInfo>();
+ private final Set<CommonProxy.HostInfo> myGenericCancelled = new THashSet<CommonProxy.HostInfo>();
+
+ public String PROXY_EXCEPTIONS;
+ public boolean USE_PAC_URL;
+ public String PAC_URL;
+
+ private transient IdeaWideProxySelector mySelector;
+
private transient final Object myLock = new Object();
- private IdeaWideProxySelector mySelector;
- private IdeaWideAuthenticator myAuthenticator;
+
+ @SuppressWarnings("UnusedDeclaration")
public transient Getter<PasswordAuthentication> myTestAuthRunnable = new StaticGetter<PasswordAuthentication>(null);
public transient Getter<PasswordAuthentication> myTestGenericAuthRunnable = new StaticGetter<PasswordAuthentication>(null);
- public String PROXY_EXCEPTIONS = "";
- public boolean USE_PAC_URL = false;
- public String PAC_URL = "";
public static HttpConfigurable getInstance() {
return ServiceManager.getService(HttpConfigurable.class);
}
- public static boolean editConfigurable(final JComponent parent) {
- return ShowSettingsUtil.getInstance().editConfigurable(parent, new HTTPProxySettingsPanel(getInstance()));
+ public static boolean editConfigurable(@Nullable JComponent parent) {
+ return ShowSettingsUtil.getInstance().editConfigurable(parent, new HttpProxyConfigurable());
}
@Override
public HttpConfigurable getState() {
CommonProxy.isInstalledAssertion();
- final HttpConfigurable state = new HttpConfigurable();
+
+ HttpConfigurable state = new HttpConfigurable();
XmlSerializerUtil.copyBean(this, state);
if (!KEEP_PROXY_PASSWORD) {
- state.PROXY_PASSWORD_CRYPT = "";
+ state.PROXY_PASSWORD_CRYPT = null;
}
- correctPasswords(this, state);
+ correctPasswords(state);
return state;
}
@Override
public void initComponent() {
mySelector = new IdeaWideProxySelector(this);
- myAuthenticator = new IdeaWideAuthenticator(this);
- final String name = getClass().getName();
+ String name = getClass().getName();
CommonProxy.getInstance().setCustom(name, mySelector);
- CommonProxy.getInstance().setCustomAuth(name, myAuthenticator);
+ CommonProxy.getInstance().setCustomAuth(name, new IdeaWideAuthenticator(this));
}
@NotNull
@@ -137,62 +142,64 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
return getClass().getName();
}
- private void correctPasswords(HttpConfigurable from, HttpConfigurable to) {
+ private void correctPasswords(@NotNull HttpConfigurable to) {
synchronized (myLock) {
- to.myGenericPasswords = new HashMap<CommonProxy.HostInfo, ProxyInfo>();
- for (Map.Entry<CommonProxy.HostInfo, ProxyInfo> entry : from.myGenericPasswords.entrySet()) {
- if (Boolean.TRUE.equals(entry.getValue().isStore())) {
- to.myGenericPasswords.put(entry.getKey(), entry.getValue());
+ to.myGenericPasswords.retainEntries(new TObjectObjectProcedure<CommonProxy.HostInfo, ProxyInfo>() {
+ @Override
+ public boolean execute(CommonProxy.HostInfo hostInfo, ProxyInfo proxyInfo) {
+ return proxyInfo.isStore();
}
- }
+ });
}
}
@Override
- public void loadState(HttpConfigurable state) {
+ public void loadState(@NotNull HttpConfigurable state) {
XmlSerializerUtil.copyBean(state, this);
if (!KEEP_PROXY_PASSWORD) {
- PROXY_PASSWORD_CRYPT = "";
+ PROXY_PASSWORD_CRYPT = null;
}
- correctPasswords(state, this);
+ correctPasswords(this);
}
- public boolean isGenericPasswordCanceled(final String host, final int port) {
+ public boolean isGenericPasswordCanceled(@NotNull String host, int port) {
synchronized (myLock) {
- return myGenericCancelled.contains(Pair.create(host, port));
+ return myGenericCancelled.contains(new CommonProxy.HostInfo(null, host, port));
}
}
public void setGenericPasswordCanceled(final String host, final int port) {
synchronized (myLock) {
- myGenericCancelled.add(new CommonProxy.HostInfo("", host, port));
+ myGenericCancelled.add(new CommonProxy.HostInfo(null, host, port));
}
}
- public PasswordAuthentication getGenericPassword(final String host, final int port) {
+ public PasswordAuthentication getGenericPassword(@NotNull String host, int port) {
final ProxyInfo proxyInfo;
synchronized (myLock) {
- proxyInfo = myGenericPasswords.get(new CommonProxy.HostInfo("", host, port));
+ proxyInfo = myGenericPasswords.get(new CommonProxy.HostInfo(null, host, port));
+ }
+ if (proxyInfo == null) {
+ return null;
}
- if (proxyInfo == null) return null;
return new PasswordAuthentication(proxyInfo.getUsername(), decode(String.valueOf(proxyInfo.getPasswordCrypt())).toCharArray());
}
- public void putGenericPassword(final String host, final int port, final PasswordAuthentication authentication, final boolean remember) {
- final PasswordAuthentication coded = new PasswordAuthentication(authentication.getUserName(), encode(String.valueOf(authentication.getPassword())).toCharArray());
+ public void putGenericPassword(final String host, final int port, @NotNull PasswordAuthentication authentication, boolean remember) {
+ PasswordAuthentication coded = new PasswordAuthentication(authentication.getUserName(), encode(String.valueOf(authentication.getPassword())).toCharArray());
synchronized (myLock) {
- myGenericPasswords.put(new CommonProxy.HostInfo("", host, port), new ProxyInfo(remember, coded.getUserName(), String.valueOf(
- coded.getPassword())));
+ myGenericPasswords.put(new CommonProxy.HostInfo(null, host, port), new ProxyInfo(remember, coded.getUserName(), String.valueOf(coded.getPassword())));
}
}
@Transient
+ @Nullable
public String getPlainProxyPassword() {
- return decode(PROXY_PASSWORD_CRYPT);
+ return PROXY_PASSWORD_CRYPT == null ? null : decode(PROXY_PASSWORD_CRYPT);
}
- private String decode(String value) {
- return new String(new Base64().decode(value.getBytes()));
+ private static String decode(String value) {
+ return new String(Base64.decode(value));
}
@Transient
@@ -200,42 +207,50 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
PROXY_PASSWORD_CRYPT = encode(password);
}
- private String encode(String password) {
- return new String(new Base64().encode(password.getBytes()));
+ private static String encode(String password) {
+ return new String(Base64.encode(password.getBytes(CharsetToolkit.UTF8_CHARSET)));
}
public PasswordAuthentication getGenericPromptedAuthentication(final String prefix, final String host, final String prompt, final int port, final boolean remember) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
return myTestGenericAuthRunnable.get();
}
- final PasswordAuthentication[] value = new PasswordAuthentication[1];
- final Runnable runnable = new Runnable() {
+
+ final Ref<PasswordAuthentication> value = Ref.create();
+ runAboveAll(new Runnable() {
+ @Override
public void run() {
- if (isGenericPasswordCanceled(host, port)) return;
- final PasswordAuthentication password = getGenericPassword(host, port);
+ if (isGenericPasswordCanceled(host, port)) {
+ return;
+ }
+
+ PasswordAuthentication password = getGenericPassword(host, port);
if (password != null) {
- value[0] = password;
+ value.set(password);
return;
}
- final AuthenticationDialog dlg = new AuthenticationDialog(PopupUtil.getActiveComponent(), prefix + host,
- "Please enter credentials for: " + prompt, "", "", remember);
- dlg.show();
- if (dlg.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
- final AuthenticationPanel panel = dlg.getPanel();
- final boolean remember1 = remember && panel.isRememberPassword();
- value[0] = new PasswordAuthentication(panel.getLogin(), panel.getPassword());
- putGenericPassword(host, port, value[0], remember1);
- } else {
+
+ AuthenticationDialog dialog = new AuthenticationDialog(PopupUtil.getActiveComponent(), prefix + host,
+ "Please enter credentials for: " + prompt, "", "", remember);
+ dialog.show();
+ if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
+ AuthenticationPanel panel = dialog.getPanel();
+ PasswordAuthentication passwordAuthentication = new PasswordAuthentication(panel.getLogin(), panel.getPassword());
+ putGenericPassword(host, port, passwordAuthentication, remember && panel.isRememberPassword());
+ value.set(passwordAuthentication);
+ }
+ else {
setGenericPasswordCanceled(host, port);
}
}
- };
- runAboveAll(runnable);
- return value[0];
+ });
+ return value.get();
}
public PasswordAuthentication getPromptedAuthentication(final String host, final String prompt) {
- if (AUTHENTICATION_CANCELLED) return null;
+ if (AUTHENTICATION_CANCELLED) {
+ return null;
+ }
final String password = getPlainProxyPassword();
if (PROXY_AUTHENTICATION && ! StringUtil.isEmptyOrSpaces(PROXY_LOGIN) && ! StringUtil.isEmptyOrSpaces(password)) {
return new PasswordAuthentication(PROXY_LOGIN, password.toCharArray());
@@ -248,63 +263,63 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
if (ApplicationManager.getApplication().isUnitTestMode()) {
return myTestGenericAuthRunnable.get();
}
- final String login = PROXY_LOGIN == null ? "" : PROXY_LOGIN;
final PasswordAuthentication[] value = new PasswordAuthentication[1];
- final Runnable runnable = new Runnable() {
+ runAboveAll(new Runnable() {
+ @Override
public void run() {
- if (AUTHENTICATION_CANCELLED) return;
+ if (AUTHENTICATION_CANCELLED) {
+ return;
+ }
+
// password might have changed, and the check below is for that
- final String password = getPlainProxyPassword();
+ String password = getPlainProxyPassword();
if (PROXY_AUTHENTICATION && ! StringUtil.isEmptyOrSpaces(PROXY_LOGIN) && ! StringUtil.isEmptyOrSpaces(password)) {
value[0] = new PasswordAuthentication(PROXY_LOGIN, password.toCharArray());
return;
}
- final AuthenticationDialog dlg = new AuthenticationDialog(PopupUtil.getActiveComponent(), "Proxy authentication: " + host,
- "Please enter credentials for: " + prompt, login, "", KEEP_PROXY_PASSWORD);
- dlg.show();
- if (dlg.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
+ AuthenticationDialog dialog = new AuthenticationDialog(PopupUtil.getActiveComponent(), "Proxy authentication: " + host,
+ "Please enter credentials for: " + prompt, PROXY_LOGIN, "", KEEP_PROXY_PASSWORD);
+ dialog.show();
+ if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) {
PROXY_AUTHENTICATION = true;
- final AuthenticationPanel panel = dlg.getPanel();
+ AuthenticationPanel panel = dialog.getPanel();
KEEP_PROXY_PASSWORD = panel.isRememberPassword();
- PROXY_LOGIN = panel.getLogin();
+ PROXY_LOGIN = StringUtil.nullize(panel.getLogin());
setPlainProxyPassword(String.valueOf(panel.getPassword()));
value[0] = new PasswordAuthentication(panel.getLogin(), panel.getPassword());
} else {
AUTHENTICATION_CANCELLED = true;
}
}
- };
- runAboveAll(runnable);
+ });
return value[0];
}
- @SuppressWarnings("MethodMayBeStatic")
- private void runAboveAll(final Runnable runnable) {
+ private static void runAboveAll(@NotNull final Runnable runnable) {
final Runnable throughSwing = new Runnable() {
@Override
public void run() {
if (SwingUtilities.isEventDispatchThread()) {
runnable.run();
- return;
}
- try {
- SwingUtilities.invokeAndWait(runnable);
- }
- catch (InterruptedException e) {
- LOG.info(e);
- }
- catch (InvocationTargetException e) {
- LOG.info(e);
+ else {
+ try {
+ SwingUtilities.invokeAndWait(runnable);
+ }
+ catch (InterruptedException e) {
+ LOG.info(e);
+ }
+ catch (InvocationTargetException e) {
+ LOG.info(e);
+ }
}
}
};
- if (ProgressManager.getInstance().getProgressIndicator() != null) {
- if (ProgressManager.getInstance().getProgressIndicator().isModal()) {
- WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(runnable);
- } else {
- throughSwing.run();
- }
- } else {
+ ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
+ if (progressIndicator != null && progressIndicator.isModal()) {
+ WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(runnable);
+ }
+ else {
throughSwing.run();
}
}
@@ -312,22 +327,23 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
//these methods are preserved for compatibility with com.intellij.openapi.project.impl.IdeaServerSettings
@Deprecated
public void readExternal(Element element) throws InvalidDataException {
+ //noinspection ConstantConditions
loadState(XmlSerializer.deserialize(element, HttpConfigurable.class));
}
@Deprecated
public void writeExternal(Element element) throws WriteExternalException {
XmlSerializer.serializeInto(getState(), element);
- if (USE_PROXY_PAC && USE_HTTP_PROXY && ! ApplicationManager.getApplication().isDisposed()) {
+ if (USE_PROXY_PAC && USE_HTTP_PROXY && !ApplicationManager.getApplication().isDisposed()) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
- final IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame();
+ IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame();
if (frame != null) {
USE_PROXY_PAC = false;
Messages.showMessageDialog(frame.getComponent(), "Proxy: both 'use proxy' and 'autodetect proxy' settings were set." +
"\nOnly one of these options should be selected.\nPlease re-configure.",
- "Proxy setup", Messages.getWarningIcon());
+ "Proxy Setup", Messages.getWarningIcon());
editConfigurable(frame.getComponent());
}
}
@@ -344,51 +360,52 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
* @param url URL for HTTP connection
* @throws IOException
*/
- public void prepareURL (String url) throws IOException {
- //setAuthenticator();
- CommonProxy.isInstalledAssertion();
-
- final URLConnection connection = openConnection(url);
+ public void prepareURL(@NotNull String url) throws IOException {
+ URLConnection connection = openConnection(url);
try {
connection.connect();
connection.getInputStream();
}
- catch (Throwable e) {
- if (e instanceof IOException) {
- throw (IOException)e;
- }
- } finally {
+ catch (IOException e) {
+ throw e;
+ }
+ catch (Throwable ignored) {
+ }
+ finally {
if (connection instanceof HttpURLConnection) {
((HttpURLConnection)connection).disconnect();
}
}
}
+ @NotNull
public URLConnection openConnection(@NotNull String location) throws IOException {
CommonProxy.isInstalledAssertion();
final URL url = new URL(location);
URLConnection urlConnection = null;
final List<Proxy> proxies = CommonProxy.getInstance().select(url);
- if (proxies == null || proxies.isEmpty()) {
+ if (ContainerUtil.isEmpty(proxies)) {
urlConnection = url.openConnection();
- } else {
- IOException ioe = null;
+ }
+ else {
+ IOException exception = null;
for (Proxy proxy : proxies) {
try {
urlConnection = url.openConnection(proxy);
- } catch (IOException e) {
+ }
+ catch (IOException e) {
// continue iteration
- ioe = e;
+ exception = e;
}
}
- if (urlConnection == null && ioe != null) {
- throw ioe;
+ if (urlConnection == null && exception != null) {
+ throw exception;
}
}
- if (urlConnection != null) {
- urlConnection.setReadTimeout(CONNECTION_TIMEOUT);
- urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
- }
+
+ assert urlConnection != null;
+ urlConnection.setReadTimeout(CONNECTION_TIMEOUT);
+ urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
return urlConnection;
}
@@ -461,12 +478,15 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
return result;
}
- public static boolean isRealProxy(Proxy proxy) {
- return ! Proxy.NO_PROXY.equals(proxy) && ! Proxy.Type.DIRECT.equals(proxy.type());
+ public static boolean isRealProxy(@NotNull Proxy proxy) {
+ return !Proxy.NO_PROXY.equals(proxy) && !Proxy.Type.DIRECT.equals(proxy.type());
}
+ @NotNull
public static List<String> convertArguments(@NotNull final List<KeyValue<String, String>> list) {
- if (list.isEmpty()) return Collections.emptyList();
+ if (list.isEmpty()) {
+ return Collections.emptyList();
+ }
final List<String> result = new ArrayList<String>(list.size());
for (KeyValue<String, String> value : list) {
result.add("-D" + value.getKey() + "=" + value.getValue());
@@ -481,7 +501,7 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
}
}
- public void removeGeneric(CommonProxy.HostInfo info) {
+ public void removeGeneric(@NotNull CommonProxy.HostInfo info) {
synchronized (myLock) {
myGenericPasswords.remove(info);
}
@@ -518,6 +538,7 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
public String myUsername;
public String myPasswordCrypt;
+ @SuppressWarnings("UnusedDeclaration")
public ProxyInfo() {
}
@@ -547,6 +568,7 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab
return myPasswordCrypt;
}
+ @SuppressWarnings("UnusedDeclaration")
public void setPasswordCrypt(String passwordCrypt) {
myPasswordCrypt = passwordCrypt;
}
diff --git a/platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java b/platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java
new file mode 100644
index 000000000000..4778c811d63e
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java
@@ -0,0 +1,44 @@
+/*
+ * 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.net;
+
+import com.intellij.openapi.options.ConfigurableBase;
+import org.jetbrains.annotations.NotNull;
+
+public class HttpProxyConfigurable extends ConfigurableBase<HttpProxySettingsUi, HttpConfigurable> {
+ private final HttpConfigurable settings;
+
+ public HttpProxyConfigurable() {
+ this(HttpConfigurable.getInstance());
+ }
+
+ public HttpProxyConfigurable(@NotNull HttpConfigurable settings) {
+ super("http.proxy", "HTTP Proxy", "http.proxy");
+
+ this.settings = settings;
+ }
+
+ @NotNull
+ @Override
+ protected HttpConfigurable getSettings() {
+ return settings;
+ }
+
+ @Override
+ protected HttpProxySettingsUi createUi() {
+ return new HttpProxySettingsUi(settings);
+ }
+} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form
index 5ffe378667d3..3d2ae0575e1f 100644
--- a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form
+++ b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.util.net.HTTPProxySettingsPanel">
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.util.net.HttpProxySettingsUi">
<grid id="111c4" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="11" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="111" y="44" width="1040" height="521"/>
+ <xy x="111" y="44" width="1369" height="608"/>
</constraints>
<properties/>
<border type="none"/>
<children>
- <grid id="fe3b6" layout-manager="GridLayoutManager" row-count="8" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="fe3b6" layout-manager="GridLayoutManager" row-count="8" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="20" bottom="10" right="10"/>
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -34,19 +34,9 @@
<text resource-bundle="messages/CommonBundle" key="editbox.port.number"/>
</properties>
</component>
- <component id="2008d" class="javax.swing.JTextField" binding="myProxyHostTextField">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
- <preferred-size width="150" height="-1"/>
- </grid>
- </constraints>
- <properties/>
- </component>
- <component id="7e62" class="javax.swing.JTextField" binding="myProxyPortTextField">
+ <component id="7e62" class="com.intellij.ui.PortField" binding="myProxyPortTextField">
<constraints>
- <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
- <preferred-size width="150" height="-1"/>
- </grid>
+ <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
@@ -105,11 +95,6 @@
<text resource-bundle="messages/CommonBundle" key="checkbox.remember.password"/>
</properties>
</component>
- <hspacer id="92b79">
- <constraints>
- <grid row="5" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
<component id="a16e5" class="javax.swing.JTextArea" binding="myProxyExceptions">
<constraints>
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
@@ -137,6 +122,14 @@
<text resource-bundle="messages/CommonBundle" key="label.proxy.exceptions.text"/>
</properties>
</component>
+ <component id="2008d" class="javax.swing.JTextField" binding="myProxyHostTextField">
+ <constraints>
+ <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="150" height="-1"/>
+ </grid>
+ </constraints>
+ <properties/>
+ </component>
</children>
</grid>
<vspacer id="53d33">
@@ -177,7 +170,7 @@
<text resource-bundle="messages/CommonBundle" key="http.noproxy"/>
</properties>
</component>
- <grid id="1bb9b" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="1bb9b" layout-manager="GridLayoutManager" row-count="1" 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="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -193,11 +186,6 @@
<text resource-bundle="messages/CommonBundle" key="http.proxy.type"/>
</properties>
</component>
- <hspacer id="14ffd">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
<component id="2538c" class="com.intellij.ui.components.JBRadioButton" binding="mySocks">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
@@ -230,7 +218,7 @@
</constraints>
<properties/>
</component>
- <grid id="fee34" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="fee34" 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="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
@@ -262,11 +250,6 @@
</constraints>
<properties/>
</component>
- <hspacer id="21dc">
- <constraints>
- <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
</children>
</grid>
</children>
diff --git a/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java
new file mode 100644
index 000000000000..e71d8e5af4ec
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java
@@ -0,0 +1,386 @@
+/*
+ * 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.net;
+
+import com.google.common.net.HostAndPort;
+import com.google.common.net.InetAddresses;
+import com.google.common.net.InternetDomainName;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.options.ConfigurableUi;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.MultiLineLabelUI;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.ui.PortField;
+import com.intellij.ui.components.JBLabel;
+import com.intellij.ui.components.JBRadioButton;
+import com.intellij.util.proxy.CommonProxy;
+import com.intellij.util.proxy.JavaProxyProperty;
+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.awt.event.ActionListener;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.concurrent.atomic.AtomicReference;
+
+class HttpProxySettingsUi implements ConfigurableUi<HttpConfigurable> {
+ private JPanel myMainPanel;
+
+ private JTextField myProxyLoginTextField;
+ private JPasswordField myProxyPasswordTextField;
+ private JCheckBox myProxyAuthCheckBox;
+ private PortField myProxyPortTextField;
+ private JTextField myProxyHostTextField;
+ private JCheckBox myRememberProxyPasswordCheckBox;
+
+ private JLabel myProxyLoginLabel;
+ private JLabel myProxyPasswordLabel;
+ private JLabel myHostNameLabel;
+ private JLabel myPortNumberLabel;
+ private JBRadioButton myAutoDetectProxyRb;
+ private JBRadioButton myUseHTTPProxyRb;
+ private JBLabel mySystemProxyDefined;
+ private JBRadioButton myNoProxyRb;
+ private JBRadioButton myHTTP;
+ private JBRadioButton mySocks;
+ private JButton myClearPasswordsButton;
+ private JLabel myErrorLabel;
+ private JButton myCheckButton;
+ private JBLabel myOtherWarning;
+ private JLabel myProxyExceptionsLabel;
+ private JTextArea myProxyExceptions;
+ private JLabel myNoProxyForLabel;
+ private JCheckBox myPacUrlCheckBox;
+ private JTextField myPacUrlTextField;
+ private volatile boolean myConnectionCheckInProgress;
+
+ @Override
+ public boolean isModified(@NotNull HttpConfigurable settings) {
+ if (!isValid()) {
+ return false;
+ }
+
+ return !Comparing.strEqual(myProxyExceptions.getText().trim(), settings.PROXY_EXCEPTIONS) ||
+ settings.USE_PROXY_PAC != myAutoDetectProxyRb.isSelected() ||
+ settings.USE_PAC_URL != myPacUrlCheckBox.isSelected() ||
+ !Comparing.strEqual(settings.PAC_URL, myPacUrlTextField.getText()) ||
+ settings.USE_HTTP_PROXY != myUseHTTPProxyRb.isSelected() ||
+ settings.PROXY_AUTHENTICATION != myProxyAuthCheckBox.isSelected() ||
+ settings.KEEP_PROXY_PASSWORD != myRememberProxyPasswordCheckBox.isSelected() ||
+ settings.PROXY_TYPE_IS_SOCKS != mySocks.isSelected() ||
+ !Comparing.strEqual(settings.PROXY_LOGIN, myProxyLoginTextField.getText()) ||
+ !Comparing.strEqual(settings.getPlainProxyPassword(), new String(myProxyPasswordTextField.getPassword())) ||
+ settings.PROXY_PORT != myProxyPortTextField.getNumber() ||
+ !Comparing.strEqual(settings.PROXY_HOST, myProxyHostTextField.getText());
+ }
+
+ public HttpProxySettingsUi(@NotNull final HttpConfigurable settings) {
+ ButtonGroup group = new ButtonGroup();
+ group.add(myUseHTTPProxyRb);
+ group.add(myAutoDetectProxyRb);
+ group.add(myNoProxyRb);
+ myNoProxyRb.setSelected(true);
+
+ ButtonGroup proxyTypeGroup = new ButtonGroup();
+ proxyTypeGroup.add(myHTTP);
+ proxyTypeGroup.add(mySocks);
+ myHTTP.setSelected(true);
+
+ myProxyExceptions.setBorder(UIUtil.getTextFieldBorder());
+
+ Boolean property = Boolean.getBoolean(JavaProxyProperty.USE_SYSTEM_PROXY);
+ mySystemProxyDefined.setVisible(Boolean.TRUE.equals(property));
+ if (Boolean.TRUE.equals(property)) {
+ mySystemProxyDefined.setIcon(Messages.getWarningIcon());
+ mySystemProxyDefined.setFont(mySystemProxyDefined.getFont().deriveFont(Font.BOLD));
+ mySystemProxyDefined.setUI(new MultiLineLabelUI());
+ }
+
+ myProxyAuthCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ enableProxyAuthentication(myProxyAuthCheckBox.isSelected());
+ }
+ });
+ myPacUrlCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ myPacUrlTextField.setEnabled(myPacUrlCheckBox.isSelected());
+ }
+ });
+
+ ActionListener listener = new ActionListener() {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ enableProxy(myUseHTTPProxyRb.isSelected());
+ }
+ };
+ myUseHTTPProxyRb.addActionListener(listener);
+ myAutoDetectProxyRb.addActionListener(listener);
+ myNoProxyRb.addActionListener(listener);
+
+ myClearPasswordsButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ settings.clearGenericPasswords();
+ //noinspection DialogTitleCapitalization
+ Messages.showMessageDialog(myMainPanel, "Proxy passwords were cleared.", "Auto-detected Proxy", Messages.getInformationIcon());
+ }
+ });
+
+ configureCheckButton();
+ }
+
+ private void configureCheckButton() {
+ if (HttpConfigurable.getInstance() == null) {
+ myCheckButton.setVisible(false);
+ return;
+ }
+
+ myCheckButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ final String title = "Check Proxy Settings";
+ final String answer = Messages.showInputDialog(myMainPanel, "Warning: your settings will be saved.\n\nEnter any URL to check connection to:",
+ title, Messages.getQuestionIcon(), "http://", null);
+ if (StringUtil.isEmptyOrSpaces(answer)) {
+ return;
+ }
+
+ final HttpConfigurable settings = HttpConfigurable.getInstance();
+ apply(settings);
+ final AtomicReference<IOException> exceptionReference = new AtomicReference<IOException>();
+ myCheckButton.setEnabled(false);
+ myCheckButton.setText("Check connection (in progress...)");
+ myConnectionCheckInProgress = true;
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ HttpURLConnection connection = null;
+ try {
+ //already checked for null above
+ //noinspection ConstantConditions
+ connection = settings.openHttpConnection(answer);
+ connection.setReadTimeout(3 * 1000);
+ connection.setConnectTimeout(3 * 1000);
+ connection.connect();
+ final int code = connection.getResponseCode();
+ if (HttpURLConnection.HTTP_OK != code) {
+ exceptionReference.set(new IOException("Error code: " + code));
+ }
+ }
+ catch (IOException e) {
+ exceptionReference.set(e);
+ }
+ finally {
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ myConnectionCheckInProgress = false;
+ reset(settings); // since password might have been set
+ Component parent;
+ if (myMainPanel.isShowing()) {
+ parent = myMainPanel;
+ myCheckButton.setText("Check connection");
+ myCheckButton.setEnabled(canEnableConnectionCheck());
+ }
+ else {
+ IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame();
+ if (frame == null) {
+ return;
+ }
+ parent = frame.getComponent();
+ }
+ //noinspection ThrowableResultOfMethodCallIgnored
+ final IOException exception = exceptionReference.get();
+ if (exception == null) {
+ Messages.showMessageDialog(parent, "Connection successful", title, Messages.getInformationIcon());
+ }
+ else {
+ final String message = exception.getMessage();
+ if (settings.USE_HTTP_PROXY) {
+ settings.LAST_ERROR = message;
+ }
+ Messages.showErrorDialog(parent, errorText(message));
+ }
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+
+ private boolean canEnableConnectionCheck() {
+ return !myNoProxyRb.isSelected() && !myConnectionCheckInProgress;
+ }
+
+ @Override
+ public void reset(@NotNull HttpConfigurable settings) {
+ myNoProxyRb.setSelected(true); // default
+ myAutoDetectProxyRb.setSelected(settings.USE_PROXY_PAC);
+ myPacUrlCheckBox.setSelected(settings.USE_PAC_URL);
+ myPacUrlTextField.setText(settings.PAC_URL);
+ myUseHTTPProxyRb.setSelected(settings.USE_HTTP_PROXY);
+ myProxyAuthCheckBox.setSelected(settings.PROXY_AUTHENTICATION);
+
+ enableProxy(settings.USE_HTTP_PROXY);
+
+ myProxyLoginTextField.setText(settings.PROXY_LOGIN);
+ myProxyPasswordTextField.setText(settings.getPlainProxyPassword());
+
+ myProxyPortTextField.setNumber(settings.PROXY_PORT);
+ myProxyHostTextField.setText(settings.PROXY_HOST);
+ myProxyExceptions.setText(StringUtil.notNullize(settings.PROXY_EXCEPTIONS));
+
+ myRememberProxyPasswordCheckBox.setSelected(settings.KEEP_PROXY_PASSWORD);
+ mySocks.setSelected(settings.PROXY_TYPE_IS_SOCKS);
+ myHTTP.setSelected(!settings.PROXY_TYPE_IS_SOCKS);
+
+ boolean showError = !StringUtil.isEmptyOrSpaces(settings.LAST_ERROR);
+ myErrorLabel.setVisible(showError);
+ myErrorLabel.setText(showError ? errorText(settings.LAST_ERROR) : null);
+
+ final String oldStyleText = CommonProxy.getMessageFromProps(CommonProxy.getOldStyleProperties());
+ myOtherWarning.setVisible(oldStyleText != null);
+ if (oldStyleText != null) {
+ myOtherWarning.setText(oldStyleText);
+ myOtherWarning.setUI(new MultiLineLabelUI());
+ myOtherWarning.setIcon(Messages.getWarningIcon());
+ }
+ }
+
+ @NotNull
+ private static String errorText(@NotNull String s) {
+ return "Problem with connection: " + s;
+ }
+
+ private boolean isValid() {
+ if (myUseHTTPProxyRb.isSelected()) {
+ String host = getText(myProxyHostTextField);
+ if (host == null) {
+ return false;
+ }
+
+ try {
+ HostAndPort parsedHost = HostAndPort.fromString(host);
+ if (parsedHost.hasPort()) {
+ return false;
+ }
+ host = parsedHost.getHostText();
+
+ try {
+ InetAddresses.forString(host);
+ return true;
+ }
+ catch (IllegalArgumentException e) {
+ // it is not an IPv4 or IPv6 literal
+ }
+
+ InternetDomainName.from(host);
+ }
+ catch (IllegalArgumentException e) {
+ return false;
+ }
+
+ if (myProxyAuthCheckBox.isSelected()) {
+ return !StringUtil.isEmptyOrSpaces(myProxyLoginTextField.getText()) && myProxyPasswordTextField.getPassword().length > 0;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void apply(@NotNull HttpConfigurable settings) {
+ if (!isValid()) {
+ return;
+ }
+
+ if (isModified(settings)) {
+ settings.AUTHENTICATION_CANCELLED = false;
+ }
+
+ settings.USE_PROXY_PAC = myAutoDetectProxyRb.isSelected();
+ settings.USE_PAC_URL = myPacUrlCheckBox.isSelected();
+ settings.PAC_URL = getText(myPacUrlTextField);
+ settings.USE_HTTP_PROXY = myUseHTTPProxyRb.isSelected();
+ settings.PROXY_TYPE_IS_SOCKS = mySocks.isSelected();
+ settings.PROXY_AUTHENTICATION = myProxyAuthCheckBox.isSelected();
+ settings.KEEP_PROXY_PASSWORD = myRememberProxyPasswordCheckBox.isSelected();
+
+ settings.PROXY_LOGIN = getText(myProxyLoginTextField);
+ settings.setPlainProxyPassword(new String(myProxyPasswordTextField.getPassword()));
+ settings.PROXY_EXCEPTIONS = StringUtil.nullize(myProxyExceptions.getText(), true);
+
+ settings.PROXY_PORT = myProxyPortTextField.getNumber();
+ settings.PROXY_HOST = getText(myProxyHostTextField);
+ }
+
+ @Nullable
+ private static String getText(@NotNull JTextField field) {
+ return StringUtil.nullize(field.getText(), true);
+ }
+
+ private void enableProxy(boolean enabled) {
+ myHostNameLabel.setEnabled(enabled);
+ myPortNumberLabel.setEnabled(enabled);
+ myProxyHostTextField.setEnabled(enabled);
+ myProxyPortTextField.setEnabled(enabled);
+ mySocks.setEnabled(enabled);
+ myHTTP.setEnabled(enabled);
+ myProxyExceptions.setEnabled(enabled);
+ myProxyExceptions.setBackground(myProxyPortTextField.getBackground());
+ myProxyExceptionsLabel.setEnabled(enabled);
+ myNoProxyForLabel.setEnabled(enabled);
+
+ myProxyAuthCheckBox.setEnabled(enabled);
+ enableProxyAuthentication(enabled && myProxyAuthCheckBox.isSelected());
+ myCheckButton.setEnabled(canEnableConnectionCheck());
+
+ final boolean autoDetectProxy = myAutoDetectProxyRb.isSelected();
+ myPacUrlCheckBox.setEnabled(autoDetectProxy);
+ myClearPasswordsButton.setEnabled(autoDetectProxy);
+ myPacUrlTextField.setEnabled(autoDetectProxy && myPacUrlCheckBox.isSelected());
+ }
+
+ private void enableProxyAuthentication(boolean enabled) {
+ myProxyPasswordLabel.setEnabled(enabled);
+ myProxyLoginLabel.setEnabled(enabled);
+
+ myProxyLoginTextField.setEnabled(enabled);
+ myProxyPasswordTextField.setEnabled(enabled);
+
+ myRememberProxyPasswordCheckBox.setEnabled(enabled);
+ }
+
+ @Override
+ @NotNull
+ public JComponent getComponent() {
+ return myMainPanel;
+ }
+}
diff --git a/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java b/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java
index f49eb983c3af..642125b275fa 100644
--- a/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java
+++ b/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.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.
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Ref;
import com.intellij.ui.GuiUtils;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -28,16 +29,9 @@ import javax.swing.*;
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;
-/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Nov 19, 2003
- * Time: 10:04:14 PM
- * To change this template use Options | File Templates.
- */
public class IOExceptionDialog extends DialogWrapper {
private static final Logger LOG = Logger.getInstance(IOExceptionDialog.class);
- private JTextArea myErrorLabel;
+ private final JTextArea myErrorLabel;
public IOExceptionDialog(String title, String errorText) {
super((Project)null, true);
@@ -65,8 +59,8 @@ public class IOExceptionDialog extends DialogWrapper {
return new Action[] {
new AbstractAction(CommonBundle.message("dialog.ioexception.proxy")) {
@Override
- public void actionPerformed(ActionEvent e) {
- new HTTPProxySettingsDialog().show();
+ public void actionPerformed(@NotNull ActionEvent e) {
+ HttpConfigurable.editConfigurable(ObjectUtils.tryCast(e.getSource(), JComponent.class));
}
}
};
@@ -79,14 +73,14 @@ public class IOExceptionDialog extends DialogWrapper {
public static boolean showErrorDialog(final String title, final String text) {
final Ref<Boolean> ok = Ref.create(false);
try {
- final Runnable doRun = new Runnable() {
+ GuiUtils.runOrInvokeAndWait(new Runnable() {
+ @Override
public void run() {
IOExceptionDialog dialog = new IOExceptionDialog(title, text);
dialog.show();
ok.set(dialog.isOK());
}
- };
- GuiUtils.runOrInvokeAndWait(doRun);
+ });
}
catch (InterruptedException e) {
LOG.info(e);
diff --git a/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java b/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java
index fedcb359b03d..b3a8fff57763 100644
--- a/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java
+++ b/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.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,6 +15,7 @@
*/
package com.intellij.util.net;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.proxy.CommonProxy;
@@ -23,12 +24,6 @@ import com.intellij.util.proxy.NonStaticAuthenticator;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 1/30/13
- * Time: 5:58 PM
- */
public class IdeaWideAuthenticator extends NonStaticAuthenticator {
private final static Logger LOG = Logger.getInstance("#com.intellij.util.net.IdeaWideAuthenticator");
private final HttpConfigurable myHttpConfigurable;
@@ -42,12 +37,14 @@ public class IdeaWideAuthenticator extends NonStaticAuthenticator {
final String host = CommonProxy.getHostNameReliably(getRequestingHost(), getRequestingSite(), getRequestingURL());
final boolean isProxy = Authenticator.RequestorType.PROXY.equals(getRequestorType());
final String prefix = isProxy ? "Proxy authentication: " : "Server authentication: ";
+ Application application = ApplicationManager.getApplication();
if (isProxy) {
// according to idea-wide settings
if (myHttpConfigurable.USE_HTTP_PROXY) {
LOG.debug("CommonAuthenticator.getPasswordAuthentication will return common defined proxy");
return myHttpConfigurable.getPromptedAuthentication(host + ":" + getRequestingPort(), getRequestingPrompt());
- } else if (myHttpConfigurable.USE_PROXY_PAC) {
+ }
+ else if (myHttpConfigurable.USE_PROXY_PAC) {
LOG.debug("CommonAuthenticator.getPasswordAuthentication will return autodetected proxy");
if (myHttpConfigurable.isGenericPasswordCanceled(host, getRequestingPort())) return null;
// same but without remembering the results..
@@ -56,16 +53,19 @@ public class IdeaWideAuthenticator extends NonStaticAuthenticator {
return password;
}
// do not try to show any dialogs if application is exiting
- if (ApplicationManager.getApplication() == null || ApplicationManager.getApplication().isDisposeInProgress() ||
- ApplicationManager.getApplication().isDisposed()) return null;
+ if (application == null || application.isDisposeInProgress() ||
+ application.isDisposed()) {
+ return null;
+ }
return myHttpConfigurable.getGenericPromptedAuthentication(prefix, host, getRequestingPrompt(), getRequestingPort(), true);
}
}
// do not try to show any dialogs if application is exiting
- if (ApplicationManager.getApplication() == null || ApplicationManager.getApplication().isDisposeInProgress() ||
- ApplicationManager.getApplication().isDisposed()) return null;
+ if (application == null || application.isDisposeInProgress() || application.isDisposed()) {
+ return null;
+ }
LOG.debug("CommonAuthenticator.getPasswordAuthentication generic authentication will be asked");
//return myHttpConfigurable.getGenericPromptedAuthentication(prefix, host, getRequestingPrompt(), getRequestingPort(), false);
diff --git a/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java b/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java
index df986ea946c4..62199b335425 100644
--- a/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java
+++ b/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java
@@ -17,7 +17,6 @@ package com.intellij.util.net;
import com.btr.proxy.search.ProxySearch;
import com.btr.proxy.selector.pac.PacProxySelector;
-import com.btr.proxy.selector.pac.PacScriptSource;
import com.btr.proxy.selector.pac.UrlPacScriptSource;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
@@ -77,8 +76,7 @@ public class IdeaWideProxySelector extends ProxySelector {
if (myHttpConfigurable.USE_PROXY_PAC) {
ProxySelector pacProxySelector = myPacProxySelector.get();
if (myHttpConfigurable.USE_PAC_URL && !StringUtil.isEmpty(myHttpConfigurable.PAC_URL)) {
- PacScriptSource pacSource = new UrlPacScriptSource(myHttpConfigurable.PAC_URL);
- myPacProxySelector.set(new PacProxySelector(pacSource));
+ myPacProxySelector.set(new PacProxySelector(new UrlPacScriptSource(myHttpConfigurable.PAC_URL)));
}
else if (pacProxySelector == null) {
ProxySearch proxySearch = ProxySearch.getDefaultProxySearch();
diff --git a/platform/platform-api/src/com/intellij/util/net/NetUtils.java b/platform/platform-api/src/com/intellij/util/net/NetUtils.java
index eb56e08e4d64..b01d4db1f1cb 100644
--- a/platform/platform-api/src/com/intellij/util/net/NetUtils.java
+++ b/platform/platform-api/src/com/intellij/util/net/NetUtils.java
@@ -66,7 +66,7 @@ public class NetUtils {
}
public static boolean isLocalhost(@NotNull String host) {
- return host.equalsIgnoreCase("localhost") || host.equals("127.0.0.1");
+ return host.equalsIgnoreCase("localhost") || host.equals("127.0.0.1") || host.equals("::1");
}
private static boolean canBindToLocalSocket(String host, int port) {
diff --git a/platform/platform-api/src/com/intellij/util/proxy/CommonProxy.java b/platform/platform-api/src/com/intellij/util/proxy/CommonProxy.java
index eff28a5fbd1e..4aa63cd39f01 100644
--- a/platform/platform-api/src/com/intellij/util/proxy/CommonProxy.java
+++ b/platform/platform-api/src/com/intellij/util/proxy/CommonProxy.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,8 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.net.NetUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,12 +33,6 @@ import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 1/21/13
- * Time: 12:39 PM
- */
public class CommonProxy extends ProxySelector {
private final static CommonProxy ourInstance = new CommonProxy();
private final CommonAuthenticator myAuthenticator;
@@ -212,14 +208,12 @@ public class CommonProxy extends ProxySelector {
}
try {
ourReenterDefence.set(Boolean.TRUE);
- final String host = uri.getHost() == null ? "" : uri.getHost();
- final int port = correctPortByProtocol(uri);
- final String protocol = uri.getScheme();
- if ("localhost".equals(host) || "127.0.0.1".equals(host) || "::1".equals(host)) {
+ String host = StringUtil.notNullize(uri.getHost());
+ if (NetUtils.isLocalhost(host)) {
return NO_PROXY_LIST;
}
- final HostInfo info = new HostInfo(protocol, host, port);
+ final HostInfo info = new HostInfo(uri.getScheme(), host, correctPortByProtocol(uri));
final Map<String, ProxySelector> copy;
synchronized (myLock) {
if (myNoProxy.contains(Pair.create(info, Thread.currentThread()))) {
@@ -230,18 +224,19 @@ public class CommonProxy extends ProxySelector {
}
for (Map.Entry<String, ProxySelector> entry : copy.entrySet()) {
final List<Proxy> proxies = entry.getValue().select(uri);
- if (proxies != null && proxies.size() > 0) {
+ if (!ContainerUtil.isEmpty(proxies)) {
LOG.debug("CommonProxy.select returns custom proxy for " + uri.toString() + ", " + proxies.toString());
return proxies;
}
}
return NO_PROXY_LIST;
- } finally {
+ }
+ finally {
ourReenterDefence.remove();
}
}
- private int correctPortByProtocol(@NotNull URI uri) {
+ private static int correctPortByProtocol(@NotNull URI uri) {
if (uri.getPort() == -1) {
if ("http".equals(uri.getScheme())) {
return ProtocolDefaultPorts.HTTP;
@@ -330,7 +325,8 @@ public class CommonProxy extends ProxySelector {
if (host == null) {
if (site != null) {
host = site.getHostName();
- } else if (requestingUrl != null) {
+ }
+ else if (requestingUrl != null) {
host = requestingUrl.getHost();
}
}
@@ -351,7 +347,7 @@ public class CommonProxy extends ProxySelector {
public HostInfo() {
}
- public HostInfo(String protocol, @NotNull String host, int port) {
+ public HostInfo(@Nullable String protocol, @NotNull String host, int port) {
myPort = port;
myHost = host;
myProtocol = protocol;
@@ -371,16 +367,15 @@ public class CommonProxy extends ProxySelector {
@Override
public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
HostInfo info = (HostInfo)o;
-
- if (myPort != info.myPort) return false;
- if (!myHost.equals(info.myHost)) return false;
- if (myProtocol != null ? !myProtocol.equals(info.myProtocol) : info.myProtocol != null) return false;
-
- return true;
+ return myPort == info.myPort && myHost.equals(info.myHost) && Comparing.equal(myProtocol, info.myProtocol);
}
@Override
diff --git a/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java b/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java
index d73e21e8dc3a..b11ca7f3222f 100644
--- a/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java
+++ b/platform/platform-api/src/com/intellij/util/ui/ButtonlessScrollBarUI.java
@@ -223,10 +223,10 @@ public class ButtonlessScrollBarUI extends BasicScrollBarUI {
}
public int getDecrementButtonHeight() {
- return decrButton.getHeight();
+ return Math.max(0, decrButton.getHeight());
}
public int getIncrementButtonHeight() {
- return incrButton.getHeight();
+ return Math.max(0, incrButton.getHeight());
}
private void resetRegularThumbAnimator() {
@@ -276,6 +276,16 @@ public class ButtonlessScrollBarUI extends BasicScrollBarUI {
return new ButtonlessScrollBarUI();
}
+
+ public static BasicScrollBarUI createTransparent() {
+ return new ButtonlessScrollBarUI() {
+ @Override
+ public boolean alwaysShowTrack() {
+ return false;
+ }
+ };
+ }
+
@Override
public void installUI(JComponent c) {
super.installUI(c);
diff --git a/platform/platform-api/src/com/intellij/util/ui/StatusText.java b/platform/platform-api/src/com/intellij/util/ui/StatusText.java
index 60f8c5c6cbc1..479b968d4317 100644
--- a/platform/platform-api/src/com/intellij/util/ui/StatusText.java
+++ b/platform/platform-api/src/com/intellij/util/ui/StatusText.java
@@ -186,7 +186,8 @@ public abstract class StatusText {
}
public void paint(Component owner, Graphics g) {
- if (!isStatusVisible() || owner != myOwner) return;
+ boolean wrongComponent = owner != myOwner && owner != null && owner.getParent() != myOwner;
+ if (!isStatusVisible() || wrongComponent) return;
Rectangle b = getTextComponentBound();
myComponent.setBounds(0, 0, b.width, b.height);
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java
index 7d5688c9d1d8..3f865dd19abd 100644
--- a/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.java
+++ b/platform/platform-impl/src/com/intellij/diagnostic/ErrorReportConfigurable.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.
@@ -21,17 +21,11 @@ import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
-import org.apache.commons.codec.binary.Base64;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.util.Base64;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
-/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Aug 11, 2003
- * Time: 8:59:04 PM
- * To change this template use Options | File Templates.
- */
public class ErrorReportConfigurable implements JDOMExternalizable, NamedComponent {
public String ITN_LOGIN = "";
public String ITN_PASSWORD_CRYPT = "";
@@ -43,31 +37,36 @@ public class ErrorReportConfigurable implements JDOMExternalizable, NamedCompone
return ServiceManager.getService(ErrorReportConfigurable.class);
}
+ @Override
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
- if (! KEEP_ITN_PASSWORD)
+ if (!KEEP_ITN_PASSWORD) {
ITN_PASSWORD_CRYPT = "";
+ }
}
+ @Override
public void writeExternal(Element element) throws WriteExternalException {
String itnPassword = ITN_PASSWORD_CRYPT;
- if (! KEEP_ITN_PASSWORD)
+ if (!KEEP_ITN_PASSWORD) {
ITN_PASSWORD_CRYPT = "";
+ }
DefaultJDOMExternalizer.writeExternal(this, element);
ITN_PASSWORD_CRYPT = itnPassword;
}
+ @Override
@NotNull
public String getComponentName() {
return "ErrorReportConfigurable";
}
- public String getPlainItnPassword () {
- return new String(new Base64().decode(ErrorReportConfigurable.getInstance().ITN_PASSWORD_CRYPT.getBytes()));
+ public String getPlainItnPassword() {
+ return new String(Base64.decode(getInstance().ITN_PASSWORD_CRYPT), CharsetToolkit.UTF8_CHARSET);
}
- public void setPlainItnPassword (String password) {
- ITN_PASSWORD_CRYPT = new String(new Base64().encode(password.getBytes()));
+ public void setPlainItnPassword(String password) {
+ ITN_PASSWORD_CRYPT = Base64.encode(password.getBytes(CharsetToolkit.UTF8_CHARSET));
}
}
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java
index 092c346d40b7..fb34ba2342cf 100644
--- a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java
+++ b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.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,32 +19,25 @@ import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.ClickListener;
-import com.intellij.util.net.HTTPProxySettingsDialog;
+import com.intellij.util.net.HttpConfigurable;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
-/**
- * Created by IntelliJ IDEA.
- * User: stathik
- * Date: Aug 8, 2003
- * Time: 3:49:50 PM
- * To change this template use Options | File Templates.
- */
public class JetBrainsAccountDialog extends DialogWrapper {
private JTextField myItnLoginTextField;
private JPasswordField myItnPasswordTextField;
private JCheckBox myRememberITNPasswordCheckBox;
- public void storeInfo () {
+ public void storeInfo() {
ErrorReportConfigurable.getInstance().ITN_LOGIN = myItnLoginTextField.getText();
ErrorReportConfigurable.getInstance().setPlainItnPassword(new String(myItnPasswordTextField.getPassword()));
ErrorReportConfigurable.getInstance().KEEP_ITN_PASSWORD = myRememberITNPasswordCheckBox.isSelected();
}
- public void loadInfo () {
+ public void loadInfo() {
myItnLoginTextField.setText(ErrorReportConfigurable.getInstance().ITN_LOGIN);
myItnPasswordTextField.setText(ErrorReportConfigurable.getInstance().getPlainItnPassword());
myRememberITNPasswordCheckBox.setSelected(ErrorReportConfigurable.getInstance().KEEP_ITN_PASSWORD);
@@ -64,6 +57,7 @@ public class JetBrainsAccountDialog extends DialogWrapper {
protected JLabel mySendingSettingsLabel;
private JLabel myCreateAccountLabel;
+ @Override
protected String getDimensionServiceKey() {
return "#com.intellij.diagnostic.AbstractSendErrorDialog";
}
@@ -73,6 +67,7 @@ public class JetBrainsAccountDialog extends DialogWrapper {
return myItnLoginTextField;
}
+ @Override
protected void init() {
setTitle(ReportMessages.ERROR_REPORT);
getContentPane().add(myMainPanel);
@@ -80,14 +75,12 @@ public class JetBrainsAccountDialog extends DialogWrapper {
new ClickListener() {
@Override
public boolean onClick(@NotNull MouseEvent e, int clickCount) {
- HTTPProxySettingsDialog settingsDialog = new HTTPProxySettingsDialog ();
- settingsDialog.pack();
- settingsDialog.show();
+ HttpConfigurable.editConfigurable(myMainPanel);
return true;
}
}.installOn(mySendingSettingsLabel);
- mySendingSettingsLabel.setCursor(new Cursor (Cursor.HAND_CURSOR));
+ mySendingSettingsLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
loadInfo();
@@ -98,9 +91,9 @@ public class JetBrainsAccountDialog extends DialogWrapper {
return true;
}
}.installOn(myCreateAccountLabel);
- myCreateAccountLabel.setCursor(new Cursor (Cursor.HAND_CURSOR));
+ myCreateAccountLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
- super.init ();
+ super.init();
}
@Override
@@ -109,6 +102,7 @@ public class JetBrainsAccountDialog extends DialogWrapper {
super.doOKAction();
}
+ @Override
protected JComponent createCenterPanel() {
return myMainPanel;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java b/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java
index 0aeb20dbda90..c288150bd7ab 100644
--- a/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.java
+++ b/platform/platform-impl/src/com/intellij/ide/CommandLineProcessor.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.
@@ -137,7 +137,9 @@ public class CommandLineProcessor {
if (args.size() > 0) {
String command = args.get(0);
for(ApplicationStarter starter: Extensions.getExtensions(ApplicationStarter.EP_NAME)) {
- if (starter instanceof ApplicationStarterEx && command.equals(starter.getCommandName())) {
+ if (command.equals(starter.getCommandName()) &&
+ starter instanceof ApplicationStarterEx &&
+ ((ApplicationStarterEx)starter).canProcessExternalCommandLine()) {
LOG.info("Processing command with " + starter);
((ApplicationStarterEx) starter).processExternalCommandLine(ArrayUtil.toStringArray(args));
return null;
diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
index a7d07c9fa1e8..23491c2bdd6a 100644
--- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
+++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
@@ -130,9 +130,9 @@ public class IdeEventQueue extends EventQueue {
private final Set<EventDispatcher> myDispatchers = new LinkedHashSet<EventDispatcher>();
- private final Set<EventDispatcher> myPostprocessors = new LinkedHashSet<EventDispatcher>();
-
+ private final Set<EventDispatcher> myPostProcessors = new LinkedHashSet<EventDispatcher>();
private final Set<Runnable> myReady = new HashSet<Runnable>();
+
private boolean myKeyboardBusy;
private boolean myDispatchingFocusEvent;
@@ -148,16 +148,14 @@ public class IdeEventQueue extends EventQueue {
private IdeEventQueue() {
addIdleTimeCounterRequest();
- final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- //noinspection HardCodedStringLiteral
+ final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
keyboardFocusManager.addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() {
@Override
public void propertyChange(final PropertyChangeEvent e) {
final Application application = ApplicationManager.getApplication();
if (application == null) {
-
// We can get focus event before application is initialized
return;
}
@@ -171,6 +169,12 @@ public class IdeEventQueue extends EventQueue {
});
addDispatcher(new WindowsAltSupressor(), null);
+
+ Application app = ApplicationManager.getApplication();
+ if (app != null && app.isUnitTestMode()) {
+ //noinspection AssignmentToStaticFieldFromInstanceMethod
+ ourAppIsLoaded = true;
+ }
}
@@ -289,11 +293,11 @@ public class IdeEventQueue extends EventQueue {
}
public void addPostprocessor(EventDispatcher dispatcher, @Nullable Disposable parent) {
- _addProcessor(dispatcher, parent, myPostprocessors);
+ _addProcessor(dispatcher, parent, myPostProcessors);
}
public void removePostprocessor(EventDispatcher dispatcher) {
- myPostprocessors.remove(dispatcher);
+ myPostProcessors.remove(dispatcher);
}
private static void _addProcessor(final EventDispatcher dispatcher, Disposable parent, final Set<EventDispatcher> set) {
@@ -344,8 +348,26 @@ public class IdeEventQueue extends EventQueue {
}
}
+ private static boolean ourAppIsLoaded = false;
+
+ private static boolean appIsLoaded() {
+ if (ourAppIsLoaded) return true;
+ boolean loaded = IdeaApplication.isLoaded();
+ if (loaded) ourAppIsLoaded = true;
+ return loaded;
+ }
+
@Override
public void dispatchEvent(AWTEvent e) {
+ if (!appIsLoaded()) {
+ try {
+ super.dispatchEvent(e);
+ }
+ catch (Throwable t) {
+ processException(t);
+ }
+ return;
+ }
fixNonEnglishKeyboardLayouts(e);
@@ -362,15 +384,13 @@ public class IdeEventQueue extends EventQueue {
_dispatchEvent(e, false);
}
catch (Throwable t) {
- if (!myToolkitBugsProcessor.process(t)) {
- PluginManager.processException(t);
- }
+ processException(t);
}
finally {
myIsInInputEvent = wasInputEvent;
myCurrentEvent = oldEvent;
- for (EventDispatcher each : myPostprocessors) {
+ for (EventDispatcher each : myPostProcessors) {
each.dispatch(e);
}
@@ -380,6 +400,12 @@ public class IdeEventQueue extends EventQueue {
}
}
+ private void processException(Throwable t) {
+ if (!myToolkitBugsProcessor.process(t)) {
+ PluginManager.processException(t);
+ }
+ }
+
private static void fixNonEnglishKeyboardLayouts(AWTEvent e) {
if (!Registry.is("ide.non.english.keyboard.layout.fix")) return;
if (e instanceof KeyEvent) {
@@ -722,9 +748,7 @@ public class IdeEventQueue extends EventQueue {
super.dispatchEvent(e);
}
catch (Throwable t) {
- if (!myToolkitBugsProcessor.process(t)) {
- PluginManager.processException(t);
- }
+ processException(t);
}
finally {
myDispatchingFocusEvent = false;
@@ -760,7 +784,7 @@ public class IdeEventQueue extends EventQueue {
}
private static boolean typeAheadDispatchToFocusManager(AWTEvent e) {
- if (e instanceof KeyEvent && appIsLoaded()) {
+ if (e instanceof KeyEvent) {
final KeyEvent event = (KeyEvent)e;
if (!event.isConsumed()) {
final IdeFocusManager focusManager = IdeFocusManager.findInstanceByComponent(event.getComponent());
@@ -771,15 +795,6 @@ public class IdeEventQueue extends EventQueue {
return false;
}
- private static boolean ourAppIsLoaded = false;
-
- private static boolean appIsLoaded() {
- if (ourAppIsLoaded) return true;
- boolean loaded = IdeaApplication.isLoaded();
- if (loaded) ourAppIsLoaded = true;
- return loaded;
- }
-
public void flushQueue() {
while (true) {
AWTEvent event = peekEvent();
diff --git a/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java b/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
index d7118949e5de..4a0e11bf5ff9 100644
--- a/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/IdeRepaintManager.java
@@ -128,19 +128,23 @@ public class IdeRepaintManager extends RepaintManager {
final Exception exception = new Exception();
StackTraceElement[] stackTrace = exception.getStackTrace();
for (StackTraceElement st : stackTrace) {
- if (repaint && st.getClassName().startsWith("javax.swing.")) {
+ String className = st.getClassName();
+ String methodName = st.getMethodName();
+
+ if (repaint && className.startsWith("javax.swing.")) {
fromSwing = true;
}
- if (repaint && "imageUpdate".equals(st.getMethodName())) {
+ if (repaint && "imageUpdate".equals(methodName)) {
swingKnownNonAwtOperations = true;
}
- if (st.getClassName().startsWith("javax.swing.JEditorPane") && st.getMethodName().equals("read")) {
+ if ("read".equals(methodName) && className.startsWith("javax.swing.JEditorPane") ||
+ "setCharacterAttributes".equals(methodName) && className.startsWith("javax.swing.text.DefaultStyledDocument")) {
swingKnownNonAwtOperations = true;
break;
}
- if ("repaint".equals(st.getMethodName())) {
+ if ("repaint".equals(methodName)) {
repaint = true;
fromSwing = false;
}
diff --git a/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java b/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java
index c25c68b4bb2b..e9de64905415 100644
--- a/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/UiActivityMonitorImpl.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,7 +16,6 @@
package com.intellij.ide;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ModalityStateListener;
@@ -24,7 +23,6 @@ import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.BusyObject;
import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.containers.FactoryMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -34,16 +32,16 @@ import javax.swing.*;
import java.util.*;
public class UiActivityMonitorImpl extends UiActivityMonitor implements ModalityStateListener, Disposable {
-
private final FactoryMap<Project, BusyContainer> myObjects = new FactoryMap<Project, BusyContainer>() {
@Override
protected BusyContainer create(Project key) {
if (isEmpty()) {
installListener();
}
- return key == null ? new BusyContainer(key) : new BusyContainer(null) {
+ return key == null ? new BusyContainer(null) : new BusyContainer(null) {
+ @NotNull
@Override
- protected BusyImpl createBusyImpl(HashSet<UiActivity> key) {
+ protected BusyImpl createBusyImpl(@NotNull Set<UiActivity> key) {
return new BusyImpl(key, this) {
@Override
public boolean isReady() {
@@ -63,7 +61,8 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
private boolean myActive;
- private BusyObject myEmptyBusy = new BusyObject.Impl() {
+ @NotNull
+ private final BusyObject myEmptyBusy = new BusyObject.Impl() {
@Override
public boolean isReady() {
return true;
@@ -84,17 +83,12 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
@Override
public void beforeModalityStateChanged(boolean entering) {
- if (isUnitTestMode()) {
- maybeReady();
- }
- else {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- maybeReady();
- }
- });
- }
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ maybeReady();
+ }
+ });
}
public void maybeReady() {
@@ -103,15 +97,17 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
}
+ @NotNull
@Override
- public BusyObject getBusy(@NotNull Project project, UiActivity... toWatch) {
+ public BusyObject getBusy(@NotNull Project project, @NotNull UiActivity... toWatch) {
if (!isActive()) return myEmptyBusy;
return _getBusy(project, toWatch);
}
+ @NotNull
@Override
- public BusyObject getBusy(UiActivity... toWatch) {
+ public BusyObject getBusy(@NotNull UiActivity... toWatch) {
if (!isActive()) return myEmptyBusy;
return _getBusy(null, toWatch);
@@ -129,10 +125,10 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
- getBusyContainer(project).addActivity(activity, allocation, effectiveModalityState);
+ public void run() {
+ getBusyContainer(project).addActivity(activity, effectiveModalityState);
}
});
}
@@ -141,9 +137,9 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void removeActivity(@NotNull final Project project, @NotNull final UiActivity activity) {
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
+ public void run() {
_getBusy(project).removeActivity(activity);
}
});
@@ -162,10 +158,10 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void addActivity(@NotNull final UiActivity activity, @NotNull final ModalityState effectiveModalityState) {
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
- getBusyContainer(null).addActivity(activity, allocation, effectiveModalityState);
+ public void run() {
+ getBusyContainer(null).addActivity(activity, effectiveModalityState);
}
});
}
@@ -174,15 +170,16 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void removeActivity(@NotNull final UiActivity activity) {
if (!isActive()) return;
- invokeLaterIfNeeded(new MyRunnable() {
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
- public void run(Throwable allocation) {
+ public void run() {
_getBusy(null).removeActivity(activity);
}
});
}
- private BusyImpl _getBusy(@Nullable Project key, UiActivity... toWatch) {
+ @NotNull
+ private BusyImpl _getBusy(@Nullable Project key, @NotNull UiActivity... toWatch) {
return getBusyContainer(key).getOrCreateBusy(toWatch);
}
@@ -204,6 +201,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
return myObjects.get(null);
}
+ @Override
public void clear() {
final Set<Project> keys = myObjects.keySet();
for (Project each : keys) {
@@ -215,7 +213,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
public void setActive(boolean active) {
if (myActive == active) return;
- if (myActive && !active) {
+ if (myActive) {
clear();
}
@@ -227,25 +225,19 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
private static class ActivityInfo {
- private final Throwable myAllocation;
private final ModalityState myEffectiveState;
- private ActivityInfo(@Nullable Throwable allocation, @NotNull ModalityState effectiveState) {
- myAllocation = allocation;
+ private ActivityInfo(@NotNull ModalityState effectiveState) {
myEffectiveState = effectiveState;
}
- @Nullable
- public Throwable getAllocation() {
- return myAllocation;
- }
-
@NotNull
public ModalityState getEffectiveState() {
return myEffectiveState;
}
}
+ @NotNull
protected ModalityState getCurrentState() {
return ModalityState.current();
}
@@ -258,9 +250,9 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
protected final Set<UiActivity> myToWatch;
protected final UiActivity[] myToWatchArray;
- private UiActivityMonitorImpl.BusyContainer myContainer;
+ private final UiActivityMonitorImpl.BusyContainer myContainer;
- private BusyImpl(Set<UiActivity> toWatch, BusyContainer container) {
+ private BusyImpl(@NotNull Set<UiActivity> toWatch, @NotNull BusyContainer container) {
myToWatch = toWatch;
myToWatchArray = toWatch.toArray(new UiActivity[toWatch.size()]);
myContainer = container;
@@ -274,9 +266,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
boolean isOwnReady() {
Map<UiActivity, ActivityInfo> infoToCheck = new HashMap<UiActivity, ActivityInfo>();
- final Iterator<Set<UiActivity>> activitySets = myContainer.myActivities2Object.keySet().iterator();
- while (activitySets.hasNext()) {
- Set<UiActivity> eachActivitySet = activitySets.next();
+ for (Set<UiActivity> eachActivitySet : myContainer.myActivities2Object.keySet()) {
final BusyImpl eachBusyObject = myContainer.myActivities2Object.get(eachActivitySet);
if (eachBusyObject == this) continue;
@@ -304,19 +294,16 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
return true;
}
+ public void addActivity(@NotNull UiActivity activity, @NotNull ModalityState effectiveModalityState) {
+ if (!myToWatch.isEmpty() && !myToWatch.contains(activity)) return;
- public void addActivity(UiActivity activity, Throwable allocation, ModalityState effectiveModalityState) {
- if (!myToWatch.isEmpty()) {
- if (!myToWatch.contains(activity)) return;
- }
-
- myActivities.put(activity, new ActivityInfo(allocation, effectiveModalityState));
+ myActivities.put(activity, new ActivityInfo(effectiveModalityState));
myQueuedToRemove.remove(activity);
- myContainer.onActivityAdded(this, activity);
+ myContainer.onActivityAdded(activity);
}
- public void removeActivity(final UiActivity activity) {
+ public void removeActivity(@NotNull final UiActivity activity) {
if (!myActivities.containsKey(activity)) return;
myQueuedToRemove.add(activity);
@@ -333,87 +320,48 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
onReady();
}
};
- if (isUnitTestMode()) {
- runnable.run();
- }
- else {
- SwingUtilities.invokeLater(runnable);
- }
+ SwingUtilities.invokeLater(runnable);
}
-
- public void clear() {
- UiActivity[] activities = myActivities.keySet().toArray(new UiActivity[myActivities.size()]);
- for (UiActivity each : activities) {
- removeActivity(each);
- }
- }
- }
-
- private static void invokeLaterIfNeeded(final MyRunnable runnable) {
- final Throwable allocation = Registry.is("ide.debugMode") ? new Exception() : null;
-
- if (isUnitTestMode()) {
- runnable.run(allocation);
- }
- else {
- UIUtil.invokeLaterIfNeeded(new Runnable() {
- @Override
- public void run() {
- runnable.run(allocation);
- }
- });
- }
- }
-
- private interface MyRunnable {
- void run(Throwable allocation);
- }
-
- private static boolean isUnitTestMode() {
- Application app = ApplicationManager.getApplication();
- return app == null || app.isUnitTestMode();
}
public class BusyContainer implements Disposable {
+ private final Map<Set<UiActivity>, BusyImpl> myActivities2Object = new HashMap<Set<UiActivity>, BusyImpl>();
+ private final Map<BusyImpl, Set<UiActivity>> myObject2Activities = new HashMap<BusyImpl, Set<UiActivity>>();
- private Map<Set<UiActivity>, BusyImpl> myActivities2Object = new HashMap<Set<UiActivity>, BusyImpl>();
- private Map<BusyImpl, Set<UiActivity>> myObject2Activities = new HashMap<BusyImpl, Set<UiActivity>>();
-
- private Set<UiActivity> myActivities = new HashSet<UiActivity>();
-
- private BusyImpl myDefault;
+ private final Set<UiActivity> myActivities = new HashSet<UiActivity>();
private boolean myRemovingActivityNow;
@Nullable private final Project myProject;
public BusyContainer(@Nullable Project project) {
myProject = project;
- myDefault = registerBusyObject(new HashSet<UiActivity>());
+ registerBusyObject(new HashSet<UiActivity>());
if (project != null) {
Disposer.register(project, this);
}
}
- public BusyImpl getOrCreateBusy(UiActivity... activities) {
- final HashSet<UiActivity> key = new HashSet<UiActivity>();
+ @NotNull
+ public BusyImpl getOrCreateBusy(@NotNull UiActivity... activities) {
+ Set<UiActivity> key = new HashSet<UiActivity>();
key.addAll(Arrays.asList(activities));
if (myActivities2Object.containsKey(key)) {
return myActivities2Object.get(key);
}
- else {
- return registerBusyObject(key);
- }
+ return registerBusyObject(key);
}
- private BusyImpl registerBusyObject(HashSet<UiActivity> key) {
+ @NotNull
+ private BusyImpl registerBusyObject(@NotNull Set<UiActivity> key) {
final BusyImpl busy = createBusyImpl(key);
myActivities2Object.put(key, busy);
myObject2Activities.put(busy, key);
return busy;
}
- protected BusyImpl createBusyImpl(HashSet<UiActivity> key) {
+ @NotNull
+ protected BusyImpl createBusyImpl(@NotNull Set<UiActivity> key) {
return new BusyImpl(key, this);
}
@@ -437,11 +385,11 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
}
- public void onActivityAdded(BusyImpl busy, UiActivity activity) {
+ public void onActivityAdded(@NotNull UiActivity activity) {
myActivities.add(activity);
}
- public void onActivityRemoved(BusyImpl busy, UiActivity activity) {
+ public void onActivityRemoved(@NotNull BusyImpl busy, @NotNull UiActivity activity) {
if (myRemovingActivityNow) return;
final Map<BusyImpl, Set<UiActivity>> toRemove = new HashMap<BusyImpl, Set<UiActivity>>();
@@ -450,9 +398,7 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
myRemovingActivityNow = true;
myActivities.remove(activity);
- final Iterator<BusyImpl> objects = myObject2Activities.keySet().iterator();
- while (objects.hasNext()) {
- BusyImpl each = objects.next();
+ for (BusyImpl each : myObject2Activities.keySet()) {
if (each != busy) {
each.removeActivity(activity);
}
@@ -472,11 +418,11 @@ public class UiActivityMonitorImpl extends UiActivityMonitor implements Modality
}
}
- public void addActivity(UiActivity activity, Throwable allocation, ModalityState state) {
+ public void addActivity(@NotNull UiActivity activity, @NotNull ModalityState state) {
getOrCreateBusy(activity);
final Set<BusyImpl> busies = myObject2Activities.keySet();
for (BusyImpl each : busies) {
- each.addActivity(activity, allocation, state);
+ each.addActivity(activity, state);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java
deleted file mode 100644
index 8b2c9acfaef5..000000000000
--- a/platform/platform-impl/src/com/intellij/ide/actionMacro/EditMacrosDialog.java
+++ /dev/null
@@ -1,37 +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.actionMacro;
-
-import com.intellij.openapi.options.ex.SingleConfigurableEditor;
-import com.intellij.openapi.project.Project;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Created by IntelliJ IDEA.
- * User: max
- * Date: Jul 22, 2003
- * Time: 3:30:56 PM
- * To change this template use Options | File Templates.
- */
-public class EditMacrosDialog extends SingleConfigurableEditor {
- public EditMacrosDialog(@Nullable Project project) {
- super(project, new ActionMacroConfigurable());
- }
-
- protected String getDimensionServiceKey(){
- return "#com.intellij.ide.actionMacro.EditMacrosDialog";
- }
-}
diff --git a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java
index cb0d0ffd4619..c46241d1c4d9 100644
--- a/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actionMacro/actions/EditMacrosAction.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.
@@ -16,29 +16,22 @@
package com.intellij.ide.actionMacro.actions;
import com.intellij.ide.actionMacro.ActionMacro;
+import com.intellij.ide.actionMacro.ActionMacroConfigurable;
import com.intellij.ide.actionMacro.ActionMacroManager;
-import com.intellij.ide.actionMacro.EditMacrosDialog;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.DumbAware;
-/**
- * Created by IntelliJ IDEA.
- * User: max
- * Date: Jul 22, 2003
- * Time: 3:33:04 PM
- * To change this template use Options | File Templates.
- */
public class EditMacrosAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(AnActionEvent e) {
- EditMacrosDialog dialog = new EditMacrosDialog(CommonDataKeys.PROJECT.getData(e.getDataContext()));
- dialog.show();
+ ShowSettingsUtil.getInstance().editConfigurable(e.getProject(), "#com.intellij.ide.actionMacro.EditMacrosDialog", new ActionMacroConfigurable());
}
+ @Override
public void update(AnActionEvent e) {
- final ActionMacroManager manager = ActionMacroManager.getInstance();
- ActionMacro[] macros = manager.getAllMacros();
+ ActionMacro[] macros = ActionMacroManager.getInstance().getAllMacros();
e.getPresentation().setEnabled(macros != null && macros.length > 0);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java b/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java
index 1c7855d2eedb..709c3b458112 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/BaseNavigateToSourceAction.java
@@ -19,7 +19,9 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbAware;
import com.intellij.pom.Navigatable;
import com.intellij.pom.NavigatableWithText;
+import com.intellij.pom.PomTargetPsiElement;
import com.intellij.util.OpenSourceUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class BaseNavigateToSourceAction extends AnAction implements DumbAware {
@@ -37,7 +39,7 @@ public abstract class BaseNavigateToSourceAction extends AnAction implements Dum
public void update(AnActionEvent event) {
DataContext dataContext = event.getDataContext();
- final Navigatable target = getTarget(dataContext);
+ final Navigatable target = findTargetForUpdate(dataContext);
boolean enabled = target != null;
if (ActionPlaces.isPopupPlace(event.getPlace())) {
event.getPresentation().setVisible(enabled);
@@ -49,36 +51,21 @@ public abstract class BaseNavigateToSourceAction extends AnAction implements Dum
else {
event.getPresentation().setEnabled(enabled);
}
- if (target != null && target instanceof NavigatableWithText) {
- //as myFocusEditor is always ignored - Main Menu|View always contains 2 actions with the same name and actually same behaviour
- if (!myFocusEditor) {
- event.getPresentation().setVisible(false);
- return;
- }
- final String navigateActionText = ((NavigatableWithText)target).getNavigateActionText(myFocusEditor);
- if (navigateActionText != null) {
- event.getPresentation().setText(navigateActionText);
- }
- else {
- event.getPresentation().setText(getTemplatePresentation().getText());
- }
- }
- else {
- event.getPresentation().setText(getTemplatePresentation().getText());
- }
+ //as myFocusEditor is always ignored - Main Menu|View always contains 2 actions with the same name and actually same behaviour
+ event.getPresentation().setVisible(target == null || myFocusEditor);
+ String navigateActionText = myFocusEditor && target instanceof NavigatableWithText?
+ ((NavigatableWithText)target).getNavigateActionText(true) : null;
+ event.getPresentation().setText(navigateActionText == null ? getTemplatePresentation().getText() : navigateActionText);
}
@Nullable
- private Navigatable getTarget(final DataContext dataContext) {
- if (!myFocusEditor && CommonDataKeys.EDITOR.getData(dataContext) != null) {
- // makes no sense in editor and conflicts with another action there (ctrl+enter)
- return null;
- }
-
+ private Navigatable findTargetForUpdate(@NotNull DataContext dataContext) {
Navigatable[] navigatables = getNavigatables(dataContext);
- if (navigatables != null) {
- for (Navigatable navigatable : navigatables) {
- if (navigatable.canNavigate()) return navigatable;
+ if (navigatables == null) return null;
+
+ for (Navigatable navigatable : navigatables) {
+ if (navigatable.canNavigate()) {
+ return navigatable instanceof PomTargetPsiElement ? ((PomTargetPsiElement)navigatable).getTarget() : navigatable;
}
}
return null;
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
index 9bdc5948cffe..136f4b166e1a 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateDesktopEntryAction.java
@@ -23,6 +23,7 @@ import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -104,11 +105,15 @@ public class CreateDesktopEntryAction extends DumbAwareAction {
final String message = ApplicationBundle.message("desktop.entry.success",
ApplicationNamesInfo.getInstance().getProductName());
- Notifications.Bus.notify(
- new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Desktop entry created", message, NotificationType.INFORMATION)
- );
+ if (ApplicationManager.getApplication() != null) {
+ Notifications.Bus
+ .notify(new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Desktop entry created", message, NotificationType.INFORMATION));
+ }
}
catch (Exception e) {
+ if (ApplicationManager.getApplication() == null) {
+ throw new RuntimeException(e);
+ }
final String message = e.getMessage();
if (!StringUtil.isEmptyOrSpaces(message)) {
LOG.warn(e);
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java b/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
index 4cabfe9b5fe9..37b09394dd89 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/OpenFileAction.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.
@@ -19,14 +19,14 @@ import com.intellij.ide.IdeBundle;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.fileChooser.FileElement;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.PathChooserDialog;
import com.intellij.openapi.fileChooser.impl.FileChooserUtil;
import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.FileEditorProvider;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
import com.intellij.openapi.fileTypes.FileType;
@@ -34,7 +34,6 @@ import com.intellij.openapi.fileTypes.ex.FileTypeChooser;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -47,54 +46,20 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
public class OpenFileAction extends AnAction implements DumbAware {
+ @Override
public void actionPerformed(AnActionEvent e) {
- @Nullable final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
+ final Project project = e.getProject();
final boolean showFiles = project != null || PlatformProjectOpenProcessor.getInstanceIfItExists() != null;
+ final FileChooserDescriptor descriptor = showFiles ? new ProjectOrFileChooserDescriptor() : new ProjectOnlyFileChooserDescriptor();
+ descriptor.putUserData(PathChooserDialog.PREFER_LAST_OVER_EXPLICIT, showFiles);
- final FileChooserDescriptor descriptor = new OpenProjectFileChooserDescriptor(true) {
- @Override
- public boolean isFileSelectable(VirtualFile file) {
- if (super.isFileSelectable(file)) {
- return true;
- }
- if (file.isDirectory()) {
- return false;
- }
- return showFiles && !FileElement.isArchive(file);
- }
-
- @Override
- public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
- if (!file.isDirectory() && isFileSelectable(file)) {
- if (!showHiddenFiles && FileElement.isFileHidden(file)) return false;
- return true;
- }
- return super.isFileVisible(file, showHiddenFiles);
- }
-
- @Override
- public boolean isChooseMultiple() {
- return showFiles;
- }
- };
- descriptor.setTitle(showFiles ? "Open File or Project" : "Open Project");
-
- VirtualFile userHomeDir = null;
- if (SystemInfo.isUnix) {
- userHomeDir = VfsUtil.getUserHomeDir();
- }
-
- descriptor.putUserData(PathChooserDialog.PREFER_LAST_OVER_EXPLICIT, Boolean.TRUE);
-
- FileChooser.chooseFiles(descriptor, project, userHomeDir, new Consumer<List<VirtualFile>>() {
+ FileChooser.chooseFiles(descriptor, project, VfsUtil.getUserHomeDir(), new Consumer<List<VirtualFile>>() {
@Override
public void consume(final List<VirtualFile> files) {
for (VirtualFile file : files) {
- if (!descriptor.isFileSelectable(file)) { // on Mac, it could be selected anyway
- Messages.showInfoMessage(project,
- file.getPresentableUrl() + " contains no " +
- ApplicationNamesInfo.getInstance().getFullProductName() + " project",
- "Cannot Open Project");
+ if (!descriptor.isFileSelectable(file)) {
+ String message = IdeBundle.message("error.dir.contains.no.project", file.getPresentableUrl());
+ Messages.showInfoMessage(project, message, IdeBundle.message("title.cannot.open.project"));
return;
}
}
@@ -103,9 +68,8 @@ public class OpenFileAction extends AnAction implements DumbAware {
});
}
- private static void doOpenFile(@Nullable final Project project,
- @NotNull final List<VirtualFile> result) {
- for (final VirtualFile file : result) {
+ private static void doOpenFile(@Nullable Project project, @NotNull List<VirtualFile> result) {
+ for (VirtualFile file : result) {
if (file.isDirectory()) {
Project openedProject;
if (ProjectAttachProcessor.canAttachToProject()) {
@@ -118,9 +82,8 @@ public class OpenFileAction extends AnAction implements DumbAware {
return;
}
- if (OpenProjectFileChooserDescriptor.isProjectFile(file) &&
- // if the ipr-based project is already open, just open the ipr file
- (project == null || !file.equals(project.getProjectFile()))) {
+ // try to open as a project - unless the file is an .ipr of the current one
+ if ((project == null || !file.equals(project.getProjectFile())) && OpenProjectFileChooserDescriptor.isProjectFile(file)) {
Project openedProject = ProjectUtil.openOrImport(file.getPath(), project, false);
if (openedProject != null) {
FileChooserUtil.setLastOpenedFile(openedProject, file);
@@ -143,26 +106,54 @@ public class OpenFileAction extends AnAction implements DumbAware {
}
}
- public static void openFile(final String filePath, final Project project) {
- final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
+ public static void openFile(String filePath, @NotNull Project project) {
+ VirtualFile file = LocalFileSystem.getInstance().findFileByPath(filePath);
if (file != null && file.isValid()) {
openFile(file, project);
}
}
- public static void openFile(final VirtualFile virtualFile, final Project project) {
- FileEditorProviderManager editorProviderManager = FileEditorProviderManager.getInstance();
- if (editorProviderManager.getProviders(project, virtualFile).length == 0) {
- Messages.showMessageDialog(project,
- IdeBundle.message("error.files.of.this.type.cannot.be.opened",
- ApplicationNamesInfo.getInstance().getProductName()),
- IdeBundle.message("title.cannot.open.file"),
- Messages.getErrorIcon());
+ public static void openFile(VirtualFile file, @NotNull Project project) {
+ FileEditorProvider[] providers = FileEditorProviderManager.getInstance().getProviders(project, file);
+ if (providers.length == 0) {
+ String message = IdeBundle.message("error.files.of.this.type.cannot.be.opened", ApplicationNamesInfo.getInstance().getProductName());
+ Messages.showErrorDialog(project, message, IdeBundle.message("title.cannot.open.file"));
return;
}
- OpenFileDescriptor descriptor = new OpenFileDescriptor(project, virtualFile);
+ OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file);
FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
}
+ private static class ProjectOnlyFileChooserDescriptor extends OpenProjectFileChooserDescriptor {
+ public ProjectOnlyFileChooserDescriptor() {
+ super(true);
+ setTitle(IdeBundle.message("title.open.project"));
+ }
+ }
+
+ // vanilla OpenProjectFileChooserDescriptor only accepts project files; this on is overridden to accept any files
+ private static class ProjectOrFileChooserDescriptor extends OpenProjectFileChooserDescriptor {
+ private final FileChooserDescriptor myStandardDescriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor();
+
+ public ProjectOrFileChooserDescriptor() {
+ super(true);
+ setTitle(IdeBundle.message("title.open.file.or.project"));
+ }
+
+ @Override
+ public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
+ return file.isDirectory() ? super.isFileVisible(file, showHiddenFiles) : myStandardDescriptor.isFileVisible(file, showHiddenFiles);
+ }
+
+ @Override
+ public boolean isFileSelectable(VirtualFile file) {
+ return file.isDirectory() ? super.isFileSelectable(file) : myStandardDescriptor.isFileSelectable(file);
+ }
+
+ @Override
+ public boolean isChooseMultiple() {
+ return true;
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java b/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java
index 51d6362b36d8..b462fcbc11ad 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/OpenProjectFileChooserDescriptor.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,74 +15,91 @@
*/
package com.intellij.ide.actions;
-import com.intellij.icons.AllIcons;
import com.intellij.ide.highlighter.ProjectFileType;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
-import com.intellij.openapi.fileChooser.FileElement;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.projectImport.ProjectOpenProcessor;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+/**
+ * Intended for use in actions related to opening or importing existing projects.
+ * <strong>Due to a high I/O impact SHOULD NOT be used in any other cases.</strong>
+ */
public class OpenProjectFileChooserDescriptor extends FileChooserDescriptor {
private static final Icon ourProjectIcon = IconLoader.getIcon(ApplicationInfoEx.getInstanceEx().getSmallIconUrl());
- public OpenProjectFileChooserDescriptor(final boolean chooseFiles) {
+ public OpenProjectFileChooserDescriptor(boolean chooseFiles) {
super(chooseFiles, true, chooseFiles, chooseFiles, false, false);
}
- public boolean isFileSelectable(final VirtualFile file) {
- if (file == null) return false;
+ @Override
+ public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
+ return super.isFileVisible(file, showHiddenFiles) && (file.isDirectory() || isProjectFile(file));
+ }
+
+ @Override
+ public boolean isFileSelectable(VirtualFile file) {
return isProjectDirectory(file) || isProjectFile(file);
}
- public Icon getIcon(final VirtualFile file) {
- if (isProjectDirectory(file)) {
- return dressIcon(file, ourProjectIcon);
- }
- final Icon icon = getImporterIcon(file);
- if (icon != null) {
- return dressIcon(file, icon);
+ @Override
+ public Icon getIcon(VirtualFile file) {
+ if (canInspectDirectory(file)) {
+ if (isIprFile(file) || isIdeaDirectory(file)) {
+ return dressIcon(file, ourProjectIcon);
+ }
+ Icon icon = getImporterIcon(file);
+ if (icon != null) {
+ return dressIcon(file, icon);
+ }
}
return super.getIcon(file);
}
- @Nullable
- private static Icon getImporterIcon(final VirtualFile virtualFile) {
- final ProjectOpenProcessor provider = ProjectOpenProcessor.getImportProvider(virtualFile);
+ private static boolean canInspectDirectory(VirtualFile file) {
+ if (file.getParent() == null) return false;
+
+ VirtualFile home = VfsUtil.getUserHomeDir();
+ if (home == null) return false; // unnatural situation
+ VirtualFile homes = home.getParent();
+ if (homes == null) return false; // another one
+ if (homes.equals(file.getParent()) || VfsUtilCore.isAncestor(file, homes, false)) return false;
+
+ return true;
+ }
+
+ private static Icon getImporterIcon(VirtualFile file) {
+ ProjectOpenProcessor provider = ProjectOpenProcessor.getImportProvider(file);
if (provider != null) {
- return virtualFile.isDirectory() && provider.lookForProjectsInDirectory() ? AllIcons.Nodes.IdeaModule : provider.getIcon(virtualFile);
+ return file.isDirectory() && provider.lookForProjectsInDirectory() ? ourProjectIcon : provider.getIcon(file);
}
return null;
}
- public boolean isFileVisible(final VirtualFile file, final boolean showHiddenFiles) {
- if (!showHiddenFiles && FileElement.isFileHidden(file)) return false;
- return isProjectFile(file) || super.isFileVisible(file, showHiddenFiles) && file.isDirectory();
+ public static boolean isProjectFile(@NotNull VirtualFile file) {
+ return !file.isDirectory() && file.isValid() && (isIprFile(file) || hasImportProvider(file));
}
- public static boolean isProjectFile(final VirtualFile file) {
- if (isIprFile(file)) return true;
- final ProjectOpenProcessor importProvider = ProjectOpenProcessor.getImportProvider(file);
- return importProvider != null;
+ private static boolean isProjectDirectory(@NotNull VirtualFile file) {
+ return file.isDirectory() && file.isValid() && (isIdeaDirectory(file) || hasImportProvider(file));
}
private static boolean isIprFile(VirtualFile file) {
- if ((!file.isDirectory() && file.getName().toLowerCase().endsWith(ProjectFileType.DOT_DEFAULT_EXTENSION))) {
- return true;
- }
- return false;
+ return ProjectFileType.DEFAULT_EXTENSION.equalsIgnoreCase(file.getExtension());
+ }
+
+ private static boolean isIdeaDirectory(VirtualFile file) {
+ return file.findChild(Project.DIRECTORY_STORE_FOLDER) != null;
}
- private static boolean isProjectDirectory(final VirtualFile virtualFile) {
- // the root directory of any drive is never an IDEA project
- if (virtualFile.getParent() == null) return false;
- // NOTE: For performance reasons, it's very important not to iterate through all of the children here.
- if (virtualFile.isDirectory() && virtualFile.isValid() && virtualFile.findChild(Project.DIRECTORY_STORE_FOLDER) != null) return true;
- return false;
+ private static boolean hasImportProvider(VirtualFile file) {
+ return ProjectOpenProcessor.getImportProvider(file) != null;
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java
index 4df11f7261ca..2c5cc5b02282 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java
@@ -15,23 +15,20 @@
*/
package com.intellij.ide.actions;
+import com.intellij.ide.ui.search.SearchUtil;
+import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.options.ConfigurableGroup;
-import com.intellij.openapi.options.SearchableConfigurable;
-import com.intellij.openapi.options.ShowSettingsUtil;
-import com.intellij.openapi.options.ex.ConfigurableExtensionPointUtil;
-import com.intellij.openapi.options.ex.IdeConfigurablesGroup;
-import com.intellij.openapi.options.ex.MixedConfigurableGroup;
-import com.intellij.openapi.options.ex.ProjectConfigurablesGroup;
-import com.intellij.openapi.options.ex.SingleConfigurableEditor;
+import com.intellij.openapi.options.*;
+import com.intellij.openapi.options.ex.*;
+import com.intellij.openapi.options.newEditor.IdeSettingsDialog;
import com.intellij.openapi.options.newEditor.OptionsEditor;
import com.intellij.openapi.options.newEditor.OptionsEditorDialog;
-import com.intellij.openapi.options.newEditor.PreferencesDialog;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.navigation.Place;
import com.intellij.util.ui.update.Activatable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NotNull;
@@ -47,7 +44,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
*/
public class ShowSettingsUtilImpl extends ShowSettingsUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.ShowSettingsUtilImpl");
- private AtomicBoolean myShown = new AtomicBoolean(false);
+ private final AtomicBoolean myShown = new AtomicBoolean(false);
@NotNull
private static Project getProject(@Nullable Project project) {
@@ -55,12 +52,16 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
}
@NotNull
- private static DialogWrapper getDialog(@Nullable Project project, @NotNull ConfigurableGroup[] groups, @Nullable Configurable toSelect) {
+ public static DialogWrapper getDialog(@Nullable Project project, @NotNull ConfigurableGroup[] groups, @Nullable Configurable toSelect) {
+ project = getProject(project);
+ final ConfigurableGroup[] filteredGroups = filterEmptyGroups(groups);
+ if (Registry.is("ide.new.settings.dialog")) {
+ return new IdeSettingsDialog(project, filteredGroups, toSelect);
+ }
+ //noinspection deprecation
return Registry.is("ide.perProjectModality")
- ? new OptionsEditorDialog(getProject(project), filterEmptyGroups(groups), toSelect, true)
- : Registry.is("ide.new.preferences")
- ? new PreferencesDialog(getProject(project), filterEmptyGroups(groups))
- : new OptionsEditorDialog(getProject(project), filterEmptyGroups(groups), toSelect);
+ ? new OptionsEditorDialog(project, filteredGroups, toSelect, true)
+ : new OptionsEditorDialog(project, filteredGroups, toSelect);
}
@NotNull
@@ -73,7 +74,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
new ProjectConfigurablesGroup(project),
new IdeConfigurablesGroup()};
- return Registry.is("ide.file.settings.order.new")
+ return Registry.is("ide.new.settings.dialog")
? MixedConfigurableGroup.getGroups(getConfigurables(groups, true))
: groups;
}
@@ -139,41 +140,34 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
@Override
public void showSettingsDialog(@Nullable final Project project, @NotNull final String nameToSelect) {
- ConfigurableGroup[] group = getConfigurableGroups(project, true);
-
+ ConfigurableGroup[] groups = getConfigurableGroups(project, true);
Project actualProject = getProject(project);
- group = filterEmptyGroups(group);
+ groups = filterEmptyGroups(groups);
+ getDialog(actualProject, groups, findPreselectedByDisplayName(nameToSelect, groups)).show();
+ }
- OptionsEditorDialog dialog;
- if (Registry.is("ide.perProjectModality")) {
- dialog = new OptionsEditorDialog(actualProject, group, nameToSelect, true);
- }
- else {
- dialog = new OptionsEditorDialog(actualProject, group, nameToSelect);
+ @Nullable
+ private static Configurable findPreselectedByDisplayName(final String preselectedConfigurableDisplayName, ConfigurableGroup[] groups) {
+ final List<Configurable> all = SearchUtil.expand(groups);
+ for (Configurable each : all) {
+ if (preselectedConfigurableDisplayName.equals(each.getDisplayName())) return each;
}
- dialog.show();
+ return null;
}
public static void showSettingsDialog(@Nullable Project project, final String id2Select, final String filter) {
ConfigurableGroup[] group = getConfigurableGroups(project, true);
- Project actualProject = getProject(project);
-
group = filterEmptyGroups(group);
final Configurable configurable2Select = findConfigurable2Select(id2Select, group);
- final OptionsEditorDialog dialog;
- if (Registry.is("ide.perProjectModality")) {
- dialog = new OptionsEditorDialog(actualProject, group, configurable2Select, true);
- } else {
- dialog = new OptionsEditorDialog(actualProject, group, configurable2Select);
- }
+ final DialogWrapper dialog = getDialog(project, group, configurable2Select);
new UiNotifyConnector.Once(dialog.getContentPane(), new Activatable.Adapter() {
@Override
public void showNotify() {
- final OptionsEditor editor = (OptionsEditor)dialog.getData(OptionsEditor.KEY.getName());
+ final OptionsEditor editor = (OptionsEditor)((DataProvider)dialog).getData(OptionsEditor.KEY.getName());
LOG.assertTrue(editor != null);
editor.select(configurable2Select, filter);
}
@@ -234,37 +228,53 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
@Override
public <T extends Configurable> T findProjectConfigurable(final Project project, final Class<T> confClass) {
+ //noinspection deprecation
return ConfigurableExtensionPointUtil.findProjectConfigurable(project, confClass);
}
@Override
public boolean editConfigurable(Project project, String dimensionServiceKey, @NotNull Configurable configurable) {
- return editConfigurable(null, project, configurable, dimensionServiceKey, null);
+ return editConfigurable(project, dimensionServiceKey, configurable, isWorthToShowApplyButton(configurable));
+ }
+
+ private static boolean isWorthToShowApplyButton(@NotNull Configurable configurable) {
+ return configurable instanceof Place.Navigator ||
+ configurable instanceof Composite ||
+ configurable instanceof TabbedConfigurable;
+ }
+
+ @Override
+ public boolean editConfigurable(Project project, String dimensionServiceKey, @NotNull Configurable configurable, boolean showApplyButton) {
+ return editConfigurable(null, project, configurable, dimensionServiceKey, null, showApplyButton);
}
@Override
public boolean editConfigurable(Project project, Configurable configurable, Runnable advancedInitialization) {
- return editConfigurable(null, project, configurable, createDimensionKey(configurable), advancedInitialization);
+ return editConfigurable(null, project, configurable, createDimensionKey(configurable), advancedInitialization, isWorthToShowApplyButton(configurable));
}
@Override
- public boolean editConfigurable(Component parent, Configurable configurable) {
+ public boolean editConfigurable(@Nullable Component parent, @NotNull Configurable configurable) {
return editConfigurable(parent, configurable, null);
}
@Override
- public boolean editConfigurable(final Component parent, final Configurable configurable, @Nullable final Runnable advancedInitialization) {
- return editConfigurable(parent, null, configurable, createDimensionKey(configurable), advancedInitialization);
+ public boolean editConfigurable(@Nullable Component parent, @NotNull Configurable configurable, @Nullable Runnable advancedInitialization) {
+ return editConfigurable(parent, null, configurable, createDimensionKey(configurable), advancedInitialization, isWorthToShowApplyButton(configurable));
}
- private static boolean editConfigurable(final @Nullable Component parent, @Nullable Project project, final Configurable configurable, final String dimensionKey,
- @Nullable final Runnable advancedInitialization) {
- SingleConfigurableEditor editor;
- if (parent != null) {
- editor = new SingleConfigurableEditor(parent, configurable, dimensionKey);
+ private static boolean editConfigurable(@Nullable Component parent,
+ @Nullable Project project,
+ @NotNull Configurable configurable,
+ String dimensionKey,
+ @Nullable final Runnable advancedInitialization,
+ boolean showApplyButton) {
+ final SingleConfigurableEditor editor;
+ if (parent == null) {
+ editor = new SingleConfigurableEditor(project, configurable, dimensionKey, showApplyButton);
}
else {
- editor = new SingleConfigurableEditor(project, configurable, dimensionKey);
+ editor = new SingleConfigurableEditor(parent, configurable, dimensionKey, showApplyButton);
}
if (advancedInitialization != null) {
new UiNotifyConnector.Once(editor.getContentPane(), new Activatable.Adapter() {
@@ -278,15 +288,14 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil {
return editor.isOK();
}
- public static String createDimensionKey(Configurable configurable) {
- String displayName = configurable.getDisplayName();
- displayName = displayName.replaceAll("\n", "_").replaceAll(" ", "_");
- return "#" + displayName;
+ @NotNull
+ public static String createDimensionKey(@NotNull Configurable configurable) {
+ return '#' + StringUtil.replaceChar(StringUtil.replaceChar(configurable.getDisplayName(), '\n', '_'), ' ', '_');
}
@Override
- public boolean editConfigurable(Component parent, String dimensionServiceKey,Configurable configurable) {
- return editConfigurable(parent, null, configurable, dimensionServiceKey, null);
+ public boolean editConfigurable(Component parent, String dimensionServiceKey, Configurable configurable) {
+ return editConfigurable(parent, null, configurable, dimensionServiceKey, null, isWorthToShowApplyButton(configurable));
}
public boolean isAlreadyShown() {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java
index a9461422f747..825db992b218 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ViewSourceAction.java
@@ -17,9 +17,21 @@
package com.intellij.ide.actions;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
public class ViewSourceAction extends BaseNavigateToSourceAction {
public ViewSourceAction() {
super(false);
}
+
+ @Override
+ public void update(AnActionEvent e) {
+ if (CommonDataKeys.EDITOR.getData(e.getDataContext()) != null) {
+ e.getPresentation().setEnabledAndVisible(false);
+ }
+ else {
+ super.update(e);
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java b/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java
index 6844ed5bab25..798247e16186 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/AbstractCustomizeWizardStep.java
@@ -21,12 +21,14 @@ import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
+import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
public abstract class AbstractCustomizeWizardStep extends JPanel {
+ protected static final int SMALL_GAP = 10;
protected static final int GAP = 20;
protected abstract String getTitle();
@@ -40,6 +42,14 @@ public abstract class AbstractCustomizeWizardStep extends JPanel {
return ColorUtil.mix(UIUtil.getListSelectionBackground(), UIUtil.getLabelBackground(), UIUtil.isUnderDarcula() ? .5 : .75);
}
+ public static Border createSmallEmptyBorder() {
+ return BorderFactory.createEmptyBorder(SMALL_GAP, SMALL_GAP, SMALL_GAP, SMALL_GAP);
+ }
+
+ public static BorderLayout createSmallBorderLayout() {
+ return new BorderLayout(SMALL_GAP, SMALL_GAP);
+ }
+
protected static JPanel createBigButtonPanel(LayoutManager layout, final JToggleButton anchorButton, final Runnable action) {
final JPanel panel = new JPanel(layout) {
@Override
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.java
new file mode 100644
index 000000000000..57b68232b797
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeDesktopEntryStep.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.ide.customize;
+
+import com.intellij.ide.actions.CreateDesktopEntryAction;
+import com.intellij.idea.ActionsBundle;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.progress.EmptyProgressIndicator;
+import com.intellij.openapi.util.EmptyRunnable;
+import com.intellij.openapi.util.IconLoader;
+import com.intellij.util.ui.GridBag;
+import com.intellij.util.ui.UIUtil;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.*;
+
+/**
+ * @author Alexander Lobas
+ */
+public class CustomizeDesktopEntryStep extends AbstractCustomizeWizardStep {
+ private final JCheckBox myCreateEntryCheckBox = new JCheckBox(ActionsBundle.message("action.CreateDesktopEntry.description"));
+ private final JCheckBox myGlobalEntryCheckBox = new JCheckBox("For all users");
+
+ public CustomizeDesktopEntryStep(String iconPath) {
+ setLayout(new BorderLayout());
+
+ JPanel panel = createBigButtonPanel(createSmallBorderLayout(), myCreateEntryCheckBox, EmptyRunnable.INSTANCE);
+ panel.setBorder(createSmallEmptyBorder());
+
+ JPanel buttonPanel = new JPanel(new GridBagLayout());
+ buttonPanel.setOpaque(false);
+
+ GridBag gbc =
+ new GridBag().setDefaultAnchor(GridBagConstraints.WEST).setDefaultFill(GridBagConstraints.HORIZONTAL).setDefaultWeightX(1);
+
+ myCreateEntryCheckBox.setOpaque(false);
+ buttonPanel.add(myCreateEntryCheckBox, gbc.nextLine());
+
+ myGlobalEntryCheckBox.setOpaque(false);
+ gbc.nextLine().insets.left = UIUtil.PANEL_REGULAR_INSETS.left;
+ buttonPanel.add(myGlobalEntryCheckBox, gbc);
+
+ panel.add(buttonPanel, BorderLayout.NORTH);
+
+ JLabel label = new JLabel(IconLoader.getIcon(iconPath));
+ label.setVerticalAlignment(JLabel.TOP);
+ panel.add(label, BorderLayout.CENTER);
+
+ add(panel, BorderLayout.CENTER);
+
+ myCreateEntryCheckBox.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ myGlobalEntryCheckBox.setEnabled(myCreateEntryCheckBox.isSelected());
+ myGlobalEntryCheckBox.setSelected(myCreateEntryCheckBox.isSelected() && !PathManager.getHomePath().startsWith("/home"));
+ }
+ });
+
+ myCreateEntryCheckBox.setSelected(true);
+ }
+
+ public static boolean isAvailable() {
+ return CreateDesktopEntryAction.isAvailable();
+ }
+
+ @Override
+ public boolean beforeOkAction() {
+ if (myCreateEntryCheckBox.isSelected()) {
+ try {
+ CreateDesktopEntryAction.createDesktopEntry(null, new EmptyProgressIndicator(), myGlobalEntryCheckBox.isSelected());
+ }
+ catch (Throwable e) {
+ // ignored
+ }
+ }
+ return true;
+ }
+
+ @Override
+ protected String getTitle() {
+ return "Desktop Entry";
+ }
+
+ @Override
+ protected String getHTMLHeader() {
+ return "<html><body><h2>Create Desktop Entry</h2>&nbsp;</body></html>";
+ }
+
+ @Override
+ protected String getHTMLFooter() {
+ return "Desktop entry can be created later in Tools | Create Desktop Entry...";
+ }
+} \ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java
index 786a5825e783..498391b8e971 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeFeaturedPluginsStepPanel.java
@@ -18,7 +18,9 @@ package com.intellij.ide.customize;
import com.intellij.CommonBundle;
import com.intellij.icons.AllIcons;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
+import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.ide.plugins.PluginNode;
+import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.progress.util.ProgressIndicatorBase;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.updateSettings.impl.PluginDownloader;
@@ -78,7 +80,7 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
final String pluginId = s.substring(j + 1);
IdeaPluginDescriptor foundDescriptor = null;
for (IdeaPluginDescriptor descriptor : pluginsFromRepository) {
- if (descriptor.getPluginId().getIdString().equals(pluginId)) {
+ if (descriptor.getPluginId().getIdString().equals(pluginId) && !PluginManagerCore.isBrokenPlugin(descriptor)) {
foundDescriptor = descriptor;
isEmptyOrOffline = false;
break;
@@ -107,11 +109,11 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
JPanel progressPanel = new JPanel(new VerticalFlowLayout(true, false));
progressPanel.add(progressBar);
final LinkLabel cancelLink = new LinkLabel("Cancel", AllIcons.Actions.Cancel);
- JPanel linkWrapper = new JPanel(new FlowLayout(FlowLayout.CENTER));
+ JPanel linkWrapper = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
linkWrapper.add(cancelLink);
progressPanel.add(linkWrapper);
- JPanel buttonPanel = new JPanel(new VerticalFlowLayout());
+ JPanel buttonPanel = new JPanel(new VerticalFlowLayout(0, 0));
buttonPanel.add(installButton);
buttonWrapper.add(buttonPanel, "button");
@@ -218,7 +220,7 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
}, null);
gbc.insets.bottom = -5;
groupPanel.add(titleLabel, gbc);
- gbc.insets.bottom = 10;
+ gbc.insets.bottom = SMALL_GAP;
groupPanel.add(topicLabel, gbc);
groupPanel.add(descriptionLabel, gbc);
gbc.weighty = 1;
@@ -238,7 +240,7 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
protected Color getColor() {
return ColorUtil.withAlpha(JBColor.foreground(), .2);
}
- }, BorderFactory.createEmptyBorder(GAP, GAP, 0, GAP)));
+ }, BorderFactory.createEmptyBorder(0, SMALL_GAP, 0, SMALL_GAP)));
cursor++;
}
@@ -260,7 +262,10 @@ public class CustomizeFeaturedPluginsStepPanel extends AbstractCustomizeWizardSt
@Override
public String getHTMLFooter() {
- return "New plugins can also be downloaded in " + CommonBundle.settingsTitle() + " | Plugins";
+ return "New plugins can also be downloaded in "
+ + CommonBundle.settingsTitle()
+ + " | " + OptionsBundle.message("configurable.group.appearance.settings.display.name")
+ + " | " + "Plugins";
}
public static class OfflineException extends Exception {};
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java
index be37f9d9d7f6..af3c193ca9d9 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeIDEWizardDialog.java
@@ -21,7 +21,7 @@ import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.JBCardLayout;
-import org.jetbrains.annotations.NotNull;
+import com.intellij.util.PlatformUtils;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -51,6 +51,7 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
public CustomizeIDEWizardDialog() {
super(null, true, true);
setTitle("Customize " + ApplicationNamesInfo.getInstance().getProductName());
+ getPeer().setAppIcons();
initSteps();
mySkipButton.addActionListener(this);
myBackButton.addActionListener(this);
@@ -119,7 +120,7 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
result.add(myContentPanel, BorderLayout.CENTER);
result.add(myFooterLabel, BorderLayout.SOUTH);
result.setPreferredSize(new Dimension(700, 600));
- result.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ result.setBorder(AbstractCustomizeWizardStep.createSmallEmptyBorder());
return result;
}
@@ -131,8 +132,10 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
- buttonPanel.add(mySkipButton, gbc);
- gbc.gridx++;
+ if (!PlatformUtils.isCLion()) {
+ buttonPanel.add(mySkipButton, gbc);
+ gbc.gridx++;
+ }
buttonPanel.add(myBackButton, gbc);
gbc.gridx++;
gbc.weightx = 1;
@@ -219,15 +222,4 @@ public class CustomizeIDEWizardDialog extends DialogWrapper implements ActionLis
}
myNavigationLabel.setText(navHTML.toString());
}
-
-
- private static <T extends Component> void getChildren(@NotNull Component c, Class<? extends T> cls, List<T> accumulator) {
- if (cls.isAssignableFrom(c.getClass())) accumulator.add((T)c);
- if (c instanceof Container) {
- Component[] components = ((Container)c).getComponents();
- for (Component component : components) {
- getChildren(component, cls, accumulator);
- }
- }
- }
}
diff --git a/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java b/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java
index 8924c09780dd..de12269b5887 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizePluginsStepPanel.java
@@ -115,7 +115,7 @@ public class CustomizePluginsStepPanel extends AbstractCustomizeWizardStep imple
gbc.weighty = 1;
groupPanel.add(Box.createVerticalGlue(), gbc);
gbc.weighty = 0;
- JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5));
+ JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, SMALL_GAP, SMALL_GAP / 2));
buttonsPanel.setOpaque(false);
if (pluginGroups.getSets(group).size() == 1) {
buttonsPanel.add(createLink(SWITCH_COMMAND + ":" + group, getGroupSwitchTextProvider(group)));
@@ -139,7 +139,7 @@ public class CustomizePluginsStepPanel extends AbstractCustomizeWizardStep imple
protected Color getColor() {
return ColorUtil.withAlpha(JBColor.foreground(), .2);
}
- }, BorderFactory.createEmptyBorder(GAP / 2, GAP, GAP / 2, GAP)));
+ }, BorderFactory.createEmptyBorder(SMALL_GAP, GAP, SMALL_GAP, GAP)));
cursor++;
}
}
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 b369e49f8bca..c7b29ef53827 100644
--- a/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
+++ b/platform/platform-impl/src/com/intellij/ide/customize/CustomizeUIThemeStepPanel.java
@@ -22,6 +22,7 @@ import com.intellij.ide.ui.laf.darcula.DarculaLaf;
import com.intellij.ide.ui.laf.darcula.DarculaLookAndFeelInfo;
import com.intellij.idea.StartupUtil;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.IconUtil;
@@ -46,7 +47,7 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
private Map<String, Icon> myLafNames = new LinkedHashMap<String, Icon>();
public CustomizeUIThemeStepPanel() {
- setLayout(new BorderLayout(10, 10));
+ setLayout(createSmallBorderLayout());
IconLoader.activate();
initLafs();
@@ -65,13 +66,13 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
radioButton.setSelected(true);
myDefaultLafName = lafName;
}
- final JPanel panel = createBigButtonPanel(new BorderLayout(10, 10), radioButton, new Runnable() {
+ final JPanel panel = createBigButtonPanel(createSmallBorderLayout(), radioButton, new Runnable() {
@Override
public void run() {
applyLaf(lafName, CustomizeUIThemeStepPanel.this);
}
});
- panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ panel.setBorder(createSmallEmptyBorder());
panel.add(radioButton, myColumnMode ? BorderLayout.WEST : BorderLayout.NORTH);
final JLabel label = new JLabel(myColumnMode ? IconUtil.scale(IconUtil.cropIcon(icon, icon.getIconWidth() * 2 / 3, icon.getIconHeight() * 2 / 3), .5) : icon);
label.setVerticalAlignment(SwingConstants.TOP);
@@ -139,7 +140,10 @@ public class CustomizeUIThemeStepPanel extends AbstractCustomizeWizardStep {
@Override
public String getHTMLFooter() {
- return "UI theme can be changed later in " + CommonBundle.settingsTitle() + " | Appearance";
+ return "UI theme can be changed later in " +
+ CommonBundle.settingsTitle()
+ + " | " + OptionsBundle.message("configurable.group.appearance.settings.display.name")
+ + " | " + "Appearance";
}
private void applyLaf(String lafName, Component component) {
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 6b0b9814698b..de5d67b5e2d8 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
@@ -15,6 +15,8 @@
*/
package com.intellij.ide.passwordSafe.impl.providers.masterKey;
+import com.intellij.concurrency.AsyncFutureFactory;
+import com.intellij.concurrency.AsyncFutureResult;
import com.intellij.ide.passwordSafe.MasterPasswordUnavailableException;
import com.intellij.ide.passwordSafe.PasswordSafeException;
import com.intellij.ide.passwordSafe.impl.PasswordSafeTimed;
@@ -23,14 +25,11 @@ import com.intellij.ide.passwordSafe.impl.providers.ByteArrayWrapper;
import com.intellij.ide.passwordSafe.impl.providers.EncryptionUtil;
import com.intellij.ide.passwordSafe.impl.providers.masterKey.windows.WindowsCryptUtils;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.openapi.util.ThrowableComputable;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,6 +37,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
/**
* The password safe that stores information in configuration file encrypted by master password
@@ -170,12 +170,6 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
throw new MasterPasswordUnavailableException("The provider is not available in headless environment");
}
- if (myDatabase.isEmpty()) {
- if (!MasterPasswordDialog.resetMasterPasswordDialog(project, this, requestor).showAndGet()) {
- throw new MasterPasswordUnavailableException("Master password is required to store passwords in the database.");
- }
- }
-
key = invokeAndWait(new ThrowableComputable<Object, PasswordSafeException>() {
@Override
public Object compute() throws PasswordSafeException {
@@ -184,7 +178,14 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
return key;
}
try {
- MasterPasswordDialog.askPassword(project, MasterKeyPasswordSafe.this, requestor);
+ if (myDatabase.isEmpty()) {
+ if (!MasterPasswordDialog.resetMasterPasswordDialog(project, MasterKeyPasswordSafe.this, requestor).showAndGet()) {
+ throw new MasterPasswordUnavailableException("Master password is required to store passwords in the database.");
+ }
+ }
+ else {
+ MasterPasswordDialog.askPassword(project, MasterKeyPasswordSafe.this, requestor);
+ }
}
catch (PasswordSafeException e) {
myKey.get().set(e);
@@ -200,35 +201,41 @@ public class MasterKeyPasswordSafe extends BasePasswordSafeProvider {
}
private static final Object ourEDTLock = new Object();
- public <T, E extends Throwable> T invokeAndWait(@NotNull final ThrowableComputable<T, E> computable, @NotNull final Condition expired) throws E {
+ public <T, E extends Throwable> T invokeAndWait(@NotNull final ThrowableComputable<T, E> computable, @NotNull final Condition<?> expired) throws E {
if (ApplicationManager.getApplication().isDispatchThread()) {
return computable.compute();
}
- final Ref<Throwable> exRef = Ref.create();
- final Ref<T> ref = Ref.create();
+
+ final AsyncFutureResult<Object> future = AsyncFutureFactory.getInstance().createAsyncFutureResult();
synchronized (ourEDTLock) {
- if (expired.value(null)) {
- throw new ProcessCanceledException();
- }
- ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+ IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(new ExpirableRunnable() {
@Override
- public void run() {
- if (expired.value(null)) {
- exRef.set(new ProcessCanceledException());
- return;
- }
+ public boolean isExpired() {
+ boolean b = expired.value(null);
+ if (b) future.setException(new ProcessCanceledException());
+ return b;
+ }
+ @Override
+ public void run() {
try {
- ref.set(computable.compute());
+ future.set(computable.compute());
}
catch (Throwable e) {
- exRef.set(e);
+ future.setException(e);
}
}
- }, ModalityState.any());
+ });
+ }
+ try {
+ return (T)future.get();
+ }
+ catch (InterruptedException e) {
+ throw new ProcessCanceledException(e);
+ }
+ catch (ExecutionException e) {
+ throw (E) e.getCause();
}
- if (!exRef.isNull()) throw (E)exRef.get();
- return ref.get();
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
index 62609d9ba5fc..0ae246d41715 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
@@ -29,7 +29,7 @@ import com.intellij.openapi.updateSettings.impl.UpdateSettings;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TableUtil;
-import com.intellij.util.net.HTTPProxySettingsDialog;
+import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.ui.update.UiNotifyConnector;
import org.jetbrains.annotations.NotNull;
@@ -41,6 +41,7 @@ import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.TreeSet;
/**
@@ -50,7 +51,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
public static final String MANAGE_REPOSITORIES = "Manage repositories...";
public static final String N_A = "N/A";
- private PluginManagerMain installed;
+ private final PluginManagerMain installed;
private final String myVendorFilter;
public AvailablePluginsManagerMain(PluginManagerMain installed, PluginManagerUISettings uiSettings, String vendorFilter) {
@@ -63,11 +64,11 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
manageRepositoriesBtn.setMnemonic('m');
manageRepositoriesBtn.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(@NotNull ActionEvent e) {
if (ShowSettingsUtil.getInstance().editConfigurable(myActionsPanel, new PluginHostsConfigurable())) {
final ArrayList<String> pluginHosts = UpdateSettings.getInstance().myPluginHosts;
if (!pluginHosts.contains(((AvailablePluginsTableModel)pluginsModel).getRepository())) {
- ((AvailablePluginsTableModel)pluginsModel).setRepository(AvailablePluginsTableModel.ALL, myFilter.getFilter().toLowerCase());
+ ((AvailablePluginsTableModel)pluginsModel).setRepository(AvailablePluginsTableModel.ALL, myFilter.getFilter().toLowerCase(Locale.ENGLISH));
}
loadAvailablePlugins();
}
@@ -78,11 +79,9 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
final JButton httpProxySettingsButton = new JButton(IdeBundle.message("button.http.proxy.settings"));
httpProxySettingsButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- HTTPProxySettingsDialog settingsDialog = new HTTPProxySettingsDialog();
- settingsDialog.pack();
- settingsDialog.show();
- if (settingsDialog.isOK()) {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
+ if (HttpConfigurable.editConfigurable(getMainPanel())) {
loadAvailablePlugins();
}
}
@@ -114,7 +113,8 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
pluginTable.registerKeyboardAction(
new ActionListener() {
- public void actionPerformed(ActionEvent e) {
+ @Override
+ public void actionPerformed(@NotNull ActionEvent e) {
installSelected(pluginTable);
}
},
@@ -235,7 +235,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
return new AnAction(availableCategory) {
@Override
public void actionPerformed(AnActionEvent e) {
- final String filter = myFilter.getFilter().toLowerCase();
+ final String filter = myFilter.getFilter().toLowerCase(Locale.ENGLISH);
((AvailablePluginsTableModel)pluginsModel).setCategory(availableCategory, filter);
}
};
@@ -277,7 +277,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
return new AnAction(host) {
@Override
public void actionPerformed(AnActionEvent e) {
- final String filter = myFilter.getFilter().toLowerCase();
+ final String filter = myFilter.getFilter().toLowerCase(Locale.ENGLISH);
((AvailablePluginsTableModel)pluginsModel).setRepository(host, filter);
TableUtil.ensureSelectionExists(getPluginTable());
}
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
index a1ea238835cd..57329fb8fe9d 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.plugins;
+import com.intellij.diagnostic.PluginException;
import com.intellij.ide.ClassUtilCore;
import com.intellij.ide.IdeBundle;
import com.intellij.idea.IdeaApplication;
@@ -100,31 +101,44 @@ public class PluginManager extends PluginManagerCore {
public static void processException(Throwable t) {
if (!IdeaApplication.isLoaded()) {
- @SuppressWarnings("ThrowableResultOfMethodCallIgnored") StartupAbortedException se = findCause(t);
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored") StartupAbortedException se = findCause(t, StartupAbortedException.class);
if (se == null) se = new StartupAbortedException(t);
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored") PluginException pe = findCause(t, PluginException.class);
+ PluginId pluginId = pe != null ? pe.getPluginId() : null;
- if (se.logError()) {
+ if (Logger.isInitialized() && !(t instanceof ProcessCanceledException)) {
try {
- if (Logger.isInitialized() && !(t instanceof ProcessCanceledException)) {
- getLogger().error(t);
- }
+ getLogger().error(t);
}
catch (Throwable ignore) { }
+ }
+
+ if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
+ disablePlugin(pluginId.getIdString());
+
+ StringWriter message = new StringWriter();
+ message.append("Plugin '").append(pluginId.getIdString()).append("' failed to initialize and will be disabled. ");
+ message.append(" Please restart ").append(ApplicationNamesInfo.getInstance().getFullProductName()).append('.');
+ message.append("\n\n");
+ pe.getCause().printStackTrace(new PrintWriter(message));
+ Main.showMessage("Plugin Error", message.toString(), false);
+ System.exit(Main.PLUGIN_ERROR);
+ }
+ else {
Main.showMessage("Start Failed", t);
+ System.exit(se.exitCode());
}
-
- System.exit(se.exitCode());
}
else if (!(t instanceof ProcessCanceledException)) {
getLogger().error(t);
}
}
- private static StartupAbortedException findCause(Throwable t) {
+ private static <T extends Throwable> T findCause(Throwable t, Class<T> clazz) {
while (t != null) {
- if (t instanceof StartupAbortedException) {
- return (StartupAbortedException)t;
+ if (clazz.isInstance(t)) {
+ return clazz.cast(t);
}
t = t.getCause();
}
@@ -229,18 +243,7 @@ public class PluginManager extends PluginManagerCore {
}
if (pluginId != null && !CORE_PLUGIN_ID.equals(pluginId.getIdString())) {
- getLogger().warn(t);
-
- disablePlugin(pluginId.getIdString());
-
- StringWriter message = new StringWriter();
- message.append("Plugin '").append(pluginId.getIdString()).append("' failed to initialize and will be disabled. ");
- message.append(" Please restart ").append(ApplicationNamesInfo.getInstance().getFullProductName()).append('.');
- message.append("\n\n");
- t.printStackTrace(new PrintWriter(message));
- Main.showMessage("Plugin Error", message.toString(), false);
-
- throw new StartupAbortedException(t).exitCode(Main.PLUGIN_ERROR).logError(false);
+ throw new StartupAbortedException(new PluginException(t, pluginId));
}
else {
throw new StartupAbortedException("Fatal error initializing '" + componentClassName + "'", t);
@@ -249,7 +252,6 @@ public class PluginManager extends PluginManagerCore {
private static class StartupAbortedException extends RuntimeException {
private int exitCode = Main.STARTUP_EXCEPTION;
- private boolean logError = true;
public StartupAbortedException(Throwable cause) {
super(cause);
@@ -267,14 +269,5 @@ public class PluginManager extends PluginManagerCore {
this.exitCode = exitCode;
return this;
}
-
- public boolean logError() {
- return logError;
- }
-
- public StartupAbortedException logError(boolean logError) {
- this.logError = logError;
- return this;
- }
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
index 59197a00e70b..550e8e2482e1 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
+++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
@@ -74,7 +74,7 @@
</component>
</children>
</grid>
- <grid id="d9fb" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="d9fb" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -82,17 +82,6 @@
<properties/>
<border type="none"/>
<children>
- <component id="5ea1e" class="javax.swing.JComboBox" binding="myFontSizeCombo" custom-create="true">
- <constraints>
- <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
- <minimum-size width="140" height="-1"/>
- <preferred-size width="140" height="-1"/>
- </grid>
- </constraints>
- <properties>
- <editable value="true"/>
- </properties>
- </component>
<component id="76cd" class="javax.swing.JComboBox" binding="myFontCombo">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
@@ -107,15 +96,6 @@
<requestFocusEnabled value="true"/>
</properties>
</component>
- <component id="4eb1b" class="javax.swing.JLabel" binding="myFontSizeLabel">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <horizontalAlignment value="10"/>
- <text resource-bundle="messages/IdeBundle" key="label.font.size"/>
- </properties>
- </component>
<component id="23221" class="javax.swing.JLabel" binding="myFontNameLabel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
@@ -127,11 +107,30 @@
</component>
<hspacer id="53ae4">
<constraints>
- <grid row="0" column="0" row-span="2" col-span="1" vsize-policy="1" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
<minimum-size width="20" height="-1"/>
</grid>
</constraints>
</hspacer>
+ <component id="4eb1b" class="javax.swing.JLabel" binding="myFontSizeLabel">
+ <constraints>
+ <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <horizontalAlignment value="10"/>
+ <text resource-bundle="messages/IdeBundle" key="label.font.size"/>
+ </properties>
+ </component>
+ <component id="5ea1e" class="javax.swing.JComboBox" binding="myFontSizeCombo" custom-create="true">
+ <constraints>
+ <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="40" height="-1"/>
+ </grid>
+ </constraints>
+ <properties>
+ <editable value="true"/>
+ </properties>
+ </component>
</children>
</grid>
<grid id="ce348" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
diff --git a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
index bbd52139bd51..7ebf2a57a998 100644
--- a/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
+++ b/platform/platform-impl/src/com/intellij/ide/util/TipUIUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.ide.util;
+import com.intellij.CommonBundle;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
@@ -97,6 +98,7 @@ public class TipUIUtil {
String minor = ApplicationInfo.getInstance().getMinorVersion();
replaced = replaced.replace("&minorVersion;", minor);
replaced = replaced.replace("&majorMinorVersion;", major + ("0".equals(minor) ? "" : ("." + minor)));
+ replaced = replaced.replace("&settingsPath;", CommonBundle.settingsActionPath());
if (UIUtil.isUnderDarcula()) {
replaced = replaced.replace("css/tips.css", "css/tips_darcula.css");
}
diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
index 94b25a1b3c94..b32729dd7328 100644
--- a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
+++ b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java
@@ -24,10 +24,7 @@ import com.intellij.ide.IdeRepaintManager;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.internal.statistic.UsageTrigger;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ApplicationStarter;
-import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.*;
import com.intellij.openapi.application.ex.ApplicationEx;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
@@ -107,6 +104,12 @@ public class IdeaApplication {
if (myStarter == null) {
myStarter = getStarter();
}
+
+ if (headless && myStarter instanceof ApplicationStarterEx && !((ApplicationStarterEx)myStarter).isHeadless()) {
+ Main.showMessage("Startup Error", "Application cannot start in headless mode", true);
+ System.exit(Main.STARTUP_IMPOSSIBLE);
+ }
+
myStarter.premain(args);
}
@@ -178,10 +181,15 @@ public class IdeaApplication {
catch (ClassNotFoundException ignored) { }
}
- protected class IdeStarter implements ApplicationStarter {
+ protected class IdeStarter extends ApplicationStarterEx {
private Splash mySplash;
@Override
+ public boolean isHeadless() {
+ return false;
+ }
+
+ @Override
public String getCommandName() {
return null;
}
diff --git a/platform/platform-impl/src/com/intellij/notification/impl/actions/ShowDelayedMessageInternalAction.java b/platform/platform-impl/src/com/intellij/notification/impl/actions/ShowDelayedMessageInternalAction.java
new file mode 100644
index 000000000000..ad133f1c7574
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/notification/impl/actions/ShowDelayedMessageInternalAction.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.notification.impl.actions;
+
+import com.intellij.CommonBundle;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.application.ApplicationBundle;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.ui.MessageDialogBuilder;
+
+import javax.swing.*;
+
+/**
+ * @author Denis Fokin
+ */
+public class ShowDelayedMessageInternalAction extends AnAction implements DumbAware{
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+
+ new Thread() {
+ @Override
+ public void run() {
+ super.run();
+
+ //noinspection EmptyCatchBlock
+ try {
+ Thread.sleep(3000);
+ }
+ catch (InterruptedException e1) {} // does not matter for an internal action
+
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ MessageDialogBuilder.yesNo("Nothing happens after that", "Some message goes here").yesText(
+ ApplicationBundle.message("command.exit")).noText(
+ CommonBundle.message("button.cancel")).show();
+ }
+ });
+ }
+ }.start();
+
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/ex/QuickListsManager.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/ex/QuickListsManager.java
index a17370e73266..bf7c79695c94 100644
--- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/ex/QuickListsManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/ex/QuickListsManager.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.DecodeDefaultsUtil;
import com.intellij.openapi.components.ExportableApplicationComponent;
import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.BaseSchemeProcessor;
import com.intellij.openapi.options.SchemesManager;
@@ -63,7 +64,7 @@ public class QuickListsManager implements ExportableApplicationComponent, NamedJ
public QuickListsManager(ActionManagerEx actionManagerEx, SchemesManagerFactory schemesManagerFactory) {
myActionManager = actionManagerEx;
mySchemesManager = schemesManagerFactory.createSchemesManager(
- "$ROOT_CONFIG$/quicklists",
+ StoragePathMacros.ROOT_CONFIG + "/quicklists",
new BaseSchemeProcessor<QuickList>(){
public QuickList readScheme(@NotNull final Document schemeContent) throws InvalidDataException, IOException, JDOMException {
return loadListFromDocument(schemeContent);
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
index 723956ef9daa..c5a9b01c4d21 100644
--- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionManagerImpl.java
@@ -39,6 +39,7 @@ import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.keymap.ex.KeymapManagerEx;
import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.ProjectType;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Disposer;
@@ -71,28 +72,6 @@ import java.util.*;
import java.util.List;
public final class ActionManagerImpl extends ActionManagerEx implements ApplicationComponent {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionManagerImpl");
- private static final int DEACTIVATED_TIMER_DELAY = 5000;
- private static final int TIMER_DELAY = 500;
- private static final int UPDATE_DELAY_AFTER_TYPING = 500;
-
- private final Object myLock = new Object();
- private final Map<String,Object> myId2Action = new THashMap<String, Object>();
- private final Map<PluginId, THashSet<String>> myPlugin2Id = new THashMap<PluginId, THashSet<String>>();
- private final TObjectIntHashMap<String> myId2Index = new TObjectIntHashMap<String>();
- private final Map<Object,String> myAction2Id = new THashMap<Object, String>();
- private final MultiMap<String,String> myId2GroupId = new MultiMap<String, String>();
- private final List<String> myNotRegisteredInternalActionIds = new ArrayList<String>();
- private MyTimer myTimer;
-
- private int myRegisteredActionsCount;
- private final List<AnActionListener> myActionListeners = ContainerUtil.createLockFreeCopyOnWriteList();
- private String myLastPreformedActionId;
- private final KeymapManager myKeymapManager;
- private final DataManager myDataManager;
- private String myPrevPerformedActionId;
- private long myLastTimeEditorWasTypedIn = 0;
-
@NonNls public static final String ACTION_ELEMENT_NAME = "action";
@NonNls public static final String GROUP_ELEMENT_NAME = "group";
@NonNls public static final String ACTIONS_ELEMENT_NAME = "actions";
@@ -130,14 +109,32 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@NonNls public static final String USE_SHORTCUT_OF_ATTR_NAME = "use-shortcut-of";
@NonNls public static final String OVERRIDES_ATTR_NAME = "overrides";
@NonNls public static final String KEEP_CONTENT_ATTR_NAME = "keep-content";
-
+ @NonNls public static final String PROJECT_TYPE = "project-type";
+ private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.actionSystem.impl.ActionManagerImpl");
+ private static final int DEACTIVATED_TIMER_DELAY = 5000;
+ private static final int TIMER_DELAY = 500;
+ private static final int UPDATE_DELAY_AFTER_TYPING = 500;
+ private final Object myLock = new Object();
+ private final Map<String,AnAction> myId2Action = new THashMap<String, AnAction>();
+ private final Map<PluginId, THashSet<String>> myPlugin2Id = new THashMap<PluginId, THashSet<String>>();
+ private final TObjectIntHashMap<String> myId2Index = new TObjectIntHashMap<String>();
+ private final Map<Object,String> myAction2Id = new THashMap<Object, String>();
+ private final MultiMap<String,String> myId2GroupId = new MultiMap<String, String>();
+ private final List<String> myNotRegisteredInternalActionIds = new ArrayList<String>();
+ private final List<AnActionListener> myActionListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private final KeymapManager myKeymapManager;
+ private final DataManager myDataManager;
private final List<ActionPopupMenuImpl> myPopups = new ArrayList<ActionPopupMenuImpl>();
-
private final Map<AnAction, DataContext> myQueuedNotifications = new LinkedHashMap<AnAction, DataContext>();
private final Map<AnAction, AnActionEvent> myQueuedNotificationsEvents = new LinkedHashMap<AnAction, AnActionEvent>();
-
+ private MyTimer myTimer;
+ private int myRegisteredActionsCount;
+ private String myLastPreformedActionId;
+ private String myPrevPerformedActionId;
+ private long myLastTimeEditorWasTypedIn = 0;
private Runnable myPreloadActionsRunnable;
private boolean myTransparentOnlyUpdate;
+ private int myActionsPreloaded = 0;
ActionManagerImpl(KeymapManager keymapManager, DataManager dataManager) {
myKeymapManager = keymapManager;
@@ -146,6 +143,257 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
registerPluginActions();
}
+ static AnAction convertStub(ActionStub stub) {
+ Object obj;
+ String className = stub.getClassName();
+ try {
+ Class<?> aClass = Class.forName(className, true, stub.getLoader());
+ obj = ReflectionUtil.newInstance(aClass);
+ }
+ catch (ClassNotFoundException e) {
+ PluginId pluginId = stub.getPluginId();
+ if (pluginId != null) {
+ throw new PluginException("class with name \"" + className + "\" not found", e, pluginId);
+ }
+ else {
+ throw new IllegalStateException("class with name \"" + className + "\" not found");
+ }
+ }
+ catch(UnsupportedClassVersionError e) {
+ PluginId pluginId = stub.getPluginId();
+ if (pluginId != null) {
+ throw new PluginException(e, pluginId);
+ }
+ else {
+ throw new IllegalStateException(e);
+ }
+ }
+ catch (Exception e) {
+ PluginId pluginId = stub.getPluginId();
+ if (pluginId != null) {
+ throw new PluginException("cannot create class \"" + className + "\"", e, pluginId);
+ }
+ else {
+ throw new IllegalStateException("cannot create class \"" + className + "\"", e);
+ }
+ }
+
+ if (!(obj instanceof AnAction)) {
+ throw new IllegalStateException("class with name '" + className + "' must be an instance of '" + AnAction.class.getName()+"'; got "+obj);
+ }
+
+ AnAction anAction = (AnAction)obj;
+ stub.initAction(anAction);
+ if (StringUtil.isNotEmpty(stub.getText())) {
+ anAction.getTemplatePresentation().setText(stub.getText());
+ }
+ String iconPath = stub.getIconPath();
+ if (iconPath != null) {
+ Class<? extends AnAction> actionClass = anAction.getClass();
+ setIconFromClass(actionClass, actionClass.getClassLoader(), iconPath, anAction.getTemplatePresentation(), stub.getPluginId());
+ }
+ return anAction;
+ }
+
+ private static void processAbbreviationNode(Element e, String id) {
+ final String abbr = e.getAttributeValue(VALUE_ATTR_NAME);
+ if (!StringUtil.isEmpty(abbr)) {
+ final AbbreviationManagerImpl abbreviationManager = ((AbbreviationManagerImpl)AbbreviationManager.getInstance());
+ abbreviationManager.register(abbr, id, true);
+ }
+ }
+
+ @Nullable
+ private static ResourceBundle getActionsResourceBundle(ClassLoader loader, IdeaPluginDescriptor plugin) {
+ @NonNls final String resBundleName = plugin != null && !"com.intellij".equals(plugin.getPluginId().getIdString())
+ ? plugin.getResourceBundleBaseName() : ACTIONS_BUNDLE;
+ ResourceBundle bundle = null;
+ if (resBundleName != null) {
+ bundle = AbstractBundle.getResourceBundle(resBundleName, loader);
+ }
+ return bundle;
+ }
+
+ private static boolean isSecondary(Element element) {
+ return "true".equalsIgnoreCase(element.getAttributeValue(SECONDARY));
+ }
+
+ private static void setIcon(@Nullable final String iconPath,
+ @NotNull String className,
+ @NotNull ClassLoader loader,
+ @NotNull Presentation presentation,
+ final PluginId pluginId) {
+ if (iconPath == null) return;
+
+ try {
+ final Class actionClass = Class.forName(className, true, loader);
+ setIconFromClass(actionClass, loader, iconPath, presentation, pluginId);
+ }
+ catch (ClassNotFoundException e) {
+ LOG.error(e);
+ reportActionError(pluginId, "class with name \"" + className + "\" not found");
+ }
+ catch (NoClassDefFoundError e) {
+ LOG.error(e);
+ reportActionError(pluginId, "class with name \"" + className + "\" not found");
+ }
+ }
+
+ private static void setIconFromClass(@NotNull final Class actionClass,
+ @NotNull final ClassLoader classLoader,
+ @NotNull final String iconPath,
+ @NotNull Presentation presentation,
+ final PluginId pluginId) {
+ final IconLoader.LazyIcon lazyIcon = new IconLoader.LazyIcon() {
+ @Override
+ protected Icon compute() {
+ //try to find icon in idea class path
+ Icon icon = IconLoader.findIcon(iconPath, actionClass, true);
+ if (icon == null) {
+ icon = IconLoader.findIcon(iconPath, classLoader);
+ }
+
+ if (icon == null) {
+ reportActionError(pluginId, "Icon cannot be found in '" + iconPath + "', action '" + actionClass + "'");
+ }
+
+ return icon;
+ }
+
+ @Override
+ public String toString() {
+ return "LazyIcon@ActionManagerImpl (path: " + iconPath + ", action class: " + actionClass + ")";
+ }
+ };
+
+ if (!Registry.is("ide.lazyIconLoading")) {
+ lazyIcon.load();
+ }
+
+ presentation.setIcon(lazyIcon);
+ }
+
+ private static String loadDescriptionForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
+ final String value = element.getAttributeValue(DESCRIPTION);
+ if (bundle != null) {
+ @NonNls final String key = elementType + "." + id + ".description";
+ return CommonBundle.messageOrDefault(bundle, key, value == null ? "" : value);
+ } else {
+ return value;
+ }
+ }
+
+ private static String loadTextForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
+ final String value = element.getAttributeValue(TEXT_ATTR_NAME);
+ return CommonBundle.messageOrDefault(bundle, elementType + "." + id + "." + TEXT_ATTR_NAME, value == null ? "" : value);
+ }
+
+ public static boolean checkRelativeToAction(final String relativeToActionId,
+ @NotNull final Anchor anchor,
+ @NotNull final String actionName,
+ @Nullable final PluginId pluginId) {
+ if ((Anchor.BEFORE == anchor || Anchor.AFTER == anchor) && relativeToActionId == null) {
+ reportActionError(pluginId, actionName + ": \"relative-to-action\" cannot be null if anchor is \"after\" or \"before\"");
+ return false;
+ }
+ return true;
+ }
+
+ @Nullable
+ public static Anchor parseAnchor(final String anchorStr,
+ @Nullable final String actionName,
+ @Nullable final PluginId pluginId) {
+ if (anchorStr == null) {
+ return Anchor.LAST;
+ }
+
+ if (FIRST.equalsIgnoreCase(anchorStr)) {
+ return Anchor.FIRST;
+ }
+ else if (LAST.equalsIgnoreCase(anchorStr)) {
+ return Anchor.LAST;
+ }
+ else if (BEFORE.equalsIgnoreCase(anchorStr)) {
+ return Anchor.BEFORE;
+ }
+ else if (AFTER.equalsIgnoreCase(anchorStr)) {
+ return Anchor.AFTER;
+ }
+ else {
+ reportActionError(pluginId, actionName + ": anchor should be one of the following constants: \"first\", \"last\", \"before\" or \"after\"");
+ return null;
+ }
+ }
+
+ private static void processMouseShortcutNode(Element element, String actionId, PluginId pluginId) {
+ String keystrokeString = element.getAttributeValue(KEYSTROKE_ATTR_NAME);
+ if (keystrokeString == null || keystrokeString.trim().isEmpty()) {
+ reportActionError(pluginId, "\"keystroke\" attribute must be specified for action with id=" + actionId);
+ return;
+ }
+ MouseShortcut shortcut;
+ try {
+ shortcut = KeymapUtil.parseMouseShortcut(keystrokeString);
+ }
+ catch (Exception ex) {
+ reportActionError(pluginId, "\"keystroke\" attribute has invalid value for action with id=" + actionId);
+ return;
+ }
+
+ String keymapName = element.getAttributeValue(KEYMAP_ATTR_NAME);
+ if (keymapName == null || keymapName.isEmpty()) {
+ reportActionError(pluginId, "attribute \"keymap\" should be defined");
+ return;
+ }
+ Keymap keymap = KeymapManager.getInstance().getKeymap(keymapName);
+ if (keymap == null) {
+ reportActionError(pluginId, "keymap \"" + keymapName + "\" not found");
+ return;
+ }
+
+ final String removeOption = element.getAttributeValue(REMOVE_SHORTCUT_ATTR_NAME);
+ if (Boolean.valueOf(removeOption)) {
+ keymap.removeShortcut(actionId, shortcut);
+ } else {
+ keymap.addShortcut(actionId, shortcut);
+ }
+ }
+
+ private static void assertActionIsGroupOrStub(final AnAction action) {
+ if (!(action instanceof ActionGroup || action instanceof ActionStub)) {
+ LOG.error("Action : " + action + "; class: " + action.getClass());
+ }
+ }
+
+ private static void reportActionError(final PluginId pluginId, @NonNls @NotNull String message) {
+ if (pluginId == null) {
+ LOG.error(message);
+ }
+ else {
+ LOG.error(new PluginException(message, null, pluginId));
+ }
+ }
+
+ @NonNls
+ private static String getPluginInfo(@Nullable PluginId id) {
+ if (id != null) {
+ final IdeaPluginDescriptor plugin = PluginManager.getPlugin(id);
+ if (plugin != null) {
+ String name = plugin.getName();
+ if (name == null) {
+ name = id.getIdString();
+ }
+ return " Plugin: " + name;
+ }
+ }
+ return "";
+ }
+
+ private static DataContext getContextBy(Component contextComponent) {
+ final DataManager dataManager = DataManager.getInstance();
+ return contextComponent != null ? dataManager.getDataContext(contextComponent) : dataManager.getDataContext();
+ }
+
@Override
public void initComponent() {}
@@ -213,7 +461,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return new ActionToolbarImpl(place, group, horizontal, decorateButtons, myDataManager, this, (KeymapManagerEx)myKeymapManager);
}
-
private void registerPluginActions() {
final IdeaPluginDescriptor[] plugins = PluginManagerCore.getPlugins();
for (IdeaPluginDescriptor plugin : plugins) {
@@ -229,12 +476,28 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@Override
public AnAction getAction(@NotNull String id) {
- return getActionImpl(id, false);
+ return getActionImpl(id, false, null);
}
- private AnAction getActionImpl(String id, boolean canReturnStub) {
+ @Override
+ public AnAction getAction(@NonNls @NotNull String actionId, @Nullable ProjectType projectType) {
+ return getActionImpl(actionId, false, projectType);
+ }
+
+ private AnAction getActionImpl(String id, boolean canReturnStub, ProjectType projectType) {
synchronized (myLock) {
- AnAction action = (AnAction)myId2Action.get(id);
+ AnAction action;
+ Object o = myId2Action.get(id);
+ if (o == null) {
+ return null;
+ }
+ if (o instanceof AnAction) {
+ action = (AnAction)o;
+ }
+ else {
+ //noinspection unchecked
+ action = ((Map<ProjectType, AnAction>)o).get(projectType);
+ }
if (!canReturnStub && action instanceof ActionStub) {
action = convert((ActionStub)action);
}
@@ -252,61 +515,14 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
LOG.assertTrue(myId2Action.containsKey(stub.getId()));
- AnAction action = (AnAction)myId2Action.remove(stub.getId());
+ AnAction action = myId2Action.remove(stub.getId());
LOG.assertTrue(action != null);
LOG.assertTrue(action.equals(stub));
- Object obj;
- String className = stub.getClassName();
- try {
- Class<?> aClass = Class.forName(className, true, stub.getLoader());
- obj = ReflectionUtil.newInstance(aClass);
- }
- catch (ClassNotFoundException e) {
- PluginId pluginId = stub.getPluginId();
- if (pluginId != null) {
- throw new PluginException("class with name \"" + className + "\" not found", e, pluginId);
- }
- else {
- throw new IllegalStateException("class with name \"" + className + "\" not found");
- }
- }
- catch(UnsupportedClassVersionError e) {
- PluginId pluginId = stub.getPluginId();
- if (pluginId != null) {
- throw new PluginException(e, pluginId);
- }
- else {
- throw new IllegalStateException(e);
- }
- }
- catch (Exception e) {
- PluginId pluginId = stub.getPluginId();
- if (pluginId != null) {
- throw new PluginException("cannot create class \"" + className + "\"", e, pluginId);
- }
- else {
- throw new IllegalStateException("cannot create class \"" + className + "\"", e);
- }
- }
-
- if (!(obj instanceof AnAction)) {
- throw new IllegalStateException("class with name '" + className + "' must be an instance of '" + AnAction.class.getName()+"'; got "+obj);
- }
+ AnAction anAction = convertStub(stub);
- AnAction anAction = (AnAction)obj;
- stub.initAction(anAction);
- if (StringUtil.isNotEmpty(stub.getText())) {
- anAction.getTemplatePresentation().setText(stub.getText());
- }
- String iconPath = stub.getIconPath();
- if (iconPath != null) {
- Class<? extends AnAction> actionClass = anAction.getClass();
- setIconFromClass(actionClass, actionClass.getClassLoader(), iconPath, anAction.getTemplatePresentation(), stub.getPluginId());
- }
-
- myId2Action.put(stub.getId(), obj);
- myAction2Id.put(obj, stub.getId());
+ addToMap(stub.getId(), anAction, stub.getPluginId(), stub.getProjectType() == null ? null : new ProjectType(stub.getProjectType()));
+ myAction2Id.put(anAction, stub.getId());
return anAction;
}
@@ -334,7 +550,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@Override
public boolean isGroup(@NotNull String actionId) {
- return getActionImpl(actionId, true) instanceof ActionGroup;
+ return getActionImpl(actionId, true, null) instanceof ActionGroup;
}
@Override
@@ -344,7 +560,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
@Override
public AnAction getActionOrStub(String id) {
- return getActionImpl(id, true);
+ return getActionImpl(id, true, null);
}
/**
@@ -386,7 +602,8 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return null;
}
- ActionStub stub = new ActionStub(className, id, text, loader, pluginId, iconPath);
+ String projectType = element.getAttributeValue(PROJECT_TYPE);
+ ActionStub stub = new ActionStub(className, id, text, loader, pluginId, iconPath, projectType);
Presentation presentation = stub.getTemplatePresentation();
presentation.setText(text);
@@ -441,99 +658,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void processAbbreviationNode(Element e, String id) {
- final String abbr = e.getAttributeValue(VALUE_ATTR_NAME);
- if (!StringUtil.isEmpty(abbr)) {
- final AbbreviationManagerImpl abbreviationManager = ((AbbreviationManagerImpl)AbbreviationManager.getInstance());
- abbreviationManager.register(abbr, id, true);
- }
- }
-
- @Nullable
- private static ResourceBundle getActionsResourceBundle(ClassLoader loader, IdeaPluginDescriptor plugin) {
- @NonNls final String resBundleName = plugin != null && !"com.intellij".equals(plugin.getPluginId().getIdString())
- ? plugin.getResourceBundleBaseName() : ACTIONS_BUNDLE;
- ResourceBundle bundle = null;
- if (resBundleName != null) {
- bundle = AbstractBundle.getResourceBundle(resBundleName, loader);
- }
- return bundle;
- }
-
- private static boolean isSecondary(Element element) {
- return "true".equalsIgnoreCase(element.getAttributeValue(SECONDARY));
- }
-
- private static void setIcon(@Nullable final String iconPath,
- @NotNull String className,
- @NotNull ClassLoader loader,
- @NotNull Presentation presentation,
- final PluginId pluginId) {
- if (iconPath == null) return;
-
- try {
- final Class actionClass = Class.forName(className, true, loader);
- setIconFromClass(actionClass, loader, iconPath, presentation, pluginId);
- }
- catch (ClassNotFoundException e) {
- LOG.error(e);
- reportActionError(pluginId, "class with name \"" + className + "\" not found");
- }
- catch (NoClassDefFoundError e) {
- LOG.error(e);
- reportActionError(pluginId, "class with name \"" + className + "\" not found");
- }
- }
-
- private static void setIconFromClass(@NotNull final Class actionClass,
- @NotNull final ClassLoader classLoader,
- @NotNull final String iconPath,
- @NotNull Presentation presentation,
- final PluginId pluginId) {
- final IconLoader.LazyIcon lazyIcon = new IconLoader.LazyIcon() {
- @Override
- protected Icon compute() {
- //try to find icon in idea class path
- Icon icon = IconLoader.findIcon(iconPath, actionClass, true);
- if (icon == null) {
- icon = IconLoader.findIcon(iconPath, classLoader);
- }
-
- if (icon == null) {
- reportActionError(pluginId, "Icon cannot be found in '" + iconPath + "', action '" + actionClass + "'");
- }
-
- return icon;
- }
-
- @Override
- public String toString() {
- return "LazyIcon@ActionManagerImpl (path: " + iconPath + ", action class: " + actionClass + ")";
- }
- };
-
- if (!Registry.is("ide.lazyIconLoading")) {
- lazyIcon.load();
- }
-
- presentation.setIcon(lazyIcon);
- }
-
- private static String loadDescriptionForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
- final String value = element.getAttributeValue(DESCRIPTION);
- if (bundle != null) {
- @NonNls final String key = elementType + "." + id + ".description";
- return CommonBundle.messageOrDefault(bundle, key, value == null ? "" : value);
- } else {
- return value;
- }
- }
-
- private static String loadTextForElement(final Element element, final ResourceBundle bundle, final String id, String elementType) {
- final String value = element.getAttributeValue(TEXT_ATTR_NAME);
- return CommonBundle.messageOrDefault(bundle, elementType + "." + id + "." + TEXT_ATTR_NAME, value == null ? "" : value);
- }
-
private AnAction processGroupElement(Element element, final ClassLoader loader, PluginId pluginId) {
final IdeaPluginDescriptor plugin = PluginManager.getPlugin(pluginId);
ResourceBundle bundle = getActionsResourceBundle(loader, plugin);
@@ -723,43 +847,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
myId2GroupId.putValue(myAction2Id.get(action), myAction2Id.get(group));
}
- public static boolean checkRelativeToAction(final String relativeToActionId,
- @NotNull final Anchor anchor,
- @NotNull final String actionName,
- @Nullable final PluginId pluginId) {
- if ((Anchor.BEFORE == anchor || Anchor.AFTER == anchor) && relativeToActionId == null) {
- reportActionError(pluginId, actionName + ": \"relative-to-action\" cannot be null if anchor is \"after\" or \"before\"");
- return false;
- }
- return true;
- }
-
- @Nullable
- public static Anchor parseAnchor(final String anchorStr,
- @Nullable final String actionName,
- @Nullable final PluginId pluginId) {
- if (anchorStr == null) {
- return Anchor.LAST;
- }
-
- if (FIRST.equalsIgnoreCase(anchorStr)) {
- return Anchor.FIRST;
- }
- else if (LAST.equalsIgnoreCase(anchorStr)) {
- return Anchor.LAST;
- }
- else if (BEFORE.equalsIgnoreCase(anchorStr)) {
- return Anchor.BEFORE;
- }
- else if (AFTER.equalsIgnoreCase(anchorStr)) {
- return Anchor.AFTER;
- }
- else {
- reportActionError(pluginId, actionName + ": anchor should be one of the following constants: \"first\", \"last\", \"before\" or \"after\"");
- return null;
- }
- }
-
@Nullable
public AnAction getParentGroup(final String groupId,
@Nullable final String actionName,
@@ -768,10 +855,10 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
reportActionError(pluginId, actionName + ": attribute \"group-id\" should be defined");
return null;
}
- AnAction parentGroup = getActionImpl(groupId, true);
+ AnAction parentGroup = getActionImpl(groupId, true, null);
if (parentGroup == null) {
reportActionError(pluginId, actionName + ": group with id \"" + groupId + "\" isn't registered; action will be added to the \"Other\" group");
- parentGroup = getActionImpl(IdeActions.GROUP_OTHER_MENU, true);
+ parentGroup = getActionImpl(IdeActions.GROUP_OTHER_MENU, true, null);
}
if (!(parentGroup instanceof DefaultActionGroup)) {
reportActionError(pluginId, actionName + ": group with id \"" + groupId + "\" should be instance of " + DefaultActionGroup.class.getName() +
@@ -850,40 +937,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void processMouseShortcutNode(Element element, String actionId, PluginId pluginId) {
- String keystrokeString = element.getAttributeValue(KEYSTROKE_ATTR_NAME);
- if (keystrokeString == null || keystrokeString.trim().isEmpty()) {
- reportActionError(pluginId, "\"keystroke\" attribute must be specified for action with id=" + actionId);
- return;
- }
- MouseShortcut shortcut;
- try {
- shortcut = KeymapUtil.parseMouseShortcut(keystrokeString);
- }
- catch (Exception ex) {
- reportActionError(pluginId, "\"keystroke\" attribute has invalid value for action with id=" + actionId);
- return;
- }
-
- String keymapName = element.getAttributeValue(KEYMAP_ATTR_NAME);
- if (keymapName == null || keymapName.isEmpty()) {
- reportActionError(pluginId, "attribute \"keymap\" should be defined");
- return;
- }
- Keymap keymap = KeymapManager.getInstance().getKeymap(keymapName);
- if (keymap == null) {
- reportActionError(pluginId, "keymap \"" + keymapName + "\" not found");
- return;
- }
-
- final String removeOption = element.getAttributeValue(REMOVE_SHORTCUT_ATTR_NAME);
- if (Boolean.valueOf(removeOption)) {
- keymap.removeShortcut(actionId, shortcut);
- } else {
- keymap.addShortcut(actionId, shortcut);
- }
- }
-
@Nullable
private AnAction processReferenceElement(Element element, PluginId pluginId) {
if (!REFERENCE_ELEMENT_NAME.equals(element.getName())) {
@@ -902,7 +955,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return null;
}
- AnAction action = getActionImpl(ref, true);
+ AnAction action = getActionImpl(ref, true, null);
if (action == null) {
if (!myNotRegisteredInternalActionIds.contains(ref)) {
@@ -936,27 +989,15 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void assertActionIsGroupOrStub(final AnAction action) {
- if (!(action instanceof ActionGroup || action instanceof ActionStub)) {
- LOG.error("Action : " + action + "; class: " + action.getClass());
- }
- }
-
@Override
public void registerAction(@NotNull String actionId, @NotNull AnAction action, @Nullable PluginId pluginId) {
synchronized (myLock) {
- if (myId2Action.containsKey(actionId)) {
- reportActionError(pluginId, "action with the ID \"" + actionId + "\" was already registered. Action being registered is " + action +
- "; Registered action is " +
- myId2Action.get(actionId) + getPluginInfo(pluginId));
- return;
- }
+ if (!addToMap(actionId, action, pluginId, null)) return;
if (myAction2Id.containsKey(action)) {
reportActionError(pluginId, "action was already registered for another ID. ID is " + myAction2Id.get(action) +
getPluginInfo(pluginId));
return;
}
- myId2Action.put(actionId, action);
myId2Index.put(actionId, myRegisteredActionsCount++);
myAction2Id.put(action, actionId);
if (pluginId != null && !(action instanceof ActionGroup)){
@@ -971,28 +1012,31 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private static void reportActionError(final PluginId pluginId, @NonNls @NotNull String message) {
- if (pluginId == null) {
- LOG.error(message);
+ public boolean addToMap(String actionId, AnAction action, PluginId pluginId, ProjectType projectType) {
+ if (myId2Action.containsKey(actionId)) {
+ // make sure id+projectType is unique
+ AnAction o = myId2Action.get(actionId);
+ ChameleonAction chameleonAction;
+ if (o instanceof ChameleonAction) {
+ chameleonAction = (ChameleonAction)o;
+ }
+ else {
+ chameleonAction = new ChameleonAction(o, projectType);
+ myId2Action.put(actionId, chameleonAction);
+ }
+ AnAction old = chameleonAction.addAction(action, projectType);
+ if (old != null) {
+ reportActionError(pluginId,
+ "action with the ID \"" + actionId + "\" was already registered. Action being registered is " + action +
+ "; Registered action is " +
+ myId2Action.get(actionId) + getPluginInfo(pluginId));
+ return false;
+ }
}
else {
- LOG.error(new PluginException(message, null, pluginId));
- }
- }
-
- @NonNls
- private static String getPluginInfo(@Nullable PluginId id) {
- if (id != null) {
- final IdeaPluginDescriptor plugin = PluginManager.getPlugin(id);
- if (plugin != null) {
- String name = plugin.getName();
- if (name == null) {
- name = id.getIdString();
- }
- return " Plugin: " + name;
- }
+ myId2Action.put(actionId, action);
}
- return "";
+ return true;
}
@Override
@@ -1067,6 +1111,12 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
+ //@Override
+ //public AnAction replaceAction(String actionId, @NotNull AnAction newAction) {
+ // synchronized (myLock) {
+ // return replaceAction(actionId, newAction, null);
+ // }
+ //}
@Override
public boolean isActionPopupStackEmpty() {
@@ -1078,13 +1128,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
return myTransparentOnlyUpdate;
}
- //@Override
- //public AnAction replaceAction(String actionId, @NotNull AnAction newAction) {
- // synchronized (myLock) {
- // return replaceAction(actionId, newAction, null);
- // }
- //}
-
private AnAction replaceAction(@NotNull String actionId, @NotNull AnAction newAction, @Nullable PluginId pluginId) {
AnAction oldAction = getActionOrStub(actionId);
if (oldAction != null) {
@@ -1208,8 +1251,6 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
- private int myActionsPreloaded = 0;
-
public void preloadActions() {
if (myPreloadActionsRunnable == null) {
myPreloadActionsRunnable = new Runnable() {
@@ -1281,6 +1322,85 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
+ @Override
+ public ActionCallback tryToExecute(@NotNull final AnAction action, @NotNull final InputEvent inputEvent, @Nullable final Component contextComponent, @Nullable final String place,
+ boolean now) {
+
+ final Application app = ApplicationManager.getApplication();
+ assert app.isDispatchThread();
+
+ final ActionCallback result = new ActionCallback();
+ final Runnable doRunnable = new Runnable() {
+ @Override
+ public void run() {
+ tryToExecuteNow(action, inputEvent, contextComponent, place, result);
+ }
+ };
+
+ if (now) {
+ doRunnable.run();
+ } else {
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(doRunnable);
+ }
+
+ return result;
+ }
+
+ private void tryToExecuteNow(final AnAction action, final InputEvent inputEvent, final Component contextComponent, final String place, final ActionCallback result) {
+ final Presentation presentation = action.getTemplatePresentation().clone();
+
+ IdeFocusManager.findInstanceByContext(getContextBy(contextComponent)).doWhenFocusSettlesDown(new Runnable() {
+ @Override
+ public void run() {
+ final DataContext context = getContextBy(contextComponent);
+
+ AnActionEvent event = new AnActionEvent(
+ inputEvent, context,
+ place != null ? place : ActionPlaces.UNKNOWN,
+ presentation, ActionManagerImpl.this,
+ inputEvent.getModifiersEx()
+ );
+
+ ActionUtil.performDumbAwareUpdate(action, event, false);
+ if (!event.getPresentation().isEnabled()) {
+ result.setRejected();
+ return;
+ }
+
+ ActionUtil.lastUpdateAndCheckDumb(action, event, false);
+ if (!event.getPresentation().isEnabled()) {
+ result.setRejected();
+ return;
+ }
+
+ Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(context);
+ if (component != null && !component.isShowing()) {
+ result.setRejected();
+ return;
+ }
+
+ fireBeforeActionPerformed(action, context, event);
+
+ UIUtil.addAwtListener(new AWTEventListener() {
+ @Override
+ public void eventDispatched(AWTEvent event) {
+ if (event.getID() == WindowEvent.WINDOW_OPENED ||event.getID() == WindowEvent.WINDOW_ACTIVATED) {
+ if (!result.isProcessed()) {
+ final WindowEvent we = (WindowEvent)event;
+ IdeFocusManager.findInstanceByComponent(we.getWindow()).doWhenFocusSettlesDown(result.createSetDoneRunnable());
+ }
+ }
+ }
+ }, AWTEvent.WINDOW_EVENT_MASK, result);
+
+ ActionUtil.performActionDumbAware(action, event);
+ result.setDone();
+ queueActionPerformedEvent(action, context, event);
+ }
+ });
+ }
+
private class MyTimer extends Timer implements ActionListener {
private final List<TimerListener> myTimerListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final List<TimerListener> myTransparentTimerListeners = ContainerUtil.createLockFreeCopyOnWriteList();
@@ -1371,88 +1491,4 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
}
}
}
-
- @Override
- public ActionCallback tryToExecute(@NotNull final AnAction action, @NotNull final InputEvent inputEvent, @Nullable final Component contextComponent, @Nullable final String place,
- boolean now) {
-
- final Application app = ApplicationManager.getApplication();
- assert app.isDispatchThread();
-
- final ActionCallback result = new ActionCallback();
- final Runnable doRunnable = new Runnable() {
- @Override
- public void run() {
- tryToExecuteNow(action, inputEvent, contextComponent, place, result);
- }
- };
-
- if (now) {
- doRunnable.run();
- } else {
- //noinspection SSBasedInspection
- SwingUtilities.invokeLater(doRunnable);
- }
-
- return result;
- }
-
- private void tryToExecuteNow(final AnAction action, final InputEvent inputEvent, final Component contextComponent, final String place, final ActionCallback result) {
- final Presentation presentation = action.getTemplatePresentation().clone();
-
- IdeFocusManager.findInstanceByContext(getContextBy(contextComponent)).doWhenFocusSettlesDown(new Runnable() {
- @Override
- public void run() {
- final DataContext context = getContextBy(contextComponent);
-
- AnActionEvent event = new AnActionEvent(
- inputEvent, context,
- place != null ? place : ActionPlaces.UNKNOWN,
- presentation, ActionManagerImpl.this,
- inputEvent.getModifiersEx()
- );
-
- ActionUtil.performDumbAwareUpdate(action, event, false);
- if (!event.getPresentation().isEnabled()) {
- result.setRejected();
- return;
- }
-
- ActionUtil.lastUpdateAndCheckDumb(action, event, false);
- if (!event.getPresentation().isEnabled()) {
- result.setRejected();
- return;
- }
-
- Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(context);
- if (component != null && !component.isShowing()) {
- result.setRejected();
- return;
- }
-
- fireBeforeActionPerformed(action, context, event);
-
- UIUtil.addAwtListener(new AWTEventListener() {
- @Override
- public void eventDispatched(AWTEvent event) {
- if (event.getID() == WindowEvent.WINDOW_OPENED ||event.getID() == WindowEvent.WINDOW_ACTIVATED) {
- if (!result.isProcessed()) {
- final WindowEvent we = (WindowEvent)event;
- IdeFocusManager.findInstanceByComponent(we.getWindow()).doWhenFocusSettlesDown(result.createSetDoneRunnable());
- }
- }
- }
- }, AWTEvent.WINDOW_EVENT_MASK, result);
-
- ActionUtil.performActionDumbAware(action, event);
- result.setDone();
- queueActionPerformedEvent(action, context, event);
- }
- });
- }
-
- private static DataContext getContextBy(Component contextComponent) {
- final DataManager dataManager = DataManager.getInstance();
- return contextComponent != null ? dataManager.getDataContext(contextComponent) : dataManager.getDataContext();
- }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ChameleonAction.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ChameleonAction.java
new file mode 100644
index 000000000000..4b46dc191c0c
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ChameleonAction.java
@@ -0,0 +1,68 @@
+/*
+ * 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.actionSystem.impl;
+
+import com.intellij.openapi.actionSystem.ActionStub;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectType;
+import com.intellij.openapi.project.ProjectTypeService;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class ChameleonAction extends AnAction {
+
+ private final Map<ProjectType, AnAction> myActions = new HashMap<ProjectType, AnAction>();
+
+ public ChameleonAction(@NotNull AnAction first, ProjectType projectType) {
+ addAction(first, projectType);
+ }
+
+ public AnAction addAction(AnAction action, ProjectType projectType) {
+ if (action instanceof ActionStub) {
+ String type = ((ActionStub)action).getProjectType();
+ action = ActionManagerImpl.convertStub((ActionStub)action);
+ projectType = type == null ? null : new ProjectType(type);
+ }
+ return myActions.put(projectType, action);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ getAction(e).actionPerformed(e);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ }
+
+ private AnAction getAction(AnActionEvent e) {
+ Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
+ ProjectType projectType = ProjectTypeService.getProjectType(project);
+ AnAction action = myActions.get(projectType);
+ if (action == null) action = myActions.get(null);
+ if (action == null) action = myActions.values().iterator().next();
+ return action;
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/config/ActionBean.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/config/ActionBean.java
index 01aa0ff4c49e..4de847213103 100644
--- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/config/ActionBean.java
+++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/config/ActionBean.java
@@ -40,7 +40,6 @@ public class ActionBean {
@Attribute(ActionManagerImpl.ICON_ATTR_NAME)
public String icon;
-
@Attribute(ActionManagerImpl.POPUP_ATTR_NAME)
public String isPopup;
@@ -58,4 +57,7 @@ public class ActionBean {
@Attribute(ActionManagerImpl.OVERRIDES_ATTR_NAME)
public boolean overrides;
+
+ @Attribute(ActionManagerImpl.PROJECT_TYPE)
+ public String projectType;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
index 46fae517170d..e3a36a2e59ab 100644
--- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
@@ -336,25 +336,26 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
private boolean disposeSelf(final boolean checkCanCloseProject) {
- final CommandProcessor commandProcessor = CommandProcessor.getInstance();
- final boolean[] canClose = {true};
- for (final Project project : ProjectManagerEx.getInstanceEx().getOpenProjects()) {
- try {
- commandProcessor.executeCommand(project, new Runnable() {
- @Override
- public void run() {
- final ProjectManagerImpl manager = (ProjectManagerImpl)ProjectManagerEx.getInstanceEx();
- if (!manager.closeProject(project, true, true, checkCanCloseProject)) {
- canClose[0] = false;
+ final ProjectManagerImpl manager = (ProjectManagerImpl)ProjectManagerEx.getInstanceEx();
+ if (manager != null) {
+ final boolean[] canClose = {true};
+ for (final Project project : manager.getOpenProjects()) {
+ try {
+ CommandProcessor.getInstance().executeCommand(project, new Runnable() {
+ @Override
+ public void run() {
+ if (!manager.closeProject(project, true, true, checkCanCloseProject)) {
+ canClose[0] = false;
+ }
}
- }
- }, ApplicationBundle.message("command.exit"), null);
- }
- catch (Throwable e) {
- LOG.error(e);
- }
- if (!canClose[0]) {
- return false;
+ }, ApplicationBundle.message("command.exit"), null);
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ }
+ if (!canClose[0]) {
+ return false;
+ }
}
}
runWriteAction(new Runnable() {
@@ -529,9 +530,13 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
}
@Override
- public void load(String path) throws IOException, InvalidDataException {
- getStateStore().setOptionsPath(path);
- getStateStore().setConfigPath(PathManager.getConfigPath());
+ public void load(@Nullable String optionsPath) throws IOException {
+ load(PathManager.getConfigPath(), optionsPath);
+ }
+
+ public void load(@NotNull String configPath, @Nullable String optionsPath) throws IOException {
+ getStateStore().setOptionsPath(optionsPath);
+ getStateStore().setConfigPath(configPath);
myIsFiringLoadingEvent = true;
try {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
index 41942960ab04..a00533d3244b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ApplicationStoreImpl.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.NamedJDOMExternalizable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.Collection;
@@ -36,13 +37,14 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
private static final String XML_EXTENSION = ".xml";
private static final String DEFAULT_STORAGE_SPEC = StoragePathMacros.APP_CONFIG + "/" + PathManager.DEFAULT_OPTIONS_FILE_NAME + XML_EXTENSION;
private static final String OPTIONS_MACRO = "OPTIONS";
- private static final String CONFIG_MACRO = "ROOT_CONFIG";
private static final String ROOT_ELEMENT_NAME = "application";
private final ApplicationImpl myApplication;
private final StateStorageManager myStateStorageManager;
private final DefaultsStateStorage myDefaultsStateStorage;
+ private String myConfigPath;
+
// created from PicoContainer
@SuppressWarnings({"UnusedDeclaration"})
public ApplicationStoreImpl(final ApplicationImpl application, PathMacroManager pathMacroManager) {
@@ -53,23 +55,24 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
return new FileBasedStorage.FileStorageData(ROOT_ELEMENT_NAME);
}
+ @Nullable
@Override
protected String getOldStorageSpec(Object component, final String componentName, final StateStorageOperation operation) {
- final String fileName;
-
if (component instanceof NamedJDOMExternalizable) {
- fileName = StoragePathMacros.APP_CONFIG + "/" + ((NamedJDOMExternalizable)component).getExternalFileName() + XML_EXTENSION;
+ return StoragePathMacros.APP_CONFIG + "/" + ((NamedJDOMExternalizable)component).getExternalFileName() + XML_EXTENSION;
}
else {
- fileName = DEFAULT_STORAGE_SPEC;
+ return DEFAULT_STORAGE_SPEC;
}
-
- return fileName;
}
@Override
protected String getVersionsFilePath() {
- return PathManager.getConfigPath() + "/options/appComponentVersions.xml";
+ String configPath = myConfigPath;
+ if (configPath == null) {
+ configPath = PathManager.getConfigPath();
+ }
+ return configPath + "/options/appComponentVersions.xml";
}
@Override
@@ -97,7 +100,8 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
@Override
public void setConfigPath(@NotNull final String configPath) {
- myStateStorageManager.addMacro(CONFIG_MACRO, configPath);
+ myStateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.ROOT_CONFIG), configPath);
+ myConfigPath = configPath;
}
@Override
@@ -150,6 +154,7 @@ class ApplicationStoreImpl extends ComponentStoreImpl implements IApplicationSto
return myStateStorageManager;
}
+ @Nullable
@Override
protected StateStorage getDefaultsStorage() {
return myDefaultsStateStorage;
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java
index 01cc0fb987b9..25dd8a05cab3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/BaseFileConfigurableStoreImpl.java
@@ -16,7 +16,6 @@
package com.intellij.openapi.components.impl.stores;
import com.intellij.openapi.components.*;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.impl.ProjectManagerImpl;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -28,8 +27,6 @@ import java.util.ArrayList;
import java.util.Set;
abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.components.impl.stores.BaseFileConfigurableStoreImpl");
-
@NonNls protected static final String VERSION_OPTION = "version";
@NonNls public static final String ATTRIBUTE_NAME = "name";
private final ComponentManager myComponentManager;
@@ -119,6 +116,7 @@ abstract class BaseFileConfigurableStoreImpl extends ComponentStoreImpl {
return (BaseStorageData) getMainStorage().getStorageData(false);
}
+ @Nullable
@Override
protected StateStorage getDefaultsStorage() {
return myDefaultsStateStorage;
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
index 575717f455f7..fc2017b57a4a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ComponentStoreImpl.java
@@ -41,8 +41,7 @@ import java.util.*;
@SuppressWarnings({"deprecation"})
public abstract class ComponentStoreImpl implements IComponentStore {
-
- private static final Logger LOG = Logger.getInstance("#com.intellij.components.ComponentStoreImpl");
+ private static final Logger LOG = Logger.getInstance(ComponentStoreImpl.class);
private final Map<String, Object> myComponents = Collections.synchronizedMap(new THashMap<String, Object>());
private final List<SettingsSavingComponent> mySettingsSavingComponents = Collections.synchronizedList(new ArrayList<SettingsSavingComponent>());
@Nullable private SaveSessionImpl mySession;
@@ -53,9 +52,8 @@ public abstract class ComponentStoreImpl implements IComponentStore {
return getStateStorageManager().getStateStorage(storageSpec);
}
- protected StateStorage getDefaultsStorage() {
- throw new UnsupportedOperationException("Method getDefaultsStorage is not supported in " + getClass());
- }
+ @Nullable
+ protected abstract StateStorage getDefaultsStorage();
@Override
public void initComponent(@NotNull final Object component, final boolean service) {
@@ -143,12 +141,10 @@ public abstract class ComponentStoreImpl implements IComponentStore {
private <T> void commitPersistentComponent(@NotNull final PersistentStateComponent<T> persistentStateComponent,
@NotNull StateStorageManager.ExternalizationSession session) {
- Storage[] storageSpecs = getComponentStorageSpecs(persistentStateComponent, StateStorageOperation.WRITE);
-
T state = persistentStateComponent.getState();
if (state != null) {
- session
- .setState(storageSpecs, persistentStateComponent, getComponentName(persistentStateComponent), state);
+ Storage[] storageSpecs = getComponentStorageSpecs(persistentStateComponent, StateStorageOperation.WRITE);
+ session.setState(storageSpecs, persistentStateComponent, getComponentName(persistentStateComponent), state);
}
}
@@ -276,13 +272,12 @@ public abstract class ComponentStoreImpl implements IComponentStore {
@NotNull
private static <T> Class<T> getComponentStateClass(@NotNull final PersistentStateComponent<T> persistentStateComponent) {
final Class persistentStateComponentClass = PersistentStateComponent.class;
+
Class componentClass = persistentStateComponent.getClass();
nextSuperClass:
while (true) {
- final Class[] interfaces = componentClass.getInterfaces();
-
- for (Class anInterface : interfaces) {
+ for (Class anInterface : componentClass.getInterfaces()) {
if (anInterface.equals(persistentStateComponentClass)) {
break nextSuperClass;
}
@@ -292,7 +287,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
}
final Type type = ReflectionUtil.resolveVariable(persistentStateComponentClass.getTypeParameters()[0], componentClass);
-
+ assert type != null;
//noinspection unchecked
return (Class<T>)ReflectionUtil.getRawType(type);
}
@@ -319,14 +314,12 @@ public abstract class ComponentStoreImpl implements IComponentStore {
protected <T> Storage[] getComponentStorageSpecs(@NotNull final PersistentStateComponent<T> persistentStateComponent,
final StateStorageOperation operation) throws StateStorageException {
final State stateSpec = getStateSpec(persistentStateComponent);
-
final Storage[] storages = stateSpec.storages();
-
- if (storages.length == 1) return storages;
-
+ if (storages.length == 1) {
+ return storages;
+ }
assert storages.length > 0;
-
final Class<StorageAnnotationsDefaultValues.NullStateStorageChooser> defaultClass =
StorageAnnotationsDefaultValues.NullStateStorageChooser.class;
@@ -340,14 +333,11 @@ public abstract class ComponentStoreImpl implements IComponentStore {
}
else {
try {
- //noinspection unchecked
- final StateStorageChooser<PersistentStateComponent<T>> storageChooser = storageChooserClass.newInstance();
+ @SuppressWarnings("unchecked")
+ StateStorageChooser<PersistentStateComponent<T>> storageChooser = ReflectionUtil.newInstance(storageChooserClass);
return storageChooser.selectStorages(storages, persistentStateComponent, operation);
}
- catch (InstantiationException e) {
- throw new StateStorageException(e);
- }
- catch (IllegalAccessException e) {
+ catch (RuntimeException e) {
throw new StateStorageException(e);
}
}
@@ -404,7 +394,7 @@ public abstract class ComponentStoreImpl implements IComponentStore {
}
catch (StateStorageException e) {
LOG.info(e);
- throw new IOException(e.getMessage());
+ throw new IOException(e.getMessage(), e);
}
return this;
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
index 48247b2de866..6f0c3b8122cf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/DefaultProjectStoreImpl.java
@@ -159,8 +159,8 @@ public class DefaultProjectStoreImpl extends ProjectStoreImpl {
}
@Override
- public String expandMacros(final String file) {
- throw new UnsupportedOperationException("Method expandMacroses not implemented in " + getClass());
+ public String expandMacros(@NotNull String file) {
+ throw new UnsupportedOperationException("Method expandMacros not implemented in " + getClass());
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java
index 574823767d9b..2120030db2c1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/OldStreamProviderAdapter.java
@@ -55,7 +55,7 @@ final class OldStreamProviderAdapter extends StreamProvider implements CurrentUs
}
@Override
- public void deleteFile(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
+ public void delete(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
if (myRoamingType == roamingType) {
myProvider.deleteFile(fileSpec, roamingType);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java
index f6a4e11e5aa5..0eed50a65131 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/ProjectStateStorageManager.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.components.*;
import com.intellij.openapi.project.impl.ProjectImpl;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
import java.util.Map;
@@ -47,6 +48,7 @@ class ProjectStateStorageManager extends StateStorageManagerImpl {
return new ProjectStoreImpl.IprStorageData(ROOT_TAG_NAME, myProject);
}
+ @Nullable
@Override
protected String getOldStorageSpec(Object component, final String componentName, final StateStorageOperation operation) throws
StateStorageException {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
index 0e2828e988a3..68d882d2b204 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManager.java
@@ -58,7 +58,7 @@ public interface StateStorageManager {
StateStorage getOldStorage(Object component, String componentName, StateStorageOperation operation) throws StateStorageException;
@Nullable
- String expandMacros(String file);
+ String expandMacros(@NotNull String file);
@Deprecated
void registerStreamProvider(@SuppressWarnings("deprecation") StreamProvider streamProvider, final RoamingType type);
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
index 1b7da8fc2144..431c9a97820c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StateStorageManagerImpl.java
@@ -331,7 +331,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
@Override
@Nullable
- public synchronized String expandMacros(final String file) {
+ public synchronized String expandMacros(@NotNull String file) {
final Matcher matcher = MACRO_PATTERN.matcher(file);
while (matcher.find()) {
String m = matcher.group(1);
@@ -427,6 +427,7 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
return getFileStateStorage(getOldStorageSpec(component, componentName, operation));
}
+ @Nullable
protected abstract String getOldStorageSpec(Object component, final String componentName, final StateStorageOperation operation)
throws StateStorageException;
@@ -615,11 +616,11 @@ public abstract class StateStorageManagerImpl implements StateStorageManager, Di
}
@Override
- public void deleteFile(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
+ public void delete(@NotNull String fileSpec, @NotNull RoamingType roamingType) {
for (StreamProvider streamProvider : myStreamProviders) {
try {
if (streamProvider.isEnabled() && streamProvider.isApplicable(fileSpec, roamingType)) {
- streamProvider.deleteFile(fileSpec, roamingType);
+ streamProvider.delete(fileSpec, roamingType);
}
}
catch (Exception e) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
index 73aea37d6444..bd732705446a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StorageUtil.java
@@ -113,19 +113,25 @@ public class StorageUtil {
@Nullable
static VirtualFile save(@NotNull IFile file, Parent element, Object requestor) throws StateStorageException {
try {
- VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
- Couple<String> pair = loadFile(vFile);
- String text = JDOMUtil.writeParent(element, pair.second);
-
+ String lineSeparator;
+ String oldText;
if (file.exists()) {
- if (text.equals(pair.first)) {
- return null;
- }
+ VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
+ Couple<String> pair = loadFile(vFile);
+ lineSeparator = pair.second;
+ oldText = pair.first;
}
else {
+ oldText = null;
+ lineSeparator = SystemProperties.getLineSeparator();
file.createParentDirs();
}
+ String text = JDOMUtil.writeParent(element, lineSeparator);
+ if (text.equals(oldText)) {
+ return null;
+ }
+
// mark this action as modifying the file which daemon analyzer should ignore
AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(DocumentRunnable.IgnoreDocumentRunnable.class);
try {
@@ -245,6 +251,7 @@ public class StorageUtil {
}
}
+ @NotNull
public static BufferExposingByteArrayOutputStream documentToBytes(@NotNull Document document, boolean useSystemLineSeparator) throws IOException {
BufferExposingByteArrayOutputStream out = new BufferExposingByteArrayOutputStream(512);
OutputStreamWriter writer = new OutputStreamWriter(out, CharsetToolkit.UTF8_CHARSET);
@@ -271,9 +278,9 @@ public class StorageUtil {
}
}
- public static void deleteContent(@NotNull StreamProvider provider, @NotNull String fileSpec, @NotNull RoamingType type) {
+ public static void delete(@NotNull StreamProvider provider, @NotNull String fileSpec, @NotNull RoamingType type) {
if (provider.isApplicable(fileSpec, type)) {
- provider.deleteFile(fileSpec, type);
+ provider.delete(fileSpec, type);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
index cf77ee377cf1..ec57d8c63601 100644
--- a/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/stores/StreamProvider.java
@@ -47,5 +47,8 @@ public abstract class StreamProvider {
return Collections.emptyList();
}
- public abstract void deleteFile(@NotNull String fileSpec, @NotNull RoamingType roamingType);
+ /**
+ * Delete file or directory
+ */
+ public abstract void delete(@NotNull String fileSpec, @NotNull RoamingType roamingType);
} \ No newline at end of file
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/ApplicationStarterBase.java b/platform/platform-impl/src/com/intellij/openapi/diff/ApplicationStarterBase.java
index 21e9f7595082..b508686ade00 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/ApplicationStarterBase.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/ApplicationStarterBase.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.
@@ -37,7 +37,7 @@ import java.util.Arrays;
* @author Konstantin Bulenkov
*/
@SuppressWarnings({"UseOfSystemOutOrSystemErr", "CallToPrintStackTrace"})
-public abstract class ApplicationStarterBase implements ApplicationStarterEx {
+public abstract class ApplicationStarterBase extends ApplicationStarterEx {
private final String myCommandName;
private final int[] myArgsCount;
@@ -52,6 +52,11 @@ public abstract class ApplicationStarterBase implements ApplicationStarterEx {
}
@Override
+ public boolean isHeadless() {
+ return false;
+ }
+
+ @Override
public void processExternalCommandLine(String[] args) {
if (!checkArguments(args)) {
Messages.showMessageDialog(getUsageMessage(), StringUtil.toTitleCase(getCommandName()), Messages.getInformationIcon());
@@ -174,4 +179,9 @@ public abstract class ApplicationStarterBase implements ApplicationStarterEx {
}
return file;
}
+
+ @Override
+ public boolean canProcessExternalCommandLine() {
+ return true;
+ }
}
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/DiffApplication.java b/platform/platform-impl/src/com/intellij/openapi/diff/DiffApplication.java
index ceb075a17095..742a405f350e 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/DiffApplication.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/DiffApplication.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.
diff --git a/platform/platform-api/src/com/intellij/openapi/diff/MergeApplication.java b/platform/platform-impl/src/com/intellij/openapi/diff/MergeApplication.java
index b2e29f1bc88d..0c088929ea49 100644
--- a/platform/platform-api/src/com/intellij/openapi/diff/MergeApplication.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/MergeApplication.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.
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 ec7a316357e2..3ad1a58a6732 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
@@ -93,7 +93,7 @@ public class DiffPanelOptions {
while (window instanceof DialogWrapperDialog) {
DialogWrapperDialog dlg = (DialogWrapperDialog)window;
window = window.getParent();
- dlg.getDialogWrapper().close(DialogWrapper.CLOSE_EXIT_CODE);
+ dlg.getDialogWrapper().doCancelAction();
}
return true;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java
index 2a5a01b43ca5..a67a6ad5af71 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.diff.impl;
+import com.intellij.codeStyle.CodeStyleFacade;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.DiffContentUtil;
@@ -84,11 +85,22 @@ public class DiffUtil {
}
public static EditorEx createEditor(Document document, Project project, boolean isViewer) {
+ return createEditor(document, project, isViewer, null);
+ }
+
+ public static EditorEx createEditor(Document document, Project project, boolean isViewer, @Nullable FileType fileType) {
EditorFactory factory = EditorFactory.getInstance();
EditorEx editor = (EditorEx)(isViewer ? factory.createViewer(document, project) : factory.createEditor(document, project));
editor.putUserData(DiffManagerImpl.EDITOR_IS_DIFF_KEY, Boolean.TRUE);
editor.setSoftWrapAppliancePlace(SoftWrapAppliancePlaces.VCS_DIFF);
editor.getGutterComponentEx().revalidateMarkup();
+
+ if (fileType != null && project != null && !project.isDisposed()) {
+ CodeStyleFacade codeStyleFacade = CodeStyleFacade.getInstance(project);
+ editor.getSettings().setTabSize(codeStyleFacade.getTabSize(fileType));
+ editor.getSettings().setUseTabCharacter(codeStyleFacade.useTabCharacter(fileType));
+ }
+
return editor;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BaseExternalTool.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BaseExternalTool.java
index 9ae17ec50df0..d4fbf23aa6c4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BaseExternalTool.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/BaseExternalTool.java
@@ -46,7 +46,7 @@ abstract class BaseExternalTool implements DiffTool {
myToolProperty = toolProperty;
}
- public final boolean canShow(DiffRequest request) {
+ public final boolean canShow(@NotNull DiffRequest request) {
if (!isEnabled() || StringUtil.isEmpty(getToolPath())) return false;
return isAvailable(request);
}
@@ -56,10 +56,10 @@ abstract class BaseExternalTool implements DiffTool {
return null;
}
- public abstract boolean isAvailable(DiffRequest request);
+ public abstract boolean isAvailable(@NotNull DiffRequest request);
@Nullable
- protected ContentExternalizer externalize(final DiffRequest request, final int index) {
+ protected ContentExternalizer externalize(@NotNull DiffRequest request, final int index) {
final VirtualFile file = getLocalFile(request.getContents()[index].getFile());
if (LocalFileExternalizer.canExternalizeAsFile(file)) {
@@ -81,7 +81,8 @@ abstract class BaseExternalTool implements DiffTool {
return myEnableProperty.value(getProperties());
}
- protected List<String> getParameters(DiffRequest request) throws Exception {
+ @NotNull
+ protected List<String> getParameters(@NotNull DiffRequest request) throws Exception {
final String p1 = convertToPath(request, 0);
final String p2 = convertToPath(request, 1);
final List<String> params = new ArrayList<String>();
@@ -91,12 +92,8 @@ abstract class BaseExternalTool implements DiffTool {
}
public void show(DiffRequest request) {
- for (DiffContent diffContent : request.getContents()) {
- Document document = diffContent.getDocument();
- if (document != null) {
- FileDocumentManager.getInstance().saveDocument(document);
- }
- }
+ saveContents(request);
+
GeneralCommandLine commandLine = new GeneralCommandLine();
commandLine.setExePath(getToolPath());
try {
@@ -109,6 +106,15 @@ abstract class BaseExternalTool implements DiffTool {
}
}
+ protected void saveContents(DiffRequest request) {
+ for (DiffContent diffContent : request.getContents()) {
+ Document document = diffContent.getDocument();
+ if (document != null) {
+ FileDocumentManager.getInstance().saveDocument(document);
+ }
+ }
+ }
+
@Nullable
protected String convertToPath(DiffRequest request, int index) throws Exception {
final ContentExternalizer externalize = externalize(request, index);
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java
index 0594ab09c0c5..6f661acf9463 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFiles.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.DiffRequest;
import com.intellij.openapi.diff.impl.DiffUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
/**
* @author Konstantin Bulenkov
@@ -30,7 +31,7 @@ class ExtCompareFiles extends BaseExternalTool {
super(DiffManagerImpl.ENABLE_FILES, DiffManagerImpl.FILES_TOOL);
}
- public boolean isAvailable(DiffRequest request) {
+ public boolean isAvailable(@NotNull DiffRequest request) {
final DiffContent[] contents = request.getContents();
for (DiffContent content : contents) {
final VirtualFile file = getLocalFile(content.getFile());
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java
index 14c0a9607293..6260176d3e26 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtCompareFolders.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.diff.impl.external;
import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.DiffRequest;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -31,7 +32,7 @@ class ExtCompareFolders extends BaseExternalTool {
}
@Override
- public boolean isAvailable(DiffRequest request) {
+ public boolean isAvailable(@NotNull DiffRequest request) {
final DiffContent[] contents = request.getContents();
if (contents.length != 2) return false;
if (externalize(request, 0) == null) return false;
@@ -40,7 +41,7 @@ class ExtCompareFolders extends BaseExternalTool {
}
@Nullable
- protected ContentExternalizer externalize(DiffRequest request, int index) {
+ protected ContentExternalizer externalize(@NotNull DiffRequest request, int index) {
final VirtualFile file = request.getContents()[index].getFile();
if (!isLocalDirectory(file)) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtMergeFiles.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtMergeFiles.java
index 82313a5c9c35..cfee691a1f1f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtMergeFiles.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/external/ExtMergeFiles.java
@@ -15,10 +15,21 @@
*/
package com.intellij.openapi.diff.impl.external;
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.util.ExecutionErrorDialog;
+import com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.diff.DiffContent;
import com.intellij.openapi.diff.DiffRequest;
import com.intellij.openapi.diff.impl.mergeTool.MergeRequestImpl;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.TimeoutUtil;
+import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@@ -34,7 +45,8 @@ public class ExtMergeFiles extends BaseExternalTool {
}
@Override
- public boolean isAvailable(DiffRequest request) {
+ public boolean isAvailable(@NotNull DiffRequest request) {
+ if (!(request instanceof MergeRequestImpl)) return false;
DiffContent[] contents = request.getContents();
if (contents.length != 3) return false;
if (externalize(request, 0) == null) return false;
@@ -45,7 +57,8 @@ public class ExtMergeFiles extends BaseExternalTool {
}
@Override
- protected List<String> getParameters(DiffRequest request) throws Exception {
+ @NotNull
+ protected List<String> getParameters(@NotNull DiffRequest request) throws Exception {
final List<String> params = new ArrayList<String>();
String result = ((MergeRequestImpl)request).getResultContent().getFile().getPath();
String left = externalize(request, 0).getContentFile().getPath();
@@ -60,4 +73,41 @@ public class ExtMergeFiles extends BaseExternalTool {
}
return params;
}
+
+ @Override
+ public void show(@NotNull DiffRequest request) {
+ saveContents(request);
+
+ int result = DialogWrapper.CANCEL_EXIT_CODE;
+
+ GeneralCommandLine commandLine = new GeneralCommandLine();
+ commandLine.setExePath(getToolPath());
+ try {
+ commandLine.addParameters(getParameters(request));
+ commandLine.createProcess();
+
+ ProgressManager.getInstance().run(new Task.Modal(request.getProject(), "Launching external tool", false) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ indicator.setIndeterminate(true);
+ TimeoutUtil.sleep(1000);
+ }
+ });
+
+ if (Messages.YES == Messages.showYesNoDialog(request.getProject(),
+ "Press \"Mark as Resolved\" when you finish resolving conflicts in the external tool",
+ "Merge In External Tool", "Mark as Resolved", "Revert", null)) {
+ result = DialogWrapper.OK_EXIT_CODE;
+ }
+ ((MergeRequestImpl)request).getResultContent().getFile().refresh(false, false);
+ // We can actually check exit code of external tool, but some of them could work with tabs -> do not close at all
+ }
+ catch (Exception e) {
+ ExecutionErrorDialog
+ .show(new ExecutionException(e.getMessage()), DiffBundle.message("cant.launch.diff.tool.error.message"), request.getProject());
+ }
+ finally {
+ ((MergeRequestImpl)request).setResult(result);
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java
index 0632b56d0f0e..dabaf5f1f030 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/EditorPlaceHolder.java
@@ -93,7 +93,7 @@ class EditorPlaceHolder extends DiffMarkup implements DiffVersionComponent {
} else {
document = new DocumentImpl("Can not show", true);
final EditorFactory editorFactory = EditorFactory.getInstance();
- myEditor = DiffUtil.createEditor(document, getProject(), true);
+ myEditor = DiffUtil.createEditor(document, getProject(), true, content.getContentType());
addDisposable(new Disposable() {
public void dispose() {
editorFactory.releaseEditor(myEditor);
@@ -105,7 +105,7 @@ class EditorPlaceHolder extends DiffMarkup implements DiffVersionComponent {
}
else {
final EditorFactory editorFactory = EditorFactory.getInstance();
- myEditor = DiffUtil.createEditor(document, getProject(), false);
+ myEditor = DiffUtil.createEditor(document, getProject(), false, content.getContentType());
addDisposable(new Disposable() {
public void dispose() {
editorFactory.releaseEditor(myEditor);
diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java
index f6cd904c9503..3bc3e90b81b3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java
+++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java
@@ -136,16 +136,13 @@ public class SyncScrollSupport implements Disposable {
Editor slaveEditor = sidesContainer.getEditor(masterSide.otherSide());
if (slaveEditor == null) return;
- ScrollingModel scrollingModel = slaveEditor.getScrollingModel();
- scrollingModel.disableAnimation();
- scrollingModel.scrollHorizontally(newScrollOffset);
- scrollingModel.enableAnimation();
+ doScrollHorizontally(slaveEditor.getScrollingModel(), newScrollOffset);
}
private static void syncVerticalScroll(@NotNull ScrollingContext context,
@NotNull Rectangle newRectangle,
@NotNull Rectangle oldRectangle) {
- if (newRectangle.y == oldRectangle.y && newRectangle.height == oldRectangle.height) return;
+ if (newRectangle.y == oldRectangle.y) return;
EditingSides sidesContainer = context.getSidesContainer();
FragmentSide masterSide = context.getMasterSide();
FragmentSide masterDiffSide = context.getMasterDiffSide();
@@ -155,42 +152,55 @@ public class SyncScrollSupport implements Disposable {
if (master == null || slave == null) return;
+ int masterVerticalScrollOffset = master.getScrollingModel().getVerticalScrollOffset();
+ int slaveVerticalScrollOffset = slave.getScrollingModel().getVerticalScrollOffset();
+
Rectangle viewRect = master.getScrollingModel().getVisibleArea();
int middleY = viewRect.height / 3;
- int masterVerticalScrollOffset = getScrollOffset(master);
- int slaveVerticalScrollOffset = getScrollOffset(slave);
+ if (master.getDocument().getTextLength() == 0) return;
LogicalPosition masterPos = master.xyToLogicalPosition(new Point(viewRect.x, masterVerticalScrollOffset + middleY));
int masterCenterLine = masterPos.line;
- if (masterCenterLine > master.getDocument().getLineCount()) {
- masterCenterLine = master.getDocument().getLineCount();
+ int scrollToLine = sidesContainer.getLineBlocks().transform(masterDiffSide, masterCenterLine);
+
+ int offset;
+ if (scrollToLine < 0) {
+ offset = slaveVerticalScrollOffset + newRectangle.y - oldRectangle.y;
}
- int scrollToLine = sidesContainer.getLineBlocks().transform(masterDiffSide, masterCenterLine) + 1;
- int actualLine = scrollToLine - 1;
+ else {
+ int correction = (masterVerticalScrollOffset + middleY) % master.getLineHeight();
+ Point point = slave.logicalPositionToXY(new LogicalPosition(scrollToLine, masterPos.column));
+ offset = point.y - middleY + correction;
+ }
+
+ int deltaHeaderOffset = getHeaderOffset(slave) - getHeaderOffset(master);
+ doScrollVertically(slave.getScrollingModel(), offset + deltaHeaderOffset);
+ }
+ private static int getHeaderOffset(@NotNull final Editor editor) {
+ final JComponent header = editor.getHeaderComponent();
+ return header == null ? 0 : header.getHeight();
+ }
- slave.getScrollingModel().disableAnimation();
+ private static void doScrollVertically(@NotNull ScrollingModel model, int offset) {
+ model.disableAnimation();
try {
- if (scrollToLine <= 0) {
- int offset = newRectangle.y - oldRectangle.y;
- slave.getScrollingModel().scrollVertically(slaveVerticalScrollOffset + offset);
- }
- else {
- int correction = (masterVerticalScrollOffset + middleY) % master.getLineHeight();
- Point point = slave.logicalPositionToXY(new LogicalPosition(actualLine, masterPos.column));
- slave.getScrollingModel().scrollVertically(point.y - middleY + correction);
- }
- } finally {
- slave.getScrollingModel().enableAnimation();
+ model.scrollVertically(offset);
+ }
+ finally {
+ model.enableAnimation();
}
}
- private static int getScrollOffset(@NotNull final Editor editor) {
- final JComponent header = editor.getHeaderComponent();
- int headerOffset = header == null ? 0 : header.getHeight();
-
- return editor.getScrollingModel().getVerticalScrollOffset() - headerOffset;
+ private static void doScrollHorizontally(@NotNull ScrollingModel model, int offset) {
+ model.disableAnimation();
+ try {
+ model.scrollHorizontally(offset);
+ }
+ finally {
+ model.enableAnimation();
+ }
}
public static void scrollEditor(@NotNull Editor editor, int logicalLine) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java
index 452d7e144356..cf3c196a9d78 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/colors/impl/EditorColorsManagerImpl.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.ExportableComponent;
import com.intellij.openapi.components.NamedComponent;
import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.colors.EditorColorsListener;
@@ -67,7 +68,7 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Name
private final DefaultColorSchemesManager myDefaultColorSchemesManager;
private final SchemesManager<EditorColorsScheme, EditorColorsSchemeImpl> mySchemesManager;
@NonNls private static final String NAME_ATTR = "name";
- private static final String FILE_SPEC = "$ROOT_CONFIG$/colors";
+ private static final String FILE_SPEC = StoragePathMacros.ROOT_CONFIG + "/colors";
private static final String FILE_EXT = ".icls";
public EditorColorsManagerImpl(DefaultColorSchemesManager defaultColorSchemesManager, SchemesManagerFactory schemesManagerFactory) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
index 216429557cea..7d9973fed2d3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
@@ -407,7 +407,7 @@ public final class EditorUtil {
IterationState state = new IterationState(editorImpl, start, end, false);
int fontType = state.getMergedAttributes().getFontType();
int column = currentColumn[0];
- int spaceSize = getSpaceWidth(fontType, editorImpl);
+ int plainSpaceSize = getSpaceWidth(Font.PLAIN, editorImpl);
for (; column < columnNumber && offset < end; offset++) {
if (offset >= state.getEndOffset()) {
state.advance();
@@ -417,7 +417,7 @@ public final class EditorUtil {
char c = text.charAt(offset);
if (c == '\t') {
final int newX = nextTabStop(x, editorImpl);
- final int columns = columnsNumber(newX - x, spaceSize);
+ final int columns = columnsNumber(newX - x, plainSpaceSize);
if (debugBuffer != null) {
debugBuffer.append(String.format(
"Processing tabulation at the offset %d. Current X: %d, new X: %d, current column: %d, new column: %d%n",
@@ -556,11 +556,11 @@ public final class EditorUtil {
return nextTabStop(x, getSpaceWidth(Font.PLAIN, editor), tabSize);
}
- public static int nextTabStop(int x, int spaceWidth, int tabSize) {
+ public static int nextTabStop(int x, int plainSpaceWidth, int tabSize) {
if (tabSize <= 0) {
- return x + spaceWidth;
+ return x + plainSpaceWidth;
}
- tabSize *= spaceWidth;
+ tabSize *= plainSpaceWidth;
int nTabs = x / tabSize;
return (nTabs + 1) * tabSize;
@@ -617,15 +617,15 @@ public final class EditorUtil {
* @param c target char
* @param x <code>'x'</code> coordinate of the line where given char is represented that indicates char end location
* @param prevX <code>'x'</code> coordinate of the line where given char is represented that indicates char start location
- * @param spaceSize <code>'space'</code> symbol width
+ * @param plainSpaceSize <code>'space'</code> symbol width (in plain font style)
* @return number of columns necessary for representation of the given char on a screen.
*/
- public static int columnsNumber(char c, int x, int prevX, int spaceSize) {
+ public static int columnsNumber(char c, int x, int prevX, int plainSpaceSize) {
if (c != '\t') {
return 1;
}
- int result = (x - prevX) / spaceSize;
- if ((x - prevX) % spaceSize > 0) {
+ int result = (x - prevX) / plainSpaceSize;
+ if ((x - prevX) % plainSpaceSize > 0) {
result++;
}
return result;
@@ -635,12 +635,12 @@ public final class EditorUtil {
* Allows to answer how many visual columns are occupied by the given width.
*
* @param width target width
- * @param spaceSize width of the single space symbol within the target editor
+ * @param plainSpaceSize width of the single space symbol within the target editor (in plain font style)
* @return number of visual columns are occupied by the given width
*/
- public static int columnsNumber(int width, int spaceSize) {
- int result = width / spaceSize;
- if (width % spaceSize > 0) {
+ public static int columnsNumber(int width, int plainSpaceSize) {
+ int result = width / plainSpaceSize;
+ if (width % plainSpaceSize > 0) {
result++;
}
return result;
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 c769f92fff78..e2693b2c835f 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
@@ -1156,7 +1156,13 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
@Override
public void setSelection(int startOffset, int endOffset) {
- doSetSelection(myEditor.offsetToVisualPosition(startOffset), startOffset, myEditor.offsetToVisualPosition(endOffset), endOffset, false);
+ setSelection(startOffset, endOffset, true);
+ }
+
+ @Override
+ public void setSelection(int startOffset, int endOffset, boolean updateSystemSelection) {
+ doSetSelection(myEditor.offsetToVisualPosition(startOffset), startOffset, myEditor.offsetToVisualPosition(endOffset), endOffset, false,
+ updateSystemSelection);
}
@Override
@@ -1173,16 +1179,22 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
@Override
public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
+ setSelection(startPosition, startOffset, endPosition, endOffset, true);
+ }
+
+ @Override
+ public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset, boolean updateSystemSelection) {
VisualPosition startPositionToUse = startPosition == null ? myEditor.offsetToVisualPosition(startOffset) : startPosition;
VisualPosition endPositionToUse = endPosition == null ? myEditor.offsetToVisualPosition(endOffset) : endPosition;
- doSetSelection(startPositionToUse, startOffset, endPositionToUse, endOffset, true);
+ doSetSelection(startPositionToUse, startOffset, endPositionToUse, endOffset, true, updateSystemSelection);
}
private void doSetSelection(@NotNull final VisualPosition startPosition,
final int _startOffset,
@NotNull final VisualPosition endPosition,
final int _endOffset,
- final boolean visualPositionAware)
+ final boolean visualPositionAware,
+ final boolean updateSystemSelection)
{
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
public void run() {
@@ -1278,7 +1290,9 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
myEditor.getSelectionModel().fireSelectionChanged(oldSelectionStart, oldSelectionEnd, startOffset, endOffset);
- updateSystemSelection();
+ if (updateSystemSelection) {
+ updateSystemSelection();
+ }
}
});
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
index 8d6608e63dd9..15a907e826e4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
@@ -443,6 +443,11 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
@Override
public void setCaretsAndSelections(@NotNull final List<CaretState> caretStates) {
+ setCaretsAndSelections(caretStates, true);
+ }
+
+ @Override
+ public void setCaretsAndSelections(@NotNull final List<CaretState> caretStates, final boolean updateSystemSelection) {
myEditor.assertIsDispatchThread();
if (caretStates.isEmpty()) {
throw new IllegalArgumentException("At least one caret should exist");
@@ -474,9 +479,11 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
caret.moveToLogicalPosition(caretState.getCaretPosition());
}
if (caretState != null && caretState.getSelectionStart() != null && caretState.getSelectionEnd() != null) {
- caret.setSelection(myEditor.logicalToVisualPosition(caretState.getSelectionStart()), myEditor.logicalPositionToOffset(caretState.getSelectionStart()),
- myEditor.logicalToVisualPosition(caretState.getSelectionEnd()), myEditor.logicalPositionToOffset(
- caretState.getSelectionEnd()));
+ caret.setSelection(myEditor.logicalToVisualPosition(caretState.getSelectionStart()),
+ myEditor.logicalPositionToOffset(caretState.getSelectionStart()),
+ myEditor.logicalToVisualPosition(caretState.getSelectionEnd()),
+ myEditor.logicalPositionToOffset(caretState.getSelectionEnd()),
+ updateSystemSelection);
}
}
int caretsToRemove = myCarets.size() - caretStates.size();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java
index 28a7c2204265..cbe6da5379cf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/ContextMenuImpl.java
@@ -46,16 +46,15 @@ import java.awt.event.ActionListener;
public class ContextMenuImpl extends JPanel implements Disposable {
@NonNls
public static final String ACTION_GROUP = "EditorContextBarMenu";
-
- private ActionGroup myActionGroup;
private final JComponent myComponent;
+ private final JLayeredPane myLayeredPane;
+ private ActionGroup myActionGroup;
private boolean myVisible = false;
private boolean myShow = false;
private int myCurrentOpacity;
private Timer myTimer;
private EditorImpl myEditor;
private boolean myDisposed;
- private final JLayeredPane myLayeredPane;
private ActionToolbar myActionToolbar;
public ContextMenuImpl(JLayeredPane layeredPane, @NotNull final JScrollPane container, @NotNull final EditorImpl editor) {
@@ -81,7 +80,7 @@ public class ContextMenuImpl extends JPanel implements Disposable {
}
});
- AnAction action = actionManager.getAction("EditorContextBarMenu");
+ AnAction action = actionManager.getAction(ACTION_GROUP);
if (action == null) {
action = new DefaultActionGroup();
actionManager.registerAction(ACTION_GROUP, action);
@@ -107,6 +106,15 @@ public class ContextMenuImpl extends JPanel implements Disposable {
return activationArea.contains(p.x, p.y - viewPosition.y);
}
+ public static boolean mayShowToolbar(@Nullable final Document document) {
+ if (document == null) {
+ return false;
+ }
+
+ final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
+ return file != null && file.isValid() && (file.isInLocalFileSystem() || file instanceof HttpVirtualFile);
+ }
+
private void toggleContextToolbar(final boolean show) {
final Component toolbar = myComponent.getComponent(0);
final int count = ((Container)toolbar).getComponentCount();
@@ -201,15 +209,6 @@ public class ContextMenuImpl extends JPanel implements Disposable {
}
}
- public static boolean mayShowToolbar(@Nullable final Document document) {
- if (document == null) {
- return false;
- }
-
- final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
- return file != null && file.isValid() && (file.isInLocalFileSystem() || file instanceof HttpVirtualFile);
- }
-
private void scheduleHide() {
if (myTimer != null && myTimer.isRunning()) {
myTimer.stop();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java
index ec0cef4e76d5..d0313e04cf9f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java
@@ -203,14 +203,17 @@ public class EditorFactoryImpl extends EditorFactory implements ApplicationCompo
@Override
public void releaseEditor(@NotNull Editor editor) {
try {
- ((EditorImpl)editor).release();
+ myEditorFactoryEventDispatcher.getMulticaster().editorReleased(new EditorFactoryEvent(this, editor));
}
finally {
- myEditors.remove(editor);
- myEditorFactoryEventDispatcher.getMulticaster().editorReleased(new EditorFactoryEvent(this, editor));
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("number of Editor's:" + myEditors.size());
+ try {
+ ((EditorImpl)editor).release();
+ }
+ finally {
+ myEditors.remove(editor);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("number of Editor's:" + myEditors.size());
+ }
}
}
}
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 39706f016adc..f773f842f323 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
@@ -1236,7 +1236,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
GutterIconRenderer renderer = getGutterRenderer(e);
AnAction clickAction = null;
- if (renderer != null) {
+ if (renderer != null && e.getButton() < 4) {
clickAction = (InputEvent.BUTTON2_MASK & e.getModifiers()) > 0
? renderer.getMiddleButtonClickAction()
: renderer.getClickAction();
@@ -1447,8 +1447,8 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
public void process(int x, int y, GutterMark renderer) {
final int ex = convertX((int)p.getX());
Icon icon = renderer.getIcon();
- if (x <= ex && ex <= x + icon.getIconWidth() &&
- y <= p.getY() && p.getY() <= y + icon.getIconHeight()) {
+ // Do not check y to extend the area where users could click
+ if (x <= ex && ex <= x + icon.getIconWidth()) {
result[0] = renderer;
}
}
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 6160ea58dcdf..51f6ec4a8cdb 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
@@ -743,12 +743,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myGutterComponent.repaint(0, y, myGutterComponent.getWidth(), myGutterComponent.getHeight() - y);
}
// make sure carets won't appear at invalid positions (e.g. on Tab width change)
- getCaretModel().runForEachCaret(new CaretAction() {
- @Override
- public void perform(Caret caret) {
- caret.moveToOffset(caret.getOffset());
- }
- });
+ for (Caret caret : getCaretModel().getAllCarets()) {
+ caret.moveToOffset(caret.getOffset());
+ }
}
private void initTabPainter() {
@@ -1153,8 +1150,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
int textLength = myDocument.getTextLength();
LogicalPosition logicalPosition = visualToLogicalPosition(new VisualPosition(line, 0));
int offset = logicalPositionToOffset(logicalPosition);
+ int plainSpaceSize = EditorUtil.getSpaceWidth(Font.PLAIN, this);
- if (offset >= textLength) return new VisualPosition(line, EditorUtil.columnsNumber(p.x, EditorUtil.getSpaceWidth(Font.PLAIN, this)));
+ if (offset >= textLength) return new VisualPosition(line, EditorUtil.columnsNumber(p.x, plainSpaceSize));
// There is a possible case that starting logical line is split by soft-wraps and it's part after the split should be drawn.
// We mark that we're under such circumstances then.
@@ -1172,12 +1170,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
+ "to offset %d (end offset). State: %s",
p, line, line, 0, logicalPosition, offset, line + 1, 0, endLogicalPosition, endOffset, dumpState()
));
- return new VisualPosition(line, EditorUtil.columnsNumber(p.x, EditorUtil.getSpaceWidth(Font.PLAIN, this)));
+ return new VisualPosition(line, EditorUtil.columnsNumber(p.x, plainSpaceSize));
}
IterationState state = new IterationState(this, offset, endOffset, false);
int fontType = state.getMergedAttributes().getFontType();
- int spaceSize = EditorUtil.getSpaceWidth(fontType, this);
int x = 0;
int charWidth;
@@ -1221,7 +1218,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (x >= px) {
break outer;
}
- column += EditorUtil.columnsNumber(c, x, prevX, spaceSize);
+ column += EditorUtil.columnsNumber(c, x, prevX, plainSpaceSize);
}
// Process 'after soft wrap' sign.
@@ -1261,7 +1258,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (x >= px) {
break;
}
- column += EditorUtil.columnsNumber(c, x, prevX, spaceSize);
+ column += EditorUtil.columnsNumber(c, x, prevX, plainSpaceSize);
offset++;
}
@@ -1272,16 +1269,16 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
if (charWidth < 0) {
- charWidth = spaceSize;
+ charWidth = plainSpaceSize;
}
if (x >= px && c == '\t' && !onSoftWrapDrawing) {
if (mySettings.isCaretInsideTabs()) {
- column += (px - prevX) / spaceSize;
- if ((px - prevX) % spaceSize > spaceSize / 2) column++;
+ column += (px - prevX) / plainSpaceSize;
+ if ((px - prevX) % plainSpaceSize > plainSpaceSize / 2) column++;
}
else if ((x - px) * 2 < x - prevX) {
- column += EditorUtil.columnsNumber(c, x, prevX, spaceSize);
+ column += EditorUtil.columnsNumber(c, x, prevX, plainSpaceSize);
}
}
else {
@@ -1290,8 +1287,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
else {
int diff = px - x;
- column += diff / spaceSize;
- if (diff % spaceSize * 2 >= spaceSize) {
+ column += diff / plainSpaceSize;
+ if (diff % plainSpaceSize * 2 >= plainSpaceSize) {
column++;
}
}
@@ -1549,7 +1546,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
// so, we can't just use 'startOffset + targetColumn' as a max end offset.
IterationState state = new IterationState(this, startOffset, calcEndOffset(startOffset, targetColumn), false);
int fontType = state.getMergedAttributes().getFontType();
- int spaceSize = EditorUtil.getSpaceWidth(fontType, this);
+ int plainSpaceSize = EditorUtil.getSpaceWidth(Font.PLAIN, this);
int column = 0;
outer:
@@ -1588,8 +1585,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (c == '\t') {
int prevX = x;
x = EditorUtil.nextTabStop(x, this);
- int columnDiff = (x - prevX) / spaceSize;
- if ((x - prevX) % spaceSize > 0) {
+ int columnDiff = (x - prevX) / plainSpaceSize;
+ if ((x - prevX) % plainSpaceSize > 0) {
// There is a possible case that tabulation symbol takes more than one visual column to represent and it's shown at
// soft-wrapped line. Soft wrap sign width may be not divisible by space size, hence, part of tabulation symbol represented
// as a separate visual column may take less space than space width.
@@ -2895,7 +2892,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
+ ", soft wraps: " + (mySoftWrapModel.isSoftWrappingEnabled() ? "on" : "off")
+ ", soft wraps data: " + getSoftWrapModel().dumpState()
+ "\n\nfolding data: " + getFoldingModel().dumpState()
- + (myDocument instanceof DocumentImpl ? "\n\ndocument info: " + ((DocumentImpl)myDocument).dumpState() : "");
+ + (myDocument instanceof DocumentImpl ? "\n\ndocument info: " + ((DocumentImpl)myDocument).dumpState() : "")
+ + "\nfont preferences: " + myScheme.getFontPreferences();
}
private class CachedFontContent {
@@ -4824,22 +4822,21 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
int getDecScrollButtonHeight() {
ScrollBarUI barUI = getUI();
Insets insets = getInsets();
+ int top = Math.max(0, insets.top);
if (barUI instanceof ButtonlessScrollBarUI) {
- return insets.top + ((ButtonlessScrollBarUI)barUI).getDecrementButtonHeight();
+ return top + ((ButtonlessScrollBarUI)barUI).getDecrementButtonHeight();
}
- else if (barUI instanceof BasicScrollBarUI) {
+ if (barUI instanceof BasicScrollBarUI) {
try {
JButton decrButtonValue = (JButton)decrButtonField.get(barUI);
LOG.assertTrue(decrButtonValue != null);
- return insets.top + decrButtonValue.getHeight();
+ return top + decrButtonValue.getHeight();
}
catch (Exception exc) {
throw new IllegalStateException(exc);
}
}
- else {
- return insets.top + 15;
- }
+ return top + 15;
}
/**
@@ -6623,7 +6620,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
int fontType = state.getMergedAttributes().getFontType();
int column = 0;
int x = 0;
- int spaceSize = EditorUtil.getSpaceWidth(fontType, this);
+ int plainSpaceSize = EditorUtil.getSpaceWidth(Font.PLAIN, this);
for (int i = start; i < offset; i++) {
if (i >= state.getEndOffset()) {
state.advance();
@@ -6639,7 +6636,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
if (c == '\t') {
int prevX = x;
x = EditorUtil.nextTabStop(x, this);
- column += EditorUtil.columnsNumber(c, x, prevX, spaceSize);
+ column += EditorUtil.columnsNumber(c, x, prevX, plainSpaceSize);
}
else {
x += EditorUtil.charWidth(c, fontType, this);
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 20c08ec4ec99..032573521b56 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
@@ -42,6 +42,7 @@ import com.intellij.openapi.editor.ex.*;
import com.intellij.openapi.editor.markup.ErrorStripeRenderer;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.fileEditor.impl.EditorWindowHolder;
+import com.intellij.openapi.ui.GraphicsConfig;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Disposer;
@@ -127,9 +128,10 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
void recalcEditorDimensions() {
EditorImpl.MyScrollBar scrollBar = myEditor.getVerticalScrollBar();
- int scrollBarHeight = scrollBar.getSize().height;
+ int scrollBarHeight = Math.max(0, scrollBar.getSize().height);
myEditorScrollbarTop = scrollBar.getDecScrollButtonHeight()/* + 1*/;
+ assert myEditorScrollbarTop>=0;
int editorScrollbarBottom = scrollBar.getIncScrollButtonHeight();
myEditorTargetHeight = scrollBarHeight - myEditorScrollbarTop - editorScrollbarBottom;
myEditorSourceHeight = myEditor.getPreferredHeight();
@@ -758,20 +760,32 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
Color color,
boolean drawTopDecoration,
boolean drawBottomDecoration) {
+ GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
int x = isMirrored() ? 3 : 5;
int paintWidth = width;
boolean flatStyle = Registry.is("ide.new.markup.markers");
if (thinErrorStripeMark) {
paintWidth /= 2;
- paintWidth += flatStyle ? 0 : 1;
+ paintWidth += flatStyle ? -2 : 1;
x = isMirrored() ? width + 2 : 0;
+ if (yEnd - yStart < 6) {
+ yStart -= 1;
+ yEnd += yEnd-yStart - 1;
+ }
}
if (color == null) return;
- Color darker = UIUtil.isUnderDarcula()? color : ColorUtil.shift(color, 0.75);
+ Color darker = color;
+ if (!UIUtil.isUnderDarcula()) {
+ float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
+ hsb[2] = Math.min(1f, hsb[2] * 0.85f);
+ //noinspection UseJBColor
+ darker = new Color(Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]));
+ }
if (flatStyle) {
g.setColor(darker);
- g.fillRect(x, yStart, paintWidth, yEnd - yStart + 1);
+ g.fillRoundRect(x, yStart, paintWidth, yEnd - yStart, 3,3);
+ config.restore();
return;
}
@@ -794,6 +808,7 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
}
//right decoration
UIUtil.drawLine(g, x + paintWidth - 2, yStart, x + paintWidth - 2, yEnd/* - 1*/);
+ config.restore();
}
// mouse events
@@ -1056,29 +1071,30 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
int startLineNumber = end == -1 ? 0 : offsetToLine(start, document);
int startY;
int lineCount;
- if (myEditorSourceHeight < myEditorTargetHeight) {
+ int editorTargetHeight = Math.max(0, myEditorTargetHeight);
+ if (myEditorSourceHeight < editorTargetHeight) {
lineCount = 0;
startY = myEditorScrollbarTop + startLineNumber * myEditor.getLineHeight();
}
else {
lineCount = myEditorSourceHeight / myEditor.getLineHeight();
- startY = myEditorScrollbarTop + (int)((float)startLineNumber / lineCount * myEditorTargetHeight);
+ startY = myEditorScrollbarTop + (int)((float)startLineNumber / lineCount * editorTargetHeight);
}
int endY;
int endLineNumber = offsetToLine(end, document);
if (end == -1 || start == -1) {
- endY = Math.min(myEditorSourceHeight, myEditorTargetHeight);
+ endY = Math.min(myEditorSourceHeight, editorTargetHeight);
}
else if (start == end || offsetToLine(start, document) == endLineNumber) {
endY = startY; // both offsets are on the same line, no need to recalc Y position
}
else {
- if (myEditorSourceHeight < myEditorTargetHeight) {
+ if (myEditorSourceHeight < editorTargetHeight) {
endY = myEditorScrollbarTop + endLineNumber * myEditor.getLineHeight();
}
else {
- endY = myEditorScrollbarTop + (int)((float)endLineNumber / lineCount * myEditorTargetHeight);
+ endY = myEditorScrollbarTop + (int)((float)endLineNumber / lineCount * editorTargetHeight);
}
}
if (endY < startY) endY = startY;
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
index 3a819d88a370..881dc4100204 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/mapping/SoftWrapApplianceManager.java
@@ -270,8 +270,9 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
EditorPosition position = new EditorPosition(logical, start, myEditor);
position.x = point.x;
int spaceWidth = EditorUtil.getSpaceWidth(myContext.fontType, myEditor);
+ int plainSpaceWidth = EditorUtil.getSpaceWidth(Font.PLAIN, myEditor);
- myContext.logicalLineData.update(logical.line, spaceWidth, myEditor);
+ myContext.logicalLineData.update(logical.line, spaceWidth, plainSpaceWidth);
myContext.currentPosition = position;
myContext.lineStartPosition = position.clone();
@@ -363,8 +364,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
revertListeners(softWrap.getStart(), myContext.currentPosition.visualLine);
for (int j = foldRegion.getStartOffset() - 1; j >= softWrap.getStart(); j--) {
int pixelsDiff = myOffset2widthInPixels.data[j - myOffset2widthInPixels.anchor];
- int tmpFontType = myOffset2fontType.get(j);
- int columnsDiff = calculateWidthInColumns(myContext.text.charAt(j), pixelsDiff, myContext.getSpaceWidth(tmpFontType));
+ int columnsDiff = calculateWidthInColumns(myContext.text.charAt(j), pixelsDiff, myContext.getPlainSpaceWidth());
myContext.currentPosition.offset--;
myContext.currentPosition.logicalColumn -= columnsDiff;
myContext.currentPosition.visualColumn -= columnsDiff;
@@ -582,8 +582,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
revertListeners(actualSoftWrapOffset, myContext.currentPosition.visualLine);
for (int j = offset - 1; j >= actualSoftWrapOffset; j--) {
int pixelsDiff = myOffset2widthInPixels.data[j - myOffset2widthInPixels.anchor];
- int tmpFontType = myOffset2fontType.get(j);
- int columnsDiff = calculateWidthInColumns(myContext.text.charAt(j), pixelsDiff, myContext.getSpaceWidth(tmpFontType));
+ int columnsDiff = calculateWidthInColumns(myContext.text.charAt(j), pixelsDiff, myContext.getPlainSpaceWidth());
myContext.currentPosition.offset--;
myContext.currentPosition.logicalColumn -= columnsDiff;
myContext.currentPosition.visualColumn -= columnsDiff;
@@ -630,12 +629,12 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
return Math.max(start, end);
}
- private static int calculateWidthInColumns(char c, int widthInPixels, int spaceWithInPixels) {
+ private static int calculateWidthInColumns(char c, int widthInPixels, int plainSpaceWithInPixels) {
if (c != '\t') {
return 1;
}
- int result = widthInPixels / spaceWithInPixels;
- if (widthInPixels % spaceWithInPixels > 0) {
+ int result = widthInPixels / plainSpaceWithInPixels;
+ if (widthInPixels % plainSpaceWithInPixels > 0) {
result++;
}
return result;
@@ -869,7 +868,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
}
}
updateLastTopLeftCornerOffset();
- return result;
+ return true;
}
private void updateLastTopLeftCornerOffset() {
@@ -1035,7 +1034,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
public int endLineOffset;
public int nonWhiteSpaceSymbolOffset;
- public void update(int logicalLine, int spaceWidth, Editor editor) {
+ public void update(int logicalLine, int spaceWidth, int plainSpaceWidth) {
Document document = myEditor.getDocument();
int startLineOffset;
if (logicalLine >= document.getLineCount()) {
@@ -1055,8 +1054,8 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
switch (c) {
case ' ': indentInColumns += 1; indentInPixels += spaceWidth; break;
case '\t':
- int x = EditorUtil.nextTabStop(indentInPixels, editor);
- indentInColumns += calculateWidthInColumns(c, x - indentInPixels, spaceWidth);
+ int x = EditorUtil.nextTabStop(indentInPixels, myEditor);
+ indentInColumns += calculateWidthInColumns(c, x - indentInPixels, plainSpaceWidth);
indentInPixels = x;
break;
default: nonWhiteSpaceSymbolOffset = i; return;
@@ -1270,8 +1269,12 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
public int getSpaceWidth() {
return getSpaceWidth(fontType);
}
-
- public int getSpaceWidth(@JdkConstants.FontStyle int fontType) {
+
+ public int getPlainSpaceWidth() {
+ return getSpaceWidth(Font.PLAIN);
+ }
+
+ private int getSpaceWidth(@JdkConstants.FontStyle int fontType) {
int result = fontType2spaceWidth.get(fontType);
if (result <= 0) {
result = EditorUtil.getSpaceWidth(fontType, myEditor);
@@ -1280,7 +1283,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
assert result > 0;
return result;
}
-
+
/**
* Asks current context to update its state assuming that it begins to point to the line next to its current position.
*/
@@ -1293,7 +1296,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
lastFoldEndPosition = null;
lastFold = null;
lineStartPosition.from(currentPosition);
- logicalLineData.update(currentPosition.logicalLine, getSpaceWidth(), myEditor);
+ logicalLineData.update(currentPosition.logicalLine, getSpaceWidth(), getPlainSpaceWidth());
fontType = myOffset2fontType.get(currentPosition.offset);
myOffset2fontType.clear();
@@ -1330,7 +1333,7 @@ public class SoftWrapApplianceManager implements DocumentListener, Dumpable {
myOffset2widthInPixels.data[currentPosition.offset - myOffset2widthInPixels.anchor] = widthInPixels;
myOffset2widthInPixels.end++;
- int widthInColumns = calculateWidthInColumns(c, widthInPixels, myContext.getSpaceWidth());
+ int widthInColumns = calculateWidthInColumns(c, widthInPixels, myContext.getPlainSpaceWidth());
if (c == '\t') {
notifyListenersOnVisualLineStart(myContext.lineStartPosition);
notifyListenersOnTabulation(widthInColumns);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java
index 92ef12c46558..48ba57e150cf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaret.java
@@ -151,6 +151,12 @@ public class TextComponentCaret extends UserDataHolderBase implements Caret {
}
@Override
+ public void setSelection(int startOffset, int endOffset, boolean updateSystemSelection) {
+ // updating system selection is not supported currently for TextComponentEditor
+ setSelection(startOffset, endOffset);
+ }
+
+ @Override
public void setSelection(int startOffset, @Nullable VisualPosition endPosition, int endOffset) {
getSelectionModel().setSelection(startOffset, endPosition, endOffset);
}
@@ -161,6 +167,13 @@ public class TextComponentCaret extends UserDataHolderBase implements Caret {
}
@Override
+ public void setSelection(@Nullable VisualPosition startPosition, int startOffset, @Nullable VisualPosition endPosition, int endOffset,
+ boolean updateSystemSelection) {
+ // updating system selection is not supported currently for TextComponentEditor
+ setSelection(startPosition, startOffset, endPosition, endOffset);
+ }
+
+ @Override
public void removeSelection() {
getSelectionModel().removeSelection();
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
index ac415f5f9409..341c8ace3598 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/textarea/TextComponentCaretModel.java
@@ -187,6 +187,11 @@ public class TextComponentCaretModel implements CaretModel {
throw new UnsupportedOperationException("Multiple carets are not supported");
}
+ @Override
+ public void setCaretsAndSelections(@NotNull List<CaretState> caretStates, boolean updateSystemSelection) {
+ throw new UnsupportedOperationException("Multiple carets are not supported");
+ }
+
@NotNull
@Override
public List<CaretState> getCaretsAndSelections() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
index b1f9ec0c2b93..b9e38809faab 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
@@ -148,7 +148,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
- private boolean showEmptyText() {
+ protected boolean showEmptyText() {
return myCurrentWindow == null || myCurrentWindow.getFiles().length == 0;
}
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 cce6de27545d..ec2559fc06ba 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
@@ -550,14 +550,18 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt
if (document != null) {
// a file is linked to a document - chances are it is an "unknown text file" now
if (isBinaryWithoutDecompiler(file)) {
- myDocuments.remove(file);
- file.putUserData(HARD_REF_TO_DOCUMENT_KEY, null);
- document.putUserData(FILE_KEY, null);
+ unbindFileFromDocument(file, document);
}
}
}
}
+ private void unbindFileFromDocument(@NotNull VirtualFile file, @NotNull Document document) {
+ myDocuments.remove(file);
+ file.putUserData(HARD_REF_TO_DOCUMENT_KEY, null);
+ document.putUserData(FILE_KEY, null);
+ }
+
private static boolean isBinaryWithDecompiler(@NotNull VirtualFile file) {
final FileType ft = file.getFileType();
return ft.isBinary() && BinaryFileTypeDecompilers.INSTANCE.forFileType(ft) != null;
@@ -609,6 +613,13 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt
return;
}
+ if (file.getLength() > FileUtilRt.LARGE_FOR_CONTENT_LOADING) {
+ unbindFileFromDocument(file, document);
+ myUnsavedDocuments.remove(document);
+ myMultiCaster.fileWithNoDocumentChanged(file);
+ return;
+ }
+
final Project project = ProjectLocator.getInstance().guessProjectForFile(file);
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
@@ -640,7 +651,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Virt
public boolean process(final VirtualFile file, final Document document) {
String message = UIBundle.message("file.cache.conflict.message.text", file.getPresentableUrl());
- final DialogBuilder builder = new DialogBuilder((Project)null);
+ final DialogBuilder builder = new DialogBuilder();
builder.setCenterPanel(new JLabel(message, Messages.getQuestionIcon(), SwingConstants.CENTER));
builder.addOkAction().setText(UIBundle.message("file.cache.conflict.load.fs.changes.button"));
builder.addCancelAction().setText(UIBundle.message("file.cache.conflict.keep.memory.changes.button"));
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 bab6d2b2fa4f..65adf52041b9 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
@@ -58,6 +58,7 @@ import com.intellij.openapi.vcs.FileStatusListener;
import com.intellij.openapi.vcs.FileStatusManager;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.StatusBarEx;
@@ -90,6 +91,7 @@ import java.beans.PropertyChangeListener;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Anton Katilin
@@ -106,10 +108,12 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
public static final String FILE_EDITOR_MANAGER = "FileEditorManager";
private volatile JPanel myPanels;
+ private PreviewPanel myPreviewPanel;
private EditorsSplitters mySplitters;
private final Project myProject;
private final List<Pair<VirtualFile, EditorWindow>> mySelectionHistory = new ArrayList<Pair<VirtualFile, EditorWindow>>();
private WeakReference<EditorComposite> myLastSelectedComposite = new WeakReference<EditorComposite>(null);
+ private final AtomicBoolean myPreviewBlocker = new AtomicBoolean(false);
private final MergingUpdateQueue myQueue = new MergingUpdateQueue("FileEditorManagerUpdateQueue", 50, true, null);
@@ -174,7 +178,11 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
}
public Set<EditorsSplitters> getAllSplitters() {
- HashSet<EditorsSplitters> all = new HashSet<EditorsSplitters>();
+ HashSet<EditorsSplitters> all = new LinkedHashSet<EditorsSplitters>();
+ if (Registry.is("editor.use.preview")) {
+ initUI();
+ all.add(myPreviewPanel.getWindow().getOwner());
+ }
all.add(getMainSplitters());
Set<DockContainer> dockContainers = myDockManager.getContainers();
for (DockContainer each : dockContainers) {
@@ -247,6 +255,11 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
}
}
}
+ if (myPreviewPanel == null && Registry.is("editor.use.preview")) {
+ synchronized (myInitLock) {
+ myPreviewPanel = new PreviewPanel(myProject, this, myDockManager);
+ }
+ }
}
private static class MyBorder implements Border {
@@ -595,7 +608,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
@NotNull
public Pair<FileEditor[], FileEditorProvider[]> openFileWithProviders(@NotNull final VirtualFile file,
final boolean focusEditor,
- boolean searchForSplitter) {
+ final boolean searchForSplitter) {
if (!file.isValid()) {
throw new IllegalArgumentException("file is not valid: " + file);
}
@@ -628,6 +641,13 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
wndToOpenIn = getSplitters().getCurrentWindow();
}
+ if (wndToOpenIn == null || !wndToOpenIn.isFileOpen(file)) {
+ EditorWindow previewWindow = getPreviewWindow(file, focusEditor, searchForSplitter);
+ if (previewWindow != null) {
+ wndToOpenIn = previewWindow;
+ }
+ }
+
EditorsSplitters splitters = getSplitters();
if (wndToOpenIn == null) {
@@ -638,6 +658,31 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
return openFileImpl2(wndToOpenIn, file, focusEditor);
}
+ @Nullable
+ private EditorWindow getPreviewWindow(@NotNull VirtualFile virtualFile, final boolean focusEditor, final boolean searchForSplitter) {
+ EditorWindow wndToOpenIn = null;
+ if (Registry.is("editor.use.preview") && !myPreviewBlocker.get()) {
+ wndToOpenIn = myPreviewPanel.getWindow();
+ if (virtualFile.equals(myPreviewPanel.getCurrentFile())) return wndToOpenIn;
+ final VirtualFile modifiedFile = myPreviewPanel.closeCurrentFile();
+ ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).activate(null, false);
+ if (modifiedFile != null) {
+ CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
+ @Override
+ public void run() {
+ myPreviewBlocker.set(true);
+ try {
+ openFileWithProviders(modifiedFile, focusEditor, searchForSplitter);
+ } finally {
+ myPreviewBlocker.set(false);
+ }
+ }
+ }, "", null);
+ }
+ }
+ return wndToOpenIn;
+ }
+
public Pair<FileEditor[], FileEditorProvider[]> openFileInNewWindow(@NotNull VirtualFile file) {
return ((DockManagerImpl)DockManager.getInstance(getProject())).createNewDockContainerFor(file, this);
}
@@ -1610,7 +1655,10 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
return null;
}
- public void runChange(FileEditorManagerChange change, EditorsSplitters splitters) {
+ /**
+ * @param splitters - taken getAllSplitters() value if parameter is null
+ */
+ public void runChange(@NotNull FileEditorManagerChange change, @Nullable EditorsSplitters splitters) {
Set<EditorsSplitters> target = new HashSet<EditorsSplitters>();
if (splitters == null) {
target.addAll(getAllSplitters());
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java
new file mode 100644
index 000000000000..a9634d5a335a
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/PreviewPanel.java
@@ -0,0 +1,244 @@
+/*
+ * 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.fileEditor.impl;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.ui.UISettings;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.event.DocumentEvent;
+import com.intellij.openapi.editor.event.DocumentListener;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.FileEditorManagerListener;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.ToolWindowAnchor;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.openapi.wm.impl.ToolWindowImpl;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.docking.DockManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+
+class PreviewPanel extends JPanel implements DocumentListener, FileEditorManagerListener.Before {
+ private static final int HISTORY_LIMIT = 10;
+
+ private final Project myProject;
+ private final FileEditorManagerImpl myManager;
+ private final DockManager myDockManager;
+ private EditorWindow myWindow;
+ private boolean myInitialized = false;
+ private EditorsSplitters myEditorsSplitters;
+ private ArrayList<VirtualFile> myHistory = new ArrayList<VirtualFile>();
+ private VirtualFile myModifiedFile = null;
+ private ToolWindowImpl myToolWindow;
+ private VirtualFile myAwaitingForOpen = null;
+
+ public PreviewPanel(Project project, FileEditorManagerImpl manager, DockManager dockManager) {
+ myProject = project;
+ myManager = manager;
+ myDockManager = dockManager;
+ setOpaque(true);
+ setBackground(JBColor.DARK_GRAY);
+ }
+
+ private void initToolWindowIfNeed() {
+ if (myInitialized) return;
+
+ myToolWindow = (ToolWindowImpl)ToolWindowManager.getInstance(myProject)
+ .registerToolWindow(ToolWindowId.PREVIEW, this, ToolWindowAnchor.RIGHT, myProject, false);
+ myToolWindow.setIcon(AllIcons.Actions.PreviewDetails);
+
+ myEditorsSplitters = new EditorsSplitters(myManager, myDockManager, false) {
+ @Override
+ public void updateFileName(VirtualFile updatedFile) {
+ super.updateFileName(updatedFile);
+ if (updatedFile != null && updatedFile.equals(getCurrentFile())) {
+ updateWindowTitle(updatedFile);
+ }
+ }
+
+ @Override
+ protected void afterFileOpen(VirtualFile file) {
+ if (file.equals(myAwaitingForOpen)) {
+ updateWindowTitle(file);
+ Document document = FileDocumentManager.getInstance().getDocument(file);
+ if (document != null) {
+ myModifiedFile = null;
+ document.addDocumentListener(PreviewPanel.this, myProject);
+ }
+ }
+ myAwaitingForOpen = null;
+ }
+
+ @Override
+ public void setTabsPlacement(int tabPlacement) {
+ super.setTabsPlacement(UISettings.TABS_NONE);
+ }
+
+ @Override
+ protected boolean showEmptyText() {
+ return false;
+ }
+ };
+
+ myProject.getMessageBus().connect().subscribe(FileEditorManagerListener.Before.FILE_EDITOR_MANAGER, this);
+ myEditorsSplitters.createCurrentWindow();
+
+ myWindow = myEditorsSplitters.getCurrentWindow();
+ myWindow.setTabsPlacement(UISettings.TABS_NONE);
+
+ setLayout(new GridLayout(1, 1));
+ add(myEditorsSplitters);
+
+ myToolWindow.setTitleActions(new MoveToEditorTabsAction(), new CloseFileAction());
+
+ myInitialized = true;
+ }
+
+ private void updateWindowTitle(VirtualFile file) {
+ if (myToolWindow == null) return;
+ if (file == null) {
+ myToolWindow.setTitle(": (empty)");
+ }
+ else {
+ myToolWindow.setTitle(": " +
+ StringUtil.getShortened(EditorTabbedContainer.calcTabTitle(myProject, file),
+ UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT));
+ }
+ }
+
+ @Override
+ public void beforeFileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
+ myAwaitingForOpen = file;
+ }
+
+ @Override
+ public void beforeFileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
+ if (file.equals(getCurrentFile())) {
+ updateWindowTitle(null);
+ Document document = FileDocumentManager.getInstance().getDocument(file);
+ if (document != null) {
+ document.removeDocumentListener(this);
+ }
+ }
+ }
+
+
+ @Override
+ public void beforeDocumentChange(DocumentEvent event) {
+
+ }
+
+ @Override
+ public void documentChanged(DocumentEvent event) {
+ VirtualFile file = FileDocumentManager.getInstance().getFile(event.getDocument());
+ if (file != null) {
+ myModifiedFile = file;
+ }
+ }
+
+ EditorWindow getWindow() {
+ initToolWindowIfNeed();
+ return myWindow;
+ }
+
+ @Nullable
+ VirtualFile getCurrentFile() {
+ VirtualFile[] files = myWindow.getFiles();
+ return files.length == 1 ? files[0] : null;
+ }
+
+ private class MoveToEditorTabsAction extends AnAction {
+ public MoveToEditorTabsAction() {
+ super(null, "Move to main tabs", AllIcons.Duplicates.SendToTheLeftGrayed);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ VirtualFile virtualFile = getCurrentFile();
+ if (virtualFile == null) {
+ return;
+ }
+
+ myManager.openFileWithProviders(virtualFile, false, myManager.getCurrentWindow());
+ closeCurrentFile();
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ VirtualFile currentFile = getCurrentFile();
+ e.getPresentation().setEnabled(currentFile != null);
+ if (currentFile == null) return;
+
+ if (isModified(currentFile)) {
+ e.getPresentation().setIcon(AllIcons.Duplicates.SendToTheLeft);
+ }
+ else {
+ e.getPresentation().setIcon(AllIcons.Duplicates.SendToTheLeftGrayed);
+ }
+ }
+ }
+
+ private boolean isModified(@NotNull VirtualFile file) {
+ return file.equals(myModifiedFile);
+ }
+
+ //returns last open file if it has "modified" status
+ @Nullable
+ VirtualFile closeCurrentFile() {
+ VirtualFile virtualFile = getCurrentFile();
+ if (virtualFile == null) return null;
+ if (!myHistory.contains(virtualFile)) {
+ myHistory.add(virtualFile);
+ while (myHistory.size() > HISTORY_LIMIT) {
+ myHistory.remove(0);
+ }
+ }
+ myWindow.closeFile(virtualFile);
+ this.revalidate();
+ this.repaint();
+ return isModified(virtualFile) ? virtualFile : null;
+ }
+
+ private class CloseFileAction extends AnAction {
+ public CloseFileAction() {
+ super(null, "Close", AllIcons.Actions.Close);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ if (getCurrentFile() == null) return;
+ closeCurrentFile();
+ ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PREVIEW).hide(null);
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ e.getPresentation().setEnabled(getCurrentFile() != null);
+ }
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java
index b24927b70726..076d29e64bbe 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/http/RemoteFilePanel.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,7 +32,7 @@ import com.intellij.openapi.vfs.impl.http.HttpVirtualFile;
import com.intellij.openapi.vfs.impl.http.RemoteFileInfo;
import com.intellij.openapi.vfs.impl.http.RemoteFileState;
import com.intellij.ui.AppUIUtil;
-import com.intellij.util.net.HTTPProxySettingsDialog;
+import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
@@ -86,22 +86,22 @@ public class RemoteFilePanel {
remoteFileInfo.addDownloadingListener(myDownloadingListener);
myCancelButton.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(final ActionEvent e) {
+ public void actionPerformed(@NotNull final ActionEvent e) {
remoteFileInfo.cancelDownloading();
}
});
myTryAgainButton.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(final ActionEvent e) {
+ public void actionPerformed(@NotNull final ActionEvent e) {
showCard(DOWNLOADING_CARD);
remoteFileInfo.restartDownloading();
}
});
myChangeProxySettingsButton.addActionListener(new ActionListener() {
@Override
- public void actionPerformed(final ActionEvent e) {
- new HTTPProxySettingsDialog().show();
+ public void actionPerformed(@NotNull ActionEvent e) {
+ HttpConfigurable.editConfigurable(myMainPanel);
}
});
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 690e7c7d2820..14f0c95ec31b 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
@@ -287,7 +287,7 @@ public class TextEditorProvider implements FileEditorProvider, DumbAware {
new LogicalPosition(caretState.SELECTION_START_LINE, caretState.SELECTION_START_COLUMN),
new LogicalPosition(caretState.SELECTION_END_LINE, caretState.SELECTION_END_COLUMN)));
}
- caretModel.setCaretsAndSelections(states);
+ caretModel.setCaretsAndSelections(states, false);
}
else {
LogicalPosition pos = new LogicalPosition(state.CARETS[0].LINE, state.CARETS[0].COLUMN);
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
index 198ed907a8d9..837626b53246 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.impl.TransferToPooledThreadQueue;
import com.intellij.openapi.components.ExportableApplicationComponent;
import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
@@ -120,7 +121,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
private static final String[] FILE_TYPES_WITH_PREDEFINED_EXTENSIONS = {"JSP", "JSPX", "DTD", "HTML", "Properties", "XHTML"};
private final SchemesManager<FileType, AbstractFileType> mySchemesManager;
@NonNls
- private static final String FILE_SPEC = "$ROOT_CONFIG$/filetypes";
+ private static final String FILE_SPEC = StoragePathMacros.ROOT_CONFIG + "/filetypes";
private final ConcurrentBitSet autoDetectWasRun = new ConcurrentBitSet();
private final ConcurrentBitSet autoDetectedAsText = new ConcurrentBitSet();
private final ConcurrentBitSet autoDetectedAsBinary = new ConcurrentBitSet();
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 7c65a805ee6c..7c30e4faedec 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
@@ -67,7 +67,7 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat
KeymapManagerImpl(DefaultKeymap defaultKeymap, SchemesManagerFactory factory) {
mySchemesManager = factory.createSchemesManager(
- "$ROOT_CONFIG$/keymaps",
+ StoragePathMacros.ROOT_CONFIG + "/keymaps",
new BaseSchemeProcessor<KeymapImpl>() {
@Override
public KeymapImpl readScheme(@NotNull final Document schemeContent) throws InvalidDataException, IOException, JDOMException {
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/CompositeConfigurable.java b/platform/platform-impl/src/com/intellij/openapi/options/CompositeConfigurable.java
index 0b9e5ade8d29..aaba0fdbaf6b 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/CompositeConfigurable.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/CompositeConfigurable.java
@@ -20,18 +20,21 @@ import java.util.List;
public abstract class CompositeConfigurable<T extends UnnamedConfigurable> extends BaseConfigurable {
private List<T> myConfigurables;
+ @Override
public void reset() {
for (T configurable : getConfigurables()) {
configurable.reset();
}
}
+ @Override
public void apply() throws ConfigurationException {
for (T configurable : getConfigurables()) {
configurable.apply();
}
}
+ @Override
public boolean isModified() {
for (T configurable : getConfigurables()) {
if (configurable.isModified()) {
@@ -41,6 +44,7 @@ public abstract class CompositeConfigurable<T extends UnnamedConfigurable> exten
return false;
}
+ @Override
public void disposeUIResources() {
if (myConfigurables != null) {
for (final T myConfigurable : myConfigurables) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerFactoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerFactoryImpl.java
index 323394ad7c94..449a2180e3c1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerFactoryImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerFactoryImpl.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.components.RoamingType;
import com.intellij.openapi.components.ServiceBean;
import com.intellij.openapi.components.SettingsSavingComponent;
+import com.intellij.openapi.components.impl.stores.IApplicationStore;
import com.intellij.openapi.components.impl.stores.StreamProvider;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.containers.ContainerUtil;
@@ -32,21 +33,22 @@ import java.util.Collections;
import java.util.List;
public class SchemesManagerFactoryImpl extends SchemesManagerFactory implements SettingsSavingComponent {
-
- private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.options.SchemesManagerFactoryImpl");
+ private static final Logger LOG = Logger.getInstance(SchemesManagerFactoryImpl.class);
private final List<SchemesManagerImpl> myRegisteredManagers = ContainerUtil.createLockFreeCopyOnWriteList();
@Override
- public <T extends Scheme, E extends ExternalizableScheme> SchemesManager<T, E> createSchemesManager(final String fileSpec,
- final SchemeProcessor<E> processor,
- final RoamingType roamingType) {
+ public <T extends Scheme, E extends ExternalizableScheme> SchemesManager<T, E> createSchemesManager(@NotNull String fileSpec,
+ @NotNull SchemeProcessor<E> processor,
+ @NotNull RoamingType roamingType) {
final Application application = ApplicationManager.getApplication();
- if (!(application instanceof ApplicationImpl)) return null;
- String baseDirPath = ((ApplicationImpl)application).getStateStore().getStateStorageManager().expandMacros(fileSpec);
-
+ if (!(application instanceof ApplicationImpl)) {
+ return null;
+ }
+ IApplicationStore applicationStore = ((ApplicationImpl)application).getStateStore();
+ String baseDirPath = applicationStore.getStateStorageManager().expandMacros(fileSpec);
if (baseDirPath != null) {
- StreamProvider provider = ((ApplicationImpl)ApplicationManager.getApplication()).getStateStore().getStateStorageManager().getStreamProvider();
+ StreamProvider provider = applicationStore.getStateStorageManager().getStreamProvider();
SchemesManagerImpl<T, E> manager = new SchemesManagerImpl<T, E>(fileSpec, processor, roamingType, provider, new File(baseDirPath));
myRegisteredManagers.add(manager);
return manager;
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
index 1c7e768c7d83..4ff3ebba1ee9 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/SchemesManagerImpl.java
@@ -34,6 +34,7 @@ import com.intellij.openapi.vfs.VirtualFileAdapter;
import com.intellij.openapi.vfs.VirtualFileEvent;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.util.Alarm;
+import com.intellij.util.SmartList;
import com.intellij.util.UniqueFileNamesProvider;
import com.intellij.util.containers.HashSet;
import com.intellij.util.text.UniqueNameGenerator;
@@ -51,7 +52,7 @@ import java.io.IOException;
import java.util.*;
public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme> extends AbstractSchemesManager<T, E> {
- private static final Logger LOG = Logger.getInstance("#" + SchemesManagerFactoryImpl.class.getName());
+ private static final Logger LOG = Logger.getInstance(SchemesManagerFactoryImpl.class);
@NonNls private static final String DEFAULT_EXT = ".xml";
@@ -292,12 +293,13 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
}
}
+ @NotNull
private Collection<E> readSchemesFromProviders() {
- Collection<E> result = new ArrayList<E>();
if (myProvider == null || !myProvider.isEnabled()) {
- return result;
+ return Collections.emptyList();
}
+ Collection<E> result = new SmartList<E>();
for (String subPath : myProvider.listSubFiles(myFileSpec, myRoamingType)) {
if (!subPath.equals(DELETED_XML)) {
try {
@@ -305,6 +307,7 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
if (subDocument != null) {
E scheme = readScheme(subDocument);
boolean fileRenamed = false;
+ assert scheme != null;
T existing = findSchemeByName(scheme.getName());
if (existing != null && existing instanceof ExternalizableScheme) {
String currentFileName = ((ExternalizableScheme)existing).getExternalInfo().getCurrentFileName();
@@ -315,7 +318,6 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
}
}
String fileName = checkFileNameIsFree(subPath, scheme.getName());
-
if (!fileRenamed && !fileName.equals(subPath)) {
deleteServerFiles(subPath);
}
@@ -325,7 +327,7 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
}
}
catch (Exception e) {
- LOG.info("Cannot load data from IDEAServer: " + e.getLocalizedMessage());
+ LOG.info("Cannot load data from stream provider: " + e.getLocalizedMessage());
}
}
}
@@ -347,21 +349,22 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
});
}
- private String checkFileNameIsFree(final String subPath, final String schemeName) {
+ @NotNull
+ private String checkFileNameIsFree(@NotNull String subPath, @NotNull String schemeName) {
for (Scheme scheme : mySchemes) {
if (scheme instanceof ExternalizableScheme) {
- ExternalInfo externalInfo = ((ExternalizableScheme)scheme).getExternalInfo();
- String name = externalInfo.getCurrentFileName();
- if (name != null) {
- String fileName = name + mySchemeExtension;
- if (fileName.equals(subPath) && !Comparing.equal(schemeName, scheme.getName())) {
- return createUniqueFileName(collectAllFileNames(), UniqueFileNamesProvider.convertName(schemeName));
+ String name = ((ExternalizableScheme)scheme).getExternalInfo().getCurrentFileName();
+ if (name != null &&
+ !schemeName.equals(scheme.getName()) &&
+ subPath.length() == (name.length() + mySchemeExtension.length()) &&
+ subPath.startsWith(name) &&
+ subPath.endsWith(mySchemeExtension)) {
+ return UniqueNameGenerator.generateUniqueName(UniqueFileNamesProvider.convertName(schemeName), collectAllFileNames());
/*VirtualFile oldFile = myVFSBaseDir.findChild(subPath);
if (oldFile != null) {
oldFile.copy(this, myVFSBaseDir, uniqueFileName + EXT);
}
externalInfo.setCurrentFileName(uniqueFileName);*/
- }
}
}
}
@@ -369,8 +372,9 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
return subPath;
}
+ @NotNull
private Collection<String> collectAllFileNames() {
- HashSet<String> result = new HashSet<String>();
+ Set<String> result = new THashSet<String>();
for (T scheme : mySchemes) {
if (scheme instanceof ExternalizableScheme) {
ExternalInfo externalInfo = ((ExternalizableScheme)scheme).getExternalInfo();
@@ -382,10 +386,6 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
return result;
}
- private static String createUniqueFileName(final Collection<String> strings, final String schemeName) {
- return UniqueNameGenerator.generateUniqueName(schemeName, strings);
- }
-
private void loadScheme(final E scheme, boolean forceAdd, final String name) {
if (scheme != null && (!myDeletedNames.contains(scheme.getName()) || forceAdd)) {
T existing = findSchemeByName(scheme.getName());
@@ -469,13 +469,6 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
}
final E scheme = readScheme(document);
if (scheme != null) {
- if (scheme.getName() == null) {
- String suggestedName = FileUtil.getNameWithoutExtension(file.getName());
- if (!"_".equals(suggestedName)) {
- scheme.setName(suggestedName);
- }
- }
-
loadScheme(scheme, forceAdd, file.getName());
result.add(scheme);
}
@@ -653,8 +646,7 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
result = new SharedSchemeData(original, name, user, description);
}
else {
- Document original = subDocument;
- result = new SharedSchemeData(original, name, null, null);
+ result = new SharedSchemeData(subDocument, name, null, null);
}
return result;
}
@@ -673,8 +665,8 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
return false;
}
- private String getFileFullPath(final String subPath) {
- return myFileSpec + "/" + subPath;
+ private String getFileFullPath(@NotNull String subPath) {
+ return myFileSpec + '/' + subPath;
}
@Override
@@ -843,9 +835,9 @@ public class SchemesManagerImpl<T extends Scheme, E extends ExternalizableScheme
deleteServerFiles(fileName);
}
- private void deleteServerFiles(final String fileName) {
+ private void deleteServerFiles(@NotNull String path) {
if (myProvider != null && myProvider.isEnabled()) {
- StorageUtil.deleteContent(myProvider, getFileFullPath(fileName), myRoamingType);
+ StorageUtil.delete(myProvider, getFileFullPath(path), myRoamingType);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java
index 5f8dc0e890df..3b67a3478368 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableWrapper.java
@@ -165,10 +165,6 @@ public class ConfigurableWrapper implements SearchableConfigurable {
return myEp;
}
- public String getGroupId() {
- return myEp.groupId;
- }
-
public String getParentId() {
return myEp.parentId;
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/GlassPanel.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/GlassPanel.java
index 96cc9e451185..c80a222ffd96 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/GlassPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/GlassPanel.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.
@@ -17,7 +17,10 @@
package com.intellij.openapi.options.ex;
import com.intellij.ide.ui.search.SearchUtil;
+import com.intellij.openapi.ui.GraphicsConfig;
+import com.intellij.ui.ColorUtil;
import com.intellij.ui.components.JBTabbedPane;
+import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
@@ -27,6 +30,7 @@ import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.Kernel;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
@@ -64,17 +68,19 @@ public class GlassPanel extends JComponent {
final Point leftPoint = SwingUtilities.convertPoint(myPanel, new Point(visibleRect.x, visibleRect.y), surfaceComponent);
Area innerPanel = new Area(new Rectangle2D.Double(leftPoint.x, leftPoint.y, visibleRect.width, visibleRect.height));
Area mask = new Area(screen);
-
+ ArrayList<JComponent> components = new ArrayList<JComponent>();
for (JComponent lightComponent : myLightComponents) {
- final Area area = getComponentArea(surfaceComponent, lightComponent);
+ final Area area = getComponentArea(surfaceComponent, lightComponent, 1);
if (area == null) continue;
+ components.add(lightComponent);
if (lightComponent instanceof JLabel) {
final JLabel label = (JLabel)lightComponent;
final Component labelFor = label.getLabelFor();
if (labelFor instanceof JComponent) {
- final Area labelForArea = getComponentArea(surfaceComponent, (JComponent)labelFor);
+ final Area labelForArea = getComponentArea(surfaceComponent, (JComponent)labelFor, 1);
if (labelForArea != null) {
+ components.add((JComponent)labelFor);
area.add(labelForArea);
}
}
@@ -86,19 +92,32 @@ public class GlassPanel extends JComponent {
Graphics2D g2 = (Graphics2D)g;
- Color shieldColor = new Color(0.0f, 0.0f, 0.0f, 0.15f);
+ Color shieldColor = new Color(0.0f, 0.0f, 0.0f, 0.20f);
Color boundsColor = Color.gray;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(shieldColor);
g2.fill(mask);
- g2.setColor(boundsColor);
- g2.draw(mask);
+ g2.setColor(ColorUtil.toAlpha(Color.orange, 25));
+ GraphicsConfig config = GraphicsUtil.setupAAPainting(g2);
+ for (int i = 2; i > 0; i--) {
+ g2.setStroke(new BasicStroke(i));
+ Area arrr = new Area();
+ for (JComponent component : components) {
+ Area area = getComponentArea(surfaceComponent, component, i-1);
+ if (area != null) {
+ arrr.add(area);
+ }
+ }
+ g2.draw(arrr);
+ }
+
+ config.restore();
}
}
@Nullable
- private Area getComponentArea(final JComponent surfaceComponent, final JComponent lightComponent) {
+ private Area getComponentArea(final JComponent surfaceComponent, final JComponent lightComponent, int offset) {
if (!lightComponent.isShowing()) return null;
final Point panelPoint = SwingUtilities.convertPoint(lightComponent, new Point(0, 0), surfaceComponent);
@@ -115,12 +134,17 @@ public class GlassPanel extends JComponent {
int hInset = isWithBorder ? 7 : isLabelFromTabbedPane ? 20 : 7;
int vInset = isWithBorder ? 1 : isLabelFromTabbedPane ? 10 : 5;
- final Area area = new Area(new RoundRectangle2D.Double(x - hInset + insetsToIgnore.left,
- y - vInset + insetsToIgnore.top,
- lightComponent.getWidth() + hInset * 2 - insetsToIgnore.right - insetsToIgnore.left,
- lightComponent.getHeight() + vInset * 2 - insetsToIgnore.top - insetsToIgnore.bottom,
- 6, 6));
- return area;
+ hInset += offset;
+ vInset += offset;
+ int xCoord = x - hInset + insetsToIgnore.left;
+ int yCoord = y - vInset + insetsToIgnore.top;
+ int width = lightComponent.getWidth() + hInset * 2 - insetsToIgnore.right - insetsToIgnore.left;
+ int height = lightComponent.getHeight() + vInset * 2 - insetsToIgnore.top - insetsToIgnore.bottom;
+ return new Area(new RoundRectangle2D.Double(xCoord,
+ yCoord,
+ width,
+ height,
+ Math.min(height, 30), Math.min(height, 30)));
}
protected static Kernel getBlurKernel(int blurSize) {
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java
index f1411cf3551d..e3404ec017cd 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/MixedConfigurableGroup.java
@@ -17,15 +17,21 @@ package com.intellij.openapi.options.ex;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurableGroup;
+import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.OptionsBundle;
import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
+import javax.swing.JComponent;
-public final class MixedConfigurableGroup implements ConfigurableGroup {
+public final class MixedConfigurableGroup implements SearchableConfigurable, ConfigurableGroup {
private final String myGroupId;
private Configurable[] myConfigurables;
@@ -34,6 +40,7 @@ public final class MixedConfigurableGroup implements ConfigurableGroup {
myConfigurables = (configurables != null)
? configurables.toArray(new Configurable[configurables.size()])
: new Configurable[0];
+ Arrays.sort(myConfigurables, COMPARATOR);
}
private MixedConfigurableGroup(String groupId, HashMap<String, ArrayList<Configurable>> configurables) {
@@ -41,6 +48,45 @@ public final class MixedConfigurableGroup implements ConfigurableGroup {
}
@Override
+ public JComponent createComponent() {
+ return null;
+ }
+
+ @Override
+ public boolean isModified() {
+ return false;
+ }
+
+ @Override
+ public void apply() throws ConfigurationException {
+ }
+
+ @Override
+ public void reset() {
+ }
+
+ @Override
+ public void disposeUIResources() {
+ myConfigurables = null;
+ }
+
+ @Override
+ public Runnable enableSearch(String option) {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public String getId() {
+ return "configurable.group." + myGroupId;
+ }
+
+ @Override
+ public String getHelpTopic() {
+ return "configurable.group." + myGroupId + ".help.topic";
+ }
+
+ @Override
public String getDisplayName() {
return OptionsBundle.message("configurable.group." + myGroupId + ".settings.display.name");
}
@@ -60,7 +106,7 @@ public final class MixedConfigurableGroup implements ConfigurableGroup {
for (Configurable configurable : configurables) {
String groupId = null;
if (configurable instanceof ConfigurableWrapper) {
- groupId = ((ConfigurableWrapper)configurable).getGroupId();
+ groupId = ((ConfigurableWrapper)configurable).getExtensionPoint().groupId;
}
ArrayList<Configurable> list = map.get(groupId);
if (list == null) {
@@ -70,7 +116,7 @@ public final class MixedConfigurableGroup implements ConfigurableGroup {
}
ArrayList<Configurable> buildList = map.get("build");
if (buildList != null) {
- NodeConfigurable buildTools = new NodeConfigurable("build.tools");
+ NodeConfigurable buildTools = new NodeConfigurable("build.tools", 1000);
buildTools.add(find("MavenSettings", buildList.iterator()));
buildTools.add(find("reference.settingsdialog.project.gradle", buildList.iterator()));
buildTools.add(find("reference.settingsdialog.project.gant", buildList.iterator()));
@@ -106,4 +152,27 @@ public final class MixedConfigurableGroup implements ConfigurableGroup {
}
return null;
}
+
+ public static int getGroupWeight(Configurable configurable) {
+ if (configurable instanceof NodeConfigurable) {
+ return ((NodeConfigurable)configurable).getGroupWeight();
+ }
+ if (configurable instanceof ConfigurableWrapper) {
+ return ((ConfigurableWrapper)configurable).getExtensionPoint().groupWeight;
+ }
+ return 0;
+ }
+
+ private static final Comparator<Configurable> COMPARATOR = new Comparator<Configurable>() {
+ @Override
+ public int compare(Configurable configurable1, Configurable configurable2) {
+ if (configurable1 == null || configurable2 == null) {
+ return configurable2 != null ? -1 : configurable1 != null ? 1 : 0;
+ }
+ int weight1 = getGroupWeight(configurable1);
+ int weight2 = getGroupWeight(configurable2);
+ return weight1 > weight2 ? -1 : weight1 < weight2 ? 1 : StringUtil.naturalCompare(configurable1.getDisplayName(),
+ configurable2.getDisplayName());
+ }
+ };
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/NodeConfigurable.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/NodeConfigurable.java
index 6571c7a63746..609943d02943 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/NodeConfigurable.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/NodeConfigurable.java
@@ -27,9 +27,15 @@ import java.util.ArrayList;
public final class NodeConfigurable extends SearchableConfigurable.Parent.Abstract {
private final ArrayList<Configurable> myConfigurables = new ArrayList<Configurable>();
private final String myId;
+ private final int myWeight;
- public NodeConfigurable(@NotNull String id) {
+ public NodeConfigurable(@NotNull String id, int weight) {
myId = id;
+ myWeight = weight;
+ }
+
+ public int getGroupWeight() {
+ return myWeight;
}
public void add(Configurable configurable) {
@@ -48,13 +54,13 @@ public final class NodeConfigurable extends SearchableConfigurable.Parent.Abstra
@NotNull
@Override
public String getId() {
- return myId;
+ return "node.configurable." + myId;
}
@Nullable
@Override
public String getHelpTopic() {
- return myId;
+ return "node.configurable." + myId + ".help.topic";
}
@Nls
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java
index 80144d230eaf..def0dd16a2d2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/SingleConfigurableEditor.java
@@ -46,7 +46,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
private Component myParentComponent;
private Configurable myConfigurable;
private JComponent myCenterPanel;
- private String myDimensionKey;
+ private final String myDimensionKey;
private final boolean myShowApplyButton;
private boolean myChangesWereApplied;
@@ -134,6 +134,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
return displayName.replaceAll("\n", " ");
}
+ @Override
protected String getDimensionServiceKey() {
if (myDimensionKey == null) {
return super.getDimensionServiceKey();
@@ -143,6 +144,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
}
}
+ @Override
@NotNull
protected Action[] createActions() {
List<Action> actions = new ArrayList<Action>();
@@ -157,6 +159,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
return actions.toArray(new Action[actions.size()]);
}
+ @Override
protected void doHelpAction() {
HelpManager.getInstance().invokeHelp(myConfigurable.getHelpTopic());
}
@@ -169,6 +172,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
super.doCancelAction();
}
+ @Override
protected void doOKAction() {
try {
if (myConfigurable.isModified()) myConfigurable.apply();
@@ -201,10 +205,11 @@ public class SingleConfigurableEditor extends DialogWrapper {
public ApplyAction() {
super(CommonBundle.getApplyButtonText());
final Runnable updateRequest = new Runnable() {
+ @Override
public void run() {
- if (!SingleConfigurableEditor.this.isShowing()) return;
+ if (!isShowing()) return;
try {
- ApplyAction.this.setEnabled(myConfigurable != null && myConfigurable.isModified());
+ setEnabled(myConfigurable != null && myConfigurable.isModified());
}
catch (IndexNotReadyException ignored) {
}
@@ -214,6 +219,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
// invokeLater necessary to make sure dialog is already shown so we calculate modality state correctly.
SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
addUpdateRequest(updateRequest);
}
@@ -224,6 +230,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
myUpdateAlarm.addRequest(updateRequest, 500, ModalityState.stateForComponent(getWindow()));
}
+ @Override
public void actionPerformed(ActionEvent event) {
if (myPerformAction) return;
try {
@@ -248,11 +255,13 @@ public class SingleConfigurableEditor extends DialogWrapper {
}
}
+ @Override
protected JComponent createCenterPanel() {
myCenterPanel = myConfigurable.createComponent();
return myCenterPanel;
}
+ @Override
public JComponent getPreferredFocusedComponent() {
if (myConfigurable instanceof BaseConfigurable) {
JComponent preferred = ((BaseConfigurable)myConfigurable).getPreferredFocusedComponent();
@@ -261,6 +270,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
return IdeFocusTraversalPolicy.getPreferredFocusedComponent(myCenterPanel);
}
+ @Override
public void dispose() {
super.dispose();
myConfigurable.disposeUIResources();
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/IdeSettingsDialog.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/IdeSettingsDialog.java
new file mode 100644
index 000000000000..c38bf6ff2033
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/IdeSettingsDialog.java
@@ -0,0 +1,330 @@
+/*
+ * 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.newEditor;
+
+import com.intellij.CommonBundle;
+import com.intellij.ide.ui.search.SearchUtil;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.actionSystem.DataProvider;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.help.HelpManager;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurableGroup;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.ActionCallback;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.ui.Gray;
+import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.border.CustomLineBorder;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public class IdeSettingsDialog extends DialogWrapper implements DataProvider {
+ private Project myProject;
+ private ConfigurableGroup[] myGroups;
+ private Configurable myPreselected;
+ private OptionsEditor myEditor;
+
+ private ApplyAction myApplyAction;
+ public static final String DIMENSION_KEY = "OptionsEditor";
+ @NonNls static final String LAST_SELECTED_CONFIGURABLE = "options.lastSelected";
+
+ /**
+ * This constructor should be eliminated after the new modality approach
+ * will have been checked. See a {@code Registry} key ide.perProjectModality
+ *
+ * @deprecated
+ */
+ public IdeSettingsDialog(Project project, ConfigurableGroup[] groups,
+ @Nullable Configurable preselectedConfigurable, boolean applicationModalIfPossible) {
+ super(project, true, applicationModalIfPossible);
+ init(project, groups, preselectedConfigurable != null ? preselectedConfigurable : findLastSavedConfigurable(groups, project));
+ }
+
+ /**
+ * This constructor should be eliminated after the new modality approach
+ * will have been checked. See a {@code Registry} key ide.perProjectModality
+ *
+ * @deprecated
+ */
+ public IdeSettingsDialog(Project project, ConfigurableGroup[] groups,
+ @NotNull String preselectedConfigurableDisplayName, boolean applicationModalIfPossible) {
+ super(project, true, applicationModalIfPossible);
+ init(project, groups, getPreselectedByDisplayName(groups, preselectedConfigurableDisplayName, project));
+ }
+
+ public IdeSettingsDialog(Project project, ConfigurableGroup[] groups, @Nullable Configurable preselectedConfigurable) {
+ super(project, true);
+ init(project, groups, preselectedConfigurable != null ? preselectedConfigurable : findLastSavedConfigurable(groups, project));
+ }
+
+ public IdeSettingsDialog(Project project, ConfigurableGroup[] groups, @NotNull String preselectedConfigurableDisplayName) {
+ super(project, true);
+ init(project, groups, getPreselectedByDisplayName(groups, preselectedConfigurableDisplayName, project));
+ }
+
+ @Nullable
+ @Override
+ protected Border createContentPaneBorder() {
+ return IdeBorderFactory.createEmptyBorder(0);
+ }
+
+ private void init(final Project project, final ConfigurableGroup[] groups, @Nullable final Configurable preselected) {
+ myProject = project;
+ myGroups = groups;
+ myPreselected = preselected;
+
+ setTitle(CommonBundle.settingsTitle());
+
+ init();
+ }
+
+ @Nullable
+ private static Configurable getPreselectedByDisplayName(final ConfigurableGroup[] groups, final String preselectedConfigurableDisplayName,
+ final Project project) {
+ Configurable result = findPreselectedByDisplayName(preselectedConfigurableDisplayName, groups);
+
+ return result == null ? findLastSavedConfigurable(groups, project) : result;
+ }
+
+ @Override
+ public boolean isTypeAheadEnabled() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createSouthPanel() {
+ final JComponent panel = super.createSouthPanel();
+ CustomLineBorder line = new CustomLineBorder(new JBColor(Gray._153.withAlpha(128), Gray._100.withAlpha(128)), 1, 0, 0, 0);
+ panel.setBorder(new CompoundBorder(line, new EmptyBorder(8, 12, 8, 12)));
+ return panel;
+ }
+
+ protected JComponent createCenterPanel() {
+ myEditor = new OptionsEditor(myProject, myGroups, myPreselected);
+ myEditor.getContext().addColleague(new OptionsEditorColleague.Adapter() {
+ @Override
+ public ActionCallback onModifiedAdded(final Configurable configurable) {
+ updateStatus();
+ return new ActionCallback.Done();
+ }
+
+ @Override
+ public ActionCallback onModifiedRemoved(final Configurable configurable) {
+ updateStatus();
+ return new ActionCallback.Done();
+ }
+
+ @Override
+ public ActionCallback onErrorsChanged() {
+ updateStatus();
+ return new ActionCallback.Done();
+ }
+ });
+ Disposer.register(myDisposable, myEditor);
+ return myEditor;
+ }
+
+ public boolean updateStatus() {
+ myApplyAction.setEnabled(myEditor.canApply());
+
+ final Map<Configurable, ConfigurationException> errors = myEditor.getContext().getErrors();
+ if (errors.size() == 0) {
+ setErrorText(null);
+ }
+ else {
+ String text = "Changes were not applied because of an error";
+
+ final String errorMessage = getErrorMessage(errors);
+ if (errorMessage != null) {
+ text += "<br>" + errorMessage;
+ }
+
+ setErrorText(text);
+ }
+
+ return errors.size() == 0;
+ }
+
+ @Nullable
+ private static String getErrorMessage(final Map<Configurable, ConfigurationException> errors) {
+ final Collection<ConfigurationException> values = errors.values();
+ final ConfigurationException[] exceptions = values.toArray(new ConfigurationException[values.size()]);
+ if (exceptions.length > 0) {
+ return exceptions[0].getMessage();
+ }
+ return null;
+ }
+
+ @Override
+ protected String getDimensionServiceKey() {
+ return DIMENSION_KEY;
+ }
+
+ @Override
+ protected void doOKAction() {
+ myEditor.flushModifications();
+
+ if (myEditor.canApply()) {
+ myEditor.apply();
+ if (!updateStatus()) return;
+ }
+
+ saveCurrentConfigurable();
+
+ ApplicationManager.getApplication().saveAll();
+
+ super.doOKAction();
+ }
+
+
+ private void saveCurrentConfigurable() {
+ final Configurable current = myEditor.getContext().getCurrentConfigurable();
+ if (current == null) return;
+
+ final PropertiesComponent props = PropertiesComponent.getInstance(myProject);
+
+ if (current instanceof SearchableConfigurable) {
+ props.setValue(LAST_SELECTED_CONFIGURABLE, ((SearchableConfigurable)current).getId());
+ }
+ else {
+ props.setValue(LAST_SELECTED_CONFIGURABLE, current.getClass().getName());
+ }
+ }
+
+ @Nullable
+ private static Configurable findLastSavedConfigurable(ConfigurableGroup[] groups, final Project project) {
+ final String id = PropertiesComponent.getInstance(project).getValue(LAST_SELECTED_CONFIGURABLE);
+ if (id == null) return null;
+
+ return findConfigurableInGroups(id, groups);
+ }
+
+ @Nullable
+ private static Configurable findConfigurableInGroups(String id, Configurable.Composite... groups) {
+ // avoid unnecessary group expand: check top-level configurables in all groups before looking at children
+ for (Configurable.Composite group : groups) {
+ final Configurable[] configurables = group.getConfigurables();
+ for (Configurable c : configurables) {
+ if (c instanceof SearchableConfigurable && id.equals(((SearchableConfigurable)c).getId())) {
+ return c;
+ }
+ else if (id.equals(c.getClass().getName())) {
+ return c;
+ }
+ }
+ }
+ for (Configurable.Composite group : groups) {
+ final Configurable[] configurables = group.getConfigurables();
+ for (Configurable c : configurables) {
+ if (c instanceof Configurable.Composite) {
+ Configurable result = findConfigurableInGroups(id, (Configurable.Composite)c);
+ if (result != null) {
+ return result;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ private static Configurable findPreselectedByDisplayName(final String preselectedConfigurableDisplayName, ConfigurableGroup[] groups) {
+ final List<Configurable> all = SearchUtil.expand(groups);
+ for (Configurable each : all) {
+ if (preselectedConfigurableDisplayName.equals(each.getDisplayName())) return each;
+ }
+ return null;
+ }
+
+ @Override
+ public void doCancelAction(final AWTEvent source) {
+ if (source instanceof KeyEvent || source instanceof ActionEvent) {
+ if (myEditor.getContext().isHoldingFilter()) {
+ myEditor.clearFilter();
+ return;
+ }
+ }
+
+ super.doCancelAction(source);
+ }
+
+ @Override
+ public void doCancelAction() {
+ saveCurrentConfigurable();
+ super.doCancelAction();
+ }
+
+ @NotNull
+ @Override
+ protected Action[] createActions() {
+ myApplyAction = new ApplyAction();
+ return new Action[]{getOKAction(), getCancelAction(), myApplyAction, getHelpAction()};
+ }
+
+ @Override
+ protected void doHelpAction() {
+ final String topic = myEditor.getHelpTopic();
+ if (topic != null) {
+ HelpManager.getInstance().invokeHelp(topic);
+ }
+ }
+
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return myEditor.getPreferredFocusedComponent();
+ }
+
+ public Object getData(@NonNls String dataId) {
+ if (OptionsEditor.KEY.is(dataId)) {
+ return myEditor;
+ }
+ return null;
+ }
+
+ private class ApplyAction extends AbstractAction {
+ public ApplyAction() {
+ super(CommonBundle.getApplyButtonText());
+ setEnabled(false);
+ }
+
+ public void actionPerformed(final ActionEvent e) {
+ myEditor.apply();
+ myEditor.revalidate();
+ myEditor.repaint();
+ }
+ }
+}
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 271539f038a0..c2119596a06e 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
@@ -15,9 +15,12 @@
*/
package com.intellij.openapi.options.newEditor;
-import com.intellij.ide.ui.search.ConfigurableHit;
+import com.intellij.AbstractBundle;
+import com.intellij.CommonBundle;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.ui.laf.darcula.ui.DarculaTextBorder;
+import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI;
import com.intellij.ide.ui.search.SearchUtil;
-import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.internal.statistic.UsageTrigger;
import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
@@ -36,18 +39,18 @@ 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.SystemInfo;
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;
import com.intellij.ui.LightColors;
+import com.intellij.ui.OnePixelSplitter;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SearchTextField;
+import com.intellij.ui.components.labels.LinkLabel;
import com.intellij.ui.components.panels.NonOpaquePanel;
import com.intellij.ui.components.panels.Wrapper;
import com.intellij.ui.navigation.History;
import com.intellij.ui.navigation.Place;
-import com.intellij.ui.speedSearch.ElementFilter;
import com.intellij.ui.treeStructure.SimpleNode;
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
import com.intellij.util.ui.UIUtil;
@@ -61,7 +64,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.event.DocumentEvent;
+import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
@@ -77,23 +80,18 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
@NonNls private static final String MAIN_SPLITTER_PROPORTION = "options.splitter.main.proportions";
@NonNls private static final String DETAILS_SPLITTER_PROPORTION = "options.splitter.details.proportions";
- @NonNls private static final String SEARCH_VISIBLE = "options.searchVisible";
-
@NonNls private static final String NOT_A_NEW_COMPONENT = "component.was.already.instantiated";
- private final Project myProject;
-
- private final OptionsEditorContext myContext;
-
private final History myHistory = new History(this);
private final OptionsTree myTree;
private final SettingsTreeView myTreeView;
- private final MySearchField mySearch;
+ private final SearchTextField mySearch;
private final Splitter myMainSplitter;
//[back/forward] JComponent myToolbarComponent;
- private final DetailsComponent myOwnDetails = new DetailsComponent().setEmptyContentText("Select configuration element in the tree to edit its settings");
+ private final DetailsComponent myOwnDetails =
+ new DetailsComponent().setEmptyContentText("Select configuration element in the tree to edit its settings");
private final ContentWrapper myContentWrapper = new ContentWrapper();
@@ -101,30 +99,54 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
private final Map<Configurable, ActionCallback> myConfigurable2LoadCallback = new HashMap<Configurable, ActionCallback>();
private final MergingUpdateQueue myModificationChecker;
- private final ConfigurableGroup[] myGroups;
private final SpotlightPainter mySpotlightPainter = new SpotlightPainter();
private final MergingUpdateQueue mySpotlightUpdate;
private final LoadingDecorator myLoadingDecorator;
- private final Filter myFilter;
+ private final SettingsFilter myFilter;
private final Wrapper mySearchWrapper = new Wrapper();
private final JPanel myLeftSide;
- private boolean myFilterDocumentWasChanged;
//[back/forward] private ActionToolbar myToolbar;
private Window myWindow;
private final PropertiesComponent myProperties;
private volatile boolean myDisposed;
+ private final KeyListener myTreeKeyListener = new KeyListener() {
+ @Override
+ public void keyPressed(KeyEvent event) {
+ keyTyped(event);
+ }
+
+ @Override
+ public void keyReleased(KeyEvent event) {
+ keyTyped(event);
+ }
+
+ @Override
+ public void keyTyped(KeyEvent event) {
+ Object source = event.getSource();
+ if (source instanceof JTree) {
+ JTree tree = (JTree)source;
+ if (tree.getInputMap().get(KeyStroke.getKeyStrokeForEvent(event)) == null) {
+ myFilter.myDocumentWasChanged = false;
+ try {
+ mySearch.keyEventToTextField(event);
+ }
+ finally {
+ if (myFilter.myDocumentWasChanged && !isFilterFieldVisible()) {
+ setFilterFieldVisible(true, false, false);
+ }
+ }
+ }
+ }
+ }
+ };
+
public OptionsEditor(Project project, ConfigurableGroup[] groups, Configurable preselectedConfigurable) {
- myProject = project;
- myGroups = groups;
myProperties = PropertiesComponent.getInstance(project);
- myFilter = new Filter();
- myContext = new OptionsEditorContext(myFilter);
-
mySearch = new MySearchField() {
@Override
protected void onTextKeyEvent(final KeyEvent e) {
@@ -137,67 +159,53 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
};
- mySearch.getTextEditor().addMouseListener(new MouseAdapter() {
- @Override
- public void mousePressed(MouseEvent e) {
- boolean hasText = mySearch.getText().length() > 0;
- if (!myContext.isHoldingFilter() && hasText) {
- myFilter.reenable();
- }
-
- if (!isSearchFieldFocused() && hasText) {
- mySearch.selectText();
- }
- }
- });
-
- final KeyListener listener = new KeyListener() {
+ myFilter = new SettingsFilter(project, groups, mySearch) {
@Override
- public void keyTyped(KeyEvent event) {
- myFilterDocumentWasChanged = false;
- try {
- mySearch.keyEventToTextField(event);
- }
- finally {
- if (myFilterDocumentWasChanged && !isFilterFieldVisible()) {
- setFilterFieldVisible(true, false, false);
- }
+ Configurable getConfigurable(SimpleNode node) {
+ if (node instanceof OptionsTree.EditorNode) {
+ return ((OptionsTree.EditorNode)node).getConfigurable();
}
+ return SettingsTreeView.getConfigurable(node);
}
@Override
- public void keyPressed(KeyEvent event) {
- keyTyped(event);
+ SimpleNode findNode(Configurable configurable) {
+ return myTreeView != null
+ ? myTreeView.findNode(configurable)
+ : myTree.findNodeFor(configurable);
}
@Override
- public void keyReleased(KeyEvent event) {
- keyTyped(event);
+ void updateSpotlight(boolean now) {
+ if (!now) {
+ mySpotlightUpdate.queue(new Update(this) {
+ @Override
+ public void run() {
+ if (!mySpotlightPainter.updateForCurrentConfigurable()) {
+ updateSpotlight(false);
+ }
+ }
+ });
+ }
+ else if (!mySpotlightPainter.updateForCurrentConfigurable()) {
+ updateSpotlight(false);
+ }
}
};
- if (Registry.is("ide.file.settings.tree.new")) {
- myTreeView = new SettingsTreeView(listener, getContext(), groups);
+
+ if (Registry.is("ide.new.settings.dialog")) {
+ myTreeView = new SettingsTreeView(myFilter, groups);
+ myTreeView.myTree.addKeyListener(myTreeKeyListener);
myTree = null;
}
else {
myTreeView = null;
- myTree = new OptionsTree(myProject, groups, getContext()) {
- @Override
- protected void onTreeKeyEvent(final KeyEvent e) {
- listener.keyTyped(e);
- }
- };
+ myTree = new OptionsTree(myFilter, groups);
+ myTree.addKeyListener(myTreeKeyListener);
}
getContext().addColleague(myTreeView != null ? myTreeView : myTree);
Disposer.register(this, myTreeView != null ? myTreeView : myTree);
- mySearch.addDocumentListener(new DocumentAdapter() {
- @Override
- protected void textChanged(DocumentEvent e) {
- myFilter.update(e.getType(), true, false);
- }
- });
-
/* [back/forward]
final DefaultActionGroup toolbarActions = new DefaultActionGroup();
@@ -246,7 +254,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
setLayout(new BorderLayout());
- myMainSplitter = new Splitter(false);
+ myMainSplitter = Registry.is("ide.new.settings.dialog") ? new OnePixelSplitter(false) : new Splitter(false);
myMainSplitter.setFirstComponent(myLeftSide);
myLoadingDecorator = new LoadingDecorator(myOwnDetails.getComponent(), this, 150);
@@ -264,13 +272,9 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
mySpotlightUpdate = new MergingUpdateQueue("OptionsSpotlight", 200, false, this, this, this);
if (preselectedConfigurable != null) {
- if (myTreeView != null) {
- myTreeView.select(preselectedConfigurable);
- }
- else {
- myTree.select(preselectedConfigurable);
- }
- } else {
+ selectInTree(preselectedConfigurable);
+ }
+ else {
if (myTreeView != null) {
myTreeView.selectFirst();
}
@@ -322,6 +326,12 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
});
}
+ private ActionCallback selectInTree(Configurable configurable) {
+ return myTreeView != null
+ ? myTreeView.select(configurable)
+ : myTree.select(configurable);
+ }
+
/** @see #select(com.intellij.openapi.options.Configurable) */
@Deprecated
public ActionCallback select(Class<? extends Configurable> configurableClass) {
@@ -354,18 +364,17 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
public ActionCallback select(Configurable configurable) {
- if (StringUtil.isEmpty(mySearch.getText())) {
+ if (myFilter.getFilterText().isEmpty()) {
return select(configurable, "");
- } else {
- return myFilter.refilterFor(mySearch.getText(), true, true);
+ }
+ else {
+ return myFilter.update(true, true);
}
}
public ActionCallback select(Configurable configurable, final String text) {
- myFilter.refilterFor(text, false, true);
- return myTreeView != null
- ? myTreeView.select(configurable)
- : myTree.select(configurable);
+ myFilter.update(text, false, true);
+ return selectInTree(configurable);
}
private float readProportion(final float defaultValue, final String propertyName) {
@@ -390,7 +399,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
if (configurable == null) {
myOwnDetails.setContent(null);
- updateSpotlight(true);
+ myFilter.updateSpotlight(true);
checkModified(oldConfigurable);
result.setDone();
@@ -417,7 +426,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
if (myTreeView != null) {
myOwnDetails.forProject(myTreeView.findConfigurableProject(configurable));
}
- else if (Registry.is("ide.file.settings.order.new")) {
+ else if (Registry.is("ide.new.settings.dialog")) {
myOwnDetails.forProject(myTree.getConfigurableProject(configurable));
}
@@ -430,7 +439,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
myLoadingDecorator.stopLoading();
- updateSpotlight(false);
+ myFilter.updateSpotlight(false);
checkModified(oldConfigurable);
checkModified(configurable);
@@ -480,7 +489,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
((ApplicationEx)app).runEdtSafeAction(new Runnable() {
@Override
public void run() {
- if (myProject.isDisposed()) {
+ if (myFilter.myProject.isDisposed()) {
result.setRejected();
}
else {
@@ -537,26 +546,6 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
return result;
}
-
- private void updateSpotlight(boolean now) {
- if (now) {
- final boolean success = mySpotlightPainter.updateForCurrentConfigurable();
- if (!success) {
- updateSpotlight(false);
- }
- } else {
- mySpotlightUpdate.queue(new Update(this) {
- @Override
- public void run() {
- final boolean success = mySpotlightPainter.updateForCurrentConfigurable();
- if (!success) {
- updateSpotlight(false);
- }
- }
- });
- }
- }
-
private String[] getBannerText(Configurable configurable) {
if (myTreeView != null) {
return myTreeView.getPathNames(configurable);
@@ -712,7 +701,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
@Override
public boolean isEnabled() {
- return myContext.isModified(myConfigurable) || getContext().getErrors().containsKey(myConfigurable);
+ return myFilter.myContext.isModified(myConfigurable) || getContext().getErrors().containsKey(myConfigurable);
}
}
@@ -849,12 +838,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
getContext().fireErrorsChanged(errors, null);
if (!errors.isEmpty()) {
- if (myTreeView != null) {
- myTreeView.select(errors.keySet().iterator().next());
- }
- else {
- myTree.select(errors.keySet().iterator().next());
- }
+ selectInTree(errors.keySet().iterator().next());
}
}
@@ -868,7 +852,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
public JComponent getPreferredFocusedComponent() {
- return mySearch;//myTree.getTree();
+ return myTreeView != null ? myTreeView.myTree : mySearch;//myTree.getTree();
}
@Override
@@ -876,145 +860,6 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
return new Dimension(1200, 768);
}
- private class Filter extends ElementFilter.Active.Impl<SimpleNode> {
-
- SearchableOptionsRegistrar myIndex = SearchableOptionsRegistrar.getInstance();
- Set<Configurable> myFiltered = null;
- ConfigurableHit myHits;
-
- boolean myUpdateEnabled = true;
- private Configurable myLastSelected;
-
- @Override
- public boolean shouldBeShowing(final SimpleNode value) {
- if (myFiltered == null) return true;
-
- if (value instanceof OptionsTree.EditorNode) {
- final OptionsTree.EditorNode node = (OptionsTree.EditorNode)value;
- return myFiltered.contains(node.getConfigurable()) || isChildOfNameHit(node);
- }
-
- return SettingsTreeView.isFiltered(myFiltered, myHits, value);
- }
-
- private boolean isChildOfNameHit(OptionsTree.EditorNode node) {
- if (myHits != null) {
- OptionsTree.Base eachParent = node;
- while (eachParent != null) {
- if (eachParent instanceof OptionsTree.EditorNode) {
- final OptionsTree.EditorNode eachEditorNode = (OptionsTree.EditorNode)eachParent;
- if (myHits.getNameFullHits().contains(eachEditorNode.myConfigurable)) return true;
- }
- eachParent = (OptionsTree.Base)eachParent.getParent();
- }
-
- return false;
- }
-
- return false;
- }
-
- public ActionCallback refilterFor(String text, boolean adjustSelection, final boolean now) {
- try {
- myUpdateEnabled = false;
- mySearch.setText(text);
- }
- finally {
- myUpdateEnabled = true;
- }
-
- return update(DocumentEvent.EventType.CHANGE, adjustSelection, now);
- }
-
- public void clearTemporary() {
- myContext.setHoldingFilter(false);
- updateSpotlight(false);
- }
-
- public void reenable() {
- myContext.setHoldingFilter(true);
- updateSpotlight(false);
- }
-
- public ActionCallback update(DocumentEvent.EventType type, boolean adjustSelection, boolean now) {
- if (!myUpdateEnabled) return new ActionCallback.Rejected();
-
- final String text = mySearch.getText();
- if (getFilterText().length() == 0) {
- myContext.setHoldingFilter(false);
- myFiltered = null;
- } else {
- myContext.setHoldingFilter(true);
- myHits = myIndex.getConfigurables(myGroups, type, myFiltered, text, myProject);
- myFiltered = myHits.getAll();
- }
-
- if (myFiltered != null && myFiltered.isEmpty()) {
- mySearch.getTextEditor().setBackground(LightColors.RED);
- } else {
- mySearch.getTextEditor().setBackground(UIUtil.getTextFieldBackground());
- }
-
-
- final Configurable current = getContext().getCurrentConfigurable();
-
- boolean shouldMoveSelection = true;
-
- if (myHits != null && (myHits.getNameFullHits().contains(current) || myHits.getContentHits().contains(current))) {
- shouldMoveSelection = false;
- }
-
- if (shouldMoveSelection && type != DocumentEvent.EventType.INSERT && (myFiltered == null || myFiltered.contains(current))) {
- shouldMoveSelection = false;
- }
-
- Configurable toSelect = adjustSelection ? current : null;
- if (shouldMoveSelection && myHits != null) {
- if (!myHits.getNameHits().isEmpty()) {
- toSelect = suggestToSelect(myHits.getNameHits(), myHits.getNameFullHits());
- } else if (!myHits.getContentHits().isEmpty()) {
- toSelect = suggestToSelect(myHits.getContentHits(), null);
- }
- }
-
- updateSpotlight(false);
-
- if ((myFiltered == null || !myFiltered.isEmpty()) && toSelect == null && myLastSelected != null) {
- toSelect = myLastSelected;
- myLastSelected = null;
- }
-
- if (toSelect == null && current != null) {
- myLastSelected = current;
- }
-
- SimpleNode node = !adjustSelection ? null : myTreeView != null ? myTreeView.findNode(toSelect) : myTree.findNodeFor(toSelect);
- final ActionCallback callback = fireUpdate(node, adjustSelection, now);
-
- myFilterDocumentWasChanged = true;
-
- return callback;
- }
-
- private boolean isEmptyParent(Configurable configurable) {
- return configurable instanceof SearchableConfigurable.Parent && !((SearchableConfigurable.Parent)configurable).hasOwnContent();
- }
-
- @Nullable
- private Configurable suggestToSelect(Set<Configurable> set, Set<Configurable> fullHits) {
- Configurable candidate = null;
- for (Configurable each : set) {
- if (fullHits != null && fullHits.contains(each)) return each;
- if (!isEmptyParent(each) && candidate == null) {
- candidate = each;
- }
- }
-
- return candidate;
- }
-
- }
-
@Override
public ActionCallback navigateTo(@Nullable final Place place, final boolean requestFocus) {
final Configurable config = (Configurable)place.getPath("configurable");
@@ -1022,15 +867,10 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
final ActionCallback result = new ActionCallback();
- myFilter.refilterFor(filter, false, true).doWhenDone(new Runnable() {
+ myFilter.update(filter, false, true).doWhenDone(new Runnable() {
@Override
public void run() {
- if (myTreeView != null) {
- myTreeView.select(config).notifyWhenDone(result);
- }
- else {
- myTree.select(config).notifyWhenDone(result);
- }
+ selectInTree(config).notifyWhenDone(result);
}
});
@@ -1041,7 +881,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
public void queryPlace(@NotNull final Place place) {
final Configurable current = getContext().getCurrentConfigurable();
place.putPath("configurable", current);
- place.putPath("filter", getFilterText());
+ place.putPath("filter", myFilter.getFilterText());
if (current instanceof Place.Navigator) {
((Place.Navigator)current).queryPlace(place);
@@ -1060,7 +900,6 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
myProperties.setValue(MAIN_SPLITTER_PROPORTION, String.valueOf(myMainSplitter.getProportion()));
myProperties.setValue(DETAILS_SPLITTER_PROPORTION, String.valueOf(myContentWrapper.myLastSplitterProportion));
- myProperties.setValue(SEARCH_VISIBLE, Boolean.valueOf(isFilterFieldVisible()).toString());
Toolkit.getDefaultToolkit().removeAWTEventListener(this);
@@ -1087,7 +926,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
public OptionsEditorContext getContext() {
- return myContext;
+ return myFilter.myContext;
}
private class MyColleague extends OptionsEditorColleague.Adapter {
@@ -1137,7 +976,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
final MouseEvent me = (MouseEvent)event;
if (SwingUtilities.isDescendingFrom(me.getComponent(), SwingUtilities.getWindowAncestor(myContentWrapper)) || isPopupOverEditor(me.getComponent())) {
queueModificationCheck();
- myFilter.clearTemporary();
+ myFilter.setHoldingFilter(false);
}
}
else if (event.getID() == KeyEvent.KEY_PRESSED || event.getID() == KeyEvent.KEY_RELEASED) {
@@ -1175,6 +1014,23 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
private MySearchField() {
super(false);
addKeyListener(new KeyAdapter() {});
+ if (Registry.is("ide.new.settings.dialog")) {
+ final JTextField editor = getTextEditor();
+ if (!SystemInfo.isMac) {
+ editor.putClientProperty("JTextField.variant", "search");
+ if (!(editor.getUI() instanceof DarculaTextFieldUI)) {
+ editor.setUI((DarculaTextFieldUI)DarculaTextFieldUI.createUI(editor));
+ editor.setBorder(new DarculaTextBorder());
+ }
+ }
+ setBackground(UIUtil.getSidePanelColor());
+ setBorder(new EmptyBorder(5, 10, 2, 10));
+ }
+ }
+
+ @Override
+ protected boolean isSearchControlUISupported() {
+ return true;
}
@Override
@@ -1236,7 +1092,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
return ApplicationManager.getApplication().isUnitTestMode();
}
- String text = getFilterText();
+ String text = myFilter.getFilterText();
try {
final boolean sameText =
@@ -1263,14 +1119,7 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
myVisible = true;//myContext.isHoldingFilter();
runnable.run();
- boolean pushFilteringFurther = true;
- if (sameText) {
- pushFilteringFurther = false;
- } else {
- if (myFilter.myHits != null) {
- pushFilteringFurther = !myFilter.myHits.getNameHits().contains(current);
- }
- }
+ boolean pushFilteringFurther = !sameText && !myFilter.contains(current);
final Runnable ownSearch = searchable.enableSearch(text);
if (pushFilteringFurther && ownSearch != null) {
@@ -1295,10 +1144,6 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
}
}
- private String getFilterText() {
- return mySearch.getText() != null ? mySearch.getText().trim() : "";
- }
-
private static class SearachableWrappper implements SearchableConfigurable {
private final Configurable myConfigurable;
@@ -1366,6 +1211,49 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
abstract void setText(final String[] bannerText);
}
+ /**
+ * Returns default view for the specified configurable.
+ * It uses the configurable identifier to retrieve description.
+ *
+ * @param searchable the configurable that does not have any view
+ * @return default view for the specified configurable
+ */
+ private JComponent createDefaultComponent(SearchableConfigurable searchable) {
+ JPanel box = new JPanel();
+ box.setLayout(new BoxLayout(box, BoxLayout.Y_AXIS));
+ try {
+ box.add(new JLabel(getDefaultDescription(searchable)));
+ }
+ catch (AssertionError error) {
+ return null; // description is not set
+ }
+ if (searchable instanceof Configurable.Composite) {
+ box.add(Box.createVerticalStrut(10));
+ Configurable.Composite composite = (Configurable.Composite)searchable;
+ for (final Configurable configurable : composite.getConfigurables()) {
+ box.add(new LinkLabel(configurable.getDisplayName(), AllIcons.Ide.Link) {
+ @Override
+ public void doClick() {
+ select(configurable, null);
+ }
+ });
+ }
+ }
+ return box;
+ }
+
+ @NotNull
+ private static String getDefaultDescription(SearchableConfigurable configurable) {
+ String key = configurable.getId() + ".settings.description";
+ if (configurable instanceof ConfigurableWrapper) {
+ ConfigurableWrapper wrapper = (ConfigurableWrapper) configurable;
+ ConfigurableEP ep = wrapper.getExtensionPoint();
+ ResourceBundle resourceBundle = AbstractBundle.getResourceBundle(ep.bundle, ep.getPluginDescriptor().getPluginClassLoader());
+ return CommonBundle.message(resourceBundle, key);
+ }
+ return OptionsBundle.message(key);
+ }
+
private class Simple extends ConfigurableContent {
JComponent myComponent;
Configurable myConfigurable;
@@ -1373,7 +1261,9 @@ public class OptionsEditor extends JPanel implements DataProvider, Place.Navigat
Simple(final Configurable configurable) {
myConfigurable = configurable;
myComponent = configurable.createComponent();
-
+ if (myComponent == null && configurable instanceof SearchableConfigurable) {
+ myComponent = createDefaultComponent((SearchableConfigurable)configurable);
+ }
if (myComponent != null) {
final Object clientProperty = myComponent.getClientProperty(NOT_A_NEW_COMPONENT);
if (clientProperty != null && ApplicationManager.getApplication().isInternal()) {
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 175b994122ef..aee9e889fdf1 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
@@ -37,6 +37,7 @@ import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
+import com.intellij.util.ui.tree.WideSelectionTreeUI;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NotNull;
@@ -49,33 +50,32 @@ import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.TreeUI;
-import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.*;
-import java.awt.event.*;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
public class OptionsTree extends JPanel implements Disposable, OptionsEditorColleague {
- Project myProject;
+ private final SettingsFilter myFilter;
final SimpleTree myTree;
List<ConfigurableGroup> myGroups;
FilteringTreeBuilder myBuilder;
Root myRoot;
- OptionsEditorContext myContext;
Map<Configurable, EditorNode> myConfigurable2Node = new HashMap<Configurable, EditorNode>();
MergingUpdateQueue mySelection;
private final OptionsTree.Renderer myRenderer;
- public OptionsTree(Project project, ConfigurableGroup[] groups, OptionsEditorContext context) {
- myProject = project;
+ public OptionsTree(SettingsFilter filter, ConfigurableGroup... groups) {
+ myFilter = filter;
myGroups = Arrays.asList(groups);
- myContext = context;
-
myRoot = new Root();
final SimpleTreeStructure structure = new SimpleTreeStructure() {
@@ -132,35 +132,8 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
}
}
});
- myTree.addKeyListener(new KeyListener() {
- public void keyTyped(final KeyEvent e) {
- _onTreeKeyEvent(e);
- }
-
- public void keyPressed(final KeyEvent e) {
- _onTreeKeyEvent(e);
- }
-
- public void keyReleased(final KeyEvent e) {
- _onTreeKeyEvent(e);
- }
- });
- }
-
- protected void _onTreeKeyEvent(KeyEvent e) {
- final KeyStroke stroke = KeyStroke.getKeyStrokeForEvent(e);
-
- final Object action = myTree.getInputMap().get(stroke);
- if (action == null) {
- onTreeKeyEvent(e);
- }
- }
-
- protected void onTreeKeyEvent(KeyEvent e) {
-
}
-
ActionCallback select(@Nullable Configurable configurable) {
return queueSelection(configurable);
}
@@ -191,7 +164,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
if (configurable == null) {
myTree.getSelectionModel().clearSelection();
- myContext.fireSelected(null, OptionsTree.this);
+ myFilter.myContext.fireSelected(null, OptionsTree.this);
}
else {
myBuilder.getReady(this).doWhenDone(new Runnable() {
@@ -232,7 +205,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
}
private void fireSelected(Configurable configurable, final ActionCallback callback) {
- myContext.fireSelected(configurable, this).doWhenProcessed(callback.createSetDoneRunnable());
+ myFilter.myContext.fireSelected(configurable, this).doWhenProcessed(callback.createSetDoneRunnable());
}
@@ -297,7 +270,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
myRendererComponent.setOpaqueActive(false);
mySeparator = new GroupSeparator();
- myRendererComponent.add(Registry.is("ide.file.settings.order.new") ? mySeparator : mySeparatorComponent, BorderLayout.NORTH);
+ myRendererComponent.add(Registry.is("ide.new.settings.dialog") ? mySeparator : mySeparatorComponent, BorderLayout.NORTH);
final NonOpaquePanel content = new NonOpaquePanel(new BorderLayout());
myHandle = new JLabel("", SwingConstants.CENTER);
@@ -401,12 +374,12 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
myTextLabel.setForeground(selected ? UIUtil.getTreeSelectionForeground() : fg);
myTextLabel.setOpaque(selected);
- if (Registry.is("ide.file.settings.order.new")) {
+ if (Registry.is("ide.new.settings.dialog")) {
myTextLabel.setBorder(new EmptyBorder(1,2,1,0));
}
Project project = null;
- if (base != null && Registry.is("ide.file.settings.order.new")) {
+ if (base != null && Registry.is("ide.new.settings.dialog")) {
SimpleNode parent = base.getParent();
if (parent == myRoot) {
project = getConfigurableProject(base); // show icon for top-level nodes
@@ -433,6 +406,9 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
} else {
myProjectIcon.setVisible(false);
}
+ if (Registry.is("ide.new.settings.dialog")) {
+ result.setBackground(selected ? UIUtil.getTreeSelectionBackground() : UIUtil.getSidePanelColor());
+ }
return result;
}
@@ -538,7 +514,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
final List<EditorNode> result = new ArrayList<EditorNode>(kids.length);
for (Configurable child : kids) {
result.add(new EditorNode(parent, child, group));
- myContext.registerKid(configurable, child);
+ myFilter.myContext.registerKid(configurable, child);
}
return result; // TODO: DECIDE IF INNERS SHOULD BE SORTED: sort(result);
}
@@ -602,12 +578,12 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
@Override
boolean isModified() {
- return myContext.getModified().contains(myConfigurable);
+ return myFilter.myContext.getModified().contains(myConfigurable);
}
@Override
boolean isError() {
- return myContext.getErrors().containsKey(myConfigurable);
+ return myFilter.myContext.getErrors().containsKey(myConfigurable);
}
}
@@ -757,7 +733,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
super.processMouseEvent(e);
}
- private class MyTreeUi extends BasicTreeUI {
+ private class MyTreeUi extends WideSelectionTreeUI {
@Override
public void toggleExpandState(final TreePath path) {
@@ -810,7 +786,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
boolean myWasHoldingFilter;
public MyBuilder(SimpleTreeStructure structure) {
- super(OptionsTree.this.myTree, myContext.getFilter(), structure, new WeightBasedComparator(false));
+ super(myTree, myFilter, structure, new WeightBasedComparator(false));
myTree.addTreeExpansionListener(new TreeExpansionListener() {
public void treeExpanded(TreeExpansionEvent event) {
invalidateExpansions();
@@ -835,7 +811,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
@Override
public boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) {
- return myContext.isHoldingFilter();
+ return myFilter.myContext.isHoldingFilter();
}
@Override
@@ -846,21 +822,21 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
@Override
protected ActionCallback refilterNow(Object preferredSelection, boolean adjustSelection) {
final List<Object> toRestore = new ArrayList<Object>();
- if (myContext.isHoldingFilter() && !myWasHoldingFilter && myToExpandOnResetFilter == null) {
+ if (myFilter.myContext.isHoldingFilter() && !myWasHoldingFilter && myToExpandOnResetFilter == null) {
myToExpandOnResetFilter = myBuilder.getUi().getExpandedElements();
- } else if (!myContext.isHoldingFilter() && myWasHoldingFilter && myToExpandOnResetFilter != null) {
+ } else if (!myFilter.myContext.isHoldingFilter() && myWasHoldingFilter && myToExpandOnResetFilter != null) {
toRestore.addAll(myToExpandOnResetFilter);
myToExpandOnResetFilter = null;
}
- myWasHoldingFilter = myContext.isHoldingFilter();
+ myWasHoldingFilter = myFilter.myContext.isHoldingFilter();
ActionCallback result = super.refilterNow(preferredSelection, adjustSelection);
myRefilteringNow = true;
return result.doWhenDone(new Runnable() {
public void run() {
myRefilteringNow = false;
- if (!myContext.isHoldingFilter() && getSelectedElements().isEmpty()) {
+ if (!myFilter.myContext.isHoldingFilter() && getSelectedElements().isEmpty()) {
restoreExpandedState(toRestore);
}
}
@@ -968,7 +944,7 @@ public class OptionsTree extends JPanel implements Disposable, OptionsEditorColl
public void paint(Graphics g) {
super.paint(g);
- if (Registry.is("ide.file.settings.order.new")) {
+ if (Registry.is("ide.new.settings.dialog")) {
ConfigurableGroup group = getGroup(GroupSeparator.SPACE + mySeparator.getFont().getSize());
if (group != null && group == getGroup(-GroupSeparator.SPACE)) {
mySeparator.configure(group, false);
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.form b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.form
deleted file mode 100644
index bfd8e1f0e416..000000000000
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.form
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.options.newEditor.PreferencesDialog">
- <grid id="27dc6" binding="myRoot" 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="400"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children>
- <grid id="81fb6" binding="myTopPanel" custom-create="true" layout-manager="BorderLayout" hgap="0" vgap="0">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
- <preferred-size width="-1" height="50"/>
- </grid>
- </constraints>
- <properties/>
- <border type="none"/>
- <children/>
- </grid>
- <vspacer id="420b1">
- <constraints>
- <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="b87b5" binding="myCenterPanel" layout-manager="BorderLayout" hgap="0" vgap="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"/>
- </constraints>
- <properties/>
- <border type="none"/>
- <children/>
- </grid>
- <hspacer id="e2eff">
- <constraints>
- <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
- </constraints>
- </hspacer>
- </children>
- </grid>
-</form>
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.java
deleted file mode 100644
index 8ed3527e090a..000000000000
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/PreferencesDialog.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2000-2013 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.newEditor;
-
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.options.ConfigurableGroup;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.DialogWrapper;
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.ui.Gray;
-import com.intellij.ui.SearchTextField;
-import com.intellij.ui.border.CustomLineBorder;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-import javax.swing.border.EmptyBorder;
-import javax.swing.border.LineBorder;
-import java.awt.*;
-
-/**
- * @author Konstantin Bulenkov
- */
-public class PreferencesDialog extends DialogWrapper {
- private JPanel myRoot;
- private JPanel myTopPanel;
- private JPanel myCenterPanel;
- private SearchTextField mySearchTextField;
-
- public PreferencesDialog(@Nullable Project project, ConfigurableGroup[] groups) {
- super(project);
- init();
- ((JDialog)getPeer().getWindow()).setUndecorated(true);
- if (SystemInfo.isMac) {
- ((JComponent)((JDialog)getPeer().getWindow()).getContentPane()).setBorder(new EmptyBorder(0, 0, 0, 0));
- }
- else {
- ((JComponent)((JDialog)getPeer().getWindow()).getContentPane()).setBorder(new LineBorder(Gray._140, 1));
- }
-
- setTitle("Preferences");
- }
-
- @Nullable
- @Override
- protected JComponent createCenterPanel() {
- final JPanel panel = new JPanel();
- panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
- panel.setBorder(null);
- panel.add(createApplicationSettings());
- panel.add(createProjectSettings());
- panel.add(createEditorSettings());
- panel.add(createOtherSettings());
- panel.setPreferredSize(new Dimension(700, 370));
- myCenterPanel.add(panel, BorderLayout.CENTER);
- return myRoot;
- }
-
- @Nullable
- @Override
- public JComponent getPreferredFocusedComponent() {
- return mySearchTextField.getTextEditor();
- }
-
- private static JComponent createEditorSettings() {
- final LabeledButtonsPanel panel = new LabeledButtonsPanel("Editor");
- panel.addButton(new PreferenceButton("Editor", AllIcons.Preferences.Editor));
- panel.addButton(new PreferenceButton("Code Style", AllIcons.Preferences.CodeStyle));
- panel.setBackground(Gray._229);
- panel.setBorder(new CustomLineBorder(Gray._223, 0, 0, 1, 0));
- return panel;
- }
-
- private static JComponent createProjectSettings() {
- final LabeledButtonsPanel panel = new LabeledButtonsPanel("Project");
- panel.addButton(new PreferenceButton("Compiler", AllIcons.Preferences.Compiler));
- panel.addButton(new PreferenceButton("Version Control", AllIcons.Preferences.VersionControl));
- panel.addButton(new PreferenceButton("File Colors", AllIcons.Preferences.FileColors));
- panel.addButton(new PreferenceButton("Scopes", AllIcons.Preferences.Editor));
- panel.setBackground(Gray._236);
- panel.setBorder(new CustomLineBorder(Gray._223, 0, 0, 1, 0));
- return panel;
- }
-
- private static JComponent createApplicationSettings() {
- final LabeledButtonsPanel panel = new LabeledButtonsPanel("IDE");
- panel.addButton(new PreferenceButton("Appearance", AllIcons.Preferences.Appearance));
- panel.addButton(new PreferenceButton("General", AllIcons.Preferences.General));
- panel.addButton(new PreferenceButton("Keymap", AllIcons.Preferences.Keymap));
- panel.addButton(new PreferenceButton("File Types", AllIcons.Preferences.FileTypes));
- panel.setBackground(Gray._229);
- panel.setBorder(new CustomLineBorder(Gray._223, 0, 0, 1, 0));
- return panel;
- }
-
- private static JComponent createOtherSettings() {
- final LabeledButtonsPanel panel = new LabeledButtonsPanel("Other");
- panel.addButton(new PreferenceButton("Plugins", AllIcons.Preferences.Plugins));
- panel.addButton(new PreferenceButton("Updates", AllIcons.Preferences.Updates));
- panel.setBackground(Gray._236);
- panel.setBorder(new CustomLineBorder(Gray._223, 0, 0, 1, 0));
- return panel;
- }
-
-
- @Nullable
- @Override
- protected JComponent createSouthPanel() {
- if (SystemInfo.isMac) {
- return null;
- }
- final JComponent panel = super.createSouthPanel();
- if (panel != null) {
- panel.setBorder(new EmptyBorder(5, 5, 10, 20));
- }
- return panel;
- }
-
- private void createUIComponents() {
- myTopPanel = new JPanel(new BorderLayout()) {
- @Override
- protected void paintComponent(Graphics g) {
- ((Graphics2D)g).setPaint(new GradientPaint(0, 0, Gray._206, 0, getHeight() - 1, Gray._172));
- g.fillRect(0, 0, getWidth(), getHeight());
- g.setColor(Gray._145);
- g.drawLine(0, getHeight() - 2, getWidth(), getHeight() - 2);
- g.setColor(Gray._103);
- g.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
- }
- };
- final JLabel title = new JLabel("Preferences");
- if (!SystemInfo.isMac) {
- title.setFont(UIUtil.getLabelFont().deriveFont(Font.BOLD, 14));
- }
- else {
- title.setFont(new Font("Lucuda Grande", Font.PLAIN, 12));
- }
- title.setHorizontalTextPosition(SwingConstants.CENTER);
- title.setHorizontalAlignment(SwingConstants.CENTER);
- title.setVerticalAlignment(SwingConstants.TOP);
- myTopPanel.add(title, BorderLayout.NORTH);
- mySearchTextField = new SearchTextField();
- mySearchTextField.setOpaque(false);
- myTopPanel.add(mySearchTextField, BorderLayout.EAST);
- }
-}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java
new file mode 100644
index 000000000000..1885a852c5da
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java
@@ -0,0 +1,211 @@
+/*
+ * 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.newEditor;
+
+import com.intellij.ide.ui.search.ConfigurableHit;
+import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurableGroup;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.ActionCallback;
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.ui.LightColors;
+import com.intellij.ui.SearchTextField;
+import com.intellij.ui.speedSearch.ElementFilter;
+import com.intellij.ui.treeStructure.SimpleNode;
+import com.intellij.util.ui.UIUtil;
+
+import javax.swing.event.DocumentEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.Set;
+
+abstract class SettingsFilter extends ElementFilter.Active.Impl<SimpleNode> {
+ final OptionsEditorContext myContext = new OptionsEditorContext(this);
+ final Project myProject;
+
+ boolean myDocumentWasChanged;
+
+ private final SearchTextField mySearch;
+ private final ConfigurableGroup[] myGroups;
+
+ private SearchableOptionsRegistrar myRegistrar = SearchableOptionsRegistrar.getInstance();
+ private Set<Configurable> myFiltered;
+ private ConfigurableHit myHits;
+
+ private boolean myUpdateRejected;
+ private Configurable myLastSelected;
+
+ SettingsFilter(Project project, ConfigurableGroup[] groups, SearchTextField search) {
+ myProject = project;
+ myGroups = groups;
+ mySearch = search;
+ mySearch.addDocumentListener(new DocumentAdapter() {
+ @Override
+ protected void textChanged(DocumentEvent event) {
+ update(event.getType(), true, false);
+ }
+ });
+ mySearch.getTextEditor().addMouseListener(new MouseAdapter() {
+ @Override
+ public void mousePressed(MouseEvent event) {
+ if (!mySearch.getText().isEmpty()) {
+ if (!myContext.isHoldingFilter()) {
+ setHoldingFilter(true);
+ }
+ if (!mySearch.getTextEditor().isFocusOwner()) {
+ mySearch.selectText();
+ }
+ }
+ }
+ });
+ }
+
+ abstract Configurable getConfigurable(SimpleNode node);
+
+ abstract SimpleNode findNode(Configurable configurable);
+
+ abstract void updateSpotlight(boolean now);
+
+ @Override
+ public boolean shouldBeShowing(SimpleNode node) {
+ if (myFiltered != null) {
+ Configurable configurable = getConfigurable(node);
+ if (configurable != null) {
+ if (!myFiltered.contains(configurable)) {
+ if (myHits != null) {
+ Set<Configurable> configurables = myHits.getNameFullHits();
+ while (node != null) {
+ if (configurable != null) {
+ if (configurables.contains(configurable)) {
+ return true;
+ }
+ }
+ node = node.getParent();
+ configurable = getConfigurable(node);
+ }
+ }
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ String getFilterText() {
+ String text = mySearch.getText();
+ return text == null ? "" : text.trim();
+ }
+
+ void setHoldingFilter(boolean holding) {
+ myContext.setHoldingFilter(holding);
+ updateSpotlight(false);
+ }
+
+ boolean contains(Configurable configurable) {
+ return myHits != null && myHits.getNameHits().contains(configurable);
+ }
+
+ ActionCallback update(boolean adjustSelection, boolean now) {
+ return update(DocumentEvent.EventType.CHANGE, adjustSelection, now);
+ }
+
+ ActionCallback update(String text, boolean adjustSelection, boolean now) {
+ try {
+ myUpdateRejected = true;
+ mySearch.setText(text);
+ }
+ finally {
+ myUpdateRejected = false;
+ }
+ return update(adjustSelection, now);
+ }
+
+ private ActionCallback update(DocumentEvent.EventType type, boolean adjustSelection, boolean now) {
+ if (myUpdateRejected) {
+ return new ActionCallback.Rejected();
+ }
+ String text = getFilterText();
+ if (text.isEmpty()) {
+ myContext.setHoldingFilter(false);
+ myFiltered = null;
+ }
+ else {
+ myContext.setHoldingFilter(true);
+ myHits = myRegistrar.getConfigurables(myGroups, type, myFiltered, text, myProject);
+ myFiltered = myHits.getAll();
+ }
+ mySearch.getTextEditor().setBackground(myFiltered != null && myFiltered.isEmpty()
+ ? LightColors.RED
+ : UIUtil.getTextFieldBackground());
+
+
+ Configurable current = myContext.getCurrentConfigurable();
+
+ boolean shouldMoveSelection = myHits == null || (
+ !myHits.getNameFullHits().contains(current) &&
+ !myHits.getContentHits().contains(current));
+
+ if (shouldMoveSelection && type != DocumentEvent.EventType.INSERT && (myFiltered == null || myFiltered.contains(current))) {
+ shouldMoveSelection = false;
+ }
+
+ Configurable candidate = adjustSelection ? current : null;
+ if (shouldMoveSelection && myHits != null) {
+ if (!myHits.getNameHits().isEmpty()) {
+ candidate = findConfigurable(myHits.getNameHits(), myHits.getNameFullHits());
+ }
+ else if (!myHits.getContentHits().isEmpty()) {
+ candidate = findConfigurable(myHits.getContentHits(), null);
+ }
+ }
+ updateSpotlight(false);
+
+ if ((myFiltered == null || !myFiltered.isEmpty()) && candidate == null && myLastSelected != null) {
+ candidate = myLastSelected;
+ myLastSelected = null;
+ }
+ if (candidate == null && current != null) {
+ myLastSelected = current;
+ }
+ SimpleNode node = !adjustSelection ? null : findNode(candidate);
+ ActionCallback callback = fireUpdate(node, adjustSelection, now);
+ myDocumentWasChanged = true;
+ return callback;
+ }
+
+ private static Configurable findConfigurable(Set<Configurable> configurables, Set<Configurable> hits) {
+ Configurable candidate = null;
+ for (Configurable configurable : configurables) {
+ if (hits != null && hits.contains(configurable)) {
+ return configurable;
+ }
+ if (candidate == null && !isEmptyParent(configurable)) {
+ candidate = configurable;
+ }
+ }
+ return candidate;
+ }
+
+ private static boolean isEmptyParent(Configurable configurable) {
+ if (configurable instanceof SearchableConfigurable.Parent) {
+ SearchableConfigurable.Parent parent = (SearchableConfigurable.Parent)configurable;
+ return !parent.hasOwnContent();
+ }
+ return false;
+ }
+}
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java
index 9269da7ab967..e10367d583bf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java
@@ -16,7 +16,6 @@
package com.intellij.openapi.options.newEditor;
import com.intellij.icons.AllIcons;
-import com.intellij.ide.ui.search.ConfigurableHit;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.*;
@@ -26,55 +25,68 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.*;
-import com.intellij.ui.treeStructure.*;
+import com.intellij.ui.treeStructure.CachingSimpleNode;
+import com.intellij.ui.treeStructure.SimpleNode;
+import com.intellij.ui.treeStructure.SimpleTree;
+import com.intellij.ui.treeStructure.SimpleTreeStructure;
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.ui.ButtonlessScrollBarUI;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
+import com.intellij.util.ui.tree.WideSelectionTreeUI;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-import java.util.List;
import javax.swing.*;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.TreeUI;
-import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
+import java.awt.*;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.util.*;
+import java.util.List;
/**
* @author Sergey.Malenkov
*/
final class SettingsTreeView extends JComponent implements Disposable, OptionsEditorColleague {
+ private static final Color NORMAL_NODE = new JBColor(Gray._60, Gray._140);
+ private static final Color WRONG_CONTENT = JBColor.RED;
+ private static final Color MODIFIED_CONTENT = JBColor.BLUE;
+
final SimpleTree myTree;
final FilteringTreeBuilder myBuilder;
- private final OptionsEditorContext myContext;
+ private final SettingsFilter myFilter;
private final MyRoot myRoot;
private final JScrollPane myScroller;
private JLabel mySeparator;
private final MyRenderer myRenderer = new MyRenderer();
private final IdentityHashMap<Configurable, MyNode> myConfigurableToNodeMap = new IdentityHashMap<Configurable, MyNode>();
- private final MergingUpdateQueue myQueue = new MergingUpdateQueue("OptionsTree", 150, false, this, this, this).setRestartTimerOnAdd(true);
+ private final MergingUpdateQueue myQueue = new MergingUpdateQueue("SettingsTreeView", 150, false, this, this, this)
+ .setRestartTimerOnAdd(true);
private Configurable myQueuedConfigurable;
- SettingsTreeView(final KeyListener listener, OptionsEditorContext context, ConfigurableGroup... groups) {
- myContext = context;
+ SettingsTreeView(SettingsFilter filter, ConfigurableGroup... groups) {
+ myFilter = filter;
myRoot = new MyRoot(groups);
-
myTree = new MyTree();
+ myTree.putClientProperty(WideSelectionTreeUI.TREE_TABLE_TREE_KEY, Boolean.TRUE);
+ myTree.setBackground(UIUtil.getSidePanelColor());
myTree.getInputMap().clear();
TreeUtil.installActions(myTree);
@@ -88,8 +100,11 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
myTree.setRootVisible(false);
myTree.setShowsRootHandles(false);
- myScroller = ScrollPaneFactory.createScrollPane(myTree);
- myScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+ myScroller = ScrollPaneFactory.createScrollPane(myTree, true);
+ myScroller.getVerticalScrollBar().setUI(ButtonlessScrollBarUI.createTransparent());
+ myScroller.setBackground(UIUtil.getSidePanelColor());
+ myScroller.getViewport().setBackground(UIUtil.getSidePanelColor());
+ myScroller.getVerticalScrollBar().setBackground(UIUtil.getSidePanelColor());
add(myScroller);
myTree.addComponentListener(new ComponentAdapter() {
@@ -116,29 +131,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
}
});
- myTree.addKeyListener(new KeyListener() {
- public void keyTyped(KeyEvent event) {
- if (listener != null && isValid(event)) {
- listener.keyTyped(event);
- }
- }
-
- public void keyPressed(KeyEvent event) {
- if (listener != null && isValid(event)) {
- listener.keyPressed(event);
- }
- }
-
- public void keyReleased(KeyEvent event) {
- if (listener != null && isValid(event)) {
- listener.keyReleased(event);
- }
- }
-
- private boolean isValid(KeyEvent event) {
- return null == myTree.getInputMap().get(KeyStroke.getKeyStrokeForEvent(event));
- }
- });
myBuilder = new MyBuilder(new SimpleTreeStructure.Impl(myRoot));
myBuilder.setFilteringMerge(300, null);
Disposer.register(this, myBuilder);
@@ -158,9 +150,15 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
return ArrayUtil.toStringArray(path);
}
+ static Configurable getConfigurable(SimpleNode node) {
+ return node instanceof MyNode
+ ? ((MyNode)node).myConfigurable
+ : null;
+ }
+
@Nullable
- SimpleNode findNode(Configurable toSelect) {
- return myConfigurableToNodeMap.get(toSelect);
+ SimpleNode findNode(Configurable configurable) {
+ return myConfigurableToNodeMap.get(configurable);
}
@Nullable
@@ -250,24 +248,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
: null;
}
- static boolean isFiltered(Set<Configurable> configurables, ConfigurableHit hits, SimpleNode value) {
- if (value instanceof MyNode && !configurables.contains(((MyNode)value).myConfigurable)) {
- if (hits != null) {
- configurables = hits.getNameFullHits();
- while (value != null) {
- if (value instanceof MyNode) {
- if (configurables.contains(((MyNode)value).myConfigurable)) {
- return true;
- }
- }
- value = value.getParent();
- }
- }
- return false;
- }
- return true;
- }
-
@Override
public void doLayout() {
myScroller.setBounds(0, 0, getWidth(), getHeight());
@@ -277,34 +257,34 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
public void paint(Graphics g) {
super.paint(g);
+ if (0 == myTree.getY()) {
+ return; // separator is not needed without scrolling
+ }
if (mySeparator == null) {
mySeparator = new JLabel();
+ mySeparator.setForeground(NORMAL_NODE);
mySeparator.setFont(UIUtil.getLabelFont());
mySeparator.setFont(getFont().deriveFont(Font.BOLD));
}
- ConfigurableGroup group = findConfigurableGroupAt(0, 5 + mySeparator.getFont().getSize());
- if (group != null && group == findConfigurableGroupAt(0, -5)) {
- int offset = UIUtil.isUnderNativeMacLookAndFeel() ? 1 : 3;
- mySeparator.setBorder(BorderFactory.createEmptyBorder(offset, 18, offset, 3));
+ int height = mySeparator.getPreferredSize().height;
+ ConfigurableGroup group = findConfigurableGroupAt(0, height);
+ if (group != null && group == findConfigurableGroupAt(0, -myRenderer.getSeparatorHeight())) {
+ mySeparator.setBorder(BorderFactory.createEmptyBorder(0, 18, 0, 0));
mySeparator.setText(group.getDisplayName());
Rectangle bounds = myScroller.getViewport().getBounds();
- int height = mySeparator.getPreferredSize().height;
if (bounds.height > height) {
bounds.height = height;
}
g.setColor(myTree.getBackground());
+ g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
if (g instanceof Graphics2D) {
- int h = bounds.height / 4;
- int y = bounds.y + bounds.height - h;
- g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height - h);
+ int h = 4; // gradient height
+ int y = bounds.y + bounds.height;
((Graphics2D)g).setPaint(UIUtil.getGradientPaint(
0, y, g.getColor(),
0, y + h, ColorUtil.toAlpha(g.getColor(), 0)));
- g.fillRect(bounds.x, y, bounds.width, h + h);
- }
- else {
- g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
+ g.fillRect(bounds.x, y, bounds.width, h);
}
mySeparator.setSize(bounds.width - 1, bounds.height);
mySeparator.paint(g.create(bounds.x + 1, bounds.y, bounds.width - 1, bounds.height));
@@ -373,7 +353,7 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
}
private void fireSelected(Configurable configurable, ActionCallback callback) {
- myContext.fireSelected(configurable, this).doWhenProcessed(callback.createSetDoneRunnable());
+ myFilter.myContext.fireSelected(configurable, this).doWhenProcessed(callback.createSetDoneRunnable());
}
@Override
@@ -435,20 +415,21 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
myConfigurable = configurable;
String name = configurable.getDisplayName();
myDisplayName = name != null ? name.replace("\n", " ") : "{ " + configurable.getClass().getSimpleName() + " }";
-
- myConfigurableToNodeMap.put(configurable, this);
}
private MyNode(CachingSimpleNode parent, ConfigurableGroup group) {
super(parent);
myComposite = group;
- myConfigurable = null;
+ myConfigurable = group instanceof Configurable ? (Configurable)group : null;
String name = group.getDisplayName();
myDisplayName = name != null ? name.replace("\n", " ") : "{ " + group.getClass().getSimpleName() + " }";
}
@Override
protected SimpleNode[] buildChildren() {
+ if (myConfigurable != null) {
+ myConfigurableToNodeMap.put(myConfigurable, this);
+ }
if (myComposite == null) {
return NO_CHILDREN;
}
@@ -460,7 +441,7 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
for (int i = 0; i < configurables.length; i++) {
result[i] = new MyNode(this, configurables[i]);
if (myConfigurable != null) {
- myContext.registerKid(myConfigurable, configurables[i]);
+ myFilter.myContext.registerKid(myConfigurable, configurables[i]);
}
}
return result;
@@ -470,11 +451,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
public boolean isAlwaysLeaf() {
return myComposite == null;
}
-
- @Override
- public int getWeight() {
- return WeightBasedComparator.UNDEFINED_WEIGHT;
- }
}
private final class MyRenderer extends GroupedElementsRenderer.Tree {
@@ -490,8 +466,9 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
protected void layout() {
myNodeIcon = new JLabel(" ", SwingConstants.RIGHT);
myProjectIcon = new JLabel(" ", SwingConstants.LEFT);
- myProjectIcon.setOpaque(true);
- myRendererComponent.add(BorderLayout.NORTH, mySeparatorComponent);
+ myNodeIcon.setOpaque(false);
+ myTextLabel.setOpaque(false);
+ myProjectIcon.setOpaque(false);
myRendererComponent.add(BorderLayout.CENTER, myComponent);
myRendererComponent.add(BorderLayout.WEST, myNodeIcon);
myRendererComponent.add(BorderLayout.EAST, myProjectIcon);
@@ -504,22 +481,17 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
boolean leaf,
int row,
boolean focused) {
- myTextLabel.setOpaque(selected);
myTextLabel.setFont(UIUtil.getLabelFont());
-
- String text;
- boolean hasSeparatorAbove = false;
- int preferredForcedWidth = -1;
+ myRendererComponent.setBackground(selected ? UIUtil.getTreeSelectionBackground() : myTree.getBackground());
MyNode node = extractNode(value);
if (node == null) {
- text = value.toString();
+ myTextLabel.setText(value.toString());
}
else {
- text = node.myDisplayName;
+ myTextLabel.setText(node.myDisplayName);
// show groups in bold
if (myRoot == node.getParent()) {
- hasSeparatorAbove = node != myRoot.getChildAt(0);
myTextLabel.setFont(myTextLabel.getFont().deriveFont(Font.BOLD));
}
TreePath path = tree.getPathForRow(row);
@@ -543,18 +515,18 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
forcedWidth = visibleRect.width > 0 ? visibleRect.width - indent : forcedWidth;
}
- preferredForcedWidth = forcedWidth - 4;
+ myRendererComponent.setPrefereedWidth(forcedWidth - 4);
}
- Component result = configureComponent(text, null, null, null, selected, hasSeparatorAbove, null, preferredForcedWidth);
// update font color for modified configurables
+ myTextLabel.setForeground(selected ? UIUtil.getTreeSelectionForeground() : NORMAL_NODE);
if (!selected && node != null) {
Configurable configurable = node.myConfigurable;
if (configurable != null) {
- if (myContext.getErrors().containsKey(configurable)) {
- myTextLabel.setForeground(JBColor.RED);
+ if (myFilter.myContext.getErrors().containsKey(configurable)) {
+ myTextLabel.setForeground(WRONG_CONTENT);
}
- else if (myContext.getModified().contains(configurable)) {
- myTextLabel.setForeground(JBColor.BLUE);
+ else if (myFilter.myContext.getModified().contains(configurable)) {
+ myTextLabel.setForeground(MODIFIED_CONTENT);
}
}
}
@@ -586,7 +558,6 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
myProjectIcon.setToolTipText(OptionsBundle.message(project.isDefault()
? "configurable.default.project.tooltip"
: "configurable.current.project.tooltip"));
- myProjectIcon.setBackground(myTextLabel.getBackground());
myProjectIcon.setVisible(true);
}
else {
@@ -601,9 +572,12 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
else {
myNodeIcon.setIcon(null);
}
- return result;
+ return myRendererComponent;
}
+ int getSeparatorHeight() {
+ return mySeparatorComponent.getParent() == null ? 0 : mySeparatorComponent.getPreferredSize().height;
+ }
public boolean isUnderHandle(Point point) {
Point handlePoint = SwingUtilities.convertPoint(myRendererComponent, point, myNodeIcon);
@@ -720,7 +694,7 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
super.processMouseEvent(e);
}
- private final class MyTreeUi extends BasicTreeUI {
+ private final class MyTreeUi extends WideSelectionTreeUI {
@Override
public void toggleExpandState(TreePath path) {
@@ -773,7 +747,7 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
boolean myWasHoldingFilter;
public MyBuilder(SimpleTreeStructure structure) {
- super(myTree, myContext.getFilter(), structure, new WeightBasedComparator(false));
+ super(myTree, myFilter, structure, null);
myTree.addTreeExpansionListener(new TreeExpansionListener() {
public void treeExpanded(TreeExpansionEvent event) {
invalidateExpansions();
@@ -798,7 +772,7 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
@Override
public boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) {
- return myContext.isHoldingFilter();
+ return myFilter.myContext.isHoldingFilter();
}
@Override
@@ -809,22 +783,22 @@ final class SettingsTreeView extends JComponent implements Disposable, OptionsEd
@Override
protected ActionCallback refilterNow(Object preferredSelection, boolean adjustSelection) {
final List<Object> toRestore = new ArrayList<Object>();
- if (myContext.isHoldingFilter() && !myWasHoldingFilter && myToExpandOnResetFilter == null) {
+ if (myFilter.myContext.isHoldingFilter() && !myWasHoldingFilter && myToExpandOnResetFilter == null) {
myToExpandOnResetFilter = myBuilder.getUi().getExpandedElements();
}
- else if (!myContext.isHoldingFilter() && myWasHoldingFilter && myToExpandOnResetFilter != null) {
+ else if (!myFilter.myContext.isHoldingFilter() && myWasHoldingFilter && myToExpandOnResetFilter != null) {
toRestore.addAll(myToExpandOnResetFilter);
myToExpandOnResetFilter = null;
}
- myWasHoldingFilter = myContext.isHoldingFilter();
+ myWasHoldingFilter = myFilter.myContext.isHoldingFilter();
ActionCallback result = super.refilterNow(preferredSelection, adjustSelection);
myRefilteringNow = true;
return result.doWhenDone(new Runnable() {
public void run() {
myRefilteringNow = false;
- if (!myContext.isHoldingFilter() && getSelectedElements().isEmpty()) {
+ if (!myFilter.myContext.isHoldingFilter() && getSelectedElements().isEmpty()) {
restoreExpandedState(toRestore);
}
}
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 6a37bb2fb69e..3d478f2b7084 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
@@ -47,6 +47,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class ProgressManagerImpl extends ProgressManager implements Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.impl.ProgressManagerImpl");
+ public static final int CHECK_CANCELED_DELAY_MILLIS = 10;
private final AtomicInteger myCurrentUnsafeProgressCount = new AtomicInteger(0);
private final AtomicInteger myCurrentModalProgressCount = new AtomicInteger(0);
@@ -64,7 +65,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable {
public void run() {
ourNeedToCheckCancel = true;
}
- }, 0, 10, TimeUnit.MILLISECONDS);
+ }, 0, CHECK_CANCELED_DELAY_MILLIS, TimeUnit.MILLISECONDS);
}
}
@@ -83,7 +84,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable {
ourLockedCheckCounter++;
if (ourLockedCheckCounter > 10) {
ourLockedCheckCounter = 0;
- ourNeedToCheckCancel = true;
+ canceled();
}
}
else {
@@ -94,10 +95,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable {
}
}
- public static void canceled() {
- ourNeedToCheckCancel = true;
- }
-
private static class NonCancelableIndicator extends EmptyProgressIndicator implements NonCancelableSection {
private final ProgressIndicator myOld;
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java
index 2d9a7b3a88e6..b4821f52fddb 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorBase.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.
@@ -19,7 +19,6 @@ import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.TaskInfo;
-import com.intellij.openapi.progress.impl.ProgressManagerImpl;
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.WeakList;
@@ -151,9 +150,6 @@ public class ProgressIndicatorBase extends AbstractProgressIndicatorBase impleme
@Override
public void cancel() {
super.cancel();
-
- ProgressManagerImpl.canceled();
-
delegateRunningChange(CANCEL_ACTION);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java
index 0c18cb7706d9..368200492cae 100644
--- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java
+++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java
@@ -22,7 +22,11 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.ui.AppUIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.ide.PooledThreadExecutor;
+
+import java.util.concurrent.Executor;
/**
* @author gregsh
@@ -44,96 +48,76 @@ public class ProgressIndicatorUtils {
return progress;
}
- public static void runWithWriteActionPriority(@NotNull final Runnable action) {
- runWithWriteActionPriority(new ReadTask() {
- @Override
- public void computeInReadAction(@NotNull ProgressIndicator indicator) {
- action.run();
- }
-
- @Override
- public void onCanceled(@NotNull ProgressIndicator indicator) {
- }
- });
- }
-
- public static void runWithWriteActionPriority(@NotNull final ReadTask task) {
- runWithWriteActionPriority(new ProgressIndicatorBase(), task);
+ public static void scheduleWithWriteActionPriority(@NotNull ReadTask task) {
+ scheduleWithWriteActionPriority(new ProgressIndicatorBase(), task);
}
- private static void surroundWithListener(@NotNull final ProgressIndicator progressIndicator, @NotNull Runnable runnable) {
- final ApplicationAdapter listener = new ApplicationAdapter() {
- @Override
- public void beforeWriteActionStart(Object action) {
- progressIndicator.cancel();
- }
- };
- final Application application = ApplicationManager.getApplication();
- application.addApplicationListener(listener);
- try {
- runnable.run();
- }
- finally {
- application.removeApplicationListener(listener);
- }
+ public static void scheduleWithWriteActionPriority(@NotNull ProgressIndicator progressIndicator, @NotNull ReadTask readTask) {
+ scheduleWithWriteActionPriority(progressIndicator, PooledThreadExecutor.INSTANCE, readTask);
}
-
- public static void runWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator, @NotNull final ReadTask task) {
- surroundWithListener(progressIndicator, new Runnable() {
+ public static void scheduleWithWriteActionPriority(@NotNull final ProgressIndicator progressIndicator,
+ @NotNull final Executor executor,
+ @NotNull final ReadTask readTask) {
+ AppUIUtil.invokeOnEdt(new Runnable() {
@Override
public void run() {
- runUnderProgress(progressIndicator, task);
+ final Application application = ApplicationManager.getApplication();
+ application.assertIsDispatchThread();
+ final ApplicationAdapter listener = new ApplicationAdapter() {
+ @Override
+ public void beforeWriteActionStart(Object action) {
+ progressIndicator.cancel();
+ }
+ };
+ application.addApplicationListener(listener);
+ try {
+ executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ runUnderProgress(progressIndicator, readTask);
+ }
+ finally {
+ application.removeApplicationListener(listener);
+ }
+ }
+ });
+ }
+ catch (RuntimeException e) {
+ application.removeApplicationListener(listener);
+ throw e;
+ }
+ catch (Error e) {
+ application.removeApplicationListener(listener);
+ throw e;
+ }
}
});
}
private static void runUnderProgress(@NotNull final ProgressIndicator progressIndicator, @NotNull final ReadTask task) {
ProgressManager.getInstance().runProcess(new Runnable() {
- @Override
- public void run() {
- // This read action can possible last for a long time, we want it to stop immediately on the first write access.
- // For this purpose we launch it under empty progress and invoke progressIndicator#cancel on write access to avoid possible write lock delays.
- try {
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- @Override
- public void run() {
- task.computeInReadAction(progressIndicator);
- }
- });
- }
- catch (ProcessCanceledException ignore) {
- }
- finally {
- if (progressIndicator.isCanceled()) {
- task.onCanceled(progressIndicator);
- }
- }
- }
- }, progressIndicator);
- }
-
- public static void scheduleWithWriteActionPriority(@NotNull final ReadTask task) {
- scheduleWithWriteActionPriority(new ProgressIndicatorBase(), task);
- }
-
- public static void scheduleWithWriteActionPriority(@NotNull final ProgressIndicator indicator, @NotNull final ReadTask task) {
- // we have to attach listeners in EDT to avoid "fire write action started while attach listeners from another thread" race condition
- ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
- surroundWithListener(indicator, new Runnable() {
- @Override
- public void run() {
- ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
- @Override
- public void run() {
- runUnderProgress(indicator, task);
- }
- });
+ // This read action can possible last for a long time, we want it to stop immediately on the first write access.
+ // For this purpose we launch it under empty progress and invoke progressIndicator#cancel on write access to avoid possible write lock delays.
+ try {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ @Override
+ public void run() {
+ task.computeInReadAction(progressIndicator);
+ }
+ });
+ }
+ catch (ProcessCanceledException ignore) {
+ }
+ finally {
+ if (progressIndicator.isCanceled()) {
+ task.onCanceled(progressIndicator);
}
- });
+ }
}
- });
+ }, progressIndicator);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java
index 77baf2a6b98c..1f3b9d149ccc 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectMacrosUtil.java
@@ -25,17 +25,13 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.PathMacros;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.options.ex.SingleConfigurableEditor;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.WaitForProgressToShow;
import org.jetbrains.annotations.NonNls;
-import javax.swing.*;
-import java.lang.reflect.InvocationTargetException;
import java.util.*;
public class ProjectMacrosUtil {
@@ -50,11 +46,7 @@ public class ProjectMacrosUtil {
if (application.isHeadlessEnvironment() || application.isUnitTestMode()) {
throw new RuntimeException(text + ": " + StringUtil.join(undefinedMacros, ", "));
}
- final UndefinedMacrosConfigurable configurable =
- new UndefinedMacrosConfigurable(text, undefinedMacros);
- final SingleConfigurableEditor editor = new SingleConfigurableEditor(project, configurable);
- editor.show();
- return editor.isOK();
+ return ShowSettingsUtil.getInstance().editConfigurable(project, new UndefinedMacrosConfigurable(text, undefinedMacros));
}
public static boolean checkNonIgnoredMacros(final Project project, final Set<String> usedMacros){
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
index 2f95c21cb558..e7b20959369e 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java
@@ -21,6 +21,7 @@ import com.intellij.conversion.ConversionService;
import com.intellij.ide.AppLifecycleListener;
import com.intellij.ide.RecentProjectsManagerBase;
import com.intellij.ide.impl.ProjectUtil;
+import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.notification.NotificationsManager;
import com.intellij.openapi.Disposable;
@@ -354,7 +355,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
myDefaultProjectRootElement = null;
}
catch (Throwable t) {
- LOG.error(t);
+ PluginManager.processException(t);
}
}
});
@@ -362,6 +363,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
return myDefaultProject;
}
+ @Nullable
public Element getDefaultProjectRootElement() {
return myDefaultProjectRootElement;
}
@@ -1126,33 +1128,27 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
}
@Override
- public void writeExternal(Element parentNode) throws WriteExternalException {
+ public void writeExternal(Element parentNode) {
if (myDefaultProject != null) {
myDefaultProject.save();
}
- if (myDefaultProjectRootElement == null) { //read external isn't called if config folder is absent
- myDefaultProjectRootElement = new Element(ELEMENT_DEFAULT_PROJECT);
+ if (myDefaultProjectRootElement != null) {
+ myDefaultProjectRootElement.detach();
+ parentNode.addContent(myDefaultProjectRootElement);
}
-
- myDefaultProjectRootElement.detach();
- parentNode.addContent(myDefaultProjectRootElement);
}
-
public void setDefaultProjectRootElement(final Element defaultProjectRootElement) {
myDefaultProjectRootElement = defaultProjectRootElement;
}
@Override
- public void readExternal(Element parentNode) throws InvalidDataException {
+ public void readExternal(Element parentNode) {
myDefaultProjectRootElement = parentNode.getChild(ELEMENT_DEFAULT_PROJECT);
-
- if (myDefaultProjectRootElement == null) {
- myDefaultProjectRootElement = new Element(ELEMENT_DEFAULT_PROJECT);
+ if (myDefaultProjectRootElement != null) {
+ myDefaultProjectRootElement.detach();
}
-
- myDefaultProjectRootElement.detach();
}
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java
index 394dec20f4ef..1160c64bbeb8 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java
@@ -15,7 +15,8 @@
*/
package com.intellij.openapi.updateSettings.impl.pluginsAdvertisement;
-import com.intellij.ide.plugins.*;
+import com.intellij.ide.plugins.IdeaPluginDescriptor;
+import com.intellij.ide.plugins.RepositoryHelper;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileTypes.FileTypeFactory;
@@ -24,7 +25,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.updateSettings.impl.*;
+import com.intellij.openapi.updateSettings.impl.PluginDownloader;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
@@ -94,7 +95,8 @@ public class PluginAdvertiserEditorNotificationProvider extends EditorNotificati
@Nullable
private EditorNotificationPanel createPanel(final String extension, final Set<PluginsAdvertiser.Plugin> plugins) {
final EditorNotificationPanel panel = new EditorNotificationPanel();
- panel.setText("Plugins supporting files with " + extension + " are found");
+
+ panel.setText("Plugins supporting " + extension + " files are found");
final IdeaPluginDescriptor disabledPlugin = PluginsAdvertiser.getDisabledPlugin(plugins);
if (disabledPlugin != null) {
panel.createActionLabel("Enable " + disabledPlugin.getName() + " plugin", new Runnable() {
@@ -143,6 +145,7 @@ public class PluginAdvertiserEditorNotificationProvider extends EditorNotificati
if (PropertiesComponent.getInstance().isTrueValue(PluginsAdvertiser.IGNORE_ULTIMATE_EDITION)) {
return null;
}
+ panel.setText(extension + " files are supported by " + PluginsAdvertiser.IDEA_ULTIMATE_EDITION);
panel.createActionLabel(PluginsAdvertiser.CHECK_ULTIMATE_EDITION_TITLE, new Runnable() {
@Override
diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
index ed6a629bff0d..4ae3caee88e1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
+++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java
@@ -63,8 +63,9 @@ public class PluginsAdvertiser implements StartupActivity {
private static final String FEATURE_IMPLEMENTATIONS_URL = "http://plugins.jetbrains.com/feature/getImplementations?";
private static final String CASHED_EXTENSIONS = "extensions.xml";
+ public static final String IDEA_ULTIMATE_EDITION = "IntelliJ IDEA Ultimate Edition";
public static final String ULTIMATE_EDITION_SUGGESTION = "Do not suggest Ultimate Edition";
- public static final String CHECK_ULTIMATE_EDITION_TITLE = "Check IntelliJ IDEA Ultimate Edition";
+ public static final String CHECK_ULTIMATE_EDITION_TITLE = "Check " + IDEA_ULTIMATE_EDITION;
public static final String DISPLAY_ID = "Plugins Suggestion";
public static final NotificationGroup NOTIFICATION_GROUP = new NotificationGroup(DISPLAY_ID, NotificationDisplayType.STICKY_BALLOON, true);
@@ -198,7 +199,7 @@ public class PluginsAdvertiser implements StartupActivity {
}
public static void openDownloadPage() {
- BrowserUtil.open(ApplicationInfo.getInstance().getCompanyURL());
+ BrowserUtil.browse(ApplicationInfo.getInstance().getCompanyURL());
}
static void enablePlugins(Project project, final Collection<IdeaPluginDescriptor> disabledPlugins) {
@@ -325,7 +326,8 @@ public class PluginsAdvertiser implements StartupActivity {
message += "<a href=\"ignore\">Ignore All</a>";
}
else if (myBundledPlugin != null && !PropertiesComponent.getInstance().isTrueValue(IGNORE_ULTIMATE_EDITION)) {
- message = "Features covered by IntelliJ IDEA Ultimate Edition (" + StringUtil.join(myBundledPlugin, ", ") + ") are detected.<br>" +
+ message = "Features covered by " + IDEA_ULTIMATE_EDITION +
+ " (" + StringUtil.join(myBundledPlugin, ", ") + ") are detected.<br>" +
"<a href=\"open\">" + CHECK_ULTIMATE_EDITION_TITLE + "</a><br>" +
"<a href=\"ignoreUltimate\">" + ULTIMATE_EDITION_SUGGESTION + "</a>";
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java
index 402d88cef38a..92eed9582fd2 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java
@@ -27,18 +27,24 @@ import java.awt.event.MouseMotionListener;
public abstract class LinkMouseListenerBase<T> extends ClickListener implements MouseMotionListener {
public static void installSingleTagOn(@NotNull SimpleColoredComponent component) {
- new LinkMouseListenerBase<Consumer<MouseEvent>>() {
+ new LinkMouseListenerBase<Object>() {
@Nullable
@Override
- protected Consumer<MouseEvent> getTagAt(@NotNull MouseEvent e) {
+ protected Object getTagAt(@NotNull MouseEvent e) {
//noinspection unchecked
- return (Consumer<MouseEvent>)((SimpleColoredComponent)e.getSource()).getFragmentTagAt(e.getX());
+ return ((SimpleColoredComponent)e.getSource()).getFragmentTagAt(e.getX());
}
@Override
- protected void handleTagClick(@Nullable Consumer<MouseEvent> tag, @NotNull MouseEvent event) {
+ protected void handleTagClick(@Nullable Object tag, @NotNull MouseEvent event) {
if (tag != null) {
- tag.consume(event);
+ if (tag instanceof Consumer) {
+ //noinspection unchecked
+ ((Consumer<MouseEvent>)tag).consume(event);
+ }
+ else {
+ ((Runnable)tag).run();
+ }
}
}
}.installOn(component);
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java
index 1c6e173b45d1..33ecf625c05d 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/temp/TempFileSystem.java
@@ -136,7 +136,8 @@ public class TempFileSystem extends LocalFileSystemBase {
}
fsItem.getParent().removeChild(fsItem);
- ((FSDir)newParentItem).addChild(fsItem);
+ newDir.addChild(fsItem);
+ fsItem.myParent = newDir;
}
@Override
@@ -263,7 +264,7 @@ public class TempFileSystem extends LocalFileSystemBase {
}
private abstract static class FSItem {
- private final FSDir myParent;
+ private FSDir myParent;
private String myName;
private long myTimestamp;
private boolean myWritable;
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java
index d7b90178e7e8..db5de4258d41 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java
@@ -67,15 +67,16 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
private final Object myInputLock = new Object();
private final AtomicBoolean myShutDown = new AtomicBoolean(false);
+ @SuppressWarnings("FieldCanBeLocal")
+ private final LowMemoryWatcher myWatcher = LowMemoryWatcher.register(new Runnable() {
+ @Override
+ public void run() {
+ clearIdCache();
+ }
+ });
public PersistentFSImpl(@NotNull MessageBus bus) {
myEventBus = bus;
- LowMemoryWatcher.register(new Runnable() {
- @Override
- public void run() {
- clearIdCache();
- }
- });
ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
@Override
public void run() {
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.form b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.form
index 2e1bb768a614..4e362a30a1ed 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.form
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.form
@@ -22,7 +22,7 @@
</constraints>
<properties>
<autoscrolls value="true"/>
- <text value="Text"/>
+ <text value=""/>
</properties>
</component>
<component id="94f42" class="javax.swing.JProgressBar" binding="myProgressBar" default-binding="true">
@@ -54,7 +54,7 @@
</grid>
</constraints>
<properties>
- <text value="Text 2"/>
+ <text value=""/>
</properties>
</component>
<vspacer id="8e674">
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java
index d7bc7024f0ed..9f82a2f60cdf 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java
@@ -22,6 +22,7 @@ import com.intellij.ui.InplaceButton;
import com.intellij.ui.TransparentPanel;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
@@ -69,7 +70,7 @@ public class PresentationModeProgressPanel {
}
if (!myProgressBar.isIndeterminate()) {
- myProgressBar.setValue(((int)(myProgress.getFraction() * 99)) + 1);
+ myProgressBar.setValue((int)(myProgress.getFraction() * 99) + 1);
}
}
@@ -83,7 +84,7 @@ public class PresentationModeProgressPanel {
AllIcons.Process.Stop,
AllIcons.Process.StopHovered);
myCancelButton = new InplaceButton(iconButton, new ActionListener() {
- public void actionPerformed(final ActionEvent e) {
+ public void actionPerformed(@NotNull final ActionEvent e) {
myProgress.cancel();
}
}).setFillBg(false);
diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
index 1fc23e5f4055..d9ebeefa7acc 100644
--- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
+++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java
@@ -368,6 +368,7 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
if (!(renderer instanceof JComponent)) return null;
myKeyItemBounds = rendererAndBounds.second;
+ myKeyItemBounds.width = Math.min(myKeyItemBounds.width, myComponent.getToolkit().getScreenSize().width);
Rectangle cellBounds = myKeyItemBounds;
Rectangle visibleRect = getVisibleRect(key);
diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
index 2a7d44d017bd..f4bf768e92a6 100644
--- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
+++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java
@@ -90,19 +90,19 @@ public class AppUIUtil {
invokeOnEdt(runnable, null);
}
- public static void invokeOnEdt(Runnable runnable, @Nullable Condition condition) {
+ public static void invokeOnEdt(Runnable runnable, @Nullable Condition expired) {
Application application = ApplicationManager.getApplication();
if (application.isDispatchThread()) {
//noinspection unchecked
- if (condition == null || !condition.value(null)) {
+ if (expired == null || !expired.value(null)) {
runnable.run();
}
}
- else if (condition == null) {
+ else if (expired == null) {
application.invokeLater(runnable);
}
else {
- application.invokeLater(runnable, condition);
+ application.invokeLater(runnable, expired);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java b/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java
index f4dfb1059651..60371365f2c3 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java
+++ b/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java
@@ -17,6 +17,7 @@ package com.intellij.ui;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NonNls;
@@ -34,10 +35,19 @@ public class EditorComboBoxEditor implements ComboBoxEditor{
@NonNls protected static final String NAME = "ComboBox.textField";
public EditorComboBoxEditor(Project project, FileType fileType) {
- myTextField = new ComboboxEditorTextField((Document)null, project, fileType);
+ myTextField = new ComboboxEditorTextField((Document)null, project, fileType) {
+ @Override
+ protected EditorEx createEditor() {
+ EditorEx editor = super.createEditor();
+ onEditorCreate(editor);
+ return editor;
+ }
+ };
myTextField.setName(NAME);
}
+ protected void onEditorCreate(EditorEx editor) {}
+
@Override
public void selectAll() {
myTextField.selectAll();
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java
index 5721f4af4821..4b788c80ae54 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java
+++ b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java
@@ -102,13 +102,7 @@ public class EditorNotificationsImpl extends EditorNotifications {
task.computeInReadAction(indicator);
}
else {
- final ProgressIndicator indicator1 = indicator;
- myExecutor.execute(new Runnable() {
- @Override
- public void run() {
- ProgressIndicatorUtils.runWithWriteActionPriority(indicator1, task);
- }
- });
+ ProgressIndicatorUtils.scheduleWithWriteActionPriority(indicator, myExecutor, task);
}
}
});
@@ -165,7 +159,7 @@ public class EditorNotificationsImpl extends EditorNotifications {
}
@Override
- public void onCanceled(@NotNull ProgressIndicator _) {
+ public void onCanceled(@NotNull ProgressIndicator ignored) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java
index c16f5f188cdc..27b1a2be56ae 100644
--- a/platform/platform-impl/src/com/intellij/ui/EditorTextField.java
+++ b/platform/platform-impl/src/com/intellij/ui/EditorTextField.java
@@ -278,13 +278,18 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
public void selectAll() {
if (myEditor != null) {
- myEditor.getSelectionModel().setSelection(0, myDocument.getTextLength());
+ doSelectAll(myEditor);
}
else {
myWholeTextSelected = true;
}
}
+ private static void doSelectAll(@NotNull Editor editor) {
+ editor.getCaretModel().removeSecondaryCarets();
+ editor.getCaretModel().getPrimaryCaret().setSelection(0, editor.getDocument().getTextLength(), false);
+ }
+
public void removeSelection() {
if (myEditor != null) {
myEditor.getSelectionModel().removeSelection();
@@ -514,7 +519,8 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
editor.getSelectionModel().removeSelection();
}
else if (myWholeTextSelected) {
- editor.getSelectionModel().setSelection(0, myDocument.getTextLength());
+ doSelectAll(editor);
+ myWholeTextSelected = false;
}
editor.putUserData(SUPPLEMENTARY_KEY, myIsSupplementary);
diff --git a/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java b/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java
index 9ad0931c85b9..5c531a7b6ae8 100644
--- a/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java
+++ b/platform/platform-impl/src/com/intellij/ui/FocusTrackback.java
@@ -191,10 +191,12 @@ public class FocusTrackback {
if (app == null || wrongOS() || myConsumed || isSheduledForRestore()) return;
Project project = null;
- DataContext context =
- myParentWindow == null ? DataManager.getInstance().getDataContext() : DataManager.getInstance().getDataContext(myParentWindow);
- if (context != null) {
- project = CommonDataKeys.PROJECT.getData(context);
+ DataManager dataManager = DataManager.getInstance();
+ if (dataManager != null) {
+ DataContext context = myParentWindow == null ? dataManager.getDataContext() : dataManager.getDataContext(myParentWindow);
+ if (context != null) {
+ project = CommonDataKeys.PROJECT.getData(context);
+ }
}
mySheduledForRestore = true;
diff --git a/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java b/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java
index e8c6f49f8088..7e613982a406 100644
--- a/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java
+++ b/platform/platform-impl/src/com/intellij/ui/LibNotifyWrapper.java
@@ -50,6 +50,8 @@ class LibNotifyWrapper implements SystemNotificationsImpl.Notifier {
private final LibNotify myLibNotify;
private final String myIcon;
+ private final Object myLock = new Object();
+ private boolean myDisposed = false;
private LibNotifyWrapper() {
myLibNotify = (LibNotify)Native.loadLibrary("libnotify.so.4", LibNotify.class);
@@ -66,14 +68,21 @@ class LibNotifyWrapper implements SystemNotificationsImpl.Notifier {
connection.subscribe(AppLifecycleListener.TOPIC, new AppLifecycleListener.Adapter() {
@Override
public void appClosing() {
- myLibNotify.notify_uninit();
+ synchronized (myLock) {
+ myDisposed = true;
+ myLibNotify.notify_uninit();
+ }
}
});
}
@Override
public void notify(@NotNull Set<String> allNames, @NotNull String name, @NotNull String title, @NotNull String description) {
- Pointer notification = myLibNotify.notify_notification_new(title, description, myIcon);
- myLibNotify.notify_notification_show(notification, null);
+ synchronized (myLock) {
+ if (!myDisposed) {
+ Pointer notification = myLibNotify.notify_notification_new(title, description, myIcon);
+ myLibNotify.notify_notification_show(notification, null);
+ }
+ }
}
}
diff --git a/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java b/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java
index cbcde2d36418..76985ad77362 100644
--- a/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java
+++ b/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java
@@ -298,6 +298,7 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
protected void processKeyEvent(KeyEvent e) {
if (e.isAltDown()) return;
+ if (e.isShiftDown() && isNavigationKey(e.getKeyCode())) return;
if (mySearchPopup != null) {
mySearchPopup.processKeyEvent(e);
return;
@@ -499,6 +500,15 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
return keyCode == KeyEvent.VK_HOME || keyCode == KeyEvent.VK_END || keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_DOWN;
}
+ private static boolean isPgUpPgDown(int keyCode) {
+ return keyCode == KeyEvent.VK_PAGE_UP || keyCode == KeyEvent.VK_PAGE_DOWN;
+ }
+
+ private static boolean isNavigationKey(int keyCode) {
+ return isPgUpPgDown(keyCode) || isUpDownHomeEnd(keyCode);
+ }
+
+
private void manageSearchPopup(@Nullable SearchPopup searchPopup) {
Project project = null;
if (ApplicationManager.getApplication() != null && !ApplicationManager.getApplication().isDisposed()) {
diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
index 2d76d6391ee8..bf0b37116941 100755
--- a/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
+++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetController.java
@@ -70,6 +70,8 @@ public class SheetController {
private static int GAP_BETWEEN_BUTTONS = 5;
+ private static String SPACE_OR_LINE_SEPARATOR_PATTERN = "[\\s" + System.getProperty("line.separator") + "]+";
+
// SHEET
public int SHEET_WIDTH = 400;
@@ -289,7 +291,7 @@ public class SheetController {
int widestWordWidth = 250;
- String [] words = (message == null) ? ArrayUtil.EMPTY_STRING_ARRAY : message.split(" ");
+ String [] words = (message == null) ? ArrayUtil.EMPTY_STRING_ARRAY : message.split(SPACE_OR_LINE_SEPARATOR_PATTERN);
for (String word : words) {
widestWordWidth = Math.max(fontMetrics.stringWidth(word), widestWordWidth);
diff --git a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
index 446722c081e4..fee84330f0a2 100755
--- a/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
+++ b/platform/platform-impl/src/com/intellij/ui/messages/SheetMessage.java
@@ -70,6 +70,8 @@ public class SheetMessage {
final Component recentFocusOwner = activeWindow == null ? null : activeWindow.getMostRecentFocusOwner();
beforeShowFocusOwner = new WeakReference<Component>(recentFocusOwner);
+ maximizeIfNeeded(owner);
+
myWindow = new JDialog(owner, "This should not be shown", Dialog.ModalityType.APPLICATION_MODAL);
myWindow.getRootPane().putClientProperty("apple.awt.draggableWindowBackground", Boolean.FALSE);
@@ -132,6 +134,16 @@ public class SheetMessage {
}
+ private static void maximizeIfNeeded(final Window owner) {
+ if (owner == null) return;
+ if (owner instanceof Frame) {
+ Frame f = (Frame)owner;
+ if (f.getState() == Frame.ICONIFIED) {
+ f.setState(Frame.NORMAL);
+ }
+ }
+ }
+
private void setWindowOpacity(float opacity) {
try {
Method setOpacityMethod = myWindow.getClass().getMethod("setOpacity", Float.TYPE);
diff --git a/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java
index 04c38a6cc295..1b9190f6a740 100644
--- a/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java
+++ b/platform/platform-impl/src/com/intellij/ui/popup/WizardPopup.java
@@ -177,15 +177,19 @@ public abstract class WizardPopup extends AbstractPopup implements ActionListene
LOG.assertTrue (!isDisposed());
Rectangle targetBounds = new Rectangle(new Point(aScreenX, aScreenY), getContent().getPreferredSize());
- ScreenUtil.moveRectangleToFitTheScreen(targetBounds);
if (getParent() != null) {
final Rectangle parentBounds = getParent().getBounds();
parentBounds.x += STEP_X_PADDING;
parentBounds.width -= STEP_X_PADDING * 2;
+ ScreenUtil.moveToFit(targetBounds, ScreenUtil.getScreenRectangle(
+ parentBounds.x + parentBounds.width / 2,
+ parentBounds.y + parentBounds.height / 2), null);
if (parentBounds.intersects(targetBounds)) {
targetBounds.x = getParent().getBounds().x - targetBounds.width - STEP_X_PADDING;
}
+ } else {
+ ScreenUtil.moveToFit(targetBounds, ScreenUtil.getScreenRectangle(aScreenX, aScreenY), null);
}
if (getParent() == null) {
diff --git a/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java b/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java
index 5b22e706508a..a2f21c3d0018 100644
--- a/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java
+++ b/platform/platform-impl/src/net/sf/cglib/proxy/AdvancedEnhancer.java
@@ -15,7 +15,7 @@
*/
package net.sf.cglib.proxy;
-import com.intellij.ide.plugins.PluginManager;
+import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.ide.plugins.cl.PluginClassLoader;
import com.intellij.util.ReflectionUtil;
import net.sf.cglib.core.*;
@@ -26,6 +26,7 @@ import org.objectweb.asm.Type;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.*;
/**
@@ -61,6 +62,7 @@ import java.util.*;
* <code>java.lang.reflect.Proxy</code>, see the {@link Proxy} class.
*/
+@SuppressWarnings("StaticFieldReferencedViaSubclass")
public class AdvancedEnhancer extends AbstractClassGenerator
{
private static final CallbackFilter ALL_ZERO = new CallbackFilter(){
@@ -125,7 +127,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
/** Internal interface, only public due to ClassLoader issues. */
public interface EnhancerKey {
- public Object newInstance(String type,
+ Object newInstance(String type,
String[] interfaces,
CallbackFilter filter,
Type[] callbackTypes,
@@ -250,18 +252,6 @@ public class AdvancedEnhancer extends AbstractClassGenerator
}
/**
- * Set the single type of {@link Callback} to use.
- * This may be used instead of {@link #setCallback} when calling
- * {@link #createClass}, since it may not be possible to have
- * an array of actual callback instances.
- * @param callbackType the type of callback to use for all methods
- * @see #setCallbackTypes
- */
- public void setCallbackType(Class callbackType) {
- setCallbackTypes(new Class[]{ callbackType });
- }
-
- /**
* Set the array of callback types to use.
* This may be used instead of {@link #setCallbacks} when calling
* {@link #createClass}, since it may not be possible to have
@@ -315,27 +305,6 @@ public class AdvancedEnhancer extends AbstractClassGenerator
}
}
- /**
- * Generate a new class if necessary and return it without creating a new instance.
- * This ignores any callbacks that have been set.
- * To create a new instance you will have to use reflection, and methods
- * called during the constructor will not be intercepted. To avoid this problem,
- * use the multi-arg <code>create</code> method.
- * @see #create(Class[], Object[])
- */
- public Class createClass() {
- classOnly = true;
- return (Class)createHelper();
- }
-
- /**
- * Insert a static serialVersionUID field into the generated class.
- * @param sUID the field value, or null to avoid generating field.
- */
- public void setSerialVersionUID(Long sUID) {
- serialVersionUID = sUID;
- }
-
private void validate() {
if (classOnly ^ (callbacks == null)) {
if (classOnly) {
@@ -401,7 +370,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
for (final Class anInterface : interfaces) {
final ClassLoader loader = anInterface.getClassLoader();
if (loader instanceof PluginClassLoader) {
- final int order = PluginManager.getPluginLoadingOrder(((PluginClassLoader)loader).getPluginId());
+ final int order = PluginManagerCore.getPluginLoadingOrder(((PluginClassLoader)loader).getPluginId());
if (maxIndex < order) {
maxIndex = order;
bestLoader = loader;
@@ -413,7 +382,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
if (superclass != null) {
superLoader = superclass.getClassLoader();
if (superLoader instanceof PluginClassLoader &&
- maxIndex < PluginManager.getPluginLoadingOrder(((PluginClassLoader)superLoader).getPluginId())) {
+ maxIndex < PluginManagerCore.getPluginLoadingOrder(((PluginClassLoader)superLoader).getPluginId())) {
return superLoader;
}
}
@@ -426,24 +395,6 @@ public class AdvancedEnhancer extends AbstractClassGenerator
sig.getDescriptor());
}
- /**
- * Finds all of the methods that will be extended by an
- * Enhancer-generated class using the specified superclass and
- * interfaces. This can be useful in building a list of Callback
- * objects. The methods are added to the end of the given list. Due
- * to the subclassing nature of the classes generated by Enhancer,
- * the methods are guaranteed to be non-static, non-final, and
- * non-private. Each method signature will only occur once, even if
- * it occurs in multiple classes.
- * @param superclass the class that will be extended, or null
- * @param interfaces the list of interfaces that will be implemented, or null
- * @param methods the list into which to copy the applicable methods
- */
- public static void getMethods(Class superclass, Class[] interfaces, List<Method> methods)
- {
- getMethods(superclass, interfaces, methods, null, null);
- }
-
private static void getMethods(Class superclass, Class[] interfaces, List<Method> methods, List<Method> interfaceMethods, Set forcePublic)
{
ReflectUtils.addAllMethods(superclass, methods);
@@ -520,6 +471,9 @@ public class AdvancedEnhancer extends AbstractClassGenerator
}
final Map<Method, MethodInfo> methodInfoMap = new HashMap<Method, MethodInfo>();
for (Method method : actualMethods) {
+ if (isJdk8DefaultMethod(method)) {
+ continue;
+ }
int modifiers =
Constants.ACC_FINAL | (method.getModifiers() & ~Constants.ACC_ABSTRACT & ~Constants.ACC_NATIVE & ~Constants.ACC_SYNCHRONIZED);
if (forcePublic.contains(MethodWrapper.create(method))) {
@@ -551,6 +505,11 @@ public class AdvancedEnhancer extends AbstractClassGenerator
e.end_class();
}
+ private static boolean isJdk8DefaultMethod(Method method) {
+ return ((method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
+ Modifier.PUBLIC) && method.getDeclaringClass().isInterface();
+ }
+
private static void removeAllCovariantMethods(final List<Method> actualMethods, final Method method, final Map<Method, Method> covariantMethods) {
if ((method.getModifiers() & Constants.ACC_SYNTHETIC) != 0) {
return;
@@ -618,57 +577,6 @@ public class AdvancedEnhancer extends AbstractClassGenerator
}
}
- /**
- * Call this method to register the {@link Callback} array to use before
- * creating a new instance of the generated class via reflection. If you are using
- * an instance of <code>Enhancer</code> or the {@link Factory} interface to create
- * new instances, this method is unnecessary. Its primary use is for when you want to
- * cache and reuse a generated class yourself, and the generated class does
- * <i>not</i> implement the {@link Factory} interface.
- * <p>
- * Note that this method only registers the callbacks on the current thread.
- * If you want to register callbacks for instances created by multiple threads,
- * use {@link #registerStaticCallbacks}.
- * <p>
- * The registered callbacks are overwritten and subsequently cleared
- * when calling any of the <code>create</code> methods (such as
- * {@link #create}).
- * @param generatedClass a class previously created by {@link Enhancer}
- * @param callbacks the array of callbacks to use when instances of the generated
- * class are created
- * @see #setUseFactory
- */
- public static void registerCallbacks(Class generatedClass, Callback[] callbacks) {
- setThreadCallbacks(generatedClass, callbacks);
- }
-
- /**
- * Similar to {@link #registerCallbacks}, but suitable for use
- * when multiple threads will be creating instances of the generated class.
- * The thread-level callbacks will always override the static callbacks.
- * Static callbacks are never cleared.
- * @param generatedClass a class previously created by {@link Enhancer}
- * @param callbacks the array of callbacks to use when instances of the generated
- * class are created
- */
- public static void registerStaticCallbacks(Class generatedClass, Callback[] callbacks) {
- setCallbacksHelper(generatedClass, callbacks, SET_STATIC_CALLBACKS_NAME);
- }
-
- /**
- * Determine if a class was generated using <code>Enhancer</code>.
- * @param type any class
- * @return whether the class was generated using <code>Enhancer</code>
- */
- public static boolean isEnhanced(Class type) {
- try {
- getCallbacksSetter(type, SET_THREAD_CALLBACKS_NAME);
- return true;
- } catch (NoSuchMethodException e) {
- return false;
- }
- }
-
private static void setThreadCallbacks(Class type, Callback[] callbacks) {
setCallbacksHelper(type, callbacks, SET_THREAD_CALLBACKS_NAME);
}
@@ -710,54 +618,6 @@ public class AdvancedEnhancer extends AbstractClassGenerator
}
}
- /**
- * Helper method to create an intercepted object.
- * For finer control over the generated instance, use a new instance of <code>Enhancer</code>
- * instead of this static method.
- * @param type class to extend or interface to implement
- * @param callback the callback to use for all methods
- */
- public static Object create(Class type, Callback callback) {
- Enhancer e = new Enhancer();
- e.setSuperclass(type);
- e.setCallback(callback);
- return e.create();
- }
-
- /**
- * Helper method to create an intercepted object.
- * For finer control over the generated instance, use a new instance of <code>Enhancer</code>
- * instead of this static method.
- * @param type class to extend or interface to implement
- * @param interfaces array of interfaces to implement, or null
- * @param callback the callback to use for all methods
- */
- public static Object create(Class superclass, Class interfaces[], Callback callback) {
- Enhancer e = new Enhancer();
- e.setSuperclass(superclass);
- e.setInterfaces(interfaces);
- e.setCallback(callback);
- return e.create();
- }
-
- /**
- * Helper method to create an intercepted object.
- * For finer control over the generated instance, use a new instance of <code>Enhancer</code>
- * instead of this static method.
- * @param type class to extend or interface to implement
- * @param interfaces array of interfaces to implement, or null
- * @param filter the callback filter to use when generating a new class
- * @param callbacks callback implementations to use for the enhanced object
- */
- public static Object create(Class superclass, Class[] interfaces, CallbackFilter filter, Callback[] callbacks) {
- Enhancer e = new Enhancer();
- e.setSuperclass(superclass);
- e.setInterfaces(interfaces);
- e.setCallbackFilter(filter);
- e.setCallbacks(callbacks);
- return e.create();
- }
-
private void emitConstructors(ClassEmitter ce, List constructors) {
boolean seenNull = false;
for (final Object constructor1 : constructors) {
@@ -791,7 +651,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
return keys;
}
- private void emitGetCallback(ClassEmitter ce, int[] keys) {
+ private static void emitGetCallback(ClassEmitter ce, int[] keys) {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, GET_CALLBACK, null);
e.load_this();
e.invoke_static_this(BIND_CALLBACKS);
@@ -866,14 +726,14 @@ public class AdvancedEnhancer extends AbstractClassGenerator
e.end_method();
}
- private void emitNewInstanceCallbacks(ClassEmitter ce) {
+ private static void emitNewInstanceCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null);
e.load_arg(0);
e.invoke_static_this(SET_THREAD_CALLBACKS);
emitCommonNewInstance(e);
}
- private void emitCommonNewInstance(CodeEmitter e) {
+ private static void emitCommonNewInstance(CodeEmitter e) {
e.new_instance_this();
e.dup();
e.invoke_constructor_this();
@@ -905,7 +765,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
emitCommonNewInstance(e);
}
- private void emitNewInstanceMultiarg(ClassEmitter ce, List constructors) {
+ private static void emitNewInstanceMultiarg(ClassEmitter ce, List constructors) {
final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, MULTIARG_NEW_INSTANCE, null);
e.load_arg(2);
e.invoke_static_this(SET_THREAD_CALLBACKS);
@@ -1034,7 +894,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
se.end_method();
}
- private void emitSetThreadCallbacks(ClassEmitter ce) {
+ private static void emitSetThreadCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
SET_THREAD_CALLBACKS,
null);
@@ -1045,7 +905,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
e.end_method();
}
- private void emitSetStaticCallbacks(ClassEmitter ce) {
+ private static void emitSetStaticCallbacks(ClassEmitter ce) {
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC | Constants.ACC_STATIC,
SET_STATIC_CALLBACKS,
null);
@@ -1055,7 +915,7 @@ public class AdvancedEnhancer extends AbstractClassGenerator
e.end_method();
}
- private void emitCurrentCallback(CodeEmitter e, int index) {
+ private static void emitCurrentCallback(CodeEmitter e, int index) {
e.load_this();
e.getfield(getCallbackField(index));
e.dup();
diff --git a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
index 7310b936246d..cba4a70487b3 100644
--- a/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
+++ b/platform/platform-impl/src/org/jetbrains/io/BuiltInServer.java
@@ -17,6 +17,7 @@ package org.jetbrains.io;
import com.intellij.ide.XmlRpcServer;
import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
@@ -91,6 +92,10 @@ public class BuiltInServer implements Disposable {
}
private void bindCustomPorts(int firstPort, int port, NioEventLoopGroup eventLoopGroup) {
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ return;
+ }
+
for (CustomPortServerManager customPortServerManager : CustomPortServerManager.EP_NAME.getExtensions()) {
try {
int customPortServerManagerPort = customPortServerManager.getPort();
diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties
index 50500e895c48..05f2cd2f8f70 100644
--- a/platform/platform-resources-en/src/messages/ActionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties
@@ -251,8 +251,6 @@ action.NewModule.text=New _Module...
action.NewModule.description=Create new module from scratch and add it to the project
action.ImportProject.description=Create project structure for directory with existing sources or convert existing project model
action.ImportModule.description=Import module from directory with existing sources or from existing project model
-action.OpenProject.text=Open Project...
-action.OpenProject.description=Open an existing project
action.OpenFile.text=_Open...
action.OpenFile.description=Open a project or a file in editor
group.reopen.win.text=_Reopen Project
diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties
index 016c62b9f601..556b246bc1b7 100644
--- a/platform/platform-resources-en/src/messages/IdeBundle.properties
+++ b/platform/platform-resources-en/src/messages/IdeBundle.properties
@@ -243,6 +243,7 @@ button.no=_No
error.project.file.does.not.exist=Cannot load {0}. The file does not exist.
error.file.does.not.exist=File {0} does not exist.
title.open.project=Open Project
+title.open.file.or.project=Open File or Project
button.cancel=&Cancel
error.cannot.load.project=Cannot load project: {0}
title.cannot.load.project=Cannot Load Project
@@ -255,7 +256,7 @@ conversion.dialog.text.2=<b> </b><a href=\"details\">Details...</a><br/><br/>Old
message.text.unlock.read.only.files=<html><body>The following files are read only. {0} will unlock them.<br>{1}</body></html>
error.message.cannot.make.files.writable=Cannot make the following files writable:\n{0}
error.cannot.convert.project=Cannot convert project: {0}
-message.files.doesn.t.exists.0.so.the.corresponding.modules.won.t.be.converted.do.you.want.to.continue=<html><body>The following files don''t exists: <br>\
+message.text.files.do.not.exist=<html><body>The following files don''t exists: <br>\
{0}The corresponding modules won''t be converted. Do you want to continue?</body></html>
select.in.project.settings=Project Structure
@@ -413,8 +414,10 @@ title.popup.new.element=New
title.popup.new.element.same.place=New in Current Directory
command.go.to.next.split=Go to next split
message.occurrence.N.of.M=Occurrence {0} of {1}
+error.dir.contains.no.project=''{0}'' does not contain a project
error.files.of.this.type.cannot.be.opened=Files of this type cannot be opened in {0}
title.cannot.open.file=Cannot Open File
+title.cannot.open.project=Cannot Open Project
filter.all.file.types=All file types
filter.project.files=Project files ({0}) or project directories (.idea)
action.unpin.tab=Unp_in Tab
@@ -556,6 +559,8 @@ action.show.modules=Show Modules
action.description.show.modules=Show/Hide Modules
action.show.libraries.contents=Show Libraries Contents
action.show.hide.library.contents=Show/Hide Library Contents
+action.show.excluded.files=Show Excluded Files
+action.show.hide.excluded.files=Show/Hide Excluded Files
action.sort.by.type=Sort by Type
action.show.structure=Show Structure
action.description.show.structure=Show structure view
diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties
index a339716f031e..98e0045a31f3 100644
--- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties
@@ -167,7 +167,7 @@ inspection.parameter.can.be.local.display.name=Parameter can be local
inspection.parameter.can.be.local.problem.descriptor=Parameter can be converted to a local variable
inspection.convert.to.local.quickfix=Convert to local
-inspection.unused.return.value.display.name=Unused method return value
+inspection.unused.return.value.display.name=Method can be void
inspection.unused.return.value.problem.descriptor=Return value of the method is never used
inspection.unused.return.value.make.void.quickfix=Make Method void
diff --git a/platform/platform-resources-en/src/messages/OptionsBundle.properties b/platform/platform-resources-en/src/messages/OptionsBundle.properties
index 2a78c19bdd82..2c06b31b53f7 100644
--- a/platform/platform-resources-en/src/messages/OptionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/OptionsBundle.properties
@@ -199,14 +199,30 @@ options.xml.display.name=XML
settings.panel.title=Settings
node.configurable.build.tools.display.name=Build Tools
+node.configurable.build.tools.settings.description=<html><body>\
+ Default view for Build Tools
configurable.group.appearance.settings.display.name=Appearance and Behavior
+configurable.group.appearance.settings.description=<html><body>\
+ Default view for Appearance and Behavior
configurable.group.editor.settings.display.name=Editor
+configurable.group.editor.settings.description=<html><body>\
+ Default view for Editor
configurable.group.project.settings.display.name=Current Project
+configurable.group.project.settings.description=<html><body>\
+ Default view for Current Project
configurable.group.build.settings.display.name=Build, Execution, Deployment
+configurable.group.build.settings.description=<html><body>\
+ Default view for Build, Execution, Deployment
configurable.group.language.settings.display.name=Languages and Frameworks
+configurable.group.language.settings.description=<html><body>\
+ Default view for Languages and Frameworks
configurable.group.tools.settings.display.name=Tools
+configurable.group.tools.settings.description=<html><body>\
+ Default view for Tools
configurable.group.null.settings.display.name=Other Settings
+configurable.group.null.settings.description=<html><body>\
+ Default view for Other Settings
configurable.default.project.tooltip=For default project
configurable.current.project.tooltip=For current project
diff --git a/platform/platform-resources-en/src/messages/UIBundle.properties b/platform/platform-resources-en/src/messages/UIBundle.properties
index 2a0a6ee4799d..5dd72ae735b7 100644
--- a/platform/platform-resources-en/src/messages/UIBundle.properties
+++ b/platform/platform-resources-en/src/messages/UIBundle.properties
@@ -42,6 +42,7 @@ tool.window.name.project=Project
tool.window.name.structure=Structure
tool.window.name.favorites=Favorites
tool.window.name.ant.build=Ant Build
+tool.window.name.preview=Preview
tool.window.name.debug=Debug
tool.window.name.run=Run
tool.window.name.find=Find
@@ -91,7 +92,6 @@ file.chooser.default.title=Select Path
file.chooser.save.dialog.default.title=Select File to Save
file.chooser.save.dialog.confirmation={0} already exists.\nDo you want to replace it?
file.chooser.save.dialog.confirmation.title=Confirm Save as
-file.chooser.select.object.title=Select {0}
delete.dialog.title=Delete
are.you.sure.you.want.to.delete.selected.folder.confirmation.message=Are you sure you want to delete selected folder?
are.you.sure.you.want.to.delete.selected.file.confirmation.message=Delete {0}?
diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
index 058e446bc896..a1300adfd1bc 100644
--- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
+++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties
@@ -123,3 +123,6 @@ setting.sort.alphabetically.label=Sort a&lphabetically
setting.hide.window.label=Hide debug &window on process termination
setting.focus.app.on.breakpoint.label=Focus application on breakpoint
+settings.show.window.label=Show &debug window on breakpoint
+
+showReferring.dialog.title=Referring Objects For {0}
diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml
index c338dac9848b..4aa4ef8dea94 100644
--- a/platform/platform-resources/src/META-INF/LangExtensions.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensions.xml
@@ -360,25 +360,25 @@
serviceImplementation="com.intellij.codeInspection.ex.ProjectInspectionProfilesVisibleTreeState"/>
<!-- Editor -->
- <applicationConfigurable groupId="editor" instance="com.intellij.application.options.editor.EditorOptions" id="editor" key="title.editor"
+ <applicationConfigurable groupId="editor" groupWeight="190" instance="com.intellij.application.options.editor.EditorOptions" id="editor" key="title.editor"
bundle="messages.ApplicationBundle" order="after appearance"
childrenEPName="com.intellij.editorOptionsProvider"/>
<projectService serviceInterface="com.intellij.semantic.SemService" serviceImplementation="com.intellij.semantic.SemServiceImpl"/>
<!-- Global Code Style -->
- <projectConfigurable groupId="editor" dynamic="true" displayName="Code Style" instance="com.intellij.application.options.CodeStyleSchemesConfigurable" order="after colors"/>
+ <projectConfigurable groupId="editor" groupWeight="170" dynamic="true" displayName="Code Style" instance="com.intellij.application.options.CodeStyleSchemesConfigurable" order="after colors"/>
<applicationService serviceInterface="com.intellij.application.options.codeStyle.CodeStyleSchemesUIConfiguration"
serviceImplementation="com.intellij.application.options.codeStyle.CodeStyleSchemesUIConfiguration"/>
<!-- File Types -->
- <applicationConfigurable groupId="editor" instance="com.intellij.openapi.fileTypes.impl.FileTypeConfigurable" id="preferences.fileTypes"
+ <applicationConfigurable groupId="editor" groupWeight="120" instance="com.intellij.openapi.fileTypes.impl.FileTypeConfigurable" id="preferences.fileTypes"
key="filetype.settings.title" bundle="messages.FileTypesBundle"/>
<applicationConfigurable groupId="editor" key="intention.settings" bundle="messages.CodeInsightBundle" instance="com.intellij.codeInsight.intention.impl.config.IntentionSettingsConfigurable" id="intentions"/>
<!-- Live Templates -->
- <applicationConfigurable groupId="editor" instance="com.intellij.codeInsight.template.impl.LiveTemplatesConfigurable" id="editing.templates"
+ <applicationConfigurable groupId="editor" groupWeight="130" instance="com.intellij.codeInsight.template.impl.LiveTemplatesConfigurable" id="editing.templates"
key="templates.settings.page.title" bundle="messages.CodeInsightBundle"/>
<lookup.actionProvider implementation="com.intellij.codeInsight.template.impl.LiveTemplateLookupActionProvider"/>
<documentationProvider implementation="com.intellij.codeInsight.template.impl.LiveTemplateDocumentationProvider"/>
@@ -386,7 +386,7 @@
serviceImplementation="com.intellij.codeInsight.template.impl.TemplateManagerImpl"/>
<!-- File Templates-->
- <applicationConfigurable groupId="editor" instance="com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable" id="fileTemplates"
+ <applicationConfigurable groupId="editor" groupWeight="150" instance="com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable" id="fileTemplates"
key="title.file.templates" bundle="messages.IdeBundle"/>
<!-- T.O.D.O -->
@@ -394,7 +394,7 @@
bundle="messages.IdeBundle"/>
<!-- External Tools -->
- <applicationConfigurable groupId="tools" instance="com.intellij.tools.ToolConfigurable" id="preferences.externalTools" key="tools.settings.title"
+ <applicationConfigurable groupId="tools" groupWeight="140" instance="com.intellij.tools.ToolConfigurable" id="preferences.externalTools" key="tools.settings.title"
bundle="messages.ToolsBundle"/>
<stepsBeforeRunProvider implementation="com.intellij.tools.ToolBeforeRunTaskProvider"/>
<checkinHandlerFactory implementation="com.intellij.tools.ExternalToolsCheckinHandlerFactory"/>
@@ -613,7 +613,7 @@
<editorCustomization implementation="com.intellij.ui.RightMarginEditorCustomization"/>
<!-- Colors & Fonts-->
- <applicationConfigurable groupId="editor" dynamic="true" instance="com.intellij.application.options.colors.ColorAndFontOptions"
+ <applicationConfigurable groupId="editor" groupWeight="180" dynamic="true" instance="com.intellij.application.options.colors.ColorAndFontOptions"
id="reference.settingsdialog.IDE.editor.colors"/>
<editorOptionsProvider instance="com.intellij.application.options.editor.EditorTabsConfigurable" id="editor.preferences.tabs"
displayName="Editor Tabs"/>
@@ -753,7 +753,7 @@
<psi.fileReferenceHelper implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.HttpFileReferenceHelper"/>
<psi.fileReferenceHelper implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.NullFileReferenceHelper" order="last"/>
- <projectConfigurable groupId="editor" key="file.encodings.configurable" bundle="messages.IdeBundle" instance="com.intellij.openapi.vfs.encoding.FileEncodingConfigurable"/>
+ <projectConfigurable groupId="editor" groupWeight="140" key="file.encodings.configurable" bundle="messages.IdeBundle" instance="com.intellij.openapi.vfs.encoding.FileEncodingConfigurable"/>
<projectConfigurable groupId="appearance" instance="com.intellij.ui.tabs.FileColorsConfigurable" id="fileColors" displayName="File Colors"/>
<uiDebuggerExtension implementation="com.intellij.ui.debugger.extensions.PlaybackDebugger"/>
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
index a4dfd49a71a8..baea70a67c7a 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml
@@ -9,6 +9,9 @@
<extensionPoint name="postStartupActivity"
interface="com.intellij.openapi.startup.StartupActivity"/>
+ <extensionPoint name="defaultProjectTypeProvider"
+ interface="com.intellij.openapi.project.DefaultProjectTypeProvider"/>
+
<extensionPoint name="errorHandler"
interface="com.intellij.openapi.diagnostic.ErrorReportSubmitter"/>
diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
index 467ef8233919..51028d93edac 100644
--- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml
+++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml
@@ -155,6 +155,7 @@
serviceImplementation="com.intellij.openapi.vcs.readOnlyHandler.ReadonlyStatusHandlerImpl"/>
<projectService serviceInterface="com.intellij.openapi.startup.StartupManager"
serviceImplementation="com.intellij.ide.startup.impl.StartupManagerImpl"/>
+ <projectService serviceImplementation="com.intellij.openapi.project.ProjectTypeService"/>
<projectService serviceInterface="com.intellij.openapi.ui.MasterDetailsStateService" serviceImplementation="com.intellij.openapi.ui.MasterDetailsStateService"/>
<projectService serviceInterface="com.intellij.ide.SelectInManager" serviceImplementation="com.intellij.ide.SelectInManager"/>
@@ -197,14 +198,14 @@
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"/>
+ <applicationConfigurable groupId="appearance" groupWeight="120" key="title.general" bundle="messages.IdeBundle" id="preferences.general" instance="com.intellij.ide.GeneralSettingsConfigurable"/>
<!-- Appearance -->
- <applicationConfigurable groupId="appearance" instance="com.intellij.ide.ui.AppearanceConfigurable" id="appearance" key="title.appearance"
+ <applicationConfigurable groupId="appearance" groupWeight="150" instance="com.intellij.ide.ui.AppearanceConfigurable" id="appearance" key="title.appearance"
bundle="messages.IdeBundle"/>
<!-- Keymap -->
- <applicationConfigurable groupId="appearance" instance="com.intellij.openapi.keymap.impl.ui.KeymapPanel" id="preferences.keymap" key="keymap.display.name"
+ <applicationConfigurable groupId="appearance" groupWeight="140" instance="com.intellij.openapi.keymap.impl.ui.KeymapPanel" id="preferences.keymap" key="keymap.display.name"
bundle="messages.KeyMapBundle"/>
<applicationConfigurable parentId="appearance" instance="com.intellij.openapi.keymap.impl.ui.QuickListsPanel" id="reference.idesettings.quicklists"
displayName="Quick Lists"/>
@@ -214,13 +215,13 @@
key="title.customizations" bundle="messages.IdeBundle"/>
<!-- Notifications -->
- <applicationConfigurable groupId="appearance" displayName="Notifications" instance="com.intellij.notification.impl.NotificationsConfigurable"/>
+ <applicationConfigurable groupId="appearance" groupWeight="110" displayName="Notifications" instance="com.intellij.notification.impl.NotificationsConfigurable"/>
<!-- Plugins -->
- <applicationConfigurable groupId="appearance" instance="com.intellij.ide.plugins.PluginManagerConfigurable" id="preferences.pluginManager"
+ <applicationConfigurable groupId="appearance" groupWeight="130" instance="com.intellij.ide.plugins.PluginManagerConfigurable" id="preferences.pluginManager"
displayName="Plugins"/>
<actionFromOptionDescriptorProvider implementation="com.intellij.ide.plugins.InstalledPluginsManagerMain$PluginsActionFromOptionDescriptorProvider"/>
- <applicationConfigurable parentId="preferences.general" instance="com.intellij.util.net.HTTPProxySettingsPanel" id="http.proxy" displayName="HTTP Proxy" />
+ <applicationConfigurable parentId="preferences.general" instance="com.intellij.util.net.HttpProxyConfigurable" id="http.proxy" displayName="HTTP Proxy"/>
<applicationConfigurable groupId="tools" displayName="Server Certificates" instance="com.intellij.util.net.ssl.CertificateConfigurable"/>
<applicationConfigurable groupId="tools" instance="com.intellij.openapi.diff.impl.external.DiffOptionsForm" id="diff" displayName="External Diff Tools" />
<!--<applicationConfigurable instance="com.intellij.ui.switcher.QuickAccessConfigurable"/>-->
@@ -250,7 +251,7 @@
<componentConfigurationMerger implementation="com.intellij.openapi.vcs.changes.shelf.ShelfManagerConfigurationMerger"/>
<editorActionHandler action="EditorEscape" implementationClass="com.intellij.codeInsight.hint.EscapeHandler" id="hide-hints"/>
- <projectConfigurable groupId="language" instance="com.intellij.javaee.ExternalResourceConfigurable" key="display.name.edit.external.resource"
+ <projectConfigurable groupId="language" groupWeight="110" instance="com.intellij.javaee.ExternalResourceConfigurable" key="display.name.edit.external.resource"
bundle="messages.XmlBundle" id="preferences.externalResources">
<configurable instance="com.intellij.javaee.XMLCatalogConfigurable" displayName="XML Catalog" id="xml.catalog"/>
</projectConfigurable>
diff --git a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml
index ea14882e5ae6..b675e6491e09 100644
--- a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml
+++ b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml
@@ -81,7 +81,7 @@
<programRunner implementation="com.intellij.execution.runners.BasicProgramRunner" order="last"/>
- <projectConfigurable groupId="editor" displayName="Inspections" provider="com.intellij.profile.codeInspection.ui.ProjectInspectionToolsConfigurableProvider" order="before intentions"/>
+ <projectConfigurable groupId="editor" groupWeight="160" displayName="Inspections" provider="com.intellij.profile.codeInspection.ui.ProjectInspectionToolsConfigurableProvider" order="before intentions"/>
<projectConfigurable groupId="project" instance="com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable" id="project.scopes" key="scopes.display.name" bundle="messages.IdeBundle" />
<checkoutCompletedListener implementation="com.intellij.openapi.vcs.checkout.PlatformProjectCheckoutListener" id="PlatformProjectCheckoutListener"/>
diff --git a/platform/platform-resources/src/META-INF/VcsExtensions.xml b/platform/platform-resources/src/META-INF/VcsExtensions.xml
index a05f28107034..2322381c3b89 100644
--- a/platform/platform-resources/src/META-INF/VcsExtensions.xml
+++ b/platform/platform-resources/src/META-INF/VcsExtensions.xml
@@ -25,7 +25,7 @@
<selectInTarget implementation="com.intellij.openapi.vcs.changes.SelectInChangesViewTarget"/>
- <projectConfigurable groupId="project" dynamic="true" key="version.control.main.configurable.name" bundle="messages.VcsBundle" instance="com.intellij.openapi.vcs.configurable.VcsManagerConfigurable" id="vcs"/>
+ <projectConfigurable groupId="project" groupWeight="110" dynamic="true" key="version.control.main.configurable.name" bundle="messages.VcsBundle" instance="com.intellij.openapi.vcs.configurable.VcsManagerConfigurable" id="vcs"/>
<changesViewContent tabName="Repository" className="com.intellij.openapi.vcs.changes.committed.CommittedChangesViewManager"
predicateClassName="com.intellij.openapi.vcs.changes.committed.CommittedChangesVisibilityPredicate"/>
diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml
index 525ea3c94540..566d674d0063 100644
--- a/platform/platform-resources/src/META-INF/XmlPlugin.xml
+++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml
@@ -329,6 +329,7 @@
<!--
<copyPastePreProcessor implementation="com.intellij.codeInsight.editorActions.XmlCopyPastePreProcessor"/>
+ <copyPastePreProcessor implementation="com.intellij.codeInsight.editorActions.HtmlCopyPastePreProcessor"/>
-->
<syntaxHighlighter key="IDEA_PROJECT" implementationClass="com.intellij.ide.highlighter.XmlFileHighlighter"/>
@@ -531,7 +532,7 @@
<selectInTarget implementation="com.intellij.ide.browsers.actions.SelectInDefaultBrowserTarget"/>
<xml.xmlExtension implementation="com.intellij.xml.HtmlXmlExtension"/>
- <applicationConfigurable groupId="tools" instance="com.intellij.ide.browsers.BrowserSettings" id="reference.settings.ide.settings.web.browsers"
+ <applicationConfigurable groupId="tools" groupWeight="160" 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"/>
diff --git a/platform/platform-resources/src/META-INF/mime.types b/platform/platform-resources/src/META-INF/mime.types
index 699aa1b3058b..9338bb4957fe 100644
--- a/platform/platform-resources/src/META-INF/mime.types
+++ b/platform/platform-resources/src/META-INF/mime.types
@@ -86,4 +86,6 @@
video/x-msvideo avi
application/x-chrome-extension crx
-application/dart dart \ No newline at end of file
+application/dart dart
+
+text/xml rng \ No newline at end of file
diff --git a/platform/platform-resources/src/META-INF/xdebugger.xml b/platform/platform-resources/src/META-INF/xdebugger.xml
index 4dde33287f0c..d28921d17ba6 100644
--- a/platform/platform-resources/src/META-INF/xdebugger.xml
+++ b/platform/platform-resources/src/META-INF/xdebugger.xml
@@ -39,5 +39,7 @@
<editor.linePainter implementation="com.intellij.xdebugger.impl.evaluate.XDebuggerEditorLinePainter"/>
<executor implementation="com.intellij.execution.executors.DefaultDebugExecutor" order="first,after run"/>
+
+ <copyPastePreProcessor implementation="com.intellij.xdebugger.impl.ui.DebuggerCopyPastePreprocessor"/>
</extensions>
</idea-plugin>
diff --git a/platform/platform-resources/src/brokenPlugins.txt b/platform/platform-resources/src/brokenPlugins.txt
index 7b0830e86b02..584c3a466615 100644
--- a/platform/platform-resources/src/brokenPlugins.txt
+++ b/platform/platform-resources/src/brokenPlugins.txt
@@ -1,18 +1,18 @@
// 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.1189 138.1145 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.1161 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
+NodeJS 138.1367 138.1495 138.1189 138.1145 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.1505 138.1161 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 7.0.0.20140707 7.0.0.20140724
-Pythonid 3.1 4.0.25
-Karma 138.21 134.1163 134.1039 134.686 134.31
-org.intellij.scala 0.42.23 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.plugins.ruby 7.0.0.20140807 6.0.0.20140207 6.5.2.20140512 7.0.0.20140704 7.0.0.20140707 7.0.0.20140724
+Pythonid 3.1 4.0.25 4.0.26
+Karma 138.317 138.21 134.1163 134.1039 134.686 134.31
+org.intellij.scala 0.42.28 0.42.23 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
-"JSTestDriver Plugin" 138.21 136.1141 134.1163 134.686 134.31 134.307 134.1039
+"JSTestDriver Plugin" 138.317 138.21 136.1141 134.1163 134.686 134.31 134.307 134.1039
AngularJS 134.1094 0.1.8 0.1.9
org.jetbrains.plugins.vagrant 0.1 0.2
org.intellij.clojure 0.2.1.178
diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml
index 3b0289f12433..39957743629d 100644
--- a/platform/platform-resources/src/idea/LangActions.xml
+++ b/platform/platform-resources/src/idea/LangActions.xml
@@ -683,6 +683,7 @@
<action id="XDebugger.ToggleSortValues" class="com.intellij.xdebugger.impl.ui.tree.actions.SortValuesToggleAction" icon="AllIcons.ObjectBrowser.Sorted"/>
<action id="Debugger.MarkObject" class="com.intellij.xdebugger.impl.actions.MarkObjectAction"/>
<action id="Debugger.FocusOnBreakpoint" class="com.intellij.xdebugger.impl.actions.FocusOnBreakpointAction"/>
+ <action id="Debugger.ShowReferring" class="com.intellij.xdebugger.impl.ui.tree.actions.ShowReferringObjectsAction"/>
</group>
<group id="XDebugger.ToolWindow.TopToolbar">
@@ -698,7 +699,6 @@
</group>
<group id="XDebugger.ToolWindow.LeftToolbar">
- <reference ref="Rerun"/>
<reference ref="Resume"/>
<reference ref="Pause"/>
<reference ref="Stop"/>
@@ -709,6 +709,7 @@
<group id="XDebugger.ValueGroup" popup="false">
<reference ref="XDebugger.Inspect"/>
+ <reference ref="Debugger.ShowReferring"/>
<reference ref="Debugger.MarkObject"/>
<reference ref="XDebugger.SetValue"/>
<reference ref="XDebugger.CopyValue"/>
diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml
index 7773a2b00e49..0c970d8e802f 100644
--- a/platform/platform-resources/src/idea/PlatformActions.xml
+++ b/platform/platform-resources/src/idea/PlatformActions.xml
@@ -611,6 +611,8 @@
<action id="TestMessageBoxAction" internal="true" class="com.intellij.diagnostic.TestMessageBoxAction" text="Show Test Dialog"/>
<separator/>
<group id="Internal.focusAndModality" popup="true" text="Focus and modality testing">
+ <action id="ShowDelayedMessageInternalAction" internal="true" class="com.intellij.notification.impl.actions.ShowDelayedMessageInternalAction"
+ text="Show Delayed Message"/>
<action id="ManualMacMessagesTest" internal="true" class="com.intellij.internal.validation.MacMessagesTest"
text="Manual test for testing MacMessages"/>
<action id="MacMessagesSequencesTest" internal="true" class="com.intellij.internal.validation.TestMacMessagesSequencesAction"
diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java
index 476bd66ddde4..d66988ab2ef5 100644
--- a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatOnlyVcsChangedTextTest.java
@@ -163,6 +163,28 @@ public class ReformatOnlyVcsChangedTextTest extends LightPlatformTestCase {
);
}
+ public void testModificationCRLF() throws IOException {
+ doTest(
+ "public class B {\r\n" +
+ " int a = 3;\r\n" +
+ " String text;\r\n" +
+ " Object last = null;\r\n" +
+ " Object first = null;\r\n" +
+ " Object second = null;\r\n" +
+ "}",
+
+ "public class B {\r\n" +
+ " int a = 33;\r\n" +
+ " String text;\r\n" +
+ " Object last = new Object();\r\n" +
+ " Object first = null;\r\n" +
+ " Object second = new Object();\r\n" +
+ "}",
+
+ line(1, 1), line(3,3), line(5,5)
+ );
+ }
+
public void testReformatFiles() throws IOException {
ChangedFilesStructure fs = new ChangedFilesStructure(myWorkingDirectory);
diff --git a/platform/platform-tests/testSrc/com/intellij/execution/process/AnsiEscapeDecoderTest.java b/platform/platform-tests/testSrc/com/intellij/execution/process/AnsiEscapeDecoderTest.java
index 32ec00d1a733..df0acc766dc7 100644
--- a/platform/platform-tests/testSrc/com/intellij/execution/process/AnsiEscapeDecoderTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/execution/process/AnsiEscapeDecoderTest.java
@@ -3,47 +3,60 @@ package com.intellij.execution.process;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.testFramework.PlatformTestCase;
-import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.junit.Assert;
+import java.util.Arrays;
import java.util.List;
public class AnsiEscapeDecoderTest extends PlatformTestCase {
public void testTextWithoutColors() throws Exception {
AnsiEscapeDecoder decoder = new AnsiEscapeDecoder();
- decoder.escapeText("", ProcessOutputTypes.STDOUT, createExpectedAcceptor(ContainerUtil.newArrayList(
+ decoder.escapeText("", ProcessOutputTypes.STDOUT, createExpectedAcceptor(
Pair.create("", ProcessOutputTypes.STDOUT)
- )));
- decoder.escapeText("simple text", ProcessOutputTypes.STDOUT, createExpectedAcceptor(ContainerUtil.newArrayList(
+ ));
+ decoder.escapeText("simple text", ProcessOutputTypes.STDOUT, createExpectedAcceptor(
Pair.create("simple text", ProcessOutputTypes.STDOUT)
- )));
+ ));
}
public void testSingleColoredChunk() throws Exception {
AnsiEscapeDecoder decoder = new AnsiEscapeDecoder();
- decoder.escapeText("Chrome 35.0.1916 (Linux): Executed 0 of 1\u001B[32m SUCCESS\u001B[39m (0 secs / 0 secs)\n", ProcessOutputTypes.STDOUT, createExpectedAcceptor(ContainerUtil.newArrayList(
+ decoder.escapeText("Chrome 35.0.1916 (Linux): Executed 0 of 1\u001B[32m SUCCESS\u001B[39m (0 secs / 0 secs)\n", ProcessOutputTypes.STDOUT, createExpectedAcceptor(
Pair.create("Chrome 35.0.1916 (Linux): Executed 0 of 1", ProcessOutputTypes.STDOUT),
Pair.create(" SUCCESS", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[32m")),
Pair.create(" (0 secs / 0 secs)\n", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[39m"))
- )));
+ ));
}
public void testCompoundEscSeq() throws Exception {
AnsiEscapeDecoder decoder = new AnsiEscapeDecoder();
- decoder.escapeText("E\u001B[41m\u001B[37mE\u001B[0mE", ProcessOutputTypes.STDOUT, createExpectedAcceptor(ContainerUtil.newArrayList(
+ decoder.escapeText("E\u001B[41m\u001B[37mE\u001B[0mE", ProcessOutputTypes.STDOUT, createExpectedAcceptor(
Pair.create("E", ProcessOutputTypes.STDOUT),
Pair.create("E", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[41;37m")),
Pair.create("E", ProcessOutputTypes.STDOUT)
- )));
+ ));
}
- private static AnsiEscapeDecoder.ColoredChunksAcceptor createExpectedAcceptor(@NotNull final List<Pair<String, Key>> expected) {
+ public void testOtherEscSeq() throws Exception {
+ AnsiEscapeDecoder decoder = new AnsiEscapeDecoder();
+ decoder.escapeText("Plain\u001B[32mGreen\u001B[39mNormal\u001B[1A\u001B[2K\u001B[31mRed\u001B[39m",
+ ProcessOutputTypes.STDOUT,
+ createExpectedAcceptor(
+ Pair.create("Plain", ProcessOutputTypes.STDOUT),
+ Pair.create("Green", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[32m")),
+ Pair.create("Normal", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[39m")),
+ Pair.create("Red", ColoredOutputTypeRegistry.getInstance().getOutputKey("\u001B[31m"))
+ )
+ );
+ }
+
+ private static AnsiEscapeDecoder.ColoredChunksAcceptor createExpectedAcceptor(@NotNull final Pair<String, Key>... expected) {
return new AnsiEscapeDecoder.ColoredChunksAcceptor() {
@Override
public void coloredChunksAvailable(List<Pair<String, Key>> chunks) {
- Assert.assertEquals(expected, chunks);
+ Assert.assertEquals(Arrays.asList(expected), chunks);
}
@Override
diff --git a/platform/platform-tests/testSrc/com/intellij/ide/ActivityMonitorTest.java b/platform/platform-tests/testSrc/com/intellij/ide/ActivityMonitorTest.java
index 3fad6d619b72..8e0a0b1e9aa3 100644
--- a/platform/platform-tests/testSrc/com/intellij/ide/ActivityMonitorTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/ide/ActivityMonitorTest.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.
@@ -15,16 +15,15 @@
*/
package com.intellij.ide;
-import com.intellij.mock.MockApplication;
import com.intellij.mock.MockProject;
import com.intellij.mock.MockProjectEx;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.application.impl.ModalityStateEx;
-import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.BusyObject;
-import com.intellij.testFramework.UsefulTestCase;
+import com.intellij.testFramework.LightPlatformTestCase;
+import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,28 +34,12 @@ import org.jetbrains.annotations.Nullable;
* Time: 10:04 AM
* To change this template use File | Settings | File Templates.
*/
-public class ActivityMonitorTest extends UsefulTestCase {
+public class ActivityMonitorTest extends LightPlatformTestCase {
private UiActivityMonitorImpl myMonitor;
- private ModalityState myCurrentState;
@Override
protected void setUp() throws Exception {
super.setUp();
- myCurrentState = ModalityState.NON_MODAL;
- final ModalityStateEx any = new ModalityStateEx();
- Extensions.registerAreaClass("IDEA_PROJECT", null);
- ApplicationManager.setApplication(new MockApplication(getTestRootDisposable()) {
- @NotNull
- @Override
- public ModalityState getCurrentModalityState() {
- return myCurrentState;
- }
-
- @Override
- public ModalityState getAnyModalityState() {
- return any;
- }
- }, getTestRootDisposable());
myMonitor = new UiActivityMonitorImpl();
myMonitor.setActive(true);
disposeOnTearDown(myMonitor);
@@ -150,19 +133,23 @@ public class ActivityMonitorTest extends UsefulTestCase {
myMonitor.addActivity(new UiActivity("non_modal_1"), ModalityState.NON_MODAL);
assertBusy(null);
- myCurrentState = new ModalityStateEx(new Object[] {"dialog"});
- assertReady(null);
+ LaterInvocator.enterModal("dialog");
+ try {
+ assertReady(null);
- myMonitor.addActivity(new UiActivity("non_modal2"), ModalityState.NON_MODAL);
- assertReady(null);
+ myMonitor.addActivity(new UiActivity("non_modal2"), ModalityState.NON_MODAL);
+ assertReady(null);
- myMonitor.addActivity(new UiActivity("modal_1"), new ModalityStateEx(new Object[] {"dialog"}));
- assertBusy(null);
+ myMonitor.addActivity(new UiActivity("modal_1"), new ModalityStateEx(new Object[] {"dialog"}));
+ assertBusy(null);
- myMonitor.addActivity(new UiActivity("modal_2"), new ModalityStateEx(new Object[] {"dialog", "popup"}));
- assertBusy(null);
+ myMonitor.addActivity(new UiActivity("modal_2"), new ModalityStateEx(new Object[] {"dialog", "popup"}));
+ assertBusy(null);
+ }
+ finally {
+ LaterInvocator.leaveModal("dialog");
+ }
- myCurrentState = ModalityState.NON_MODAL;
assertBusy(null);
}
@@ -172,8 +159,13 @@ public class ActivityMonitorTest extends UsefulTestCase {
myMonitor.addActivity(new UiActivity("non_modal_1"), ModalityState.any());
assertBusy(null);
- myCurrentState = new ModalityStateEx(new Object[] {"dialog"});
- assertBusy(null);
+ try {
+ LaterInvocator.enterModal("dialog");
+ assertBusy(null);
+ }
+ finally {
+ LaterInvocator.leaveModal("dialog");
+ }
}
public void testUiActivity() throws Exception {
@@ -183,11 +175,12 @@ public class ActivityMonitorTest extends UsefulTestCase {
assertFalse(new UiActivity("root", "folder2").isSameOrGeneralFor(new UiActivity("anotherRoot")));
}
- private void assertReady(@Nullable Project key, UiActivity ... activities) {
+ private void assertReady(@Nullable Project key, @NotNull UiActivity ... activities) {
+ UIUtil.dispatchAllInvocationEvents();
BusyObject.Impl busy = (BusyObject.Impl)(key != null ? myMonitor.getBusy(key, activities) : myMonitor.getBusy(activities));
assertTrue("Must be READY, but was: BUSY", busy.isReady());
- final boolean[] done = new boolean[] {false};
+ final boolean[] done = {false};
busy.getReady(this).doWhenDone(new Runnable() {
@Override
public void run() {
@@ -198,9 +191,9 @@ public class ActivityMonitorTest extends UsefulTestCase {
assertTrue(done[0]);
}
- private void assertBusy(@Nullable Project key, UiActivity ... activities) {
+ private void assertBusy(@Nullable Project key, @NotNull UiActivity ... activities) {
+ UIUtil.dispatchAllInvocationEvents();
BusyObject.Impl busy = (BusyObject.Impl)(key != null ? myMonitor.getBusy(key, activities) : myMonitor.getBusy(activities));
assertFalse("Must be BUSY, but was: READY", busy.isReady());
}
-
}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ApplicationStoreTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ApplicationStoreTest.java
new file mode 100644
index 000000000000..cfbd5a12f146
--- /dev/null
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/ApplicationStoreTest.java
@@ -0,0 +1,153 @@
+package com.intellij.openapi.components.impl;
+
+import com.intellij.application.options.PathMacrosImpl;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.components.impl.stores.*;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.testFramework.LightPlatformLangTestCase;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+public class ApplicationStoreTest extends LightPlatformLangTestCase {
+ private File testAppConfig;
+ private MyComponentStore componentStore;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ String testAppConfigPath = System.getProperty("test.app.config.path");
+ if (testAppConfigPath == null) {
+ testAppConfig = FileUtil.createTempDirectory("testAppSettings", null);
+ }
+ else {
+ testAppConfig = new File(FileUtil.expandUserHome(testAppConfigPath));
+ }
+ FileUtil.delete(testAppConfig);
+
+ componentStore = new MyComponentStore(testAppConfig.getAbsolutePath());
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ try {
+ Disposer.dispose(componentStore);
+ componentStore = null;
+ }
+ finally {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.delete(testAppConfig);
+ }
+ }
+ }
+
+ public void testStreamProviderSaveIfSeveralStoragesConfigured() throws Exception {
+ SeveralStoragesConfigured component = new SeveralStoragesConfigured();
+ componentStore.initComponent(component, false);
+ StoreUtil.doSave(componentStore);
+ }
+
+ class MyComponentStore extends ComponentStoreImpl implements Disposable {
+ private final StateStorageManager stateStorageManager;
+
+ MyComponentStore(@NotNull final String testAppConfigPath) {
+ TrackingPathMacroSubstitutor macroSubstitutor = new ApplicationPathMacroManager().createTrackingSubstitutor();
+ stateStorageManager = new StateStorageManagerImpl(macroSubstitutor, "application", this, ApplicationManager.getApplication().getPicoContainer()) {
+ @Override
+ protected StorageData createStorageData(String storageSpec) {
+ return new FileBasedStorage.FileStorageData("application");
+ }
+
+ @Nullable
+ @Override
+ protected String getOldStorageSpec(Object component, final String componentName, final StateStorageOperation operation) {
+ return null;
+ }
+
+ @Override
+ protected String getVersionsFilePath() {
+ return testAppConfigPath + "/options/appComponentVersions.xml";
+ }
+
+ @Override
+ protected TrackingPathMacroSubstitutor getMacroSubstitutor(@NotNull final String fileSpec) {
+ if (fileSpec.equals(StoragePathMacros.APP_CONFIG + "/" + PathMacrosImpl.EXT_FILE_NAME + ".xml")) {
+ return null;
+ }
+ return super.getMacroSubstitutor(fileSpec);
+ }
+ };
+
+ stateStorageManager.addMacro(StoragePathMacros.getMacroName(StoragePathMacros.APP_CONFIG), testAppConfigPath);
+ }
+
+ @Override
+ public void load() throws IOException, StateStorageException {
+ }
+
+ @NotNull
+ @Override
+ public StateStorageManager getStateStorageManager() {
+ return stateStorageManager;
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Nullable
+ @Override
+ protected StateStorage getDefaultsStorage() {
+ return null;
+ }
+ }
+
+ static class SeveralStoragesConfiguredStorageChooser implements StateStorageChooser<SeveralStoragesConfigured> {
+ @Override
+ public Storage[] selectStorages(Storage[] storages, SeveralStoragesConfigured component, StateStorageOperation operation) {
+ if (operation == StateStorageOperation.WRITE) {
+ for (Storage storage : storages) {
+ if (storage.file().equals(StoragePathMacros.APP_CONFIG + "/proxy.settings.xml")) {
+ return new Storage[]{storage};
+ }
+ }
+ }
+ return storages;
+ }
+ }
+
+ @State(
+ name = "HttpConfigurable",
+ storages = {
+ // we use two storages due to backward compatibility, see http://crucible.labs.intellij.net/cru/CR-IC-5142
+ @Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml"),
+ @Storage(file = StoragePathMacros.APP_CONFIG + "/proxy.settings.xml")
+ },
+ storageChooser = SeveralStoragesConfiguredStorageChooser.class
+ )
+ static class SeveralStoragesConfigured implements PersistentStateComponent<SeveralStoragesConfigured> {
+ public String foo = "defaultValue";
+
+ @Nullable
+ @Override
+ public SeveralStoragesConfigured getState() {
+ foo = "newValue";
+ return this;
+ }
+
+ @Override
+ public void loadState(SeveralStoragesConfigured state) {
+ XmlSerializerUtil.copyBean(state, this);
+ }
+ }
+}
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java
index a4e3024a60d0..76c673626b26 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/components/impl/StateStorageManagerImplTest.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.components.impl.stores.StateStorageManagerImpl;
import com.intellij.openapi.components.impl.stores.StorageData;
import com.intellij.openapi.util.Disposer;
import com.intellij.testFramework.LightPlatformLangTestCase;
+import org.jetbrains.annotations.Nullable;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
@@ -43,6 +44,7 @@ public class StateStorageManagerImplTest extends LightPlatformLangTestCase {
throw new UnsupportedOperationException("Method createStorageData not implemented in " + getClass());
}
+ @Nullable
@Override
protected String getOldStorageSpec(Object component, String componentName, StateStorageOperation operation) throws StateStorageException {
throw new UnsupportedOperationException("Method getOldStorageSpec not implemented in " + getClass());
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/HeavyFileEditorManagerTestCase.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/HeavyFileEditorManagerTestCase.java
index f494f565acf1..b128eb5d3ec2 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/HeavyFileEditorManagerTestCase.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/HeavyFileEditorManagerTestCase.java
@@ -56,6 +56,13 @@ public abstract class HeavyFileEditorManagerTestCase extends CodeInsightFixtureT
}
@Override
+ protected void tearDown() throws Exception {
+ myManager = null;
+
+ super.tearDown();
+ }
+
+ @Override
protected String getBasePath() {
return "/platform/platform-tests/testData/fileEditorManager";
}
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 96d85c122624..54a2865ad444 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
@@ -22,20 +22,19 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.util.Clock;
-import com.intellij.testFramework.LightPlatformTestCase;
+import com.intellij.testFramework.LightPlatformLangTestCase;
import javax.swing.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
-public class ModifierKeyDoubleClickHandlerTest extends LightPlatformTestCase {
+public class ModifierKeyDoubleClickHandlerTest extends LightPlatformLangTestCase {
private static final String MY_SHIFT_SHIFT_ACTION = "ModifierKeyDoubleClickHandlerTest.action1";
private static final String MY_SHIFT_KEY_ACTION = "ModifierKeyDoubleClickHandlerTest.action2";
private static final String MY_SHIFT_SHIFT_KEY_ACTION = "ModifierKeyDoubleClickHandlerTest.action3";
- public static final KeyboardShortcut SHIFT_KEY_SHORTCUT = new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,
- InputEvent.SHIFT_MASK),
- null);
+ private static final KeyboardShortcut SHIFT_KEY_SHORTCUT =
+ new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, InputEvent.SHIFT_MASK), null);
private final JComponent myComponent = new JPanel();
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
index 66c10c26b528..1a0d9c37388e 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/local/LocalFileSystemTest.java
@@ -396,8 +396,8 @@ public class LocalFileSystemTest extends PlatformLangTestCase {
PersistentFS.getInstance().findRoot("", myFS);
fail("should fail by assertion in PersistentFsImpl.findRoot()");
}
- catch (AssertionError e) {
- String message = e.getMessage();
+ catch (Throwable t) {
+ String message = t.getMessage();
assertTrue(message, message.startsWith("Invalid root"));
}
}
diff --git a/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java b/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java
index b1ab5117dba9..693c23766d62 100644
--- a/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiDocumentManagerImplTest.java
@@ -25,11 +25,13 @@ import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ex.ProjectManagerEx;
+import com.intellij.openapi.util.ThrowableComputable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
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.*;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.testFramework.LeakHunter;
import com.intellij.testFramework.LightVirtualFile;
@@ -40,6 +42,7 @@ import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.ui.UIUtil;
import java.io.File;
+import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
public class PsiDocumentManagerImplTest extends PlatformLangTestCase {
@@ -394,4 +397,63 @@ public class PsiDocumentManagerImplTest extends PlatformLangTestCase {
});
assertTrue(commitThread.isEnabled());
}
+
+ public void testFileChangesToText() throws IOException {
+ VirtualFile vFile = getVirtualFile(createTempFile("a.txt", "abc"));
+ PsiFile psiFile = getPsiManager().findFile(vFile);
+ Document document = getPsiDocumentManager().getDocument(psiFile);
+
+ rename(vFile, "a.xml");
+ assertFalse(psiFile.isValid());
+ assertNotSame(psiFile, getPsiManager().findFile(vFile));
+ psiFile = getPsiManager().findFile(vFile);
+
+ assertSame(document, FileDocumentManager.getInstance().getDocument(vFile));
+ assertSame(document, getPsiDocumentManager().getDocument(psiFile));
+ }
+
+ public void testFileChangesToBinary() throws IOException {
+ VirtualFile vFile = getVirtualFile(createTempFile("a.txt", "abc"));
+ PsiFile psiFile = getPsiManager().findFile(vFile);
+ Document document = getPsiDocumentManager().getDocument(psiFile);
+
+ rename(vFile, "a.zip");
+ assertFalse(psiFile.isValid());
+ psiFile = getPsiManager().findFile(vFile);
+ assertInstanceOf(psiFile, PsiBinaryFile.class);
+
+ assertNoFileDocumentMapping(vFile, psiFile, document);
+ assertEquals("abc", document.getText());
+ }
+
+ public void testFileBecomesTooLarge() throws Exception {
+ VirtualFile vFile = getVirtualFile(createTempFile("a.txt", "abc"));
+ PsiFile psiFile = getPsiManager().findFile(vFile);
+ Document document = getPsiDocumentManager().getDocument(psiFile);
+
+ makeFileTooLarge(vFile);
+ assertFalse(psiFile.isValid());
+ psiFile = getPsiManager().findFile(vFile);
+ assertInstanceOf(psiFile, PsiLargeFile.class);
+
+ assertNoFileDocumentMapping(vFile, psiFile, document);
+ assertEquals("abc", document.getText());
+ }
+
+ private void assertNoFileDocumentMapping(VirtualFile vFile, PsiFile psiFile, Document document) {
+ assertNull(FileDocumentManager.getInstance().getDocument(vFile));
+ assertNull(FileDocumentManager.getInstance().getFile(document));
+ assertNull(getPsiDocumentManager().getPsiFile(document));
+ assertNull(getPsiDocumentManager().getDocument(psiFile));
+ }
+
+ private void makeFileTooLarge(final VirtualFile vFile) throws Exception {
+ WriteCommandAction.runWriteCommandAction(myProject, new ThrowableComputable<Object, Exception>() {
+ @Override
+ public Object compute() throws Exception {
+ VfsUtil.saveText(vFile, StringUtil.repeat("a", FileUtil.LARGE_FOR_CONTENT_LOADING + 1));
+ return null;
+ }
+ });
+ }
}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java b/platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java
index 765f350309bd..374423225694 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/components/StoragePathMacros.java
@@ -31,6 +31,8 @@ import org.jetbrains.annotations.NotNull;
* @since 5/2/12 12:57 PM
*/
public class StoragePathMacros {
+ @NonNls @NotNull public static final String ROOT_CONFIG = "$ROOT_CONFIG$";
+
/** Points to the application-level settings root directory. */
@NonNls @NotNull public static final String APP_CONFIG = "$APP_CONFIG$";
diff --git a/platform/projectModel-api/src/com/intellij/openapi/project/DefaultProjectTypeProvider.java b/platform/projectModel-api/src/com/intellij/openapi/project/DefaultProjectTypeProvider.java
new file mode 100644
index 000000000000..81887eba0f98
--- /dev/null
+++ b/platform/projectModel-api/src/com/intellij/openapi/project/DefaultProjectTypeProvider.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.openapi.project;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public abstract class DefaultProjectTypeProvider {
+
+ private final static ExtensionPointName<DefaultProjectTypeProvider> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.defaultProjectTypeProvider");
+
+ @Nullable
+ public static ProjectType getDefaultProjectType() {
+ DefaultProjectTypeProvider[] extensions = EXTENSION_POINT_NAME.getExtensions();
+ return extensions.length > 0 ? extensions[0].getProjectType() : null;
+ }
+
+ protected abstract ProjectType getProjectType();
+}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/project/ProjectType.java b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectType.java
new file mode 100644
index 000000000000..f096e67c0ff5
--- /dev/null
+++ b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectType.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.openapi.project;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class ProjectType {
+
+ private String id;
+
+ /**
+ * For serialization.
+ */
+ public ProjectType() {
+ }
+
+ public ProjectType(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ProjectType type = (ProjectType)o;
+
+ if (id != null ? !id.equals(type.id) : type.id != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return id != null ? id.hashCode() : 0;
+ }
+}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/project/ProjectTypeService.java b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectTypeService.java
new file mode 100644
index 000000000000..e43059390b19
--- /dev/null
+++ b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectTypeService.java
@@ -0,0 +1,61 @@
+/*
+ * 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.project;
+
+import com.intellij.openapi.components.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Dmitry Avdeev
+ */
+
+@State(
+ name = "ProjectType",
+ storages = {
+ @Storage(file = StoragePathMacros.PROJECT_FILE),
+ @Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/misc.xml", scheme = StorageScheme.DIRECTORY_BASED)
+ }
+)
+public class ProjectTypeService implements PersistentStateComponent<ProjectType> {
+
+ private ProjectType myProjectType;
+
+ @Nullable
+ public static ProjectType getProjectType(@Nullable Project project) {
+ ProjectType projectType;
+ if (project != null) {
+ projectType = getInstance(project).myProjectType;
+ if (projectType != null) return projectType;
+ }
+ return DefaultProjectTypeProvider.getDefaultProjectType();
+ }
+
+ public static ProjectTypeService getInstance(@NotNull Project project) {
+ return ServiceManager.getService(project, ProjectTypeService.class);
+ }
+
+ @Nullable
+ @Override
+ public ProjectType getState() {
+ return myProjectType;
+ }
+
+ @Override
+ public void loadState(ProjectType state) {
+ myProjectType = state;
+ }
+}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java b/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java
index 60fccacb04c0..3230ed3ae496 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/OrderRootType.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import java.util.*;
@@ -111,8 +112,8 @@ public class OrderRootType {
List<PersistentOrderRootType> allTypes = new ArrayList<PersistentOrderRootType>();
Collections.addAll(allTypes, getAllPersistentTypes());
Collections.sort(allTypes, new Comparator<PersistentOrderRootType>() {
- public int compare(final PersistentOrderRootType o1, final PersistentOrderRootType o2) {
- return o1.getSdkRootName().compareTo(o2.getSdkRootName());
+ public int compare(@NotNull final PersistentOrderRootType o1, @NotNull final PersistentOrderRootType o2) {
+ return o1.name().compareToIgnoreCase(o2.name());
}
});
return allTypes;
diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java b/platform/projectModel-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java
index b799e76ad351..cb8f90e35326 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/roots/PersistentOrderRootType.java
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots;
import org.jetbrains.annotations.NonNls;
import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.Nullable;
/**
* @author yole
@@ -27,7 +28,7 @@ public class PersistentOrderRootType extends OrderRootType {
private final String myModulePathsName;
private final String myOldSdkRootName;
- protected PersistentOrderRootType(@NonNls String name, @NonNls String sdkRootName, @NonNls String modulePathsName, @NonNls final String oldSdkRootName) {
+ protected PersistentOrderRootType(@NonNls String name, @NonNls @Nullable String sdkRootName, @NonNls @Nullable String modulePathsName, @NonNls final @Nullable String oldSdkRootName) {
super(name);
mySdkRootName = sdkRootName;
myModulePathsName = modulePathsName;
@@ -37,12 +38,14 @@ public class PersistentOrderRootType extends OrderRootType {
}
/**
- * @return Element name used for storing roots of this type in JDK and library definitions.
+ * @return Element name used for storing roots of this type in JDK definitions.
*/
+ @Nullable
public String getSdkRootName() {
return mySdkRootName;
}
+ @Nullable
public String getOldSdkRootName() {
return myOldSdkRootName;
}
@@ -50,6 +53,7 @@ public class PersistentOrderRootType extends OrderRootType {
/**
* @return Element name used for storing roots of this type in module definitions.
*/
+ @Nullable
public String getModulePathsName() {
return myModulePathsName;
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java
index 890d77578a81..608a350d770c 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/DefaultStateSerializer.java
@@ -27,11 +27,11 @@ import com.intellij.util.xmlb.Accessor;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializer;
import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.Annotation;
-
@SuppressWarnings({"deprecation"})
class DefaultStateSerializer {
@@ -40,7 +40,7 @@ class DefaultStateSerializer {
private DefaultStateSerializer() {
}
- static Element serializeState(Object state, final Storage storage) throws WriteExternalException {
+ static Element serializeState(@NotNull Object state, final Storage storage) throws WriteExternalException {
if (state instanceof Element) {
return (Element)state;
}
@@ -53,7 +53,8 @@ class DefaultStateSerializer {
}
catch (WriteExternalException e) {
throw e;
- }catch (Throwable e) {
+ }
+ catch (Throwable e) {
LOG.info("Unable to serialize component state!", e);
return new Element("empty");
}
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java
index 22800f9a4e1a..1036456dfc6b 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectRootContainerImpl.java
@@ -23,10 +23,7 @@ import com.intellij.openapi.projectRoots.ex.ProjectRoot;
import com.intellij.openapi.projectRoots.ex.ProjectRootContainer;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.PersistentOrderRootType;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.JDOMExternalizable;
-import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.vfs.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
@@ -223,7 +220,8 @@ public class ProjectRootContainerImpl implements JDOMExternalizable, ProjectRoot
}
private void read(Element element, PersistentOrderRootType type) throws InvalidDataException {
- Element child = element.getChild(type.getSdkRootName());
+ String sdkRootName = type.getSdkRootName();
+ Element child = sdkRootName != null ? element.getChild(sdkRootName) : null;
if (child == null) {
myRoots.put(type, new CompositeProjectRoot());
return;
@@ -236,11 +234,14 @@ public class ProjectRootContainerImpl implements JDOMExternalizable, ProjectRoot
}
private void write(Element roots, PersistentOrderRootType type) throws WriteExternalException {
- Element e = new Element(type.getSdkRootName());
- roots.addContent(e);
- final Element root = ProjectRootUtil.write(myRoots.get(type));
- if (root != null) {
- e.addContent(root);
+ String sdkRootName = type.getSdkRootName();
+ if (sdkRootName != null) {
+ Element e = new Element(sdkRootName);
+ roots.addContent(e);
+ final Element root = ProjectRootUtil.write(myRoots.get(type));
+ if (root != null) {
+ e.addContent(root);
+ }
}
}
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 8e80670b1f76..c439a35d0a36 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
@@ -134,6 +134,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
public ProjectRootManagerImpl(Project project) {
myProject = project;
myRootsCache = new OrderRootsCache(project);
+ myJdkTableMultiListener = new JdkTableMultiListener(project);
}
@Override
@@ -281,7 +282,6 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
@Override
public void disposeComponent() {
- myJdkTableMultiListener = null;
}
@Override
@@ -478,45 +478,52 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
void addListenerForTable(LibraryTable.Listener libraryListener,
final LibraryTable libraryTable) {
- LibraryTableMultilistener multilistener = myLibraryTableMultilisteners.get(libraryTable);
- if (multilistener == null) {
- multilistener = new LibraryTableMultilistener(libraryTable);
+ synchronized (myLibraryTableListenersLock) {
+ LibraryTableMultiListener multiListener = myLibraryTableMultiListeners.get(libraryTable);
+ if (multiListener == null) {
+ multiListener = new LibraryTableMultiListener(libraryTable);
+ libraryTable.addListener(multiListener);
+ myLibraryTableMultiListeners.put(libraryTable, multiListener);
+ }
+ multiListener.addListener(libraryListener);
}
- multilistener.addListener(libraryListener);
}
void removeListenerForTable(LibraryTable.Listener libraryListener,
final LibraryTable libraryTable) {
- LibraryTableMultilistener multilistener = myLibraryTableMultilisteners.get(libraryTable);
- if (multilistener == null) {
- multilistener = new LibraryTableMultilistener(libraryTable);
+ synchronized (myLibraryTableListenersLock) {
+ LibraryTableMultiListener multiListener = myLibraryTableMultiListeners.get(libraryTable);
+ if (multiListener != null) {
+ boolean last = multiListener.removeListener(libraryListener);
+ if (last) {
+ libraryTable.removeListener(multiListener);
+ myLibraryTableMultiListeners.remove(libraryTable);
+ }
+ }
}
- multilistener.removeListener(libraryListener);
}
- private final Map<LibraryTable, LibraryTableMultilistener> myLibraryTableMultilisteners
- = new HashMap<LibraryTable, LibraryTableMultilistener>();
+ private final Object myLibraryTableListenersLock = new Object();
+ private final Map<LibraryTable, LibraryTableMultiListener> myLibraryTableMultiListeners = new HashMap<LibraryTable, LibraryTableMultiListener>();
- private class LibraryTableMultilistener implements LibraryTable.Listener {
- final List<LibraryTable.Listener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
+ private class LibraryTableMultiListener implements LibraryTable.Listener {
+ private final Set<LibraryTable.Listener> myListeners = new LinkedHashSet<LibraryTable.Listener>();
private final LibraryTable myLibraryTable;
+ private LibraryTable.Listener[] myListenersArray;
- private LibraryTableMultilistener(LibraryTable libraryTable) {
+ private LibraryTableMultiListener(LibraryTable libraryTable) {
myLibraryTable = libraryTable;
- myLibraryTable.addListener(this);
- myLibraryTableMultilisteners.put(myLibraryTable, this);
}
- private void addListener(LibraryTable.Listener listener) {
+ private synchronized void addListener(LibraryTable.Listener listener) {
myListeners.add(listener);
+ myListenersArray = null;
}
- private void removeListener(LibraryTable.Listener listener) {
+ private synchronized boolean removeListener(LibraryTable.Listener listener) {
myListeners.remove(listener);
- if (myListeners.isEmpty()) {
- myLibraryTable.removeListener(this);
- myLibraryTableMultilisteners.remove(myLibraryTable);
- }
+ myListenersArray = null;
+ return myListeners.isEmpty();
}
@Override
@@ -525,20 +532,27 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- for (LibraryTable.Listener listener : myListeners) {
+ for (LibraryTable.Listener listener : getListeners()) {
listener.afterLibraryAdded(newLibrary);
}
}
});
}
+ private synchronized LibraryTable.Listener[] getListeners() {
+ if (myListenersArray == null) {
+ myListenersArray = myListeners.toArray(new LibraryTable.Listener[myListeners.size()]);
+ }
+ return myListenersArray;
+ }
+
@Override
public void afterLibraryRenamed(final Library library) {
incModificationCount();
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- for (LibraryTable.Listener listener : myListeners) {
+ for (LibraryTable.Listener listener : getListeners()) {
listener.afterLibraryRenamed(library);
}
}
@@ -551,7 +565,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- for (LibraryTable.Listener listener : myListeners) {
+ for (LibraryTable.Listener listener : getListeners()) {
listener.beforeLibraryRemoved(library);
}
}
@@ -564,7 +578,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- for (LibraryTable.Listener listener : myListeners) {
+ for (LibraryTable.Listener listener : getListeners()) {
listener.afterLibraryRemoved(library);
}
}
@@ -572,24 +586,33 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
}
}
- private JdkTableMultiListener myJdkTableMultiListener = null;
+ private final JdkTableMultiListener myJdkTableMultiListener;
private class JdkTableMultiListener implements ProjectJdkTable.Listener {
- final EventDispatcher<ProjectJdkTable.Listener> myDispatcher = EventDispatcher.create(ProjectJdkTable.Listener.class);
+ private final Set<ProjectJdkTable.Listener> myListeners = new LinkedHashSet<ProjectJdkTable.Listener>();
private MessageBusConnection listenerConnection;
+ private ProjectJdkTable.Listener[] myListenersArray;
private JdkTableMultiListener(Project project) {
listenerConnection = project.getMessageBus().connect();
listenerConnection.subscribe(ProjectJdkTable.JDK_TABLE_TOPIC, this);
}
- private void addListener(ProjectJdkTable.Listener listener) {
- myDispatcher.addListener(listener);
+ private synchronized void addListener(ProjectJdkTable.Listener listener) {
+ myListeners.add(listener);
+ myListenersArray = null;
+ }
+
+ private synchronized void removeListener(ProjectJdkTable.Listener listener) {
+ myListeners.remove(listener);
+ myListenersArray = null;
}
- private void removeListener(ProjectJdkTable.Listener listener) {
- myDispatcher.removeListener(listener);
- uninstallListener(true);
+ private synchronized ProjectJdkTable.Listener[] getListeners() {
+ if (myListenersArray == null) {
+ myListenersArray = myListeners.toArray(new ProjectJdkTable.Listener[myListeners.size()]);
+ }
+ return myListenersArray;
}
@Override
@@ -597,7 +620,9 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- myDispatcher.getMulticaster().jdkAdded(jdk);
+ for (ProjectJdkTable.Listener listener : getListeners()) {
+ listener.jdkAdded(jdk);
+ }
}
});
}
@@ -607,7 +632,9 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- myDispatcher.getMulticaster().jdkRemoved(jdk);
+ for (ProjectJdkTable.Listener listener : getListeners()) {
+ listener.jdkRemoved(jdk);
+ }
}
});
}
@@ -617,7 +644,9 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
mergeRootsChangesDuring(new Runnable() {
@Override
public void run() {
- myDispatcher.getMulticaster().jdkNameChanged(jdk, previousName);
+ for (ProjectJdkTable.Listener listener : getListeners()) {
+ listener.jdkNameChanged(jdk, previousName);
+ }
}
});
String currentName = getProjectSdkName();
@@ -627,32 +656,15 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
myProjectSdkType = jdk.getSdkType().getName();
}
}
-
- public void uninstallListener(boolean soft) {
- if (!soft || !myDispatcher.hasListeners()) {
- if (listenerConnection != null) {
- listenerConnection.disconnect();
- listenerConnection = null;
- }
- }
- }
}
private final Map<RootProvider, Set<OrderEntry>> myRegisteredRootProviders = new HashMap<RootProvider, Set<OrderEntry>>();
void addJdkTableListener(ProjectJdkTable.Listener jdkTableListener) {
- getJdkTableMultiListener().addListener(jdkTableListener);
- }
-
- private JdkTableMultiListener getJdkTableMultiListener() {
- if (myJdkTableMultiListener == null) {
- myJdkTableMultiListener = new JdkTableMultiListener(myProject);
- }
- return myJdkTableMultiListener;
+ myJdkTableMultiListener.addListener(jdkTableListener);
}
void removeJdkTableListener(ProjectJdkTable.Listener jdkTableListener) {
- if (myJdkTableMultiListener == null) return;
myJdkTableMultiListener.removeListener(jdkTableListener);
}
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 bc85dabc9aec..bd9531a2d888 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
@@ -71,14 +71,6 @@ public class RootIndex {
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) {
@@ -98,6 +90,12 @@ public class RootIndex {
myProjectExcludedRoots.add(root);
}
}
+ LowMemoryWatcher.register(new Runnable() {
+ @Override
+ public void run() {
+ myNonExistentPackages.clear();
+ }
+ }, project);
}
@NotNull
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 fa901849867f..7b5de892d4da 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
@@ -22,7 +22,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.OrderRootType;
-import com.intellij.openapi.roots.PersistentOrderRootType;
import com.intellij.openapi.roots.RootProvider;
import com.intellij.openapi.roots.impl.RootModelImpl;
import com.intellij.openapi.roots.impl.RootProviderBaseImpl;
@@ -320,23 +319,13 @@ public class LibraryImpl extends TraceableDisposable implements LibraryEx.Modifi
List<OrderRootType> allTypes = new ArrayList<OrderRootType>(rootTypes);
Collections.sort(allTypes, new Comparator<OrderRootType>() {
@Override
- public int compare(final OrderRootType o1, final OrderRootType o2) {
- return getSortKey(o1).compareTo(getSortKey(o2));
+ public int compare(@NotNull final OrderRootType o1, @NotNull final OrderRootType o2) {
+ return o1.name().compareToIgnoreCase(o2.name());
}
});
return allTypes;
}
- private static String getSortKey(OrderRootType orderRootType) {
- if (orderRootType instanceof PersistentOrderRootType) {
- return ((PersistentOrderRootType)orderRootType).getSdkRootName();
- }
- if (orderRootType instanceof OrderRootType.DocumentationRootType) {
- return ((OrderRootType.DocumentationRootType)orderRootType).getSdkRootName();
- }
- return "";
- }
-
@Override
public void writeExternal(Element rootElement) throws WriteExternalException {
checkDisposed();
diff --git a/platform/projectModel-impl/src/messages/ProjectBundle.properties b/platform/projectModel-impl/src/messages/ProjectBundle.properties
index 2d74782822db..a0fe65ad981a 100644
--- a/platform/projectModel-impl/src/messages/ProjectBundle.properties
+++ b/platform/projectModel-impl/src/messages/ProjectBundle.properties
@@ -128,6 +128,7 @@ button.text.attach.files=Attach &Files or Directories...
library.attach.files.action=Attach Files or Directories
library.attach.files.to.library.action=Attach Files or Directories to Library ''{0}''
library.attach.files.description=Select files or directories in which library classes, sources and documentation are located
+library.java.attach.files.description=Select files or directories in which library classes, sources, documentation or native libraries are located
library.sources.not.found=Sources not found
library.sources.not.attached=Sources not attached
@@ -318,6 +319,7 @@ external.annotations.root.chooser.description=External annotations would be save
external.annotation.prompt=External annotation prompt
external.annotations.suggestion.message=<html><body>If you do not want annotations in your code you may use external storage.<br> \
To configure external annotations please specify root directory where files with annotations would be placed</body></html>
+project.roots.native.library.node.text=Native Library Locations
sdk.configure.annotations.tab=Annotations
project.roots.path.tab.title=Paths
project.roots.external.annotations.tab.title=External Annotations
diff --git a/platform/remote-servers/impl/src/META-INF/RemoteServers.xml b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
index 41067b075460..2888727432c9 100644
--- a/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
+++ b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml
@@ -42,6 +42,8 @@
<action id="RemoteServers.EditServer" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.EditConfigurationAction"/>
<separator/>
<action id="RemoteServers.DeployAll" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.DeployAllAction"/>
+ <action id="Servers.Deploy" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.DeployAction"/>
+ <action id="Servers.Undeploy" class="com.intellij.remoteServer.impl.runtime.ui.tree.actions.UndeployAction"/>
</group>
</actions>
</idea-plugin> \ No newline at end of file
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 5a3d150daf57..729a1e9bc605 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
@@ -127,21 +127,16 @@ public class CloudAccountSelectionEditor {
}
};
- final SingleConfigurableEditor configurableEditor
- = new SingleConfigurableEditor(myMainPanel, configurable, ShowSettingsUtilImpl.createDimensionKey(configurable), false) {
-
+ if (!new SingleConfigurableEditor(myMainPanel, configurable, ShowSettingsUtilImpl.createDimensionKey(configurable), false) {
{
errorConsumerRef.set(new Consumer<String>() {
-
@Override
public void consume(String s) {
setErrorText(s);
}
});
}
- };
-
- if (!configurableEditor.showAndGet()) {
+ }.showAndGet()) {
return;
}
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 c033a6979f09..27bd8abfe0ce 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
@@ -2,7 +2,7 @@ package org.jetbrains.debugger.sourcemap;
import com.google.gson.stream.JsonToken;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.Function;
+import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.util.PathUtil;
import com.intellij.util.SmartList;
import com.intellij.util.text.CharSequenceSubSequence;
@@ -24,7 +24,7 @@ public final class SourceMapDecoder {
private static final Comparator<MappingEntry> MAPPING_COMPARATOR_BY_SOURCE_POSITION = new Comparator<MappingEntry>() {
@Override
- public int compare(MappingEntry o1, MappingEntry o2) {
+ public int compare(@NotNull MappingEntry o1, @NotNull MappingEntry o2) {
if (o1.getSourceLine() == o2.getSourceLine()) {
return o1.getSourceColumn() - o2.getSourceColumn();
}
@@ -36,7 +36,7 @@ public final class SourceMapDecoder {
public static final Comparator<MappingEntry> MAPPING_COMPARATOR_BY_GENERATED_POSITION = new Comparator<MappingEntry>() {
@Override
- public int compare(MappingEntry o1, MappingEntry o2) {
+ public int compare(@NotNull MappingEntry o1, @NotNull MappingEntry o2) {
if (o1.getGeneratedLine() == o2.getGeneratedLine()) {
return o1.getGeneratedColumn() - o2.getGeneratedColumn();
}
@@ -46,7 +46,12 @@ public final class SourceMapDecoder {
}
};
- public static SourceMap decode(@NotNull String contents, @NotNull Function<List<String>, SourceResolver> sourceResolverFactory) throws IOException {
+ public interface SourceResolverFactory {
+ @NotNull
+ SourceResolver create(@NotNull List<String> sourcesUrl, @Nullable List<String> sourcesContent);
+ }
+
+ public static SourceMap decode(@NotNull String contents, @NotNull SourceResolverFactory sourceResolverFactory) throws IOException {
if (contents.isEmpty()) {
throw new IOException("source map contents cannot be empty");
}
@@ -59,7 +64,7 @@ public final class SourceMapDecoder {
}
@Nullable
- public static SourceMap decode(@NotNull CharSequence in, @NotNull Function<List<String>, SourceResolver> sourceResolverFactory) throws IOException {
+ public static SourceMap decode(@NotNull CharSequence in, @NotNull SourceResolverFactory sourceResolverFactory) throws IOException {
JsonReaderEx reader = new JsonReaderEx(in);
List<MappingEntry> mappings = new ArrayList<MappingEntry>();
return parseMap(reader, 0, 0, mappings, sourceResolverFactory);
@@ -70,7 +75,7 @@ public final class SourceMapDecoder {
int line,
int column,
List<MappingEntry> mappings,
- @NotNull Function<List<String>, SourceResolver> sourceResolverFactory) throws IOException {
+ @NotNull SourceResolverFactory sourceResolverFactory) throws IOException {
reader.beginObject();
String sourceRoot = null;
JsonReaderEx sourcesReader = null;
@@ -78,6 +83,7 @@ public final class SourceMapDecoder {
String encodedMappings = null;
String file = null;
int version = -1;
+ List<String> sourcesContent = null;
while (reader.hasNext()) {
String propertyName = reader.nextName();
if (propertyName.equals("sections")) {
@@ -98,7 +104,14 @@ public final class SourceMapDecoder {
if (reader.hasNext()) {
names = new ArrayList<String>();
do {
- names.add(reader.nextString(true));
+ if (reader.peek() == JsonToken.BEGIN_OBJECT) {
+ // polymer map
+ reader.skipValue();
+ names.add("POLYMER UNKNOWN NAME");
+ }
+ else {
+ names.add(reader.nextString(true));
+ }
}
while (reader.hasNext());
}
@@ -113,6 +126,17 @@ public final class SourceMapDecoder {
else if (propertyName.equals("file")) {
file = reader.nextString();
}
+ else if (propertyName.equals("sourcesContent")) {
+ reader.beginArray();
+ if (reader.peek() != JsonToken.END_ARRAY) {
+ sourcesContent = new SmartList<String>();
+ do {
+ sourcesContent.add(StringUtilRt.convertLineSeparators(reader.nextString()));
+ }
+ while (reader.hasNext());
+ }
+ reader.endArray();
+ }
else {
// skip file or extensions
reader.skipValue();
@@ -152,7 +176,7 @@ public final class SourceMapDecoder {
sourceToEntries[i] = new SourceMappingList(entries);
}
}
- return new SourceMap(file, new GeneratedMappingList(mappings), sourceToEntries, sourceResolverFactory.fun(sources));
+ return new SourceMap(file, new GeneratedMappingList(mappings), sourceToEntries, sourceResolverFactory.create(sources, sourcesContent));
}
@Nullable
diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceResolver.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceResolver.java
index 38693e4ac3ae..665039507ace 100644
--- a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceResolver.java
+++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceResolver.java
@@ -8,6 +8,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Url;
import com.intellij.util.UrlImpl;
import com.intellij.util.Urls;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.ObjectIntHashMap;
import com.intellij.util.io.URLUtil;
import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
@@ -20,6 +21,7 @@ import java.util.List;
public class SourceResolver {
private final List<String> rawSources;
+ @Nullable private final List<String> sourcesContent;
final Url[] canonicalizedSources;
private final ObjectIntHashMap<Url> canonicalizedSourcesMap;
@@ -28,14 +30,15 @@ public class SourceResolver {
// absoluteLocalPathToSourceIndex contains canonical paths too, but this map contains only used (specified in the source map) path
private String[] sourceIndexToAbsoluteLocalPath;
- public SourceResolver(@NotNull List<String> sources, boolean trimFileScheme, @Nullable Url baseFileUrl) {
- rawSources = sources;
- canonicalizedSources = new Url[sources.size()];
+ public SourceResolver(@NotNull List<String> sourcesUrl, boolean trimFileScheme, @Nullable Url baseFileUrl, @Nullable List<String> sourcesContent) {
+ rawSources = sourcesUrl;
+ this.sourcesContent = sourcesContent;
+ canonicalizedSources = new Url[sourcesUrl.size()];
canonicalizedSourcesMap = SystemInfo.isFileSystemCaseSensitive
? new ObjectIntHashMap<Url>(canonicalizedSources.length)
: new ObjectIntHashMap<Url>(canonicalizedSources.length, Urls.getCaseInsensitiveUrlHashingStrategy());
- for (int i = 0; i < sources.size(); i++) {
- String rawSource = sources.get(i);
+ for (int i = 0; i < sourcesUrl.size(); i++) {
+ String rawSource = sourcesUrl.get(i);
Url url = canonicalizeUrl(rawSource, baseFileUrl, trimFileScheme, i);
canonicalizedSources[i] = url;
canonicalizedSourcesMap.put(url, i);
@@ -111,6 +114,16 @@ public class SourceResolver {
}
@Nullable
+ public String getSourceContent(@NotNull MappingEntry entry) {
+ if (ContainerUtil.isEmpty(sourcesContent)) {
+ return null;
+ }
+
+ int index = entry.getSource();
+ return index < 0 || index >= sourcesContent.size() ? null : sourcesContent.get(index);
+ }
+
+ @Nullable
public String getRawSource(@NotNull MappingEntry entry) {
int index = entry.getSource();
return index < 0 ? null : rawSources.get(index);
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeStructure.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeStructure.java
index b740bb6a0ccc..7d15140c8de5 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeStructure.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeStructure.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.
@@ -43,6 +43,11 @@ public class SMTRunnerTreeStructure extends AbstractTreeStructure
public void commit() {
}
+ @Override
+ public boolean hasSomethingToCommit() {
+ return false;
+ }
+
@NotNull
@Override
public SMTRunnerNodeDescriptor createDescriptor(final Object element,
@@ -70,17 +75,12 @@ public class SMTRunnerTreeStructure extends AbstractTreeStructure
return ((AbstractTestProxy)element).getParent();
}
+
@Override
public Object getRootElement() {
return myRootNode;
}
-
- @Override
- public boolean hasSomethingToCommit() {
- return false;
- }
-
public void setFilter(final Filter nodesFilter) {
myTestNodesFilter = nodesFilter;
}
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestComparisionFailedState.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestComparisionFailedState.java
index 84b28a79c5e8..2d500115c038 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestComparisionFailedState.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestComparisionFailedState.java
@@ -15,9 +15,11 @@
*/
package com.intellij.execution.testframework.sm.runner.states;
+import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.testframework.AbstractTestProxy;
import com.intellij.execution.testframework.CompositePrintable;
import com.intellij.execution.testframework.Printer;
+import com.intellij.execution.testframework.sm.runner.ui.TestsPresentationUtil;
import com.intellij.execution.testframework.stacktrace.DiffHyperlink;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.project.Project;
@@ -41,10 +43,8 @@ public class TestComparisionFailedState extends TestFailedState implements Abstr
super(localizedMessage, stackTrace);
myHyperlink = new DiffHyperlink(expectedText, actualText, null);
- myErrorMsgPresentation = StringUtil.isEmptyOrSpaces(localizedMessage) ? ""
- : localizedMessage;
- myStacktracePresentation = StringUtil.isEmptyOrSpaces(stackTrace) ? ""
- : stackTrace;
+ myErrorMsgPresentation = StringUtil.isEmptyOrSpaces(localizedMessage) ? "" : localizedMessage;
+ myStacktracePresentation = StringUtil.isEmptyOrSpaces(stackTrace) ? "" : stackTrace;
}
@Override
@@ -53,20 +53,15 @@ public class TestComparisionFailedState extends TestFailedState implements Abstr
printer.mark();
// Error msg
- if (myErrorMsgPresentation != null) {
- printer.print(myErrorMsgPresentation, ConsoleViewContentType.ERROR_OUTPUT);
- }
+ TestsPresentationUtil.printWithAnsiColoring(printer, myErrorMsgPresentation, ProcessOutputTypes.STDERR);
// Diff link
myHyperlink.printOn(printer);
// Stacktrace
- if (myStacktracePresentation != null) {
- printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT);
-
- printer.print(myStacktracePresentation, ConsoleViewContentType.ERROR_OUTPUT);
- printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT);
- }
+ printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT);
+ TestsPresentationUtil.printWithAnsiColoring(printer, myStacktracePresentation, ProcessOutputTypes.STDERR);
+ printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT);
}
public void openDiff(final Project project) {
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java
index 8906bd1867a9..712f6fc35dbf 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestFailedState.java
@@ -15,8 +15,10 @@
*/
package com.intellij.execution.testframework.sm.runner.states;
+import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.testframework.CompositePrintable;
import com.intellij.execution.testframework.Printer;
+import com.intellij.execution.testframework.sm.runner.ui.TestsPresentationUtil;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.ContainerUtilRt;
@@ -75,7 +77,7 @@ public class TestFailedState extends AbstractState {
printer.mark();
addMark = false;
}
- printer.print(errorText, ConsoleViewContentType.ERROR_OUTPUT);
+ TestsPresentationUtil.printWithAnsiColoring(printer, errorText, ProcessOutputTypes.STDERR);
}
}
}
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java
index 7cb42773f735..d36250191b09 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java
@@ -15,14 +15,19 @@
*/
package com.intellij.execution.testframework.sm.runner.ui;
+import com.intellij.execution.process.AnsiEscapeDecoder;
+import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.testframework.PoolOfTestIcons;
+import com.intellij.execution.testframework.Printer;
import com.intellij.execution.testframework.TestConsoleProperties;
import com.intellij.execution.testframework.TestsUIUtil;
import com.intellij.execution.testframework.sm.SMTestsRunnerBundle;
import com.intellij.execution.testframework.sm.runner.SMTestProxy;
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo;
import com.intellij.execution.testframework.ui.TestsProgressAnimator;
+import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.icons.AllIcons;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ColoredTableCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
@@ -448,4 +453,18 @@ public class TestsPresentationUtil {
break;
}
}
+
+ public static void printWithAnsiColoring(@NotNull final Printer printer, @NotNull String text, @NotNull final Key processOutputType) {
+ AnsiEscapeDecoder decoder = new AnsiEscapeDecoder();
+ decoder.escapeText(text, ProcessOutputTypes.STDOUT, new AnsiEscapeDecoder.ColoredTextAcceptor() {
+ @Override
+ public void coloredTextAvailable(String text, Key attributes) {
+ ConsoleViewContentType contentType = ConsoleViewContentType.getConsoleViewType(attributes);
+ if (contentType == null || contentType == ConsoleViewContentType.NORMAL_OUTPUT) {
+ contentType = ConsoleViewContentType.getConsoleViewType(processOutputType);
+ }
+ printer.print(text, contentType);
+ }
+ });
+ }
}
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java
deleted file mode 100644
index e7327fad7e5e..000000000000
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/DataProvider.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.intellij.structuralsearch.impl.matcher;
-
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.project.Project;
-
-/**
- * Created by IntelliJ IDEA.
- * User: maxim
- * Date: 07.01.2004
- * Time: 1:06:51
- * To change this template use Options | File Templates.
- */
-public interface DataProvider {
- Editor getEditor();
- Project getProject();
-}
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java
index 6a0d352d3284..f5279e15026e 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/ui/ReplaceUsageViewContext.java
@@ -44,13 +44,6 @@ class ReplaceUsageViewContext extends UsageViewContext {
return command;
}
- protected String _getPresentableText() {
- return SSRBundle.message("replaceusageview.text",
- getConfiguration().getMatchOptions().getSearchPattern(),
- ((ReplaceConfiguration)getConfiguration()).getOptions().getReplacement()
- );
- }
-
public Replacer getReplacer() {
return replacer;
}
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java
deleted file mode 100644
index 83d93ba0d05c..000000000000
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/DialogBase.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package com.intellij.structuralsearch.plugin.ui;
-
-import com.intellij.openapi.MnemonicHelper;
-import com.intellij.CommonBundle;
-
-import javax.swing.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.InputEvent;
-import java.awt.*;
-
-import org.jetbrains.annotations.NonNls;
-
-/**
- * Base dialog class
- */
-public abstract class DialogBase extends JDialog {
- private JButton ok;
- private JButton cancel;
-
- private Action okAction;
- private Action cancelAction;
- private static Rectangle virtualBounds;
-
- class OkAction extends AbstractAction {
- OkAction() {
- putValue(NAME, CommonBundle.getOkButtonText());
- }
- public void actionPerformed(ActionEvent e) {
- doOKAction();
- }
- }
-
- class CancelAction extends AbstractAction {
- CancelAction() {
- putValue(NAME,CommonBundle.getCancelButtonText());
- }
-
- public void actionPerformed(ActionEvent e) {
- doCancelAction();
- }
- }
-
- protected DialogBase() {
- this(null);
- }
-
- protected DialogBase(Frame frame) {
- this(frame,true);
- }
-
- protected DialogBase(Frame frame,boolean modal) {
- super(frame,modal);
-
- new MnemonicHelper().register(getContentPane());
-
- okAction = new OkAction();
- cancelAction = new CancelAction();
-
- ok = createJButtonForAction(okAction);
- cancel = createJButtonForAction(cancelAction);
-
- if (virtualBounds == null) {
- GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- GraphicsDevice[] gs = ge.getScreenDevices();
- virtualBounds = new Rectangle();
-
- for (int j = 0; j < gs.length; j++) {
- GraphicsDevice gd = gs[j];
- GraphicsConfiguration[] gc = gd.getConfigurations();
-
- for (int i=0; i < gc.length; i++) {
- virtualBounds = virtualBounds.union(gc[i].getBounds());
- }
- }
- }
-
- @NonNls String cancelCommandName = "close";
- KeyStroke escKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
- ok.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escKeyStroke, cancelCommandName);
- ok.getActionMap().put(cancelCommandName, cancelAction);
-
- @NonNls String startCommandName = "start";
- KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,InputEvent.CTRL_MASK);
- ok.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(enterKeyStroke, startCommandName);
- ok.getActionMap().put(startCommandName, okAction);
- }
-
- protected JButton getCancelButton() {
- return cancel;
- }
-
- protected JButton getOkButton() {
- return ok;
- }
-
- protected abstract JComponent createCenterPanel();
-
- protected JComponent createSouthPanel() {
- JPanel p = new JPanel( null );
- p.setLayout( new BoxLayout(p,BoxLayout.X_AXIS) );
- p.add(Box.createHorizontalGlue());
- p.add(getOkButton());
- p.add(getCancelButton());
- return p;
- }
-
- public void init() {
- getContentPane().setLayout(new BorderLayout());
- getContentPane().add(BorderLayout.CENTER,createCenterPanel());
- getContentPane().add(BorderLayout.SOUTH,createSouthPanel());
- pack();
-
- Dimension dim = getPreferredSize();
- setLocation(
- (int)(virtualBounds.getWidth()/2 - dim.getWidth()/2),
- (int)(virtualBounds.getHeight()/2 - dim.getHeight()/2)
- );
- }
-
- public void show() {
- pack();
- super.show();
- }
-
- protected void doCancelAction() {
- setVisible(false);
- }
-
- protected void doOKAction() {
- setVisible(false);
- }
-
- protected void setOKActionEnabled(boolean b) {
- okAction.setEnabled(b);
- }
-
- protected void setOKButtonText(String text) {
- okAction.putValue(Action.NAME,text);
- }
-
- protected void setCancelButtonText(String text) {
- cancelAction.putValue(Action.NAME,text);
- }
-
- protected JButton createJButtonForAction(Action _action) {
- JButton jb = new JButton( (String)_action.getValue(Action.NAME) );
- jb.setAction(_action);
-
- return jb;
- }
-}
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 f82ad12e5f4f..258aaf6b8ccc 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/EditVarConstraintsDialog.java
@@ -30,11 +30,13 @@ import com.intellij.structuralsearch.MatchVariableConstraint;
import com.intellij.structuralsearch.NamedScriptableDefinition;
import com.intellij.structuralsearch.ReplacementVariableDefinition;
import com.intellij.structuralsearch.SSRBundle;
+import com.intellij.structuralsearch.impl.matcher.CompiledPattern;
import com.intellij.structuralsearch.impl.matcher.predicates.ScriptSupport;
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.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -47,6 +49,7 @@ import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
+import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -223,7 +226,10 @@ class EditVarConstraintsDialog extends DialogWrapper {
customScriptCode.getButton().addActionListener(new ActionListener() {
public void actionPerformed(@NotNull final ActionEvent e) {
- final EditScriptDialog dialog = new EditScriptDialog(project, customScriptCode.getChildComponent().getText());
+ Set<String> strings = ContainerUtil.collectSet(model.getConfig().getMatchOptions().getVariableConstraintNames());
+ strings.remove(current.getName());
+ strings.remove(CompiledPattern.ALL_CLASS_UNMATCHED_CONTENT_VAR_ARTIFICIAL_NAME);
+ EditScriptDialog dialog = new EditScriptDialog(project, customScriptCode.getChildComponent().getText(), strings);
dialog.show();
if (dialog.getExitCode() == OK_EXIT_CODE) {
customScriptCode.getChildComponent().setText(dialog.getScriptText());
@@ -585,11 +591,13 @@ class EditVarConstraintsDialog extends DialogWrapper {
private static class EditScriptDialog extends DialogWrapper {
private final Editor editor;
+ private final String title;
- public EditScriptDialog(final Project project, String text) {
+ public EditScriptDialog(Project project, String text, Set<String> names) {
super(project, true);
setTitle(SSRBundle.message("edit.groovy.script.constraint.title"));
editor = createEditor(project, text, "1.groovy");
+ title = names.size() > 0 ? "Available variables: " + StringUtil.join(names, ", ") : "";
init();
}
@@ -604,7 +612,15 @@ class EditVarConstraintsDialog extends DialogWrapper {
}
protected JComponent createCenterPanel() {
- return editor.getComponent();
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.add(editor.getComponent(), BorderLayout.CENTER);
+ if (!title.isEmpty()) {
+ JTextField f=new JTextField(title);
+ f.setEditable(false);
+ f.setBorder(null);
+ panel.add(f, BorderLayout.SOUTH);
+ }
+ return panel;
}
String getScriptText() {
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java
index 8cb7e55ea290..80f0c7b8ce0d 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchCommand.java
@@ -56,6 +56,7 @@ public class SearchCommand {
}
public void matchingFinished() {
+ if (project.isDisposed()) return;
findEnded();
progress.setText(SSRBundle.message("found.progress.message", count));
}
@@ -114,7 +115,7 @@ public class SearchCommand {
new Runnable() {
@Override
public void run() {
- NotificationGroup.toolWindowGroup("Structural Search", ToolWindowId.FIND, true)
+ NotificationGroup.toolWindowGroup("Structural Search", ToolWindowId.FIND)
.createNotification(SSRBundle.message("problem", e.getMessage()), MessageType.ERROR).notify(project);
}
},
@@ -132,9 +133,7 @@ public class SearchCommand {
}
protected void findEnded() {
- if (!project.isDisposed()) {
- StructuralSearchPlugin.getInstance(project).setSearchInProgress(false);
- }
+ StructuralSearchPlugin.getInstance(project).setSearchInProgress(false);
}
protected void foundUsage(MatchResult result, Usage usage) {
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java
index 62371e7e29d1..045c2749871c 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchContext.java
@@ -9,12 +9,11 @@ import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
-import com.intellij.structuralsearch.impl.matcher.DataProvider;
/**
* Context of the search to be done
*/
-public final class SearchContext implements DataProvider, Cloneable {
+public final class SearchContext implements Cloneable {
private final PsiFile file;
private final Project project;
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java
index a3bee702563e..3f89f11b9e6d 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java
@@ -12,6 +12,7 @@ import com.intellij.lang.LanguageUtil;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
@@ -90,8 +91,6 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
private boolean useLastConfiguration;
- private static boolean ourOpenInNewTab;
-
@NonNls private FileType ourFtSearchVariant = StructuralSearchUtil.getDefaultFileType();
private static Language ourDialect = null;
private static String ourContext = null;
@@ -184,7 +183,7 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
try {
new WriteAction(){
@Override
- protected void run(Result result) throws Throwable {
+ protected void run(Result result) {
if (!isValid()) {
getOKAction().setEnabled(false);
}
@@ -195,8 +194,8 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
}
}.execute();
}
- catch (Exception e) {
- e.printStackTrace();
+ catch (RuntimeException e) {
+ Logger.getInstance(SearchDialog.class).error(e);
}
}
}, 500);
@@ -498,7 +497,7 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
final UsageViewContext context = createUsageViewContext(config);
final UsageViewPresentation presentation = new UsageViewPresentation();
- presentation.setOpenInNewTab(openInNewTab.isSelected());
+ presentation.setOpenInNewTab(FindSettings.getInstance().isShowResultsInSeparateView());
presentation.setScopeText(config.getMatchOptions().getScope().getDisplayName());
context.configure(presentation);
@@ -635,7 +634,7 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
openInNewTab = new JCheckBox(FindBundle.message("find.open.in.new.tab.checkbox"));
- openInNewTab.setSelected(ourOpenInNewTab);
+ openInNewTab.setSelected(FindSettings.getInstance().isShowResultsInSeparateView());
ToolWindow findWindow = ToolWindowManager.getInstance(searchContext.getProject()).getToolWindow(ToolWindowId.FIND);
openInNewTab.setEnabled(findWindow != null && findWindow.isAvailable());
panel.add(openInNewTab, BorderLayout.EAST);
@@ -868,8 +867,9 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator
super.doOKAction();
if (!myRunFindActionOnClose) return;
- FindSettings.getInstance().setDefaultScopeName(selectedScope.getDisplayName());
- ourOpenInNewTab = openInNewTab.isSelected();
+ final FindSettings findSettings = FindSettings.getInstance();
+ findSettings.setDefaultScopeName(selectedScope.getDisplayName());
+ findSettings.setShowResultsInSeparateView(openInNewTab.isSelected());
try {
if (model.getShadowConfig() != null) {
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 e2c16bfbc355..7521b9bbc014 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UIUtil.java
@@ -3,7 +3,6 @@ package com.intellij.structuralsearch.plugin.ui;
import com.intellij.codeInsight.hint.TooltipController;
import com.intellij.codeInsight.hint.TooltipGroup;
import com.intellij.codeInsight.template.TemplateContextType;
-import com.intellij.codeInsight.template.impl.TemplateContext;
import com.intellij.codeInsight.template.impl.TemplateEditorUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
@@ -77,12 +76,8 @@ public class UIUtil {
else {
((EditorEx)editor).setEmbeddedIntoDialogWrapper(true);
}
-
- if (contextType != null) {
- TemplateContext context = new TemplateContext();
- context.setEnabled(contextType, true);
- TemplateEditorUtil.setHighlighter(editor, context);
- }
+
+ TemplateEditorUtil.setHighlighter(editor, contextType);
if (addToolTipForVariableHandler) {
SubstitutionShortInfoHandler handler = new SubstitutionShortInfoHandler(editor);
@@ -222,11 +217,6 @@ public class UIUtil {
}
public static void updateHighlighter(Editor editor, StructuralSearchProfile profile) {
- final TemplateContextType contextType = profile.getTemplateContextType();
- if (contextType != null) {
- TemplateContext context = new TemplateContext();
- context.setEnabled(contextType, true);
- TemplateEditorUtil.setHighlighter(editor, context);
- }
+ TemplateEditorUtil.setHighlighter(editor, profile.getTemplateContextType());
}
}
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 a55a16d4c379..e492906f0d4f 100644
--- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/UsageViewContext.java
@@ -8,9 +8,13 @@ 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.structuralsearch.MatchOptions;
import com.intellij.structuralsearch.SSRBundle;
import com.intellij.structuralsearch.plugin.replace.ui.ReplaceCommand;
-import com.intellij.usages.*;
+import com.intellij.usages.ConfigurableUsageTarget;
+import com.intellij.usages.Usage;
+import com.intellij.usages.UsageView;
+import com.intellij.usages.UsageViewPresentation;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -61,20 +65,15 @@ public class UsageViewContext {
return new SearchCommand(mySearchContext.getProject(), this);
}
- protected String _getPresentableText() {
- return myConfiguration.getMatchOptions().getSearchPattern();
- }
-
- public UsageTarget getTarget() {
- return new MyUsageTarget(_getPresentableText());
+ public ConfigurableUsageTarget getTarget() {
+ return new MyUsageTarget();
}
public void configure(@NotNull UsageViewPresentation presentation) {
- String s = _getPresentableText();
- if (s.length() > 15) s = s.substring(0,15) + "...";
- final String usagesString = SSRBundle.message("occurrences.of", s);
- presentation.setUsagesString(usagesString);
- presentation.setTabText(StringUtil.capitalize(usagesString));
+ final String pattern = myConfiguration.getMatchOptions().getSearchPattern();
+ final String usagesString = SSRBundle.message("occurrences.of", StringUtil.shortenTextWithEllipsis(pattern, 50, 0, true));
+ presentation.setUsagesString(SSRBundle.message("occurrences.of", pattern));
+ presentation.setTabText(usagesString);
presentation.setUsagesWord(SSRBundle.message("occurrence"));
presentation.setCodeUsagesString(SSRBundle.message("found.occurrences"));
}
@@ -82,15 +81,12 @@ public class UsageViewContext {
protected void configureActions() {}
private class MyUsageTarget implements ConfigurableUsageTarget,ItemPresentation {
- private final String myPresentableText;
-
- MyUsageTarget(String str) {
- myPresentableText = str;
- }
+ @NotNull
@Override
public String getPresentableText() {
- return myPresentableText;
+ final MatchOptions matchOptions = myConfiguration.getMatchOptions();
+ return SSRBundle.message("occurrences.of.0.in.1", matchOptions.getSearchPattern(), matchOptions.getScope().getDisplayName());
}
@Override
@@ -177,7 +173,7 @@ public class UsageViewContext {
@NotNull
@Override
public String getLongDescriptiveName() {
- return _getPresentableText();
+ return getPresentableText();
}
}
}
diff --git a/platform/structuralsearch/source/messages/SSRBundle.properties b/platform/structuralsearch/source/messages/SSRBundle.properties
index bfd12890ffb9..97baac9bf247 100644
--- a/platform/structuralsearch/source/messages/SSRBundle.properties
+++ b/platform/structuralsearch/source/messages/SSRBundle.properties
@@ -31,9 +31,10 @@ search.dialog.file.dialect.label=D&ialect:
#search usage view specific
looking.in.progress.message=Looking in {0}
found.progress.message=Found {0} occurrences
-occurrences.of=occurrences of {0}
+occurrences.of=Occurrences of ''{0}''
+occurrences.of.0.in.1=Occurrences of ''{0}'' in {1}
occurrence=occurrence
-found.occurrences=Found occurrence
+found.occurrences=Found occurrences
# search dialog messages
this.pattern.is.malformed.message=This pattern is malformed\n {0}
@@ -48,7 +49,6 @@ selecttemplate.template.label.please.select.template=<html><body><center>Please
# Replace Dialog specific titles/options
structural.replace.title=Structural Replace
shorten.fully.qualified.names.checkbox=Sh&orten fully qualified names
-format.according.to.style.checkbox=Fo&rmat according to style
replacement.template.label=Replacement template:
# Replace validation messages
diff --git a/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java b/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java
index 478c160b8c14..be7eb5453638 100644
--- a/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java
+++ b/platform/structure-view-impl/src/com/intellij/ide/util/treeView/smartTree/SmartTreeStructure.java
@@ -36,6 +36,12 @@ public class SmartTreeStructure extends AbstractTreeStructure {
@Override
public void commit() {
+ PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+ }
+
+ @Override
+ public boolean hasSomethingToCommit() {
+ return PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments();
}
@Override
@@ -71,11 +77,6 @@ public class SmartTreeStructure extends AbstractTreeStructure {
return ((AbstractTreeNode)element).isAlwaysLeaf();
}
- @Override
- public boolean hasSomethingToCommit() {
- return PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments();
- }
-
public void rebuildTree() {
((CachingChildrenTreeNode)getRootElement()).rebuildChildren();
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/MockSchemesManagerFactory.java b/platform/testFramework/src/com/intellij/testFramework/MockSchemesManagerFactory.java
index b74bb8e204b5..ab5ee3d9f7c6 100644
--- a/platform/testFramework/src/com/intellij/testFramework/MockSchemesManagerFactory.java
+++ b/platform/testFramework/src/com/intellij/testFramework/MockSchemesManagerFactory.java
@@ -2,16 +2,19 @@ package com.intellij.testFramework;
import com.intellij.openapi.components.RoamingType;
import com.intellij.openapi.options.*;
+import org.jetbrains.annotations.NotNull;
public class MockSchemesManagerFactory extends SchemesManagerFactory {
@Override
- public <T extends Scheme,E extends ExternalizableScheme> SchemesManager<T,E> createSchemesManager(final String fileSpec,
- final SchemeProcessor<E> processor, final RoamingType roamingType) {
+ public <T extends Scheme, E extends ExternalizableScheme> SchemesManager<T, E> createSchemesManager(@NotNull String fileSpec,
+ @NotNull SchemeProcessor<E> processor,
+ @NotNull RoamingType roamingType) {
+ //noinspection unchecked
return SchemesManager.EMPTY;
}
@Override
public void updateConfigFilesFromStreamProviders() {
-
+
}
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
index d9b32080f458..ea7a7c0deed1 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
@@ -141,7 +141,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
}
private static final String[] PREFIX_CANDIDATES = {
- "AppCode", "CppIde", "CidrCommon",
+ "AppCode", "CLion", "CidrCommon",
"Python", "PyCharmCore", "Ruby", "UltimateLangXml", "Idea" };
public static void autodetectPlatformPrefix() {
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
index 307fb65e5ef1..ee6e519cb583 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestUtil.java
@@ -52,6 +52,7 @@ import com.intellij.util.io.ZipUtil;
import com.intellij.util.ui.UIUtil;
import junit.framework.AssertionFailedError;
import org.jdom.Element;
+import org.jdom.JDOMException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -752,6 +753,18 @@ public class PlatformTestUtil {
}
}
+ public static void assertElementEquals(final String expected, final Element actual) {
+ try {
+ assertElementsEqual(JDOMUtil.loadDocument(expected).getRootElement(), actual);
+ }
+ catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ catch (JDOMException e) {
+ throw new AssertionError(e);
+ }
+ }
+
public static String printElement(final Element element) throws IOException {
final StringWriter writer = new StringWriter();
JDOMUtil.writeElement(element, writer, "\n");
diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformUltraLiteTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/PlatformUltraLiteTestFixture.java
index 5b01cf414149..ee6c3bd68304 100644
--- a/platform/testFramework/src/com/intellij/testFramework/PlatformUltraLiteTestFixture.java
+++ b/platform/testFramework/src/com/intellij/testFramework/PlatformUltraLiteTestFixture.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,10 +15,10 @@
*/
package com.intellij.testFramework;
-import com.intellij.mock.MockApplication;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.util.Disposer;
import org.jetbrains.annotations.NotNull;
@@ -28,21 +28,19 @@ public class PlatformUltraLiteTestFixture {
return new PlatformUltraLiteTestFixture();
}
- private Disposable myAppDisposable = null;
+ private final Disposable myAppDisposable = Disposer.newDisposable();
private PlatformUltraLiteTestFixture() { }
public void setUp() {
final Application application = ApplicationManager.getApplication();
if (application == null) {
- myAppDisposable = Disposer.newDisposable();
- ApplicationManager.setApplication(new MockApplication(myAppDisposable), myAppDisposable);
+ ApplicationImpl testapp = new ApplicationImpl(false, true, true, true, "testapp", null);
+ ApplicationManager.setApplication(testapp, myAppDisposable);
}
}
public void tearDown() {
- if (myAppDisposable != null) {
- Disposer.dispose(myAppDisposable);
- }
+ Disposer.dispose(myAppDisposable);
}
}
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 449b1bacf8e9..8aafb17da1de 100644
--- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
+++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
@@ -576,6 +576,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
@Override
public void launchAction(@NotNull final IntentionAction action) {
ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
+ UIUtil.dispatchAllInvocationEvents();
}
@Override
@@ -1424,6 +1425,8 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
}
}
+ PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+
if (myCaresAboutInjection) {
setupEditorForInjectedLanguage();
}
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java
index 2ecb0fca32cd..839568b4c2a9 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java
@@ -52,6 +52,10 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro
public abstract AbstractTestProxy getSelectedTest(@NotNull TreePath selectionPath);
+ protected TestFrameworkRunningModel getTestFrameworkRunningModel() {
+ return myModel;
+ }
+
@Nullable
public AbstractTestProxy getSelectedTest() {
TreePath[] paths = getSelectionPaths();
diff --git a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java
index 44e33ef3632a..ac4079d1309e 100644
--- a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java
+++ b/platform/usageView/src/com/intellij/usages/impl/GroupNode.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.
@@ -294,8 +294,8 @@ public class GroupNode extends Node implements Navigatable, Comparable<GroupNode
protected boolean isDataReadOnly() {
Enumeration enumeration = children();
while (enumeration.hasMoreElements()) {
- Node node = (Node)enumeration.nextElement();
- if (node.isReadOnly()) return true;
+ Object element = enumeration.nextElement();
+ if (element instanceof Node && ((Node)element).isReadOnly()) return true;
}
return false;
}
diff --git a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
index 170d1802eee4..8771ef75502b 100644
--- a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
+++ b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java
@@ -327,7 +327,7 @@ class SearchForUsagesRunnable implements Runnable {
@Override
public void run() {
notifyByFindBalloon(null, MessageType.WARNING, myProcessPresentation, myProject,
- Collections.singletonList(UsageViewManagerImpl.getProgressTitle(myPresentation)));
+ Collections.singletonList(StringUtil.escapeXml(UsageViewManagerImpl.getProgressTitle(myPresentation))));
findStartedBalloonShown.set(true);
}
}, 300, ModalityState.NON_MODAL);
diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
index b9fc77295d62..a33bc9e48437 100644
--- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
+++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java
@@ -196,8 +196,7 @@ public class UsageViewManagerImpl extends UsageViewManager {
public static String getProgressTitle(@NotNull UsageViewPresentation presentation) {
final String scopeText = presentation.getScopeText();
String usagesString = StringUtil.capitalize(presentation.getUsagesString());
- String result = UsageViewBundle.message("progress.searching.for.in", usagesString, scopeText);
- return StringUtil.escapeXml(result);
+ return UsageViewBundle.message("progress.searching.for.in", usagesString, scopeText);
}
void showToolWindow(boolean activateWindow) {
diff --git a/platform/util-rt/src/com/intellij/openapi/util/Conditions.java b/platform/util-rt/src/com/intellij/openapi/util/Conditions.java
index 791a5a9756dd..48bb06ad8b8e 100644
--- a/platform/util-rt/src/com/intellij/openapi/util/Conditions.java
+++ b/platform/util-rt/src/com/intellij/openapi/util/Conditions.java
@@ -34,10 +34,18 @@ public class Conditions {
return (Condition<T>)FALSE;
}
+ public static <T> Condition<T> instanceOf(final Class<?> clazz) {
+ return new Condition<T>() {
+ public boolean value(T t) {
+ return clazz.isInstance(t);
+ }
+ };
+ }
+
public static <T> Condition<T> is(final T option) {
return new Condition<T>() {
public boolean value(T t) {
- return t == option;
+ return Comparing.equal(t, option);
}
};
}
diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties
index e9802f2321ae..11ace8a42cad 100644
--- a/platform/util/resources/misc/registry.properties
+++ b/platform/util/resources/misc/registry.properties
@@ -58,7 +58,7 @@ ide.checkDuplicateMnemonics.description=Check for duplicate mnemonics.
ide.dnd.textHints=false
ide.max.recent.projects=25
-ide.hide.excluded.files=true
+ide.hide.excluded.files=false
ide.hide.excluded.files.restartRequired=true
ide.hide.excluded.files.description=Do not show excluded files in Project View and exclude them from VCS
@@ -122,7 +122,7 @@ editor.use.scrollable.tabs=true
editor.smarterSelectionQuoting=true
editor.skip.copy.and.cut.for.empty.selection=false
editor.distraction.free.mode=false
-
+editor.use.preview=false
editor.add.carets.on.double.control.arrows=true
ide.showIndexRebuildMessage=false
@@ -150,7 +150,6 @@ ide.perProjectModality.description=New modality approach. All dialogs are DOCUME
ide.mac.retina.disableDrawingFix=false
-ide.new.preferences=false
ide.new.license.dialog=true
debugger.valueTooltipAutoShow=true
@@ -160,6 +159,8 @@ debugger.breakpoint.message.full.trace=false
debugger.breakpoint.message.full.trace.description='Log message to console' breakpoint action will out full stacktrace\
for the thread that hit the breakpoint.
debugger.batch.evaluation=false
+debugger.compiling.evaluator=false
+debugger.watches.in.variables=false
analyze.exceptions.on.the.fly=false
analyze.exceptions.on.the.fly.description=Automatically analyze clipboard on frame activation,\
@@ -320,6 +321,7 @@ diff.status.tracker.skip.spaces=true
svn.use.terminal=false
svn.use.incoming.optimization=false
svn.executable.locale=C.UTF-8
+svn.lowest.supported.format.for.command.line=1.7.0
completion.enable.relevant.method.chain.suggestions=false
ide.mac.message.sheets.java.emulation=false
@@ -354,8 +356,10 @@ embed.scene.builder=true
dsm.retina.darcula.legend=true
dsm.retina.darcula.legend.description=Experimental DSM legend component
-ide.scratch.enabled=false
-ide.show.progress.without.status.bar=false
+ide.scratch.enabled=true
+ide.scratch.enabled.description=Disables Tools > Scratchpad: temporary editor without persistence
+ide.show.progress.without.status.bar=true
+ide.show.progress.without.status.bar.description=Disables transparent progress indicator when status bar is switched off
editor.injected.highlighting.enabled=true
editor.injected.highlighting.enabled.description=Disables injected fragments highlighting (requires project reopening)
@@ -393,8 +397,8 @@ console.too.much.text.buffer.ratio=10
console.too.much.text.buffer.ratio.description=Used for disabling of console processing(console filters for highlights, foldings...),\n\
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.file.settings.tree.new=false
+ide.new.settings.dialog=true
+ide.new.settings.dialog.description=New settings dialog
ide.new.project.settings=true
ide.new.project.settings.description=Temporary key for new project settings dialog UI
diff --git a/platform/util/src/com/intellij/diagnostic/ThreadDumper.java b/platform/util/src/com/intellij/diagnostic/ThreadDumper.java
index ede7cddbd5c5..a67cc6cbdc31 100644
--- a/platform/util/src/com/intellij/diagnostic/ThreadDumper.java
+++ b/platform/util/src/com/intellij/diagnostic/ThreadDumper.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.
@@ -24,6 +24,8 @@ import java.io.Writer;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
+import java.util.Arrays;
+import java.util.Comparator;
/**
* @author yole
@@ -44,7 +46,7 @@ public class ThreadDumper {
boolean dumpSuccessful = false;
try {
- ThreadInfo[] threads = threadMXBean.dumpAllThreads(false, false);
+ ThreadInfo[] threads = sort(threadMXBean.dumpAllThreads(false, false));
for(ThreadInfo info: threads) {
if (info != null) {
if (info.getThreadName().equals("AWT-EventQueue-1")) {
@@ -61,7 +63,7 @@ public class ThreadDumper {
if (!dumpSuccessful) {
final long[] threadIds = threadMXBean.getAllThreadIds();
- final ThreadInfo[] threadInfo = threadMXBean.getThreadInfo(threadIds, Integer.MAX_VALUE);
+ final ThreadInfo[] threadInfo = sort(threadMXBean.getThreadInfo(threadIds, Integer.MAX_VALUE));
for (ThreadInfo info : threadInfo) {
if (info != null) {
if (info.getThreadName().equals("AWT-EventQueue-1")) {
@@ -75,6 +77,25 @@ public class ThreadDumper {
return edtStack;
}
+ private static ThreadInfo[] sort(ThreadInfo[] threads) {
+ Arrays.sort(threads, new Comparator<ThreadInfo>() {
+ @Override
+ public int compare(ThreadInfo o1, ThreadInfo o2) {
+ final String t1 = o1.getThreadName();
+ final String t2 = o2.getThreadName();
+ if (t1.startsWith("AWT-EventQueue")) return -1;
+ if (t2.startsWith("AWT-EventQueue")) return 1;
+ final boolean r1 = o1.getThreadState() == Thread.State.RUNNABLE;
+ final boolean r2 = o2.getThreadState() == Thread.State.RUNNABLE;
+ if (r1 && !r2) return -1;
+ if (r2 && !r1) return 1;
+ return 0;
+ }
+ });
+
+ return threads;
+ }
+
private static void dumpThreadInfo(final ThreadInfo info, final Writer f) {
dumpCallStack(info, f, info.getStackTrace());
}
diff --git a/platform/util/src/com/intellij/icons/AllIcons.java b/platform/util/src/com/intellij/icons/AllIcons.java
index 318895db57f1..a80ffccdd58e 100644
--- a/platform/util/src/com/intellij/icons/AllIcons.java
+++ b/platform/util/src/com/intellij/icons/AllIcons.java
@@ -74,9 +74,9 @@ 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 GroupByClass = IconLoader.getIcon("/actions/GroupByClass.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 GroupByClass = IconLoader.getIcon("/actions/GroupByClass.png"); // 16x16
public static final Icon GroupByModule = IconLoader.getIcon("/actions/GroupByModule.png"); // 16x16
public static final Icon GroupByModuleGroup = IconLoader.getIcon("/actions/GroupByModuleGroup.png"); // 16x16
public static final Icon GroupByPackage = IconLoader.getIcon("/actions/GroupByPackage.png"); // 16x16
@@ -833,6 +833,7 @@ public class AllIcons {
public static final Icon Method = IconLoader.getIcon("/nodes/method.png"); // 16x16
public static final Icon Module = IconLoader.getIcon("/nodes/Module.png"); // 16x16
public static final Icon ModuleGroup = IconLoader.getIcon("/nodes/moduleGroup.png"); // 16x16
+ public static final Icon NativeLibrariesFolder = IconLoader.getIcon("/nodes/nativeLibrariesFolder.png"); // 16x16
public static final Icon NewException = IconLoader.getIcon("/nodes/newException.png"); // 14x14
public static final Icon NewFolder = IconLoader.getIcon("/nodes/newFolder.png"); // 16x16
public static final Icon NewParameter = IconLoader.getIcon("/nodes/newParameter.png"); // 14x14
diff --git a/platform/util/src/com/intellij/openapi/application/PathManager.java b/platform/util/src/com/intellij/openapi/application/PathManager.java
index 4001fd0138ef..9956959f0e22 100644
--- a/platform/util/src/com/intellij/openapi/application/PathManager.java
+++ b/platform/util/src/com/intellij/openapi/application/PathManager.java
@@ -418,7 +418,7 @@ public class PathManager {
private static String getAbsolutePath(String path) {
path = FileUtil.expandUserHome(path);
- return new File(path).getAbsolutePath();
+ return FileUtil.toCanonicalPath(new File(FileUtil.toCanonicalPath(path)).getAbsolutePath());
}
private static String trimPathQuotes(String path){
diff --git a/platform/util/src/com/intellij/openapi/diagnostic/Logger.java b/platform/util/src/com/intellij/openapi/diagnostic/Logger.java
index f3da0c22fde5..d90876fe6be9 100644
--- a/platform/util/src/com/intellij/openapi/diagnostic/Logger.java
+++ b/platform/util/src/com/intellij/openapi/diagnostic/Logger.java
@@ -69,6 +69,7 @@ public abstract class Logger {
return ourFactory.getLoggerInstance(category);
}
+ @NotNull
public static Logger getInstance(Class cl) {
return getInstance("#" + cl.getName());
}
diff --git a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
index 2cd5ed09bfdc..c82ee6df346b 100644
--- a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java
@@ -204,34 +204,34 @@ public class JDOMUtil {
@NotNull
private static String intern(@NotNull final StringInterner interner, @NotNull final String s) {
- synchronized (interner) {
- return interner.intern(s);
- }
+ return interner.intern(s);
}
@NotNull
- public static String legalizeText(@NotNull final String str) {
- StringReader reader = new StringReader(str);
- StringBuilder result = new StringBuilder();
-
- while(true) {
- try {
- int each = reader.read();
- if (each == -1) break;
+ public static String legalizeText(@NotNull String str) {
+ return legalizeChars(str).toString();
+ }
- if (Verifier.isXMLCharacter(each)) {
- result.append((char)each);
- } else {
- result.append("0x").append(StringUtil.toUpperCase(Long.toHexString(each)));
- }
- }
- catch (IOException ignored) {
- }
+ @NotNull
+ public static CharSequence legalizeChars(@NotNull CharSequence str) {
+ StringBuilder result = new StringBuilder(str.length());
+ for (int i = 0, len = str.length(); i < len; i ++) {
+ appendLegalized(result, str.charAt(i));
}
-
- return result.toString().replaceAll("<", "&lt;").replaceAll(">", "&gt;");
+ return result;
}
+ public static void appendLegalized(@NotNull StringBuilder sb, char each) {
+ if (each == '<' || each == '>') {
+ sb.append(each == '<' ? "&lt;" : "&gt;");
+ }
+ else if (!Verifier.isXMLCharacter(each)) {
+ sb.append("0x").append(StringUtil.toUpperCase(Long.toHexString(each)));
+ }
+ else {
+ sb.append(each);
+ }
+ }
private static class EmptyTextFilter implements Filter {
@Override
diff --git a/platform/util/src/com/intellij/openapi/util/LowMemoryWatcher.java b/platform/util/src/com/intellij/openapi/util/LowMemoryWatcher.java
index 33bd953d422f..f6c7b924590a 100644
--- a/platform/util/src/com/intellij/openapi/util/LowMemoryWatcher.java
+++ b/platform/util/src/com/intellij/openapi/util/LowMemoryWatcher.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.util;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.containers.WeakList;
@@ -93,10 +94,29 @@ public class LowMemoryWatcher {
}, null, null);
}
+ /**
+ * Registers a runnable to run on low memory events
+ * @return a LowMemoryWatcher instance holding the runnable. This instance should be kept in memory while the
+ * low memory notification functionality is needed. As soon as it's garbage-collected, the runnable won't receive any further notifications.
+ */
public static LowMemoryWatcher register(Runnable runnable) {
return new LowMemoryWatcher(runnable);
}
+ /**
+ * Registers a runnable to run on low memory events. The notifications will be issued until parentDisposable is disposed.
+ */
+ public static void register(Runnable runnable, Disposable parentDisposable) {
+ final Ref<LowMemoryWatcher> watcher = Ref.create(new LowMemoryWatcher(runnable));
+ Disposer.register(parentDisposable, new Disposable() {
+ @Override
+ public void dispose() {
+ watcher.get().stop();
+ watcher.set(null);
+ }
+ });
+ }
+
private LowMemoryWatcher(Runnable runnable) {
myRunnable = runnable;
ourInstances.add(this);
diff --git a/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java b/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java
index 96eefe8ddf78..d604d5f41ed1 100644
--- a/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java
+++ b/platform/util/src/com/intellij/openapi/util/NotNullLazyValue.java
@@ -38,6 +38,7 @@ public abstract class NotNullLazyValue<T> {
return myValue;
}
+ @NotNull
public static <T> NotNullLazyValue<T> createConstantValue(@NotNull final T value) {
return new NotNullLazyValue<T>() {
@NotNull
diff --git a/platform/util/src/com/intellij/openapi/util/Ref.java b/platform/util/src/com/intellij/openapi/util/Ref.java
index d35b39de264b..0119c5626bf7 100644
--- a/platform/util/src/com/intellij/openapi/util/Ref.java
+++ b/platform/util/src/com/intellij/openapi/util/Ref.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.util;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -49,6 +50,7 @@ public class Ref<T> {
return false;
}
+ @NotNull
public static <T> Ref<T> create() {
return new Ref<T>();
}
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 adec13d20412..7d3d6f557249 100644
--- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java
@@ -848,9 +848,10 @@ public class FileUtil extends FileUtilRt {
}
public static boolean isFilePathAcceptable(@NotNull File root, @Nullable FileFilter fileFilter) {
+ if (fileFilter == null) return true;
File file = root;
do {
- if (fileFilter != null && !fileFilter.accept(file)) return false;
+ if (!fileFilter.accept(file)) return false;
file = file.getParentFile();
}
while (file != null);
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 e364a8568fda..af2b3dd4293e 100644
--- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java
+++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.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.
@@ -96,7 +96,7 @@ public class StringUtil extends StringUtilRt {
@Nullable
@Override
public String fun(@Nullable String s) {
- return s == null ? null : s.trim();
+ return trim(s);
}
};
@@ -246,6 +246,7 @@ public class StringUtil extends StringUtilRt {
return html.replaceAll("<(.|\n)*?>", "");
}
+ @Contract("null -> null; !null -> !null")
public static String toLowerCase(@Nullable final String str) {
//noinspection ConstantConditions
return str == null ? null : str.toLowerCase();
@@ -852,6 +853,11 @@ public class StringUtil extends StringUtilRt {
return startsWithConcatenation(string, firstPrefix, secondPrefix, thirdPrefix);
}
+ @Contract("null -> null; !null -> !null")
+ public static String trim(@Nullable String s) {
+ return s == null ? null : s.trim();
+ }
+
@NotNull
public static String trimEnd(@NotNull String s, @NonNls @NotNull String suffix) {
if (s.endsWith(suffix)) {
@@ -1467,7 +1473,7 @@ public class StringUtil extends StringUtilRt {
/**
* @deprecated use #capitalize(String)
*/
- @Nullable
+ @Contract("null -> null; !null -> !null")
public static String firstLetterToUpperCase(@Nullable final String displayString) {
if (displayString == null || displayString.isEmpty()) return displayString;
char firstChar = displayString.charAt(0);
@@ -1827,11 +1833,13 @@ public class StringUtil extends StringUtilRt {
@NonNls private static final String[] REPLACES_REFS = {"&lt;", "&gt;", "&amp;", "&#39;", "&quot;"};
@NonNls private static final String[] REPLACES_DISP = {"<", ">", "&", "'", "\""};
+ @Contract("null -> null; !null -> !null")
public static String unescapeXml(@Nullable final String text) {
if (text == null) return null;
return replace(text, REPLACES_REFS, REPLACES_DISP);
}
+ @Contract("null -> null; !null -> !null")
public static String escapeXml(@Nullable final String text) {
if (text == null) return null;
return replace(text, REPLACES_DISP, REPLACES_REFS);
diff --git a/platform/util/src/com/intellij/util/ArrayUtil.java b/platform/util/src/com/intellij/util/ArrayUtil.java
index 5de68c11799b..d0419de9e820 100644
--- a/platform/util/src/com/intellij/util/ArrayUtil.java
+++ b/platform/util/src/com/intellij/util/ArrayUtil.java
@@ -190,7 +190,7 @@ public class ArrayUtil extends ArrayUtilRt {
}
@NotNull
- public static int[] toIntArray(@NotNull List<Integer> list) {
+ public static int[] toIntArray(@NotNull Collection<Integer> list) {
int[] ret = newIntArray(list.size());
int i = 0;
for (Integer e : list) {
diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java
index 1d7016460f1e..19961bfc0b89 100644
--- a/platform/util/src/com/intellij/util/EnvironmentUtil.java
+++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java
@@ -255,6 +255,24 @@ public class EnvironmentUtil {
return getEnvironmentMap();
}
+ public static void inlineParentOccurrences(@NotNull Map<String, String> envs) {
+ Map<String, String> parentParams = new HashMap<String, String>(System.getenv());
+ for (Map.Entry<String, String> entry : envs.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+ if (value != null) {
+ String parentVal = parentParams.get(key);
+ if (parentVal != null && containsEnvKeySubstitution(key, value)) {
+ envs.put(key, value.replace("$" + key + "$", parentVal));
+ }
+ }
+ }
+ }
+
+ private static boolean containsEnvKeySubstitution(final String envKey, final String val) {
+ return ArrayUtil.find(val.split(File.pathSeparator), "$" + envKey + "$") != -1;
+ }
+
@TestOnly
static Map<String, String> testLoader() {
try {
diff --git a/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java b/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java
index 2ef9cfbedc61..cdc892071e01 100644
--- a/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java
+++ b/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.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.
@@ -46,8 +46,9 @@ public class BoundedTaskExecutor implements Executor {
}
};
- public BoundedTaskExecutor(Executor backendExecutor, int maxSimultaneousTasks) {
+ public BoundedTaskExecutor(@NotNull Executor backendExecutor, int maxSimultaneousTasks) {
myBackendExecutor = backendExecutor;
+ assert maxSimultaneousTasks >= 1 : maxSimultaneousTasks;
myMaxTasks = Math.max(maxSimultaneousTasks, 1);
}
@@ -56,7 +57,8 @@ public class BoundedTaskExecutor implements Executor {
submit(task);
}
- public Future<?> submit(Runnable task) {
+ @NotNull
+ public Future<?> submit(@NotNull Runnable task) {
final RunnableFuture<Void> future = queueTask(new FutureTask<Void>(task, null));
if (future == null) {
throw new RuntimeException("Failed to queue task: " + task);
@@ -64,7 +66,8 @@ public class BoundedTaskExecutor implements Executor {
return future;
}
- public <T> Future<T> submit(Callable<T> task) {
+ @NotNull
+ public <T> Future<T> submit(@NotNull Callable<T> task) {
final RunnableFuture<T> future = queueTask(new FutureTask<T>(task));
if (future == null) {
throw new RuntimeException("Failed to queue task: " + task);
@@ -73,7 +76,7 @@ public class BoundedTaskExecutor implements Executor {
}
@Nullable
- private <T> RunnableFuture<T> queueTask(FutureTask<T> futureTask) {
+ private <T> RunnableFuture<T> queueTask(@NotNull FutureTask<T> futureTask) {
if (myTaskQueue.offer(futureTask)) {
processQueue();
return futureTask;
diff --git a/platform/util/src/com/intellij/util/concurrency/SequentialTaskExecutor.java b/platform/util/src/com/intellij/util/concurrency/SequentialTaskExecutor.java
index c05579c8f002..86fa72075e90 100644
--- a/platform/util/src/com/intellij/util/concurrency/SequentialTaskExecutor.java
+++ b/platform/util/src/com/intellij/util/concurrency/SequentialTaskExecutor.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.
@@ -16,11 +16,12 @@
package com.intellij.util.concurrency;
+import org.jetbrains.annotations.NotNull;
+
import java.util.concurrent.Executor;
public class SequentialTaskExecutor extends BoundedTaskExecutor {
-
- public SequentialTaskExecutor(Executor executor) {
+ public SequentialTaskExecutor(@NotNull Executor executor) {
super(executor, 1);
}
}
diff --git a/platform/util/src/com/intellij/util/containers/ConcurrentInstanceMap.java b/platform/util/src/com/intellij/util/containers/ConcurrentInstanceMap.java
index e99db9d1d2c3..4c85f15a8c7c 100644
--- a/platform/util/src/com/intellij/util/containers/ConcurrentInstanceMap.java
+++ b/platform/util/src/com/intellij/util/containers/ConcurrentInstanceMap.java
@@ -29,10 +29,10 @@ public class ConcurrentInstanceMap<T> extends ConcurrentFactoryMap<Class<? exten
return key.newInstance();
}
catch (InstantiationException e) {
- throw new RuntimeException(e);
+ throw new RuntimeException("Couldn't instantiate " + key, e);
}
catch (IllegalAccessException e) {
- throw new RuntimeException(e);
+ throw new RuntimeException("Couldn't instantiate " + key, e);
}
}
} \ No newline at end of file
diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
index dca7a0e6b30d..40bd75a2eff8 100644
--- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java
+++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java
@@ -1073,7 +1073,8 @@ public class ContainerUtil extends ContainerUtilRt {
}
public static <T, U extends T> U findInstance(@NotNull Iterator<T> iterator, @NotNull Class<U> aClass) {
- @SuppressWarnings("unchecked") U u = (U)find(iterator, new FilteringIterator.InstanceOf<U>(aClass));
+ //noinspection unchecked
+ U u = (U)find(iterator, FilteringIterator.instanceOf(aClass));
return u;
}
@@ -1429,6 +1430,16 @@ public class ContainerUtil extends ContainerUtilRt {
return sorted;
}
+ @NotNull
+ public static <T extends Comparable<T>> List<T> sorted(@NotNull Collection<T> list) {
+ return sorted(list, new Comparator<T>() {
+ @Override
+ public int compare(T o1, T o2) {
+ return o1.compareTo(o2);
+ }
+ });
+ }
+
public static <T> void sort(@NotNull T[] a, @NotNull Comparator<T> comparator) {
int size = a.length;
@@ -1927,6 +1938,15 @@ public class ContainerUtil extends ContainerUtilRt {
return -1;
}
+ public static <T> int indexOf(@NotNull List<T> list, @NotNull final T object) {
+ return indexOf(list, new Condition<T>() {
+ @Override
+ public boolean value(T t) {
+ return t.equals(object);
+ }
+ });
+ }
+
@NotNull
public static <A,B> Map<B,A> reverseMap(@NotNull Map<A,B> map) {
final Map<B,A> result = newHashMap();
diff --git a/platform/util/src/com/intellij/util/containers/FilteringIterator.java b/platform/util/src/com/intellij/util/containers/FilteringIterator.java
index c6b7173b4db2..3e146441d6ab 100644
--- a/platform/util/src/com/intellij/util/containers/FilteringIterator.java
+++ b/platform/util/src/com/intellij/util/containers/FilteringIterator.java
@@ -17,7 +17,6 @@ package com.intellij.util.containers;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
-import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
@@ -30,7 +29,7 @@ import java.util.NoSuchElementException;
*/
public class FilteringIterator<Dom, E extends Dom> implements Iterator<E> {
private final Iterator<Dom> myBaseIterator;
- private final Condition<Dom> myFilter;
+ private final Condition<? super Dom> myFilter;
private boolean myNextObtained = false;
private boolean myCurrentIsValid = false;
private Dom myCurrent;
@@ -42,7 +41,7 @@ public class FilteringIterator<Dom, E extends Dom> implements Iterator<E> {
}
};
- public FilteringIterator(@NotNull Iterator<Dom> baseIterator, @NotNull Condition<Dom> filter) {
+ public FilteringIterator(@NotNull Iterator<Dom> baseIterator, @NotNull Condition<? super Dom> filter) {
myBaseIterator = baseIterator;
myFilter = filter;
}
@@ -103,7 +102,7 @@ public class FilteringIterator<Dom, E extends Dom> implements Iterator<E> {
return create(iterator, NOT_NULL);
}
- public static <Dom, T extends Dom> Iterator<T> create(Iterator<Dom> iterator, Condition<Dom> condition) {
+ public static <Dom, T extends Dom> Iterator<T> create(Iterator<Dom> iterator, Condition<? super Dom> condition) {
return new FilteringIterator<Dom, T>(iterator, condition);
}
@@ -119,7 +118,7 @@ public class FilteringIterator<Dom, E extends Dom> implements Iterator<E> {
return create((Iterator<T>)iterator, instanceOf(aClass));
}
- public static class InstanceOf<T> implements Condition {
+ public static class InstanceOf<T> implements Condition<Object> {
private final Class<T> myInstancesClass;
public InstanceOf(Class<T> instancesClass) {
@@ -130,13 +129,5 @@ public class FilteringIterator<Dom, E extends Dom> implements Iterator<E> {
public boolean value(Object object) {
return myInstancesClass.isInstance(object);
}
-
- public boolean isClassAcceptable(Class hintClass) {
- return ReflectionUtil.isAssignable(myInstancesClass, hintClass);
- }
-
- public T cast(Object object) {
- return (T)object;
- }
}
}
diff --git a/platform/util/src/com/intellij/util/containers/InternalIterator.java b/platform/util/src/com/intellij/util/containers/InternalIterator.java
index 9b7d1da8f156..49c84ece6a48 100644
--- a/platform/util/src/com/intellij/util/containers/InternalIterator.java
+++ b/platform/util/src/com/intellij/util/containers/InternalIterator.java
@@ -70,10 +70,10 @@ public interface InternalIterator<T>{
}
class Filtering<T> implements InternalIterator<T> {
- private final Condition<T> myFilter;
+ private final Condition<? super T> myFilter;
private final InternalIterator<T> myIterator;
- public Filtering(InternalIterator<T> iterator, Condition<T> filter) {
+ public Filtering(InternalIterator<T> iterator, Condition<? super T> filter) {
myIterator = iterator;
myFilter = filter;
}
diff --git a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java
index 663cd215cfbe..0f14dcb8511b 100644
--- a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java
+++ b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java
@@ -20,7 +20,6 @@
package com.intellij.util.io.storage;
import com.intellij.openapi.Disposable;
-import com.intellij.openapi.util.Disposer;
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.NotNull;
@@ -56,10 +55,8 @@ public class HeavyProcessLatch {
public void processFinished();
}
- @NotNull
- public Disposable addListener(@NotNull HeavyProcessListener listener) {
- Disposable disposable = Disposer.newDisposable();
- myEventDispatcher.addListener(listener, disposable);
- return disposable;
+ public void addListener(@NotNull Disposable parentDisposable,
+ @NotNull HeavyProcessListener listener) {
+ myEventDispatcher.addListener(listener, parentDisposable);
}
} \ No newline at end of file
diff --git a/platform/util/src/com/intellij/util/xmlb/MapBinding.java b/platform/util/src/com/intellij/util/xmlb/MapBinding.java
index dbc3c0e082c3..354af5f93d7b 100644
--- a/platform/util/src/com/intellij/util/xmlb/MapBinding.java
+++ b/platform/util/src/com/intellij/util/xmlb/MapBinding.java
@@ -15,6 +15,7 @@
*/
package com.intellij.util.xmlb;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.xmlb.annotations.MapAnnotation;
@@ -34,6 +35,8 @@ import java.util.Set;
import static com.intellij.util.xmlb.Constants.*;
class MapBinding implements Binding {
+ private static final Logger LOG = Logger.getInstance(MapBinding.class);
+
private static final Comparator<Object> KEY_COMPARATOR = new Comparator<Object>() {
@SuppressWarnings("unchecked")
@Override
@@ -161,7 +164,10 @@ class MapBinding implements Binding {
Object k = null;
Object v = null;
- assert entry.getName().equals(getEntryAttributeName());
+ if (!entry.getName().equals(getEntryAttributeName())) {
+ LOG.warn("unexpected entry for serialized Map will be skipped: " + entry);
+ continue;
+ }
Attribute keyAttr = entry.getAttribute(getKeyAttributeName());
if (keyAttr != null) {
diff --git a/platform/util/src/com/intellij/util/xmlb/XmlSerializer.java b/platform/util/src/com/intellij/util/xmlb/XmlSerializer.java
index 86b7d111430f..73f216bc3749 100644
--- a/platform/util/src/com/intellij/util/xmlb/XmlSerializer.java
+++ b/platform/util/src/com/intellij/util/xmlb/XmlSerializer.java
@@ -45,6 +45,7 @@ public class XmlSerializer {
return serialize(object, TRUE_FILTER);
}
+ @NotNull
public static Element serialize(@NotNull Object object, @Nullable SerializationFilter filter) throws XmlSerializationException {
return new XmlSerializerImpl(filter == null ? TRUE_FILTER : filter).serialize(object);
}
diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
index 9a3fcb9d7066..8d0576c12405 100644
--- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
+++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java
@@ -23,6 +23,7 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.annotations.*;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
+import org.intellij.lang.annotations.Language;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -1133,6 +1134,24 @@ public class XmlSerializerTest extends TestCase {
bean);
}
+ public static class BeanWithMapAtTopLevel {
+ @Property(surroundWithTag = false)
+ @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false)
+ public Map<String, String> map = new HashMap<String, String>();
+
+ public String option;
+ }
+
+ public void testMapAtTopLevel() {
+ BeanWithMapAtTopLevel bean = new BeanWithMapAtTopLevel();
+ bean.map.put("a", "b");
+ bean.option = "xxx";
+ doSerializerTest("<BeanWithMapAtTopLevel>\n" +
+ " <entry key=\"a\" value=\"b\" />\n" +
+ " <option name=\"option\" value=\"xxx\" />\n" +
+ "</BeanWithMapAtTopLevel>", bean);
+ }
+
private static class BeanWithConverter {
private static class MyConverter extends Converter<Ref<String>> {
@Nullable
@@ -1193,7 +1212,7 @@ public class XmlSerializerTest extends TestCase {
return assertSerializer(bean, expected, "Serialization failure", filter);
}
- private static Object doSerializerTest(String expectedText, Object bean) {
+ private static Object doSerializerTest(@Language("XML") String expectedText, Object bean) {
try {
Element element = assertSerializer(bean, expectedText, null);
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java
index 6f5ea05abea3..28f162908a20 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsTaskHandler.java
@@ -17,16 +17,27 @@ package com.intellij.openapi.vcs;
import com.intellij.openapi.extensions.ExtensionPointName;
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 java.util.List;
+
/**
* @author Dmitry Avdeev
* Date: 16.07.13
*/
public abstract class VcsTaskHandler {
- public static VcsTaskHandler[] getAllHandlers(Project project) {
- return EXTENSION_POINT_NAME.getExtensions(project);
+ public static VcsTaskHandler[] getAllHandlers(final Project project) {
+ VcsTaskHandler[] extensions = EXTENSION_POINT_NAME.getExtensions(project);
+ List<VcsTaskHandler> handlers = ContainerUtil.filter(extensions, new Condition<VcsTaskHandler>() {
+ @Override
+ public boolean value(VcsTaskHandler handler) {
+ return handler.isEnabled(project);
+ }
+ });
+ return handlers.toArray(new VcsTaskHandler[handlers.size()]);
}
public static class TaskInfo {
@@ -49,6 +60,8 @@ public abstract class VcsTaskHandler {
private static final ExtensionPointName<VcsTaskHandler> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.vcs.taskHandler");
+ public abstract boolean isEnabled(Project project);
+
public abstract TaskInfo startNewTask(String taskName);
public abstract void switchToTask(TaskInfo taskInfo, Runnable invokeAfter);
diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManagerGate.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManagerGate.java
index 376188e477eb..d0c28f5583fc 100644
--- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManagerGate.java
+++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangeListManagerGate.java
@@ -15,7 +15,6 @@
*/
package com.intellij.openapi.vcs.changes;
-import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -39,8 +38,13 @@ public interface ChangeListManagerGate {
void editComment(final String name, final String comment);
void editName(final String oldName, final String newName);
- // must be allowed only for perforce change synchronizer, not during normal update
+
+
+ /**
+ * @deprecated unused, to be removed in IDEA 15
+ */
void moveChanges(final String toList, final Collection<Change> changes);
+
void setListsToDisappear(final Collection<String> names);
FileStatus getStatus(final VirtualFile file);
FileStatus getStatus(final File file);
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotifier.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotifier.java
index 4b7f6baf2616..985f383ecbc6 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotifier.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/VcsNotifier.java
@@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable;
public class VcsNotifier {
private static final NotificationGroup NOTIFICATION_GROUP_ID = NotificationGroup.toolWindowGroup(
- "Vcs Messages", ChangesViewContentManager.TOOLWINDOW_ID, true);
+ "Vcs Messages", ChangesViewContentManager.TOOLWINDOW_ID);
private static final NotificationGroup IMPORTANT_ERROR_NOTIFICATION = new NotificationGroup(
"Vcs Important Messages", NotificationDisplayType.STICKY_BALLOON, true);
private static final NotificationGroup MINOR_NOTIFICATION = new NotificationGroup(
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CallbackData.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CallbackData.java
index 8ad034cfee1b..c1d2d0049edb 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CallbackData.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/CallbackData.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.
@@ -24,8 +24,6 @@ import com.intellij.openapi.vcs.VcsBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
-
class CallbackData {
private final static Logger LOG = Logger.getInstance("com.intellij.openapi.vcs.changes.CallbackData");
private final Runnable myCallback;
@@ -50,7 +48,7 @@ class CallbackData {
return new CallbackData(new Runnable() {
public void run() {
if (mode.isCallbackOnAwt()) {
- SwingUtilities.invokeLater(new Runnable() {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
LOG.debug("invokeAfterUpdate: silent wrapper called for project: " + project.getName());
if (project.isDisposed()) return;
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
index 731634b85080..53092e6a1369 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesFragmentedDiffPanel.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.vcs.changes;
+import com.intellij.codeStyle.CodeStyleFacade;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
@@ -55,6 +56,7 @@ import com.intellij.util.BeforeAfter;
import com.intellij.util.PlatformIcons;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -152,87 +154,87 @@ public class ChangesFragmentedDiffPanel implements Disposable {
private void createNavigateAction() {
myNavigateAction = new DumbAwareAction("Edit Source", "Edit Source", AllIcons.Actions.EditSource) {
+ @Nullable
+ private OpenFileDescriptor createDescriptor() {
+ if (myFragmentedContent == null || myFragmentedContent.getFile() == null) return null;
+
+ final DiffPanel panel = myCurrentHorizontal ? myHorizontal : myVertical;
+ final DiffSideView side = ((DiffPanelImpl)panel).getCurrentSide();
+ if (side == null || side.getEditor() == null) return null;
+
+ final boolean isAfter = FragmentSide.SIDE2.equals(side.getSide());
+ if (isAfter) {
+ final LogicalPosition position = side.getEditor().getCaretModel().getLogicalPosition();
+ final int line = position.line;
+ final int converted = myFragmentedContent.getNewConvertor().execute(line);
+ return new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, position.column);
+ }
+
+ if (((DiffPanelImpl)panel).getEditor1().getDocument().getTextLength() == 0) {
+ return new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), 0);
+ }
+
+ final CaretModel model = side.getEditor().getCaretModel();
+ final FragmentList fragments = ((DiffPanelImpl)panel).getFragments();
+ final int line = model.getLogicalPosition().line;
+ //final int offset = side.getEditor().getDocument().getLineStartOffset(line);
+ final int offset = model.getOffset();
+
+ BeforeAfter<Integer> current = null;
+ final List<BeforeAfter<Integer>> ranges = myFragmentedContent.getLineRanges();
+ for (BeforeAfter<Integer> range : ranges) {
+ if (range.getBefore() > line) break;
+ current = range;
+ }
+ if (current == null) return null;
+ final Fragment at = fragments.getFragmentAt(offset, FragmentSide.SIDE1, Condition.TRUE);
+ if (at == null) return null;
+ final TextRange opposite = at.getRange(FragmentSide.SIDE2);
+
+ final int lineInNew = ((DiffPanelImpl)panel).getEditor2().getDocument().getLineNumber(opposite.getStartOffset());
+
+ int correctLine;
+ int column;
+ if (at.getType() == null || TextDiffTypeEnum.NONE.equals(at.getType())) {
+ column = model.getLogicalPosition().column;
+ final int startIn1 =
+ ((DiffPanelImpl)panel).getEditor1().getDocument().getLineNumber(at.getRange(FragmentSide.SIDE1).getStartOffset());
+ correctLine = lineInNew + line - startIn1;
+ }
+ else {
+ column = 0;
+ correctLine = Math.max(lineInNew, current.getAfter());
+ }
+
+ int converted = myFragmentedContent.getNewConvertor().execute(correctLine);
+ return new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, column);
+ }
+
@Override
public void actionPerformed(AnActionEvent e) {
- final boolean enabled = getEnabled();
- if (enabled) {
- OpenFileDescriptor descriptor = null;
- if (myFragmentedContent != null && myFragmentedContent.getFile() != null) {
- final DiffPanel panel = myCurrentHorizontal ? myHorizontal : myVertical;
-
- final DiffSideView side = ((DiffPanelImpl)panel).getCurrentSide();
- if (side == null || side.getEditor() == null) return;
-
- final boolean isAfter = FragmentSide.SIDE2.equals(side.getSide());
- if (isAfter) {
- final LogicalPosition position = side.getEditor().getCaretModel().getLogicalPosition();
- final int line = position.line;
- final int converted = myFragmentedContent.getNewConvertor().execute(line);
- descriptor = new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, position.column);
- } else {
- if (((DiffPanelImpl) panel).getEditor1().getDocument().getTextLength() == 0) {
- FileEditorManager.getInstance(myProject).openTextEditor(new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), 0),
- true);
- return;
- }
-
- final CaretModel model = side.getEditor().getCaretModel();
- final FragmentList fragments = ((DiffPanelImpl)panel).getFragments();
- final int line = model.getLogicalPosition().line;
- //final int offset = side.getEditor().getDocument().getLineStartOffset(line);
- final int offset = model.getOffset();
-
- BeforeAfter<Integer> current = null;
- final List<BeforeAfter<Integer>> ranges = myFragmentedContent.getLineRanges();
- for (BeforeAfter<Integer> range : ranges) {
- if (range.getBefore() > line) break;
- current = range;
- }
- if (current == null) return;
- final Fragment at = fragments.getFragmentAt(offset, FragmentSide.SIDE1, Condition.TRUE);
- if (at == null) return;
- final TextRange opposite = at.getRange(FragmentSide.SIDE2);
-
- final int lineInNew = ((DiffPanelImpl)panel).getEditor2().getDocument().getLineNumber(opposite.getStartOffset());
-
- int correctLine;
- int column;
- if (at.getType() == null || TextDiffTypeEnum.NONE.equals(at.getType())) {
- column = model.getLogicalPosition().column;
- final int startIn1 =
- ((DiffPanelImpl)panel).getEditor1().getDocument().getLineNumber(at.getRange(FragmentSide.SIDE1).getStartOffset());
- correctLine = lineInNew + line - startIn1;
- }
- else {
- column = 0;
- correctLine = Math.max(lineInNew, current.getAfter());
- }
-
- int converted = myFragmentedContent.getNewConvertor().execute(correctLine);
- descriptor = new OpenFileDescriptor(myProject, myFragmentedContent.getFile(), converted, column);
- }
+ if (!getEnabled()) return;
+ final OpenFileDescriptor descriptor = createDescriptor();
+ if (descriptor == null) return;
+
+ final Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ FileEditorManager.getInstance(myProject).openTextEditor(descriptor, true);
}
- if (descriptor == null) return;
- final OpenFileDescriptor finalDescriptor = descriptor;
- final Runnable runnable = new Runnable() {
- @Override
- public void run() {
- FileEditorManager.getInstance(myProject).openTextEditor(finalDescriptor, true);
- }
- };
- if (! ModalityState.NON_MODAL.equals(ModalityState.current())) {
- final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
- if (window instanceof DialogWrapperDialog) {
- final DialogWrapper wrapper = ((DialogWrapperDialog)window).getDialogWrapper();
- if (wrapper != null) {
- Disposer.dispose(wrapper.getDisposable());
- wrapper.close(DialogWrapper.CANCEL_EXIT_CODE);
- ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL, myProject.getDisposed());
- return;
- }
+ };
+
+ if (ModalityState.NON_MODAL.equals(ModalityState.current())) {
+ runnable.run();
+ }
+ else {
+ final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
+ if (window instanceof DialogWrapperDialog) {
+ final DialogWrapper wrapper = ((DialogWrapperDialog)window).getDialogWrapper();
+ if (wrapper != null) {
+ wrapper.doCancelAction();
+ ApplicationManager.getApplication().invokeLater(runnable, ModalityState.NON_MODAL, myProject.getDisposed());
}
}
- runnable.run();
}
}
@@ -280,15 +282,25 @@ public class ChangesFragmentedDiffPanel implements Disposable {
myTitleLabel.setText(titleText((DiffPanelImpl)currentPanel));
myLeftLines = state.getLeftLines();
+ EditorEx hEditor1 = (EditorEx)((DiffPanelImpl)myHorizontal).getEditor1();
+ EditorEx vEditor1 = (EditorEx)((DiffPanelImpl)myVertical).getEditor1();
+ EditorEx hEditor2 = (EditorEx)((DiffPanelImpl)myHorizontal).getEditor2();
+ EditorEx vEditor2 = (EditorEx)((DiffPanelImpl)myVertical).getEditor2();
+
+ assert hEditor1 != null;
+ assert vEditor1 != null;
+ assert hEditor2 != null;
+ assert vEditor2 != null;
+
FragmentedEditorHighlighter bh = fragmentedContent.getBeforeHighlighter();
if (bh != null) {
- ((EditorEx) ((DiffPanelImpl) myHorizontal).getEditor1()).setHighlighter(bh);
- ((EditorEx) ((DiffPanelImpl) myVertical).getEditor1()).setHighlighter(bh);
+ hEditor1.setHighlighter(bh);
+ vEditor1.setHighlighter(bh);
}
FragmentedEditorHighlighter ah = fragmentedContent.getAfterHighlighter();
if (ah != null) {
- ((EditorEx) ((DiffPanelImpl) myHorizontal).getEditor2()).setHighlighter(ah);
- ((EditorEx) ((DiffPanelImpl) myVertical).getEditor2()).setHighlighter(ah);
+ hEditor2.setHighlighter(ah);
+ vEditor2.setHighlighter(ah);
}
if (((DiffPanelImpl) currentPanel).getEditor1() != null) {
highlightTodo(true, fragmentedContent.getBeforeTodoRanges());
@@ -296,6 +308,19 @@ public class ChangesFragmentedDiffPanel implements Disposable {
if (((DiffPanelImpl) currentPanel).getEditor2() != null) {
highlightTodo(false, fragmentedContent.getAfterTodoRanges());
}
+ if (fragmentedContent.getFileType() != null && myProject != null && !myProject.isDisposed()) {
+ CodeStyleFacade codeStyleFacade = CodeStyleFacade.getInstance(myProject);
+ int tabSize = codeStyleFacade.getTabSize(fragmentedContent.getFileType());
+ boolean useTabCharacter = codeStyleFacade.useTabCharacter(fragmentedContent.getFileType());
+ hEditor1.getSettings().setTabSize(tabSize);
+ vEditor1.getSettings().setTabSize(tabSize);
+ hEditor2.getSettings().setTabSize(tabSize);
+ vEditor2.getSettings().setTabSize(tabSize);
+ hEditor1.getSettings().setUseTabCharacter(useTabCharacter);
+ vEditor1.getSettings().setUseTabCharacter(useTabCharacter);
+ hEditor2.getSettings().setUseTabCharacter(useTabCharacter);
+ vEditor2.getSettings().setUseTabCharacter(useTabCharacter);
+ }
ensurePresentation();
softWraps(myConfiguration.SOFT_WRAPS_IN_SHORT_DIFF);
}
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 6e8a1a04d135..2722239d33b7 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
@@ -398,4 +398,8 @@ public class PreparedFragmentedContent {
public VirtualFile getFile() {
return myFile;
}
+
+ public FileType getFileType() {
+ return myFileType;
+ }
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/CompoundShelfFileProcessor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/CompoundShelfFileProcessor.java
index cb073e2c129b..f060cca6368f 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/CompoundShelfFileProcessor.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/CompoundShelfFileProcessor.java
@@ -19,6 +19,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.components.RoamingType;
+import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.components.impl.stores.StorageUtil;
import com.intellij.openapi.components.impl.stores.StreamProvider;
import com.intellij.openapi.diagnostic.Logger;
@@ -36,6 +37,8 @@ import java.util.Collections;
import java.util.List;
public class CompoundShelfFileProcessor {
+ public static final String SHELF_DIR_NAME = "shelf";
+
private final String mySubdirName;
private final StreamProvider myServerStreamProvider;
private final String FILE_SPEC;
@@ -43,19 +46,20 @@ public class CompoundShelfFileProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.shelf.CompoundShelfFileProcessor");
- public CompoundShelfFileProcessor(final String subdirName) {
- mySubdirName = subdirName;
- myServerStreamProvider = ((ApplicationImpl)ApplicationManager.getApplication()).getStateStore().getStateStorageManager().getStreamProvider();
+ public CompoundShelfFileProcessor() {
+ this(PathManager.getConfigPath());
+ }
- FILE_SPEC = "$ROOT_CONFIG$/" + subdirName + "/";
- myShelfPath = PathManager.getConfigPath() + File.separator + mySubdirName;
+ public CompoundShelfFileProcessor(String shelfBaseDirPath) {
+ this(((ApplicationImpl)ApplicationManager.getApplication()).getStateStore().getStateStorageManager().getStreamProvider(),
+ shelfBaseDirPath + File.separator + SHELF_DIR_NAME);
}
public CompoundShelfFileProcessor(@Nullable StreamProvider serverStreamProvider, String shelfPath) {
myServerStreamProvider = serverStreamProvider;
myShelfPath = shelfPath;
mySubdirName = new File(myShelfPath).getName();
- FILE_SPEC = "$ROOT_CONFIG$/" + mySubdirName + "/";
+ FILE_SPEC = StoragePathMacros.ROOT_CONFIG + "/" + mySubdirName + "/";
}
/*
@@ -150,7 +154,7 @@ public class CompoundShelfFileProcessor {
if (stream != null) {
File file = new File(myShelfPath + "/" + newName);
copyFileToStream(stream, file);
- serverStreamProvider.deleteFile(oldFilePath, RoamingType.PER_USER);
+ serverStreamProvider.delete(oldFilePath, RoamingType.PER_USER);
copyFileContentToProviders(newFilePath, serverStreamProvider, file);
}
}
@@ -221,7 +225,7 @@ public class CompoundShelfFileProcessor {
public void delete(final String name) {
FileUtil.delete(new File(getBaseIODir(), name));
if (myServerStreamProvider != null && myServerStreamProvider.isEnabled()) {
- StorageUtil.deleteContent(myServerStreamProvider, FILE_SPEC + name, RoamingType.PER_USER);
+ StorageUtil.delete(myServerStreamProvider, FILE_SPEC + name, RoamingType.PER_USER);
}
}
} \ No newline at end of file
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelfManagerConfigurationMerger.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelfManagerConfigurationMerger.java
index bfaead47ab3a..b05cc9067592 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelfManagerConfigurationMerger.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelfManagerConfigurationMerger.java
@@ -35,7 +35,7 @@ public class ShelfManagerConfigurationMerger implements XmlConfigurationMerger {
public ShelfManagerConfigurationMerger() {
myConfigPath = PathManager.getConfigPath()+ "/shelf";
- myFileProcessor = new CompoundShelfFileProcessor("shelf");
+ myFileProcessor = new CompoundShelfFileProcessor();
}
@TestOnly
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
index e76ba194672e..96bb835bc086 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java
@@ -26,6 +26,7 @@ import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.components.AbstractProjectComponent;
+import com.intellij.openapi.components.StorageScheme;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.impl.patch.*;
import com.intellij.openapi.diff.impl.patch.apply.ApplyFilePatchBase;
@@ -34,6 +35,7 @@ import com.intellij.openapi.diff.impl.patch.formove.PatchApplier;
import com.intellij.openapi.progress.AsynchronousExecution;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ex.ProjectEx;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
@@ -65,6 +67,8 @@ import javax.swing.event.ChangeListener;
import java.io.*;
import java.util.*;
+import static com.intellij.openapi.vcs.changes.shelf.CompoundShelfFileProcessor.SHELF_DIR_NAME;
+
public class ShelveChangesManager extends AbstractProjectComponent implements JDOMExternalizable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager");
@@ -86,10 +90,16 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
super(project);
myBus = bus;
if (project.isDefault()) {
- myFileProcessor = new CompoundShelfFileProcessor(null, PathManager.getConfigPath() + File.separator + "shelf");
+ myFileProcessor = new CompoundShelfFileProcessor(null, PathManager.getConfigPath() + File.separator + SHELF_DIR_NAME);
}
else {
- myFileProcessor = new CompoundShelfFileProcessor("shelf");
+ if (project instanceof ProjectEx && ((ProjectEx)project).getStateStore().getStorageScheme() == StorageScheme.DIRECTORY_BASED) {
+ String shelfBaseDirPath = project.getBaseDir().getPath() + File.separator + Project.DIRECTORY_STORE_FOLDER;
+ myFileProcessor = new CompoundShelfFileProcessor(shelfBaseDirPath);
+ }
+ else {
+ myFileProcessor = new CompoundShelfFileProcessor();
+ }
}
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java
index 8d5463cd444b..57229c3fdf18 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeAnalysisBeforeCheckinHandler.java
@@ -30,14 +30,12 @@ import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.changes.CommitExecutor;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PairConsumer;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -139,7 +137,8 @@ public class CodeAnalysisBeforeCheckinHandler extends CheckinHandler {
try {
final List<CodeSmellInfo> codeSmells =
- CodeSmellDetector.getInstance(myProject).findCodeSmells(new ArrayList<VirtualFile>(myCheckinPanel.getVirtualFiles()));
+ CodeSmellDetector.getInstance(myProject)
+ .findCodeSmells(CheckinHandlerUtil.filterOutGeneratedAndExcludedFiles(myCheckinPanel.getVirtualFiles(), myProject));
if (!codeSmells.isEmpty()) {
return processFoundCodeSmells(codeSmells, executor);
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeCleanupCheckinHandlerFactory.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeCleanupCheckinHandlerFactory.java
index 97e9e4d1b534..b80936aafa14 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeCleanupCheckinHandlerFactory.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkin/CodeCleanupCheckinHandlerFactory.java
@@ -24,10 +24,12 @@ import com.intellij.openapi.vcs.CheckinProjectPanel;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.changes.CommitContext;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
+import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
+import java.util.List;
public class CodeCleanupCheckinHandlerFactory extends CheckinHandlerFactory {
@@ -75,7 +77,8 @@ public class CodeCleanupCheckinHandlerFactory extends CheckinHandlerFactory {
public void runCheckinHandlers(Runnable runnable) {
if (VcsConfiguration.getInstance(myProject).CHECK_CODE_CLEANUP_BEFORE_PROJECT_COMMIT && !DumbService.isDumb(myProject)) {
- GlobalInspectionContextBase.codeCleanup(myProject, new AnalysisScope(myProject, myPanel.getVirtualFiles()), runnable);
+ List<VirtualFile> filesToProcess = CheckinHandlerUtil.filterOutGeneratedAndExcludedFiles(myPanel.getVirtualFiles(), myProject);
+ GlobalInspectionContextBase.codeCleanup(myProject, new AnalysisScope(myProject, filesToProcess), runnable);
} else {
runnable.run();
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
index 9d8d73a92be9..daef43857c4e 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.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.
@@ -39,13 +39,11 @@ import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
-import com.intellij.util.ExceptionUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.diff.FilesTooBigForDiffException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import javax.swing.*;
import java.util.*;
/**
@@ -459,7 +457,7 @@ public class LineStatusTracker {
}
if (myRanges.isEmpty() && myVirtualFile != null) {
- SwingUtilities.invokeLater(new Runnable() {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
FileDocumentManager.getInstance().saveDocument(myDocument);
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java
index 908a3d9f8433..82ff0bcc6e5a 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ui/VcsBalloonProblemNotifier.java
@@ -37,7 +37,7 @@ import javax.swing.event.HyperlinkEvent;
*/
public class VcsBalloonProblemNotifier implements Runnable {
public static final NotificationGroup
- NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("Common Version Control Messages", ChangesViewContentManager.TOOLWINDOW_ID, true);
+ NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("Common Version Control Messages", ChangesViewContentManager.TOOLWINDOW_ID);
private final Project myProject;
private final String myMessage;
private final MessageType myMessageType;
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java
index 19cfbdf486eb..65b999f4c4db 100644
--- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogFilterCollection.java
@@ -40,6 +40,9 @@ public interface VcsLogFilterCollection {
VcsLogTextFilter getTextFilter();
@Nullable
+ VcsLogHashFilter getHashFilter();
+
+ @Nullable
VcsLogStructureFilter getStructureFilter();
/**
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java
index acd39bf51b18..71a14e1f732d 100644
--- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHashFilter.java
@@ -15,10 +15,13 @@
*/
package com.intellij.vcs.log;
+import org.jetbrains.annotations.NotNull;
+
import java.util.Collection;
public interface VcsLogHashFilter {
- Collection<Hash> getHashes();
+ @NotNull
+ Collection<String> getHashes();
}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java
index 18d7222d9257..83cb53fd8c8f 100644
--- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java
@@ -85,6 +85,8 @@ public abstract class AbstractVisibleGraph<CommitId> implements VisibleGraph<Com
@NotNull
@Override
public RowInfo<CommitId> getRowInfo(final int visibleRow) {
+ if (visibleRow < 0 || visibleRow >= getVisibleCommitCount())
+ throw new IndexOutOfBoundsException("VisibleCommitCount is: " + getVisibleCommitCount() + ", but visibleRow: " + visibleRow);
return new RowInfo<CommitId>() {
@NotNull
@Override
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementsManager.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementsManager.java
index 8219c50a4851..8da596f026bf 100644
--- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementsManager.java
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementsManager.java
@@ -108,8 +108,8 @@ public abstract class AbstractPrintElementsManager<CommitId> implements PrintEle
if (printElement != null) {
GraphEdge graphEdge = containedCollapsedEdge(printElement.getGraphElement(), myPrintedLinearGraph);
- if (graphEdge != null) {
- mySelectedNodes = ContainerUtil.set(graphEdge.getUpNodeIndex(), graphEdge.getDownNodeIndex());
+ if (graphEdge != null && allowSelectCollapsedEdge(graphEdge)) {
+ mySelectedNodes = ContainerUtil.set(graphEdge.getUpNodeIndex(), graphEdge.getDownNodeIndex());
} else {
mySelectedNodes = getSelectedNodes(printElement.getGraphElement());
}
@@ -150,4 +150,8 @@ public abstract class AbstractPrintElementsManager<CommitId> implements PrintEle
@NotNull
protected abstract Set<Integer> getSelectedNodes(@NotNull GraphElement graphElement);
+
+ protected boolean allowSelectCollapsedEdge(@NotNull GraphEdge graphEdge) {
+ return true;
+ }
}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/FilterPrintElementsManager.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/FilterPrintElementsManager.java
index 517128e01f4f..12ac6af5f388 100644
--- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/FilterPrintElementsManager.java
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/FilterPrintElementsManager.java
@@ -18,6 +18,7 @@ package com.intellij.vcs.log.graph.impl.print;
import com.intellij.vcs.log.graph.GraphColorManager;
import com.intellij.vcs.log.graph.api.LinearGraphWithCommitInfo;
+import com.intellij.vcs.log.graph.api.elements.GraphEdge;
import com.intellij.vcs.log.graph.api.elements.GraphElement;
import org.jetbrains.annotations.NotNull;
@@ -35,4 +36,9 @@ public class FilterPrintElementsManager<CommitId> extends AbstractPrintElementsM
protected Set<Integer> getSelectedNodes(@NotNull GraphElement graphElement) {
return Collections.emptySet();
}
+
+ @Override
+ protected boolean allowSelectCollapsedEdge(@NotNull GraphEdge graphEdge) {
+ return false;
+ }
}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdges.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdges.java
new file mode 100644
index 000000000000..d6ff4230b4df
--- /dev/null
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdges.java
@@ -0,0 +1,73 @@
+/*
+ * 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.graph.impl.visible;
+
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class DottedEdges {
+
+ @NotNull
+ public static DottedEdges newInstance(@NotNull MultiMap<Integer, Integer> delegate) {
+ int[] nodesWithEdges = ArrayUtil.toIntArray(delegate.keySet());
+ Arrays.sort(nodesWithEdges);
+
+ int[] startIndexes = new int[nodesWithEdges.length + 1];
+ int[] edges = new int[delegate.values().size()];
+
+ int start = 0;
+ for (int i = 0; i < startIndexes.length - 1; i++) {
+ startIndexes[i] = start;
+ for (int toNode : delegate.get(nodesWithEdges[i])) {
+ edges[start] = toNode;
+ start++;
+ }
+ }
+ startIndexes[startIndexes.length - 1] = start;
+
+ return new DottedEdges(nodesWithEdges, startIndexes, edges);
+ }
+
+ @NotNull private final int[] sortedStartNodes; // graph is not oriented => end nodes are there as well
+
+ @NotNull private final int[] startEdgesPosition;
+
+ @NotNull private final int[] endNodes;
+
+ public DottedEdges(@NotNull int[] sortedStartNodes, @NotNull int[] startEdgesPosition, @NotNull int[] endNodes) {
+ this.sortedStartNodes = sortedStartNodes;
+ this.startEdgesPosition = startEdgesPosition;
+ this.endNodes = endNodes;
+ }
+
+ public List<Integer> getAdjacentNodes(int nodeIndex) {
+ int smallIndex = Arrays.binarySearch(sortedStartNodes, nodeIndex);
+ if (smallIndex < 0)
+ return Collections.emptyList();
+ List<Integer> result = new SmartList<Integer>();
+
+ for (int i = startEdgesPosition[smallIndex]; i < startEdgesPosition[smallIndex + 1]; i++)
+ result.add(endNodes[i]);
+ return result;
+ }
+
+}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdgesComputer.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdgesComputer.java
new file mode 100644
index 000000000000..a5d9ef7cc15f
--- /dev/null
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/DottedEdgesComputer.java
@@ -0,0 +1,129 @@
+/*
+ * 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.graph.impl.visible;
+
+import com.intellij.util.containers.MultiMap;
+import com.intellij.vcs.log.graph.api.LinearGraph;
+import com.intellij.vcs.log.graph.utils.Flags;
+import org.jetbrains.annotations.NotNull;
+
+public class DottedEdgesComputer {
+ @NotNull
+ public static MultiMap<Integer, Integer> compute(@NotNull LinearGraph delegateGraph, @NotNull Flags visibleNodes) {
+ DottedEdgesComputer dottedEdgesComputer = new DottedEdgesComputer(delegateGraph, visibleNodes);
+ dottedEdgesComputer.compute();
+ return dottedEdgesComputer.myDottedEdges;
+ }
+
+ @NotNull
+ private final LinearGraph myDelegateGraph;
+
+ @NotNull
+ private final Flags myVisibleNodes;
+
+ @NotNull
+ private final MultiMap<Integer, Integer> myDottedEdges;
+
+ @NotNull
+ private final int[] myNumbers;
+
+ private DottedEdgesComputer(@NotNull LinearGraph delegateGraph, @NotNull Flags visibleNodes) {
+ assert delegateGraph.nodesCount() == visibleNodes.size();
+ myDelegateGraph = delegateGraph;
+ myVisibleNodes = visibleNodes;
+ myDottedEdges = MultiMap.create();
+ myNumbers = new int[myDelegateGraph.nodesCount()];
+ }
+
+ private void putEdge(int node1, int node2) {
+ myDottedEdges.putValue(node1, node2);
+ myDottedEdges.putValue(node2, node1);
+ }
+
+ private void compute() {
+ downWalk();
+ upWalk();
+ }
+
+ private void downWalk() {
+ for (int i = 0; i < myDelegateGraph.nodesCount() - 1; i++) {
+ if (myVisibleNodes.get(i)) {
+ int nearlyUp = Integer.MIN_VALUE;
+ int maxAdjNumber = Integer.MIN_VALUE;
+ for (int upNode : myDelegateGraph.getUpNodes(i)) {
+ if (myVisibleNodes.get(upNode))
+ maxAdjNumber = Math.max(maxAdjNumber, myNumbers[upNode]);
+ else
+ nearlyUp = Math.max(nearlyUp, myNumbers[upNode]);
+ }
+
+ if (nearlyUp == maxAdjNumber || nearlyUp == Integer.MIN_VALUE) {
+ myNumbers[i] = maxAdjNumber;
+ } else {
+ putEdge(i, nearlyUp);
+ myNumbers[i] = nearlyUp;
+ }
+ } else {
+ // node i invisible
+
+ int nearlyUp = Integer.MIN_VALUE;
+ for (int upNode : myDelegateGraph.getUpNodes(i)) {
+ if (myVisibleNodes.get(upNode))
+ nearlyUp = Math.max(nearlyUp, upNode);
+ else
+ nearlyUp = Math.max(nearlyUp, myNumbers[upNode]);
+ }
+ myNumbers[i] = nearlyUp;
+ }
+ }
+ }
+
+ private void upWalk() {
+ for (int i = myDelegateGraph.nodesCount() - 1; i >= 0; i--) {
+ if (myVisibleNodes.get(i)) {
+ int nearlyDown = Integer.MAX_VALUE;
+ int minAdjNumber = Integer.MAX_VALUE;
+ for (int downNode : myDelegateGraph.getDownNodes(i)) {
+ if (downNode == LinearGraph.NOT_LOAD_COMMIT) continue;
+ if (myVisibleNodes.get(downNode))
+ minAdjNumber = Math.min(minAdjNumber, myNumbers[downNode]);
+ else
+ nearlyDown = Math.min(nearlyDown, myNumbers[downNode]);
+ }
+
+ if (nearlyDown == minAdjNumber || nearlyDown == Integer.MAX_VALUE) {
+ myNumbers[i] = minAdjNumber;
+ } else {
+ putEdge(i, nearlyDown);
+ myNumbers[i] = nearlyDown;
+ }
+
+ } else {
+ // node i invisible
+
+ int nearlyDown = Integer.MAX_VALUE;
+ for (int downNode : myDelegateGraph.getDownNodes(i)) {
+ if (downNode == LinearGraph.NOT_LOAD_COMMIT) continue;
+ if (myVisibleNodes.get(downNode))
+ nearlyDown = Math.min(nearlyDown, downNode);
+ else
+ nearlyDown = Math.min(nearlyDown, myNumbers[downNode]);
+ }
+ myNumbers[i] = nearlyDown;
+ }
+ }
+ }
+}
diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/FilterGraphWithHiddenNodes.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/FilterGraphWithHiddenNodes.java
index 72f02273d488..667b8c744fc4 100644
--- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/FilterGraphWithHiddenNodes.java
+++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/visible/FilterGraphWithHiddenNodes.java
@@ -19,6 +19,7 @@ package com.intellij.vcs.log.graph.impl.visible;
import com.intellij.openapi.util.Condition;
import com.intellij.util.Consumer;
import com.intellij.util.SmartList;
+import com.intellij.util.containers.MultiMap;
import com.intellij.vcs.log.graph.api.LinearGraph;
import com.intellij.vcs.log.graph.api.LinearGraphWithHiddenNodes;
import com.intellij.vcs.log.graph.api.elements.GraphEdge;
@@ -39,6 +40,9 @@ public class FilterGraphWithHiddenNodes implements LinearGraphWithHiddenNodes {
private final Flags myVisibleNodes;
@NotNull
+ private final DottedEdges myDottedEdges;
+
+ @NotNull
private final SetListenerController<UpdateListener> myListenerController = new SetListenerController<UpdateListener>();
public FilterGraphWithHiddenNodes(@NotNull LinearGraphWithHiddenNodes delegateGraph, @NotNull Condition<Integer> isVisibleNode) {
@@ -47,6 +51,10 @@ public class FilterGraphWithHiddenNodes implements LinearGraphWithHiddenNodes {
for (int i = 0; i < delegateGraph.nodesCount(); i++) {
myVisibleNodes.set(i, delegateGraph.nodeIsVisible(i) && isVisibleNode.value(i)); // todo: think about it: may be drop myVisibleNodes
}
+
+ MultiMap<Integer, Integer> edges = DottedEdgesComputer.compute(myDelegateGraph, myVisibleNodes);
+ myDottedEdges = DottedEdges.newInstance(edges);
+
addUpdateListener();
}
@@ -78,7 +86,10 @@ public class FilterGraphWithHiddenNodes implements LinearGraphWithHiddenNodes {
@NotNull
@Override
public GraphEdge.Type getEdgeType(int upNodeIndex, int downNodeIndex) {
- return GraphEdge.Type.USUAL;
+ if (myDottedEdges.getAdjacentNodes(upNodeIndex).contains(downNodeIndex))
+ return GraphEdge.Type.HIDE;
+ else
+ return GraphEdge.Type.USUAL;
}
@NotNull
@@ -100,6 +111,10 @@ public class FilterGraphWithHiddenNodes implements LinearGraphWithHiddenNodes {
if (nodeIsVisible(upNode))
upNodes.add(upNode);
}
+ for (int adjNode : myDottedEdges.getAdjacentNodes(nodeIndex)) {
+ if (adjNode < nodeIndex)
+ upNodes.add(adjNode);
+ }
return upNodes;
}
@@ -111,6 +126,10 @@ public class FilterGraphWithHiddenNodes implements LinearGraphWithHiddenNodes {
if (downNode != LinearGraph.NOT_LOAD_COMMIT && nodeIsVisible(downNode))
downNodes.add(downNode);
}
+ for (int adjNode : myDottedEdges.getAdjacentNodes(nodeIndex)) {
+ if (adjNode > nodeIndex)
+ downNodes.add(adjNode);
+ }
return downNodes;
}
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
index 5a1766d9cb81..f0bf75c08dcf 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
@@ -48,11 +48,33 @@ public class VcsLogFilterer {
@NotNull
public AbstractVcsLogTableModel applyFiltersAndUpdateUi(@NotNull DataPack dataPack, @NotNull VcsLogFilterCollection filters) {
resetFilters(dataPack);
+ VcsLogHashFilter hashFilter = filters.getHashFilter();
+ if (hashFilter != null && !hashFilter.getHashes().isEmpty()) { // hashes should be shown, no matter if they match other filters or not
+ return applyHashFilter(dataPack, hashFilter.getHashes());
+ }
List<VcsLogDetailsFilter> detailsFilters = filters.getDetailsFilters();
applyGraphFilters(dataPack, filters.getBranchFilter());
return applyDetailsFilter(dataPack, detailsFilters);
}
+ private GraphTableModel applyHashFilter(@NotNull DataPack dataPack, @NotNull Collection<String> hashes) {
+ final List<Integer> indices = ContainerUtil.mapNotNull(hashes, new Function<String, Integer>() {
+ @Override
+ public Integer fun(String partOfHash) {
+ Hash hash = myLogDataHolder.findHashByString(partOfHash);
+ return hash != null ? myLogDataHolder.getCommitIndex(hash) : null;
+ }
+ });
+ dataPack.getGraphFacade().setVisibleBranches(null);
+ dataPack.getGraphFacade().setFilter(new Condition<Integer>() {
+ @Override
+ public boolean value(Integer integer) {
+ return indices.contains(integer);
+ }
+ });
+ return new GraphTableModel(dataPack, myLogDataHolder, myUI, LoadMoreStage.ALL_REQUESTED);
+ }
+
private static void resetFilters(@NotNull DataPack dataPack) {
GraphFacade facade = dataPack.getGraphFacade();
facade.setVisibleBranches(null);
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 12996f91c116..c7ab5e324b3d 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
@@ -15,12 +15,14 @@
*/
package com.intellij.vcs.log.data;
+import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.progress.impl.ProgressManagerImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
@@ -272,22 +274,23 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
Map<VirtualFile, Collection<VcsRef>> currentRefs = myCurrentDataPack.getRefsModel().getAllRefsByRoot();
try {
if (permanentGraph != null) {
- loadLogAndRefs(roots, currentRefs, myRecentCommitCount);
- List<? extends GraphCommit<Integer>> compoundLog = compound(ContainerUtil.map(myLoadedInfos.values(),
- new Function<LogAndRefs, List<? extends GraphCommit<Integer>>>() {
- @Override
- public List<? extends GraphCommit<Integer>> fun(
- LogAndRefs refs) {
- return refs.log;
- }
- }));
- Map<VirtualFile, Collection<VcsRef>> allNewRefs = getAllNewRefs(myLoadedInfos, currentRefs);
- 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);
+ int commitCount = myRecentCommitCount;
+ for (int attempt = 0; attempt <= 1; attempt++) {
+ loadLogAndRefs(roots, currentRefs, commitCount);
+ List<? extends GraphCommit<Integer>> compoundLog = compoundLoadedLogs(myLoadedInfos.values());
+ Map<VirtualFile, Collection<VcsRef>> allNewRefs = getAllNewRefs(myLoadedInfos, currentRefs);
+ List<GraphCommit<Integer>> joinedFullLog = join(compoundLog, permanentGraph.getAllCommits(), currentRefs, allNewRefs);
+ if (joinedFullLog == null) {
+ commitCount *= 5;
+ }
+ else {
+ return DataPack.build(joinedFullLog, new RefsModel(allNewRefs, myHashMap.asIndexGetter()),
+ myHashMap.asIndexGetter(), myHashMap.asHashGetter(), myProviders, true);
+ }
}
- // couldn't join => need to reload everything; this shouldn't happen often, the error is logged in join().
+ // couldn't join => need to reload everything; if 5000 commits is still not enough, it's worth reporting:
+ LOG.error("Couldn't join " + commitCount + " recent commits to the log (" + permanentGraph.getAllCommits().size() + " commits)",
+ new Attachment("recent_commits", toLogString(myLoadedInfos)));
}
Pair<PermanentGraph<Integer>, Map<VirtualFile, Collection<VcsRef>>> fullLogAndRefs = loadFullLog();
@@ -302,6 +305,38 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
}
}
+ private String toLogString(Map<VirtualFile, LogAndRefs> infos) {
+ StringBuilder sb = new StringBuilder();
+ for (Map.Entry<VirtualFile, LogAndRefs> entry : infos.entrySet()) {
+ sb.append(entry.getKey().getName());
+ sb.append(" LOG:\n");
+ sb.append(StringUtil.join(entry.getValue().log, new Function<GraphCommit<Integer>, String>() {
+ @Override
+ public String fun(GraphCommit<Integer> commit) {
+ return commit.getId() + "<-" + StringUtil.join(commit.getParents(), ",");
+ }
+ }, "\n"));
+ sb.append("\nREFS:\n");
+ sb.append(StringUtil.join(entry.getValue().refs, new Function<VcsRef, String>() {
+ @Override
+ public String fun(VcsRef ref) {
+ return ref.getName() + "(" + myHashMap.getCommitIndex(ref.getCommitHash()) + ")";
+ }
+ }, ","));
+ }
+ return sb.toString();
+ }
+
+ @NotNull
+ private List<? extends GraphCommit<Integer>> compoundLoadedLogs(@NotNull Collection<LogAndRefs> logsAndRefs) {
+ return compound(ContainerUtil.map(logsAndRefs, new Function<LogAndRefs, List<? extends GraphCommit<Integer>>>() {
+ @Override
+ public List<? extends GraphCommit<Integer>> fun(LogAndRefs refs) {
+ return refs.log;
+ }
+ }));
+ }
+
@NotNull
private Map<VirtualFile, Collection<VcsRef>> getAllNewRefs(@NotNull Map<VirtualFile, LogAndRefs> newInfo,
@NotNull Map<VirtualFile, Collection<VcsRef>> previousRefs) {
@@ -374,7 +409,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
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
+ LOG.info(e);
}
catch (IllegalStateException e) {
LOG.error(e);
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java
index 285e3ce91079..3fbb7cb7b82f 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java
@@ -27,17 +27,20 @@ public class VcsLogFilterCollectionImpl implements VcsLogFilterCollection {
@Nullable private final VcsLogBranchFilter myBranchFilter;
@Nullable private final VcsLogUserFilter myUserFilter;
+ @Nullable private final VcsLogHashFilter myHashFilter;
@Nullable private final VcsLogDateFilter myDateFilter;
@Nullable private final VcsLogTextFilter myTextFilter;
@Nullable private final VcsLogStructureFilter myStructureFilter;
public VcsLogFilterCollectionImpl(@Nullable VcsLogBranchFilter branchFilter,
@Nullable VcsLogUserFilter userFilter,
+ @Nullable VcsLogHashFilter hashFilter,
@Nullable VcsLogDateFilter dateFilter,
@Nullable VcsLogTextFilter textFilter,
@Nullable VcsLogStructureFilter structureFilter) {
myBranchFilter = branchFilter;
myUserFilter = userFilter;
+ myHashFilter = hashFilter;
myDateFilter = dateFilter;
myTextFilter = textFilter;
myStructureFilter = structureFilter;
@@ -49,6 +52,12 @@ public class VcsLogFilterCollectionImpl implements VcsLogFilterCollection {
return myBranchFilter;
}
+ @Override
+ @Nullable
+ public VcsLogHashFilter getHashFilter() {
+ return myHashFilter;
+ }
+
@Nullable
@Override
public VcsLogUserFilter getUserFilter() {
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java
new file mode 100644
index 000000000000..ff747f4f37d4
--- /dev/null
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.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.vcs.log.impl;
+
+import com.intellij.vcs.log.VcsLogHashFilter;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class VcsLogHashFilterImpl implements VcsLogHashFilter {
+
+ @NotNull private final Collection<String> myHashes;
+
+ public VcsLogHashFilterImpl(@NotNull Collection<String> hashes) {
+ myHashes = hashes;
+ }
+
+ @NotNull
+ @Override
+ public Collection<String> getHashes() {
+ return myHashes;
+ }
+}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java
index 88b2b449ac69..016f08451a95 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java
@@ -45,9 +45,4 @@ public class VcsLogSettingsImpl implements VcsLogSettings, PersistentStateCompon
public void setShowBranchesPanel(boolean show) {
myState.SHOW_BRANCHES_PANEL = show;
}
-
- public void setRecentCommitsBlockSize(int commitCount) {
- myState.RECENT_COMMITS_COUNT = commitCount;
- }
-
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
index d18c99c4e24c..9a44f320f040 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
@@ -20,15 +20,20 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.SearchTextField;
import com.intellij.ui.SearchTextFieldWithStoredHistory;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.data.DataPack;
import com.intellij.vcs.log.data.VcsLogDataHolder;
import com.intellij.vcs.log.data.VcsLogUiProperties;
import com.intellij.vcs.log.impl.VcsLogFilterCollectionImpl;
+import com.intellij.vcs.log.impl.VcsLogHashFilterImpl;
import com.intellij.vcs.log.ui.VcsLogUiImpl;
import org.jetbrains.annotations.NotNull;
@@ -43,6 +48,9 @@ import java.util.List;
*/
public class VcsLogClassicFilterUi implements VcsLogFilterUi {
+ private static final Logger LOG = Logger.getInstance(VcsLogClassicFilterUi.class);
+ private static final String HASH_PATTERN = "[a-fA-F0-9]{7,}";
+
@NotNull private final SearchTextField myTextFilter;
@NotNull private final VcsLogUiImpl myUi;
@NotNull private final DefaultActionGroup myActionGroup;
@@ -104,9 +112,38 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi {
@NotNull
@Override
public VcsLogFilterCollection getFilters() {
- VcsLogTextFilter textFilter = !myTextFilter.getText().isEmpty() ? new VcsLogTextFilterImpl(myTextFilter.getText().trim()) : null;
+ Pair<VcsLogTextFilter, VcsLogHashFilter> filtersFromText = getFiltersFromTextArea(myTextFilter.getText().trim());
return new VcsLogFilterCollectionImpl(myBranchFilterComponent.getFilter(), myUserFilterComponent.getFilter(),
- myDateFilterComponent.getFilter(), textFilter, myStructureFilterComponent.getFilter());
+ filtersFromText.second, myDateFilterComponent.getFilter(),
+ filtersFromText.first, myStructureFilterComponent.getFilter());
+ }
+
+ @NotNull
+ private static Pair<VcsLogTextFilter, VcsLogHashFilter> getFiltersFromTextArea(@NotNull String text) {
+ if (text.isEmpty()) {
+ return Pair.empty();
+ }
+ List<String> hashes = ContainerUtil.newArrayList();
+ for (String word : StringUtil.split(text, " ")) {
+ if (!StringUtil.isEmptyOrSpaces(word) && word.matches(HASH_PATTERN)) {
+ hashes.add(word);
+ }
+ else {
+ break;
+ }
+ }
+
+ VcsLogTextFilter textFilter;
+ VcsLogHashFilterImpl hashFilter;
+ if (!hashes.isEmpty()) { // text is ignored if there are hashes in the text
+ textFilter = null;
+ hashFilter = new VcsLogHashFilterImpl(hashes);
+ }
+ else {
+ textFilter = new VcsLogTextFilterImpl(text);
+ hashFilter = null;
+ }
+ return Pair.<VcsLogTextFilter, VcsLogHashFilter>create(textFilter, hashFilter);
}
@Override
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
index 33fa877064db..5e43a76c6c6d 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugSession.java
@@ -61,9 +61,20 @@ public interface XDebugSession extends AbstractDebuggerSession {
XSuspendContext getSuspendContext();
+ /**
+ * Position from the current frame
+ * @return
+ */
@Nullable
XSourcePosition getCurrentPosition();
+ /**
+ * Position from the top frame
+ * @return
+ */
+ @Nullable
+ XSourcePosition getTopFramePosition();
+
void stepOver(boolean ignoreBreakpoints);
void stepInto();
@@ -80,13 +91,12 @@ public interface XDebugSession extends AbstractDebuggerSession {
void showExecutionPoint();
- void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame);
+ void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame, boolean isTopFrame);
/**
- * @deprecated use {@link #setCurrentStackFrame(com.intellij.xdebugger.frame.XExecutionStack, com.intellij.xdebugger.frame.XStackFrame)} instead
+ * @deprecated use {@link #setCurrentStackFrame(com.intellij.xdebugger.frame.XExecutionStack, com.intellij.xdebugger.frame.XStackFrame, boolean)} instead
*/
- @SuppressWarnings("UnusedDeclaration")
- void setCurrentStackFrame(@NotNull XStackFrame frame);
+ void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame);
/**
* Call this method to setup custom icon and/or error message (it will be shown in tooltip) for breakpoint
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XNearestSourcePosition.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XNearestSourcePosition.java
new file mode 100644
index 000000000000..87abf3da3b21
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XNearestSourcePosition.java
@@ -0,0 +1,22 @@
+/*
+ * 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.frame;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+public interface XNearestSourcePosition extends XNavigatable {
+}
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java
new file mode 100644
index 000000000000..9f9f3a8bf407
--- /dev/null
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XReferrersProvider.java
@@ -0,0 +1,23 @@
+/*
+ * 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.frame;
+
+/**
+ * @author traff
+ */
+public interface XReferrersProvider<T extends XValue> {
+ T getReferringObjectsValue();
+}
diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java
index ff2b3303d4da..9cfa2fb15af4 100644
--- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java
+++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValue.java
@@ -87,4 +87,9 @@ public abstract class XValue extends XValueContainer {
public void computeTypeSourcePosition(@NotNull XNavigatable navigatable) {
navigatable.setSourcePosition(null);
}
+
+ @Nullable
+ public XReferrersProvider getReferrersProvider() {
+ return null;
+ }
} \ No newline at end of file
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 8ee2f1ee587a..1b0f0ca69a59 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
@@ -45,6 +45,7 @@ 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.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.ui.AppUIUtil;
@@ -96,7 +97,8 @@ public class XDebugSessionImpl implements XDebugSession {
private XSuspendContext mySuspendContext;
private XExecutionStack myCurrentExecutionStack;
private XStackFrame myCurrentStackFrame;
- private XSourcePosition myCurrentPosition;
+ private boolean myIsTopFrame;
+ private XSourcePosition myTopFramePosition;
private final AtomicBoolean myPaused = new AtomicBoolean();
private MyDependentBreakpointListener myDependentBreakpointListener;
private XValueMarkers<?, ?> myValueMarkers;
@@ -255,7 +257,13 @@ public class XDebugSessionImpl implements XDebugSession {
@Override
@Nullable
public XSourcePosition getCurrentPosition() {
- return myCurrentPosition;
+ return myCurrentStackFrame != null ? myCurrentStackFrame.getSourcePosition() : null;
+ }
+
+ @Nullable
+ @Override
+ public XSourcePosition getTopFramePosition() {
+ return myTopFramePosition;
}
public XDebugSessionTab init(@NotNull XDebugProcess process, @NotNull XDebugSessionData sessionData, @Nullable RunContentDescriptor contentToReuse) {
@@ -538,8 +546,8 @@ public class XDebugSessionImpl implements XDebugSession {
mySuspendContext = null;
myCurrentExecutionStack = null;
myCurrentStackFrame = null;
- adjustMouseTrackingCounter(myCurrentPosition, -1);
- myCurrentPosition = null;
+ adjustMouseTrackingCounter(myTopFramePosition, -1);
+ myTopFramePosition = null;
myActiveNonLineBreakpoint = null;
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
@@ -559,7 +567,7 @@ public class XDebugSessionImpl implements XDebugSession {
}
private boolean isTopFrameSelected() {
- return myCurrentExecutionStack != null && myCurrentExecutionStack.getTopFrame() == myCurrentStackFrame;
+ return myCurrentExecutionStack != null && myIsTopFrame;
}
@@ -570,7 +578,7 @@ public class XDebugSessionImpl implements XDebugSession {
if (executionStack != null) {
XStackFrame topFrame = executionStack.getTopFrame();
if (topFrame != null) {
- setCurrentStackFrame(executionStack, topFrame);
+ setCurrentStackFrame(executionStack, topFrame, true);
myDebuggerManager.showExecutionPosition();
}
}
@@ -578,17 +586,18 @@ public class XDebugSessionImpl implements XDebugSession {
}
@Override
- public void setCurrentStackFrame(@NotNull final XStackFrame frame) {
- setCurrentStackFrame(myCurrentExecutionStack, frame);
+ public void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame) {
+ setCurrentStackFrame(myCurrentExecutionStack, frame, frame == executionStack.getTopFrame());
}
@Override
- public void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame) {
+ public void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame, boolean isTopFrame) {
if (mySuspendContext == null) return;
boolean frameChanged = myCurrentStackFrame != frame;
myCurrentExecutionStack = executionStack;
myCurrentStackFrame = frame;
+ myIsTopFrame = isTopFrame;
activateSession();
if (frameChanged) {
@@ -708,7 +717,9 @@ public class XDebugSessionImpl implements XDebugSession {
@Override
public void run() {
if (mySessionTab != null) {
- mySessionTab.toFront(true);
+ if (XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings().isShowDebuggerOnBreakpoint()) {
+ mySessionTab.toFront(true);
+ }
mySessionTab.getUi().attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
}
}
@@ -781,14 +792,14 @@ public class XDebugSessionImpl implements XDebugSession {
mySuspendContext = suspendContext;
myCurrentExecutionStack = suspendContext.getActiveExecutionStack();
myCurrentStackFrame = myCurrentExecutionStack != null ? myCurrentExecutionStack.getTopFrame() : null;
- myCurrentPosition = myCurrentStackFrame != null ? myCurrentStackFrame.getSourcePosition() : null;
+ myTopFramePosition = myCurrentStackFrame != null ? myCurrentStackFrame.getSourcePosition() : null;
myPaused.set(true);
- if (myCurrentPosition != null) {
- myDebuggerManager.setActiveSession(this, myCurrentPosition, false, getPositionIconRenderer(true));
+ if (myTopFramePosition != null) {
+ myDebuggerManager.setActiveSession(this, myTopFramePosition, false, getPositionIconRenderer(true));
}
- adjustMouseTrackingCounter(myCurrentPosition, 1);
+ adjustMouseTrackingCounter(myTopFramePosition, 1);
if (myShowTabOnSuspend.compareAndSet(true, false)) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@@ -810,6 +821,7 @@ public class XDebugSessionImpl implements XDebugSession {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
+ if (myProject.isDisposed()) return;
Editor editor = XDebuggerUtilImpl.createEditor(new OpenFileDescriptor(myProject, position.getFile()));
if (editor != null) {
JComponent component = editor.getComponent();
@@ -855,8 +867,8 @@ public class XDebugSessionImpl implements XDebugSession {
mySessionTab.detachFromSession();
}
- adjustMouseTrackingCounter(myCurrentPosition, -1);
- myCurrentPosition = null;
+ adjustMouseTrackingCounter(myTopFramePosition, -1);
+ myTopFramePosition = null;
myCurrentExecutionStack = null;
myCurrentStackFrame = null;
mySuspendContext = null;
@@ -970,6 +982,9 @@ public class XDebugSessionImpl implements XDebugSession {
public void setWatchExpressions(@NotNull XExpression[] watchExpressions) {
mySessionData.setWatchExpressions(watchExpressions);
myDebuggerManager.getWatchesManager().setWatches(getWatchesKey(), watchExpressions);
+ if (Registry.is("debugger.watches.in.variables")) {
+ rebuildViews();
+ }
}
XExpression[] getWatchExpressions() {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
index 6d09b8fd3128..2b84d05011c2 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
@@ -47,7 +47,7 @@ public class XDebuggerSmartStepIntoHandler extends XDebuggerSuspendedActionHandl
@Override
protected void perform(@NotNull XDebugSession session, DataContext dataContext) {
final XSmartStepIntoHandler<?> handler = session.getDebugProcess().getSmartStepIntoHandler();
- final XSourcePosition position = session.getCurrentPosition();
+ final XSourcePosition position = session.getTopFramePosition();
if (position == null || handler == null) return;
final FileEditor editor = FileEditorManager.getInstance(session.getProject()).getSelectedEditor(position.getFile());
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
index e2ce9ca7c63d..855abaaad74e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.DocumentUtil;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.XSourcePosition;
@@ -91,7 +92,7 @@ public class XLineBreakpointImpl<P extends XBreakpointProperties> extends XBreak
RangeHighlighterEx highlighter = myHighlighter;
if (highlighter != null &&
(!highlighter.isValid()
- || highlighter.getStartOffset() >= document.getTextLength()
+ || !DocumentUtil.isValidOffset(highlighter.getStartOffset(), document)
|| !Comparing.equal(highlighter.getTextAttributes(), attributes)
// it seems that this check is not needed - we always update line number from the highlighter
// and highlighter is removed on line and file change anyway
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
index 098b64052284..e88f54f24799 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
@@ -261,7 +261,7 @@ public class XLineBreakpointManager {
|| mouseEvent.isMetaDown() || mouseEvent.isControlDown()
|| mouseEvent.getButton() != MouseEvent.BUTTON1
|| MarkupEditorFilterFactory.createIsDiffFilter().avaliableIn(editor)
- || e.getArea() != EditorMouseEventArea.LINE_MARKERS_AREA
+ || (e.getArea() != EditorMouseEventArea.LINE_MARKERS_AREA && e.getArea() != EditorMouseEventArea.FOLDING_OUTLINE_AREA)
|| ConsoleViewUtil.isConsoleViewEditor(editor)
||!isFromMyProject(editor)) {
return;
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 36584d1105d4..de4d45f483bf 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
@@ -122,6 +122,13 @@ public class XBreakpointActionsPanel<B extends XBreakpointBase<?,?,?>> extends X
}
}
+ JComponent getDefaultFocusComponent() {
+ if (myLogExpressionComboBox != null && myLogExpressionComboBox.getComboBox().isEnabled()) {
+ return myLogExpressionComboBox.getEditorComponent();
+ }
+ return null;
+ }
+
public void dispose() {
}
}
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 75cbb569ddfd..4e91c27f011d 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
@@ -180,8 +180,15 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpointBase<?,?,?>> i
myMainPanel.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent event) {
- if (myConditionComboBox != null) {
- IdeFocusManager.findInstance().requestFocus(myConditionComboBox.getEditorComponent(), false);
+ JComponent compToFocus;
+ if (myConditionComboBox != null && myConditionComboBox.getComboBox().isEnabled()) {
+ compToFocus = myConditionComboBox.getEditorComponent();
+ }
+ else {
+ compToFocus = myActionsPanel.getDefaultFocusComponent();
+ }
+ if (compToFocus != null) {
+ IdeFocusManager.findInstance().requestFocus(compToFocus, false);
}
}
});
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java
index 141a56c9b721..be44e2c01d2b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java
@@ -54,6 +54,7 @@ public class CodeFragmentInputComponent extends EvaluationInputComponent {
myMainPanel.add(editorPanel, BorderLayout.CENTER);
}
+ @NotNull
protected XDebuggerEditorBase getInputEditor() {
return myMultilineEditor;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java
index c702cae00c6e..3803945f9598 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java
@@ -16,6 +16,7 @@
package com.intellij.xdebugger.impl.evaluate;
import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -33,6 +34,7 @@ public abstract class EvaluationInputComponent {
return myTitle;
}
+ @NotNull
protected abstract XDebuggerEditorBase getInputEditor();
public abstract void addComponent(JPanel contentPanel, JPanel resultPanel);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java
index 15a8bf6aed84..45b140ddf8e8 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java
@@ -63,6 +63,7 @@ public class ExpressionInputComponent extends EvaluationInputComponent {
contentPanel.add(hint, BorderLayout.SOUTH);
}
+ @NotNull
protected XDebuggerEditorBase getInputEditor() {
return myExpressionComboBox;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java
index a3aa8ec43fc5..e73564095b21 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java
@@ -15,61 +15,214 @@
*/
package com.intellij.xdebugger.impl.evaluate;
+import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorLinePainter;
import com.intellij.openapi.editor.LineExtensionInfo;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleColoredText;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
+import com.intellij.xdebugger.impl.frame.XDebugView;
import com.intellij.xdebugger.impl.frame.XVariablesView;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueTextRendererImpl;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
+import java.util.List;
/**
* @author Konstantin Bulenkov
*/
public class XDebuggerEditorLinePainter extends EditorLinePainter {
+ public static final Key<Map<Variable, VariableValue>> CACHE = Key.create("debug.inline.variables.cache");
@Override
public Collection<LineExtensionInfo> getLineExtensions(@NotNull Project project, @NotNull VirtualFile file, int lineNumber) {
if (!Registry.is("ide.debugger.inline")) {
return null;
}
- Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = project.getUserData(XVariablesView.DEBUG_VARIABLES);
- if (map != null) {
- Set<XValueNodeImpl> values = map.get(Pair.create(file, lineNumber));
- if (values != null && !values.isEmpty()) {
- ArrayList<LineExtensionInfo> result = new ArrayList<LineExtensionInfo>();
- for (XValueNodeImpl value : values) {
- SimpleColoredText text = new SimpleColoredText();
- XValueTextRendererImpl renderer = new XValueTextRendererImpl(text);
- final XValuePresentation presentation = value.getValuePresentation();
- if (presentation == null) continue;
+ final Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = project.getUserData(XVariablesView.DEBUG_VARIABLES);
+ final Map<VirtualFile, Long> timestamps = project.getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS);
+ final Document doc = FileDocumentManager.getInstance().getDocument(file);
+
+ if (map == null || timestamps == null || doc == null) {
+ return null;
+ }
+
+ Map<Variable, VariableValue> oldValues = project.getUserData(CACHE);
+ if (oldValues == null) {
+ oldValues = new HashMap<Variable, VariableValue>();
+ project.putUserData(CACHE, oldValues);
+ }
+ final Long timestamp = timestamps.get(file);
+ if (timestamp == null || timestamp < doc.getModificationStamp()) {
+ return null;
+ }
+ Set<XValueNodeImpl> values = map.get(Pair.create(file, lineNumber));
+ if (values != null && !values.isEmpty()) {
+ final int bpLine = getCurrentBreakPointLine(values);
+ ArrayList<LineExtensionInfo> result = new ArrayList<LineExtensionInfo>();
+ for (XValueNodeImpl value : values) {
+ SimpleColoredText text = new SimpleColoredText();
+ XValueTextRendererImpl renderer = new XValueTextRendererImpl(text);
+ final XValuePresentation presentation = value.getValuePresentation();
+ if (presentation == null) continue;
+ try {
if (presentation instanceof XValueCompactPresentation) {
((XValueCompactPresentation)presentation).renderValue(renderer, value);
} else {
presentation.renderValue(renderer);
}
- final Color color = new JBColor(new Color(61, 128, 101), new Color(61, 128, 101));
- result.add(new LineExtensionInfo(" " + value.getName() + ": ", color, null, null, Font.PLAIN));
+ if (StringUtil.isEmpty(text.toString())) {
+ final String type = value.getValuePresentation().getType();
+ if (!StringUtil.isEmpty(type)) {
+ text.append(type, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+ }
+ } catch (Exception e) {
+ continue;
+ }
+ final Color color = bpLine == lineNumber ? new JBColor(Gray._180, new Color(147, 217, 186)) : getForeground();
+
+ final String name = value.getName();
+ if (StringUtil.isEmpty(text.toString())) {
+ continue;
+ }
+ result.add(new LineExtensionInfo(" " + name + ": ", color, null, null, Font.PLAIN));
+
+ Variable var = new Variable(name, lineNumber);
+ VariableValue variableValue = oldValues.get(var);
+ if (variableValue == null) {
+ variableValue = new VariableValue(text.toString(), null, value.hashCode());
+ oldValues.put(var, variableValue);
+ }
+ if (variableValue.valueNodeHashCode != value.hashCode()) {
+ variableValue.old = variableValue.actual;
+ variableValue.actual = text.toString();
+ variableValue.valueNodeHashCode = value.hashCode();
+ }
+
+ if (!variableValue.isChanged()) {
for (String s : text.getTexts()) {
result.add(new LineExtensionInfo(s, color, null, null, Font.PLAIN));
}
+ } else {
+ variableValue.produceChangedParts(result);
}
- return result;
}
+ return result;
}
return null;
}
+
+ private static int getCurrentBreakPointLine(Set<XValueNodeImpl> values) {
+ try {
+ final XValueNodeImpl node = values.iterator().next();
+ final XDebugSession session = XDebugView.getSession(node.getTree());
+ if (session != null) {
+ final XSourcePosition position = session.getCurrentPosition();
+ if (position != null) {
+ return position.getLine();
+ }
+ }
+ } catch (Exception ignore){}
+ return -1;
+ }
+
+ public static JBColor getForeground() {
+ return new JBColor(new Color(61, 128, 101), new Color(61, 128, 101));
+ }
+
+ public static JBColor getChangedForeground() {
+ return new JBColor(new Color(202, 128, 33), new Color(161, 131, 10));
+ }
+
+ static class Variable {
+ private int lineNumber;
+ private String name;
+
+ public Variable(String name, int lineNumber) {
+ this.lineNumber = lineNumber;
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Variable variable = (Variable)o;
+
+ if (lineNumber != variable.lineNumber) return false;
+ if (!name.equals(variable.name)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = lineNumber;
+ result = 31 * result + name.hashCode();
+ return result;
+ }
+ }
+
+ static class VariableValue {
+ private String actual;
+ private String old;
+ private int valueNodeHashCode;
+
+ public VariableValue(String actual, String old, int valueNodeHashCode) {
+ this.actual = actual;
+ this.old = old;
+ this.valueNodeHashCode = valueNodeHashCode;
+ }
+
+ public boolean isChanged() {
+ return old != null && !StringUtil.equals(actual, old);
+ }
+
+ public void produceChangedParts(List<LineExtensionInfo> result) {
+ if (isArray(actual) && isArray(old)) {
+ List<String> actualParts = getArrayParts(actual);
+ List<String> oldParts = getArrayParts(old);
+ result.add(new LineExtensionInfo("{", getForeground(), null, null, Font.PLAIN));
+ for (int i = 0; i < actualParts.size(); i++) {
+ if (i < oldParts.size() && StringUtil.equals(actualParts.get(i), oldParts.get(i))) {
+ result.add(new LineExtensionInfo(actualParts.get(i), getForeground(), null, null, Font.PLAIN));
+ } else {
+ result.add(new LineExtensionInfo(actualParts.get(i), getChangedForeground(), null, null, Font.BOLD));
+ }
+ if (i != actualParts.size() - 1) {
+ result.add(new LineExtensionInfo(", ", getForeground(), null, null, Font.PLAIN));
+ }
+ }
+ result.add(new LineExtensionInfo("}", getForeground(), null, null, Font.PLAIN));
+ return;
+ }
+
+ result.add(new LineExtensionInfo(actual, getChangedForeground(), null, null, Font.BOLD));
+ }
+
+ private static boolean isArray(String s) {
+ return s != null && s.startsWith("{") && s.endsWith("}");
+ }
+
+ private static List<String> getArrayParts(String array) {
+ return StringUtil.split(array.substring(1, array.length() - 1), ", ");
+ }
+ }
}
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 37da856156ea..74b3b5202dbd 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
@@ -18,6 +18,7 @@ package com.intellij.xdebugger.impl.evaluate;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
@@ -79,13 +80,23 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
mySession.addSessionListener(new XDebugSessionAdapter() {
@Override
public void sessionStopped() {
- SwingUtilities.invokeLater(new Runnable() {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
close(CANCEL_EXIT_CODE);
}
});
}
+
+ @Override
+ public void stackFrameChanged() {
+ updateSourcePosition();
+ }
+
+ @Override
+ public void sessionPaused() {
+ updateSourcePosition();
+ }
}, myDisposable);
myTreePanel = new XDebuggerTreePanel(session.getProject(), editorsProvider, myDisposable, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP,
@@ -124,6 +135,15 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
init();
}
+ private void updateSourcePosition() {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ getInputEditor().setSourcePosition(mySession.getCurrentPosition());
+ }
+ });
+ }
+
@Override
protected void doOKAction() {
evaluate();
@@ -138,7 +158,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
super.actionPerformed(e);
if (myMode == EvaluationMode.EXPRESSION && ((e.getModifiers() & InputEvent.CTRL_MASK) != 0)) {
// add to watches
- XExpression expression = myInputComponent.getInputEditor().getExpression();
+ XExpression expression = getInputEditor().getExpression();
if (!XDebuggerUtilImpl.isEmptyExpression(expression)) {
XDebugSessionTab tab = ((XDebugSessionImpl)mySession).getSessionTab();
if (tab != null) {
@@ -179,7 +199,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
public XExpression getExpression() {
- return myInputComponent.getInputEditor().getExpression();
+ return getInputEditor().getExpression();
}
private static String getSwitchButtonText(EvaluationMode mode) {
@@ -205,12 +225,16 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
private void requestFocusInEditor() {
- JComponent preferredFocusedComponent = myInputComponent.getInputEditor().getPreferredFocusedComponent();
+ JComponent preferredFocusedComponent = getInputEditor().getPreferredFocusedComponent();
if (preferredFocusedComponent != null) {
IdeFocusManager.getInstance(mySession.getProject()).requestFocus(preferredFocusedComponent, true);
}
}
+ private XDebuggerEditorBase getInputEditor() {
+ return myInputComponent.getInputEditor();
+ }
+
private EvaluationInputComponent createInputComponent(EvaluationMode mode, XExpression text) {
final Project project = mySession.getProject();
text = XExpressionImpl.changeMode(text, mode);
@@ -223,7 +247,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
private void evaluate() {
- final XDebuggerEditorBase inputEditor = myInputComponent.getInputEditor();
+ final XDebuggerEditorBase inputEditor = getInputEditor();
int offset = -1;
//try to save caret position
@@ -262,7 +286,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
public void startEvaluation(@NotNull XDebuggerEvaluator.XEvaluationCallback evaluationCallback) {
- final XDebuggerEditorBase inputEditor = myInputComponent.getInputEditor();
+ final XDebuggerEditorBase inputEditor = getInputEditor();
inputEditor.saveTextInHistory();
XExpression expression = inputEditor.getExpression();
@@ -277,13 +301,13 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
@Override
public JComponent getPreferredFocusedComponent() {
- return myInputComponent.getInputEditor().getPreferredFocusedComponent();
+ return getInputEditor().getPreferredFocusedComponent();
}
private class SwitchModeAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
- XExpression text = myInputComponent.getInputEditor().getExpression();
+ XExpression text = getInputEditor().getExpression();
if (myMode == EvaluationMode.EXPRESSION) {
switchToMode(EvaluationMode.CODE_FRAGMENT, text);
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
index b98440b5d69f..9999ac015b77 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
@@ -188,10 +188,10 @@ public class XFramesView extends XDebugView {
return toolbar;
}
- private StackFramesListBuilder getOrCreateBuilder(XExecutionStack executionStack) {
+ private StackFramesListBuilder getOrCreateBuilder(XExecutionStack executionStack, XDebugSession session) {
StackFramesListBuilder builder = myBuilders.get(executionStack);
if (builder == null) {
- builder = new StackFramesListBuilder(executionStack);
+ builder = new StackFramesListBuilder(executionStack, session);
myBuilders.put(executionStack, builder);
}
return builder;
@@ -244,7 +244,6 @@ public class XFramesView extends XDebugView {
}
myToolbar.setAddSeparatorFirst(!invisible);
updateFrames(activeExecutionStack, session);
- myListenersEnabled = true;
}
@Override
@@ -270,19 +269,14 @@ public class XFramesView extends XDebugView {
return;
}
if (mySelectedStack != null) {
- getOrCreateBuilder(mySelectedStack).stop();
+ getOrCreateBuilder(mySelectedStack, session).stop();
}
mySelectedStack = executionStack;
if (executionStack != null) {
- StackFramesListBuilder builder = getOrCreateBuilder(executionStack);
+ StackFramesListBuilder builder = getOrCreateBuilder(executionStack, session);
builder.initModel(myFramesList.getModel());
builder.start();
- XStackFrame topFrame = executionStack.getTopFrame();
- if (topFrame != null) {
- myFramesList.setSelectedValue(topFrame, true);
- session.setCurrentStackFrame(executionStack, topFrame);
- }
}
}
@@ -303,7 +297,7 @@ public class XFramesView extends XDebugView {
if (selected instanceof XStackFrame) {
XDebugSession session = getSession(e);
if (session != null) {
- session.setCurrentStackFrame(mySelectedStack, (XStackFrame)selected);
+ session.setCurrentStackFrame(mySelectedStack, (XStackFrame)selected, myFramesList.getSelectedIndex() == 0);
}
}
}
@@ -312,21 +306,15 @@ public class XFramesView extends XDebugView {
private XExecutionStack myExecutionStack;
private final List<XStackFrame> myStackFrames;
private String myErrorMessage;
- private int myNextFrameIndex;
+ private int myNextFrameIndex = 0;
private boolean myRunning;
private boolean myAllFramesLoaded;
+ private final XDebugSession mySession;
- private StackFramesListBuilder(final XExecutionStack executionStack) {
+ private StackFramesListBuilder(final XExecutionStack executionStack, XDebugSession session) {
myExecutionStack = executionStack;
+ mySession = session;
myStackFrames = new ArrayList<XStackFrame>();
- XStackFrame topFrame = executionStack.getTopFrame();
- if (topFrame != null) {
- myStackFrames.add(topFrame);
- myNextFrameIndex = 1;
- }
- else {
- myNextFrameIndex = 0;
- }
}
@Override
@@ -336,6 +324,9 @@ public class XFramesView extends XDebugView {
public void run() {
myStackFrames.addAll(stackFrames);
addFrameListElements(stackFrames, last);
+ if (myNextFrameIndex == 0) {
+ selectTopFrame();
+ }
myNextFrameIndex += stackFrames.size();
myAllFramesLoaded = last;
if (last) {
@@ -399,6 +390,15 @@ public class XFramesView extends XDebugView {
myRunning = false;
}
+ private void selectTopFrame() {
+ if (!myStackFrames.isEmpty() && mySelectedStack != null) {
+ XStackFrame topFrame = myStackFrames.get(0);
+ myFramesList.setSelectedValue(topFrame, true);
+ mySession.setCurrentStackFrame(mySelectedStack, topFrame, true);
+ myListenersEnabled = true;
+ }
+ }
+
@SuppressWarnings("unchecked")
public void initModel(final DefaultListModel model) {
model.removeAllElements();
@@ -411,6 +411,7 @@ public class XFramesView extends XDebugView {
else if (!myAllFramesLoaded) {
model.addElement(null);
}
+ selectTopFrame();
}
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
index df43b1147419..ea53645b57e5 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
@@ -36,7 +36,8 @@ import static com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode.createIn
* @author nik
*/
public class XVariablesView extends XVariablesViewBase {
- public static final Key<Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>> DEBUG_VARIABLES = Key.create("debug.frame");
+ public static final Key<Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>> DEBUG_VARIABLES = Key.create("debug.variables");
+ public static final Key<Map<VirtualFile, Long>> DEBUG_VARIABLES_TIMESTAMPS = Key.create("debug.variables.timestamps");
public XVariablesView(@NotNull XDebugSessionImpl session) {
super(session.getProject(), session.getDebugProcess().getEditorsProvider(), session.getValueMarkers());
@@ -69,6 +70,7 @@ public class XVariablesView extends XVariablesViewBase {
protected void clear() {
XDebuggerTree tree = getTree();
tree.getProject().putUserData(DEBUG_VARIABLES, null);
+ tree.getProject().putUserData(DEBUG_VARIABLES_TIMESTAMPS, null);
tree.setSourcePosition(null);
XDebuggerTreeNode node;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
index ace9938318df..d4bd27c30d9b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
@@ -15,20 +15,42 @@
*/
package com.intellij.xdebugger.impl.frame;
+import com.intellij.codeInsight.hint.HintManager;
+import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.ide.dnd.DnDManager;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.event.SelectionEvent;
+import com.intellij.openapi.editor.event.SelectionListener;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
+import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.SimpleColoredComponent;
+import com.intellij.ui.SimpleColoredText;
import com.intellij.xdebugger.XDebuggerBundle;
+import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
+import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.frame.XValue;
+import com.intellij.xdebugger.frame.XValuePlace;
+import com.intellij.xdebugger.frame.presentation.XValuePresentation;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XEvaluationCallbackBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XStackFrameNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodePresentationConfigurator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,17 +73,84 @@ public abstract class XVariablesViewBase extends XDebugView {
DnDManager.getInstance().registerSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
}
- protected void buildTreeAndRestoreState(@NotNull XStackFrame stackFrame) {
+ protected void buildTreeAndRestoreState(@NotNull final XStackFrame stackFrame) {
XDebuggerTree tree = myDebuggerTreePanel.getTree();
- tree.setSourcePosition(stackFrame.getSourcePosition());
+ final XSourcePosition position = stackFrame.getSourcePosition();
+ tree.setSourcePosition(position);
tree.setRoot(new XStackFrameNode(tree, stackFrame), false);
- tree.getProject().putUserData(XVariablesView.DEBUG_VARIABLES, new HashMap<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>());
+ final Project project = tree.getProject();
+ project.putUserData(XVariablesView.DEBUG_VARIABLES, new HashMap<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>());
+ project.putUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS, new HashMap<VirtualFile, Long>());
Object newEqualityObject = stackFrame.getEqualityObject();
if (myFrameEqualityObject != null && newEqualityObject != null && myFrameEqualityObject.equals(newEqualityObject)
&& myTreeState != null) {
disposeTreeRestorer();
myTreeRestorer = myTreeState.restoreState(tree);
}
+ if (position != null && Registry.is("ide.debugger.inline")) {
+ final VirtualFile file = position.getFile();
+ final FileEditor fileEditor = FileEditorManagerEx.getInstanceEx(project).getSelectedEditor(file);
+ if (fileEditor instanceof PsiAwareTextEditorImpl) {
+ final Editor editor = ((PsiAwareTextEditorImpl)fileEditor).getEditor();
+ final SelectionListener listener = new SelectionListener() {
+ @Override
+ public void selectionChanged(SelectionEvent e) {
+ final String text = editor.getDocument().getText(e.getNewRange());
+ final XDebuggerEvaluator evaluator = stackFrame.getEvaluator();
+ if (evaluator != null && !StringUtil.isEmpty(text)
+ && !(text.contains("exec(") || text.contains("++") || text.contains("--") || text.contains("="))) {
+ evaluator.evaluate(text, new XEvaluationCallbackBase() {
+ @Override
+ public void evaluated(@NotNull XValue result) {
+ result.computePresentation(new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
+ @Override
+ public void applyPresentation(@Nullable Icon icon,
+ @NotNull XValuePresentation valuePresenter,
+ boolean hasChildren) {
+ SimpleColoredText text = new SimpleColoredText();
+ XValueNodeImpl.buildText(valuePresenter, text, false);
+ SimpleColoredComponent component = HintUtil.createInformationComponent();
+ text.appendToComponent(component);
+ String str = text.toString();
+ if ("undefined".equals(str) || str.startsWith("Cannot find local variable")
+ || str.startsWith("Invalid expression")) {
+ return; //todo[kb] this is temporary solution
+ }
+ HintManager.getInstance().hideAllHints();
+ HintManager.getInstance().showInformationHint(editor, component);
+ }
+
+ @Override
+ public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
+ }
+
+ @Override
+ public boolean isObsolete() {
+ return true;
+ }
+ }, XValuePlace.TOOLTIP);
+ }
+
+ @Override
+ public void errorOccurred(@NotNull String errorMessage) {
+ System.out.println(errorMessage);
+ }
+ }, position);
+ }
+ }
+ };
+ editor.getSelectionModel().addSelectionListener(listener);
+ Disposer.register(tree, new Disposable() {
+ @Override
+ public void dispose() {
+ final FileEditor fileEditor = FileEditorManagerEx.getInstanceEx(project).getSelectedEditor(file);
+ if (fileEditor instanceof PsiAwareTextEditorImpl) {
+ ((PsiAwareTextEditorImpl)fileEditor).getEditor().getSelectionModel().removeSelectionListener(listener);
+ }
+ }
+ });
+ }
+ }
}
protected void saveCurrentTreeState(@Nullable XStackFrame stackFrame) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form
index 4d1f8e52d24f..1260cb3ff44a 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.xdebugger.impl.settings.GeneralConfigurableUi">
- <grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" 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"/>
@@ -10,7 +10,7 @@
<children>
<component id="4b50" class="javax.swing.JCheckBox" binding="hideDebugWindowCheckBox">
<constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="2" 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>
<text resource-bundle="messages/XDebuggerBundle" key="setting.hide.window.label"/>
@@ -18,7 +18,7 @@
</component>
<vspacer id="8e2ed">
<constraints>
- <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"/>
+ <grid row="3" 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="fc652" class="javax.swing.JCheckBox" binding="focusApplicationOnBreakpointCheckBox" default-binding="true">
@@ -29,6 +29,14 @@
<text resource-bundle="messages/XDebuggerBundle" key="setting.focus.app.on.breakpoint.label"/>
</properties>
</component>
+ <component id="4c3e" class="javax.swing.JCheckBox" binding="myShowDebugWindowOnCheckBox" default-binding="true">
+ <constraints>
+ <grid row="1" 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>
+ <text resource-bundle="messages/XDebuggerBundle" key="settings.show.window.label"/>
+ </properties>
+ </component>
</children>
</grid>
</form>
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java
index 273c5490e35d..bab2c88465ad 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java
@@ -25,23 +25,27 @@ class GeneralConfigurableUi implements ConfigurableUi<XDebuggerGeneralSettings>
private JPanel rootPanel;
private JCheckBox hideDebugWindowCheckBox;
private JCheckBox focusApplicationOnBreakpointCheckBox;
+ private JCheckBox myShowDebugWindowOnCheckBox;
@Override
public void reset(@NotNull XDebuggerGeneralSettings settings) {
focusApplicationOnBreakpointCheckBox.setSelected(Registry.is("debugger.mayBringFrameToFrontOnBreakpoint"));
hideDebugWindowCheckBox.setSelected(settings.isHideDebuggerOnProcessTermination());
+ myShowDebugWindowOnCheckBox.setSelected(settings.isShowDebuggerOnBreakpoint());
}
@Override
public boolean isModified(@NotNull XDebuggerGeneralSettings settings) {
return focusApplicationOnBreakpointCheckBox.isSelected() != Registry.is("debugger.mayBringFrameToFrontOnBreakpoint") ||
- hideDebugWindowCheckBox.isSelected() != settings.isHideDebuggerOnProcessTermination();
+ hideDebugWindowCheckBox.isSelected() != settings.isHideDebuggerOnProcessTermination() ||
+ myShowDebugWindowOnCheckBox.isSelected() != settings.isShowDebuggerOnBreakpoint();
}
@Override
public void apply(@NotNull XDebuggerGeneralSettings settings) {
Registry.get("debugger.mayBringFrameToFrontOnBreakpoint").setValue(focusApplicationOnBreakpointCheckBox.isSelected());
settings.setHideDebuggerOnProcessTermination(hideDebugWindowCheckBox.isSelected());
+ settings.setShowDebuggerOnBreakpoint(myShowDebugWindowOnCheckBox.isSelected());
}
@NotNull
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java
index 9720d9517c51..205c1c3948ed 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java
@@ -27,6 +27,7 @@ public class XDebuggerGeneralSettings {
private boolean myUnmuteOnStop = false;
private boolean hideDebuggerOnProcessTermination;
+ private boolean myShowDebuggerOnBreakpoint = true;
@Tag("evaluation-dialog-mode")
public EvaluationMode getEvaluationDialogMode() {
@@ -53,4 +54,12 @@ public class XDebuggerGeneralSettings {
public void setHideDebuggerOnProcessTermination(boolean hideDebuggerOnProcessTermination) {
this.hideDebuggerOnProcessTermination = hideDebuggerOnProcessTermination;
}
+
+ public boolean isShowDebuggerOnBreakpoint() {
+ return myShowDebuggerOnBreakpoint;
+ }
+
+ public void setShowDebuggerOnBreakpoint(boolean showDebuggerOnBreakpoint) {
+ this.myShowDebuggerOnBreakpoint = showDebuggerOnBreakpoint;
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java
new file mode 100644
index 000000000000..7041b24f07fc
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java
@@ -0,0 +1,47 @@
+/*
+ * 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.ui;
+
+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.RawText;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author egor
+ */
+public class DebuggerCopyPastePreprocessor implements CopyPastePreProcessor {
+ public static final Key<Boolean> REMOVE_NEWLINES_ON_PASTE = new Key<Boolean>("REMOVE_NEWLINES_ON_PASTE");
+
+ @Nullable
+ @Override
+ public String preprocessOnCopy(PsiFile file, int[] startOffsets, int[] endOffsets, String text) {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public String preprocessOnPaste(Project project, PsiFile file, Editor editor, String text, RawText rawText) {
+ if (editor.getUserData(REMOVE_NEWLINES_ON_PASTE) != null) {
+ return text.replace("\n", " ");
+ }
+ return text;
+ }
+}
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 4c3766f23f5d..1a4505f6d85b 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
@@ -227,6 +227,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
final Executor debugExecutor = DefaultDebugExecutor.getDebugExecutorInstance();
ExecutionEnvironment environment = getEnvironment();
if (environment != null) {
+ leftToolbar.add(ActionManager.getInstance().getAction(IdeActions.ACTION_RERUN));
List<AnAction> additionalRestartActions = session.getRestartActions();
if (!additionalRestartActions.isEmpty()) {
leftToolbar.addAll(additionalRestartActions);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
index 991036b7f438..61a499ccf4dd 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
@@ -59,7 +59,7 @@ public abstract class XDebuggerEditorBase {
private final XDebuggerEditorsProvider myDebuggerEditorsProvider;
@NotNull private final EvaluationMode myMode;
@Nullable private final String myHistoryId;
- private final XSourcePosition mySourcePosition;
+ @Nullable private XSourcePosition mySourcePosition;
private int myHistoryIndex;
private final JLabel myChooseFactory = new JLabel();
@@ -124,6 +124,13 @@ public abstract class XDebuggerEditorBase {
return panel;
}
+ public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
+ if (mySourcePosition != sourcePosition) {
+ mySourcePosition = sourcePosition;
+ setExpression(getExpression(), false);
+ }
+ }
+
@NotNull
public EvaluationMode getMode() {
return myMode;
@@ -137,10 +144,16 @@ public abstract class XDebuggerEditorBase {
protected abstract void doSetText(XExpression text);
public void setExpression(@Nullable XExpression text) {
+ setExpression(text, true);
+ }
+
+ private void setExpression(@Nullable XExpression text, boolean saveInHistory) {
if (text == null) {
text = getMode() == EvaluationMode.EXPRESSION ? XExpressionImpl.EMPTY_EXPRESSION : XExpressionImpl.EMPTY_CODE_FRAGMENT;
}
- saveTextInHistory(text);
+ if (saveInHistory) {
+ saveTextInHistory(text);
+ }
Language language = text.getLanguage();
if (language == null) {
if (mySourcePosition != null) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
index 051683b875c1..3039d2acda7f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
@@ -17,9 +17,7 @@ package com.intellij.xdebugger.impl.ui;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.editor.event.DocumentListener;
+import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.ui.EditorComboBoxEditor;
@@ -101,6 +99,11 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
}
super.setItem(createDocument(((XExpression)anObject)));
}
+
+ @Override
+ protected void onEditorCreate(EditorEx editor) {
+ editor.putUserData(DebuggerCopyPastePreprocessor.REMOVE_NEWLINES_ON_PASTE, true);
+ }
};
myEditor.getEditorComponent().setFontInheritedFromLAF(false);
myComboBox.setEditor(myEditor);
@@ -110,23 +113,6 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
}
@Override
- protected Document createDocument(XExpression text) {
- Document document = super.createDocument(text);
- document.addDocumentListener(REPLACE_NEWLINES_LISTENER);
- return document;
- }
-
- private static DocumentListener REPLACE_NEWLINES_LISTENER = new DocumentAdapter() {
- @Override
- public void documentChanged(DocumentEvent e) {
- String text = e.getNewFragment().toString();
- if (text.contains("\n")) {
- e.getDocument().replaceString(e.getOffset(), e.getOffset() + e.getNewLength(), text.replace('\n', ' '));
- }
- }
- };
-
- @Override
protected void onHistoryChanged() {
fillComboBox();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
index aa3445b4b421..3f06418ac8ac 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
@@ -71,7 +71,7 @@ public class XDebuggerMultilineEditor extends XDebuggerEditorBase {
@Override
public XExpression getExpression() {
- return XExpressionImpl.fromText(myEditorTextField.getText(), EvaluationMode.CODE_FRAGMENT);
+ return getEditorsProvider().createExpression(getProject(), myEditorTextField.getDocument(), myExpression.getLanguage(), EvaluationMode.CODE_FRAGMENT);
}
@Override
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java
new file mode 100644
index 000000000000..4c2962f7f576
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java
@@ -0,0 +1,51 @@
+/*
+ * 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.ui.tree.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.xdebugger.XDebuggerBundle;
+import com.intellij.xdebugger.frame.XReferrersProvider;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
+import com.intellij.xdebugger.impl.ui.tree.XInspectDialog;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author egor
+ */
+public class ShowReferringObjectsAction extends XDebuggerTreeActionBase {
+
+ @Override
+ protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
+ return node.getValueContainer().getReferrersProvider() != null;
+ }
+
+ @Override
+ protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) {
+ XReferrersProvider referrersProvider = node.getValueContainer().getReferrersProvider();
+ if (referrersProvider != null) {
+ XDebuggerTree tree = XDebuggerTree.getTree(e.getDataContext());
+ XInspectDialog dialog = new XInspectDialog(tree.getProject(),
+ tree.getEditorsProvider(),
+ tree.getSourcePosition(),
+ nodeName,
+ referrersProvider.getReferringObjectsValue(),
+ tree.getValueMarkers());
+ dialog.setTitle(XDebuggerBundle.message("showReferring.dialog.title", nodeName));
+ dialog.show();
+ }
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
index 7c77bafc6553..211fddae40ea 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
@@ -23,6 +23,7 @@ import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
import com.intellij.xdebugger.impl.frame.XWatchesView;
+import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
@@ -41,10 +42,7 @@ class XAddToWatchesAction extends XDebuggerTreeActionBase {
if (watchesView != null) {
String expression = node.getValueContainer().getEvaluationExpression();
if (!StringUtil.isEmpty(expression)) {
- XExpressionImpl watchExpression = XExpressionImpl.fromText(expression);
- if (watchExpression != null) {
- watchesView.addWatchExpression(watchExpression, -1, true);
- }
+ watchesView.addWatchExpression(XExpressionImpl.fromText(expression), -1, true);
}
}
}
@@ -55,7 +53,10 @@ class XAddToWatchesAction extends XDebuggerTreeActionBase {
if (view == null && project != null) {
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
if (session != null) {
- return ((XDebugSessionImpl)session).getSessionTab().getWatchesView();
+ XDebugSessionTab tab = ((XDebugSessionImpl)session).getSessionTab();
+ if (tab != null) {
+ return tab.getWatchesView();
+ }
}
}
return view;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java
index fa32ebcc4d75..b7b21560f438 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java
@@ -15,7 +15,16 @@
*/
package com.intellij.xdebugger.impl.ui.tree.nodes;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XExpression;
+import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.frame.XValue;
+import com.intellij.xdebugger.frame.XValueChildrenList;
+import com.intellij.xdebugger.impl.XDebugSessionImpl;
+import com.intellij.xdebugger.impl.frame.XDebugView;
+import com.intellij.xdebugger.impl.ui.XDebugSessionData;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import org.jetbrains.annotations.NotNull;
@@ -27,4 +36,32 @@ public class XStackFrameNode extends XValueContainerNode<XStackFrame> {
super(tree, null, xStackFrame);
setLeaf(false);
}
+
+ @Override
+ public void startComputingChildren() {
+ if (Registry.is("debugger.watches.in.variables")) {
+ XDebugSession session = XDebugView.getSession(getTree());
+ XDebuggerEvaluator evaluator = getValueContainer().getEvaluator();
+ if (session != null && evaluator != null) {
+ XDebugSessionData data = ((XDebugSessionImpl)session).getSessionData();
+ XExpression[] expressions = data.getWatchExpressions();
+ for (final XExpression expression : expressions) {
+ evaluator.evaluate(expression, new XDebuggerEvaluator.XEvaluationCallback() {
+ @Override
+ public void evaluated(@NotNull XValue result) {
+ XValueChildrenList watches = new XValueChildrenList();
+ watches.add(expression.getExpression(), result);
+ addChildren(watches, false);
+ }
+
+ @Override
+ public void errorOccurred(@NotNull String errorMessage) {
+ // do not add anything
+ }
+ }, getValueContainer().getSourcePosition());
+ }
+ }
+ }
+ super.startComputingChildren();
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
index b9f90fe86b2b..a2fb3d51d253 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.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.
@@ -15,6 +15,7 @@
*/
package com.intellij.xdebugger.impl.ui.tree.nodes;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ObjectUtils;
import com.intellij.util.SmartList;
@@ -90,6 +91,11 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
XValueNodeImpl node = new XValueNodeImpl(myTree, XValueContainerNode.this, children.getName(i), children.getValue(i));
myValueChildren.add(node);
newChildren.add(node);
+
+ if (Registry.is("ide.debugger.inline") && "this".equals(node.getName())) { //todo[kb]: try to generify this dirty hack
+ //initialize "this" fields to display in inline view
+ node.getChildren();
+ }
}
myTopGroups = createGroupNodes(children.getTopGroups(), myTopGroups, newChildren);
myBottomGroups = createGroupNodes(children.getBottomGroups(), myBottomGroups, newChildren);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
index 1f3d4c77e84f..292cca541699 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
@@ -16,6 +16,8 @@
package com.intellij.xdebugger.impl.ui.tree.nodes;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -24,9 +26,11 @@ import com.intellij.ui.AppUIUtil;
import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.NotNullFunction;
+import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
+import com.intellij.xdebugger.impl.frame.XDebugView;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.frame.XVariablesView;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
@@ -120,26 +124,7 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
myValuePresentation = valuePresentation;
myRawValue = XValuePresentationUtil.computeValueText(valuePresentation);
if (Registry.is("ide.debugger.inline")) {
- try {
- getValueContainer().computeSourcePosition(new XNavigatable() {
- @Override
- public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
- Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES);
- if (map == null || sourcePosition == null) return;
- VirtualFile file = sourcePosition.getFile();
- int line = sourcePosition.getLine();
- Pair<VirtualFile, Integer> key = Pair.create(file, line);
- Set<XValueNodeImpl> presentations = map.get(key);
- if (presentations == null) {
- presentations = new LinkedHashSet<XValueNodeImpl>();
- map.put(key, presentations);
- }
- presentations.add(XValueNodeImpl.this);
- }
- });
- }
- catch (Exception ignore) {
- }
+ updateInlineDebuggerData();
}
updateText();
setLeaf(!hasChildren);
@@ -147,6 +132,39 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
myTree.nodeLoaded(this, myName);
}
+ public void updateInlineDebuggerData() {
+ try {
+ final XDebugSession session = XDebugView.getSession(getTree());
+ if (session != null) {
+ final XSourcePosition position = session.getCurrentPosition();
+ if (position != null) {
+ getValueContainer().computeSourcePosition(new XNearestSourcePosition() {
+ @Override
+ public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
+ final Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES);
+ final Map<VirtualFile, Long> timestamps = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS);
+ if (map == null || timestamps == null || sourcePosition == null) return;
+ VirtualFile file = sourcePosition.getFile();
+ final Document doc = FileDocumentManager.getInstance().getDocument(file);
+ if (doc == null) return;
+ int line = sourcePosition.getLine();
+ Pair<VirtualFile, Integer> key = Pair.create(file, line);
+ Set<XValueNodeImpl> presentations = map.get(key);
+ if (presentations == null) {
+ presentations = new LinkedHashSet<XValueNodeImpl>();
+ map.put(key, presentations);
+ timestamps.put(file, doc.getModificationStamp());
+ }
+ presentations.add(XValueNodeImpl.this);
+ }
+ });
+ }
+ }
+ }
+ catch (Exception ignore) {
+ }
+ }
+
@Override
public void setFullValueEvaluator(@NotNull final XFullValueEvaluator fullValueEvaluator) {
AppUIUtil.invokeOnEdt(new Runnable() {
@@ -179,7 +197,13 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
}
public static void buildText(@NotNull XValuePresentation valuePresenter, @NotNull ColoredTextContainer text) {
- XValuePresentationUtil.appendSeparator(text, valuePresenter.getSeparator());
+ buildText(valuePresenter, text, true);
+ }
+
+ public static void buildText(@NotNull XValuePresentation valuePresenter, @NotNull ColoredTextContainer text, boolean appendSeparator) {
+ if (appendSeparator) {
+ XValuePresentationUtil.appendSeparator(text, valuePresenter.getSeparator());
+ }
String type = valuePresenter.getType();
if (type != null) {
text.append("{" + type + "} ", XDebuggerUIConstants.TYPE_ATTRIBUTES);