Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/GerritOperationFactory.java9
-rw-r--r--org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/Messages.java5
-rw-r--r--org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/GerritClient.java20
-rw-r--r--org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/messages.properties2
-rw-r--r--org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/operations/DiscardDraftRequest.java65
-rw-r--r--org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/operations/SaveDraftRequest.java18
-rw-r--r--org.eclipse.mylyn.gerrit.dashboard.ui/src/org/eclipse/mylyn/gerrit/dashboard/ui/views/GerritTableView.java3
-rw-r--r--org.eclipse.mylyn.gerrit.tests/src/org/eclipse/mylyn/internal/gerrit/core/remote/PatchSetRemoteFactoryTest.java2
-rw-r--r--org.eclipse.mylyn.gerrit.ui/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.mylyn.gerrit.ui/src/org/eclipse/mylyn/internal/gerrit/ui/GerritReviewBehavior.java59
-rw-r--r--org.eclipse.mylyn.reviews.tests/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/AllReviewsTests.java2
-rw-r--r--org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewAnnotationModelTest.java14
-rw-r--r--org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewCompareAnnotationSupportTest.java233
-rw-r--r--org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewUiTest.java9
-rw-r--r--org.eclipse.mylyn.reviews.ui/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/ReviewsUiConstants.java6
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/actions/AddLineCommentToFileAction.java4
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/CommentPopupDialog.java121
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/Messages.java3
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/ReviewAnnotationModel.java99
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/messages.properties2
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/Direction.java2
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/ReviewCompareAnnotationSupport.java343
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/ReviewCompareInputListener.java8
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/AddCommentDialog.java1
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/CommentInputDialog.java576
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/Messages.java55
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/messages.properties23
-rw-r--r--org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/reviews/ui/ReviewBehavior.java6
30 files changed, 1654 insertions, 42 deletions
diff --git a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/GerritOperationFactory.java b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/GerritOperationFactory.java
index 1a1ba27d5..f2243b891 100644
--- a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/GerritOperationFactory.java
+++ b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/GerritOperationFactory.java
@@ -8,6 +8,7 @@
* Contributors:
* Tasktop Technologies - initial API and implementation
* Sascha Scholz (SAP) - improvements
+ * Guy Perron 423242: Add ability to edit comment from compare navigator popup
*******************************************************************************/
package org.eclipse.mylyn.internal.gerrit.core;
@@ -16,6 +17,7 @@ import org.eclipse.mylyn.internal.gerrit.core.client.GerritClient;
import org.eclipse.mylyn.internal.gerrit.core.client.GerritConfiguration;
import org.eclipse.mylyn.internal.gerrit.core.operations.AbandonRequest;
import org.eclipse.mylyn.internal.gerrit.core.operations.AddReviewersRequest;
+import org.eclipse.mylyn.internal.gerrit.core.operations.DiscardDraftRequest;
import org.eclipse.mylyn.internal.gerrit.core.operations.GerritOperation;
import org.eclipse.mylyn.internal.gerrit.core.operations.PublishRequest;
import org.eclipse.mylyn.internal.gerrit.core.operations.RebaseRequest;
@@ -30,10 +32,12 @@ import org.eclipse.mylyn.tasks.core.TaskRepository;
import com.google.gerrit.common.data.ChangeDetail;
import com.google.gerrit.common.data.ReviewerResult;
import com.google.gerrit.reviewdb.PatchLineComment;
+import com.google.gwtjsonrpc.client.VoidResult;
/**
* @author Steffen Pingel
* @author Sascha Scholz
+ * @author Guy Perron
*/
public class GerritOperationFactory {
@@ -47,6 +51,11 @@ public class GerritOperationFactory {
return new GerritOperation<PatchLineComment>(Messages.GerritOperationFactory_Saving_Draft, getClient(review), request);
}
+ public GerritOperation<VoidResult> createDiscardDraftOperation(ITask review, DiscardDraftRequest request) {
+ return new GerritOperation<VoidResult>(Messages.GerritOperationFactory_Discarding_Draft, getClient(review),
+ request);
+ }
+
public GerritOperation<ChangeDetail> createAbandonOperation(ITask review, AbandonRequest request) {
return new GerritOperation<ChangeDetail>(Messages.GerritOperationFactory_Abandoning_Change, getClient(review), request);
}
diff --git a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/Messages.java b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/Messages.java
index 91239adf4..714fa7a77 100644
--- a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/Messages.java
+++ b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/Messages.java
@@ -57,6 +57,11 @@ public class Messages extends NLS {
public static String GerritUtil_X_dot_dot_dot;
public static String GerritUtil_Unknown;
+
+ public static String GerritOperationFactory_Discarding_Draft;
+
+ public static String GerritReviewBehavior_Internal_Exception;
+
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/GerritClient.java b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/GerritClient.java
index 75922b9e9..1fdf2caeb 100644
--- a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/GerritClient.java
+++ b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/client/GerritClient.java
@@ -14,6 +14,7 @@
* Francois Chouinard - Added "LABELS" option on selected queries
* Jacques Bouthillier - Bug 414253 Add support for Gerrit Dashboard
* Jacques Bouthillier (Ericsson) - Bug 426505 Add Starred functionality
+ * Guy Perron (Ericsson) Bug 423242 Add ability to edit comment from compare navigator popup
*********************************************************************/
package org.eclipse.mylyn.internal.gerrit.core.client;
@@ -125,6 +126,7 @@ import com.google.gwtjsonrpc.client.VoidResult;
* @author Miles Parker
* @author Francois Chouinard
* @author Jacques Bouthillier
+ * @author Guy Perron
*/
public class GerritClient extends ReviewsClient {
@@ -261,8 +263,8 @@ public class GerritClient extends ReviewsClient {
}
public PatchLineComment saveDraft(Patch.Key patchKey, String message, int line, short side, String parentUuid,
- IProgressMonitor monitor) throws GerritException {
- PatchLineComment.Key id = new PatchLineComment.Key(patchKey, null);
+ String uuid, IProgressMonitor monitor) throws GerritException {
+ PatchLineComment.Key id = new PatchLineComment.Key(patchKey, uuid);
final PatchLineComment comment = new PatchLineComment(id, line, getAccount(monitor).getId(), parentUuid);
comment.setMessage(message);
comment.setSide(side);
@@ -274,6 +276,20 @@ public class GerritClient extends ReviewsClient {
});
}
+ public VoidResult deleteDraft(Patch.Key patchkey, String message, int line, short side, String uuid,
+ IProgressMonitor monitor) throws GerritException {
+ final PatchLineComment.Key id = new PatchLineComment.Key(patchkey, uuid);
+ final PatchLineComment comment = new PatchLineComment(id, line, getAccount(monitor).getId(), uuid);
+ comment.setMessage(message);
+ comment.setSide(side);
+ return execute(monitor, new Operation<VoidResult>() {
+ @Override
+ public void execute(IProgressMonitor monitor) throws GerritException {
+ getPatchDetailService(monitor).deleteDraft(comment.getKey(), this);
+ }
+ });
+ }
+
public ChangeDetail abandon(String reviewId, int patchSetId, final String message, IProgressMonitor monitor)
throws GerritException {
final PatchSet.Id id = new PatchSet.Id(new Change.Id(id(reviewId)), patchSetId);
diff --git a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/messages.properties b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/messages.properties
index 1a588cd65..c4bc04e21 100644
--- a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/messages.properties
+++ b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/messages.properties
@@ -29,3 +29,5 @@ GerritTaskSchema_Review=Review
GerritUtil_Anonymous=Anonymous
GerritUtil_X_dot_dot_dot={0}...
GerritUtil_Unknown=<Unknown>
+GerritOperationFactory_Discarding_Draft=Discarding Draft
+GerritReviewBehavior_Internal_Exception=Internal Exception. No line location for comment. Comment: {0}
diff --git a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/operations/DiscardDraftRequest.java b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/operations/DiscardDraftRequest.java
new file mode 100644
index 000000000..e1727b5f6
--- /dev/null
+++ b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/operations/DiscardDraftRequest.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ericsson - initial API and implementation
+ * Guy Perron 423242: Add ability to edit comment from compare navigator popup
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.gerrit.core.operations;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.mylyn.internal.gerrit.core.client.GerritClient;
+import org.eclipse.mylyn.internal.gerrit.core.client.GerritException;
+
+import com.google.gerrit.reviewdb.Patch;
+import com.google.gerrit.reviewdb.Patch.Key;
+import com.google.gwtjsonrpc.client.VoidResult;
+
+public class DiscardDraftRequest extends AbstractRequest<VoidResult> {
+
+ private final Key patchKey;
+
+ private final int line;
+
+ private String uuid;
+
+ private final short side;
+
+ public DiscardDraftRequest(Patch.Key patchKey, int line, short side, String uuid) {
+ this.patchKey = patchKey;
+ this.line = line;
+ this.side = side;
+ this.uuid = uuid;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String Uuid) {
+ this.uuid = Uuid;
+ }
+
+ public Key getPatchKey() {
+ return patchKey;
+ }
+
+ public short getSide() {
+ return side;
+ }
+
+ @Override
+ protected VoidResult execute(GerritClient client, IProgressMonitor monitor) throws GerritException {
+ return client.deleteDraft(getPatchKey(), getMessage(), getLine(), getSide(), getUuid(), monitor);
+ }
+
+}
diff --git a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/operations/SaveDraftRequest.java b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/operations/SaveDraftRequest.java
index 1c5d137bc..8635577ec 100644
--- a/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/operations/SaveDraftRequest.java
+++ b/org.eclipse.mylyn.gerrit.core/src/org/eclipse/mylyn/internal/gerrit/core/operations/SaveDraftRequest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Tasktop Technologies - initial API and implementation
+ * Guy Perron 423242: Add ability to edit comment from compare navigator popup
*******************************************************************************/
package org.eclipse.mylyn.internal.gerrit.core.operations;
@@ -21,14 +22,17 @@ import com.google.gerrit.reviewdb.PatchLineComment;
/**
* @author Steffen Pingel
+ * @author Guy Perron
*/
public class SaveDraftRequest extends AbstractRequest<PatchLineComment> {
private final Key patchKey;
- int line;
+ private final int line;
- String parentUuid;
+ private String uUid = null;
+
+ private String parentUuid;
private final short side;
@@ -58,9 +62,17 @@ public class SaveDraftRequest extends AbstractRequest<PatchLineComment> {
this.parentUuid = parentUuid;
}
+ public String getUuid() {
+ return uUid;
+ }
+
+ public void setUuid(String uUid) {
+ this.uUid = uUid;
+ }
+
@Override
protected PatchLineComment execute(GerritClient client, IProgressMonitor monitor) throws GerritException {
- return client.saveDraft(getPatchKey(), getMessage(), getLine(), getSide(), getParentUuid(), monitor);
+ return client.saveDraft(getPatchKey(), getMessage(), getLine(), getSide(), getParentUuid(), getUuid(), monitor);
}
}
diff --git a/org.eclipse.mylyn.gerrit.dashboard.ui/src/org/eclipse/mylyn/gerrit/dashboard/ui/views/GerritTableView.java b/org.eclipse.mylyn.gerrit.dashboard.ui/src/org/eclipse/mylyn/gerrit/dashboard/ui/views/GerritTableView.java
index 8cc2f8a4c..690a436b9 100644
--- a/org.eclipse.mylyn.gerrit.dashboard.ui/src/org/eclipse/mylyn/gerrit/dashboard/ui/views/GerritTableView.java
+++ b/org.eclipse.mylyn.gerrit.dashboard.ui/src/org/eclipse/mylyn/gerrit/dashboard/ui/views/GerritTableView.java
@@ -848,7 +848,8 @@ public class GerritTableView extends ViewPart implements ITaskListChangeListener
* @throws GerritQueryException
*/
private IStatus getReviews(TaskRepository repository, String queryType) throws GerritQueryException {
- if (repository.getUserName() == null || repository.getUserName().isEmpty()) {
+ if (repository.getUserName() == null
+ || repository.getUserName().isEmpty()) {
//Test for Anonymous user
if (queryType.equals(GerritQuery.MY_CHANGES)
|| queryType.equals(GerritQuery.QUERY_MY_DRAFTS_COMMENTS_CHANGES)) {
diff --git a/org.eclipse.mylyn.gerrit.tests/src/org/eclipse/mylyn/internal/gerrit/core/remote/PatchSetRemoteFactoryTest.java b/org.eclipse.mylyn.gerrit.tests/src/org/eclipse/mylyn/internal/gerrit/core/remote/PatchSetRemoteFactoryTest.java
index 46015b099..b6e44f1da 100644
--- a/org.eclipse.mylyn.gerrit.tests/src/org/eclipse/mylyn/internal/gerrit/core/remote/PatchSetRemoteFactoryTest.java
+++ b/org.eclipse.mylyn.gerrit.tests/src/org/eclipse/mylyn/internal/gerrit/core/remote/PatchSetRemoteFactoryTest.java
@@ -267,7 +267,7 @@ public class PatchSetRemoteFactoryTest extends GerritRemoteTest {
assertThat(commentFile.getAllComments().size(), is(0));
String id = commentFile.getReference();
- reviewHarness.client.saveDraft(Patch.Key.parse(id), "Line 2 Comment", 2, (short) 1, null,
+ reviewHarness.client.saveDraft(Patch.Key.parse(id), "Line 2 Comment", 2, (short) 1, null, null,
new NullProgressMonitor());
patchSetObserver.retrieve(false);
patchSetObserver.waitForResponse();
diff --git a/org.eclipse.mylyn.gerrit.ui/META-INF/MANIFEST.MF b/org.eclipse.mylyn.gerrit.ui/META-INF/MANIFEST.MF
index 940945cc0..44176c5a3 100644
--- a/org.eclipse.mylyn.gerrit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.gerrit.ui/META-INF/MANIFEST.MF
@@ -45,5 +45,6 @@ Import-Package: com.google.gerrit.common;version="2.1.5",
com.google.gerrit.common.data;version="2.1.5",
com.google.gerrit.reviewdb;version="2.1.5",
com.google.gson;version="[2.1.0,3.0.0)",
+ com.google.gwtjsonrpc.client;version="1.2.4",
com.google.gwtorm.client;version="1.1.4",
org.apache.commons.io;version="1.4.0"
diff --git a/org.eclipse.mylyn.gerrit.ui/src/org/eclipse/mylyn/internal/gerrit/ui/GerritReviewBehavior.java b/org.eclipse.mylyn.gerrit.ui/src/org/eclipse/mylyn/internal/gerrit/ui/GerritReviewBehavior.java
index 8a36b1533..4b53955b3 100644
--- a/org.eclipse.mylyn.gerrit.ui/src/org/eclipse/mylyn/internal/gerrit/ui/GerritReviewBehavior.java
+++ b/org.eclipse.mylyn.gerrit.ui/src/org/eclipse/mylyn/internal/gerrit/ui/GerritReviewBehavior.java
@@ -8,6 +8,7 @@
* Contributors:
* Tasktop Technologies - initial API and implementation
* Sebastien Dubois (Ericsson) - Improvements for bug 400266
+ * Guy Perron 423242: Add ability to edit comment from compare navigator popup
*******************************************************************************/
package org.eclipse.mylyn.internal.gerrit.ui;
@@ -15,7 +16,10 @@ package org.eclipse.mylyn.internal.gerrit.ui;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.util.StringUtils;
import org.eclipse.mylyn.internal.gerrit.core.GerritOperationFactory;
+import org.eclipse.mylyn.internal.gerrit.core.Messages;
+import org.eclipse.mylyn.internal.gerrit.core.operations.DiscardDraftRequest;
import org.eclipse.mylyn.internal.gerrit.core.operations.GerritOperation;
import org.eclipse.mylyn.internal.gerrit.core.operations.SaveDraftRequest;
import org.eclipse.mylyn.internal.gerrit.ui.egit.GitFileRevisionUtils;
@@ -26,18 +30,27 @@ import org.eclipse.mylyn.reviews.core.model.ILocation;
import org.eclipse.mylyn.reviews.core.model.IReviewItem;
import org.eclipse.mylyn.reviews.ui.ReviewBehavior;
import org.eclipse.mylyn.tasks.core.ITask;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.history.IFileRevision;
import com.google.gerrit.reviewdb.Patch;
import com.google.gerrit.reviewdb.PatchLineComment;
+import com.google.gwtjsonrpc.client.VoidResult;
/**
* @author Steffen Pingel
+ * @author Guy Perron
*/
public class GerritReviewBehavior extends ReviewBehavior {
private Repository repository = null;
+ private final short LEFT_SIDE = 0;
+
+ private final short RIGHT_SIDE = 1;
+
+ private final String BASE = "base-"; //$NON-NLS-1$
+
public GerritReviewBehavior(ITask task) {
super(task);
}
@@ -53,12 +66,12 @@ public class GerritReviewBehavior extends ReviewBehavior {
@Override
public IStatus addComment(IReviewItem item, IComment comment, IProgressMonitor monitor) {
- short side = 1;
+ short side = RIGHT_SIDE;
String id = item.getId();
- if (id.startsWith("base-")) { //$NON-NLS-1$
+ if (id.startsWith(BASE)) {
// base revision
- id = id.substring(5);
- side = 0;
+ id = id.substring(BASE.length());
+ side = LEFT_SIDE;
}
Patch.Key key = Patch.Key.parse(id);
for (ILocation location : comment.getLocations()) {
@@ -66,14 +79,48 @@ public class GerritReviewBehavior extends ReviewBehavior {
ILineLocation lineLocation = (ILineLocation) location;
SaveDraftRequest request = new SaveDraftRequest(key, lineLocation.getRangeMin(), side);
request.setMessage(comment.getDescription());
+ if (!StringUtils.isEmptyOrNull(comment.getId())) {
+ request.setUuid(comment.getId());
+ }
GerritOperation<PatchLineComment> operation = getOperationFactory().createSaveDraftOperation(getTask(),
request);
- return operation.run(monitor);
+ IStatus status = operation.run(monitor);
+ PatchLineComment patchLineComment = operation.getOperationResult();
+ // save the value of uuid, and keep it with the comment
+ if (patchLineComment != null && patchLineComment.getKey() != null) {
+ comment.setId(patchLineComment.getKey().get());
+ }
+ return status;
}
}
//We'll only get here if there is something really broken in calling code or model. Gerrit has one and only one comment per location.
- throw new RuntimeException("Internal Exception. No line location for comment. Comment: " + comment.getId()); //$NON-NLS-1$
+ throw new RuntimeException(NLS.bind(Messages.GerritReviewBehavior_Internal_Exception, comment.getId()));
+ }
+
+ @Override
+ public IStatus discardComment(IReviewItem item, IComment comment, IProgressMonitor monitor) {
+ short side = RIGHT_SIDE;
+ String id = item.getId();
+ if (id.startsWith(BASE)) {
+ // base revision
+ id = id.substring(BASE.length());
+ side = LEFT_SIDE;
+ }
+ Patch.Key key = Patch.Key.parse(id);
+ for (ILocation location : comment.getLocations()) {
+ if (location instanceof ILineLocation) {
+ ILineLocation lineLocation = (ILineLocation) location;
+ DiscardDraftRequest request = new DiscardDraftRequest(key, lineLocation.getRangeMin(), side,
+ comment.getId());
+ request.setMessage(comment.getDescription());
+
+ GerritOperation<VoidResult> operation = getOperationFactory().createDiscardDraftOperation(getTask(),
+ request);
+ return operation.run(monitor);
+ }
+ }
+ throw new RuntimeException(Messages.GerritReviewBehavior_Internal_Exception + comment.getId());
}
@Override
diff --git a/org.eclipse.mylyn.reviews.tests/META-INF/MANIFEST.MF b/org.eclipse.mylyn.reviews.tests/META-INF/MANIFEST.MF
index 1d8d8f93b..641435916 100644
--- a/org.eclipse.mylyn.reviews.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.reviews.tests/META-INF/MANIFEST.MF
@@ -25,7 +25,9 @@ Require-Bundle: org.hamcrest;bundle-version="1.1.0",
org.eclipse.emf.ecore;bundle-version="2.5.0",
org.eclipse.emf.edit;bundle-version="2.5.0",
org.apache.commons.io,
- org.eclipse.jface.text
+ org.eclipse.jface.text,
+ org.mockito;bundle-version="1.8.4"
Export-Package: org.eclipse.mylyn.reviews.spi.edit.remote;x-internal:=true,
org.eclipse.mylyn.reviews.tests;x-internal:=true,
org.eclipse.mylyn.reviews.tests.ui;x-internal:=true
+Import-Package: org.eclipse.compare.internal
diff --git a/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/AllReviewsTests.java b/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/AllReviewsTests.java
index 65560ec10..e015dafdf 100644
--- a/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/AllReviewsTests.java
+++ b/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/AllReviewsTests.java
@@ -16,6 +16,7 @@ import junit.framework.TestSuite;
import org.eclipse.mylyn.reviews.spi.edit.remote.AbstractRemoteEditFactoryProviderTest;
import org.eclipse.mylyn.reviews.tests.ui.ReviewAnnotationModelTest;
+import org.eclipse.mylyn.reviews.tests.ui.ReviewCompareAnnotationSupportTest;
import org.eclipse.mylyn.reviews.tests.ui.ReviewUiTest;
import org.eclipse.mylyn.reviews.tests.ui.UiDataLocatorTest;
@@ -30,6 +31,7 @@ public class AllReviewsTests {
suite.addTestSuite(UiDataLocatorTest.class);
suite.addTestSuite(AbstractRemoteEditFactoryProviderTest.class);
suite.addTestSuite(ReviewAnnotationModelTest.class);
+ suite.addTestSuite(ReviewCompareAnnotationSupportTest.class);
return suite;
}
diff --git a/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewAnnotationModelTest.java b/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewAnnotationModelTest.java
index 7099a36e1..950cf87fa 100644
--- a/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewAnnotationModelTest.java
+++ b/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewAnnotationModelTest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Tasktop Technologies - initial API and implementation
+ * Guy Perron 423242: Add ability to edit comment from compare navigator popup
*******************************************************************************/
package org.eclipse.mylyn.reviews.tests.ui;
@@ -38,6 +39,7 @@ import org.eclipse.team.core.history.IFileRevision;
/**
* @author Leo Dos Santos
+ * @author Guy Perron
*/
public class ReviewAnnotationModelTest extends TestCase {
@@ -67,6 +69,11 @@ public class ReviewAnnotationModelTest extends TestCase {
return null;
}
+ @Override
+ public IStatus discardComment(IReviewItem fileItem, IComment comment, IProgressMonitor monitor) {
+ return null;
+ }
+
}
@Override
@@ -117,6 +124,13 @@ public class ReviewAnnotationModelTest extends TestCase {
iter = model.getAnnotationIterator();
assertEquals(2, getCount(iter));
+
+ notification = new NotificationImpl(Notification.REMOVE, newComment, null);
+ model.getItem().eNotify(notification);
+
+ iter = model.getAnnotationIterator();
+ assertEquals(1, getCount(iter));
+
}
private int getCount(Iterator<CommentAnnotation> iter) {
diff --git a/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewCompareAnnotationSupportTest.java b/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewCompareAnnotationSupportTest.java
new file mode 100644
index 000000000..5bc7cae93
--- /dev/null
+++ b/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewCompareAnnotationSupportTest.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Guy Perron - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.reviews.tests.ui;
+
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import junit.framework.TestCase;
+
+import org.eclipse.compare.internal.MergeSourceViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.mylyn.internal.reviews.ui.compare.Direction;
+import org.eclipse.mylyn.internal.reviews.ui.compare.ReviewCompareAnnotationSupport;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+
+/**
+ * @author Guy Perron
+ */
+public class ReviewCompareAnnotationSupportTest extends TestCase {
+
+ @Mock
+ private ReviewCompareAnnotationSupport rcaSupportspy;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ ListViewer mockListViewer = mock(ListViewer.class);
+ ReviewCompareAnnotationSupport rcaSupport = new ReviewCompareAnnotationSupport(mockListViewer);
+
+ rcaSupportspy = spy(rcaSupport);
+ doNothing().when(rcaSupportspy).moveToAnnotation((MergeSourceViewer) Matchers.any(),
+ (MergeSourceViewer) Matchers.any(), (Position) Matchers.any());
+
+ }
+
+ //Test FORWARDS direction
+
+ @Test
+ public void testNextAnnotFwdLeftBeforeRightOffsetAfterBoth() throws Exception {
+ int ret;
+
+ // Position left < right, currentLeftOffset > Left and Right position, moving forward
+ int currentLeftOffset = 10;
+ Position nextLeftPosition = new Position(5, 0);
+ Position nextRightPosition = new Position(8, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.FORWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.LEFT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotFwdLeftAfterRightOffsetAfterBoth() throws Exception {
+ int ret;
+
+ // Position left > right, currentLeftOffset >Left and Right position, moving forward
+ int currentLeftOffset = 10;
+ Position nextLeftPosition = new Position(5, 0);
+ Position nextRightPosition = new Position(3, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.FORWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.RIGHT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotFwdLeftBeforeRightOffsetBeforeBoth() throws Exception {
+ int ret;
+
+ // Position left < right, currentLeftOffset < Left and Right position, moving forward
+ int currentLeftOffset = 10;
+ Position nextLeftPosition = new Position(15, 0);
+ Position nextRightPosition = new Position(16, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.FORWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.LEFT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotFwdLeftAfterRightOffsetBeforeBoth() throws Exception {
+ int ret;
+
+ // Position left > right, currentLeftOffset < Left and Right position, moving forward
+ int currentLeftOffset = 10;
+ Position nextLeftPosition = new Position(20, 0);
+ Position nextRightPosition = new Position(15, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.FORWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.RIGHT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotFwdLeftBeforeRightOffsetAfterLeftBeforeRightAfter() throws Exception {
+ int ret;
+
+ // Position left < right, currentLeftOffset > Left and currentLeftOffset < Right, moving forward
+ int currentLeftOffset = 10;
+ Position nextLeftPosition = new Position(5, 0);
+ Position nextRightPosition = new Position(15, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.FORWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.RIGHT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotFwdLeftAfterRightOffsetBeforeLeftAfterRight() throws Exception {
+ int ret;
+
+ // left > right, currentLeftOffset < left && currentLeftOffset > Right , moving forward
+ int currentLeftOffset = 1;
+ Position nextLeftPosition = new Position(10, 0);
+ Position nextRightPosition = new Position(0, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.FORWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.LEFT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotFwdLeftAfterRightOffsetEqualLeftAfterRight() throws Exception {
+ int ret;
+
+ // Position left > right, currentLeftOffset = next left && currentLeftOffset > next Right, moving forward
+ int currentLeftOffset = 10;
+ Position nextLeftPosition = new Position(10, 0);
+ Position nextRightPosition = new Position(0, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.FORWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.RIGHT_SIDE, ret);
+ }
+
+ //Test BACKWARDS direction
+ @Test
+ public void testNextAnnotBwdLeftAfterRightOffsetBeforeBoth() throws Exception {
+ int ret;
+
+ // left after right, currentLeftOffset is before both position, moving backwards
+ int currentLeftOffset = 10;
+ Position nextLeftPosition = new Position(20, 0);
+ Position nextRightPosition = new Position(15, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.BACKWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.LEFT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotBwdLeftBeforeRightOffsetBeforeBoth() throws Exception {
+ int ret;
+
+ // left before right, currentLeftOffset is before both position, moving backwards
+ int currentLeftOffset = 10;
+ Position nextLeftPosition = new Position(20, 0);
+ Position nextRightPosition = new Position(25, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.BACKWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.RIGHT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotBwdLeftAfterRightOffsetAfterBoth() throws Exception {
+ int ret;
+
+ // left after right, currentLeftOffset is after both position, moving backwards
+ int currentLeftOffset = 15;
+ Position nextLeftPosition = new Position(10, 0);
+ Position nextRightPosition = new Position(0, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.BACKWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.LEFT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotBwdLeftBeforeRightOffsetAfterBoth() throws Exception {
+ int ret;
+
+ // left after right, currentLeftOffset is after both position, moving backwards
+ int currentLeftOffset = 10;
+ Position nextLeftPosition = new Position(5, 0);
+ Position nextRightPosition = new Position(8, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.BACKWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.RIGHT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotBwdLeftAfterRightOffsetLeftAfterRightBefore() throws Exception {
+ int ret;
+
+ // left after right, currentLeftOffset is before Left and After Right position, moving backwards
+ int currentLeftOffset = 1;
+ Position nextLeftPosition = new Position(10, 0);
+ Position nextRightPosition = new Position(0, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.BACKWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.RIGHT_SIDE, ret);
+ }
+
+ @Test
+ public void testNextAnnotBwdLeftBeforeRightOffsetLeftBeforeRightAfter() throws Exception {
+ int ret;
+
+ // left before right, currentLeftOffset is after Left and Before Right, moving backwards
+ int currentLeftOffset = 10;
+ Position nextLeftPosition = new Position(5, 0);
+ Position nextRightPosition = new Position(15, 0);
+ ret = rcaSupportspy.calculateNextAnnotation(Direction.BACKWARDS, nextLeftPosition, nextRightPosition,
+ currentLeftOffset);
+
+ assertEquals(rcaSupportspy.LEFT_SIDE, ret);
+ }
+
+}
diff --git a/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewUiTest.java b/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewUiTest.java
index d0de291e4..9c60e6b8e 100644
--- a/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewUiTest.java
+++ b/org.eclipse.mylyn.reviews.tests/src/org/eclipse/mylyn/reviews/tests/ui/ReviewUiTest.java
@@ -7,6 +7,8 @@
*
* Contributors:
* Tasktop Technologies - initial API and implementation
+ * Guy Perron 423242: Add ability to edit comment from compare navigator popup
+
*******************************************************************************/
package org.eclipse.mylyn.reviews.tests.ui;
@@ -25,6 +27,7 @@ import org.junit.Test;
/**
* @author Steffen Pingel
+ * @author Guy Perron
*/
public class ReviewUiTest extends TestCase {
@@ -42,6 +45,12 @@ public class ReviewUiTest extends TestCase {
// ignore
return null;
}
+
+ @Override
+ public IStatus discardComment(IReviewItem fileItem, IComment comment, IProgressMonitor monitor) {
+ // ignore
+ return null;
+ }
};
ReviewUi.setActiveReview(activeReview);
assertEquals(activeReview, ReviewUi.getActiveReview());
diff --git a/org.eclipse.mylyn.reviews.ui/META-INF/MANIFEST.MF b/org.eclipse.mylyn.reviews.ui/META-INF/MANIFEST.MF
index 249ea11cc..9531ecde0 100644
--- a/org.eclipse.mylyn.reviews.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.mylyn.reviews.ui/META-INF/MANIFEST.MF
@@ -17,6 +17,7 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.ui.navigator,
org.eclipse.ui.workbench.texteditor,
org.eclipse.mylyn.commons.core;bundle-version="3.8.0",
+ org.eclipse.mylyn.commons.net;bundle-version="3.8.0",
org.eclipse.mylyn.commons.ui;bundle-version="3.8.0",
org.eclipse.mylyn.commons.workbench;bundle-version="3.8.0",
org.eclipse.mylyn.tasks.ui;bundle-version="3.8.0",
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/ReviewsUiConstants.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/ReviewsUiConstants.java
index 623782595..3105a17d0 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/ReviewsUiConstants.java
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/ReviewsUiConstants.java
@@ -7,6 +7,7 @@
*
* Contributors:
* Miles Parker (Tasktop Technologies) - initial API and implementation
+ * Guy Perron (Ericsson) - 423242: Add ability to edit comment from compare navigator popup
*******************************************************************************/
package org.eclipse.mylyn.internal.reviews.ui;
@@ -23,4 +24,9 @@ public interface ReviewsUiConstants {
public static final String REVIEW_FLAT_CONTENT_ID = "org.eclipse.mylyn.reviews.ui.ReviewFlatContent"; //$NON-NLS-1$
public static final String REVIEW_FILTER_FOR_COMMENTS = "org.eclipse.mylyn.reviews.ui.CommonFilter"; //$NON-NLS-1$
+
+ public static final int DIALOG_DEFAULT_HEIGHT = 300;
+
+ public static final int DIALOG_DEFAULT_WIDTH = 400;
+
}
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/actions/AddLineCommentToFileAction.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/actions/AddLineCommentToFileAction.java
index 0bd9a314b..07e516850 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/actions/AddLineCommentToFileAction.java
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/actions/AddLineCommentToFileAction.java
@@ -104,6 +104,10 @@ public class AddLineCommentToFileAction extends AbstractReviewAction {
public ILocation getLocation() {
LineRange selectedRange = getSelectedRange();
+ int maxNumberOfLines = compareSourceViewer.getAnnotationModel().getDocument().getNumberOfLines();
+ if (selectedRange.getStartLine() == maxNumberOfLines) {
+ selectedRange = new LineRange(maxNumberOfLines - 1, 1);
+ }
ILineLocation location = ReviewsFactory.eINSTANCE.createLineLocation();
ILineRange range = ReviewsFactory.eINSTANCE.createLineRange();
range.setStart(selectedRange.getStartLine());
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/CommentPopupDialog.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/CommentPopupDialog.java
index 940bb0bc8..426c7d3d9 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/CommentPopupDialog.java
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/CommentPopupDialog.java
@@ -7,19 +7,32 @@
*
* Contributors:
* Atlassian - initial API and implementation
+ * Guy Perron 423242: Add ability to edit comment from compare navigator popup
******************************************************************************/
package org.eclipse.mylyn.internal.reviews.ui.annotations;
+import java.util.HashMap;
+import java.util.Map;
+
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.PopupDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.PixelConverter;
+import org.eclipse.jface.text.source.LineRange;
import org.eclipse.mylyn.commons.workbench.forms.CommonFormUtil;
import org.eclipse.mylyn.internal.reviews.ui.IReviewActionListener;
+import org.eclipse.mylyn.internal.reviews.ui.dialogs.CommentInputDialog;
import org.eclipse.mylyn.internal.reviews.ui.editors.parts.CommentPart;
+import org.eclipse.mylyn.reviews.core.model.IReviewItem;
+import org.eclipse.mylyn.reviews.internal.core.model.Comment;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridLayout;
@@ -27,12 +40,15 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.widgets.FormToolkit;
/**
* Popup to show the information about the annotation in
*
* @author Shawn Minto
+ * @author Guy Perron
*/
public class CommentPopupDialog extends PopupDialog implements IReviewActionListener {
@@ -52,10 +68,29 @@ public class CommentPopupDialog extends PopupDialog implements IReviewActionList
private CommentInformationControl informationControl;
+ private IReviewItem reviewitem;
+
+ private LineRange range;
+
private static CommentPopupDialog currentPopupDialog;
+ private CommentInputDialog currentCommentInputDialog = null;
+
+ public final boolean isHoverActive;
+
+ private int lineNumber = 0;
+
public CommentPopupDialog(Shell parent, int shellStyle) {
super(parent, shellStyle, false, false, false, false, false, null, null);
+ isHoverActive = true;
+
+ }
+
+ public CommentPopupDialog(Shell parent, int shellStyle, boolean bHoverActive, IReviewItem reviewitm, LineRange range) {
+ super(parent, shellStyle, false, false, false, false, false, null, null);
+ this.isHoverActive = bHoverActive;
+ this.reviewitem = reviewitm;
+ this.range = range;
}
@Override
@@ -76,6 +111,7 @@ public class CommentPopupDialog extends PopupDialog implements IReviewActionList
public void dispose() {
currentPopupDialog = null;
+
close();
toolkit.dispose();
}
@@ -108,6 +144,7 @@ public class CommentPopupDialog extends PopupDialog implements IReviewActionList
}
public void removeFocusListener(FocusListener listener) {
+ currentCommentInputDialog = null;
composite.removeFocusListener(listener);
}
@@ -117,7 +154,6 @@ public class CommentPopupDialog extends PopupDialog implements IReviewActionList
}
public boolean isFocusControl() {
- //return composite.isFocusControl();
return getShell().getDisplay().getActiveShell() == getShell();
}
@@ -152,7 +188,7 @@ public class CommentPopupDialog extends PopupDialog implements IReviewActionList
width = computeSize.x;
}
getShell().setSize(width, height);
-// scrolledComposite.setSize(width, height);
+ scrolledComposite.setSize(width, height);
}
public void setInput(Object input) {
@@ -165,9 +201,29 @@ public class CommentPopupDialog extends PopupDialog implements IReviewActionList
}
currentPopupDialog = this;
- // FIXME
+
+ final Map<Integer, Comment> commentList = new HashMap<Integer, Comment>();
+
+ int count = 0;
for (CommentAnnotation annotation : annotationInput.getAnnotations()) {
+
+ if ((reviewitem != null)
+ && reviewitem.getReview() != null
+ && reviewitem.getReview().getRepository() != null
+ && reviewitem.getReview().getRepository().getAccount() != null
+ && reviewitem.getReview()
+ .getRepository()
+ .getAccount()
+ .toString()
+ .compareTo(((Comment) annotation.getComment()).getAuthor().toString()) != 0
+ && ((Comment) annotation.getComment()).isDraft()) {
+ continue;
+ }
+
CommentPart part = new CommentPart(annotation.getComment(), annotationInput.getBehavior());
+ count++;
+
+ commentList.put(new Integer(count), (Comment) annotation.getComment());
part.hookCustomActionRunListener(this);
Control control = part.createControl(composite, toolkit);
toolkit.adapt(control, true, true);
@@ -178,15 +234,60 @@ public class CommentPopupDialog extends PopupDialog implements IReviewActionList
scrolledComposite.layout(true, true);
scrolledComposite.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
-// focusLabel = toolkit.createLabel(composite, "Press 'F2' for focus.");
-// focusLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
-// GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(focusLabel);
+ focusLabel = toolkit.createLabel(composite, ""); //$NON-NLS-1$
+ focusLabel.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
+ GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(focusLabel);
+
+ PixelConverter Pc = new PixelConverter(composite.getFont());
+
+ final int avgHeight = Pc.convertHeightInCharsToPixels(1);
+
+ focusLabel.getParent().addMouseTrackListener(mouseTrackAdapter(commentList, avgHeight));
+
} else {
input = null;
}
}
+ private MouseTrackAdapter mouseTrackAdapter(final Map<Integer, Comment> commentList, final int avgHeight) {
+ return new MouseTrackAdapter() {
+
+ @Override
+ public void mouseEnter(MouseEvent e) {
+ if (!isHoverActive && currentCommentInputDialog == null) {
+
+ Point size = getShell().getSize();
+ dispose();
+ Shell ashell = PlatformUI.getWorkbench().getDisplay().getActiveShell();
+
+ currentCommentInputDialog = new CommentInputDialog(ashell, annotationInput.getBehavior(),
+ reviewitem, range);
+
+ currentCommentInputDialog.setComments(commentList);
+ currentCommentInputDialog.create();
+ currentCommentInputDialog.getShell().setText(
+ NLS.bind(Messages.CommentInputDialog_LineNumber, getLineNumber()));
+
+ // adjust size to display maximum of 15 lines, which means 5 comments
+ if (annotationInput.getAnnotations().size() < 5) {
+ size.y = size.y + (annotationInput.getAnnotations().size() * 3 * avgHeight);
+ } else {
+ size.y = size.y + (15 * avgHeight);
+ }
+ currentCommentInputDialog.getShell().setSize(size);
+ currentCommentInputDialog.open();
+
+ }
+ }
+
+ @Override
+ public void mouseExit(MouseEvent e) {
+ //ignore
+ };
+ };
+ }
+
public void actionAboutToRun(Action action) {
close();
}
@@ -207,4 +308,12 @@ public class CommentPopupDialog extends PopupDialog implements IReviewActionList
return informationControl;
}
+ public void setLineNumber(int lineOfOffset) {
+ lineNumber = lineOfOffset + 1;
+ }
+
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
}
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/Messages.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/Messages.java
index 386c7702f..ddfea5575 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/Messages.java
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/Messages.java
@@ -19,6 +19,9 @@ public class Messages extends NLS {
public static String CommentAnnotation_X_dash_Y;
public static String CommentAnnotationHover_Multiple_comments;
+
+ public static String CommentInputDialog_LineNumber;
+
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/ReviewAnnotationModel.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/ReviewAnnotationModel.java
index cd049587c..e9daa8765 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/ReviewAnnotationModel.java
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/ReviewAnnotationModel.java
@@ -8,6 +8,7 @@
* Contributors:
* Atlassian - initial API and implementation
* Tasktop Technologies - improvements
+ * Guy Perron 423242: Add ability to edit comment from compare navigator popup
******************************************************************************/
package org.eclipse.mylyn.internal.reviews.ui.annotations;
@@ -47,6 +48,7 @@ import org.eclipse.mylyn.reviews.ui.ReviewBehavior;
*
* @author Shawn Minto
* @author Steffen Pingel
+ * @author Guy Perron
*/
public class ReviewAnnotationModel implements IAnnotationModel {
@@ -81,6 +83,23 @@ public class ReviewAnnotationModel implements IAnnotationModel {
}
fireModelChanged(event);
}
+
+ if (notification.getEventType() == Notification.REMOVE) {
+ AnnotationModelEvent event = new AnnotationModelEvent(ReviewAnnotationModel.this);
+ if (notification.getOldValue() instanceof IComment) {
+ removeCommentAnnotations(document, event, (IComment) notification.getOldValue());
+ }
+ updateAnnotations();
+ }
+
+ if (notification.getEventType() == Notification.SET) {
+ AnnotationModelEvent event = new AnnotationModelEvent(ReviewAnnotationModel.this);
+ if (notification.getNewValue() instanceof IComment) {
+ modifyCommentAnnotations(document, event, (IComment) notification.getOldValue(),
+ (IComment) notification.getNewValue());
+ }
+ updateAnnotations();
+ }
}
};
@@ -220,7 +239,8 @@ public class ReviewAnnotationModel implements IAnnotationModel {
int offset = 0;
int length = 0;
- if (startLine != 0) {
+ if (startLine != 0 && startLine <= document.getNumberOfLines()) {
+
offset = document.getLineOffset(startLine - 1);
if (endLine == 0) {
endLine = startLine;
@@ -234,13 +254,88 @@ public class ReviewAnnotationModel implements IAnnotationModel {
event.annotationAdded(ca);
}
} catch (BadLocationException e) {
- StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID, "Unable to add annotation.", //$NON-NLS-1$
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID, "Unable to add annotation.",
e));
}
}
}
}
+ private void removeCommentAnnotations(IDocument document, AnnotationModelEvent event, IComment comment) {
+ int startLine = 0;
+ int endLine = 0;
+ for (ILocation location : comment.getLocations()) {
+ if (location instanceof ILineLocation) {
+ ILineLocation lineLocation = (ILineLocation) location;
+ try {
+ startLine = lineLocation.getRangeMin();
+ endLine = lineLocation.getRangeMax();
+
+ int offset = 0;
+ int length = 0;
+ if (startLine != 0 && startLine <= document.getNumberOfLines()) {
+
+ offset = document.getLineOffset(startLine - 1);
+ if (endLine == 0) {
+ endLine = startLine;
+ }
+ length = Math.max(document.getLineOffset(endLine - 1) - offset, 0);
+
+ }
+ length = Math.max(1, length);
+ CommentAnnotation ca = new CommentAnnotation(offset, length, comment);
+
+ annotations.remove(ca);
+ List<IComment> lst = reviewItem.getComments();
+ lst.remove(comment);
+ event.annotationRemoved(ca);
+
+ } catch (BadLocationException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID,
+ "Unable to remove annotation.", e));
+ }
+ }
+ }
+ }
+
+ private void modifyCommentAnnotations(IDocument document, AnnotationModelEvent event, IComment oldcomment,
+ IComment comment) {
+ int startLine = 0;
+ int endLine = 0;
+ for (ILocation location : comment.getLocations()) {
+ if (location instanceof ILineLocation) {
+ ILineLocation lineLocation = (ILineLocation) location;
+ try {
+ startLine = lineLocation.getRangeMin();
+ endLine = lineLocation.getRangeMax();
+
+ int offset = 0;
+ int length = 0;
+ if (startLine != 0 && startLine <= document.getNumberOfLines()) {
+
+ offset = document.getLineOffset(startLine - 1);
+ if (endLine == 0) {
+ endLine = startLine;
+ }
+ length = Math.max(document.getLineOffset(endLine - 1) - offset, 0);
+
+ }
+ length = Math.max(1, length);
+ CommentAnnotation oldca = new CommentAnnotation(offset, length, oldcomment);
+ CommentAnnotation ca = new CommentAnnotation(offset, length, comment);
+ annotations.remove(oldca);
+ annotations.add(ca);
+ event.annotationRemoved(oldca);
+ event.annotationChanged(ca);
+
+ } catch (BadLocationException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID,
+ "Unable to modify annotation.", e));
+ }
+ }
+ }
+ }
+
protected void clear() {
AnnotationModelEvent event = new AnnotationModelEvent(this);
clear(event);
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/messages.properties b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/messages.properties
index c5d595528..69742f4bb 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/messages.properties
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/annotations/messages.properties
@@ -10,3 +10,5 @@
###############################################################################
CommentAnnotation_X_dash_Y={0} - {1}
CommentAnnotationHover_Multiple_comments=There are multiple comments on this line
+CommentInputDialog_LineNumber=Comment for line number {0}
+
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/Direction.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/Direction.java
index 965ca3699..4ef33b323 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/Direction.java
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/Direction.java
@@ -11,7 +11,7 @@
package org.eclipse.mylyn.internal.reviews.ui.compare;
-enum Direction {
+public enum Direction {
FORWARDS, BACKWARDS;
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/ReviewCompareAnnotationSupport.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/ReviewCompareAnnotationSupport.java
index c3452d890..c5b20bb41 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/ReviewCompareAnnotationSupport.java
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/ReviewCompareAnnotationSupport.java
@@ -8,17 +8,22 @@
* Contributors:
* Atlassian - initial API and implementation
* Tasktop Technologies - cleanup and support for gotoAnnotation
+ * Guy Perron 423242: Add ability to edit comment from compare navigator popup
******************************************************************************/
package org.eclipse.mylyn.internal.reviews.ui.compare;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
+import java.util.List;
import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
import org.eclipse.compare.internal.MergeSourceViewer;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
@@ -26,14 +31,21 @@ import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.LineRange;
import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.projection.AnnotationBag;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.reviews.ui.ReviewsUiPlugin;
import org.eclipse.mylyn.internal.reviews.ui.annotations.CommentAnnotation;
+import org.eclipse.mylyn.internal.reviews.ui.annotations.CommentAnnotationHoverInput;
+import org.eclipse.mylyn.internal.reviews.ui.annotations.CommentPopupDialog;
import org.eclipse.mylyn.internal.reviews.ui.annotations.ReviewAnnotationModel;
import org.eclipse.mylyn.reviews.core.model.IFileItem;
+import org.eclipse.mylyn.reviews.core.model.IReviewItem;
import org.eclipse.mylyn.reviews.ui.ReviewBehavior;
+import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.texteditor.AbstractTextEditor;
@@ -43,12 +55,23 @@ import org.eclipse.ui.texteditor.AbstractTextEditor;
*
* @author Thomas Ehrnhoefer
* @author Steffen Pingel
+ * @author Guy Perron
*/
@SuppressWarnings("restriction")
public class ReviewCompareAnnotationSupport {
+ private static final int INTERRUPT_INTERVAL = 16;
+
+ private static final int PAUSE_DELAY = 250;
+
+ public final int LEFT_SIDE = 0;
+
+ public final int RIGHT_SIDE = 1;
+
private static String KEY_ANNOTAION_SUPPORT = ReviewItemSetCompareEditorInput.class.getName();
+ private CommentPopupDialog commentPopupDialog = null;
+
public static ReviewCompareAnnotationSupport getAnnotationSupport(Viewer contentViewer) {
ReviewCompareAnnotationSupport support = (ReviewCompareAnnotationSupport) contentViewer.getData(KEY_ANNOTAION_SUPPORT);
if (support == null) {
@@ -58,6 +81,15 @@ public class ReviewCompareAnnotationSupport {
return support;
}
+ private Thread watchDog = null;
+
+ private boolean sentinel = false;
+
+ public class MonitorObject {
+ };
+
+ MonitorObject myMonitorObject = new MonitorObject();
+
private ReviewBehavior behavior;
private final ReviewAnnotationModel leftAnnotationModel;
@@ -76,6 +108,7 @@ public class ReviewCompareAnnotationSupport {
this.leftAnnotationModel = new ReviewAnnotationModel();
this.rightAnnotationModel = new ReviewAnnotationModel();
install(contentViewer);
+ contentViewer.setData(KEY_ANNOTAION_SUPPORT, this);
}
@Override
@@ -143,6 +176,11 @@ public class ReviewCompareAnnotationSupport {
}
}
+ public boolean hasAnnotation(Direction direction) {
+ Position rightPosition = new Position(0, 0);
+ return findAnnotation(rightSourceViewer, direction, rightPosition, rightAnnotationModel) == null ? false : true;
+ }
+
/**
* Jumps to the next annotation according to the given direction.
*
@@ -151,41 +189,325 @@ public class ReviewCompareAnnotationSupport {
* @return the selected annotation or <code>null</code> if none
*/
public Annotation gotoAnnotation(Direction direction) {
- Position leftPosition = new Position(0, 0);
- Annotation leftAnnotation = findAnnotation(leftSourceViewer, direction, leftPosition, leftAnnotationModel);
- Position rightPosition = new Position(0, 0);
- Annotation rightAnnotation = findAnnotation(rightSourceViewer, direction, rightPosition, rightAnnotationModel);
+ if (leftSourceViewer == null) {
+ return null;
+ }
+ ITextSelection selection = (ITextSelection) leftSourceViewer.getSourceViewer()
+ .getSelectionProvider()
+ .getSelection();
+ int currentLeftOffset = selection.getOffset();
+ selection = (ITextSelection) rightSourceViewer.getSourceViewer().getSelectionProvider().getSelection();
+
+ Position nextLeftPosition = new Position(0, 0);
+ Annotation leftAnnotation = findAnnotation(leftSourceViewer, direction, nextLeftPosition, leftAnnotationModel);
+ Position nextRightPosition = new Position(0, 0);
+ Annotation rightAnnotation = findAnnotation(rightSourceViewer, direction, nextRightPosition,
+ rightAnnotationModel);
if (leftAnnotation == null && rightAnnotation != null) {
- selectAndReveal(rightSourceViewer, rightPosition);
+ selectAndReveal(rightSourceViewer, nextRightPosition);
return rightAnnotation;
} else if (leftAnnotation != null && rightAnnotation == null) {
- selectAndReveal(leftSourceViewer, leftPosition);
+ selectAndReveal(leftSourceViewer, nextLeftPosition);
return leftAnnotation;
} else if (leftAnnotation != null && rightAnnotation != null) {
- if ((direction == Direction.FORWARDS && leftPosition.offset <= rightPosition.offset)
- || (direction == Direction.BACKWARDS && leftPosition.offset >= rightPosition.offset)) {
- selectAndReveal(leftSourceViewer, leftPosition);
+ int line, offset = 0;
+ try {
+ line = leftAnnotationModel.getDocument().getLineOfOffset(nextLeftPosition.offset);
+ offset = leftAnnotationModel.getDocument().getLineOffset(line);
+ } catch (BadLocationException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID, "Error displaying comment", e)); //$NON-NLS-1$
+ }
+ nextLeftPosition.offset = offset;
+ nextLeftPosition.length = 1;
+ try {
+ line = rightAnnotationModel.getDocument().getLineOfOffset(nextRightPosition.offset);
+ offset = rightAnnotationModel.getDocument().getLineOffset(line);
+ } catch (BadLocationException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID, "Error displaying comment", e)); //$NON-NLS-1$
+ }
+ nextRightPosition.offset = offset;
+ nextRightPosition.length = 1;
+ try {
+ line = leftAnnotationModel.getDocument().getLineOfOffset(currentLeftOffset);
+ offset = leftAnnotationModel.getDocument().getLineOffset(line);
+ } catch (BadLocationException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID, "Error displaying comment", e)); //$NON-NLS-1$
+ }
+ currentLeftOffset = offset;
+
+ if (calculateNextAnnotation(direction, nextLeftPosition, nextRightPosition, currentLeftOffset) == LEFT_SIDE) {
return leftAnnotation;
} else {
- selectAndReveal(rightSourceViewer, rightPosition);
return rightAnnotation;
}
}
return null;
}
+ public int calculateNextAnnotation(Direction direction, Position nextLeftPosition, Position nextRightPosition,
+ Integer currentLeftOffset) {
+ if (direction == Direction.FORWARDS) {
+ if (nextLeftPosition.offset == nextRightPosition.offset) {
+ moveToAnnotation(rightSourceViewer, leftSourceViewer, nextLeftPosition);
+ rightSourceViewer.getSourceViewer().revealRange(nextLeftPosition.offset - 1,
+ nextLeftPosition.length - 1);
+ rightSourceViewer.getSourceViewer().setSelectedRange(nextLeftPosition.offset - 1,
+ nextLeftPosition.length - 1);
+ return LEFT_SIDE;
+ } else if ((nextLeftPosition.offset < currentLeftOffset && nextRightPosition.offset < currentLeftOffset)) {
+ if ((nextLeftPosition.offset < nextRightPosition.offset)) {
+ moveToAnnotation(rightSourceViewer, leftSourceViewer, nextLeftPosition);
+ return LEFT_SIDE;
+ } else {
+ moveToAnnotation(leftSourceViewer, rightSourceViewer, nextRightPosition);
+ return RIGHT_SIDE;
+ }
+ } else if ((nextLeftPosition.offset > currentLeftOffset && nextRightPosition.offset > currentLeftOffset)) {
+ if ((nextLeftPosition.offset < nextRightPosition.offset)) {
+ moveToAnnotation(rightSourceViewer, leftSourceViewer, nextLeftPosition);
+ return LEFT_SIDE;
+ } else {
+ moveToAnnotation(leftSourceViewer, rightSourceViewer, nextRightPosition);
+ return RIGHT_SIDE;
+ }
+ } else if ((nextLeftPosition.offset < currentLeftOffset && nextRightPosition.offset > currentLeftOffset)) {
+ moveToAnnotation(leftSourceViewer, rightSourceViewer, nextRightPosition);
+ return RIGHT_SIDE;
+
+ } else if ((nextLeftPosition.offset > currentLeftOffset && nextRightPosition.offset < currentLeftOffset)) {
+ moveToAnnotation(rightSourceViewer, leftSourceViewer, nextLeftPosition);
+ return LEFT_SIDE;
+ } else {
+ moveToAnnotation(leftSourceViewer, rightSourceViewer, nextRightPosition);
+ return RIGHT_SIDE;
+ }
+
+ } else { // backwards
+ if (nextLeftPosition.offset == nextRightPosition.offset) {
+ moveToAnnotation(leftSourceViewer, rightSourceViewer, nextRightPosition);
+ int line;
+ IRegion region;
+ int offset = 0;
+ int length = 0;
+ try {
+ line = rightAnnotationModel.getDocument().getLineOfOffset(nextRightPosition.offset);
+ region = rightAnnotationModel.getDocument().getLineInformation(line + 1);
+ offset = region.getOffset();
+ length = region.getLength();
+ } catch (BadLocationException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID,
+ "Error displaying comment", e)); //$NON-NLS-1$
+ }
+ nextLeftPosition.offset = offset;
+ nextLeftPosition.length = length;
+ leftSourceViewer.getSourceViewer().revealRange(nextLeftPosition.offset, nextLeftPosition.length);
+ leftSourceViewer.getSourceViewer().setSelectedRange(nextLeftPosition.offset, nextLeftPosition.length);
+ return RIGHT_SIDE;
+ } else if ((nextLeftPosition.offset > currentLeftOffset && nextRightPosition.offset > currentLeftOffset)) {
+ if ((nextLeftPosition.offset > nextRightPosition.offset)) {
+ moveToAnnotation(rightSourceViewer, leftSourceViewer, nextLeftPosition);
+ return LEFT_SIDE;
+ } else {
+ moveToAnnotation(leftSourceViewer, rightSourceViewer, nextRightPosition);
+ return RIGHT_SIDE;
+ }
+ } else if ((nextLeftPosition.offset < currentLeftOffset && nextRightPosition.offset < currentLeftOffset)) {
+ if ((nextLeftPosition.offset > nextRightPosition.offset)) {
+ moveToAnnotation(rightSourceViewer, leftSourceViewer, nextLeftPosition);
+ return LEFT_SIDE;
+ } else {
+ moveToAnnotation(leftSourceViewer, rightSourceViewer, nextRightPosition);
+ return RIGHT_SIDE;
+ }
+ } else if ((nextLeftPosition.offset > currentLeftOffset && nextRightPosition.offset < currentLeftOffset)) {
+ moveToAnnotation(leftSourceViewer, rightSourceViewer, nextRightPosition);
+ return RIGHT_SIDE;
+
+ } else if ((nextLeftPosition.offset < currentLeftOffset && nextRightPosition.offset > currentLeftOffset)) {
+ moveToAnnotation(rightSourceViewer, leftSourceViewer, nextLeftPosition);
+ return LEFT_SIDE;
+ } else {
+ moveToAnnotation(leftSourceViewer, rightSourceViewer, nextRightPosition);
+ return RIGHT_SIDE;
+ }
+
+ }
+ }
+
+ public void moveToAnnotation(MergeSourceViewer adjacentViewer, MergeSourceViewer annotationViewer, Position position) {
+ adjacentViewer.getSourceViewer().revealRange(position.offset, position.length);
+ adjacentViewer.getSourceViewer().setSelectedRange(position.offset, position.length);
+ selectAndReveal(annotationViewer, position);
+ }
+
// adapted from {@link AbstractTextEditor#selectAndReveal(int, int)}
private void selectAndReveal(MergeSourceViewer sourceViewer, Position position) {
StyledText widget = sourceViewer.getSourceViewer().getTextWidget();
widget.setRedraw(false);
{
+ int currentLineNumber = 0;
+ try {
+ currentLineNumber = sourceViewer.getSourceViewer().getDocument().getLineOfOffset(position.getOffset());
+ } catch (BadLocationException e1) {
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID, "Error displaying comment", e1)); //$NON-NLS-1$
+ }
adjustHighlightRange(sourceViewer.getSourceViewer(), position.offset, position.length);
sourceViewer.getSourceViewer().revealRange(position.offset, position.length);
sourceViewer.getSourceViewer().setSelectedRange(position.offset, position.length);
+ SourceViewer srcViewer = sourceViewer.getSourceViewer();
+
+ IReviewItem reviewitem = ((ReviewAnnotationModel) srcViewer.getAnnotationModel()).getItem();
+
+ List<CommentAnnotation> comments = getAnnotationsForLine(srcViewer, position.offset);
+
+ org.eclipse.swt.graphics.Point p = sourceViewer.getLineRange(position, sourceViewer.getSourceViewer()
+ .getSelectedRange());
+ LineRange range = new LineRange(p.x + 1, p.y);
+
+ if (commentPopupDialog != null) {
+ if (watchDog != null) {
+ try {
+ synchronized (myMonitorObject) {
+ sentinel = true;
+ commentPopupDialog.dispose();
+ myMonitorObject.wait();
+ }
+ } catch (InterruptedException e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID,
+ "Error destroying dialog", e)); //$NON-NLS-1$
+ }
+ }
+ }
+
+ commentPopupDialog = new CommentPopupDialog(ReviewsUiPlugin.getDefault()
+ .getWorkbench()
+ .getActiveWorkbenchWindow()
+ .getShell(), SWT.NO_FOCUS | SWT.ON_TOP, false, reviewitem, range);
+
+ CommentAnnotationHoverInput input = new CommentAnnotationHoverInput(comments,
+ ((ReviewAnnotationModel) srcViewer.getAnnotationModel()).getBehavior());
+
+ commentPopupDialog.create();
+ commentPopupDialog.setInput(input);
+
+ commentPopupDialog.setLineNumber(currentLineNumber);
+
+ commentPopupDialog.setSize(50, 150);
+
+ org.eclipse.swt.graphics.Point location = sourceViewer.getSourceViewer().getControl().getLocation();
+ location = Display.getCurrent().getCursorLocation();
+
+ location.y = location.y + (sourceViewer.getViewportHeight() / 2);
+
+ commentPopupDialog.setLocation(location);
+
+ commentPopupDialog.open();
+
+ watchDog = new Thread(new Runnable() {
+ public void run() {
+ try {
+ for (int x = 0; x < INTERRUPT_INTERVAL; x++) {
+ if (sentinel) {
+ Thread.currentThread().interrupt();
+ break;
+ }
+ Thread.sleep(PAUSE_DELAY);
+ }
+ } catch (Exception e) {
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID,
+ "Error interrupting thread", e)); //$NON-NLS-1$
+ }
+ if (!sentinel) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ if (commentPopupDialog != null) {
+ commentPopupDialog.dispose();
+ commentPopupDialog = null;
+ }
+ }
+ });
+ }
+ synchronized (myMonitorObject) {
+ myMonitorObject.notify();
+ }
+ }
+ });
+ sentinel = false;
+
+ watchDog.start();
}
widget.setRedraw(true);
}
+ @SuppressWarnings("unchecked")
+ private List<CommentAnnotation> getAnnotationsForLine(SourceViewer viewer, int offset) {
+ IAnnotationModel model = viewer.getAnnotationModel();
+ if (model == null) {
+ return Collections.emptyList();
+ }
+
+ IDocument document = viewer.getDocument();
+ int line = 0;
+ try {
+ line = document.getLineOfOffset(offset);
+ } catch (BadLocationException e1) {
+ StatusHandler.log(new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID, "Error fetching line", e1)); //$NON-NLS-1$
+ }
+
+ List<CommentAnnotation> commentAnnotations = new ArrayList<CommentAnnotation>();
+
+ for (Iterator<Annotation> it = model.getAnnotationIterator(); it.hasNext();) {
+ Annotation annotation = it.next();
+ Position position = model.getPosition(annotation);
+ if (position == null) {
+ continue;
+ }
+
+ if (!isRulerLine(position, document, line)) {
+ continue;
+ }
+
+ if (annotation instanceof AnnotationBag) {
+ AnnotationBag bag = (AnnotationBag) annotation;
+ Iterator<Annotation> e = bag.iterator();
+ while (e.hasNext()) {
+ annotation = e.next();
+ position = model.getPosition(annotation);
+ if (position != null && includeAnnotation(annotation, position, commentAnnotations)
+ && annotation instanceof CommentAnnotation) {
+ commentAnnotations.add((CommentAnnotation) annotation);
+ }
+ }
+ continue;
+ }
+
+ if (includeAnnotation(annotation, position, commentAnnotations) && annotation instanceof CommentAnnotation) {
+ commentAnnotations.add((CommentAnnotation) annotation);
+ }
+ }
+
+ return commentAnnotations;
+ }
+
+ private boolean includeAnnotation(Annotation annotation, Position position, List<CommentAnnotation> annotations) {
+ if (!(annotation instanceof CommentAnnotation)) {
+ return false;
+ }
+
+ return (annotation != null && !annotations.contains(annotation));
+ }
+
+ private boolean isRulerLine(Position position, IDocument document, int line) {
+ if (position.getOffset() > -1 && position.getLength() > -1) {
+ try {
+ return line == document.getLineOfOffset(position.getOffset());
+ } catch (BadLocationException x) {
+ // ignore
+ }
+ }
+ return false;
+ }
+
// adapted from {@link AbstractTextEditor#selectAndReveal(int, int)}
protected void adjustHighlightRange(SourceViewer sourceViewer, int offset, int length) {
if (sourceViewer instanceof ITextViewerExtension5) {
@@ -253,6 +575,7 @@ public class ReviewCompareAnnotationSupport {
* @return the found annotation
* @see borrowed and adapted from {@link AbstractTextEditor}
*/
+ @SuppressWarnings("null")
protected Annotation findAnnotation(MergeSourceViewer viewer, Direction direction, Position annotationPosition,
ReviewAnnotationModel annotationModel) {
if (viewer == null) {
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/ReviewCompareInputListener.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/ReviewCompareInputListener.java
index a3d2a58de..0527aa527 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/ReviewCompareInputListener.java
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/compare/ReviewCompareInputListener.java
@@ -51,8 +51,6 @@ import org.eclipse.mylyn.reviews.core.model.ILocation;
import org.eclipse.swt.custom.LineBackgroundEvent;
import org.eclipse.swt.custom.LineBackgroundListener;
import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
@@ -385,12 +383,6 @@ class ReviewCompareInputListener implements ITextInputListener, IReviewCompareSo
support.setAnnotationPreference((AnnotationPreference) e.next());
}
support.install(EditorsUI.getPreferenceStore());
- sourceViewer.getControl().addDisposeListener(new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- support.dispose();
- }
- });
-
Field overViewRulerField = sourceViewerClazz.getDeclaredField("fOverviewRuler"); //$NON-NLS-1$
overViewRulerField.setAccessible(true);
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/AddCommentDialog.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/AddCommentDialog.java
index 75d94ee29..288a15567 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/AddCommentDialog.java
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/AddCommentDialog.java
@@ -123,6 +123,7 @@ public class AddCommentDialog extends ProgressDialog {
new Status(IStatus.ERROR, ReviewsUiPlugin.PLUGIN_ID,
"Unexpected error during execution of operation", e), //$NON-NLS-1$
StatusManager.SHOW | StatusManager.LOG);
+ return false;
} catch (InterruptedException e) {
// cancelled
return false;
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/CommentInputDialog.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/CommentInputDialog.java
new file mode 100644
index 000000000..94c94354e
--- /dev/null
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/CommentInputDialog.java
@@ -0,0 +1,576 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson AB and others.
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Guy Perron - original version
+ *
+ ******************************************************************************/
+
+package org.eclipse.mylyn.internal.reviews.ui.dialogs;
+
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.text.source.LineRange;
+import org.eclipse.mylyn.commons.net.AuthenticationType;
+import org.eclipse.mylyn.internal.reviews.ui.ReviewsUiPlugin;
+import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
+import org.eclipse.mylyn.reviews.core.model.IComment;
+import org.eclipse.mylyn.reviews.core.model.IFileItem;
+import org.eclipse.mylyn.reviews.core.model.IFileVersion;
+import org.eclipse.mylyn.reviews.core.model.ILineLocation;
+import org.eclipse.mylyn.reviews.core.model.ILineRange;
+import org.eclipse.mylyn.reviews.core.model.IReviewItem;
+import org.eclipse.mylyn.reviews.core.model.IReviewItemSet;
+import org.eclipse.mylyn.reviews.core.model.IUser;
+import org.eclipse.mylyn.reviews.core.spi.ReviewsConnector;
+import org.eclipse.mylyn.reviews.core.spi.remote.emf.RemoteEmfConsumer;
+import org.eclipse.mylyn.reviews.core.spi.remote.review.IReviewRemoteFactoryProvider;
+import org.eclipse.mylyn.reviews.internal.core.model.Comment;
+import org.eclipse.mylyn.reviews.internal.core.model.ReviewsFactory;
+import org.eclipse.mylyn.reviews.ui.ReviewBehavior;
+import org.eclipse.mylyn.tasks.core.TaskRepository;
+import org.eclipse.mylyn.tasks.ui.TasksUi;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.FormDialog;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+/**
+ * This class implements the dialog used to fill-in the Comment element details.
+ *
+ * @author Guy Perron
+ */
+public class CommentInputDialog extends FormDialog {
+
+ // ------------------------------------------------------------------------
+ // Member variables
+ // ------------------------------------------------------------------------
+
+ private Text fCommentInputTextField;
+
+ private static final int BUTTON_REPLY_ID = 2;
+
+ private static final int BUTTON_REPLY_DONE_ID = 3;
+
+ private static final int BUTTON_DISCARD_ID = 4;
+
+ private static final int BUTTON_EDIT_ID = 5;
+
+ private static final int BUTTON_SAVE_ID = 6;
+
+ private static final String RESIZABLE_DIALOG_SETTINGS = "MyResizableDialogSettings"; //$NON-NLS-1$
+
+ private final ReviewBehavior reviewBehavior;
+
+ public IReviewItem reviewitem;
+
+ public LineRange range;
+
+ public Map<Integer, Comment> commentList;
+
+ public boolean isUpdate = false;
+
+ public boolean isDiscard = false;
+
+ public boolean isSave = false;
+
+ public boolean isDone = false;
+
+ public boolean isReply = false;
+
+ public String currentUuid;
+
+ public String currentAuthor;
+
+ public Composite buttonparent;
+
+ public Composite buttonBarParent;
+
+ private final Shell parent;
+
+ public CommentInputDialog(Shell aParentShell, ReviewBehavior reviewBehavior, IReviewItem reviewitm, LineRange range) {
+ super(aParentShell);
+ if (!isWindowPlatform()) {
+ setShellStyle(SWT.MODELESS | SWT.SHELL_TRIM | SWT.BORDER);
+ }
+ this.reviewBehavior = reviewBehavior;
+ this.reviewitem = reviewitm;
+ this.range = range;
+ this.parent = aParentShell;
+
+ }
+
+ private boolean isWindowPlatform() {
+ return Platform.getOS().equals(Platform.WS_WIN32);
+ }
+
+ @Override
+ protected IDialogSettings getDialogBoundsSettings() {
+ IDialogSettings settings = ReviewsUiPlugin.getDefault().getDialogSettings();
+
+ IDialogSettings section = settings.getSection(RESIZABLE_DIALOG_SETTINGS);
+ if (section == null) {
+ return settings.addNewSection(RESIZABLE_DIALOG_SETTINGS);
+ }
+ return section;
+ }
+
+ @Override
+ protected void buttonPressed(int buttonId) {
+
+ if (buttonId == IDialogConstants.CANCEL_ID) {
+ super.buttonPressed(0);
+ parent.setFocus();
+ return;
+ }
+
+ IComment comment = ReviewsFactory.eINSTANCE.createComment();
+ comment.setDescription(fCommentInputTextField.getText().trim());
+ switch (buttonId) {
+ case BUTTON_EDIT_ID:
+ comment.setId(currentUuid);
+ deleteButtons();
+ createSaveDiscard();
+ return;
+ case BUTTON_DISCARD_ID:
+ comment.setId(currentUuid);
+ isDiscard = true;
+ break;
+ case BUTTON_REPLY_ID:
+ comment.setId(currentUuid);
+ isSave = true;
+ isReply = true;
+ deleteButtons();
+ if (isOwn()) {
+ createSaveDiscard();
+ } else {
+ createSave();
+ }
+ fCommentInputTextField.setText(""); //$NON-NLS-1$
+ break;
+ case BUTTON_REPLY_DONE_ID:
+ isSave = true;
+ isDone = true;
+ comment.setDescription(Messages.CommentInputDialog_Done);
+ comment.setId(""); //$NON-NLS-1$
+ break;
+ case BUTTON_SAVE_ID:
+ comment.setId(currentUuid);
+ isSave = true;
+ if (isReply) {
+ isDone = true;
+ comment.setId(""); //$NON-NLS-1$
+ isReply = false;
+ }
+ }
+ comment.setDraft(true);
+ comment.setAuthor(getIUser());
+ comment.setCreationDate(new Date());
+
+ LineRange selectedRange = range;
+ ILineLocation location = ReviewsFactory.eINSTANCE.createLineLocation();
+ ILineRange aRange = ReviewsFactory.eINSTANCE.createLineRange();
+ aRange.setStart(selectedRange.getStartLine());
+ aRange.setEnd(selectedRange.getStartLine() + selectedRange.getNumberOfLines());
+ location.getRanges().add(aRange);
+
+ if (location != null) {
+ comment.getLocations().add(location);
+ }
+ if (buttonId != BUTTON_REPLY_ID) {
+ performOperation(comment);
+ super.buttonPressed(0);
+ }
+
+ }
+
+ private IUser getIUser() {
+ if ((reviewitem != null) && (reviewitem.getReview() != null)
+ && (reviewitem.getReview().getRepository() != null)
+ && (reviewitem.getReview().getRepository().getAccount() != null)) {
+ return reviewitem.getReview().getRepository().getAccount();
+ } else {
+ return null;
+ }
+ }
+
+ private boolean isOwn() {
+ return (reviewitem != null)
+ && (reviewitem.getReview() != null)
+ && (reviewitem.getReview().getRepository() != null)
+ && (reviewitem.getReview().getRepository().getTaskRepository() != null)
+ && (reviewitem.getReview()
+ .getRepository()
+ .getTaskRepository()
+ .getCredentials(AuthenticationType.REPOSITORY) != null)
+ && (reviewitem.getReview()
+ .getRepository()
+ .getTaskRepository()
+ .getCredentials(AuthenticationType.REPOSITORY)
+ .getUserName()
+ .compareTo(currentAuthor) == 0);
+
+ }
+
+ private boolean performOperation(final IComment comment) {
+ final IReviewItem item = reviewitem;
+ final AtomicReference<IStatus> result = new AtomicReference<IStatus>();
+
+ if (isSave || isDiscard) {
+ final Job job = new Job(Messages.CommandServerOperation) {
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ IStatus status = null;
+ if (isSave) {
+ status = reviewBehavior.addComment(item, comment, monitor);
+ if (status.isOK()) {
+ result.set(status);
+ updateClient(comment, item);
+ return Status.OK_STATUS;
+ }
+ } else {
+ status = reviewBehavior.discardComment(item, comment, monitor);
+
+ if (status.isOK()) {
+ result.set(status);
+ updateClient(comment, item);
+ return Status.OK_STATUS;
+ }
+ }
+ processServerError(status.getException().getCause().toString());
+
+ return Status.OK_STATUS;
+ }
+
+ };
+ job.setUser(true);
+ job.schedule();
+ }
+
+ return true;
+
+ }
+
+ private void updateClient(final IComment comment, final IReviewItem item) {
+ comment.setAuthor(getIUser());
+
+ if (!isUpdate || isDone) {
+ item.getComments().add(comment);
+ } else if (isDiscard == true) {
+ List<IComment> commentlist = item.getComments();
+ for (Iterator<IComment> iter = commentlist.iterator(); iter.hasNext();) {
+ IComment element = iter.next();
+ if (element.getId() != null && element.getId().compareTo(currentUuid) == 0) {
+ iter.remove();
+ }
+ }
+ } else {
+ List<IComment> commentlist = item.getComments();
+ for (int i = 0; i < commentlist.size(); i++) {
+ if (commentlist.get(i).getId() != null && commentlist.get(i).getId().compareTo(currentUuid) == 0) {
+ item.getComments().set(i, comment);
+ }
+ }
+
+ }
+
+ IFileItem file = null;
+ if (item instanceof IFileItem) {
+ file = (IFileItem) item;
+ } else if (item instanceof IFileVersion) {
+ file = ((IFileVersion) item).getFile();
+ }
+ if (file != null && file.getReview() != null) {
+ //Update any review item set observers IFF we belong to a review. (The set might represent a compare, in which case we won't have a relevant model object.)
+ updateConsumer(file);
+
+ }
+ }
+
+ private void processServerError(final String message) {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ final MessageDialog dialog = new MessageDialog(null, Messages.CommentInputDialog_ServerError, null,
+ message, MessageDialog.ERROR, new String[] { IDialogConstants.CANCEL_LABEL }, 0);
+ dialog.open();
+ }
+ });
+ }
+
+ private void updateConsumer(IFileItem file) {
+ TaskRepository taskRepository = TasksUi.getRepositoryManager().getRepository(
+ reviewBehavior.getTask().getConnectorKind(), reviewBehavior.getTask().getRepositoryUrl());
+ @SuppressWarnings("restriction")
+ ReviewsConnector connector = (ReviewsConnector) TasksUiPlugin.getConnector(reviewBehavior.getTask()
+ .getConnectorKind());
+ IReviewRemoteFactoryProvider factoryProvider = (IReviewRemoteFactoryProvider) connector.getReviewClient(
+ taskRepository).getFactoryProvider();
+
+ RemoteEmfConsumer<IReviewItemSet, List<IFileItem>, String, ?, ?, Long> consumer = factoryProvider.getReviewItemSetContentFactory()
+ .getConsumerForLocalKey(file.getSet(), file.getSet().getId());
+ consumer.updateObservers();
+ consumer.release();
+ }
+
+ @Override
+ protected void createFormContent(final IManagedForm mform) {
+
+ final ScrolledForm scrolledform = mform.getForm();
+ scrolledform.setExpandVertical(true);
+ scrolledform.setExpandHorizontal(true);
+ final Composite composite = scrolledform.getBody();
+
+ scrolledform.setContent(composite);
+
+ final GridLayout layout = new GridLayout(1, false);
+
+ composite.setLayout(layout);
+ GridData textGridData = null;
+
+ for (int i = 0; i < commentList.size(); i++) {
+ final Button button = new Button(composite, SWT.RADIO);
+
+ button.setBackground(composite.getBackground());
+
+ @SuppressWarnings("restriction")
+ Comment currentComment = commentList.get(new Integer(i + 1));
+
+ final String uuid = currentComment.getId();
+ final boolean isDraft = currentComment.isDraft();
+ final String commentText = currentComment.getDescription();
+ final String authorName, authorAndDate;
+ IUser author = currentComment.getAuthor();
+ if (author != null) {
+ authorName = currentComment.getAuthor().getDisplayName();
+ authorAndDate = currentComment.getAuthor().getDisplayName() + " " //$NON-NLS-1$
+ + currentComment.getCreationDate().toString();
+ } else {
+ authorName = Messages.CommentInputDialog_No_author;
+ authorAndDate = authorName + " " //$NON-NLS-1$
+ + currentComment.getCreationDate().toString();
+
+ }
+
+ String comment_str = currentComment.getDescription().length() < 50
+ ? currentComment.getDescription()
+ : currentComment.getDescription().substring(0, 46) + " ..."; //$NON-NLS-1$
+ if (isDraft) {
+ button.setText(NLS.bind(Messages.CommentInputDialog_Draft, authorAndDate, comment_str));
+ } else {
+ button.setText(authorAndDate + " " + comment_str); //$NON-NLS-1$
+ }
+
+ button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ deleteButtons();
+ if (isDraft) {
+ createEdit();
+ } else {
+ createReplyReplyDone();
+ }
+ currentUuid = uuid;
+ currentAuthor = authorName;
+ fCommentInputTextField.setText(commentText);
+ isUpdate = true;
+ }
+ });
+ GridDataFactory.fillDefaults().span(2, 1).applyTo(button);
+ }
+
+ fCommentInputTextField = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.WRAP);
+
+ textGridData = new GridData(GridData.FILL, GridData.FILL, true, true);
+ textGridData.horizontalSpan = 2;
+ textGridData.minimumHeight = fCommentInputTextField.getLineHeight() * 4;
+ fCommentInputTextField.setToolTipText(Messages.ReviewsCommentToolTip);
+ fCommentInputTextField.setLayoutData(textGridData);
+ fCommentInputTextField.setEnabled(false);
+
+ //Set default focus
+ fCommentInputTextField.setFocus();
+
+ if (!isWindowPlatform()) {
+ getShell().addShellListener(new ShellAdapter() {
+ @Override
+ public void shellDeactivated(ShellEvent e) {
+ boolean isExit = MessageDialog.openQuestion(getShell(),
+ Messages.CommentInputDialog_ConfirmExitCaption, Messages.CommentInputDialog_ConfirmExit);
+ if (isExit) {
+ buttonPressed(IDialogConstants.CANCEL_ID);
+ } else {
+ getShell().setFocus();
+ }
+ }
+ });
+ }
+
+ this.setHelpAvailable(false);
+
+ }
+
+ /**
+ * Configures the button bar.
+ *
+ * @param parent
+ * the parent composite
+ * @return Control
+ */
+ @Override
+ protected Control createButtonBar(final Composite parent) {
+
+ final Composite composite = new Composite(parent, SWT.NONE);
+ buttonBarParent = parent;
+
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.horizontalSpacing = 0;
+ layout.marginTop = 0;
+ layout.marginBottom = 0;
+ layout.verticalSpacing = 0;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(SWT.LEFT, SWT.BOTTOM, true, false));
+ composite.setFont(parent.getFont());
+
+ final Control buttonSection = super.createButtonBar(composite);
+ ((GridData) buttonSection.getLayoutData()).grabExcessHorizontalSpace = true;
+ ((GridData) buttonSection.getLayoutData()).grabExcessVerticalSpace = false;
+ buttonSection.addControlListener(new ControlListener() {
+
+ @Override
+ public void controlResized(ControlEvent e) {
+ buttonBar.pack();
+ }
+
+ @Override
+ public void controlMoved(ControlEvent e) {
+ // ignore
+ }
+ });
+
+ return composite;
+
+ }
+
+ @Override
+ public void createButtonsForButtonBar(Composite parent) {
+ buttonparent = parent;
+
+ createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+
+ }
+
+ @Override
+ protected boolean isResizable() {
+ return true;
+ }
+
+ public void setComments(Map<Integer, Comment> commentList) {
+ this.commentList = commentList;
+ }
+
+ private void deleteButtons() {
+
+ for (int buttonId : new int[] { BUTTON_REPLY_ID, BUTTON_REPLY_DONE_ID, BUTTON_DISCARD_ID, BUTTON_EDIT_ID,
+ BUTTON_SAVE_ID }) {
+ Button button = getButton(buttonId);
+ if (button != null) {
+ button.dispose();
+ }
+ }
+// if (this.getButton(BUTTON_REPLY_ID) != null) {
+// Button button = (this.getButton(BUTTON_REPLY_ID));
+// button.dispose();
+// }
+//
+// if (this.getButton(BUTTON_REPLY_DONE_ID) != null) {
+// Button button = (this.getButton(BUTTON_REPLY_DONE_ID));
+// button.dispose();
+// }
+//
+// if (this.getButton(BUTTON_DISCARD_ID) != null) {
+// Button button = (this.getButton(BUTTON_DISCARD_ID));
+// button.dispose();
+// }
+//
+// if (this.getButton(BUTTON_EDIT_ID) != null) {
+// Button button = (this.getButton(BUTTON_EDIT_ID));
+// button.dispose();
+// }
+//
+// if (this.getButton(BUTTON_SAVE_ID) != null) {
+// Button button = (this.getButton(BUTTON_SAVE_ID));
+// button.dispose();
+// }
+ fCommentInputTextField.setEnabled(false);
+
+ }
+
+ private void createEdit() {
+ createButton(buttonparent, BUTTON_EDIT_ID, Messages.CommentInputDialog_Edit, true);
+
+ buttonBar.pack();
+ }
+
+ private void createReplyReplyDone() {
+ createButton(buttonparent, BUTTON_REPLY_ID, Messages.CommentInputDialog_Reply, true);
+
+ createButton(buttonparent, BUTTON_REPLY_DONE_ID, Messages.CommentInputDialog_ReplyDone, true);
+
+ buttonBar.pack();
+ }
+
+ private void createSaveDiscard() {
+ createButton(buttonparent, BUTTON_SAVE_ID, Messages.CommentInputDialog_Save, true);
+
+ createButton(buttonparent, BUTTON_DISCARD_ID, Messages.CommentInputDialog_Discard, true);
+
+ fCommentInputTextField.setEnabled(true);
+ buttonBar.pack();
+
+ }
+
+ private void createSave() {
+ createButton(buttonparent, BUTTON_SAVE_ID, Messages.CommentInputDialog_Save, true);
+
+ fCommentInputTextField.setEnabled(true);
+ buttonBar.pack();
+
+ }
+
+}
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/Messages.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/Messages.java
new file mode 100644
index 000000000..93a68212b
--- /dev/null
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/Messages.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson AB and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ericsson AB - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.reviews.ui.dialogs;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author Guy Perron
+ */
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.mylyn.internal.reviews.ui.dialogs.messages"; //$NON-NLS-1$
+
+ public static String ReviewsCommentToolTip;
+
+ public static String CommentInputDialog_Draft;
+
+ public static String CommentInputDialog_Done;
+
+ public static String CommentInputDialog_Reply;
+
+ public static String CommentInputDialog_ReplyDone;
+
+ public static String CommentInputDialog_Discard;
+
+ public static String CommentInputDialog_Edit;
+
+ public static String CommentInputDialog_Save;
+
+ public static String CommandServerOperation;
+
+ public static String CommentInputDialog_ServerError;
+
+ public static String CommentInputDialog_No_author;
+
+ public static String CommentInputDialog_ConfirmExit;
+
+ public static String CommentInputDialog_ConfirmExitCaption;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/messages.properties b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/messages.properties
new file mode 100644
index 000000000..548bdfb89
--- /dev/null
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/internal/reviews/ui/dialogs/messages.properties
@@ -0,0 +1,23 @@
+###############################################################################
+# Copyright (c) 2014 Ericsson Communications
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Ericsson Communications - initial API and implementation
+###############################################################################
+CommentInputDialog_Draft={0} DRAFT {1}
+CommentInputDialog_Done=Done
+CommentInputDialog_Reply=Reply ...
+CommentInputDialog_ReplyDone=Reply 'Done'
+CommentInputDialog_Discard=Discard
+CommentInputDialog_Edit=Edit
+CommentInputDialog_Save=Save
+ReviewsCommentToolTip=The Comment Description
+CommandServerOperation=Performing server operation...
+CommentInputDialog_ServerError=Server Connection Error
+CommentInputDialog_No_author=(no author)
+CommentInputDialog_ConfirmExit=Do you want to exit the dialog ?
+CommentInputDialog_ConfirmExitCaption=Confirm exit
diff --git a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/reviews/ui/ReviewBehavior.java b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/reviews/ui/ReviewBehavior.java
index 46f34f264..eba55e8b7 100644
--- a/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/reviews/ui/ReviewBehavior.java
+++ b/org.eclipse.mylyn.reviews.ui/src/org/eclipse/mylyn/reviews/ui/ReviewBehavior.java
@@ -8,20 +8,22 @@
* Contributors:
* Tasktop Technologies - initial API and implementation
* Sebastien Dubois (Ericsson) - Improvements for Bug 400266
+ * Guy Perron 423242: Add ability to edit comment from compare navigator popup
*******************************************************************************/
package org.eclipse.mylyn.reviews.ui;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.mylyn.reviews.core.model.IComment;
import org.eclipse.mylyn.reviews.core.model.IFileVersion;
import org.eclipse.mylyn.reviews.core.model.IReviewItem;
-import org.eclipse.mylyn.reviews.core.model.IComment;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.team.core.history.IFileRevision;
/**
* @author Steffen Pingel
+ * @author Guy Perron
*/
public abstract class ReviewBehavior {
@@ -37,5 +39,7 @@ public abstract class ReviewBehavior {
public abstract IStatus addComment(IReviewItem fileItem, IComment comment, IProgressMonitor monitor);
+ public abstract IStatus discardComment(IReviewItem fileItem, IComment comment, IProgressMonitor monitor);
+
public abstract IFileRevision getFileRevision(IFileVersion reviewFileVersion);
}

Back to the top