[diff]: move preview panel with horizontal splitter into separated class

* create common refreshable diff processor class, rename method
* add javadoc for refreshable RequestProcessor
This commit is contained in:
Nadya Zabrodina
2017-05-17 17:22:55 +03:00
parent be35049bde
commit 20ad59ddbb
4 changed files with 147 additions and 59 deletions
@@ -16,12 +16,10 @@
package com.intellij.openapi.vcs.changes;
import com.intellij.diff.chains.DiffRequestProducerException;
import com.intellij.diff.impl.CacheDiffRequestProcessor;
import com.intellij.diff.requests.DiffRequest;
import com.intellij.diff.requests.ErrorDiffRequest;
import com.intellij.diff.requests.LoadingDiffRequest;
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
@@ -33,15 +31,10 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
public abstract class CacheChangeProcessor extends CacheDiffRequestProcessor<CacheChangeProcessor.ChangeWrapper> {
private static final Logger LOG = Logger.getInstance(CacheChangeProcessor.class);
public abstract class CacheChangeProcessor extends CacheDiffRefreshableRequestProcessor<CacheChangeProcessor.ChangeWrapper> {
@Nullable private Change myCurrentChange;
public CacheChangeProcessor(@NotNull Project project) {
super(project);
}
public CacheChangeProcessor(@NotNull Project project, @NotNull String place) {
super(project, place);
}
@@ -121,11 +114,14 @@ public abstract class CacheChangeProcessor extends CacheDiffRequestProcessor<Cac
* current element should always be among allChanges and selection (if they are not empty)
*/
@CalledInAwt
@Override
public void clear() {
myCurrentChange = null;
updateRequest();
}
@Override
@CalledInAwt
public void refresh() {
List<Change> selectedChanges = getSelectedChanges();
@@ -0,0 +1,45 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.vcs.changes;
import com.intellij.diff.impl.CacheDiffRequestProcessor;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class CacheDiffRefreshableRequestProcessor<T> extends CacheDiffRequestProcessor<T> {
public CacheDiffRefreshableRequestProcessor(@Nullable Project project) {
super(project);
}
public CacheDiffRefreshableRequestProcessor(@Nullable Project project, @NotNull String place) {
super(project, place);
}
/**
* Notify currently shown diff that it's not needed now and cached values can be reset, a.e. before hiding preview panel
*/
@CalledInAwt
public abstract void clear();
/**
* Get newly requested element for diff and update/create new diff request for it
* a.e. get selection from some model and check if previously shown diff request need to be replaced or still valid for such selection
*/
@CalledInAwt
public abstract void refresh();
}
@@ -36,7 +36,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
@@ -48,7 +47,8 @@ import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager;
import com.intellij.openapi.vcs.changes.ui.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.ui.*;
import com.intellij.ui.JBColor;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.content.Content;
import com.intellij.util.Alarm;
import com.intellij.util.FunctionUtil;
@@ -72,6 +72,7 @@ import java.awt.event.KeyEvent;
import java.util.Collection;
import java.util.List;
import static com.intellij.util.ObjectUtils.assertNotNull;
import static java.util.stream.Collectors.toList;
@State(
@@ -81,6 +82,7 @@ import static java.util.stream.Collectors.toList;
public class ChangesViewManager implements ChangesViewI, ProjectComponent, PersistentStateComponent<ChangesViewManager.State> {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.ChangesViewManager");
public static final String CHANGES_VIEW_PREVIEW_SPLITTER_PROPORTION = "ChangesViewManager.DETAILS_SPLITTER_PROPORTION";
@NotNull private final ChangesListView myView;
private JPanel myProgressLabel;
@@ -95,16 +97,7 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
@NotNull private ChangesViewManager.State myState = new ChangesViewManager.State();
private JBSplitter mySplitter;
private boolean myDetailsOn;
@NotNull private final NotNullLazyValue<MyChangeProcessor> myDiffDetails = new NotNullLazyValue<MyChangeProcessor>() {
@NotNull
@Override
protected MyChangeProcessor compute() {
return new MyChangeProcessor(myProject);
}
};
private PreviewDiffSplitterComponent mySplitterComponent;
@NotNull private final TreeSelectionListener myTsl;
private Content myContent;
@@ -134,7 +127,7 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
LOG.debug(message);
}
}
SwingUtilities.invokeLater(() -> changeDetails());
ApplicationManager.getApplication().invokeLater(() -> updatePreview());
}
};
}
@@ -157,9 +150,7 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
scheduleRefresh();
myProject.getMessageBus().connect().subscribe(RemoteRevisionsCache.REMOTE_VERSION_CHANGED,
() -> ApplicationManager.getApplication().invokeLater(() -> refreshView(), ModalityState.NON_MODAL, myProject.getDisposed()));
myDetailsOn = VcsConfiguration.getInstance(myProject).LOCAL_CHANGES_DETAILS_PREVIEW_SHOWN;
changeDetails();
updatePreview();
}
@Override
@@ -219,13 +210,15 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
panel.setToolbar(toolbarPanel);
final JPanel content = new JPanel(new BorderLayout());
mySplitter = new JBSplitter(false, "ChangesViewManager.DETAILS_SPLITTER_PROPORTION", 0.5f);
mySplitter.setHonorComponentsMinimumSize(false);
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myView);
final JPanel wrapper = new JPanel(new BorderLayout());
wrapper.add(scrollPane, BorderLayout.CENTER);
mySplitter.setFirstComponent(wrapper);
content.add(mySplitter, BorderLayout.CENTER);
MyChangeProcessor changeProcessor = new MyChangeProcessor(myProject);
mySplitterComponent =
new PreviewDiffSplitterComponent(wrapper, changeProcessor, CHANGES_VIEW_PREVIEW_SPLITTER_PROPORTION,
VcsConfiguration.getInstance(myProject).LOCAL_CHANGES_DETAILS_PREVIEW_SHOWN);
content.add(mySplitterComponent, BorderLayout.CENTER);
content.add(myProgressLabel, BorderLayout.SOUTH);
panel.setContent(content);
@@ -234,32 +227,6 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
return panel;
}
private void changeDetails() {
if (!myDetailsOn) {
if (myDiffDetails.isComputed()) {
myDiffDetails.getValue().clear();
if (mySplitter.getSecondComponent() != null) {
setChangeDetailsPanel(null);
}
}
}
else {
myDiffDetails.getValue().refresh();
if (mySplitter.getSecondComponent() == null) {
setChangeDetailsPanel(myDiffDetails.getValue().getComponent());
}
}
}
private void setChangeDetailsPanel(@Nullable JComponent component) {
mySplitter.setSecondComponent(component);
mySplitter.getFirstComponent().setBorder(component == null ? null : IdeBorderFactory.createBorder(SideBorder.RIGHT));
mySplitter.revalidate();
mySplitter.repaint();
}
@JdkConstants.InputEventMask
private static int ctrlMask() {
return SystemInfo.isMac ? InputEvent.META_DOWN_MASK : InputEvent.CTRL_DOWN_MASK;
@@ -330,7 +297,13 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
treeModelBuilder.build()
);
changeDetails();
updatePreview();
}
private void updatePreview() {
if (mySplitterComponent != null) {
mySplitterComponent.updatePreview();
}
}
@NotNull
@@ -508,14 +481,19 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi
@Override
public boolean isSelected(AnActionEvent e) {
return myDetailsOn;
return assertNotNull(mySplitterComponent).isDetailsOn();
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
myDetailsOn = state;
VcsConfiguration.getInstance(myProject).LOCAL_CHANGES_DETAILS_PREVIEW_SHOWN = myDetailsOn;
changeDetails();
assertNotNull(mySplitterComponent).setDetailsOn(state);
VcsConfiguration.getInstance(myProject).LOCAL_CHANGES_DETAILS_PREVIEW_SHOWN = state;
}
@Override
public void update(@NotNull AnActionEvent e) {
super.update(e);
e.getPresentation().setEnabled(mySplitterComponent != null);
}
}
@@ -0,0 +1,69 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.vcs.changes;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.JBSplitter;
import com.intellij.ui.SideBorder;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class PreviewDiffSplitterComponent extends JBSplitter {
@NotNull private final JComponent myFirstComponent;
@NotNull private final CacheDiffRefreshableRequestProcessor myProcessor;
private boolean myDetailsOn;
public PreviewDiffSplitterComponent(@NotNull JComponent firstComponent,
@NotNull CacheDiffRefreshableRequestProcessor processor,
@NotNull String splitterDimensionKey, boolean detailsOn) {
super(splitterDimensionKey, 0.5f);
myFirstComponent = firstComponent;
myProcessor = processor;
setHonorComponentsMinimumSize(false);
setFirstComponent(firstComponent);
setDetailsOn(detailsOn);
}
public void updatePreview() {
if (isDetailsOn()) {
myProcessor.refresh();
}
else {
myProcessor.clear();
}
}
private void updateVisibility() {
setSecondComponent(myDetailsOn ? myProcessor.getComponent() : null);
myFirstComponent.setBorder(myDetailsOn ? IdeBorderFactory.createBorder(SideBorder.RIGHT) : null);
revalidate();
repaint();
}
public boolean isDetailsOn() {
return myDetailsOn;
}
public void setDetailsOn(boolean detailsOn) {
myDetailsOn = detailsOn;
updatePreview();
if (myDetailsOn == (getSecondComponent() == null)) {
updateVisibility();
}
}
}