2 * Copyright (c) 2004 JetBrains s.r.o. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * -Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * -Redistribution in binary form must reproduct the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the distribution.
15 * Neither the name of JetBrains or IntelliJ IDEA
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * This software is provided "AS IS," without a warranty of any kind. ALL
20 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
21 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
22 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT
23 * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT
24 * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS
25 * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST
26 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
27 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
28 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN
29 * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32 package com
.intellij
.openapi
.vcs
.impl
;
34 import com
.intellij
.openapi
.application
.ApplicationManager
;
35 import com
.intellij
.openapi
.application
.ModalityState
;
36 import com
.intellij
.openapi
.components
.ProjectComponent
;
37 import com
.intellij
.openapi
.diagnostic
.Logger
;
38 import com
.intellij
.openapi
.editor
.DisposableEditorPanel
;
39 import com
.intellij
.openapi
.editor
.Editor
;
40 import com
.intellij
.openapi
.editor
.EditorFactory
;
41 import com
.intellij
.openapi
.editor
.EditorSettings
;
42 import com
.intellij
.openapi
.editor
.markup
.TextAttributes
;
43 import com
.intellij
.openapi
.extensions
.Extensions
;
44 import com
.intellij
.openapi
.progress
.ProcessCanceledException
;
45 import com
.intellij
.openapi
.project
.DumbAwareRunnable
;
46 import com
.intellij
.openapi
.project
.Project
;
47 import com
.intellij
.openapi
.startup
.StartupManager
;
48 import com
.intellij
.openapi
.util
.*;
49 import com
.intellij
.openapi
.util
.io
.FileUtil
;
50 import com
.intellij
.openapi
.vcs
.*;
51 import com
.intellij
.openapi
.vcs
.changes
.ChangesUtil
;
52 import com
.intellij
.openapi
.vcs
.checkin
.CheckinHandlerFactory
;
53 import com
.intellij
.openapi
.vcs
.checkout
.CompositeCheckoutListener
;
54 import com
.intellij
.openapi
.vcs
.ex
.ProjectLevelVcsManagerEx
;
55 import com
.intellij
.openapi
.vcs
.impl
.projectlevelman
.*;
56 import com
.intellij
.openapi
.vcs
.update
.ActionInfo
;
57 import com
.intellij
.openapi
.vcs
.update
.UpdateInfoTree
;
58 import com
.intellij
.openapi
.vcs
.update
.UpdatedFiles
;
59 import com
.intellij
.openapi
.vfs
.LocalFileSystem
;
60 import com
.intellij
.openapi
.vfs
.VirtualFile
;
61 import com
.intellij
.openapi
.wm
.ToolWindow
;
62 import com
.intellij
.openapi
.wm
.ToolWindowAnchor
;
63 import com
.intellij
.openapi
.wm
.ToolWindowId
;
64 import com
.intellij
.openapi
.wm
.ToolWindowManager
;
65 import com
.intellij
.ui
.content
.Content
;
66 import com
.intellij
.ui
.content
.ContentFactory
;
67 import com
.intellij
.ui
.content
.ContentManager
;
68 import com
.intellij
.util
.ContentsUtil
;
69 import com
.intellij
.util
.EventDispatcher
;
70 import com
.intellij
.util
.Icons
;
71 import com
.intellij
.util
.Processor
;
72 import com
.intellij
.util
.containers
.Convertor
;
73 import com
.intellij
.util
.ui
.EditorAdapter
;
74 import org
.jdom
.Element
;
75 import org
.jetbrains
.annotations
.NonNls
;
76 import org
.jetbrains
.annotations
.NotNull
;
77 import org
.jetbrains
.annotations
.Nullable
;
81 public class ProjectLevelVcsManagerImpl
extends ProjectLevelVcsManagerEx
implements ProjectComponent
, JDOMExternalizable
{
82 private static final Logger LOG
= Logger
.getInstance("#com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl");
84 private final ProjectLevelVcsManagerSerialization mySerialization
;
85 private final OptionsAndConfirmations myOptionsAndConfirmations
;
87 private NewMappings myMappings
;
88 private final Project myProject
;
89 private MappingsToRoots myMappingsToRoots
;
91 private volatile boolean myIsDisposed
= false;
92 private final Object myDisposeLock
= new Object();
94 private ContentManager myContentManager
;
95 private EditorAdapter myEditorAdapter
;
97 @NonNls private static final String ELEMENT_MAPPING
= "mapping";
98 @NonNls private static final String ATTRIBUTE_DIRECTORY
= "directory";
99 @NonNls private static final String ATTRIBUTE_VCS
= "vcs";
100 @NonNls private static final String ATTRIBUTE_DEFAULT_PROJECT
= "defaultProject";
101 @NonNls private static final String ELEMENT_ROOT_SETTINGS
= "rootSettings";
102 @NonNls private static final String ATTRIBUTE_CLASS
= "class";
104 private final List
<CheckinHandlerFactory
> myRegisteredBeforeCheckinHandlers
= new ArrayList
<CheckinHandlerFactory
>();
105 private final EventDispatcher
<VcsListener
> myEventDispatcher
= EventDispatcher
.create(VcsListener
.class);
106 private boolean myMappingsLoaded
= false;
107 private boolean myHaveLegacyVcsConfiguration
= false;
108 private boolean myCheckinHandlerFactoriesLoaded
= false;
109 private DefaultVcsRootPolicy myDefaultVcsRootPolicy
;
111 private volatile int myBackgroundOperationCounter
= 0;
113 private final Map
<VcsBackgroundableActions
, BackgroundableActionEnabledHandler
> myBackgroundableActionHandlerMap
;
115 private List
<Pair
<String
, TextAttributes
>> myPendingOutput
= new ArrayList
<Pair
<String
, TextAttributes
>>();
117 public ProjectLevelVcsManagerImpl(Project project
) {
119 mySerialization
= new ProjectLevelVcsManagerSerialization();
120 myOptionsAndConfirmations
= new OptionsAndConfirmations();
122 myDefaultVcsRootPolicy
= DefaultVcsRootPolicy
.getInstance(project
);
124 myMappings
= new NewMappings(myProject
, myEventDispatcher
);
125 myMappingsToRoots
= new MappingsToRoots(myMappings
, myProject
);
126 myBackgroundableActionHandlerMap
= new HashMap
<VcsBackgroundableActions
, BackgroundableActionEnabledHandler
>();
129 public void initComponent() {
130 myOptionsAndConfirmations
.init(new Convertor
<String
, VcsShowConfirmationOption
.Value
>() {
131 public VcsShowConfirmationOption
.Value
convert(String o
) {
132 return mySerialization
.getInitOptionValue(o
);
137 public void registerVcs(AbstractVcs vcs
) {
138 AllVcses
.getInstance(myProject
).registerManually(vcs
);
142 public AbstractVcs
findVcsByName(String name
) {
143 if (name
== null) return null;
144 if (myProject
.isDisposed()) return null;
145 return AllVcses
.getInstance(myProject
).getByName(name
);
148 public AbstractVcs
[] getAllVcss() {
149 return AllVcses
.getInstance(myProject
).getAll();
152 public boolean haveVcses() {
153 return ! AllVcses
.getInstance(myProject
).isEmpty();
156 public void disposeComponent() {
157 if (ApplicationManager
.getApplication().isUnitTestMode()) {
162 public void projectOpened() {
163 final StartupManager manager
= StartupManager
.getInstance(myProject
);
164 manager
.registerPostStartupActivity(new DumbAwareRunnable() {
166 ToolWindowManager toolWindowManager
= ToolWindowManager
.getInstance(myProject
);
167 if (toolWindowManager
!= null) { // Can be null in tests
168 ToolWindow toolWindow
=
169 toolWindowManager
.registerToolWindow(ToolWindowId
.VCS
, true, ToolWindowAnchor
.BOTTOM
, myProject
, true);
170 myContentManager
= toolWindow
.getContentManager();
171 toolWindow
.setIcon(Icons
.VCS_SMALL_TAB
);
172 toolWindow
.installWatcher(myContentManager
);
174 myContentManager
= ContentFactory
.SERVICE
.getInstance().createContentManager(true, myProject
);
180 public void projectClosed() {
185 public String
getComponentName() {
186 return "ProjectLevelVcsManager";
189 public boolean checkAllFilesAreUnder(AbstractVcs abstractVcs
, VirtualFile
[] files
) {
190 if (files
== null) return false;
191 for (VirtualFile file
: files
) {
192 if (getVcsFor(file
) != abstractVcs
) {
200 public AbstractVcs
getVcsFor(@NotNull VirtualFile file
) {
201 final String vcsName
= myMappings
.getVcsFor(file
);
202 if (vcsName
== null || vcsName
.length() == 0) {
205 return AllVcses
.getInstance(myProject
).getByName(vcsName
);
209 public AbstractVcs
getVcsFor(final FilePath file
) {
210 return ApplicationManager
.getApplication().runReadAction(new Computable
<AbstractVcs
>() {
212 public AbstractVcs
compute() {
213 if (! myProject
.isInitialized()) return null;
214 if (myProject
.isDisposed()) throw new ProcessCanceledException();
215 VirtualFile vFile
= ChangesUtil
.findValidParent(file
);
217 return getVcsFor(vFile
);
225 public VirtualFile
getVcsRootFor(final VirtualFile file
) {
226 final VcsDirectoryMapping mapping
= myMappings
.getMappingFor(file
);
227 if (mapping
== null) {
230 final String directory
= mapping
.getDirectory();
231 if (directory
.length() == 0) {
232 return myDefaultVcsRootPolicy
.getVcsRootFor(file
);
234 return LocalFileSystem
.getInstance().findFileByPath(directory
);
238 public VirtualFile
getVcsRootFor(final FilePath file
) {
239 return ApplicationManager
.getApplication().runReadAction(new Computable
<VirtualFile
>() {
241 public VirtualFile
compute() {
242 VirtualFile vFile
= ChangesUtil
.findValidParent(file
);
244 return getVcsRootFor(vFile
);
251 private void dispose() {
252 // todo dispose lock is bad here..
253 synchronized (myDisposeLock
) {
254 if (myIsDisposed
) return;
256 myMappings
.disposeMe();
258 myContentManager
= null;
260 ToolWindowManager toolWindowManager
= ToolWindowManager
.getInstance(myProject
);
261 if (toolWindowManager
!= null && toolWindowManager
.getToolWindow(ToolWindowId
.VCS
) != null) {
262 toolWindowManager
.unregisterToolWindow(ToolWindowId
.VCS
);
271 public void unregisterVcs(AbstractVcs vcs
) {
272 if ((! ApplicationManager
.getApplication().isUnitTestMode()) && (myMappings
.haveActiveVcs(vcs
.getName()))) {
274 LOG
.warn("Active vcs '" + vcs
.getName() + "' is being unregistered. Remove from mappings first.");
276 myMappings
.beingUnregistered(vcs
.getName());
277 AllVcses
.getInstance(myProject
).unregisterManually(vcs
);
280 public ContentManager
getContentManager() {
281 return myContentManager
;
284 public boolean checkVcsIsActive(AbstractVcs vcs
) {
285 return checkVcsIsActive(vcs
.getName());
288 public boolean checkVcsIsActive(final String vcsName
) {
289 return myMappings
.haveActiveVcs(vcsName
);
292 public AbstractVcs
[] getAllActiveVcss() {
293 return myMappings
.getActiveVcses();
296 public boolean hasAnyMappings() {
297 return ! myMappings
.isEmpty();
300 public void addMessageToConsoleWindow(final String message
, final TextAttributes attributes
) {
301 ApplicationManager
.getApplication().invokeLater(new Runnable() {
303 // for default and disposed projects the ContentManager is not available.
304 if (myProject
.isDisposed() || myProject
.isDefault()) return;
305 final ContentManager contentManager
= getContentManager();
306 if (contentManager
== null) {
307 myPendingOutput
.add(new Pair
<String
, TextAttributes
>(message
, attributes
));
310 getOrCreateConsoleContent(contentManager
);
311 myEditorAdapter
.appendString(message
, attributes
);
314 }, ModalityState
.defaultModalityState());
317 private Content
getOrCreateConsoleContent(final ContentManager contentManager
) {
318 final String displayName
= VcsBundle
.message("vcs.console.toolwindow.display.name");
319 Content content
= contentManager
.findContent(displayName
);
320 if (content
== null) {
321 final EditorFactory editorFactory
= EditorFactory
.getInstance();
322 final Editor editor
= editorFactory
.createViewer(editorFactory
.createDocument(""));
323 EditorSettings editorSettings
= editor
.getSettings();
324 editorSettings
.setLineMarkerAreaShown(false);
325 editorSettings
.setLineNumbersShown(false);
326 editorSettings
.setFoldingOutlineShown(false);
328 myEditorAdapter
= new EditorAdapter(editor
, myProject
);
329 content
= ContentFactory
.SERVICE
.getInstance().createContent(new DisposableEditorPanel(editor
), displayName
, true);
330 contentManager
.addContent(content
);
332 for (Pair
<String
, TextAttributes
> pair
: myPendingOutput
) {
333 myEditorAdapter
.appendString(pair
.first
, pair
.second
);
335 myPendingOutput
.clear();
341 public VcsShowSettingOption
getOptions(VcsConfiguration
.StandardOption option
) {
342 return myOptionsAndConfirmations
.getOptions(option
);
345 public List
<VcsShowOptionsSettingImpl
> getAllOptions() {
346 return myOptionsAndConfirmations
.getAllOptions();
350 public VcsShowSettingOption
getStandardOption(@NotNull VcsConfiguration
.StandardOption option
, @NotNull AbstractVcs vcs
) {
351 final VcsShowOptionsSettingImpl options
= (VcsShowOptionsSettingImpl
) getOptions(option
);
352 options
.addApplicableVcs(vcs
);
357 public VcsShowSettingOption
getOrCreateCustomOption(@NotNull String vcsActionName
, @NotNull AbstractVcs vcs
) {
358 return myOptionsAndConfirmations
.getOrCreateCustomOption(vcsActionName
, vcs
);
361 public void showProjectOperationInfo(final UpdatedFiles updatedFiles
, String displayActionName
) {
362 showUpdateProjectInfo(updatedFiles
, displayActionName
, ActionInfo
.STATUS
);
365 public UpdateInfoTree
showUpdateProjectInfo(UpdatedFiles updatedFiles
, String displayActionName
, ActionInfo actionInfo
) {
366 synchronized (myDisposeLock
) {
367 if (myIsDisposed
) return null;
368 ContentManager contentManager
= getContentManager();
369 if (contentManager
== null) {
370 return null; // content manager is made null during dispose; flag is set later
372 final UpdateInfoTree updateInfoTree
= new UpdateInfoTree(contentManager
, myProject
, updatedFiles
, displayActionName
, actionInfo
);
373 Content content
= ContentFactory
.SERVICE
.getInstance().createContent(updateInfoTree
, VcsBundle
.message(
374 "toolwindow.title.update.action.info", displayActionName
), true);
375 Disposer
.register(content
, updateInfoTree
);
376 ContentsUtil
.addContent(contentManager
, content
, true);
377 ToolWindowManager
.getInstance(myProject
).getToolWindow(ToolWindowId
.VCS
).activate(null);
378 updateInfoTree
.expandRootChildren();
379 return updateInfoTree
;
383 public void cleanupMappings() {
384 myMappings
.cleanupMappings();
387 public List
<VcsDirectoryMapping
> getDirectoryMappings() {
388 return myMappings
.getDirectoryMappings();
391 public List
<VcsDirectoryMapping
> getDirectoryMappings(final AbstractVcs vcs
) {
392 return myMappings
.getDirectoryMappings(vcs
.getName());
396 public VcsDirectoryMapping
getDirectoryMappingFor(final FilePath path
) {
397 return ApplicationManager
.getApplication().runReadAction(new Computable
<VcsDirectoryMapping
>() {
399 public VcsDirectoryMapping
compute() {
400 VirtualFile vFile
= ChangesUtil
.findValidParent(path
);
402 return myMappings
.getMappingFor(vFile
);
409 public boolean hasExplicitMapping(final FilePath f
) {
410 VirtualFile vFile
= ChangesUtil
.findValidParent(f
);
411 if (vFile
== null) return false;
412 return hasExplicitMapping(vFile
);
415 public boolean hasExplicitMapping(final VirtualFile vFile
) {
416 final VcsDirectoryMapping mapping
= myMappings
.getMappingFor(vFile
);
417 return mapping
!= null && (! mapping
.isDefaultMapping());
420 public void setDirectoryMapping(final String path
, final String activeVcsName
) {
421 if (myMappingsLoaded
) return; // ignore per-module VCS settings if the mapping table was loaded from .ipr
422 myHaveLegacyVcsConfiguration
= true;
423 myMappings
.setMapping(FileUtil
.toSystemIndependentName(path
), activeVcsName
);
426 public void setAutoDirectoryMapping(String path
, String activeVcsName
) {
427 myMappings
.setMapping(path
, activeVcsName
);
430 public void removeDirectoryMapping(VcsDirectoryMapping mapping
) {
431 myMappings
.removeDirectoryMapping(mapping
);
434 public void setDirectoryMappings(final List
<VcsDirectoryMapping
> items
) {
435 myMappings
.setDirectoryMappings(items
);
438 public void iterateVcsRoot(final VirtualFile root
, final Processor
<FilePath
> iterator
) {
439 VcsRootIterator
.iterateVcsRoot(myProject
, root
, iterator
);
442 public void readExternal(Element element
) throws InvalidDataException
{
443 mySerialization
.readExternalUtil(element
, myOptionsAndConfirmations
);
446 public void writeExternal(Element element
) throws WriteExternalException
{
447 mySerialization
.writeExternalUtil(element
, myOptionsAndConfirmations
);
451 public VcsShowConfirmationOption
getStandardConfirmation(@NotNull VcsConfiguration
.StandardConfirmation option
,
452 @NotNull AbstractVcs vcs
) {
453 final VcsShowConfirmationOptionImpl result
= getConfirmation(option
);
454 result
.addApplicableVcs(vcs
);
458 public List
<VcsShowConfirmationOptionImpl
> getAllConfirmations() {
459 return myOptionsAndConfirmations
.getAllConfirmations();
463 public VcsShowConfirmationOptionImpl
getConfirmation(VcsConfiguration
.StandardConfirmation option
) {
464 return myOptionsAndConfirmations
.getConfirmation(option
);
467 public List
<CheckinHandlerFactory
> getRegisteredCheckinHandlerFactories() {
468 if (!myCheckinHandlerFactoriesLoaded
) {
469 myCheckinHandlerFactoriesLoaded
= true;
470 Collections
.addAll(myRegisteredBeforeCheckinHandlers
, Extensions
.getExtensions(CheckinHandlerFactory
.EP_NAME
, myProject
));
472 return Collections
.unmodifiableList(myRegisteredBeforeCheckinHandlers
);
475 public void registerCheckinHandlerFactory(CheckinHandlerFactory factory
) {
476 myRegisteredBeforeCheckinHandlers
.add(factory
);
479 public void unregisterCheckinHandlerFactory(CheckinHandlerFactory handler
) {
480 myRegisteredBeforeCheckinHandlers
.remove(handler
);
483 public void addVcsListener(VcsListener listener
) {
484 myEventDispatcher
.addListener(listener
);
487 public void removeVcsListener(VcsListener listener
) {
488 myEventDispatcher
.removeListener(listener
);
491 public void startBackgroundVcsOperation() {
492 myBackgroundOperationCounter
++;
495 public void stopBackgroundVcsOperation() {
496 // in fact, the condition is "should not be called under ApplicationManager.invokeLater() and similiar"
497 assert ! ApplicationManager
.getApplication().isDispatchThread();
498 LOG
.assertTrue(myBackgroundOperationCounter
> 0, "myBackgroundOperationCounter > 0");
499 myBackgroundOperationCounter
--;
502 public boolean isBackgroundVcsOperationRunning() {
503 return myBackgroundOperationCounter
> 0;
506 public VirtualFile
[] getRootsUnderVcs(AbstractVcs vcs
) {
507 return myMappingsToRoots
.getRootsUnderVcs(vcs
);
510 public VirtualFile
[] getAllVersionedRoots() {
511 List
<VirtualFile
> vFiles
= new ArrayList
<VirtualFile
>();
512 final AbstractVcs
[] vcses
= myMappings
.getActiveVcses();
513 for (AbstractVcs vcs
: vcses
) {
514 Collections
.addAll(vFiles
, getRootsUnderVcs(vcs
));
516 return vFiles
.toArray(new VirtualFile
[vFiles
.size()]);
520 public VcsRoot
[] getAllVcsRoots() {
521 List
<VcsRoot
> vcsRoots
= new ArrayList
<VcsRoot
>();
522 final AbstractVcs
[] vcses
= myMappings
.getActiveVcses();
523 for (AbstractVcs vcs
: vcses
) {
524 final VirtualFile
[] roots
= getRootsUnderVcs(vcs
);
525 for(VirtualFile root
: roots
) {
526 vcsRoots
.add(new VcsRoot(vcs
, root
));
529 return vcsRoots
.toArray(new VcsRoot
[vcsRoots
.size()]);
532 public void updateActiveVcss() {
536 public void notifyDirectoryMappingChanged() {
537 myEventDispatcher
.getMulticaster().directoryMappingChanged();
540 public void readDirectoryMappings(final Element element
) {
543 final List
<VcsDirectoryMapping
> mappingsList
= new ArrayList
<VcsDirectoryMapping
>();
544 final List list
= element
.getChildren(ELEMENT_MAPPING
);
545 boolean haveNonEmptyMappings
= false;
546 for(Object childObj
: list
) {
547 Element child
= (Element
) childObj
;
548 final String vcs
= child
.getAttributeValue(ATTRIBUTE_VCS
);
549 if (vcs
!= null && vcs
.length() > 0) {
550 haveNonEmptyMappings
= true;
552 VcsDirectoryMapping mapping
= new VcsDirectoryMapping(child
.getAttributeValue(ATTRIBUTE_DIRECTORY
), vcs
);
553 mappingsList
.add(mapping
);
555 Element rootSettingsElement
= child
.getChild(ELEMENT_ROOT_SETTINGS
);
556 if (rootSettingsElement
!= null) {
557 String className
= rootSettingsElement
.getAttributeValue(ATTRIBUTE_CLASS
);
558 AbstractVcs vcsInstance
= findVcsByName(mapping
.getVcs());
559 if (vcsInstance
!= null && className
!= null) {
561 final Class
<?
> aClass
= vcsInstance
.getClass().getClassLoader().loadClass(className
);
562 final VcsRootSettings instance
= (VcsRootSettings
) aClass
.newInstance();
563 instance
.readExternal(rootSettingsElement
);
564 mapping
.setRootSettings(instance
);
566 catch (Exception e
) {
567 LOG
.error("Failed to load VCS root settings class "+ className
+ " for VCS " + vcsInstance
.getClass().getName(), e
);
572 boolean defaultProject
= Boolean
.TRUE
.toString().equals(element
.getAttributeValue(ATTRIBUTE_DEFAULT_PROJECT
));
573 // run autodetection if there's no VCS in default project and
574 if (haveNonEmptyMappings
|| !defaultProject
) {
575 myMappingsLoaded
= true;
577 StartupManager
.getInstance(myProject
).registerStartupActivity(new Runnable() {
579 myMappings
.setDirectoryMappings(mappingsList
);
584 public void writeDirectoryMappings(final Element element
) {
585 if (myProject
.isDefault()) {
586 element
.setAttribute(ATTRIBUTE_DEFAULT_PROJECT
, Boolean
.TRUE
.toString());
588 for(VcsDirectoryMapping mapping
: getDirectoryMappings()) {
589 Element child
= new Element(ELEMENT_MAPPING
);
590 child
.setAttribute(ATTRIBUTE_DIRECTORY
, mapping
.getDirectory());
591 child
.setAttribute(ATTRIBUTE_VCS
, mapping
.getVcs());
592 final VcsRootSettings rootSettings
= mapping
.getRootSettings();
593 if (rootSettings
!= null) {
594 Element rootSettingsElement
= new Element(ELEMENT_ROOT_SETTINGS
);
595 rootSettingsElement
.setAttribute(ATTRIBUTE_CLASS
, rootSettings
.getClass().getName());
597 rootSettings
.writeExternal(rootSettingsElement
);
598 child
.addContent(rootSettingsElement
);
600 catch (WriteExternalException e
) {
604 element
.addContent(child
);
608 public boolean needAutodetectMappings() {
609 return !myHaveLegacyVcsConfiguration
&& !myMappingsLoaded
;
613 public AbstractVcs
findVersioningVcs(VirtualFile file
) {
614 for(AbstractVcs vcs
: getAllVcss()) {
615 if (vcs
.isVersionedDirectory(file
)) {
622 public CheckoutProvider
.Listener
getCompositeCheckoutListener() {
623 return new CompositeCheckoutListener(myProject
);
626 public void fireDirectoryMappingsChanged() {
627 if (! myIsDisposed
) {
628 myMappings
.mappingsChanged();
632 public String
haveDefaultMapping() {
633 return myMappings
.haveDefaultMapping();
636 public BackgroundableActionEnabledHandler
getBackgroundableActionHandler(final VcsBackgroundableActions action
) {
637 ApplicationManager
.getApplication().assertIsDispatchThread();
639 BackgroundableActionEnabledHandler result
= myBackgroundableActionHandlerMap
.get(action
);
640 if (result
== null) {
641 result
= new BackgroundableActionEnabledHandler();
642 myBackgroundableActionHandlerMap
.put(action
, result
);