diff --git a/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java b/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java index b7fafec0bfd3..a3b4ba723c13 100644 --- a/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java +++ b/platform/lang-impl/src/com/intellij/application/options/InitialConfigurationDialog.java @@ -159,6 +159,11 @@ public class InitialConfigurationDialog extends DialogWrapper { return myHidingPreviewPanel; } + @Override + protected void initOnImpl() { + //? + } + @Override protected void onImpl() { myWrapper.setVisible(true); diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractTitledSeparatorWithIcon.java b/platform/platform-impl/src/com/intellij/ui/AbstractTitledSeparatorWithIcon.java index 7293e1289a47..5a061dfef07a 100644 --- a/platform/platform-impl/src/com/intellij/ui/AbstractTitledSeparatorWithIcon.java +++ b/platform/platform-impl/src/com/intellij/ui/AbstractTitledSeparatorWithIcon.java @@ -114,6 +114,15 @@ public abstract class AbstractTitledSeparatorWithIcon extends JPanel { onImpl(); } + public void initOn() { + initDetails(); + myOn = true; + myLabel.setIcon(myIconOpen); + initOnImpl(); + } + + protected abstract void initOnImpl(); + public void off() { myOn = false; myLabel.setIcon(myIcon); diff --git a/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java b/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java index 880060b2b868..2b86c4af99a6 100644 --- a/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java +++ b/platform/platform-impl/src/com/intellij/ui/SplitterWithSecondHideable.java @@ -15,6 +15,7 @@ */ package com.intellij.ui; +import com.intellij.openapi.ui.PseudoSplitter; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.vcs.changes.RefreshablePanel; @@ -35,7 +36,7 @@ import java.awt.event.MouseWheelEvent; * Time: 2:33 PM */ public abstract class SplitterWithSecondHideable { - private final Splitter mySplitter; + private final PseudoSplitter mySplitter; private final AbstractTitledSeparatorWithIcon myTitledSeparator; private final boolean myVertical; private final OnOffListener myListener; @@ -67,14 +68,32 @@ public abstract class SplitterWithSecondHideable { } @Override - protected void onImpl() { - final int firstSize = vertical ? mySplitter.getFirstComponent().getHeight() : mySplitter.getFirstComponent().getWidth(); + protected void initOnImpl() { final float proportion = myPreviousProportion > 0 ? myPreviousProportion : getSplitterInitialProportion(); - mySplitter.setProportion(proportion); + mySplitter.setSecondComponent(myDetailsComponent.getPanel()); + mySuperDivider.setResizeEnabled(true); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + mySplitter.fixFirst(proportion); + mySplitter.revalidate(); + mySplitter.repaint(); + } + }); + } + + @Override + protected void onImpl() { + final float proportion = myPreviousProportion > 0 ? myPreviousProportion : getSplitterInitialProportion(); + final int firstSize = vertical ? mySplitter.getFirstComponent().getHeight() : mySplitter.getFirstComponent().getWidth(); + // !! order is important! first fix + mySplitter.fixFirst(); + myListener.on((int) ((1 - proportion) * firstSize / proportion)); + //mySplitter.setProportion(proportion); mySplitter.setSecondComponent(myDetailsComponent.getPanel()); mySplitter.revalidate(); mySplitter.repaint(); - myListener.on((int) ((1 - proportion) * firstSize / proportion)); mySuperDivider.setResizeEnabled(true); } @@ -83,6 +102,7 @@ public abstract class SplitterWithSecondHideable { final int previousSize = vertical ? mySplitter.getSecondComponent().getHeight() : mySplitter.getSecondComponent().getWidth(); mySplitter.setSecondComponent(myFictivePanel); myPreviousProportion = mySplitter.getProportion(); + mySplitter.freeAll(); mySplitter.setProportion(1.0f); mySplitter.revalidate(); mySplitter.repaint(); @@ -90,7 +110,7 @@ public abstract class SplitterWithSecondHideable { mySuperDivider.setResizeEnabled(false); } }; - mySplitter = new Splitter(vertical) { + mySplitter = new PseudoSplitter(vertical) { { myTitledSeparator.mySeparator.addMouseListener(new MouseAdapter() { @Override @@ -200,6 +220,10 @@ public abstract class SplitterWithSecondHideable { public float getUsedProportion() { return isOn() ? mySplitter.getProportion() : myPreviousProportion; } + + public void initOn() { + myTitledSeparator.initOn(); + } public void on() { myTitledSeparator.on(); diff --git a/platform/util/src/com/intellij/openapi/ui/PseudoSplitter.java b/platform/util/src/com/intellij/openapi/ui/PseudoSplitter.java new file mode 100644 index 000000000000..34debeed1858 --- /dev/null +++ b/platform/util/src/com/intellij/openapi/ui/PseudoSplitter.java @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2011 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.ui; + +import javax.swing.*; + +/** + * Created by IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 12/3/11 + * Time: 6:13 PM + */ +public class PseudoSplitter extends Splitter { + private boolean myFirstIsFixed; + private boolean mySecondIsFixed; + private int myFirstFixedSize; + private int mySecondFixedSize; + + public PseudoSplitter(boolean vertical) { + super(vertical); + myFirstIsFixed = false; + mySecondIsFixed = false; + } + + public PseudoSplitter(boolean vertical, float proportion) { + super(vertical, proportion); + myFirstIsFixed = true; + } + + public PseudoSplitter(boolean vertical, float proportion, float minProp, float maxProp) { + super(vertical, proportion, minProp, maxProp); + myFirstIsFixed = true; + } + + private int getSizeForComp(final JComponent component) { + return getOrientation() ? component.getHeight() : component.getWidth(); + } + + public void fixFirst(final float proportion) { + assert getFirstComponent() != null; + int comp = getSizeForComp(this); + myFirstFixedSize = (int)(comp * proportion); + myFirstIsFixed = true; + mySecondIsFixed = false; + } + + public void fixFirst() { + assert getFirstComponent() != null; + myFirstFixedSize = getSizeForComp(getFirstComponent()); + myFirstIsFixed = true; + mySecondIsFixed = false; + } + + public void fixSecond() { + assert getSecondComponent() != null; + mySecondFixedSize = getSizeForComp(getSecondComponent()); + myFirstIsFixed = false; + mySecondIsFixed = true; + } + + public void freeAll() { + myFirstIsFixed = false; + mySecondIsFixed = false; + } + + @Override + public void doLayout() { + int total = getSizeForComp(this); + if (myFirstIsFixed) { + myProportion = ((float)myFirstFixedSize) / (total - getDividerWidth()); + } else if (mySecondIsFixed) { + myProportion = ((float)total - mySecondFixedSize) / (total - getDividerWidth()); + } + super.doLayout(); + } + + @Override + public void setProportion(float proportion) { + boolean firstIsFixed = myFirstIsFixed; + boolean secondIsFixed = mySecondIsFixed; + myFirstIsFixed = false; + mySecondIsFixed = false; + super.setProportion(proportion); + + int total = getSizeForComp(this); + if (firstIsFixed) { + myFirstFixedSize = (int) (myProportion * (total - getDividerWidth())); + myFirstIsFixed = true; + } else if (secondIsFixed) { + mySecondFixedSize = (int) ((1 - myProportion) * (total - getDividerWidth())); + mySecondIsFixed = true; + } + } +} diff --git a/platform/util/src/com/intellij/openapi/ui/Splitter.java b/platform/util/src/com/intellij/openapi/ui/Splitter.java index 1aac8335f09a..bfd632013c1a 100644 --- a/platform/util/src/com/intellij/openapi/ui/Splitter.java +++ b/platform/util/src/com/intellij/openapi/ui/Splitter.java @@ -53,7 +53,7 @@ public class Splitter extends JPanel { private final float myMaxProp; - private float myProportion; + protected float myProportion; private final Divider myDivider; private JComponent mySecondComponent; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java index 7dbf8370e7f9..b65831f7b667 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ShortDiffDetails.java @@ -197,7 +197,9 @@ public class ShortDiffDetails implements RefreshablePanel, Disposable { @Override public void dispose() { - myDetailsLoader.dispose(); + if (myDetailsLoader != null) { + myDetailsLoader.dispose(); + } myDetailsPanel.clear(); myDetailsCache.clear(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java index d81ac648695c..fb5976f0501c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/CommitChangeListDialog.java @@ -46,7 +46,6 @@ import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.SplitterWithSecondHideable; import com.intellij.util.Alarm; import com.intellij.util.OnOffListener; -import com.intellij.util.ui.AdjustComponentWhenShown; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -54,7 +53,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; -import java.awt.font.LineMetrics; import java.io.File; import java.util.*; import java.util.List; @@ -83,7 +81,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj private final Alarm myOKButtonUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private String myLastKnownComment = ""; private final boolean myAllOfDefaultChangeListChangesIncluded; - @NonNls private static final String SPLITTER_PROPORTION_OPTION = "CommitChangeListDialog.SPLITTER_PROPORTION"; + @NonNls private static final String SPLITTER_PROPORTION_OPTION = "CommitChangeListDialog.SPLITTER_PROPORTION_"; private final Action[] myExecutorActions; private final boolean myShowVcsCommit; private final Map myPerVcsOptionsPanels = new HashMap(); @@ -104,12 +102,13 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj private String myHelpId; private SplitterWithSecondHideable myDetailsSplitter; - private static final String DETAILS_SPLITTER_PROPORTION_OPTION = "CommitChangeListDialog.DETAILS_SPLITTER_PROPORTION_OPTION"; - private static final String DETAILS_SHOW_OPTION = "CommitChangeListDialog.DETAILS_SHOW_OPTION"; + private static final String DETAILS_SPLITTER_PROPORTION_OPTION = "CommitChangeListDialog.DETAILS_SPLITTER_PROPORTION_OPTION_"; + private static final String DETAILS_SHOW_OPTION = "CommitChangeListDialog.DETAILS_SHOW_OPTION_"; private JPanel myDetailsPanel; - private final AdjustComponentWhenShown myAdjustWhenShown; private final FileAndDocumentListenersForShortDiff myListenersForShortDiff; private String myOkActionText; + private final ZipperUpdater myZipperUpdater; + private final Runnable myRefreshDetails; private static class MyUpdateButtonsRunnable implements Runnable { private CommitChangeListDialog myDialog; @@ -275,8 +274,8 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj myBrowserExtender = browser.getExtender(); } myDiffDetails.setParent(myBrowser); - final ZipperUpdater zipperUpdater = new ZipperUpdater(30, Alarm.ThreadToUse.SWING_THREAD, getDisposable()); - final Runnable refreshShortDiffDetails = new Runnable() { + myZipperUpdater = new ZipperUpdater(30, Alarm.ThreadToUse.SWING_THREAD, getDisposable()); + myRefreshDetails = new Runnable() { @Override public void run() { myDiffDetails.refresh(); @@ -285,7 +284,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj myListenersForShortDiff = new FileAndDocumentListenersForShortDiff(myDiffDetails) { @Override protected void updateDetails() { - zipperUpdater.queue(refreshShortDiffDetails); + myZipperUpdater.queue(myRefreshDetails); } @Override protected boolean updateSynchronously() { @@ -297,7 +296,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj myBrowser.getViewer().addSelectionListener(new Runnable() { @Override public void run() { - zipperUpdater.queue(refreshShortDiffDetails); + myZipperUpdater.queue(myRefreshDetails); } }); @@ -468,21 +467,23 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj support.installSearch(myCommitMessageArea.getEditorField(), myCommitMessageArea.getEditorField()); } - myAdjustWhenShown = new AdjustComponentWhenShown() { - @Override - protected boolean init() { - myDiffDetails.refresh(); - String value = PropertiesComponent.getInstance().getValue(DETAILS_SHOW_OPTION); - if (value != null) { - Boolean asBoolean = Boolean.valueOf(value); - if (Boolean.TRUE.equals(asBoolean)) { - myDetailsSplitter.on(); - } - } - return calcSplitterProportion(); + showDetailsIfSaved(); + } + + private void showDetailsIfSaved() { + String value = PropertiesComponent.getInstance().getValue(DETAILS_SHOW_OPTION); + if (value != null) { + Boolean asBoolean = Boolean.valueOf(value); + if (Boolean.TRUE.equals(asBoolean)) { + myDetailsSplitter.initOn(); } - }; - myAdjustWhenShown.install(myBrowser); + } + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + myZipperUpdater.queue(myRefreshDetails); + } + }); } private void updateOnListSelection() { @@ -938,6 +939,8 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj mySplitter.setFirstComponent(myBrowser); mySplitter.setSecondComponent(myCommitMessageArea); mySplitter.setDividerWidth(3); + initMainSplitter(); + rootPane.add(mySplitter, BorderLayout.CENTER); JComponent browserHeader = myBrowser.getHeaderPanel(); @@ -968,7 +971,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj new OnOffListener() { @Override public void on(Integer integer) { - if (! myAdjustWhenShown.isAdjusted()) return; + if (integer == 0) return; final Dimension dialogSize = getSize(); setSize(dialogSize.width, dialogSize.height + integer); repaint(); @@ -976,7 +979,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj @Override public void off(Integer integer) { - if (! myAdjustWhenShown.isAdjusted()) return; + if (integer == 0) return; final Dimension dialogSize = getSize(); setSize(dialogSize.width, dialogSize.height - integer); repaint(); @@ -1000,7 +1003,7 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj } } if (value <= 0.05 || value >= 0.95) { - return 0.7f; + return 0.6f; } return value; } @@ -1009,30 +1012,23 @@ public class CommitChangeListDialog extends DialogWrapper implements CheckinProj return myDetailsSplitter.getComponent(); } - private void initDetails() { - if (myDetailsPanel == null) { - myDetailsPanel = myDiffDetails.getPanel(); - //myDetailsPanel.setBorder(BorderFactory.createLineBorder(UIUtil.getBorderColor())); - } - } - - private boolean calcSplitterProportion() { + private void initMainSplitter() { final String s = PropertiesComponent.getInstance().getValue(SPLITTER_PROPORTION_OPTION); if (s != null) { try { mySplitter.setProportion(Float.valueOf(s).floatValue()); - return true; } catch (NumberFormatException e) { // } + } else { + mySplitter.setProportion(0.8f); + } + } + + private void initDetails() { + if (myDetailsPanel == null) { + myDetailsPanel = myDiffDetails.getPanel(); } - int height = mySplitter.getHeight(); - if (height == 0) return false; - Graphics g = myCommitMessageArea.getEditorField().getGraphics(); - final LineMetrics lm = g.getFont().getLineMetrics("Wp", g.getFontMetrics().getFontRenderContext()); - final float commentHeight = 8 * lm.getHeight(); - mySplitter.setProportion((height - commentHeight)/height); - return true; } public Collection getAffectedVcses() {