mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
RemoteTarget validation improved
* validation method api changed: now only user's string input validation performed for selected repo; * not null target created only if user's input is valid; * postpone validation for dialog switched off; * request focus added to repository panel renderer; * tree root became inline; * annotations added
This commit is contained in:
@@ -18,7 +18,6 @@ package com.intellij.dvcs.push;
|
||||
import com.intellij.dvcs.repo.Repository;
|
||||
import com.intellij.dvcs.repo.RepositoryManager;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.ui.ValidationInfo;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -31,7 +30,8 @@ import java.util.Collection;
|
||||
|
||||
public abstract class PushSupport<Repo extends Repository> {
|
||||
|
||||
public static final ExtensionPointName<PushSupport<? extends Repository>> PUSH_SUPPORT_EP = ExtensionPointName.create("com.intellij.pushSupport");
|
||||
public static final ExtensionPointName<PushSupport<? extends Repository>> PUSH_SUPPORT_EP =
|
||||
ExtensionPointName.create("com.intellij.pushSupport");
|
||||
|
||||
@NotNull
|
||||
public abstract AbstractVcs getVcs();
|
||||
@@ -63,6 +63,7 @@ public abstract class PushSupport<Repo extends 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.
|
||||
*
|
||||
* @see #validateSpec(Repository, PushSpec)
|
||||
*/
|
||||
@Nullable
|
||||
@@ -80,8 +81,8 @@ public abstract class PushSupport<Repo extends Repository> {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null if push spec are valid for selected repository
|
||||
* @return null if target is valid for selected repository
|
||||
*/
|
||||
@Nullable
|
||||
public abstract ValidationInfo validateSpec(@NotNull Repository repository, @NotNull PushSpec spec);
|
||||
public abstract VcsError validate(@NotNull Repository repository, @Nullable String targetToValidate);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ 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;
|
||||
@@ -76,14 +77,18 @@ public class PushController implements Disposable {
|
||||
@Nullable
|
||||
public ValidationInfo validate() {
|
||||
ValidationInfo validInfo = new ValidationInfo("There are no selected repository to push!");
|
||||
for (MyRepoModel model : myView2Model.values()) {
|
||||
for (Map.Entry<RepositoryNode, MyRepoModel> entry : myView2Model.entrySet()) {
|
||||
MyRepoModel model = entry.getValue();
|
||||
if (model.isSelected()) {
|
||||
//has one or more selected roots
|
||||
PushSupport support = model.getSupport();
|
||||
validInfo = support.validateSpec(model.getRepository(), model.getSpec());
|
||||
if (validInfo != null) {
|
||||
// return first non valid node
|
||||
return validInfo;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,6 +96,7 @@ public class PushController implements Disposable {
|
||||
}
|
||||
|
||||
private void startLoadingCommits() {
|
||||
//todo should be reworked
|
||||
Map<RepositoryNode, MyRepoModel> priorityLoading = new HashMap<RepositoryNode, MyRepoModel>();
|
||||
Map<RepositoryNode, MyRepoModel> others = new HashMap<RepositoryNode, MyRepoModel>();
|
||||
for (Map.Entry<RepositoryNode, MyRepoModel> entry : myView2Model.entrySet()) {
|
||||
@@ -152,9 +158,16 @@ public class PushController implements Disposable {
|
||||
repoPanel.addRepoNodeListener(new RepositoryNodeListener() {
|
||||
@Override
|
||||
public void onTargetChanged(String newValue) {
|
||||
myView2Model.get(repoNode).setSpec(new PushSpec(model.getSpec().getSource(), support.createTarget(repository, newValue)));
|
||||
VcsError validationError = support.validate(model.getRepository(), newValue);
|
||||
if (validationError == null) {
|
||||
myView2Model.get(repoNode).setSpec(new PushSpec(model.getSpec().getSource(), support.createTarget(repository, newValue)));
|
||||
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));
|
||||
}
|
||||
myDialog.updateButtons();
|
||||
loadCommits(model, repoNode, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -31,16 +31,14 @@ 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;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
import javax.swing.tree.TreeSelectionModel;
|
||||
import javax.swing.tree.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
@@ -57,15 +55,13 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
|
||||
private static final String START_EDITING = "startEditing";
|
||||
private final ChangesBrowser myChangesBrowser;
|
||||
private final CheckboxTree myTree;
|
||||
private final CheckedTreeNode myRootNode;
|
||||
private final MyTreeCellRenderer myTreeCellRenderer;
|
||||
|
||||
public PushLog(Project project, CheckedTreeNode root) {
|
||||
myRootNode = root;
|
||||
DefaultTreeModel treeModel = new DefaultTreeModel(myRootNode);
|
||||
treeModel.nodeStructureChanged(myRootNode);
|
||||
DefaultTreeModel treeModel = new DefaultTreeModel(root);
|
||||
treeModel.nodeStructureChanged(root);
|
||||
myTreeCellRenderer = new MyTreeCellRenderer();
|
||||
myTree = new CheckboxTree(myTreeCellRenderer, myRootNode) {
|
||||
myTree = new CheckboxTree(myTreeCellRenderer, root) {
|
||||
|
||||
public boolean isPathEditable(TreePath path) {
|
||||
return isEditable() && path.getLastPathComponent() instanceof DefaultMutableTreeNode;
|
||||
@@ -217,7 +213,10 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
|
||||
return tag instanceof EditorTextField;
|
||||
}
|
||||
//if keyboard event - then anEvent will be null =( See BasicTreeUi
|
||||
Object treeNode = myTree.getAnchorSelectionPath().getLastPathComponent();
|
||||
TreePath treePath = myTree.getAnchorSelectionPath();
|
||||
//there is no selection path if we start editing during initial validation//
|
||||
if (treePath == null) return true;
|
||||
Object treeNode = treePath.getLastPathComponent();
|
||||
return treeNode instanceof EditableTreeNode;
|
||||
}
|
||||
|
||||
@@ -277,4 +276,14 @@ public class PushLog extends JPanel implements TypeSafeDataProvider {
|
||||
TREE_CONSTRUCTION_LOCK.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JComponent startEditNode(@NotNull TreeNode node) {
|
||||
TreePath path = TreeUtil.getPathFromRoot(node);
|
||||
if (!myTree.isEditing()) {
|
||||
myTree.startEditingAtPath(path);
|
||||
}
|
||||
return (JComponent)myTree.getCellEditor()
|
||||
.getTreeCellEditorComponent(myTree, node, false, false, false, myTree.getRowForPath(path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +159,8 @@ public class RepositoryWithBranchPanel extends NonOpaquePanel implements TreeCel
|
||||
if (bounds != null) {
|
||||
setPreferredSize(new Dimension(tree.getWidth() - bounds.x, bounds.height));
|
||||
}
|
||||
myDestBranchTextField.grabFocus();
|
||||
myDestBranchTextField.requestFocus();
|
||||
revalidate();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -103,6 +103,11 @@ public class VcsPushDialog extends DialogWrapper {
|
||||
initValidation();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean postponeValidation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private class DvcsPushAction extends AbstractAction implements OptionAction {
|
||||
private Action[] myOptions = new Action[0];
|
||||
private final boolean myForce;
|
||||
|
||||
@@ -19,7 +19,6 @@ import com.intellij.dvcs.push.*;
|
||||
import com.intellij.dvcs.repo.Repository;
|
||||
import com.intellij.dvcs.repo.RepositoryManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.ValidationInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.AbstractVcs;
|
||||
import com.intellij.util.Function;
|
||||
@@ -104,9 +103,7 @@ public class HgPushSupport extends PushSupport<HgRepository> {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ValidationInfo validateSpec(@NotNull Repository repository, @NotNull PushSpec spec) {
|
||||
PushTarget target = spec.getTarget();
|
||||
return (target == null || StringUtil.isEmptyOrSpaces(target.getPresentation())) ? new ValidationInfo(
|
||||
"Please, specify remote push path for selected repos!") : null;
|
||||
public VcsError validate(@NotNull Repository repository, @Nullable String targetToValidate) {
|
||||
return StringUtil.isEmptyOrSpaces(targetToValidate) ? new VcsError("Please, specify remote push path for repository!") : null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user