diff options
author | Tor Norbye <tnorbye@google.com> | 2013-08-09 11:23:59 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2013-08-09 11:23:59 -0700 |
commit | 10605ee04b8297b2f9f2d90aa91d73bc669ce891 (patch) | |
tree | de8a2f44bdd9e0969b79431cfba64a9036d69681 /plugins | |
parent | 3361ba4955436eee16e16e1f0ae0c20c98d35c45 (diff) | |
parent | 9fdfa377b20b105e3a9907d32434787f75781c35 (diff) | |
download | idea-10605ee04b8297b2f9f2d90aa91d73bc669ce891.tar.gz |
Merge remote-tracking branch 'aosp/snapshot-master' into merge
Diffstat (limited to 'plugins')
52 files changed, 684 insertions, 1595 deletions
diff --git a/plugins/git4idea/src/git4idea/rebase/GitRebaseEditor.java b/plugins/git4idea/src/git4idea/rebase/GitRebaseEditor.java index 5e0b960ed269..fc0d1102326e 100644 --- a/plugins/git4idea/src/git4idea/rebase/GitRebaseEditor.java +++ b/plugins/git4idea/src/git4idea/rebase/GitRebaseEditor.java @@ -22,7 +22,6 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; import com.intellij.util.ListWithSelection; -import com.intellij.util.ui.ComboBoxTableCellEditor; import com.intellij.util.ui.ComboBoxTableCellRenderer; import git4idea.GitUtil; import git4idea.config.GitConfigUtil; @@ -105,6 +104,7 @@ public class GitRebaseEditor extends DialogWrapper { myGitRoot = gitRoot; setTitle(GitBundle.getString("rebase.editor.title")); setOKButtonText(GitBundle.getString("rebase.editor.button")); + if (SystemInfo.isWindows && file.startsWith(CYGDRIVE_PREFIX)) { final int prefixSize = CYGDRIVE_PREFIX.length(); file = file.substring(prefixSize, prefixSize + 1) + ":" + file.substring(prefixSize + 1); @@ -114,9 +114,15 @@ public class GitRebaseEditor extends DialogWrapper { myTableModel.load(file); myCommitsTable.setModel(myTableModel); myCommitsTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); + + final JComboBox editorComboBox = new JComboBox(); + for (Object option : GitRebaseEntry.Action.values()) { + editorComboBox.addItem(option); + } TableColumn actionColumn = myCommitsTable.getColumnModel().getColumn(MyTableModel.ACTION); - actionColumn.setCellEditor(ComboBoxTableCellEditor.INSTANCE); + actionColumn.setCellEditor(new DefaultCellEditor(editorComboBox)); actionColumn.setCellRenderer(ComboBoxTableCellRenderer.INSTANCE); + myCommitsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(final ListSelectionEvent e) { myViewButton.setEnabled(myCommitsTable.getSelectedRowCount() == 1); diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java index f6c075f0fda6..0ca65ea8a666 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCreateGistAction.java @@ -100,7 +100,7 @@ public class GithubCreateGistAction extends DumbAwareAction { @Nullable final VirtualFile[] files) { // Ask for description and other params - final GithubCreateGistDialog dialog = new GithubCreateGistDialog(project, editor, file); + final GithubCreateGistDialog dialog = new GithubCreateGistDialog(project, editor, files, file); dialog.show(); if (!dialog.isOK()) { return; diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestAction.java index 60e6bb91ea4d..472be8864dd7 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubCreatePullRequestAction.java @@ -30,8 +30,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Function; -import javax.swing.SwingWorker; - import com.intellij.util.ThrowableConsumer; import com.intellij.util.containers.ContainerUtil; import git4idea.DialogManager; @@ -71,7 +69,7 @@ public class GithubCreatePullRequestAction extends DumbAwareAction { return; } - if (StringUtil.isEmptyOrSpaces(GithubSettings.getInstance().getLogin())) { + if (!GithubSettings.getInstance().isAuthConfigured()) { setVisibleEnabled(e, false, false); return; } @@ -134,13 +132,13 @@ public class GithubCreatePullRequestAction extends DumbAwareAction { return; } - final GithubInfo info = loadGithubInfoWithModal(project, userAndRepo); + final GithubInfo info = loadGithubInfoWithModal(project, userAndRepo, upstreamUserAndRepo); if (info == null) { return; } - final GithubCreatePullRequestDialog dialog = new GithubCreatePullRequestDialog(project); - initLoadAvailableBranches(project, info, upstreamUserAndRepo, dialog); + String suggestedBranch = info.getRepo().getParent() == null ? null : info.getRepo().getParent().getUserName() + ":master"; + final GithubCreatePullRequestDialog dialog = new GithubCreatePullRequestDialog(project, info.getBranches(), suggestedBranch); DialogManager.show(dialog); if (!dialog.isOK()) { return; @@ -171,7 +169,9 @@ public class GithubCreatePullRequestAction extends DumbAwareAction { } @Nullable - private static GithubInfo loadGithubInfoWithModal(@NotNull final Project project, @NotNull final GithubFullPath userAndRepo) { + private static GithubInfo loadGithubInfoWithModal(@NotNull final Project project, + @NotNull final GithubFullPath userAndRepo, + @Nullable final GithubFullPath upstreamUserAndRepo) { final Ref<GithubInfo> githubInfoRef = new Ref<GithubInfo>(); final Ref<IOException> exceptionRef = new Ref<IOException>(); ProgressManager.getInstance().run(new Task.Modal(project, "Access to GitHub", true) { @@ -185,7 +185,8 @@ public class GithubCreatePullRequestAction extends DumbAwareAction { reposRef.set(GithubApiUtil.getDetailedRepoInfo(authData, userAndRepo.getUser(), userAndRepo.getRepository())); } }); - githubInfoRef.set(new GithubInfo(auth, reposRef.get())); + List<String> branches = loadAvailableBranches(project, auth, reposRef.get(), upstreamUserAndRepo); + githubInfoRef.set(new GithubInfo(auth, reposRef.get(), branches)); } catch (IOException e) { exceptionRef.set(e); @@ -280,85 +281,70 @@ public class GithubCreatePullRequestAction extends DumbAwareAction { return StringUtil.equalsIgnoreCase(user, repo.getUserName()); } - private static void initLoadAvailableBranches(@NotNull final Project project, - @NotNull final GithubInfo info, - @Nullable final GithubFullPath upstreamPath, - @NotNull final GithubCreatePullRequestDialog dialog) { - dialog.setBusy(true); - new SwingWorker<List<String>, Void>() { - @Override - protected List<String> doInBackground() throws Exception { - List<String> result = new ArrayList<String>(); - try { - final GithubAuthData auth = info.getAuthData(); - final GithubRepoDetailed repo = info.getRepo(); - final GithubRepo parent = repo.getParent(); - final GithubRepo source = repo.getSource(); - - result.addAll(getBranches(auth, repo.getUserName(), repo.getName())); + private static List<String> loadAvailableBranches(@NotNull final Project project, + @NotNull final GithubAuthData auth, + @NotNull final GithubRepoDetailed repo, + @Nullable final GithubFullPath upstreamPath) { + List<String> result = new ArrayList<String>(); + try { + final GithubRepo parent = repo.getParent(); + final GithubRepo source = repo.getSource(); - if (parent != null) { - result.addAll(getBranches(auth, parent.getUserName(), parent.getName())); - } + if (parent != null) { + result.addAll(getBranches(auth, parent.getUserName(), parent.getName())); + } - if (source != null && !equals(source, parent)) { - result.addAll(getBranches(auth, source.getUserName(), source.getName())); - } + result.addAll(getBranches(auth, repo.getUserName(), repo.getName())); - if (upstreamPath != null && !equals(upstreamPath, repo) && !equals(upstreamPath, parent) && !equals(upstreamPath, source)) { - result.addAll(getBranches(auth, upstreamPath.getUser(), upstreamPath.getRepository())); - } - } - catch (IOException e) { - GithubNotifications.showError(project, "Can't load available branches", e); - } - return result; + if (source != null && !equals(source, parent)) { + result.addAll(getBranches(auth, source.getUserName(), source.getName())); } - @Override - protected void done() { - try { - dialog.addBranches(get()); - } - catch (Exception ignore) { - } - dialog.setBusy(false); + if (upstreamPath != null && !equals(upstreamPath, repo) && !equals(upstreamPath, parent) && !equals(upstreamPath, source)) { + result.addAll(getBranches(auth, upstreamPath.getUser(), upstreamPath.getRepository())); } + } + catch (IOException e) { + GithubNotifications.showError(project, "Can't load available branches", e); + } + return result; + } - @NotNull - private List<String> getBranches(@NotNull GithubAuthData auth, @NotNull final String user, @NotNull String repo) throws IOException { - List<GithubBranch> branches = GithubApiUtil.getRepoBranches(auth, user, repo); - return ContainerUtil.map(branches, new Function<GithubBranch, String>() { - @Override - public String fun(GithubBranch branch) { - return user + ":" + branch.getName(); - } - }); + @NotNull + private static List<String> getBranches(@NotNull GithubAuthData auth, @NotNull final String user, @NotNull String repo) + throws IOException { + List<GithubBranch> branches = GithubApiUtil.getRepoBranches(auth, user, repo); + return ContainerUtil.map(branches, new Function<GithubBranch, String>() { + @Override + public String fun(GithubBranch branch) { + return user + ":" + branch.getName(); } + }); + } - private boolean equals(@NotNull GithubRepo repo1, @Nullable GithubRepo repo2) { - if (repo2 == null) { - return false; - } - return StringUtil.equalsIgnoreCase(repo1.getUserName(), repo2.getUserName()); - } + private static boolean equals(@NotNull GithubRepo repo1, @Nullable GithubRepo repo2) { + if (repo2 == null) { + return false; + } + return StringUtil.equalsIgnoreCase(repo1.getUserName(), repo2.getUserName()); + } - private boolean equals(@NotNull GithubFullPath repo1, @Nullable GithubRepo repo2) { - if (repo2 == null) { - return false; - } - return StringUtil.equalsIgnoreCase(repo1.getUser(), repo2.getUserName()); - } - }.execute(); + private static boolean equals(@NotNull GithubFullPath repo1, @Nullable GithubRepo repo2) { + if (repo2 == null) { + return false; + } + return StringUtil.equalsIgnoreCase(repo1.getUser(), repo2.getUserName()); } private static class GithubInfo { @NotNull private final GithubRepoDetailed myRepo; @NotNull private final GithubAuthData myAuthData; + @NotNull private final List<String> myBranches; - private GithubInfo(@NotNull GithubAuthData authData, @NotNull GithubRepoDetailed repo) { + private GithubInfo(@NotNull GithubAuthData authData, @NotNull GithubRepoDetailed repo, @NotNull List<String> branches) { myAuthData = authData; myRepo = repo; + myBranches = branches; } @NotNull @@ -370,5 +356,10 @@ public class GithubCreatePullRequestAction extends DumbAwareAction { public GithubAuthData getAuthData() { return myAuthData; } + + @NotNull + public List<String> getBranches() { + return myBranches; + } } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java index e2f00946629f..bdbf6b0dc635 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubRebaseAction.java @@ -23,7 +23,6 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ThrowableConvertor; @@ -42,7 +41,9 @@ import git4idea.util.GitPreservingProcess; import icons.GithubIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.github.api.*; +import org.jetbrains.plugins.github.api.GithubApiUtil; +import org.jetbrains.plugins.github.api.GithubFullPath; +import org.jetbrains.plugins.github.api.GithubRepoDetailed; import java.io.IOException; import java.util.Collections; @@ -71,7 +72,7 @@ public class GithubRebaseAction extends DumbAwareAction { return; } - if (StringUtil.isEmptyOrSpaces(GithubSettings.getInstance().getLogin())) { + if (!GithubSettings.getInstance().isAuthConfigured()) { setVisibleEnabled(e, false, false); return; } @@ -115,6 +116,7 @@ public class GithubRebaseAction extends DumbAwareAction { new Task.Backgroundable(project, "Rebasing GitHub fork...") { @Override public void run(@NotNull ProgressIndicator indicator) { + gitRepository.update(); String upstreamRemoteUrl = GithubUtil.findUpstreamRemote(gitRepository); if (upstreamRemoteUrl == null) { diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubSettings.java b/plugins/github/src/org/jetbrains/plugins/github/GithubSettings.java index 6ac53c59a92f..ebe8d6fb8831 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubSettings.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubSettings.java @@ -23,9 +23,11 @@ import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.github.api.GithubApiUtil; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; import static org.jetbrains.plugins.github.GithubAuthData.AuthType; @@ -52,15 +54,15 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S } public static class State { - public String LOGIN = ""; - public String HOST = GithubApiUtil.DEFAULT_GITHUB_HOST; - public AuthType AUTH_TYPE = AuthType.ANONYMOUS; + @Nullable public String LOGIN = null; + @NotNull public String HOST = GithubApiUtil.DEFAULT_GITHUB_HOST; + @NotNull public AuthType AUTH_TYPE = AuthType.ANONYMOUS; public boolean ANONYMOUS_GIST = false; public boolean OPEN_IN_BROWSER_GIST = true; public boolean PRIVATE_GIST = true; public boolean SAVE_PASSWORD = true; - public Collection<String> TRUSTED_HOSTS = new ArrayList<String>(); - public String CREATE_PULL_REQUEST_DEFAULT_BRANCH = ""; + @NotNull public Collection<String> TRUSTED_HOSTS = new ArrayList<String>(); + @Nullable public String CREATE_PULL_REQUEST_DEFAULT_BRANCH = null; } public static GithubSettings getInstance() { @@ -72,8 +74,7 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S return myState.HOST; } - // TODO return null if no login instead of empty string - @NotNull + @Nullable public String getLogin() { return StringUtil.notNullize(myState.LOGIN); } @@ -83,11 +84,15 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S return myState.AUTH_TYPE; } + public boolean isAuthConfigured() { + return !myState.AUTH_TYPE.equals(AuthType.ANONYMOUS); + } + private void setHost(@NotNull String host) { myState.HOST = StringUtil.notNullize(host, GithubApiUtil.DEFAULT_GITHUB_HOST); } - private void setLogin(@NotNull String login) { + private void setLogin(@Nullable String login) { myState.LOGIN = login; } @@ -116,7 +121,7 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S return passwordSafe.getSettings().getProviderType() == PasswordSafeSettings.ProviderType.MASTER_PASSWORD; } - @NotNull + @Nullable public String getCreatePullRequestDefaultBranch() { return myState.CREATE_PULL_REQUEST_DEFAULT_BRANCH; } @@ -203,13 +208,16 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S switch (auth.getAuthType()) { case BASIC: assert auth.getBasicAuth() != null; + setLogin(auth.getBasicAuth().getLogin()); setPassword(auth.getBasicAuth().getPassword(), rememberPassword); break; case TOKEN: assert auth.getTokenAuth() != null; + setLogin(null); setPassword(auth.getTokenAuth().getToken(), rememberPassword); break; case ANONYMOUS: + setLogin(null); setPassword("", rememberPassword); break; default: @@ -217,9 +225,8 @@ public class GithubSettings implements PersistentStateComponent<GithubSettings.S } } - public void setCredentials(@NotNull String host, @NotNull String login, @NotNull GithubAuthData auth, boolean rememberPassword) { + public void setCredentials(@NotNull String host, @NotNull GithubAuthData auth, boolean rememberPassword) { setHost(host); - setLogin(login); setAuthData(auth, rememberPassword); } }
\ No newline at end of file diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index a6edc0229575..b961d421cd0b 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -35,7 +35,8 @@ import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.github.api.*; +import org.jetbrains.plugins.github.api.GithubApiUtil; +import org.jetbrains.plugins.github.api.GithubUserDetailed; import org.jetbrains.plugins.github.ui.GithubBasicLoginDialog; import org.jetbrains.plugins.github.ui.GithubLoginDialog; @@ -109,12 +110,15 @@ public class GithubUtil { } @NotNull - public static <T> T runWithValidBasicAuth(@Nullable Project project, - @NotNull ProgressIndicator indicator, - @NotNull ThrowableConvertor<GithubAuthData, T, IOException> task) throws IOException { + public static <T> T runWithValidBasicAuthForHost(@Nullable Project project, + @NotNull ProgressIndicator indicator, + @NotNull String host, + @NotNull ThrowableConvertor<GithubAuthData, T, IOException> task) throws IOException { + GithubSettings settings = GithubSettings.getInstance(); GithubAuthData auth; - if (GithubSettings.getInstance().getAuthType() == GithubAuthData.AuthType.BASIC) { - auth = GithubSettings.getInstance().getAuthData(); + if (settings.getAuthType() == GithubAuthData.AuthType.BASIC && + StringUtil.equalsIgnoreCase(GithubUrlUtil.getApiUrl(host), GithubUrlUtil.getApiUrl(settings.getHost()))) { + auth = settings.getAuthData(); } else { auth = GithubAuthData.createAnonymous(); @@ -126,7 +130,7 @@ public class GithubUtil { return task.convert(auth); } catch (GithubAuthenticationException e) { - auth = getValidBasicAuthData(project, indicator); + auth = getValidBasicAuthDataForHost(project, indicator, host); if (auth == null) { throw new GithubAuthenticationCanceledException("Can't get valid credentials"); } @@ -134,7 +138,7 @@ public class GithubUtil { } catch (IOException e) { if (checkSSLCertificate(e, auth.getHost(), indicator)) { - return runWithValidBasicAuth(project, indicator, task); + return runWithValidBasicAuthForHost(project, indicator, host, task); } throw e; } @@ -177,8 +181,11 @@ public class GithubUtil { * @return null if user canceled login dialog. Valid GithubAuthData otherwise. */ @Nullable - public static GithubAuthData getValidBasicAuthData(@Nullable Project project, @NotNull ProgressIndicator indicator) { + public static GithubAuthData getValidBasicAuthDataForHost(@Nullable Project project, + @NotNull ProgressIndicator indicator, + @NotNull String host) { final GithubLoginDialog dialog = new GithubBasicLoginDialog(project); + dialog.lockHost(host); ApplicationManager.getApplication().invokeAndWait(new Runnable() { @Override public void run() { @@ -232,12 +239,7 @@ public class GithubUtil { throw new GithubAuthenticationException("Anonymous connection not allowed"); } - try { - return testConnection(auth); - } - catch (JsonException e) { - throw new GithubAuthenticationException("Can't get user info", e); - } + return testConnection(auth); } @NotNull @@ -266,10 +268,10 @@ public class GithubUtil { if (GithubUrlUtil.isGithubUrl(remoteUrl)) { final String remoteName = gitRemote.getName(); if ("github".equals(remoteName) || "origin".equals(remoteName)) { - return new Pair<GitRemote, String>(gitRemote, remoteUrl); + return Pair.create(gitRemote, remoteUrl); } if (githubRemote == null) { - githubRemote = new Pair<GitRemote, String>(gitRemote, remoteUrl); + githubRemote = Pair.create(gitRemote, remoteUrl); } break; } diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/DataConstructor.java b/plugins/github/src/org/jetbrains/plugins/github/api/DataConstructor.java index d0005c12a858..20a957ccf746 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/api/DataConstructor.java +++ b/plugins/github/src/org/jetbrains/plugins/github/api/DataConstructor.java @@ -19,9 +19,7 @@ import org.jetbrains.annotations.NotNull; /** * @author Aleksey Pivovarov - */ - -/** + * * All fields of the raw type are nullable by the nature of GSon parser; * but some of them are required, so we want them to be @NotNull in the actual data class, * otherwise there is an error in JSon data received from the server diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java index 107476f56160..d83eec467cf7 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java @@ -43,6 +43,7 @@ public class GithubApiUtil { public static final String DEFAULT_GITHUB_HOST = "github.com"; private static final int CONNECTION_TIMEOUT = 5000; + private static final String PER_PAGE = "per_page=100"; private static final Logger LOG = GithubUtil.LOG; private static final Header ACCEPT_HTML_BODY_MARKUP = new Header("Accept", "application/vnd.github.v3.html+json"); @@ -84,7 +85,7 @@ public class GithubApiUtil { private static ResponsePage request(@NotNull GithubAuthData auth, @NotNull String path, @Nullable String requestBody, - @Nullable Collection<Header> headers, + @NotNull Collection<Header> headers, @NotNull HttpVerb verb) throws IOException { HttpMethod method = null; try { @@ -128,7 +129,7 @@ public class GithubApiUtil { private static HttpMethod doREST(@NotNull final GithubAuthData auth, @NotNull String path, @Nullable final String requestBody, - @Nullable final Collection<Header> headers, + @NotNull final Collection<Header> headers, @NotNull final HttpVerb verb) throws IOException { HttpClient client = getHttpClient(auth.getBasicAuth()); String uri = GithubUrlUtil.getApiUrl(auth.getHost()) + path; @@ -160,10 +161,8 @@ public class GithubApiUtil { if (tokenAuth != null) { method.addRequestHeader("Authorization", "token " + tokenAuth.getToken()); } - if (headers != null) { - for (Header header : headers) { - method.addRequestHeader(header); - } + for (Header header : headers) { + method.addRequestHeader(header); } return method; } @@ -207,10 +206,9 @@ public class GithubApiUtil { case HttpStatus.SC_UNAUTHORIZED: case HttpStatus.SC_PAYMENT_REQUIRED: case HttpStatus.SC_FORBIDDEN: - case HttpStatus.SC_NOT_FOUND: throw new GithubAuthenticationException("Request response: " + getErrorMessage(method)); default: - throw new HttpException(code + ": " + getErrorMessage(method)); + throw new GithubStatusCodeException(code + ": " + getErrorMessage(method), code); } } @@ -375,7 +373,7 @@ public class GithubApiUtil { public static Collection<String> getTokenScopes(@NotNull GithubAuthData auth) throws IOException { HttpMethod method = null; try { - method = doREST(auth, "", null, null, HttpVerb.HEAD); + method = doREST(auth, "/user", null, Collections.<Header>emptyList(), HttpVerb.HEAD); checkStatusCode(method); @@ -410,6 +408,16 @@ public class GithubApiUtil { } @NotNull + public static String getReadOnlyToken(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, @Nullable String note) + throws IOException { + GithubRepo repository = getDetailedRepoInfo(auth, user, repo); + + List<String> scopes = repository.isPrivate() ? Collections.singletonList("repo") : Collections.<String>emptyList(); + + return getScopedToken(auth, scopes, note); + } + + @NotNull public static GithubUser getCurrentUser(@NotNull GithubAuthData auth) throws IOException { JsonElement result = getRequest(auth, "/user"); return createDataFromRaw(fromJson(result, GithubUserRaw.class), GithubUser.class); @@ -433,7 +441,7 @@ public class GithubApiUtil { @NotNull private static List<GithubRepo> doGetAvailableRepos(@NotNull GithubAuthData auth, @Nullable String user) throws IOException { - String path = user == null ? "/user/repos" : "/users/" + user + "/repos?per_page=100"; + String path = user == null ? "/user/repos" : "/users/" + user + "/repos?" + PER_PAGE; PagedRequest<GithubRepo> request = new PagedRequest<GithubRepo>(path, GithubRepo.class, GithubRepoRaw[].class); @@ -509,10 +517,10 @@ public class GithubApiUtil { @Nullable String assigned) throws IOException { String path; if (StringUtil.isEmptyOrSpaces(assigned)) { - path = "/repos/" + user + "/" + repo + "/issues?per_page=100"; + path = "/repos/" + user + "/" + repo + "/issues?" + PER_PAGE; } else { - path = "/repos/" + user + "/" + repo + "/issues?assignee=" + assigned + "&per_page=100"; + path = "/repos/" + user + "/" + repo + "/issues?assignee=" + assigned + "&" + PER_PAGE; } PagedRequest<GithubIssue> request = new PagedRequest<GithubIssue>(path, GithubIssue.class, GithubIssueRaw[].class); @@ -521,7 +529,6 @@ public class GithubApiUtil { } @NotNull - public static List<GithubIssue> getIssuesQueried(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, @@ -549,7 +556,7 @@ public class GithubApiUtil { @NotNull public static List<GithubIssueComment> getIssueComments(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, long id) throws IOException { - String path = "/repos/" + user + "/" + repo + "/issues/" + id + "/comments?per_page=100"; + String path = "/repos/" + user + "/" + repo + "/issues/" + id + "/comments?" + PER_PAGE; PagedRequest<GithubIssueComment> request = new PagedRequest<GithubIssueComment>(path, GithubIssueComment.class, GithubIssueCommentRaw[].class, ACCEPT_HTML_BODY_MARKUP); @@ -579,7 +586,7 @@ public class GithubApiUtil { @NotNull public static List<GithubPullRequest> getPullRequests(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo) throws IOException { - String path = "/repos/" + user + "/" + repo + "/pulls?per_page=100"; + String path = "/repos/" + user + "/" + repo + "/pulls?" + PER_PAGE; PagedRequest<GithubPullRequest> request = new PagedRequest<GithubPullRequest>(path, GithubPullRequest.class, GithubPullRequestRaw[].class, ACCEPT_HTML_BODY_MARKUP); @@ -589,7 +596,7 @@ public class GithubApiUtil { @NotNull public static PagedRequest<GithubPullRequest> getPullRequests(@NotNull String user, @NotNull String repo) { - String path = "/repos/" + user + "/" + repo + "/pulls?per_page=100"; + String path = "/repos/" + user + "/" + repo + "/pulls?" + PER_PAGE; return new PagedRequest<GithubPullRequest>(path, GithubPullRequest.class, GithubPullRequestRaw[].class, ACCEPT_HTML_BODY_MARKUP); } @@ -597,7 +604,7 @@ public class GithubApiUtil { @NotNull public static List<GithubCommit> getPullRequestCommits(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, long id) throws IOException { - String path = "/repos/" + user + "/" + repo + "/pulls/" + id + "/commits?per_page=100"; + String path = "/repos/" + user + "/" + repo + "/pulls/" + id + "/commits?" + PER_PAGE; PagedRequest<GithubCommit> request = new PagedRequest<GithubCommit>(path, GithubCommit.class, GithubCommitRaw[].class); @@ -607,7 +614,7 @@ public class GithubApiUtil { @NotNull public static List<GithubFile> getPullRequestFiles(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, long id) throws IOException { - String path = "/repos/" + user + "/" + repo + "/pulls/" + id + "/files?per_page=100"; + String path = "/repos/" + user + "/" + repo + "/pulls/" + id + "/files?" + PER_PAGE; PagedRequest<GithubFile> request = new PagedRequest<GithubFile>(path, GithubFile.class, GithubFileRaw[].class); @@ -617,7 +624,7 @@ public class GithubApiUtil { @NotNull public static List<GithubBranch> getRepoBranches(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo) throws IOException { - String path = "/repos/" + user + "/" + repo + "/branches?per_page=100"; + String path = "/repos/" + user + "/" + repo + "/branches?" + PER_PAGE; PagedRequest<GithubBranch> request = new PagedRequest<GithubBranch>(path, GithubBranch.class, GithubBranchRaw[].class); @@ -629,7 +636,7 @@ public class GithubApiUtil { @NotNull String user, @NotNull String repo, @NotNull String forkUser) throws IOException { - String path = "/repos/" + user + "/" + repo + "/forks?per_page=100"; + String path = "/repos/" + user + "/" + repo + "/forks?" + PER_PAGE; PagedRequest<GithubRepo> request = new PagedRequest<GithubRepo>(path, GithubRepo.class, GithubRepoRaw[].class); diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubStatusCodeException.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubStatusCodeException.java new file mode 100644 index 000000000000..3b15c000d900 --- /dev/null +++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubStatusCodeException.java @@ -0,0 +1,34 @@ +/* + * 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 org.jetbrains.plugins.github.api; + +import java.io.IOException; + +/** + * @author Aleksey Pivovarov + */ +public class GithubStatusCodeException extends IOException { + private final int myStatusCode; + + public GithubStatusCodeException(String message, int statusCode) { + super(message); + myStatusCode = statusCode; + } + + public int getStatusCode() { + return myStatusCode; + } +} diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java index d2b4a8728ba1..df1fd7f38515 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java +++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java @@ -13,16 +13,19 @@ import com.intellij.util.ThrowableConvertor; import com.intellij.util.ui.FormBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.github.*; import org.jetbrains.plugins.github.GithubAuthData; +import org.jetbrains.plugins.github.GithubAuthenticationCanceledException; +import org.jetbrains.plugins.github.GithubNotifications; +import org.jetbrains.plugins.github.GithubUtil; import org.jetbrains.plugins.github.api.GithubApiUtil; 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.util.Collection; -import java.util.Collections; /** * @author Dennis.Ushakov @@ -34,7 +37,7 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor private JButton myTokenButton; private JBLabel myRepoAuthorLabel; private JBLabel myRepoLabel; - private JCheckBox myPrivateRepo; + private JBLabel myTokenLabel; public GithubRepositoryEditor(final Project project, final GithubRepository repository, Consumer<GithubRepository> changeListener) { super(project, repository, changeListener); @@ -42,11 +45,32 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor myUsernameLabel.setVisible(false); myPasswordText.setVisible(false); myPasswordLabel.setVisible(false); + myUseHttpAuthenticationCheckBox.setVisible(false); myToken.setText(repository.getToken()); myRepoAuthor.setText(repository.getRepoAuthor()); myRepoName.setText(repository.getRepoName()); - myPrivateRepo.setSelected(false); + + DocumentListener buttonUpdater = new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + updateTokenButton(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + updateTokenButton(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + updateTokenButton(); + } + }; + + myRepoAuthor.getDocument().addDocumentListener(buttonUpdater); + myRepoName.getDocument().addDocumentListener(buttonUpdater); + myURLText.getDocument().addDocumentListener(buttonUpdater); setAnchor(myRepoAuthorLabel); } @@ -56,7 +80,7 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor protected JComponent createCustomPanel() { myUrlLabel.setText("Host:"); - myRepoAuthorLabel = new JBLabel("Repository author:", SwingConstants.RIGHT); + myRepoAuthorLabel = new JBLabel("Repository Owner:", SwingConstants.RIGHT); myRepoAuthor = new JTextField(); installListener(myRepoAuthor); @@ -64,9 +88,10 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor myRepoName = new JTextField(); installListener(myRepoName); + myTokenLabel = new JBLabel("API Token:", SwingConstants.RIGHT); myToken = new JTextField(); installListener(myToken); - myTokenButton = new JButton("API token"); + myTokenButton = new JButton("Create API token"); myTokenButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { generateToken(); @@ -74,70 +99,39 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor } }); - myPrivateRepo = new JCheckBox("Private repository"); - installListener(myPrivateRepo); + JPanel myTokenPanel = new JPanel(); + myTokenPanel.setLayout(new BorderLayout(5, 5)); + myTokenPanel.add(myToken, BorderLayout.CENTER); + myTokenPanel.add(myTokenButton, BorderLayout.EAST); - return FormBuilder.createFormBuilder().setAlignLabelOnRight(true).addLabeledComponent(myTokenButton, myToken) - .addLabeledComponent(myRepoAuthorLabel, myRepoAuthor).addLabeledComponent(myRepoLabel, myRepoName) - .addComponentToRightColumn(myPrivateRepo).getPanel(); + return FormBuilder.createFormBuilder().setAlignLabelOnRight(true).addLabeledComponent(myRepoAuthorLabel, myRepoAuthor) + .addLabeledComponent(myRepoLabel, myRepoName).addLabeledComponent(myTokenLabel, myTokenPanel).getPanel(); } @Override public void apply() { - myRepository.setRepoName(myRepoName.getText().trim()); - myRepository.setRepoAuthor(myRepoAuthor.getText().trim()); - myRepository.setToken(myToken.getText().trim()); - myUseHttpAuthenticationCheckBox.setSelected(!StringUtil.isEmpty(myUserNameText.getText())); + myRepository.setRepoName(getRepoName()); + myRepository.setRepoAuthor(getRepoAuthor()); + myRepository.setToken(getToken()); super.apply(); } - @Override - protected void afterTestConnection(final boolean connectionSuccessful) { - if (connectionSuccessful) { - final Ref<Collection<String>> scopesRef = new Ref<Collection<String>>(); - final Ref<IOException> exceptionRef = new Ref<IOException>(); - ProgressManager.getInstance().run(new Task.Modal(myProject, "Access to GitHub", true) { - public void run(@NotNull ProgressIndicator indicator) { - try { - scopesRef - .set(GithubApiUtil.getTokenScopes(GithubAuthData.createTokenAuth(myURLText.getText().trim(), myToken.getText().trim()))); - } - catch (IOException e) { - exceptionRef.set(e); - } - } - }); - if (!exceptionRef.isNull()) { - GithubNotifications.showErrorDialog(myProject, "Can't check token scopes", exceptionRef.get()); - return; - } - Collection<String> scopes = scopesRef.get(); - if (myPrivateRepo.isSelected()) { - scopes.remove("repo"); - } - if (scopes.isEmpty()) { - return; - } - GithubNotifications - .showWarningDialog(myProject, "Unneeded token scopes detected", "Unneeded scopes: " + StringUtil.join(scopes, ", ")); - } - } - private void generateToken() { final Ref<String> tokenRef = new Ref<String>(); final Ref<IOException> exceptionRef = new Ref<IOException>(); - final Collection<String> scopes = myPrivateRepo.isSelected() ? Collections.singleton("repo") : Collections.<String>emptyList(); ProgressManager.getInstance().run(new Task.Modal(myProject, "Access to GitHub", true) { public void run(@NotNull ProgressIndicator indicator) { try { - tokenRef.set(GithubUtil.runWithValidBasicAuth(myProject, indicator, new ThrowableConvertor<GithubAuthData, String, IOException>() { - @Nullable - @Override - public String convert(GithubAuthData auth) throws IOException { - return GithubApiUtil.getScopedToken(auth, scopes, "Intellij tasks plugin"); - - } - })); + tokenRef.set(GithubUtil.runWithValidBasicAuthForHost(myProject, indicator, getHost(), + new ThrowableConvertor<GithubAuthData, String, IOException>() { + @NotNull + @Override + public String convert(GithubAuthData auth) throws IOException { + return GithubApiUtil + .getReadOnlyToken(auth, getRepoAuthor(), getRepoName(), + "Intellij tasks plugin"); + } + })); } catch (IOException e) { exceptionRef.set(e); @@ -159,5 +153,37 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor super.setAnchor(anchor); myRepoAuthorLabel.setAnchor(anchor); myRepoLabel.setAnchor(anchor); + myTokenLabel.setAnchor(anchor); + } + + private void updateTokenButton() { + if (StringUtil.isEmptyOrSpaces(getHost()) || + StringUtil.isEmptyOrSpaces(getRepoAuthor()) || + StringUtil.isEmptyOrSpaces(getRepoName())) { + myTokenButton.setEnabled(false); + } + else { + myTokenButton.setEnabled(true); + } + } + + @NotNull + private String getHost() { + return myURLText.getText().trim(); + } + + @NotNull + private String getRepoAuthor() { + return myRepoAuthor.getText().trim(); + } + + @NotNull + private String getRepoName() { + return myRepoName.getText().trim(); + } + + @NotNull + private String getToken() { + return myToken.getText().trim(); } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubBasicLoginDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubBasicLoginDialog.java index 3395d7247874..da9a7e9ef63b 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubBasicLoginDialog.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubBasicLoginDialog.java @@ -34,8 +34,7 @@ public class GithubBasicLoginDialog extends GithubLoginDialog { protected void saveCredentials(GithubAuthData auth) { final GithubSettings settings = GithubSettings.getInstance(); if (settings.getAuthType() != GithubAuthData.AuthType.TOKEN) { - settings - .setCredentials(myGithubLoginPanel.getHost(), myGithubLoginPanel.getLogin(), auth, myGithubLoginPanel.isSavePasswordSelected()); + settings.setCredentials(myGithubLoginPanel.getHost(), auth, myGithubLoginPanel.isSavePasswordSelected()); } } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistDialog.java index 259cb393a77f..4e9a70a83559 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistDialog.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistDialog.java @@ -32,7 +32,7 @@ import javax.swing.*; public class GithubCreateGistDialog extends DialogWrapper { private final GithubCreateGistPanel myGithubCreateGistPanel; - public GithubCreateGistDialog(@NotNull final Project project, @Nullable Editor editor, @Nullable VirtualFile file) { + public GithubCreateGistDialog(@NotNull final Project project, @Nullable Editor editor, @Nullable VirtualFile[] files, @Nullable VirtualFile file) { super(project, true); myGithubCreateGistPanel = new GithubCreateGistPanel(); // Use saved settings for controls @@ -41,21 +41,27 @@ public class GithubCreateGistDialog extends DialogWrapper { myGithubCreateGistPanel.setPrivate(settings.isPrivateGist()); myGithubCreateGistPanel.setOpenInBrowser(settings.isOpenInBrowserGist()); - if (file != null && !file.isDirectory()) { - myGithubCreateGistPanel.showFileNameField(file.getName()); + if (editor != null) { + if (file != null) { + myGithubCreateGistPanel.showFileNameField(file.getName()); + } + else { + myGithubCreateGistPanel.showFileNameField(""); + } + } + else if (files != null) { + if (files.length == 1 && !files[0].isDirectory()) { + myGithubCreateGistPanel.showFileNameField(files[0].getName()); + } } - else if (editor != null) { - myGithubCreateGistPanel.showFileNameField(""); + else if (file != null && !file.isDirectory()) { + myGithubCreateGistPanel.showFileNameField(file.getName()); } + setTitle("Create Gist"); init(); } - @NotNull - protected Action[] createActions() { - return new Action[] {getOKAction(), getCancelAction(), getHelpAction()}; - } - @Override protected JComponent createCenterPanel() { return myGithubCreateGistPanel.getPanel(); diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistPanel.form index bc2c02451e28..5b6207c7257a 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistPanel.form +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreateGistPanel.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="org.jetbrains.plugins.github.ui.GithubCreateGistPanel"> - <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="4" 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"/> @@ -8,19 +8,6 @@ <properties/> <border type="none"/> <children> - <vspacer id="1202b"> - <constraints> - <grid row="4" 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="51bc1" class="javax.swing.JTextArea" binding="myDescriptionTextArea"> - <constraints> - <grid row="2" column="0" row-span="1" col-span="4" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"> - <preferred-size width="150" height="50"/> - </grid> - </constraints> - <properties/> - </component> <component id="b0e4d" class="javax.swing.JLabel"> <constraints> <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> @@ -74,6 +61,22 @@ </constraints> <properties/> </component> + <scrollpane id="6c5d2" class="com.intellij.ui.components.JBScrollPane"> + <constraints> + <grid row="2" column="0" row-span="1" col-span="4" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"> + <minimum-size width="150" height="50"/> + <preferred-size width="150" height="50"/> + </grid> + </constraints> + <properties/> + <border type="none"/> + <children> + <component id="51bc1" class="javax.swing.JTextArea" binding="myDescriptionTextArea"> + <constraints/> + <properties/> + </component> + </children> + </scrollpane> </children> </grid> </form> diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestDialog.java index 8308b3dfcf9f..32e6184040b5 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestDialog.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestDialog.java @@ -26,6 +26,7 @@ import org.jetbrains.plugins.github.GithubSettings; import javax.swing.*; import java.util.Collection; +import java.util.List; import java.util.regex.Pattern; /** @@ -35,11 +36,14 @@ public class GithubCreatePullRequestDialog extends DialogWrapper { private final GithubCreatePullRequestPanel myGithubCreatePullRequestPanel; private static final Pattern GITHUB_REPO_PATTERN = Pattern.compile("[a-zA-Z0-9_.-]+:[a-zA-Z0-9_.-]+"); - public GithubCreatePullRequestDialog(@NotNull final Project project) { + public GithubCreatePullRequestDialog(@NotNull final Project project, @NotNull List<String> branches, @Nullable String suggestedBranch) { super(project, true); myGithubCreatePullRequestPanel = new GithubCreatePullRequestPanel(); - myGithubCreatePullRequestPanel.setBranch(GithubSettings.getInstance().getCreatePullRequestDefaultBranch()); + myGithubCreatePullRequestPanel.setBranches(branches); + + String configBranch = GithubSettings.getInstance().getCreatePullRequestDefaultBranch(); + myGithubCreatePullRequestPanel.setSelectedBranch(configBranch != null ? configBranch : suggestedBranch); setTitle("Create Pull Request"); init(); @@ -83,14 +87,6 @@ public class GithubCreatePullRequestDialog extends DialogWrapper { GithubSettings.getInstance().setCreatePullRequestDefaultBranch(getTargetBranch()); } - public void addBranches(@NotNull Collection<String> branches) { - myGithubCreatePullRequestPanel.addBranches(branches); - } - - public void setBusy(boolean busy) { - myGithubCreatePullRequestPanel.setBusy(busy); - } - @Nullable @Override protected ValidationInfo doValidate() { @@ -111,6 +107,6 @@ public class GithubCreatePullRequestDialog extends DialogWrapper { @TestOnly public void setBranch(String branch) { - myGithubCreatePullRequestPanel.setBranch(branch); + myGithubCreatePullRequestPanel.setSelectedBranch(branch); } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestPanel.form index cf528f8ed93c..e5dda901b53e 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestPanel.form +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestPanel.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="org.jetbrains.plugins.github.ui.GithubCreatePullRequestPanel"> - <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" 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"/> @@ -34,21 +34,13 @@ </component> <component id="996e9" class="javax.swing.JTextField" binding="myTitleTextField"> <constraints> - <grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> + <grid row="1" column="1" 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="21aa4" class="javax.swing.JTextArea" binding="myDescriptionTextArea"> - <constraints> - <grid row="3" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"> - <preferred-size width="150" height="50"/> - </grid> - </constraints> - <properties/> - </component> - <component id="78a64" class="javax.swing.JComboBox" binding="myBranchComboBox"> + <component id="78a64" class="com.intellij.openapi.ui.ComboBox" binding="myBranchComboBox"> <constraints> <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/> </constraints> @@ -57,17 +49,21 @@ <toolTipText value="Target branch in format 'user:branch', where user - owner of the target repository"/> </properties> </component> - <vspacer id="2ad8"> + <scrollpane id="61e54" class="com.intellij.ui.components.JBScrollPane"> <constraints> - <grid row="4" 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="5be7e" class="com.intellij.util.ui.AsyncProcessIcon" binding="myAsyncProcessIcon" custom-create="true"> - <constraints> - <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/> + <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"> + <minimum-size width="150" height="50"/> + </grid> </constraints> <properties/> - </component> + <border type="none"/> + <children> + <component id="21aa4" class="javax.swing.JTextArea" binding="myDescriptionTextArea"> + <constraints/> + <properties/> + </component> + </children> + </scrollpane> </children> </grid> </form> diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestPanel.java index 1714e85fe36f..a178024d1911 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestPanel.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubCreatePullRequestPanel.java @@ -15,13 +15,15 @@ */ package org.jetbrains.plugins.github.ui; +import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.ui.AsyncProcessIcon; +import com.intellij.ui.SortedComboBoxModel; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.Collection; -import java.util.HashSet; +import java.util.Comparator; /** * @author Aleksey Pivovarov @@ -29,12 +31,19 @@ import java.util.HashSet; public class GithubCreatePullRequestPanel { private JTextField myTitleTextField; private JTextArea myDescriptionTextArea; - private JComboBox myBranchComboBox; + private ComboBox myBranchComboBox; + private SortedComboBoxModel<String> myBranchModel; private JPanel myPanel; - private AsyncProcessIcon myAsyncProcessIcon; public GithubCreatePullRequestPanel() { myDescriptionTextArea.setBorder(BorderFactory.createEtchedBorder()); + myBranchModel = new SortedComboBoxModel<String>(new Comparator<String>() { + @Override + public int compare(String o1, String o2) { + return StringUtil.naturalCompare(o1, o2); + } + }); + myBranchComboBox.setModel(myBranchModel); } @NotNull @@ -52,30 +61,18 @@ public class GithubCreatePullRequestPanel { return myBranchComboBox.getSelectedItem().toString(); } - public void setBranch(@NotNull String branch) { + public void setSelectedBranch(@Nullable String branch) { if (StringUtil.isEmptyOrSpaces(branch)) { + myBranchComboBox.setSelectedItem(""); return; } - for (int i = 0; i < myBranchComboBox.getItemCount(); i++) { - Object element = myBranchComboBox.getItemAt(i); - if (branch.equals(element)) { - myBranchComboBox.setSelectedItem(element); - return; - } - } - myBranchComboBox.addItem(branch); myBranchComboBox.setSelectedItem(branch); } - public void addBranches(@NotNull Collection<String> branches) { - HashSet<Object> set = new HashSet<Object>(branches); - for (int i = 0; i < myBranchComboBox.getItemCount(); i++) { - set.remove(myBranchComboBox.getItemAt(i)); - } - for (Object element : set) { - myBranchComboBox.addItem(element); - } + public void setBranches(@NotNull Collection<String> branches) { + myBranchModel.clear(); + myBranchModel.addAll(branches); } public JPanel getPanel() { @@ -87,15 +84,6 @@ public class GithubCreatePullRequestPanel { return myTitleTextField; } - public void setBusy(boolean busy) { - if (busy) { - myAsyncProcessIcon.resume(); - } - else { - myAsyncProcessIcon.suspend(); - } - } - public JComboBox getComboBox() { return myBranchComboBox; } @@ -107,8 +95,4 @@ public class GithubCreatePullRequestPanel { public void setTitle(String title) { myTitleTextField.setText(title); } - - private void createUIComponents() { - myAsyncProcessIcon = new AsyncProcessIcon("Loading available branches"); - } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java index 402cb4eb1a9a..e7968be7b7df 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginDialog.java @@ -6,10 +6,8 @@ import com.intellij.openapi.ui.DialogWrapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.github.GithubAuthData; -import org.jetbrains.plugins.github.GithubAuthenticationException; import org.jetbrains.plugins.github.GithubSettings; import org.jetbrains.plugins.github.GithubUtil; -import org.jetbrains.plugins.github.api.GithubUserDetailed; import javax.swing.*; import java.io.IOException; @@ -70,12 +68,7 @@ public class GithubLoginDialog extends DialogWrapper { protected void doOKAction() { final GithubAuthData auth = myGithubLoginPanel.getAuthData(); try { - GithubUserDetailed user = GithubUtil.checkAuthData(auth); - if (!myGithubLoginPanel.getLogin().equalsIgnoreCase(user.getLogin())) { - myGithubLoginPanel.setLogin(user.getLogin()); - setErrorText("Login doesn't match credentials. Fixed"); - return; - } + GithubUtil.checkAuthData(auth); saveCredentials(auth); if (mySettings.isSavePasswordMakesSense()) { @@ -91,7 +84,7 @@ public class GithubLoginDialog extends DialogWrapper { protected void saveCredentials(GithubAuthData auth) { final GithubSettings settings = GithubSettings.getInstance(); - settings.setCredentials(myGithubLoginPanel.getHost(), myGithubLoginPanel.getLogin(), auth, myGithubLoginPanel.isSavePasswordSelected()); + settings.setCredentials(myGithubLoginPanel.getHost(), auth, myGithubLoginPanel.isSavePasswordSelected()); } public void clearErrors() { @@ -102,4 +95,8 @@ public class GithubLoginDialog extends DialogWrapper { public GithubAuthData getAuthData() { return myGithubLoginPanel.getAuthData(); } + + public void lockHost(String host) { + myGithubLoginPanel.lockHost(host); + } }
\ No newline at end of file diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form index 7dad2a149ac9..eedbe5e17b00 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.form @@ -3,29 +3,13 @@ <grid id="27dc6" binding="myPane" layout-manager="GridLayoutManager" row-count="6" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <xy x="20" y="20" width="500" height="168"/> + <xy x="20" y="20" width="500" height="174"/> </constraints> <properties> <focusable value="false"/> </properties> <border type="none"/> <children> - <component id="e76ec" class="javax.swing.JTextField" binding="myLoginTextField"> - <constraints> - <grid row="1" column="1" row-span="1" col-span="2" 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="c0234" class="javax.swing.JLabel"> - <constraints> - <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="Login:"/> - </properties> - </component> <component id="28ddd" class="javax.swing.JTextPane" binding="mySignupTextField"> <constraints> <grid row="4" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> @@ -71,7 +55,7 @@ </component> <component id="f851a" class="javax.swing.JComboBox" binding="myAuthTypeComboBox"> <constraints> - <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false"/> + <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false"/> </constraints> <properties> <model/> @@ -80,7 +64,7 @@ </component> <component id="b466f" class="javax.swing.JCheckBox" binding="mySavePasswordCheckBox"> <constraints> - <grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"> + <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"> <preferred-size width="120" height="-1"/> </grid> </constraints> @@ -91,7 +75,7 @@ </component> <component id="325bb" class="javax.swing.JLabel"> <constraints> - <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> <text value="Auth type:"/> @@ -105,6 +89,22 @@ <text value="Password:"/> </properties> </component> + <component id="e76ec" class="javax.swing.JTextField" binding="myLoginTextField"> + <constraints> + <grid row="2" column="1" row-span="1" col-span="2" 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="c0234" class="javax.swing.JLabel" binding="myLoginLabel"> + <constraints> + <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <text value="Login:"/> + </properties> + </component> </children> </grid> </form> diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.java index 226265546db1..ea565e03c5c9 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubLoginPanel.java @@ -21,6 +21,7 @@ import com.intellij.ui.HyperlinkAdapter; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.table.ComponentsListFocusTraversalPolicy; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.github.GithubAuthData; import org.jetbrains.plugins.github.GithubUtil; @@ -31,7 +32,7 @@ import javax.swing.event.HyperlinkEvent; import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; -import java.util.*; +import java.util.ArrayList; import java.util.List; /** @@ -47,6 +48,7 @@ public class GithubLoginPanel { private JCheckBox mySavePasswordCheckBox; private JComboBox myAuthTypeComboBox; private JLabel myPasswordLabel; + private JLabel myLoginLabel; private final static String AUTH_PASSWORD = "Password"; private final static String AUTH_TOKEN = "Token"; @@ -79,8 +81,21 @@ public class GithubLoginPanel { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { String item = e.getItem().toString(); - myPasswordLabel.setText(item + ":"); - mySavePasswordCheckBox.setText("Save " + item.toLowerCase()); + if (AUTH_PASSWORD.equals(item)) { + myPasswordLabel.setText("Password:"); + mySavePasswordCheckBox.setText("Save password"); + myLoginLabel.setVisible(true); + myLoginTextField.setVisible(true); + } + if (AUTH_TOKEN.equals(item)) { + myPasswordLabel.setText("Token:"); + mySavePasswordCheckBox.setText("Save token"); + myLoginLabel.setVisible(false); + myLoginTextField.setVisible(false); + } + if (dialog.isShowing()) { + dialog.pack(); + } } } }); @@ -103,7 +118,7 @@ public class GithubLoginPanel { myHostTextField.setText(host); } - public void setLogin(@NotNull String login) { + public void setLogin(@Nullable String login) { myLoginTextField.setText(login); } @@ -125,6 +140,11 @@ public class GithubLoginPanel { myAuthTypeComboBox.setEnabled(false); } + public void lockHost(@NotNull String host) { + setHost(host); + myHostTextField.setEnabled(false); + } + public void setSavePasswordSelected(boolean savePassword) { mySavePasswordCheckBox.setSelected(savePassword); } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsConfigurable.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsConfigurable.java index 03e3b08801ef..f4c312d11b13 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsConfigurable.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsConfigurable.java @@ -46,7 +46,7 @@ public class GithubSettingsConfigurable implements SearchableConfigurable, VcsCo public void apply() throws ConfigurationException { if (mySettingsPane != null) { - mySettings.setCredentials(mySettingsPane.getHost(), mySettingsPane.getLogin(), mySettingsPane.getAuthData(), true); + mySettings.setCredentials(mySettingsPane.getHost(), mySettingsPane.getAuthData(), true); mySettingsPane.resetCredentialsModification(); } } diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form index 81400ae3000e..cc283855bc64 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form @@ -16,7 +16,7 @@ </constraints> <properties/> </component> - <component id="c0234" class="javax.swing.JLabel"> + <component id="c0234" class="javax.swing.JLabel" binding="myLoginLabel"> <constraints> <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java index c6a18378802e..54e1f61b1a14 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java +++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java @@ -22,8 +22,12 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.HyperlinkAdapter; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.github.*; -import org.jetbrains.plugins.github.api.GithubUserDetailed; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.github.GithubAuthData; +import org.jetbrains.plugins.github.GithubAuthenticationException; +import org.jetbrains.plugins.github.GithubSettings; +import org.jetbrains.plugins.github.GithubUtil; +import org.jetbrains.plugins.github.api.GithubUser; import javax.swing.*; import javax.swing.event.DocumentEvent; @@ -53,6 +57,7 @@ public class GithubSettingsPanel { private JButton myTestButton; private JTextField myHostTextField; private JComboBox myAuthTypeComboBox; + private JLabel myLoginLabel; private boolean myCredentialsModified; @@ -71,19 +76,17 @@ public class GithubSettingsPanel { myAuthTypeComboBox.addItem(AUTH_PASSWORD); myAuthTypeComboBox.addItem(AUTH_TOKEN); - reset(); - myTestButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { - GithubUserDetailed user = GithubUtil.checkAuthData(getAuthData()); - if (!getLogin().equalsIgnoreCase(user.getLogin())) { - setLogin(user.getLogin()); - Messages.showInfoMessage(myPane, "Login doesn't match credentials. Fixed", "Success"); - return; + GithubUser user = GithubUtil.checkAuthData(getAuthData()); + if (GithubAuthData.AuthType.TOKEN.equals(getAuthType())) { + Messages.showInfoMessage(myPane, "Connection successful for user " + user.getLogin(), "Success"); + } + else { + Messages.showInfoMessage(myPane, "Connection successful", "Success"); } - Messages.showInfoMessage(myPane, "Connection successful", "Success"); } catch (GithubAuthenticationException ex) { Messages.showErrorDialog(myPane, "Can't login using given credentials: " + ex.getMessage(), "Login Failure"); @@ -116,24 +119,21 @@ public class GithubSettingsPanel { @Override public void insertUpdate(DocumentEvent e) { if (!myCredentialsModified) { - setPassword(""); - myCredentialsModified = true; + erasePassword(); } } @Override public void removeUpdate(DocumentEvent e) { if (!myCredentialsModified) { - setPassword(""); - myCredentialsModified = true; + erasePassword(); } } @Override public void changedUpdate(DocumentEvent e) { if (!myCredentialsModified) { - setPassword(""); - myCredentialsModified = true; + erasePassword(); } } }; @@ -145,8 +145,7 @@ public class GithubSettingsPanel { @Override public void focusGained(FocusEvent e) { if (!myCredentialsModified && !getPassword().isEmpty()) { - setPassword(""); - myCredentialsModified = true; + erasePassword(); } } @@ -158,10 +157,28 @@ public class GithubSettingsPanel { myAuthTypeComboBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { - setPassword(""); - myCredentialsModified = true; + if (e.getStateChange() == ItemEvent.SELECTED) { + String item = e.getItem().toString(); + if (AUTH_PASSWORD.equals(item)) { + myLoginLabel.setVisible(true); + myLoginTextField.setVisible(true); + } + if (AUTH_TOKEN.equals(item)) { + myLoginLabel.setVisible(false); + myLoginTextField.setVisible(false); + } + myPane.validate(); + erasePassword(); + } } }); + + reset(); + } + + private void erasePassword() { + setPassword(""); + myCredentialsModified = true; } public JComponent getPanel() { @@ -182,7 +199,7 @@ public class GithubSettingsPanel { myHostTextField.setText(host); } - public void setLogin(@NotNull final String login) { + public void setLogin(@Nullable final String login) { myLoginTextField.setText(login); } @@ -232,18 +249,15 @@ public class GithubSettingsPanel { } public void reset() { - String login = mySettings.getLogin(); setHost(mySettings.getHost()); - setLogin(login); - setPassword(login.isEmpty() ? "" : DEFAULT_PASSWORD_TEXT); + setLogin(mySettings.getLogin()); + setPassword(mySettings.isAuthConfigured() ? DEFAULT_PASSWORD_TEXT : ""); setAuthType(mySettings.getAuthType()); resetCredentialsModification(); } public boolean isModified() { - return !Comparing.equal(mySettings.getHost(), getHost()) || - !Comparing.equal(mySettings.getLogin(), getLogin()) || - myCredentialsModified; + return !Comparing.equal(mySettings.getHost(), getHost()) || myCredentialsModified; } public void resetCredentialsModification() { diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTest.java index b3c04d8ec2f0..53843019d3f2 100644 --- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTest.java +++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTest.java @@ -52,4 +52,19 @@ public class GithubCreatePullRequestTest extends GithubCreatePullRequestTestBase checkRemoteConfigured(); checkLastCommitPushed(); } + + public void testCommitRef1() throws Exception { + registerDefaultCreatePullRequestDialogHandler(myLogin1 + ":refs/heads/master"); + + cd(myProjectRoot.getPath()); + cloneRepo(); + createBranch(); + createChanges(); + + GithubCreatePullRequestAction.createPullRequest(myProject, myProjectRoot); + + checkNotification(NotificationType.INFORMATION, "Successfully created pull request", null); + checkRemoteConfigured(); + checkLastCommitPushed(); + } } diff --git a/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java b/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java index 21c78af951dd..ee5233c8057e 100644 --- a/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java +++ b/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java @@ -173,7 +173,7 @@ public abstract class GithubTest extends UsefulTestCase { myAuth = GithubAuthData.createBasicAuth(host, login1, password); myGitHubSettings = GithubSettings.getInstance(); - myGitHubSettings.setCredentials(myHost, myLogin1, myAuth, false); + myGitHubSettings.setCredentials(myHost, myAuth, false); myDialogManager = (TestDialogManager)ServiceManager.getService(DialogManager.class); myNotificator = (TestNotificator)ServiceManager.getService(myProject, Notificator.class); diff --git a/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java b/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java index 2e7dae2262ea..5e2d5ead054d 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/actions/AppEngineUploader.java @@ -69,6 +69,8 @@ import com.intellij.packaging.impl.artifacts.ArtifactUtil; import com.intellij.packaging.impl.compiler.ArtifactCompileScope; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; +import com.intellij.remoteServer.runtime.deployment.DeploymentRuntime; +import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance; import com.intellij.util.net.HttpConfigurable; import com.intellij.util.xml.GenericDomValue; import org.jetbrains.annotations.NotNull; @@ -90,40 +92,39 @@ public class AppEngineUploader { private final AppEngineSdk mySdk; private final String myEmail; private final String myPassword; + private final ServerRuntimeInstance.DeploymentOperationCallback myCallback; - private AppEngineUploader(Project project, - Artifact artifact, - AppEngineFacet appEngineFacet, - AppEngineSdk sdk, - String email, - String password) { + private AppEngineUploader(Project project, Artifact artifact, AppEngineFacet appEngineFacet, AppEngineSdk sdk, String email, + String password, ServerRuntimeInstance.DeploymentOperationCallback callback) { myProject = project; myArtifact = artifact; myAppEngineFacet = appEngineFacet; mySdk = sdk; myEmail = email; myPassword = password; + myCallback = callback; } @Nullable public static AppEngineUploader createUploader(@NotNull Project project, @NotNull Artifact artifact, - @Nullable AppEngineServerConfiguration configuration) { + @Nullable AppEngineServerConfiguration configuration, + ServerRuntimeInstance.DeploymentOperationCallback callback) { final String explodedPath = artifact.getOutputPath(); if (explodedPath == null) { - Messages.showErrorDialog(project, "Output path isn't specified for '" + artifact.getName() + "' artifact", CommonBundle.getErrorTitle()); + callback.errorOccurred("Output path isn't specified for '" + artifact.getName() + "' artifact"); return null; } final AppEngineFacet appEngineFacet = AppEngineUtil.findAppEngineFacet(project, artifact); if (appEngineFacet == null) { - Messages.showErrorDialog(project, "App Engine facet not found in '" + artifact.getName() + "' artifact", CommonBundle.getErrorTitle()); + callback.errorOccurred("App Engine facet not found in '" + artifact.getName() + "' artifact"); return null; } final AppEngineSdk sdk = appEngineFacet.getSdk(); if (!sdk.getAppCfgFile().exists()) { - Messages.showErrorDialog(project, "Path to App Engine SDK isn't specified correctly in App Engine Facet settings", CommonBundle.getErrorTitle()); + callback.errorOccurred("Path to App Engine SDK isn't specified correctly in App Engine Facet settings"); return null; } @@ -169,7 +170,7 @@ public class AppEngineUploader { password = dialog.getPassword(); } - return new AppEngineUploader(project, artifact, appEngineFacet, sdk, email, password); + return new AppEngineUploader(project, artifact, appEngineFacet, sdk, email, password, callback); } public void startUploading() { @@ -235,7 +236,7 @@ public class AppEngineUploader { process = commandLine.createProcess(); } catch (ExecutionException e) { - Messages.showErrorDialog(myProject, "Cannot start uploading: " + e.getMessage(), CommonBundle.getErrorTitle()); + myCallback.errorOccurred("Cannot start uploading: " + e.getMessage()); return; } @@ -281,5 +282,12 @@ public class AppEngineUploader { } } } + + @Override + public void processTerminated(ProcessEvent event) { + if (event.getExitCode() == 0) { + myCallback.succeeded(new DeploymentRuntime()); + } + } } } diff --git a/plugins/google-app-engine/source/com/intellij/appengine/actions/UploadApplicationAction.java b/plugins/google-app-engine/source/com/intellij/appengine/actions/UploadApplicationAction.java index 15fb4051d1db..fe7f71dbb51b 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/actions/UploadApplicationAction.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/actions/UploadApplicationAction.java @@ -24,6 +24,9 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.packaging.artifacts.Artifact; +import com.intellij.remoteServer.runtime.deployment.DeploymentRuntime; +import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -57,7 +60,17 @@ public class UploadApplicationAction extends AnAction { return; } } - final AppEngineUploader uploader = AppEngineUploader.createUploader(project, artifact, null); + final AppEngineUploader uploader = AppEngineUploader.createUploader(project, artifact, null, new ServerRuntimeInstance.DeploymentOperationCallback() { + @Override + public void succeeded(@NotNull DeploymentRuntime deployment) { + + } + + @Override + public void errorOccurred(@NotNull String errorMessage) { + Messages.showErrorDialog(project, errorMessage, CommonBundle.getErrorTitle()); + } + }); if (uploader != null) { uploader.startUploading(); } diff --git a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java index a7b798c6df2e..b69b47a034fe 100644 --- a/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java +++ b/plugins/google-app-engine/source/com/intellij/appengine/cloud/AppEngineCloudType.java @@ -25,10 +25,12 @@ import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.artifacts.ArtifactPointerManager; import com.intellij.remoteServer.ServerType; import com.intellij.remoteServer.configuration.deployment.*; +import com.intellij.remoteServer.runtime.Deployment; import com.intellij.remoteServer.runtime.ServerConnector; import com.intellij.remoteServer.runtime.ServerTaskExecutor; import com.intellij.remoteServer.runtime.deployment.DeploymentTask; import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.FormBuilder; import icons.GoogleAppEngineIcons; import org.jetbrains.annotations.NotNull; @@ -181,15 +183,15 @@ public class AppEngineCloudType extends ServerType<AppEngineServerConfiguration> Artifact artifact = ((ArtifactDeploymentSource)task.getSource()).getArtifact(); if (artifact == null) return; - AppEngineUploader uploader = AppEngineUploader.createUploader(task.getProject(), artifact, myConfiguration); + AppEngineUploader uploader = AppEngineUploader.createUploader(task.getProject(), artifact, myConfiguration, callback); if (uploader != null) { uploader.startUploading(); } } @Override - public void undeploy(@NotNull DeploymentTask<DummyDeploymentConfiguration> task, - @NotNull DeploymentOperationCallback callback) { + public void computeDeployments(@NotNull ComputeDeploymentsCallback deployments) { + deployments.succeeded(ContainerUtil.<Deployment>emptyList()); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/AbstractMvcPsiNodeDescriptor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/AbstractMvcPsiNodeDescriptor.java index e1639e4b0774..b7e19ba80012 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/AbstractMvcPsiNodeDescriptor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/AbstractMvcPsiNodeDescriptor.java @@ -10,7 +10,7 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.problems.WolfTheProblemSolver; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFileSystemItem; +import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -59,6 +59,7 @@ public abstract class AbstractMvcPsiNodeDescriptor extends AbstractPsiBasedNode< return super.contains(file); } + @Override @Nullable protected PsiElement extractPsiFromValue() { final NodeId nodeId = getValue(); @@ -86,15 +87,10 @@ public abstract class AbstractMvcPsiNodeDescriptor extends AbstractPsiBasedNode< if (!isValid()) { return null; } - final PsiElement psiElement = extractPsiFromValue(); - assert psiElement != null; - - if (psiElement instanceof PsiFileSystemItem) { - return ((PsiFileSystemItem)psiElement).getVirtualFile(); - } - return psiElement.getContainingFile().getVirtualFile(); + return PsiUtilCore.getVirtualFile(extractPsiFromValue()); } + @Override protected void updateImpl(final PresentationData data) { final PsiElement psiElement = extractPsiFromValue(); if (psiElement instanceof NavigationItem) { @@ -110,14 +106,17 @@ public abstract class AbstractMvcPsiNodeDescriptor extends AbstractPsiBasedNode< return myWeight; } + @Override protected boolean hasProblemFileBeneath() { return WolfTheProblemSolver.getInstance(getProject()).hasProblemFilesBeneath(new Condition<VirtualFile>() { + @Override public boolean value(final VirtualFile virtualFile) { return contains(virtualFile); } }); } + @Override public boolean isValid() { final PsiElement psiElement = extractPsiFromValue(); return psiElement != null && psiElement.isValid(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java index 6af5356a51aa..e50be1749d92 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java @@ -34,11 +34,11 @@ import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ui.configuration.actions.ModuleDeleteProvider; -import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; @@ -169,19 +169,23 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id toolWindow.setTitleActions(new AnAction[]{new ScrollFromSourceAction(), collapseAction}); } + @Override public String getTitle() { throw new UnsupportedOperationException(); } + @Override public Icon getIcon() { return myDescriptor.getFramework().getIcon(); } + @Override @NotNull public String getId() { return myId; } + @Override public int getWeight() { throw new UnsupportedOperationException(); } @@ -191,6 +195,7 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id throw new UnsupportedOperationException(); } + @Override public SelectInTarget createSelectInTarget() { throw new UnsupportedOperationException(); } @@ -199,12 +204,14 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id @Override protected BaseProjectTreeBuilder createBuilder(final DefaultTreeModel treeModel) { return new ProjectTreeBuilder(myProject, myTree, treeModel, null, (ProjectAbstractTreeStructureBase)myTreeStructure) { + @Override protected AbstractTreeUpdater createUpdater() { return createTreeUpdater(this); } }; } + @Override protected ProjectAbstractTreeStructureBase createStructure() { final Project project = myProject; final String id = getId(); @@ -215,28 +222,33 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id return myViewState.hideEmptyMiddlePackages; } + @Override protected AbstractTreeNode createRoot(final Project project, ViewSettings settings) { return new MvcProjectNode(project, this, myDescriptor); } }; } + @Override protected ProjectViewTree createTree(final DefaultTreeModel treeModel) { return new ProjectViewTree(myProject, treeModel) { public String toString() { return myDescriptor.getFramework().getDisplayName() + " " + super.toString(); } + @Override public DefaultMutableTreeNode getSelectedNode() { return MvcProjectViewPane.this.getSelectedNode(); } }; } + @Override protected AbstractTreeUpdater createTreeUpdater(final AbstractTreeBuilder treeBuilder) { return new AbstractTreeUpdater(treeBuilder); } + @Override @Nullable protected PsiElement getPSIElement(@Nullable final Object element) { // E.g is used by Project View's DataProvider @@ -305,20 +317,23 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id return content == null ? null : (MvcProjectViewPane)content.getDisposer(); } + @Override public void selectElement(PsiElement element) { PsiFileSystemItem psiFile; - - if (!(element instanceof PsiFileSystemItem)) { - psiFile = element.getContainingFile(); + if (element instanceof PsiFileSystemItem) { + psiFile = (PsiFileSystemItem)element; } else { - psiFile = (PsiFileSystemItem)element; + psiFile = element.getContainingFile(); + if (psiFile == null) { + return; + } } - if (psiFile == null) return; - VirtualFile virtualFile = psiFile.getVirtualFile(); - if (virtualFile == null) return; + if (virtualFile == null) { + return; + } selectFile(virtualFile, false); @@ -337,10 +352,12 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id } } + @Override public PsiDirectory[] getDirectories() { return getSelectedDirectories(); } + @Override public PsiDirectory getOrChooseDirectory() { return DirectoryChooserUtil.getOrChooseDirectory(this); } @@ -360,7 +377,7 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id return null; } - final Module module = ModuleUtil.findModuleForFile(file, project); + final Module module = ModuleUtilCore.findModuleForFile(file, project); if (module == null || !framework.hasSupport(module)) { return null; } @@ -386,7 +403,7 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id if (descriptor instanceof AbstractFolderNode) { final AbstractFolderNode folderNode = (AbstractFolderNode)descriptor; final VirtualFile dir = folderNode.getVirtualFile(); - if (dir != null && VfsUtil.isAncestor(dir, file, false)) { + if (dir != null && VfsUtilCore.isAncestor(dir, file, false)) { cur = folderNode; result.add(folderNode); if (dir.equals(file)) { @@ -506,6 +523,7 @@ public class MvcProjectViewPane extends AbstractProjectViewPSIPane implements Id return myViewState.hideEmptyMiddlePackages; } + @Override public void setSelected(AnActionEvent event, boolean flag) { myViewState.hideEmptyMiddlePackages = flag; TreeUtil.collapseAll(myTree, 1); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestGenerator.java index d0b59c48b873..22c7a1871954 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestGenerator.java @@ -47,6 +47,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; /** * @author Maxim.Medvedev @@ -138,14 +140,15 @@ public class GroovyTestGenerator implements TestGenerator { Collection<MemberInfo> methods, boolean generateBefore, boolean generateAfter) throws IncorrectOperationException { + final HashSet<String> existingNames = new HashSet<String>(); if (generateBefore) { - generateMethod(TestIntegrationUtils.MethodKind.SET_UP, descriptor, targetClass, editor, null); + generateMethod(TestIntegrationUtils.MethodKind.SET_UP, descriptor, targetClass, editor, null, existingNames); } if (generateAfter) { - generateMethod(TestIntegrationUtils.MethodKind.TEAR_DOWN, descriptor, targetClass, editor, null); + generateMethod(TestIntegrationUtils.MethodKind.TEAR_DOWN, descriptor, targetClass, editor, null, existingNames); } for (MemberInfo m : methods) { - generateMethod(TestIntegrationUtils.MethodKind.TEST, descriptor, targetClass, editor, m.getMember().getName()); + generateMethod(TestIntegrationUtils.MethodKind.TEST, descriptor, targetClass, editor, m.getMember().getName(), existingNames); } } @@ -163,10 +166,10 @@ public class GroovyTestGenerator implements TestGenerator { TestFramework descriptor, PsiClass targetClass, Editor editor, - @Nullable String name) { + @Nullable String name, Set<String> existingNames) { GroovyPsiElementFactory f = GroovyPsiElementFactory.getInstance(targetClass.getProject()); PsiMethod method = (PsiMethod)targetClass.add(f.createMethod("dummy", PsiType.VOID)); PsiDocumentManager.getInstance(targetClass.getProject()).doPostponedOperationsAndUnblockDocument(editor.getDocument()); - TestIntegrationUtils.runTestMethodTemplate(methodKind, descriptor, editor, targetClass, method, name, true); + TestIntegrationUtils.runTestMethodTemplate(methodKind, descriptor, editor, targetClass, method, name, true, existingNames); } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java index be51fc91c38a..4b40ce77fa65 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgVcs.java @@ -92,7 +92,7 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> { private final HgCheckinEnvironment checkinEnvironment; private final HgAnnotationProvider annotationProvider; private final HgUpdateEnvironment updateEnvironment; - private final HgCachingCommitedChangesProvider commitedChangesProvider; + private final HgCachingCommittedChangesProvider committedChangesProvider; private MessageBusConnection messageBusConnection; @NotNull private final HgGlobalSettings globalSettings; @NotNull private final HgProjectSettings projectSettings; @@ -127,7 +127,7 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> { checkinEnvironment = new HgCheckinEnvironment(project); annotationProvider = new HgAnnotationProvider(project); updateEnvironment = new HgUpdateEnvironment(project); - commitedChangesProvider = new HgCachingCommitedChangesProvider(project, this); + committedChangesProvider = new HgCachingCommittedChangesProvider(project, this); myMergeProvider = new HgMergeProvider(myProject); myCommitAndPushExecutor = new HgCommitAndPushExecutor(checkinEnvironment); } @@ -205,7 +205,7 @@ public class HgVcs extends AbstractVcs<CommittedChangeList> { @Override public CommittedChangesProvider getCommittedChangesProvider() { - return commitedChangesProvider; + return committedChangesProvider; } @Override diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgLogCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgLogCommand.java index 740603de504a..2faf8760f206 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgLogCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgLogCommand.java @@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.HgFile; import org.zmlx.hg4idea.HgFileRevision; import org.zmlx.hg4idea.HgRevisionNumber; +import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.execution.HgCommandException; import org.zmlx.hg4idea.execution.HgCommandExecutor; import org.zmlx.hg4idea.execution.HgCommandResult; @@ -36,12 +37,18 @@ import java.util.*; public class HgLogCommand { private static final Logger LOG = Logger.getInstance(HgLogCommand.class.getName()); - private static final String[] SHORT_TEMPLATE_ITEMS = {"{rev}", "{node|short}", "{parents}", "{date|isodatesec}", "{author}", "{branches}", "{desc}"}; private static final String[] LONG_TEMPLATE_ITEMS = {"{rev}", "{node|short}", "{parents}", "{date|isodatesec}", "{author}", "{branches}", "{desc}", "{file_adds}", "{file_mods}", - "{file_dels}", "{file_copies}"}; + "{file_dels}", "{join(file_copies,'" + HgChangesetUtil.FILE_SEPARATOR + "')}"}; + /** + * The reason of existing 2 different templates for bash and others explained in + * {@link org.zmlx.hg4idea.provider.HgCachingCommittedChangesProvider.HgLogArgsBuilder#getLogArgs()} + */ + private static final String[] LONG_TEMPLATE_FOR_BASH = + {"{rev}", "{node|short}", "{parents}", "{date|isodatesec}", "{author}", "{branches}", "{desc}", "{file_adds}", "{file_mods}", + "{file_dels}", "{\"join(file_copies,'" + HgChangesetUtil.FILE_SEPARATOR + "')\"}"}; private static final int REVISION_INDEX = 0; private static final int CHANGESET_INDEX = 1; @@ -96,7 +103,15 @@ public class HgLogCommand { return Collections.emptyList(); } - String template = HgChangesetUtil.makeTemplate(includeFiles ? LONG_TEMPLATE_ITEMS : SHORT_TEMPLATE_ITEMS); + String template; + HgVcs vcs = HgVcs.getInstance(myProject); + if (vcs != null && vcs.getGlobalSettings().isRunViaBash() && includeFiles) { + template = HgChangesetUtil.makeTemplate(LONG_TEMPLATE_FOR_BASH); + } + else { + template = HgChangesetUtil.makeTemplate(includeFiles ? LONG_TEMPLATE_ITEMS : SHORT_TEMPLATE_ITEMS); + } + int expectedItemCount = includeFiles ? LONG_TEMPLATE_ITEMS.length : SHORT_TEMPLATE_ITEMS.length; FilePath originalFileName = HgUtil.getOriginalFileName(hgFile.toFilePath(), ChangeListManager.getInstance(myProject)); @@ -118,7 +133,7 @@ public class HgLogCommand { try { String[] attributes = line.split(HgChangesetUtil.ITEM_SEPARATOR); // At least in the case of the long template, it's OK that we don't have everything...for example, if there were no - // deleted or copied files, then we won't get any attribtes for them... + // deleted or copied files, then we won't get any attributes for them... int numAttributes = attributes.length; if (!includeFiles && (numAttributes != expectedItemCount)) { LOG.debug("Wrong format. Skipping line " + line); @@ -244,58 +259,20 @@ public class HgLogCommand { } @NotNull - private static Map<String, String> parseCopiesFileList(@Nullable String fileListString) { + public static Map<String, String> parseCopiesFileList(@Nullable String fileListString) { if (StringUtil.isEmpty(fileListString)) { return Collections.emptyMap(); } - else { - Map<String, String> copies = new HashMap<String, String>(); - assert fileListString != null; // checked via StringUtil - //hg copied files output looks like: "target1 (source1)target2 (source2)target3 .... (target_n)" - //so we should split i-1 source from i target. - // If some sources or targets contatins '(' we suppose that it has Regular Bracket sequence and perform appropriate string parsing. - //if it fails just return. (to avoid ArrayIndexOutOfBoundsException) - String[] filesList = fileListString.split("\\s"); - String target = filesList[0]; - - for (int i = 1; i < filesList.length; ++i) { - String source = filesList[i]; - int afterRightBraceIndex = findRightBracePosition(source); - if (afterRightBraceIndex == -1) { - break; - } - copies.put(source.substring(0, afterRightBraceIndex), target); - if (afterRightBraceIndex >= source.length()) { //the last 'word' in str - break; - } - target = source.substring(afterRightBraceIndex); - } - return copies; - } - } + Map<String, String> copies = new HashMap<String, String>(); + String[] filesList = fileListString.split(HgChangesetUtil.FILE_SEPARATOR); - private static int findRightBracePosition(@NotNull String str) { - if (!str.startsWith("(")) { - LOG.info("Unexpected output during parse copied files in log command " + str); - return -1; - } - int len = str.length(); - int depth = 0; - for (int i = 0; i < len; ++i) { - char c = str.charAt(i); - switch (c) { - case '(': - depth++; - break; - case ')': - depth--; - break; - } - if (depth == 0) { - return i + 1; + for (String pairOfFiles : filesList) { + String[] files = pairOfFiles.split("\\s+\\("); + if (files.length != 2) { + LOG.error("Couldn't parse copied files: " + fileListString); } + copies.put(files[1].substring(0, files[1].length() - 1), files[0]); } - LOG.info("Unexpected output during parse copied files in log command " + str); - return -1; + return copies; } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/ShellCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/ShellCommand.java index e9ca21463fd1..d41cd4d92508 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/ShellCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/ShellCommand.java @@ -43,11 +43,11 @@ public final class ShellCommand { } if (myRunViaBash) { - // run via bash -cl <hg command> => need to escape bash special symbols + // run via bash -cl <hg command> => need to escape bash special symbols but not quoted // '-l' makes bash execute as a login shell thus reading .bash_profile StringBuilder hgCommandBuilder = new StringBuilder(); for (String command : commandLine) { - hgCommandBuilder.append(escapeSpacesIfNeeded(command)); + hgCommandBuilder.append(command); //do not escape whitespaces because arguments may be quoted hgCommandBuilder.append(" "); } String hgCommand = escapeBashControlCharacters(hgCommandBuilder.toString()); @@ -72,42 +72,33 @@ public final class ShellCommand { int exitValue = processOutput.getExitCode(); out.write(processOutput.getStdout()); err.write(processOutput.getStderr()); - return new HgCommandResult(out, err, exitValue ); - } catch (IOException e) { + return new HgCommandResult(out, err, exitValue); + } + catch (IOException e) { throw new ShellCommandException(e); } } /** - * Escapes charactes in the command which will be executed via 'bash -c' - these are standard chars like \n, and some bash specials. + * Escapes characters in the command which will be executed via 'bash -c' - these are standard chars like \n, and some bash specials. + * * @param source Original string. * @return Escaped string. */ - private static String escapeBashControlCharacters(String source) { - final String controlChars = "|>$\"'&"; - final String standardChars = "\b\t\n\f\r"; - final String standardCharsLetters = "btnfr"; + private static String escapeBashControlCharacters(@NotNull String source) { + //need to control other bash control chars manually to avoid conflicts with mercurial symbols (>,',", whitespaces) + final String controlChars = "|&$"; final StringBuilder sb = new StringBuilder(); for (int i = 0; i < source.length(); i++) { char ch = source.charAt(i); if (controlChars.indexOf(ch) > -1) { sb.append("\\").append(ch); - } else { - final int index = standardChars.indexOf(ch); - if (index > -1) { - sb.append("\\").append(standardCharsLetters.charAt(index)); - } else { - sb.append(ch); - } + } + else { + sb.append(ch); } } return sb.toString(); } - - @NotNull - private String escapeSpacesIfNeeded(@NotNull String s) { - return myRunViaBash ? s.replace(" ", "\\ ") : s; - } - } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCachingCommitedChangesProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCachingCommittedChangesProvider.java index 6d6b771e2fd5..f5d4b8654d94 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCachingCommitedChangesProvider.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCachingCommittedChangesProvider.java @@ -50,13 +50,13 @@ import java.io.IOException; import java.text.SimpleDateFormat; import java.util.*; -public class HgCachingCommitedChangesProvider implements CachingCommittedChangesProvider<CommittedChangeList, ChangeBrowserSettings> { +public class HgCachingCommittedChangesProvider implements CachingCommittedChangesProvider<CommittedChangeList, ChangeBrowserSettings> { private final Project project; private final HgVcs myVcs; public final static int VERSION_WITH_REPOSITORY_BRANCHES = 2; - public HgCachingCommitedChangesProvider(Project project, HgVcs vcs) { + public HgCachingCommittedChangesProvider(Project project, HgVcs vcs) { this.project = project; myVcs = vcs; } @@ -214,7 +214,7 @@ public class HgCachingCommitedChangesProvider implements CachingCommittedChanges hgLogCommand.setLogFile(false); List<String> args = null; if (changeBrowserSettings != null) { - HgLogArgsBuilder argsBuilder = new HgLogArgsBuilder(changeBrowserSettings); + HgLogArgsBuilder argsBuilder = new HgLogArgsBuilder(changeBrowserSettings, myVcs.getGlobalSettings().isRunViaBash()); args = argsBuilder.getLogArgs(); if (args.isEmpty()) { maxCount = maxCount == 0 ? VcsConfiguration.getInstance(project).MAXIMUM_HISTORY_ROWS : maxCount; @@ -304,11 +304,11 @@ public class HgCachingCommitedChangesProvider implements CachingCommittedChanges settings.CHANGE_AFTER = number.asString(); settings.CHANGE_BEFORE = number.asString(); // todo implement in proper way - VirtualFile localVitrualFile = HgUtil.convertToLocalVirtualFile(file); - if (localVitrualFile == null) { + VirtualFile localVirtualFile = HgUtil.convertToLocalVirtualFile(file); + if (localVirtualFile == null) { return null; } - final FilePathImpl filePath = new FilePathImpl(localVitrualFile); + final FilePathImpl filePath = new FilePathImpl(localVirtualFile); final CommittedChangeList list = getCommittedChangesForRevision(getLocationFor(filePath), number.asString()); if (list != null) { return new Pair<CommittedChangeList, FilePath>(list, filePath); @@ -385,41 +385,49 @@ public class HgCachingCommitedChangesProvider implements CachingCommittedChanges private static class HgLogArgsBuilder { @NotNull private final ChangeBrowserSettings myBrowserSettings; + private final boolean isRunViaBash; - HgLogArgsBuilder(@NotNull ChangeBrowserSettings browserSettings) { + HgLogArgsBuilder(@NotNull ChangeBrowserSettings browserSettings, boolean runViaBash) { myBrowserSettings = browserSettings; + isRunViaBash = runViaBash; } @NotNull List<String> getLogArgs() { StringBuilder args = new StringBuilder(); - Date afterDate = myBrowserSettings.getDateAfter(); Date beforeDate = myBrowserSettings.getDateBefore(); Long afterFilter = myBrowserSettings.getChangeAfterFilter(); Long beforeFilter = myBrowserSettings.getChangeBeforeFilter(); final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm"); - - if ((null != afterFilter) && (null != beforeFilter)) { + //if command executed via bash all mercurial internal (like date, ancestor etc. ) commands should be quoted, + // but several commands should be quoted once not each. + //f.e. bash -cl 'hg log --rev "date('> 2013')"' OR bash -cl 'hg log --rev "date('> 2013') and date('< 2014')" ' + //this complex workaround is needed because java process wrap arguments in single or double quotes, + // so this may produce conflicts with hg commands. + //If command wrapped by quotes should not escape bash control symbols inside! + String separator = isRunViaBash ? "\"" : ""; + + if ((afterFilter != null) && (beforeFilter != null)) { args.append(afterFilter).append(":").append(beforeFilter); } - else if (null != afterFilter) { + else if (afterFilter != null) { args.append("tip:").append(afterFilter); } - else if (null != beforeFilter) { - args.append("'reverse(:").append(beforeFilter).append(")'"); + else if (beforeFilter != null) { + args.append("reverse(:").append(beforeFilter).append(")"); } - if (null != afterDate) { + if (afterDate != null) { if (args.length() > 0) { args.append(" and "); } args.append("date('>").append(dateFormatter.format(afterDate)).append("')"); } - if (null != beforeDate) { + if (beforeDate != null) { if (args.length() > 0) { args.append(" and "); } @@ -430,7 +438,7 @@ public class HgCachingCommitedChangesProvider implements CachingCommittedChanges if (args.length() > 0) { List<String> logArgs = new ArrayList<String>(); logArgs.add("-r"); - logArgs.add(args.toString()); + logArgs.add(separator + args.toString() + separator); return logArgs; } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java index 9118dc217fb9..db5a7135d560 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgChangesetUtil.java @@ -19,15 +19,20 @@ import com.intellij.openapi.util.SystemInfo; /** * Utilities for operations involving working with a number of changesets: log, incoming, outgoing, parents, etc. + * Storage for different mercurial response separators. + * * @author Kirill Likhodedov */ public class HgChangesetUtil { public static final String CHANGESET_SEPARATOR = "\u0003"; public static final String ITEM_SEPARATOR = "\u0017"; + public static final String FILE_SEPARATOR = "\u0001"; +//FILE_SEPARATOR used for file_copies pair (by default no separator between prev source and next target) /** * Common method for hg commands which receive templates via --template option. + * * @param templateItems template items like <pre>{rev}</pre>, <pre>{node}</pre>. * @return items joined by ITEM_SEPARATOR, ended by CHANGESET_SEPARATOR, and, if needed (for Windows), surrounded with double-quotes. */ @@ -44,5 +49,4 @@ public class HgChangesetUtil { } return template.toString(); } - } diff --git a/plugins/hg4idea/testSrc/hg4idea/test/history/HgLogTest.java b/plugins/hg4idea/testSrc/hg4idea/test/history/HgLogTest.java index d6f9d7b2e7bc..4e1638e00ff1 100644 --- a/plugins/hg4idea/testSrc/hg4idea/test/history/HgLogTest.java +++ b/plugins/hg4idea/testSrc/hg4idea/test/history/HgLogTest.java @@ -1,15 +1,18 @@ package hg4idea.test.history; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import hg4idea.test.HgPlatformTest; import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.HgFile; import org.zmlx.hg4idea.HgFileRevision; +import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.command.HgLogCommand; import org.zmlx.hg4idea.execution.HgCommandException; import java.util.List; +import java.util.Map; import static com.intellij.dvcs.test.Executor.cd; import static com.intellij.dvcs.test.Executor.touch; @@ -19,6 +22,14 @@ import static hg4idea.test.HgExecutor.hg; * @author Nadya Zabrodina */ public class HgLogTest extends HgPlatformTest { + private HgVcs myVcs; + + @Override + public void setUp() throws Exception { + super.setUp(); + myVcs = HgVcs.getInstance(myProject); + assert myVcs != null; + } public void testParseCopiedWithoutBraces() throws HgCommandException { parseCopied("f.txt"); @@ -28,6 +39,22 @@ public class HgLogTest extends HgPlatformTest { parseCopied("(f.txt)"); } + public void testLogCommandViaBash() throws HgCommandException { + if (SystemInfo.isWindows) { + return; + } + myVcs.getGlobalSettings().setRunViaBash(true); + parseCopied("f.txt"); + } + + public void testParseFileCopiesWithWhitespaces() { + Map<String, String> filesMap = HgLogCommand.parseCopiesFileList("/a/b c/d.txt (a/b a/d.txt)\u0001/a/b c/(d).txt (/a/b c/(f).txt)"); + assertTrue(filesMap.containsKey("a/b a/d.txt")); + assertTrue(filesMap.containsKey("/a/b c/(f).txt")); + assertTrue(filesMap.containsValue("/a/b c/d.txt")); + assertTrue(filesMap.containsValue("/a/b c/(d).txt")); + } + private void parseCopied(@NotNull String sourceFileName) throws HgCommandException { cd(myRepository); String copiedFileName = "copy".concat(sourceFileName); diff --git a/plugins/junit/src/com/intellij/execution/junit/TestObject.java b/plugins/junit/src/com/intellij/execution/junit/TestObject.java index 071429050545..cdd5ad02b84f 100644 --- a/plugins/junit/src/com/intellij/execution/junit/TestObject.java +++ b/plugins/junit/src/com/intellij/execution/junit/TestObject.java @@ -61,6 +61,7 @@ import com.intellij.openapi.util.Getter; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; @@ -71,6 +72,7 @@ import com.intellij.rt.execution.junit.JUnitStarter; import com.intellij.util.Function; import com.intellij.util.PathUtil; import jetbrains.buildServer.messages.serviceMessages.ServiceMessageTypes; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.serialization.PathMacroUtil; @@ -83,7 +85,7 @@ public abstract class TestObject implements JavaCommandLine { protected static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit.TestObject"); private static final String MESSAGE = ExecutionBundle.message("configuration.not.speficied.message"); - private static final String JUNIT_TEST_FRAMEWORK_NAME = "JUnit"; + @NonNls private static final String JUNIT_TEST_FRAMEWORK_NAME = "JUnit"; protected JavaParameters myJavaParameters; private final Project myProject; @@ -230,7 +232,7 @@ public abstract class TestObject implements JavaCommandLine { myListenersFile = FileUtil.createTempFile("junit_listeners_", ""); myListenersFile.deleteOnExit(); myJavaParameters.getProgramParametersList().add("@@" + myListenersFile.getPath()); - FileUtil.writeToFile(myListenersFile, buf.toString().getBytes()); + FileUtil.writeToFile(myListenersFile, buf.toString().getBytes(CharsetToolkit.UTF8_CHARSET)); } catch (IOException e) { LOG.error(e); @@ -416,17 +418,17 @@ public abstract class TestObject implements JavaCommandLine { private boolean forkPerModule() { final String workingDirectory = myConfiguration.getWorkingDirectory(); - return JUnitConfiguration.TEST_PACKAGE.equals(myConfiguration.getPersistentData().TEST_OBJECT) && - myConfiguration.getPersistentData().getScope() != TestSearchScope.SINGLE_MODULE && + return JUnitConfiguration.TEST_PACKAGE.equals(myConfiguration.getPersistentData().TEST_OBJECT) && + myConfiguration.getPersistentData().getScope() != TestSearchScope.SINGLE_MODULE && ("$" + PathMacroUtil.MODULE_DIR_MACRO_NAME + "$").equals(workingDirectory); } - + private void appendForkInfo(Executor executor) throws ExecutionException { final String forkMode = myConfiguration.getForkMode(); if (Comparing.strEqual(forkMode, "none")) { final String workingDirectory = myConfiguration.getWorkingDirectory(); - if (!JUnitConfiguration.TEST_PACKAGE.equals(myConfiguration.getPersistentData().TEST_OBJECT) || - myConfiguration.getPersistentData().getScope() == TestSearchScope.SINGLE_MODULE || + if (!JUnitConfiguration.TEST_PACKAGE.equals(myConfiguration.getPersistentData().TEST_OBJECT) || + myConfiguration.getPersistentData().getScope() == TestSearchScope.SINGLE_MODULE || !("$" + PathMacroUtil.MODULE_DIR_MACRO_NAME + "$").equals(workingDirectory)) { return; } @@ -445,7 +447,7 @@ public abstract class TestObject implements JavaCommandLine { try { final File tempFile = FileUtil.createTempFile("command.line", "", true); - final PrintWriter writer = new PrintWriter(tempFile, "UTF-8"); + final PrintWriter writer = new PrintWriter(tempFile, CharsetToolkit.UTF8); try { writer.println(((JavaSdkType)jdk.getSdkType()).getVMExecutablePath(jdk)); for (String vmParameter : javaParameters.getVMParametersList().getList()) { @@ -457,7 +459,7 @@ public abstract class TestObject implements JavaCommandLine { finally { writer.close(); } - + myJavaParameters.getProgramParametersList().add("@@@" + forkMode + ',' + tempFile.getAbsolutePath()); } catch (Exception e) { @@ -476,7 +478,7 @@ public abstract class TestObject implements JavaCommandLine { } final Map<String, List<String>> perModule = forkPerModule() ? new TreeMap<String, List<String>>() : null; - final PrintWriter writer = new PrintWriter(myTempFile, "UTF-8"); + final PrintWriter writer = new PrintWriter(myTempFile, CharsetToolkit.UTF8); try { writer.println(packageName); final List<String> testNames = new ArrayList<String>(); @@ -519,7 +521,7 @@ public abstract class TestObject implements JavaCommandLine { } if (perModule != null && perModule.size() > 1) { - final PrintWriter wWriter = new PrintWriter(myWorkingDirsFile, "UTF-8"); + final PrintWriter wWriter = new PrintWriter(myWorkingDirsFile, CharsetToolkit.UTF8); try { wWriter.println(packageName); for (String workingDir : perModule.keySet()) { diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java b/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java index f91cedd49688..b6c1257a4b6c 100644 --- a/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java +++ b/plugins/junit/src/com/intellij/execution/junit2/ui/TestsPacketsReceiver.java @@ -42,6 +42,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.rt.execution.junit.segments.PoolOfDelimiters; import com.intellij.rt.execution.junit.states.PoolOfTestStates; import com.intellij.util.containers.HashMap; +import gnu.trove.TIntObjectHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -51,10 +52,9 @@ import java.util.Map; import java.util.Set; public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable { - - public static final Map<Integer, StateChanger> STATE_CLASSES = new HashMap<Integer, StateChanger>(); + private static final TIntObjectHashMap<StateChanger> STATE_CLASSES = new TIntObjectHashMap<StateChanger>(); private Map<String, TestProxy> myKnownDynamicParents; - private TestProxy myUnboundOutput; + private final TestProxy myUnboundOutput; static { mapClass(PoolOfTestStates.RUNNING_INDEX, new RunningStateSetter()); @@ -66,9 +66,9 @@ public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable { mapClass(PoolOfTestStates.COMPARISON_FAILURE, new StateReader(ComparisonFailureState.class)); } - public static void mapClass(final int magnitude, final StateChanger factory) { + public static void mapClass(final int magnitude, @NotNull StateChanger factory) { factory.setMagnitude(magnitude); - STATE_CLASSES.put(new Integer(magnitude), factory); + STATE_CLASSES.put(magnitude, factory); } private final InputObjectRegistry myObjectRegistry; @@ -86,6 +86,7 @@ public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable { Disposer.register(consoleView, this); } + @Override public void processPacket(final String packet) { ApplicationManager.getApplication().assertIsDispatchThread(); @@ -162,6 +163,7 @@ public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable { setClassName(parentClass); } + @Override public void readFrom(ObjectReader reader) { } }); @@ -180,7 +182,7 @@ public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable { } final int state = reader.readInt(); - final StateChanger stateChanger = STATE_CLASSES.get(new Integer(state)); + final StateChanger stateChanger = STATE_CLASSES.get(state); stateChanger.changeStateOf(testProxy, reader); synchronized (myCurrentTests) { if (stateChanger instanceof RunningStateSetter) { @@ -217,6 +219,7 @@ public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable { return myModel; } + @Override public void dispose() { myModel = null; } @@ -252,7 +255,7 @@ public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable { } } - private static abstract class StateChanger { + private abstract static class StateChanger { static final Logger LOG = Logger.getInstance("#" + StateChanger.class.getName()); abstract void changeStateOf(TestProxy testProxy, ObjectReader reader); @@ -283,6 +286,7 @@ public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable { } private static class RunningStateSetter extends StateChanger { + @Override public void changeStateOf(final TestProxy testProxy, final ObjectReader reader) { testProxy.setState(TestState.RUNNING_STATE); TestProxy parent = testProxy.getParent(); @@ -304,6 +308,7 @@ public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable { myStateClass = stateClass; } + @Override public void changeStateOf(final TestProxy testProxy, final ObjectReader reader) { final ReadableState state; try { @@ -319,12 +324,14 @@ public class TestsPacketsReceiver implements OutputPacketProcessor, Disposable { complete(testProxy); } + @Override public void setMagnitude(final int magnitude) { myInstanceMagnitude = magnitude; } } private static class TestCompleter extends StateChanger { + @Override public void changeStateOf(final TestProxy testProxy, final ObjectReader reader) { TestState state = testProxy.getState(); if (!testProxy.getState().isFinal()) { diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/CloseTaskDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/CloseTaskDialog.java index 1dc84b944f5b..5e087258b3f4 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/CloseTaskDialog.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/CloseTaskDialog.java @@ -24,6 +24,7 @@ import com.intellij.tasks.TaskManager; import com.intellij.tasks.TaskRepository; import com.intellij.tasks.TaskState; import com.intellij.tasks.impl.TaskManagerImpl; +import com.intellij.tasks.impl.TaskUtil; import com.intellij.ui.components.JBCheckBox; import javax.swing.*; @@ -45,7 +46,7 @@ public class CloseTaskDialog extends DialogWrapper { super(project, false); setTitle("Close Task"); - myTaskLabel.setText(task.getSummary()); + myTaskLabel.setText(TaskUtil.getTrimmedSummary(task)); myTaskLabel.setIcon(task.getIcon()); TaskRepository repository = task.getRepository(); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.form b/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.form index bb2cf0d68e45..a81ab2aaa098 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.form +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.form @@ -3,7 +3,7 @@ <grid id="27dc6" binding="myPanel" 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="579" height="400"/> + <xy x="20" y="20" width="538" height="293"/> </constraints> <properties/> <border type="none"/> @@ -19,7 +19,7 @@ <grid id="7efb3" binding="myServersPanel" 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="1" fill="1" indent="0" use-parent-layout="false"> - <preferred-size width="0" height="100"/> + <preferred-size width="0" height="50"/> </grid> </constraints> <properties/> @@ -32,7 +32,26 @@ </constraints> <properties/> <border type="none"/> - <children/> + <children> + <grid id="602e0" binding="myEmptyPanel" layout-manager="BorderLayout" hgap="0" vgap="0"> + <constraints> + <card name="Card1"/> + </constraints> + <properties/> + <border type="empty"> + <size top="100" left="220" bottom="100" right="220"/> + </border> + <children> + <component id="76503" class="com.intellij.ui.components.JBLabel"> + <constraints border-constraint="Center"/> + <properties> + <horizontalAlignment value="0"/> + <text value="No server selected"/> + </properties> + </component> + </children> + </grid> + </children> </grid> <component id="4840c" class="com.intellij.openapi.ui.Splitter" binding="mySplitter"> <constraints> diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java index 7f94c639f730..1b5ad857daa9 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/config/TaskRepositoriesConfigurable.java @@ -44,6 +44,7 @@ import java.util.Set; @SuppressWarnings("unchecked") public class TaskRepositoriesConfigurable extends BaseConfigurable implements Configurable.NoScroll { + private static final String EMPTY_PANEL = "empty.panel"; private JPanel myPanel; private JPanel myServersPanel; private final JBList myRepositoriesList; @@ -52,6 +53,7 @@ public class TaskRepositoriesConfigurable extends BaseConfigurable implements Co private JPanel myRepositoryEditor; private JBLabel myServersLabel; private Splitter mySplitter; + private JPanel myEmptyPanel; private final List<TaskRepository> myRepositories = new ArrayList<TaskRepository>(); private final List<TaskRepositoryEditor> myEditors = new ArrayList<TaskRepositoryEditor>(); @@ -237,6 +239,8 @@ public class TaskRepositoriesConfigurable extends BaseConfigurable implements Co public void reset() { myRepoNames.clear(); myRepositoryEditor.removeAll(); + myRepositoryEditor.add(myEmptyPanel, EMPTY_PANEL); +// ((CardLayout)myRepositoryEditor.getLayout()).show(myRepositoryEditor, ); myRepositories.clear(); CollectionListModel listModel = new CollectionListModel(new ArrayList()); diff --git a/plugins/tasks/tasks-time-tracking/src/META-INF/plugin.xml b/plugins/tasks/tasks-time-tracking/src/META-INF/plugin.xml deleted file mode 100644 index d0b4664d1072..000000000000 --- a/plugins/tasks/tasks-time-tracking/src/META-INF/plugin.xml +++ /dev/null @@ -1,26 +0,0 @@ -<idea-plugin version="2"> - <id>com.intellij.tasks.timeTracking</id> - <name>Time Tracking</name> - <description>Enables time tracking for "Task Management" plugin</description> - <vendor>JetBrains</vendor> - <version>1.0</version> - - <depends>com.intellij.tasks</depends> - - <project-components> - <component> - <implementation-class>com.intellij.tasks.timeTracking.TimeTrackingManager</implementation-class> - </component> - </project-components> - - <extensions defaultExtensionNs="com.intellij"> - <projectConfigurable instance="com.intellij.tasks.timeTracking.TimeTrackingConfigurable" displayName="Time Tracking" - id="tasks.timeTracking" - nonDefaultProject="true" - parentId="tasks"/> - - <toolWindow id="Time Tracking" anchor="right" secondary="false" icon="TasksIcons.Clock" - factoryClass="com.intellij.tasks.timeTracking.TasksToolWindowFactory" - conditionClass="com.intellij.tasks.timeTracking.TasksToolWindowFactory"/> - </extensions> -</idea-plugin> diff --git a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/SendTimeTrackingInformationDialog.form b/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/SendTimeTrackingInformationDialog.form deleted file mode 100644 index 2470a2f7ef4f..000000000000 --- a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/SendTimeTrackingInformationDialog.form +++ /dev/null @@ -1,130 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.tasks.timeTracking.SendTimeTrackingInformationDialog"> - <grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> - <margin top="0" left="0" bottom="0" right="0"/> - <constraints> - <xy x="20" y="20" width="721" height="328"/> - </constraints> - <properties/> - <border type="none"/> - <children> - <component id="c5275" class="com.intellij.ui.components.JBLabel"> - <constraints> - <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="Issue:"/> - </properties> - </component> - <component id="59138" class="com.intellij.ui.components.JBLabel"> - <constraints> - <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="&Comment:"/> - <toolTipText value=""/> - </properties> - </component> - <component id="225af" class="javax.swing.JLabel" binding="myTaskNameLabel"> - <constraints> - <grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="Label"/> - </properties> - </component> - <scrollpane id="f2f7d" class="com.intellij.ui.components.JBScrollPane"> - <constraints> - <grid row="2" column="1" row-span="1" col-span="2" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/> - </constraints> - <properties/> - <border type="none"/> - <children> - <component id="e531f" class="javax.swing.JTextArea" binding="myCommentTextArea"> - <constraints/> - <properties/> - </component> - </children> - </scrollpane> - <grid id="50cf9" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> - <margin top="5" left="0" bottom="5" right="0"/> - <constraints> - <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/> - </constraints> - <properties/> - <border type="none"/> - <children> - <component id="45822" class="javax.swing.JRadioButton" binding="myFromPreviousPostRadioButton" default-binding="true"> - <constraints> - <grid row="1" column="1" 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 value="From &previous post:"/> - </properties> - </component> - <component id="a4c4" class="javax.swing.JRadioButton" binding="myCustomRadioButton" default-binding="true"> - <constraints> - <grid row="2" column="1" 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 value="Custo&m:"/> - </properties> - </component> - <component id="89994" class="javax.swing.JTextField" binding="myFromPreviousPostTextField"> - <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> - </constraints> - <properties> - <editable value="false"/> - </properties> - </component> - <component id="c9593" class="javax.swing.JTextField" binding="myCustomTextField"> - <constraints> - <grid row="2" 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> - <text value="0d 0h 0m"/> - </properties> - </component> - <component id="65cc2" class="javax.swing.JRadioButton" binding="myTotallyRadioButton" default-binding="true"> - <constraints> - <grid row="0" column="1" 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 value="Totall&y:"/> - </properties> - </component> - <component id="8f5d7" class="javax.swing.JTextField" binding="myTotallyTextField"> - <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> - <editable value="false"/> - </properties> - </component> - <component id="bbd54" class="com.intellij.ui.components.JBLabel"> - <constraints> - <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="Time Spent:"/> - </properties> - </component> - </children> - </grid> - </children> - </grid> - <buttonGroups> - <group name="myGroup1"> - <member id="45822"/> - <member id="65cc2"/> - <member id="a4c4"/> - </group> - </buttonGroups> -</form> diff --git a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/SendTimeTrackingInformationDialog.java b/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/SendTimeTrackingInformationDialog.java deleted file mode 100644 index c0f2cc0a8965..000000000000 --- a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/SendTimeTrackingInformationDialog.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2000-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.tasks.timeTracking; - -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.ui.ValidationInfo; -import com.intellij.tasks.LocalTask; -import com.intellij.tasks.TaskRepository; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.util.Date; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * User: evgeny.zakrevsky - * Date: 12/26/12 - */ -public class SendTimeTrackingInformationDialog extends DialogWrapper { - private final static Logger LOG = Logger.getInstance("#com.intellij.tasks.timeTracking.TasksToolWindowPanel"); - public static final Pattern PATTERN = Pattern.compile("([0-9]+)d ([0-9]+)h ([0-9]+)m"); - - @Nullable private final Project myProject; - private final LocalTask myTask; - private JRadioButton myFromPreviousPostRadioButton; - private JRadioButton myTotallyRadioButton; - private JRadioButton myCustomRadioButton; - private JTextField myFromPreviousPostTextField; - private JTextField myTotallyTextField; - private JTextField myCustomTextField; - private JTextArea myCommentTextArea; - private JPanel myPanel; - private JLabel myTaskNameLabel; - - protected SendTimeTrackingInformationDialog(@Nullable final Project project, final LocalTask localTask) { - super(project); - myProject = project; - myTask = localTask; - setTitle("Time Tracking"); - - myTaskNameLabel.setText(myTask.getPresentableName()); - myFromPreviousPostRadioButton.setSelected(true); - if (myTask.getLastPost() == null) { - myFromPreviousPostRadioButton.setVisible(false); - myFromPreviousPostTextField.setVisible(false); - myTotallyRadioButton.setSelected(true); - } - myFromPreviousPostTextField.setText(formatDuration(myTask.getTimeSpentFromLastPost())); - myTotallyTextField.setText(formatDuration(myTask.getTotalTimeSpent())); - - init(); - } - - @Nullable - @Override - protected JComponent createCenterPanel() { - return myPanel; - } - - private static String formatDuration(final long milliseconds) { - final int second = 1000; - final int minute = 60 * second; - final int hour = 60 * minute; - final int day = 24 * hour; - - final int days = (int)(milliseconds / day); - final int hours = (int)(milliseconds % day / hour); - final int minutes = (int)(milliseconds % hour / minute); - - String daysString = days + "d "; - String hoursString = hours + "h "; - String minutesString = minutes + "m"; - - return daysString + hoursString + minutesString; - } - - @Override - protected void doOKAction() { - String timeSpentText = myFromPreviousPostRadioButton.isSelected() ? myFromPreviousPostTextField.getText() - : myTotallyRadioButton.isSelected() ? myTotallyTextField.getText() : myCustomTextField.getText(); - final Matcher matcher = PATTERN.matcher(timeSpentText); - if (matcher.matches()) { - final int timeSpent = Integer.valueOf(matcher.group(1)) * 24 * 60 + Integer.valueOf(matcher.group(2)) * 60 + Integer.valueOf( - matcher.group(3)); - - final TaskRepository repository = myTask.getRepository(); - if (repository != null && - repository.isSupported(TaskRepository.TIME_MANAGEMENT)) { - try { - repository.updateTimeSpent(myTask, timeSpentText, myCommentTextArea.getText()); - myTask.setLastPost(new Date()); - } - catch (Exception e1) { - Messages - .showErrorDialog(myProject, "<html>Could not send information for " + myTask.getPresentableName() + "<br/>" + e1.getMessage(), - "Error"); - LOG.warn(e1); - } - } - } - - - super.doOKAction(); - } - - @Nullable - @Override - protected ValidationInfo doValidate() { - String timeSpentText = myFromPreviousPostRadioButton.isSelected() ? myFromPreviousPostTextField.getText() - : myTotallyRadioButton.isSelected() ? myTotallyTextField.getText() : myCustomTextField.getText(); - if (!PATTERN.matcher(timeSpentText).matches()) return new ValidationInfo("Time Spent has broken format"); - return null; - } - - @Nullable - @Override - protected String getDimensionServiceKey() { - return "com.intellij.tasks.timeTracking.TasksToolWindowPanel"; - } -} diff --git a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TasksToolWindowFactory.java b/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TasksToolWindowFactory.java deleted file mode 100644 index fd1593fc94b2..000000000000 --- a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TasksToolWindowFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.intellij.tasks.timeTracking; - -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.wm.ToolWindow; -import com.intellij.openapi.wm.ToolWindowAnchor; -import com.intellij.openapi.wm.ToolWindowFactory; -import com.intellij.ui.content.Content; -import com.intellij.ui.content.ContentFactory; -import com.intellij.ui.content.ContentManager; - -/** - * User: evgeny.zakrevsky - * Date: 11/8/12 - */ -public class TasksToolWindowFactory implements ToolWindowFactory, Condition<Project>, DumbAware { - - @Override - public boolean value(final Project project) { - return TimeTrackingManager.getInstance(project).isTimeTrackingToolWindowAvailable(); - } - - @Override - public void createToolWindowContent(final Project project, final ToolWindow toolWindow) { - final ContentManager contentManager = toolWindow.getContentManager(); - final Content content = ContentFactory.SERVICE.getInstance(). - createContent(new TasksToolWindowPanel(project, toolWindow.getAnchor() == ToolWindowAnchor.LEFT || - toolWindow.getAnchor() == ToolWindowAnchor.RIGHT), null, false); - contentManager.addContent(content); - } -} diff --git a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TasksToolWindowPanel.java b/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TasksToolWindowPanel.java deleted file mode 100644 index 9e28eec7fe34..000000000000 --- a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TasksToolWindowPanel.java +++ /dev/null @@ -1,363 +0,0 @@ -package com.intellij.tasks.timeTracking; - -import com.intellij.icons.AllIcons; -import com.intellij.openapi.Disposable; -import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.SimpleToolWindowPanel; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.IconLoader; -import com.intellij.tasks.*; -import com.intellij.tasks.actions.GotoTaskAction; -import com.intellij.tasks.actions.SwitchTaskAction; -import com.intellij.ui.LayeredIcon; -import com.intellij.ui.ScrollPaneFactory; -import com.intellij.ui.SimpleColoredComponent; -import com.intellij.ui.SimpleTextAttributes; -import com.intellij.ui.table.TableView; -import com.intellij.util.IconUtil; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.text.DateFormatUtil; -import com.intellij.util.ui.ColumnInfo; -import com.intellij.util.ui.ListTableModel; -import com.intellij.util.ui.UIUtil; -import icons.TasksIcons; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import javax.swing.table.TableCellRenderer; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Comparator; - -/** - * User: evgeny.zakrevsky - * Date: 11/8/12 - */ -public class TasksToolWindowPanel extends SimpleToolWindowPanel implements Disposable { - - private final ListTableModel<LocalTask> myTableModel; - private final TimeTrackingManager myTimeTrackingManager; - private final Project myProject; - private Timer myTimer; - private final TableView<LocalTask> myTable; - private final TaskManager myTaskManager; - - public TasksToolWindowPanel(final Project project, final boolean vertical) { - super(vertical); - myProject = project; - myTimeTrackingManager = TimeTrackingManager.getInstance(project); - myTaskManager = TaskManager.getManager(project); - - myTable = new TableView<LocalTask>(createListModel()); - myTableModel = myTable.getListTableModel(); - updateTable(); - - setContent(ScrollPaneFactory.createScrollPane(myTable, true)); - setToolbar(createToolbar()); - - myTaskManager.addTaskListener(new TaskListenerAdapter() { - @Override - public void taskDeactivated(final LocalTask task) { - myTable.repaint(); - } - - @Override - public void taskActivated(final LocalTask task) { - myTable.repaint(); - } - - @Override - public void taskAdded(final LocalTask task) { - updateTable(); - } - - @Override - public void taskRemoved(final LocalTask task) { - updateTable(); - } - }); - - myTimer = new Timer(TimeTrackingManager.TIME_TRACKING_TIME_UNIT, new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - myTable.repaint(); - } - }); - myTimer.start(); - } - - private static SimpleTextAttributes getAttributes(final boolean isClosed, final boolean isActive, final boolean isSelected) { - return new SimpleTextAttributes(isActive ? SimpleTextAttributes.STYLE_BOLD : SimpleTextAttributes.STYLE_PLAIN, - isSelected - ? UIUtil.getTableSelectionForeground() - : isClosed && !isActive ? UIUtil.getLabelDisabledForeground() : UIUtil.getTableForeground()); - } - - private static String formatDuration(final long milliseconds) { - final int second = 1000; - final int minute = 60 * second; - final int hour = 60 * minute; - final int day = 24 * hour; - final int days = (int)milliseconds / day; - String daysString = days != 0 ? days + "d " : ""; - - return daysString + String.format("%d:%02d:%02d", milliseconds % day / hour, milliseconds % hour / minute, - milliseconds % minute / second); - } - - private JComponent createToolbar() { - DefaultActionGroup group = new DefaultActionGroup(); - final AnAction action = ActionManager.getInstance().getAction(GotoTaskAction.ID); - assert action instanceof GotoTaskAction; - final GotoTaskAction gotoTaskAction = (GotoTaskAction)action; - group.add(gotoTaskAction); - group.add(new AnAction("Remove Task", "Remove Task", IconUtil.getRemoveIcon()) { - @Override - public void actionPerformed(final AnActionEvent e) { - for (LocalTask localTask : myTable.getSelectedObjects()) { - SwitchTaskAction.removeTask(myProject, localTask, myTaskManager); - } - } - }); - group.add(new ToggleAction("Show closed tasks", "Show closed tasks", AllIcons.Actions.Checked) { - @Override - public boolean isSelected(final AnActionEvent e) { - return myTimeTrackingManager.getState().showClosedTasks; - } - - @Override - public void setSelected(final AnActionEvent e, final boolean state) { - myTimeTrackingManager.getState().showClosedTasks = state; - updateTable(); - } - }); - group.add(new ModeToggleAction()); - group.add(new StartStopAction()); - - if (timeManagementExist()) { - group.add(new AnAction("Post work item to bugtracker", "Post work item to bugtracker", AllIcons.Actions.Export) { - @Override - public void actionPerformed(final AnActionEvent e) { - final LocalTask localTask = myTable.getSelectedObject(); - if (localTask == null) return; - new SendTimeTrackingInformationDialog(myProject, localTask).show(); - } - - @Override - public void update(final AnActionEvent e) { - final LocalTask localTask = myTable.getSelectedObject(); - if (localTask == null) { - e.getPresentation().setEnabled(false); - } - else { - final TaskRepository repository = localTask.getRepository(); - e.getPresentation().setEnabled(repository != null && repository.isSupported(TaskRepository.TIME_MANAGEMENT)); - } - } - }); - - group.add(new ToggleAction("Show time spent from last post of work item", "Show time spent from last post of work item", - TasksIcons.Clock) { - @Override - public boolean isSelected(final AnActionEvent e) { - return myTimeTrackingManager.getState().showSpentTimeFromLastPost; - } - - @Override - public void setSelected(final AnActionEvent e, final boolean state) { - myTimeTrackingManager.getState().showSpentTimeFromLastPost = state; - myTable.repaint(); - } - }); - } - final ActionToolbar actionToolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, myVertical); - return actionToolBar.getComponent(); - } - - private void updateTable() { - myTableModel.setItems(ContainerUtil.filter(myTaskManager.getLocalTasks(), - new Condition<LocalTask>() { - @Override - public boolean value(final LocalTask task) { - return task.isActive() || - (task.getTotalTimeSpent() != 0 && - (myTimeTrackingManager.getState().showClosedTasks || - !myTaskManager.isLocallyClosed(task))); - } - })); - } - - private ListTableModel<LocalTask> createListModel() { - final ColumnInfo<LocalTask, String> task = new ColumnInfo<LocalTask, String>("Task") { - - @Nullable - @Override - public String valueOf(final LocalTask task) { - return task.getPresentableName(); - } - - @Nullable - @Override - public TableCellRenderer getRenderer(final LocalTask task) { - return new TableCellRenderer() { - @Override - public Component getTableCellRendererComponent(final JTable table, - final Object value, - final boolean isSelected, - final boolean hasFocus, - final int row, - final int column) { - JPanel panel = new JPanel(new BorderLayout()); - panel.setBackground(UIUtil.getTableBackground(isSelected)); - final SimpleColoredComponent component = new SimpleColoredComponent(); - final boolean isClosed = task.isClosed() || myTaskManager.isLocallyClosed(task); - final boolean isActive = task.isActive(); - final boolean isRunning = myTimeTrackingManager.getState().autoMode ? isActive : isActive && task.isRunning(); - component.append((String)value, getAttributes(isClosed, isActive, isSelected)); - component.setIcon(isRunning - ? LayeredIcon.create(task.getIcon(), AllIcons.Nodes.RunnableMark) - : isClosed && !isActive ? IconLoader.getTransparentIcon(task.getIcon()) : task.getIcon()); - component.setOpaque(false); - panel.add(component, BorderLayout.CENTER); - panel.setOpaque(true); - return panel; - } - }; - } - - @Nullable - @Override - public Comparator<LocalTask> getComparator() { - return new Comparator<LocalTask>() { - public int compare(LocalTask o1, LocalTask o2) { - int i = Comparing.compare(o2.getUpdated(), o1.getUpdated()); - return i == 0 ? Comparing.compare(o2.getCreated(), o1.getCreated()) : i; - } - }; - } - }; - - final ColumnInfo<LocalTask, String> spentTime = new ColumnInfo<LocalTask, String>("Time Spent") { - @Nullable - @Override - public String valueOf(final LocalTask task) { - long timeSpent = - myTimeTrackingManager.getState().showSpentTimeFromLastPost ? task.getTimeSpentFromLastPost() : task.getTotalTimeSpent(); - if (task.isActive()) { - return formatDuration(timeSpent); - } - return DateFormatUtil.formatDuration(timeSpent); - } - - @Nullable - @Override - public TableCellRenderer getRenderer(final LocalTask task) { - return new TableCellRenderer() { - @Override - public Component getTableCellRendererComponent(final JTable table, - final Object value, - final boolean isSelected, - final boolean hasFocus, - final int row, - final int column) { - JPanel panel = new JPanel(new BorderLayout()); - panel.setBackground(UIUtil.getTableBackground(isSelected)); - final SimpleColoredComponent component = new SimpleColoredComponent(); - final boolean isClosed = task.isClosed() || myTaskManager.isLocallyClosed(task); - final boolean isActive = task.isActive(); - component.append((String)value, getAttributes(isClosed, isActive, isSelected)); - component.setOpaque(false); - panel.add(component, BorderLayout.CENTER); - panel.setOpaque(true); - return panel; - } - }; - } - - @Nullable - @Override - public Comparator<LocalTask> getComparator() { - return new Comparator<LocalTask>() { - @Override - public int compare(final LocalTask o1, final LocalTask o2) { - final long timeSpent1 = - myTimeTrackingManager.getState().showSpentTimeFromLastPost ? o1.getTimeSpentFromLastPost() : o1.getTotalTimeSpent(); - final long timeSpent2 = - myTimeTrackingManager.getState().showSpentTimeFromLastPost ? o2.getTimeSpentFromLastPost() : o2.getTotalTimeSpent(); - return Comparing.compare(timeSpent1, timeSpent2); - } - }; - } - }; - - return new ListTableModel<LocalTask>((new ColumnInfo[]{task, spentTime})); - } - - private boolean timeManagementExist() { - for (TaskRepository repository : myTaskManager.getAllRepositories()) { - if (repository.isSupported(TaskRepository.TIME_MANAGEMENT)) { - return true; - } - } - return false; - } - - @Override - public void dispose() { - myTimer.stop(); - myTimer = null; - } - - private class StartStopAction extends AnAction { - @Override - public void update(final AnActionEvent e) { - if (myTimeTrackingManager.getState().autoMode) { - e.getPresentation().setEnabled(false); - e.getPresentation().setIcon(TasksIcons.StartTimer); - e.getPresentation().setText("Start timer for active task"); - } - else { - e.getPresentation().setEnabled(true); - if (myTaskManager.getActiveTask().isRunning()) { - e.getPresentation().setIcon(TasksIcons.StopTimer); - e.getPresentation().setText("Stop timer for active task"); - } - else { - e.getPresentation().setIcon(TasksIcons.StartTimer); - e.getPresentation().setText("Start timer for active task"); - } - } - } - - @Override - public void actionPerformed(final AnActionEvent e) { - final LocalTask activeTask = myTaskManager.getActiveTask(); - if (activeTask.isRunning()) { - activeTask.setRunning(false); - } - else { - activeTask.setRunning(true); - } - } - } - - private class ModeToggleAction extends ToggleAction { - public ModeToggleAction() { - super("Auto mode", "Automatic starting and stopping of timer", TasksIcons.AutoMode); - } - - @Override - public boolean isSelected(final AnActionEvent e) { - return myTimeTrackingManager.getState().autoMode; - } - - @Override - public void setSelected(final AnActionEvent e, final boolean state) { - myTimeTrackingManager.setAutoMode(state); - updateTable(); - } - } -} diff --git a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TimeTrackingConfigurable.form b/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TimeTrackingConfigurable.form deleted file mode 100644 index 26dfc39e8f7c..000000000000 --- a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TimeTrackingConfigurable.form +++ /dev/null @@ -1,68 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.tasks.timeTracking.TimeTrackingConfigurable"> - <grid id="27dc6" binding="myPanel" 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> - <vspacer id="9d80d"> - <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="f42" binding="myTimeTrackingSettings" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> - <margin top="0" left="0" bottom="0" right="0"/> - <constraints> - <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> - </constraints> - <properties/> - <clientProperties> - <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/> - </clientProperties> - <border type="none" title="Time Tracking settings"/> - <children> - <component id="e1b59" class="com.intellij.ui.components.JBLabel"> - <constraints> - <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="Suspend delay:"/> - </properties> - </component> - <component id="463e7" class="javax.swing.JTextField" binding="myTimeTrackingSuspendDelay"> - <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"> - <preferred-size width="50" height="-1"/> - </grid> - </constraints> - <properties/> - </component> - <component id="5584b" class="com.intellij.ui.components.JBLabel"> - <constraints> - <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="seconds"/> - </properties> - </component> - </children> - </grid> - <component id="c5b5" class="javax.swing.JCheckBox" binding="myEnableTimeTrackingCheckBox" default-binding="true"> - <constraints> - <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> - </constraints> - <properties> - <text value="&Enable Time Tracking"/> - </properties> - </component> - <hspacer id="e6e8e"> - <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/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TimeTrackingConfigurable.java b/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TimeTrackingConfigurable.java deleted file mode 100644 index ba0f21bcd3d6..000000000000 --- a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TimeTrackingConfigurable.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.intellij.tasks.timeTracking; - -import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.options.SearchableConfigurable; -import com.intellij.openapi.project.Project; -import com.intellij.ui.GuiUtils; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -/** - * User: Evgeny.Zakrevsky - * Date: 11/19/12 - */ -public class TimeTrackingConfigurable implements SearchableConfigurable, Configurable.NoScroll { - private JCheckBox myEnableTimeTrackingCheckBox; - private JTextField myTimeTrackingSuspendDelay; - private JPanel myTimeTrackingSettings; - private JPanel myPanel; - private Project myProject; - - - public TimeTrackingConfigurable(Project project) { - myProject = project; - myEnableTimeTrackingCheckBox.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - enableTimeTrackingPanel(); - } - }); - } - - private void enableTimeTrackingPanel() { - GuiUtils.enableChildren(myTimeTrackingSettings, myEnableTimeTrackingCheckBox.isSelected()); - } - - private TimeTrackingManager.Config getConfig() { - return TimeTrackingManager.getInstance(myProject).getState(); - } - - @Override - public void reset() { - myEnableTimeTrackingCheckBox.setSelected(getConfig().enabled); - myTimeTrackingSuspendDelay.setText(String.valueOf(getConfig().suspendDelayInSeconds)); - enableTimeTrackingPanel(); - } - - @Override - public void disposeUIResources() { - } - - - @Override - public boolean isModified() { - return myEnableTimeTrackingCheckBox.isSelected() != getConfig().enabled || - !myTimeTrackingSuspendDelay.getText().equals(String.valueOf(getConfig().suspendDelayInSeconds)); - } - - @Override - public void apply() { - boolean oldTimeTrackingEnabled = getConfig().enabled; - getConfig().enabled = myEnableTimeTrackingCheckBox.isSelected(); - if (getConfig().enabled != oldTimeTrackingEnabled) { - TimeTrackingManager.getInstance(myProject).updateTimeTrackingToolWindow(); - } - try{ - getConfig().suspendDelayInSeconds = Integer.parseInt(myTimeTrackingSuspendDelay.getText()); - } - catch (NumberFormatException ignored) { - } - } - - @NotNull - @Override - public String getId() { - return "tasks.timeTracking"; - } - - @Nullable - @Override - public Runnable enableSearch(final String option) { - return null; - } - - @Nls - @Override - public String getDisplayName() { - return "Time Tracking"; - } - - @Nullable - @Override - public String getHelpTopic() { - return null; - //return "reference.settings.project.tasks.timeTracking"; - } - - @Nullable - @Override - public JComponent createComponent() { - return myPanel; - } -} diff --git a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TimeTrackingManager.java b/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TimeTrackingManager.java deleted file mode 100644 index b78a24db5304..000000000000 --- a/plugins/tasks/tasks-time-tracking/src/com/intellij/tasks/timeTracking/TimeTrackingManager.java +++ /dev/null @@ -1,218 +0,0 @@ -package com.intellij.tasks.timeTracking; - -import com.intellij.ide.IdeEventQueue; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.*; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.wm.*; -import com.intellij.tasks.LocalTask; -import com.intellij.tasks.TaskManager; -import com.intellij.tasks.timeTracking.model.WorkItem; -import com.intellij.util.Alarm; -import com.intellij.util.ui.UIUtil; -import com.intellij.util.xmlb.XmlSerializerUtil; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Date; - -/** - * User: Evgeny.Zakrevsky - * Date: 11/19/12 - */ - -@State( - name = "TimeTrackingManager", - storages = { - @Storage(file = StoragePathMacros.WORKSPACE_FILE) - } -) -public class TimeTrackingManager implements ProjectComponent, PersistentStateComponent<TimeTrackingManager.Config> { - - public static final int TIME_TRACKING_TIME_UNIT = 1000; - - private final Project myProject; - private final TaskManager myTaskManager; - private final Config myConfig = new Config(); - private Timer myTimeTrackingTimer; - private final Alarm myIdleAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); - private Runnable myActivityListener; - private LocalTask myLastActiveTask; - - public TimeTrackingManager(Project project, - TaskManager taskManager) { - myProject = project; - myTaskManager = taskManager; - } - - public static TimeTrackingManager getInstance(Project project) { - return project.getComponent(TimeTrackingManager.class); - } - - private void startTimeTrackingTimer() { - if (!myTimeTrackingTimer.isRunning()) { - myTimeTrackingTimer.start(); - } - - myIdleAlarm.cancelAllRequests(); - myIdleAlarm.addRequest(new Runnable() { - @Override - public void run() { - if (myTimeTrackingTimer.isRunning()) { - myTimeTrackingTimer.stop(); - } - } - }, getState().suspendDelayInSeconds * 1000); - } - - public void updateTimeTrackingToolWindow() { - ToolWindow toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.TASKS); - if (isTimeTrackingToolWindowAvailable()) { - if (toolWindow == null) { - toolWindow = - ToolWindowManager.getInstance(myProject).registerToolWindow(ToolWindowId.TASKS, true, ToolWindowAnchor.RIGHT, myProject, true); - new TasksToolWindowFactory().createToolWindowContent(myProject, toolWindow); - } - final ToolWindow finalToolWindow = toolWindow; - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - finalToolWindow.setAvailable(true, null); - finalToolWindow.show(null); - finalToolWindow.activate(null); - } - }); - } - else { - if (toolWindow != null) { - final ToolWindow finalToolWindow = toolWindow; - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - finalToolWindow.setAvailable(false, null); - } - }); - } - } - } - - public boolean isTimeTrackingToolWindowAvailable() { - return getState().enabled; - } - - @Override - public void initComponent() { - if (!ApplicationManager.getApplication().isUnitTestMode()) { - myTimeTrackingTimer = UIUtil.createNamedTimer("TaskManager time tracking", TIME_TRACKING_TIME_UNIT, new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - final LocalTask activeTask = myTaskManager.getActiveTask(); - if (myLastActiveTask != activeTask) { - activeTask.addWorkItem(new WorkItem(new Date())); - } - if (getState().autoMode) { - final WorkItem lastWorkItem = activeTask.getWorkItems().get(activeTask.getWorkItems().size() - 1); - lastWorkItem.duration += TIME_TRACKING_TIME_UNIT; - getState().totallyTimeSpent += TIME_TRACKING_TIME_UNIT; - } - else { - if (activeTask.isRunning()) { - final WorkItem lastWorkItem = activeTask.getWorkItems().get(activeTask.getWorkItems().size() - 1); - lastWorkItem.duration += TIME_TRACKING_TIME_UNIT; - getState().totallyTimeSpent += TIME_TRACKING_TIME_UNIT; - } - } - myLastActiveTask = activeTask; - } - }); - StartupManager.getInstance(myProject).registerStartupActivity(new Runnable() { - public void run() { - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - startTimeTrackingTimer(); - } - }); - } - }); - - myActivityListener = new Runnable() { - @Override - public void run() { - final IdeFrame frame = IdeFocusManager.getGlobalInstance().getLastFocusedFrame(); - if (frame == null) return; - final Project project = frame.getProject(); - if (project == null || !myProject.equals(project)) return; - startTimeTrackingTimer(); - } - }; - if (getState().autoMode) { - IdeEventQueue.getInstance().addActivityListener(myActivityListener, myProject); - } - } - } - - public void setAutoMode(final boolean on) { - final boolean oldState = getState().autoMode; - if (on != oldState) { - getState().autoMode = on; - if (on) { - IdeEventQueue.getInstance().addActivityListener(myActivityListener, myProject); - } - else { - IdeEventQueue.getInstance().removeActivityListener(myActivityListener); - myIdleAlarm.cancelAllRequests(); - if (!myTimeTrackingTimer.isRunning()) { - myTimeTrackingTimer.start(); - } - } - } - } - - @Override - public void disposeComponent() { - if (myTimeTrackingTimer != null) { - myTimeTrackingTimer.stop(); - } - myIdleAlarm.cancelAllRequests(); - Disposer.dispose(myIdleAlarm); - } - - @NotNull - @Override - public String getComponentName() { - return "Time Tracking Manager"; - } - - @NotNull - @Override - public TimeTrackingManager.Config getState() { - return myConfig; - } - - @Override - public void loadState(final TimeTrackingManager.Config state) { - XmlSerializerUtil.copyBean(state, myConfig); - } - - @Override - public void projectOpened() { - } - - @Override - public void projectClosed() { - } - - public static class Config { - public boolean enabled = false; - public long totallyTimeSpent = 0; - public int suspendDelayInSeconds = 600; - public boolean autoMode = true; - public boolean showClosedTasks = true; - public boolean showSpentTimeFromLastPost = false; - } -} diff --git a/plugins/tasks/tasks-time-tracking/tasks-time-tracking.iml b/plugins/tasks/tasks-time-tracking/tasks-time-tracking.iml deleted file mode 100644 index ecee65315829..000000000000 --- a/plugins/tasks/tasks-time-tracking/tasks-time-tracking.iml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="JAVA_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$"> - <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> - </content> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - <orderEntry type="module" module-name="tasks-api" /> - <orderEntry type="module" module-name="tasks-core" /> - <orderEntry type="module" module-name="util" /> - <orderEntry type="module" module-name="core-api" /> - <orderEntry type="module" module-name="platform-api" /> - <orderEntry type="module" module-name="platform-impl" /> - <orderEntry type="module" module-name="lang-impl" /> - </component> -</module> - diff --git a/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltBasicTest.java b/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltBasicTest.java index e053411c15c4..7070314550e1 100644 --- a/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltBasicTest.java +++ b/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltBasicTest.java @@ -15,9 +15,11 @@ */ package org.intellij.lang.xpath.xslt; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.impl.PsiFileEx; import com.intellij.psi.xml.XmlFile; +import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl; import org.intellij.lang.xpath.TestBase; import org.intellij.lang.xpath.xslt.impl.XsltChecker; @@ -91,7 +93,9 @@ public class XsltBasicTest extends TestBase { private void configure() throws Throwable { final String fileName = getTestFileName(); - myFixture.configureByFile(fileName.replaceAll("_.*$", "") + ".xsl"); + String path = fileName.replaceAll("_.*$", "") + ".xsl"; + final VirtualFile file = myFixture.copyFileToProject(path); + ((CodeInsightTestFixtureImpl)myFixture).openFileInEditor(file); if (fileName.endsWith("_Loaded")) { ((XmlFile)myFixture.getFile()).getDocument(); assertTrue(((PsiFileEx)myFixture.getFile()).isContentsLoaded()); diff --git a/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltResolveTest.java b/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltResolveTest.java index 08f6041879b4..0c9eb2560f4b 100644 --- a/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltResolveTest.java +++ b/plugins/xpath/xpath-lang/test/org/intellij/lang/xpath/xslt/XsltResolveTest.java @@ -15,7 +15,6 @@ */ package org.intellij.lang.xpath.xslt; -import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiPolyVariantReference; import com.intellij.psi.PsiReference; @@ -126,8 +125,7 @@ public class XsltResolveTest extends TestBase { private PsiReference findInjectedReferenceAtCaret(String... moreFiles) throws Throwable { configure(moreFiles); - final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(myFixture.getProject()); - final PsiElement e = manager.findInjectedElementAt(myFixture.getFile(), myFixture.getEditor().getCaretModel().getOffset()); + final PsiElement e = myFixture.getFile().findElementAt(myFixture.getEditor().getCaretModel().getOffset()); assertNotNull(e); final PsiReference reference = e.getContainingFile().findReferenceAt(e.getTextOffset()); |