diff --git a/platform/platform-impl/src/com/intellij/ui/layout/Row.kt b/platform/platform-impl/src/com/intellij/ui/layout/Row.kt index 623d5d6cc9d4..23006471ad3c 100644 --- a/platform/platform-impl/src/com/intellij/ui/layout/Row.kt +++ b/platform/platform-impl/src/com/intellij/ui/layout/Row.kt @@ -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 } +} diff --git a/platform/vcs-api/vcs-api-core/resources/messages/VcsBundle.properties b/platform/vcs-api/vcs-api-core/resources/messages/VcsBundle.properties index ec33e1d6e1ec..bc3fe3880e40 100644 --- a/platform/vcs-api/vcs-api-core/resources/messages/VcsBundle.properties +++ b/platform/vcs-api/vcs-api-core/resources/messages/VcsBundle.properties @@ -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 diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictConfigurable.form b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictConfigurable.form deleted file mode 100644 index 5ea9cd00f907..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictConfigurable.form +++ /dev/null @@ -1,89 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictConfigurable.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictConfigurable.java deleted file mode 100644 index 5a069357bbff..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictConfigurable.java +++ /dev/null @@ -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 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(); - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictConfigurable.kt b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictConfigurable.kt new file mode 100644 index 000000000000..76c24a2f7f91 --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictConfigurable.kt @@ -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() + 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()) + } + }) + } + } +} \ No newline at end of file diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationPanel.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationPanel.java index 52bcd5c42142..ef4a4e128f74 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationPanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/conflicts/ChangelistConflictNotificationPanel.java @@ -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)); } })); }