vcs: migrate Changelists configurable to UI DSL

GitOrigin-RevId: 172bdc5fa3f7b04207b0a845ef472dcf768359a9
This commit is contained in:
Aleksey Pivovarov
2021-04-14 23:51:55 +03:00
committed by intellij-monorepo-bot
parent aa07d72bc6
commit 66e9b89b03
6 changed files with 150 additions and 249 deletions
@@ -166,3 +166,8 @@ fun Row.enableIf(predicate: ComponentPredicate) {
enabled = predicate()
predicate.addListener { enabled = it }
}
fun Row.enableSubRowsIf(predicate: ComponentPredicate) {
subRowsEnabled = predicate()
predicate.addListener { subRowsEnabled = it }
}
@@ -125,11 +125,13 @@ tooltip.text.action.applicable.to.vcses=Applicable to: {0}
version.control.main.configurable.name=Version Control
action.name.show.difference=Show Difference
settings.filter.update.project.info.by.scope=Filter Update Project information by scope
settings.partial.changelists.enable.checkbox=Track changed blocks in text files separately
settings.show.conflict.resolve.dialog.checkbox=Show &dialog on attempt to edit file from non-active changelist
settings.partial.changelists.enable.checkbox=Allow &putting changes within one file into different changelists
settings.show.conflict.resolve.dialog.checkbox=Show &dialog on attempt to edit file from inactive changelist
settings.highlight.files.with.conflicts.checkbox=&Highlight files with changelist conflicts
settings.highlight.files.from.non.active.changelist.checkbox=Highlight files from &non-active changelists
settings.highlight.files.from.non.active.changelist.checkbox=Highlight files from &inactive changelists
settings.files.with.ignored.conflicts.list.title=Files with ignored conflicts:
settings.inactive.changelist.group.title=Inactive Changelist
settings.changelist.conflicts.group.title=Conflicts
#file view
action.name.show.files.as.tree=Show as Tree
label.selected.revision.commit.message=Commit Message
@@ -1,89 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.openapi.vcs.changes.conflicts.ChangelistConflictConfigurable">
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="854" height="412"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<vspacer id="523f5">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="10c41" class="javax.swing.JCheckBox" binding="myEnablePartialChangelists">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/VcsBundle" key="settings.partial.changelists.enable.checkbox"/>
</properties>
</component>
<component id="6646a" class="javax.swing.JCheckBox" binding="myShowDialogCheckBox">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/VcsBundle" key="settings.show.conflict.resolve.dialog.checkbox"/>
</properties>
</component>
<component id="644ea" class="javax.swing.JCheckBox" binding="myHighlightConflictsCheckBox">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/VcsBundle" key="settings.highlight.files.with.conflicts.checkbox"/>
</properties>
</component>
<component id="6b1a6" class="javax.swing.JCheckBox" binding="myHighlightNonActiveCheckBox">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/VcsBundle" key="settings.highlight.files.from.non.active.changelist.checkbox"/>
</properties>
</component>
<grid id="722" binding="myIgnoredFilesPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
</clientProperties>
<border type="none"/>
<children>
<scrollpane id="66692" class="com.intellij.ui.components.JBScrollPane">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="5cdb5" class="com.intellij.ui.components.JBList" binding="myIgnoredFiles">
<constraints/>
<properties/>
</component>
</children>
</scrollpane>
<component id="9276f" class="javax.swing.JButton" binding="myClearButton" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/VcsBundle" key="button.clear"/>
</properties>
</component>
<hspacer id="61e54">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</children>
</grid>
</form>
@@ -1,149 +0,0 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vcs.changes.conflicts;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.binding.BindControl;
import com.intellij.openapi.options.binding.BindableConfigurable;
import com.intellij.openapi.options.binding.ControlBinder;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.VcsApplicationSettings;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.ChangeListUtil;
import com.intellij.openapi.vcs.impl.LineStatusTrackerSettingListener;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.components.JBList;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
/**
* @author Dmitry Avdeev
*/
public class ChangelistConflictConfigurable extends BindableConfigurable implements SearchableConfigurable, Configurable.NoScroll {
private JPanel myPanel;
@BindControl("SHOW_DIALOG")
private JCheckBox myShowDialogCheckBox;
@BindControl("HIGHLIGHT_CONFLICTS")
private JCheckBox myHighlightConflictsCheckBox;
@BindControl("HIGHLIGHT_NON_ACTIVE_CHANGELIST")
private JCheckBox myHighlightNonActiveCheckBox;
private JBList myIgnoredFiles;
private JButton myClearButton;
private JCheckBox myEnablePartialChangelists;
private JPanel myIgnoredFilesPanel;
private boolean myIgnoredFilesCleared;
private final ChangelistConflictTracker myConflictTracker;
private final VcsApplicationSettings myVcsApplicationSettings;
@Nullable
private Disposable myDisposable;
public ChangelistConflictConfigurable(Project project) {
this(ChangelistConflictTracker.getInstance(project));
}
public ChangelistConflictConfigurable(ChangelistConflictTracker conflictTracker) {
super(new ControlBinder(conflictTracker.getOptions()));
myVcsApplicationSettings = VcsApplicationSettings.getInstance();
myConflictTracker = conflictTracker;
myClearButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myIgnoredFiles.setModel(new DefaultListModel());
myIgnoredFilesCleared = true;
myClearButton.setEnabled(false);
}
});
myIgnoredFilesPanel.setBorder(IdeBorderFactory.createTitledBorder(VcsBundle.message("settings.files.with.ignored.conflicts.list.title"), false,
JBUI.insetsTop(8)).setShowLine(false));
myIgnoredFiles.getEmptyText().setText(VcsBundle.message("no.ignored.files"));
}
@Override
public JComponent createComponent() {
getBinder().bindAnnotations(this);
SwingUtilities.updateComponentTreeUI(myPanel); // TODO: create Swing components in this method (see javadoc)
myDisposable = Disposer.newDisposable("Changelist Conflict Configurable");
ChangeListUtil.onChangeListAvailabilityChanged(myConflictTracker.getProject(), myDisposable, true, () -> {
UIUtil.setEnabled(myPanel, ChangeListManager.getInstance(myConflictTracker.getProject()).areChangeListsEnabled(), true);
});
return myPanel;
}
@Override
public void reset() {
super.reset();
myEnablePartialChangelists.setSelected(myVcsApplicationSettings.ENABLE_PARTIAL_CHANGELISTS);
Collection<String> conflicts = myConflictTracker.getIgnoredConflicts();
myIgnoredFiles.setListData(ArrayUtilRt.toStringArray(conflicts));
myClearButton.setEnabled(!conflicts.isEmpty());
}
@Override
public void apply() throws ConfigurationException {
super.apply();
if (myIgnoredFilesCleared) {
for (ChangelistConflictTracker.Conflict conflict : myConflictTracker.getConflicts().values()) {
conflict.ignored = false;
}
}
if (myEnablePartialChangelists.isSelected() != myVcsApplicationSettings.ENABLE_PARTIAL_CHANGELISTS) {
myVcsApplicationSettings.ENABLE_PARTIAL_CHANGELISTS = myEnablePartialChangelists.isSelected();
ApplicationManager.getApplication().getMessageBus().syncPublisher(LineStatusTrackerSettingListener.TOPIC).settingsUpdated();
}
myConflictTracker.optionsChanged();
}
@Override
public boolean isModified() {
return super.isModified() ||
myIgnoredFiles.getModel().getSize() != myConflictTracker.getIgnoredConflicts().size() ||
myEnablePartialChangelists.isSelected() != myVcsApplicationSettings.ENABLE_PARTIAL_CHANGELISTS;
}
@Override
public String getDisplayName() {
return VcsBundle.message("configurable.ChangelistConflictConfigurable.display.name");
}
@Override
public String getHelpTopic() {
return "project.propVCSSupport.ChangelistConflict";
}
@Override
@NotNull
public String getId() {
return getHelpTopic();
}
@Override
public void disposeUIResources() {
if (myDisposable != null) Disposer.dispose(myDisposable);
myDisposable = null;
super.disposeUIResources();
}
}
@@ -0,0 +1,130 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vcs.changes.conflicts
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.options.BoundSearchableConfigurable
import com.intellij.openapi.options.Configurable.NoScroll
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.DialogPanel
import com.intellij.openapi.vcs.VcsApplicationSettings
import com.intellij.openapi.vcs.VcsBundle.message
import com.intellij.openapi.vcs.changes.ChangeListManager
import com.intellij.openapi.vcs.changes.onChangeListAvailabilityChanged
import com.intellij.openapi.vcs.impl.LineStatusTrackerSettingListener
import com.intellij.ui.components.JBList
import com.intellij.ui.layout.*
import javax.swing.DefaultListModel
import javax.swing.event.ListDataEvent
import javax.swing.event.ListDataListener
class ChangelistConflictConfigurable(val project: Project)
: BoundSearchableConfigurable(message("configurable.ChangelistConflictConfigurable.display.name"),
"project.propVCSSupport.ChangelistConflict"), NoScroll {
override fun createPanel(): DialogPanel {
val appSettings = VcsApplicationSettings.getInstance()
val conflictTracker = ChangelistConflictTracker.getInstance(project)
val conflictOptions = conflictTracker.options
val changeListsEnabledPredicate = ChangeListsEnabledPredicate(project, disposable!!)
return panel {
row {
enableIf(changeListsEnabledPredicate)
checkBox(message("settings.partial.changelists.enable.checkbox"), appSettings::ENABLE_PARTIAL_CHANGELISTS)
.onApply {
ApplicationManager.getApplication().messageBus.syncPublisher(LineStatusTrackerSettingListener.TOPIC).settingsUpdated()
}
}
titledRow(message("settings.inactive.changelist.group.title")) {
enableSubRowsIf(changeListsEnabledPredicate)
row {
checkBox(message("settings.highlight.files.from.non.active.changelist.checkbox"),
conflictOptions::HIGHLIGHT_NON_ACTIVE_CHANGELIST)
.onApply { conflictTracker.optionsChanged() }
}
row {
checkBox(message("settings.show.conflict.resolve.dialog.checkbox"), conflictOptions::SHOW_DIALOG)
.onApply { conflictTracker.optionsChanged() }
}
}
titledRow(message("settings.changelist.conflicts.group.title")) {
enableSubRowsIf(changeListsEnabledPredicate)
row {
checkBox(message("settings.highlight.files.with.conflicts.checkbox"), conflictOptions::HIGHLIGHT_CONFLICTS)
.onApply { conflictTracker.optionsChanged() }
}.largeGapAfter()
val ignoredFilesModel = DefaultListModel<String>()
row {
label(message("settings.files.with.ignored.conflicts.list.title"))
}
row {
val list = JBList(ignoredFilesModel).apply {
emptyText.text = message("no.ignored.files")
}
scrollPane(list)
.onReset {
ignoredFilesModel.clear()
for (path in conflictTracker.ignoredConflicts) {
ignoredFilesModel.addElement(path)
}
}
}
row {
right {
var shouldClear = false
button(message("button.clear")) {
shouldClear = true
ignoredFilesModel.clear()
}
.onIsModified { shouldClear }
.onReset { shouldClear = false }
.onApply {
if (shouldClear) {
for (conflict in conflictTracker.conflicts.values) {
conflict.ignored = false
}
shouldClear = false
}
}
.enableIf(ListNotEmptyPredicate(ignoredFilesModel))
}
}
}
}
}
class ChangeListsEnabledPredicate(val project: Project, val disposable: Disposable) : ComponentPredicate() {
override fun invoke(): Boolean = ChangeListManager.getInstance(project).areChangeListsEnabled()
override fun addListener(listener: (Boolean) -> Unit) {
onChangeListAvailabilityChanged(project, disposable, true) {
listener(invoke())
}
}
}
class ListNotEmptyPredicate(val listModel: DefaultListModel<*>) : ComponentPredicate() {
override fun invoke(): Boolean = !listModel.isEmpty
override fun addListener(listener: (Boolean) -> Unit) {
listModel.addListDataListener(object : ListDataListener {
override fun intervalAdded(e: ListDataEvent?) {
listener(invoke())
}
override fun intervalRemoved(e: ListDataEvent?) {
listener(invoke())
}
override fun contentsChanged(e: ListDataEvent?) {
listener(invoke())
}
})
}
}
}
@@ -4,6 +4,7 @@ package com.intellij.openapi.vcs.changes.conflicts;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.changes.Change;
@@ -44,11 +45,13 @@ public final class ChangelistConflictNotificationPanel extends EditorNotificatio
myTracker = tracker;
myFile = file;
final ChangeListManager manager = tracker.getChangeListManager();
Project project = myTracker.getProject();
ChangeListManager manager = tracker.getChangeListManager();
myChangeList = changeList;
myLabel.setText(VcsBundle.message("changes.file.from.non.active.changelist.is.modified"));
createActionLabel(VcsBundle.message("link.label.move.changes"), () -> ChangelistConflictResolution.MOVE.resolveConflict(myTracker.getProject(), myChangeList.getChanges(), myFile)).
setToolTipText(VcsBundle.message("changes.move.changes.to.active.change.list.name", manager.getDefaultChangeList().getName()));
createActionLabel(VcsBundle.message("link.label.move.changes"),
() -> ChangelistConflictResolution.MOVE.resolveConflict(project, myChangeList.getChanges(), myFile))
.setToolTipText(VcsBundle.message("changes.move.changes.to.active.change.list.name", manager.getDefaultChangeList().getName()));
createActionLabel(VcsBundle.message("link.label.switch.changelist"), () -> {
Change change = myTracker.getChangeListManager().getChange(myFile);
@@ -56,18 +59,17 @@ public final class ChangelistConflictNotificationPanel extends EditorNotificatio
Messages.showInfoMessage(VcsBundle.message("dialog.message.no.changes.for.this.file"), VcsBundle.message("dialog.title.message"));
}
else {
ChangelistConflictResolution.SWITCH.resolveConflict(myTracker.getProject(), Collections.singletonList(change), null);
ChangelistConflictResolution.SWITCH.resolveConflict(project, Collections.singletonList(change), null);
}
}).setToolTipText(VcsBundle.message("changes.set.active.changelist.to.change.list.name", myChangeList.getName()));
createActionLabel(VcsBundle.message("link.label.ignore"), () -> myTracker.ignoreConflict(myFile, true)).setToolTipText(
VcsBundle.message("changes.hide.this.notification"));
createActionLabel(VcsBundle.message("link.label.ignore"), () -> myTracker.ignoreConflict(myFile, true))
.setToolTipText(VcsBundle.message("changes.hide.this.notification"));
myLinksPanel.add(new InplaceButton(VcsBundle.message("tooltip.show.options.dialog"), AllIcons.General.Settings, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ShowSettingsUtil.getInstance().editConfigurable(myTracker.getProject(), new ChangelistConflictConfigurable(tracker));
ShowSettingsUtil.getInstance().editConfigurable(project, new ChangelistConflictConfigurable(project));
}
}));
}