IDEA-52201 (svn credentials not remembered), + allow repository changes to load;...
authorirengrig <Irina.Chernushina@jetbrains.com>
Tue, 16 Feb 2010 20:54:55 +0000 (23:54 +0300)
committerirengrig <Irina.Chernushina@jetbrains.com>
Tue, 16 Feb 2010 20:54:55 +0000 (23:54 +0300)
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesCache.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/IncomingChangesViewProvider.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/OutdatedVersionNotifier.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/RefreshIncomingChangesAction.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitHelper.java
plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/NewRootBunch.java
plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/BranchConfigurationDialog.java
plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CopyDialog.java
plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/SelectLocationDialog.java
plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnIntegrateRootOptionsPanel.java

index 822cddff6adabfc268864d1b76da3ed3630994ec..39477fe14a1ee87a7da05d9d229059d0a5e24bf7 100644 (file)
@@ -540,7 +540,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
     return changes;
   }
 
-  private List<CommittedChangeList> loadIncomingChanges() {
+  private List<CommittedChangeList> loadIncomingChanges(boolean inBackground) {
     final List<CommittedChangeList> result = new ArrayList<CommittedChangeList>();
     final Collection<ChangesCacheFile> caches = myCachesHolder.getAllCaches();
 
@@ -549,7 +549,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
 
     for(ChangesCacheFile cache: caches) {
       try {
-        if (! cache.getVcs().isVcsBackgroundOperationsAllowed(cache.getRootPath().getVirtualFile())) continue;
+        if (inBackground && (! cache.getVcs().isVcsBackgroundOperationsAllowed(cache.getRootPath().getVirtualFile()))) continue;
         if (!cache.isEmpty()) {
           debug("Loading incoming changes for " + cache.getLocation());
           final List<CommittedChangeList> incomingChanges = cache.loadIncomingChanges();
@@ -627,11 +627,11 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
     }
   }
 
-  public void loadIncomingChangesAsync(@Nullable final Consumer<List<CommittedChangeList>> consumer) {
+  public void loadIncomingChangesAsync(@Nullable final Consumer<List<CommittedChangeList>> consumer, final boolean inBackground) {
     debug("Loading incoming changes");
     final Runnable task = new Runnable() {
       public void run() {
-        final List<CommittedChangeList> list = loadIncomingChanges();
+        final List<CommittedChangeList> list = loadIncomingChanges(inBackground);
         if (consumer != null) {
           consumer.consume(new ArrayList<CommittedChangeList>(list));
         }
@@ -775,7 +775,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
     myTaskQueue.run(task);    
   }
 
-  public void refreshAllCachesAsync(final boolean initIfEmpty) {
+  public void refreshAllCachesAsync(final boolean initIfEmpty, final boolean inBackground) {
     final Runnable task = new Runnable() {
       public void run() {
         final List<ChangesCacheFile> files = myCachesHolder.getAllCaches();
@@ -805,7 +805,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
           }
         };
         for(ChangesCacheFile file: files) {
-          if (file.getVcs().isVcsBackgroundOperationsAllowed(file.getRootPath().getVirtualFile())) {
+          if ((! inBackground) || file.getVcs().isVcsBackgroundOperationsAllowed(file.getRootPath().getVirtualFile())) {
             refreshCacheAsync(file, initIfEmpty, notifyConsumer, false);
           }
         }
@@ -946,7 +946,7 @@ public class CommittedChangesCache implements PersistentStateComponent<Committed
     public void run() {
       final CommittedChangesCache cache = myCache;
       if (cache == null) return;
-      cache.refreshAllCachesAsync(false);
+      cache.refreshAllCachesAsync(false, true);
       final List<ChangesCacheFile> list = cache.getCachesHolder().getAllCaches();
       for(ChangesCacheFile file: list) {
         if (file.getVcs().isVcsBackgroundOperationsAllowed(file.getRootPath().getVirtualFile())) {
index 1e7978bebf032e9f19681bd536c27940026de60b..9b743ccbefad0a24b8b820d0cb9cdc183a5c0624 100644 (file)
@@ -59,7 +59,7 @@ public class IncomingChangesViewProvider implements ChangesViewContentProvider {
     myBrowser.setTableContextMenu(group, Collections.<AnAction>emptyList());
     myConnection = myBus.connect();
     myConnection.subscribe(CommittedChangesCache.COMMITTED_TOPIC, new MyCommittedChangesListener());
-    loadChangesToBrowser();
+    loadChangesToBrowser(false);
 
     JPanel contentPane = new JPanel(new BorderLayout());
     contentPane.add(myBrowser, BorderLayout.CENTER);
@@ -73,18 +73,18 @@ public class IncomingChangesViewProvider implements ChangesViewContentProvider {
     myBrowser = null;
   }
 
-  private void updateModel() {
+  private void updateModel(final boolean inBackground) {
     ApplicationManager.getApplication().invokeLater(new Runnable() {
       public void run() {
         if (myProject.isDisposed()) return;
         if (myBrowser != null) {
-          loadChangesToBrowser();
+          loadChangesToBrowser(inBackground);
         }
       }
     });
   }
 
-  private void loadChangesToBrowser() {
+  private void loadChangesToBrowser(boolean inBackground) {
     final CommittedChangesCache cache = CommittedChangesCache.getInstance(myProject);
     if (cache.hasCachesForAnyRoot()) {
       final List<CommittedChangeList> list = cache.getCachedIncomingChanges();
@@ -93,18 +93,18 @@ public class IncomingChangesViewProvider implements ChangesViewContentProvider {
         myBrowser.setItems(list, false, CommittedChangesBrowserUseCase.INCOMING);
       }
       else {
-        cache.loadIncomingChangesAsync(null);
+        cache.loadIncomingChangesAsync(null, inBackground);
       }
     }
   }
 
   private class MyCommittedChangesListener extends CommittedChangesAdapter {
     public void changesLoaded(final RepositoryLocation location, final List<CommittedChangeList> changes) {
-      updateModel();
+      updateModel(true);
     }
 
     public void incomingChangesUpdated(final List<CommittedChangeList> receivedChanges) {
-      updateModel();
+      updateModel(true);
     }
 
     public void refreshErrorStatusChanged(@Nullable final VcsException lastError) {
index eea29cadae4159e3ff2cc7483b99ac66b74ad5ff..2915b1c4faffaeab0fc28a0d8dbf31a19b5d7b44 100644 (file)
@@ -79,7 +79,7 @@ public class OutdatedVersionNotifier implements ProjectComponent {
           myIncomingChangesRequested = false;
           updateAllEditorsLater();
         }
-      });
+      }, true);
     }
   }
 
index 63fcabc74b7fb5e1be87758d3df1b5e02b0ab8e7..d7fa3ce390f6288a957b243bc85a3a10e3bebd86 100644 (file)
@@ -18,8 +18,8 @@ package com.intellij.openapi.vcs.changes.committed;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
 
 /**
  * @author yole
@@ -37,7 +37,7 @@ public class RefreshIncomingChangesAction extends AnAction implements DumbAware
     if (!cache.hasCachesForAnyRoot() && !CacheSettingsDialog.showSettingsDialog(project)) {
       return;
     }
-    cache.refreshAllCachesAsync(true);
+    cache.refreshAllCachesAsync(true, false);
     cache.refreshIncomingChangesAsync();
   }
 
index 3187b7b652340c9631df6f08083d5b53ac9d304a..4d53f91cab2c09efd85724b470348a9cf8f0ce76 100644 (file)
@@ -379,7 +379,8 @@ public class CommitHelper {
                   }
                 }
                 final CommittedChangesCache cache = CommittedChangesCache.getInstance(myProject);
-                cache.refreshAllCachesAsync(false);
+                // in background since commit must have authorized
+                cache.refreshAllCachesAsync(false, true);
                 cache.refreshIncomingChangesAsync();
               }
             }, InvokeAfterUpdateMode.SILENT, null, new Consumer<VcsDirtyScopeManager>() {
index 779b4c09ddb707f51c74a549dc0b3e0eb6f763be..c424becccf39548befad282b06a6b95510b70642 100644 (file)
@@ -29,6 +29,7 @@ import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.integrate.SvnBranchItem;
 import org.tmatesoft.svn.core.SVNException;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -114,11 +115,13 @@ public class NewRootBunch implements SvnBranchConfigManager {
     }
 
     public void run() {
+      boolean callbackCalled = false;
       try {
         final List<SvnBranchItem> items = BranchesLoader.loadBranches(myProject, myUrl);
         myBunch.updateBranches(myRoot, myUrl, new InfoStorage<List<SvnBranchItem>>(items, myInfoReliability));
         if (myCallback != null) {
           myCallback.consume(items);
+          callbackCalled = true;
         }
       }
       catch (SVNException e) {
@@ -126,6 +129,11 @@ public class NewRootBunch implements SvnBranchConfigManager {
         if (InfoReliability.setByUser.equals(myInfoReliability)) {
           ChangesViewBalloonProblemNotifier.showMe(myProject, "Branches load error: " + e.getMessage(), MessageType.ERROR);
         }
+      } finally {
+        // callback must be called by contract
+        if (myCallback != null && (! callbackCalled)) {
+          myCallback.consume(Collections.<SvnBranchItem>emptyList());
+        }
       }
     }
   }
index e0128ad933b1aee93abe890c44d1a324647c5f2d..7072477d7353a19883af730a99a6f0d33fef6a3d 100644 (file)
@@ -32,7 +32,6 @@ import org.jetbrains.idea.svn.branchConfig.InfoStorage;
 import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigManager;
 import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
 import org.jetbrains.idea.svn.integrate.SvnBranchItem;
-import org.tmatesoft.svn.core.SVNException;
 
 import javax.swing.*;
 import javax.swing.event.DocumentEvent;
@@ -70,15 +69,9 @@ public class BranchConfigurationDialog extends DialogWrapper {
     myTrunkLocationTextField.setText(configuration.getTrunkUrl());
     myTrunkLocationTextField.addActionListener(new ActionListener() {
       public void actionPerformed(final ActionEvent e) {
-        try {
-          SelectLocationDialog dlg = new SelectLocationDialog(project, myTrunkLocationTextField.getText());
-          dlg.show();
-          if (dlg.isOK()) {
-            myTrunkLocationTextField.setText(dlg.getSelectedURL());
-          }
-        }
-        catch (SVNException e1) {
-          // can not parse url, do not know repository 
+        final String selectedUrl = SelectLocationDialog.selectLocation(project, myTrunkLocationTextField.getText());
+        if (selectedUrl != null) {
+          myTrunkLocationTextField.setText(selectedUrl);
         }
       }
     });
@@ -91,23 +84,15 @@ public class BranchConfigurationDialog extends DialogWrapper {
     myLocationList.setModel(listModel);
     myAddButton.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
-        try {
-          SelectLocationDialog dlg = new SelectLocationDialog(project, rootUrl);
-          dlg.show();
-          if (dlg.isOK()) {
-            if (!configuration.getBranchUrls().contains(dlg.getSelectedURL())) {
-              final String url = dlg.getSelectedURL();
-              configuration.addBranches(url, new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(), InfoReliability.empty));
-              mySvnBranchConfigManager.reloadBranches(myRoot, url, null);
-              listModel.fireItemAdded();
-              myLocationList.setSelectedIndex(listModel.getSize()-1);
-            }
+        final String selectedUrl = SelectLocationDialog.selectLocation(project, rootUrl);
+        if (selectedUrl != null) {
+          if (!configuration.getBranchUrls().contains(selectedUrl)) {
+            configuration.addBranches(selectedUrl, new InfoStorage<List<SvnBranchItem>>(new ArrayList<SvnBranchItem>(), InfoReliability.empty));
+            mySvnBranchConfigManager.reloadBranches(myRoot, selectedUrl, null);
+            listModel.fireItemAdded();
+            myLocationList.setSelectedIndex(listModel.getSize()-1);
           }
         }
-        catch (SVNException e1) {
-          Messages.showErrorDialog(project, SvnBundle.message("select.location.invalid.url.message", rootUrl),
-                                   SvnBundle.message("dialog.title.select.repository.location"));
-        }
       }
     });
     myRemoveButton.addActionListener(new ActionListener() {
index 030e0117b38d920f94a0311841fad48ee805246c..de013f4a84918dfdb893a3ec4ed53de45d88cd2b 100644 (file)
@@ -22,7 +22,6 @@ import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
-import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.IconLoader;
 import com.intellij.openapi.vcs.ProjectLevelVcsManager;
 import com.intellij.openapi.vcs.VcsException;
@@ -32,7 +31,6 @@ import com.intellij.ui.ComboboxWithBrowseButton;
 import com.intellij.ui.DocumentAdapter;
 import com.intellij.util.ArrayUtil;
 import org.jetbrains.annotations.NonNls;
-import org.jetbrains.idea.svn.SvnBranchConfiguration;
 import org.jetbrains.idea.svn.SvnBranchConfigurationManager;
 import org.jetbrains.idea.svn.SvnBundle;
 import org.jetbrains.idea.svn.SvnVcs;
@@ -124,20 +122,10 @@ public class CopyDialog extends DialogWrapper {
         String url = myToURLText.getText();
         String dstName = SVNPathUtil.tail(mySrcURL);
         dstName = SVNEncodingUtil.uriDecode(dstName);
-        try {
-          SelectLocationDialog dialog = new SelectLocationDialog(myProject, SVNPathUtil.removeTail(url), SvnBundle.message("label.copy.select.location.dialog.copy.as"), dstName, false);
-          dialog.show();
-          if (dialog.isOK()) {
-            url = dialog.getSelectedURL();
-            String name = dialog.getDestinationName();
-            url = SVNPathUtil.append(url, name);
-            myToURLText.setText(url);
-          }
-        }
-        catch (SVNException e1) {
-          Messages.showErrorDialog(project, SvnBundle.message("select.location.invalid.url.message", url),
-                                   SvnBundle.message("dialog.title.select.repository.location"));
-          //typed text can not be parsed - no information on what repository to use
+        url = SelectLocationDialog.selectCopyDestination(myProject, SVNPathUtil.removeTail(url),
+                                                  SvnBundle.message("label.copy.select.location.dialog.copy.as"), dstName, false);
+        if (url != null) {
+          myToURLText.setText(url);
         }
       }
     });
index 73c6c95e848f1b3a4b4a91edebefbe9d3c1fb77e..d46e27eed61764bd87a06b5d59a5edf88a6cf478 100644 (file)
 package org.jetbrains.idea.svn.dialogs;
 
 import com.intellij.openapi.help.HelpManager;
+import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Ref;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.idea.svn.SvnBundle;
@@ -28,6 +30,7 @@ import org.jetbrains.idea.svn.dialogs.browser.UrlOpeningExpander;
 import org.tmatesoft.svn.core.SVNException;
 import org.tmatesoft.svn.core.SVNURL;
 import org.tmatesoft.svn.core.internal.util.SVNEncodingUtil;
+import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
 import org.tmatesoft.svn.core.io.SVNRepository;
 
 import javax.swing.*;
@@ -51,32 +54,48 @@ public class SelectLocationDialog extends DialogWrapper {
 
   @NonNls private static final String HELP_ID = "vcs.subversion.common";
 
+  // todo check that works when authenticated
   @Nullable
   public static String selectLocation(Project project, String url) {
     try {
       SVNURL.parseURIEncoded(url);
-      SelectLocationDialog dialog = new SelectLocationDialog(project, url);
+      final SVNURL svnurl = initRoot(project, url);
+      SelectLocationDialog dialog = new SelectLocationDialog(project, svnurl, null, null, true);
       dialog.show();
       if (!dialog.isOK()) return null;
       return dialog.getSelectedURL();
     } catch (SVNException e) {
-      Messages.showErrorDialog(project, SvnBundle.message("select.location.invalid.url.message", url),
-                               SvnBundle.message("dialog.title.select.repository.location"));
+      Messages.showErrorDialog(project, e.getMessage(), SvnBundle.message("dialog.title.select.repository.location"));
       return null;
     }
   }
 
-  public SelectLocationDialog(Project project, String url) throws SVNException {
-    this(project, url, null, null, true);
+  @Nullable
+  public static String selectCopyDestination(Project project, String url, String dstLabel, String dstName, boolean showFiles) {
+    try {
+      SVNURL.parseURIEncoded(url);
+      final SVNURL svnurl = initRoot(project, url);
+      SelectLocationDialog dialog = new SelectLocationDialog(project, svnurl, dstLabel, dstName, showFiles);
+      dialog.show();
+      if (!dialog.isOK()) return null;
+
+      final String result = dialog.getSelectedURL();
+      final String name = dialog.getDestinationName();
+      return SVNPathUtil.append(result, name);
+    } catch (SVNException e) {
+      Messages.showErrorDialog(project, SvnBundle.message("select.location.invalid.url.message", url),
+                               SvnBundle.message("dialog.title.select.repository.location"));
+      return null;
+    }
   }
 
-  public SelectLocationDialog(Project project, String url,
+  private SelectLocationDialog(Project project, SVNURL url,
                               String dstLabel, String dstName, boolean showFiles) throws SVNException {
     super(project, true);
     myProject = project;
     myDstLabel = dstLabel;
     myDstName = dstName;
-    myURL = SVNURL.parseURIEncoded(url);
+    myURL = url;
     myIsShowFiles = showFiles;
     setTitle(SvnBundle.message("dialog.title.select.repository.location"));
     getHelpAction().setEnabled(true);
@@ -95,16 +114,30 @@ public class SelectLocationDialog extends DialogWrapper {
     return "svn.repositoryBrowser";
   }
 
+  private static SVNURL initRoot(final Project project, final String urlString) throws SVNException {
+    final Ref<SVNURL> result = new Ref<SVNURL>();
+    final Ref<SVNException> excRef = new Ref<SVNException>();
+
+    ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
+      public void run() {
+        try {
+          SVNRepository repos = SvnVcs.getInstance(project).createRepository(urlString);
+          result.set(repos.getRepositoryRoot(true));
+          repos.closeSession();
+        } catch (SVNException e) {
+          excRef.set(e);
+        }
+      }
+    }, "Detecting repository root", true, project);
+    if (! excRef.isNull()) {
+      throw excRef.get();
+    }
+    return result.get();
+  }
+
   protected void init() {
     super.init();
-    String urlString = myURL.toString();
-    try {
-      SVNRepository repos = SvnVcs.getInstance(myProject).createRepository(urlString);
-      myURL = repos.getRepositoryRoot(true);
-      repos.closeSession();
-    } catch (SVNException e) {
-      // show error dialog.
-    }
+    final String urlString = myURL.toString();
     myRepositoryBrowser.setRepositoryURL(myURL, myIsShowFiles, new UrlOpeningExpander.Factory(urlString, urlString));
     myRepositoryBrowser.addChangeListener(new TreeSelectionListener() {
       public void valueChanged(TreeSelectionEvent e) {
index b7a848c0f49eb2ccd183111b59d46c80639a7b8f..e8154157c97a873eb203948686157e5f0c346a20 100644 (file)
@@ -17,13 +17,11 @@ package org.jetbrains.idea.svn.update;
 
 import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.ui.TextFieldWithBrowseButton;
-import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.vcs.FilePath;
 import org.jetbrains.idea.svn.SvnBundle;
 import org.jetbrains.idea.svn.SvnConfiguration;
 import org.jetbrains.idea.svn.SvnVcs;
 import org.jetbrains.idea.svn.dialogs.SelectLocationDialog;
-import org.tmatesoft.svn.core.SVNException;
 
 import javax.swing.*;
 import java.awt.event.ActionEvent;
@@ -87,24 +85,11 @@ public class SvnIntegrateRootOptionsPanel implements SvnPanel{
 
   private boolean chooseUrl(final TextFieldWithBrowseButton textField, final SvnVcs vcs) {
     String url = textField.getText();
-    try {
-      SelectLocationDialog dialog = new SelectLocationDialog(vcs.getProject(), url, null, null, true);
-      dialog.show();
-      if (dialog.isOK()) {
-        url = dialog.getSelectedURL();
-        if (url != null) {
-          textField.setText(url);
-          return true;
-        } else {
-          return false;
-        }
-      } else {
-        return false;
-      }
-    }
-    catch (SVNException e) {
-      Messages.showErrorDialog(myVcs.getProject(), SvnBundle.message("select.location.invalid.url.message", url),
-                               SvnBundle.message("dialog.title.select.repository.location"));
+    final String selectedUrl = SelectLocationDialog.selectLocation(vcs.getProject(), url);
+    if (selectedUrl != null) {
+      textField.setText(selectedUrl);
+      return true;
+    } else {
       return false;
     }
   }