diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ui/VcsCloneComponentStub.kt b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/VcsCloneComponentStub.kt index 1fb0b99c13bc..ce72cac6175b 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/ui/VcsCloneComponentStub.kt +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/VcsCloneComponentStub.kt @@ -24,4 +24,6 @@ class VcsCloneComponentStub(private val checkoutProvider: CheckoutProvider, override fun isOkEnabled() = true override fun doValidateAll() = emptyList() + + override fun getOkButtonText() = primaryActionText } \ No newline at end of file diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogComponentStateListener.kt b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogComponentStateListener.kt new file mode 100644 index 000000000000..7676c4b98ea7 --- /dev/null +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogComponentStateListener.kt @@ -0,0 +1,15 @@ +// Copyright 2000-2019 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.ui.cloneDialog + +import java.util.* + +/** + * Informs the parent dialog about need to update its state regarding to the state of internal component + */ +interface VcsCloneDialogComponentStateListener : EventListener { + fun onOkActionNameChanged(name: String) + + fun onOkActionEnabled(enabled: Boolean) + + fun onListItemChanged() +} \ No newline at end of file diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtension.kt b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtension.kt index 617dc0ba4a17..a75e5402debb 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtension.kt +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtension.kt @@ -24,6 +24,16 @@ interface VcsCloneDialogExtension { */ fun getIcon(): Icon + /** + * Additional status lines, which may contain some info and actions related to authorized accounts, internal errors, etc + */ + fun getAdditionalStatusLines(): List = emptyList() + + /** + * Optional tooltip for extension item + */ + fun getTooltip(): String? = null + /** * Builds [VcsCloneDialogExtensionComponent] that would be displayed on center of get-from-vcs dialog when extension is selected. * Will be called lazily and once on first choosing of extension. diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtensionComponent.kt b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtensionComponent.kt index 47bd203b6165..dc834f0cb095 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtensionComponent.kt +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtensionComponent.kt @@ -1,7 +1,10 @@ // Copyright 2000-2019 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.ui.cloneDialog +import com.intellij.openapi.Disposable import com.intellij.openapi.ui.ValidationInfo +import com.intellij.util.EventDispatcher +import org.jetbrains.annotations.CalledInAwt import javax.swing.JComponent /** @@ -10,36 +13,51 @@ import javax.swing.JComponent * 1. Providing extension-specific UI for get-from-vcs dialog by [getView] * 2. handling commands that would be provided from top-level [com.intellij.openapi.ui.DialogWrapper] */ -interface VcsCloneDialogExtensionComponent { +abstract class VcsCloneDialogExtensionComponent : Disposable { + private val listeners = EventDispatcher.create(VcsCloneDialogComponentStateListener::class.java) + + protected val dialogStateListener = listeners.multicaster /** * Return main [JComponent] that will be displayed in center of get-from-vcs dialog when extension is selected. * * It is called once when extension is selected first time */ - fun getView(): JComponent + @CalledInAwt + abstract fun getView(): JComponent /** - * Checks that is possible to perform ok action in current state of component - * - * Would be called form [com.intellij.openapi.ui.DialogWrapper.isOKActionEnabled] when extension is selected + * Performs primary clone/checkout action. [doClone] is called from the UI-thread, but internal heavy clone task should be scheduled + * in background */ - fun isOkEnabled(): Boolean - - /** - * Perform primary clone/checkout action. - */ - fun doClone() + @CalledInAwt + abstract fun doClone() /** * would be called from [com.intellij.openapi.ui.DialogWrapper.doValidateAll] when extension is selected * * @see com.intellij.openapi.ui.DialogWrapper.doValidateAll */ - fun doValidateAll(): List + @CalledInAwt + abstract fun doValidateAll(): List /** - * Text that represents dialog primary action + * Adds listener that would be called from component in order to notify parent dialog about internal state + * + * @see VcsCloneDialogComponentStateListener */ - fun getOkButtonText(): String = "Clone" + @CalledInAwt + fun addComponentStateListener(componentStateListener: VcsCloneDialogComponentStateListener) { + listeners.addListener(componentStateListener) + } + + @CalledInAwt + fun removeComponentListener(componentStateListener: VcsCloneDialogComponentStateListener) { + listeners.removeListener(componentStateListener) + } + + @CalledInAwt + abstract fun onComponentSelected() + + final override fun dispose() = listeners.listeners.clear() } diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtensionStatusLine.kt b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtensionStatusLine.kt new file mode 100644 index 000000000000..82bcaac892fe --- /dev/null +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/ui/cloneDialog/VcsCloneDialogExtensionStatusLine.kt @@ -0,0 +1,16 @@ +// Copyright 2000-2019 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.ui.cloneDialog + +import com.intellij.ui.SimpleTextAttributes +import java.awt.event.ActionListener + +data class VcsCloneDialogExtensionStatusLine(val text: String, + val attribute: SimpleTextAttributes, + val actionListener: ActionListener? = null) { + + companion object { + fun greyText(text: String): VcsCloneDialogExtensionStatusLine { + return VcsCloneDialogExtensionStatusLine(text, SimpleTextAttributes.GRAY_ATTRIBUTES) + } + } +} \ No newline at end of file diff --git a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/RepositoryUrlCloneDialogExtension.kt b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/RepositoryUrlCloneDialogExtension.kt index f6c6ec798ea9..a7a18b0baaa2 100644 --- a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/RepositoryUrlCloneDialogExtension.kt +++ b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/RepositoryUrlCloneDialogExtension.kt @@ -12,8 +12,7 @@ import com.intellij.openapi.vcs.ui.cloneDialog.VcsCloneDialogExtension import com.intellij.openapi.vcs.ui.cloneDialog.VcsCloneDialogExtensionComponent import com.intellij.ui.SimpleListCellRenderer import com.intellij.ui.layout.* -import com.intellij.util.ui.JBUI -import com.intellij.util.ui.UIUtil +import com.intellij.util.ui.JBEmptyBorder import java.awt.BorderLayout import java.awt.CardLayout import java.awt.event.ItemEvent @@ -22,15 +21,28 @@ import javax.swing.Icon import javax.swing.JPanel class RepositoryUrlCloneDialogExtension : VcsCloneDialogExtension { + private val tooltip = CheckoutProvider.EXTENSION_POINT_NAME.extensions + .map { it.vcsName } + .joinToString { it.replace("_".toRegex(), "") } + override fun getIcon(): Icon = AllIcons.Welcome.FromVCS override fun getName() = "Repository URL" + override fun getTooltip(): String? { + return tooltip + } + override fun createMainComponent(project: Project): RepositoryUrlMainExtensionComponent { return RepositoryUrlMainExtensionComponent(project) } - class RepositoryUrlMainExtensionComponent(private val project: Project) : VcsCloneDialogExtensionComponent { + class RepositoryUrlMainExtensionComponent(private val project: Project) : VcsCloneDialogExtensionComponent() { + override fun onComponentSelected() { + dialogStateListener.onOkActionNameChanged(getCurrentVcsComponent()?.getOkButtonText() ?: "Clone") + dialogStateListener.onOkActionEnabled(true) + } + private val vcsComponents = HashMap() private val cardLayout = CardLayout() private val mainPanel = JPanel(BorderLayout()) @@ -39,7 +51,7 @@ class RepositoryUrlCloneDialogExtension : VcsCloneDialogExtension { } init { - mainPanel.border = JBUI.Borders.emptyRight(UIUtil.PANEL_REGULAR_INSETS.right) + mainPanel.border = JBEmptyBorder(VcsCloneDialogUiSpec.Components.rightInsets) val northPanel = panel { row("Version control:") { comboBox() } } @@ -51,6 +63,7 @@ class RepositoryUrlCloneDialogExtension : VcsCloneDialogExtension { comboBox.addItemListener { e: ItemEvent -> if (e.stateChange == ItemEvent.SELECTED) { val provider = e.item as CheckoutProvider + onComponentSelected() cardLayout.show(centerPanel, provider.vcsName) } } @@ -66,10 +79,6 @@ class RepositoryUrlCloneDialogExtension : VcsCloneDialogExtension { override fun getView() = mainPanel - override fun getOkButtonText(): String { - return getCurrentVcsComponent()?.getOkButtonText() ?: "Clone" - } - fun openForVcs(clazz: Class): RepositoryUrlMainExtensionComponent { comboBox.selectedItem = CheckoutProvider.EXTENSION_POINT_NAME.findExtension(clazz) return this @@ -80,10 +89,6 @@ class RepositoryUrlCloneDialogExtension : VcsCloneDialogExtension { getCurrentVcsComponent()?.doClone(project, listener) } - override fun isOkEnabled(): Boolean { - return getCurrentVcsComponent()?.isOkEnabled() ?: true - } - override fun doValidateAll(): List { return getCurrentVcsComponent()?.doValidateAll() ?: emptyList() } diff --git a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialog.kt b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialog.kt index d4e8ea4a10a7..3ce232710499 100644 --- a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialog.kt +++ b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialog.kt @@ -2,21 +2,17 @@ package com.intellij.util.ui.cloneDialog import com.intellij.openapi.project.Project +import com.intellij.openapi.rd.attachChild import com.intellij.openapi.ui.DialogWrapper import com.intellij.openapi.ui.ValidationInfo import com.intellij.openapi.vcs.CheckoutProvider +import com.intellij.openapi.vcs.ui.cloneDialog.VcsCloneDialogComponentStateListener import com.intellij.openapi.vcs.ui.cloneDialog.VcsCloneDialogExtension import com.intellij.openapi.vcs.ui.cloneDialog.VcsCloneDialogExtensionComponent import com.intellij.openapi.wm.impl.welcomeScreen.FlatWelcomeFrame -import com.intellij.openapi.wm.impl.welcomeScreen.FlatWelcomeFrame.getSeparatorColor -import com.intellij.ui.CollectionListModel -import com.intellij.ui.ScrollPaneFactory -import com.intellij.ui.ScrollingUtil -import com.intellij.ui.border.CustomLineBorder +import com.intellij.ui.* import com.intellij.util.ui.JBEmptyBorder -import com.intellij.util.ui.JBInsets import com.intellij.util.ui.JBUI -import com.intellij.util.ui.UIUtil import com.intellij.util.ui.cloneDialog.RepositoryUrlCloneDialogExtension.RepositoryUrlMainExtensionComponent import java.awt.CardLayout import java.util.* @@ -35,6 +31,20 @@ internal class VcsCloneDialog private constructor(private val project: Project, private val cardLayout = CardLayout() private val mainPanel = JPanel(cardLayout) private val extensionComponents: MutableMap = HashMap() + private val listModel = CollectionListModel(VcsCloneDialogExtension.EP_NAME.extensionList) + + private val listener = object : VcsCloneDialogComponentStateListener { + override fun onOkActionNameChanged(name: String) = setOKButtonText(name) + + override fun onOkActionEnabled(enabled: Boolean) { + isOKActionEnabled = enabled + } + + override fun onListItemChanged() { + listModel.allContentsChanged() + pack() + } + } init { init() @@ -44,11 +54,7 @@ internal class VcsCloneDialog private constructor(private val project: Project, rootPane.preferredSize = it } - val withoutRightInset = UIUtil.PANEL_REGULAR_INSETS.let { - // use empty right inset to align the scroll bar to the edge of panel - JBInsets(it.top, it.left, it.bottom, 0) - } - mainPanel.border = JBEmptyBorder(withoutRightInset) + mainPanel.border = JBEmptyBorder(VcsCloneDialogUiSpec.Dialog.mainComponentParentInsets) VcsCloneDialogExtension.EP_NAME.findExtension(initialExtensionClass)?.let { ScrollingUtil.selectItem(extensionList, it) @@ -58,9 +64,6 @@ internal class VcsCloneDialog private constructor(private val project: Project, override fun getStyle() = DialogStyle.COMPACT override fun createCenterPanel(): JComponent { - val extensions = VcsCloneDialogExtension.EP_NAME.extensionList - val listModel = CollectionListModel(extensions) - extensionList = VcsCloneDialogExtensionList(listModel).apply { addListSelectionListener(ListSelectionListener { e -> val source = e.source as VcsCloneDialogExtensionList @@ -68,19 +71,14 @@ internal class VcsCloneDialog private constructor(private val project: Project, }) } val scrollableList = ScrollPaneFactory.createScrollPane(extensionList, true).apply { - border = CustomLineBorder(getSeparatorColor(), JBUI.insetsRight(1)) + + border = IdeBorderFactory.createBorder(SideBorder.RIGHT) } return JBUI.Panels.simplePanel() .addToCenter(mainPanel) - .addToLeft(scrollableList).apply { - border = CustomLineBorder(getSeparatorColor(), JBUI.insetsBottom(1)) - } + .addToLeft(scrollableList) } - override fun isOKActionEnabled(): Boolean { - return getSelectedComponent()?.isOkEnabled() ?: false - } - override fun doValidateAll(): List { return getSelectedComponent()?.doValidateAll() ?: emptyList() } @@ -97,13 +95,15 @@ internal class VcsCloneDialog private constructor(private val project: Project, scrollableMainPanel.verticalScrollBarPolicy = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED scrollableMainPanel.horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER mainPanel.add(scrollableMainPanel, extensionId) + disposable.attachChild(component) + component.addComponentStateListener(listener) component }) - setOKButtonText(mainComponent.getOkButtonText()) if (mainComponent is RepositoryUrlMainExtensionComponent) { initialVcs?.let { mainComponent.openForVcs(it) } } + mainComponent.onComponentSelected() cardLayout.show(mainPanel, extensionId) } diff --git a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogExtensionList.kt b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogExtensionList.kt index 6417d035e5aa..9f0087aeb9fc 100644 --- a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogExtensionList.kt +++ b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogExtensionList.kt @@ -8,39 +8,35 @@ import com.intellij.ui.components.JBList import com.intellij.util.ui.ListUiUtil import com.intellij.util.ui.UIUtil import java.awt.Component -import java.awt.FlowLayout -import javax.swing.* -import javax.swing.border.EmptyBorder +import javax.swing.JList +import javax.swing.ListCellRenderer +import javax.swing.ListModel class VcsCloneDialogExtensionList(listModel: ListModel) : JBList(listModel) { init { selectionModel = SingleSelectionModel() - cellRenderer = Renderer() + val renderer = Renderer() + cellRenderer = renderer + UIUtil.putClientProperty(this, UIUtil.NOT_IN_HIERARCHY_COMPONENTS, listOf(renderer)) ScrollingUtil.installActions(this) } - class Renderer : ListCellRenderer { - val component = VcsCloneDialogExtensionListItem - val wrapper: JComponent - - init { - wrapper = JPanel(FlowLayout(FlowLayout.LEADING)).apply { - border = EmptyBorder(UIUtil.PANEL_REGULAR_INSETS) - add(component) - } - } - + class Renderer + : ListCellRenderer, + VcsCloneDialogExtensionListItem() { override fun getListCellRendererComponent(list: JList, - value: VcsCloneDialogExtension, + extension: VcsCloneDialogExtension, index: Int, isSelected: Boolean, cellHasFocus: Boolean): Component { - component.setTitle(value.getName()) - component.setTitleForeground(ListUiUtil.WithTallRow.foreground(list, isSelected)) - component.setIcon(value.getIcon()) - UIUtil.setBackgroundRecursively(wrapper, ListUiUtil.WithTallRow.background(list, isSelected)) - return wrapper + setTitle(extension.getName()) + setTitleForeground(ListUiUtil.WithTallRow.foreground(list, isSelected)) + setIcon(extension.getIcon()) + toolTipText = extension.getTooltip() + setAdditionalStatusLines(extension.getAdditionalStatusLines()) + UIUtil.setBackgroundRecursively(this, ListUiUtil.WithTallRow.background(list, isSelected)) + return this } } } diff --git a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogExtensionListItem.kt b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogExtensionListItem.kt index 3598996f7fa3..ed3fdae3b161 100644 --- a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogExtensionListItem.kt +++ b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogExtensionListItem.kt @@ -1,37 +1,51 @@ // Copyright 2000-2019 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.util.ui.cloneDialog +import com.intellij.openapi.vcs.ui.cloneDialog.VcsCloneDialogExtensionStatusLine +import com.intellij.ui.SimpleColoredComponent +import com.intellij.ui.components.panels.VerticalLayout import com.intellij.util.IconUtil import com.intellij.util.ui.GridBag +import com.intellij.util.ui.JBEmptyBorder import com.intellij.util.ui.JBUI -import com.intellij.util.ui.UIUtil import java.awt.Color import java.awt.GridBagLayout import javax.swing.Icon -import javax.swing.JComponent import javax.swing.JLabel +import javax.swing.JPanel +import javax.swing.SwingConstants - -object VcsCloneDialogExtensionListItem : JComponent() { - +open class VcsCloneDialogExtensionListItem : JPanel(GridBagLayout()) { private val iconLabel: JLabel = JLabel() private val titleLabel: JLabel = JLabel() - init { - layout = GridBagLayout() + private val labelsPool = ArrayList() + private val additionalLinesPanel = JPanel(VerticalLayout(0, SwingConstants.LEFT)) - var gbc = GridBag().next() - .insetRight(UIUtil.DEFAULT_VGAP) + init { + border = JBEmptyBorder(VcsCloneDialogUiSpec.ExtensionsList.insets) + relayout() + } + + private fun relayout() { + var gbc = GridBag().nextLine().next() + .insets(JBUI.insetsRight(VcsCloneDialogUiSpec.ExtensionsList.iconTitleGap)) + .weightx(0.0) .anchor(GridBag.LINE_START) .fillCellNone() add(iconLabel, gbc) gbc = gbc.next() + .weightx(1.0) .insets(JBUI.emptyInsets()) - .anchor(GridBag.BELOW_BASELINE_LEADING) .fillCellHorizontally() titleLabel.font = JBUI.Fonts.label().asBold() add(titleLabel, gbc) + + gbc = gbc.nextLine().next().next() + .insets(JBUI.emptyInsets()) + .fillCellHorizontally() + add(additionalLinesPanel, gbc) } fun setTitle(title: String) { @@ -39,7 +53,24 @@ object VcsCloneDialogExtensionListItem : JComponent() { } fun setIcon(icon: Icon) { - iconLabel.icon = IconUtil.scale(icon, null, 22.0f/icon.iconHeight) // scale is chosen so that the size of icon corresponds the design + val scale = VcsCloneDialogUiSpec.ExtensionsList.iconSize.float / icon.iconWidth + iconLabel.icon = IconUtil.scale(icon, null, scale) + } + + fun setAdditionalStatusLines(additionalLines: List) { + additionalLinesPanel.removeAll() + while (labelsPool.size < additionalLines.size) { + labelsPool.add(SimpleColoredComponent()) + } + + for ((index, line) in additionalLines.withIndex()) { + val component = labelsPool[index] + component.ipad = JBUI.insets(0, 0) + component.clear() + // TODO: add handling for long text lines + component.append(line.text, line.attribute, line.actionListener) + additionalLinesPanel.add(component) + } } fun setTitleForeground(foreground: Color) { diff --git a/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogUiSpec.kt b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogUiSpec.kt new file mode 100644 index 000000000000..3340a031e464 --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/util/ui/cloneDialog/VcsCloneDialogUiSpec.kt @@ -0,0 +1,30 @@ +// Copyright 2000-2019 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.util.ui.cloneDialog + +import com.intellij.util.ui.JBInsets +import com.intellij.util.ui.JBUI +import com.intellij.util.ui.JBValue +import com.intellij.util.ui.UIUtil + +/** + * Contains a lot of UI specific constants for clone dialog that can be helpful for external implementations. + */ +object VcsCloneDialogUiSpec { + object Dialog { + val mainComponentParentInsets = UIUtil.PANEL_REGULAR_INSETS.let { + // use empty right inset to align the scroll bar to the edge of panel + JBInsets(it.top, it.left, it.bottom, 0) + } + } + + object ExtensionsList { + val iconSize = JBValue.UIInteger("VcsCloneDialog.iconSize", 22) + const val iconTitleGap = 6 + val insets = JBUI.insets(8, 10) + } + + object Components { + // insets for component without full-height scrollbar + val rightInsets = JBUI.insetsRight((UIUtil.PANEL_REGULAR_INSETS.right)) + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java index 67ef2d251e35..06221034f7ad 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkout/SvnCheckoutProvider.java @@ -16,6 +16,8 @@ import com.intellij.openapi.vcs.CheckoutProvider; import com.intellij.openapi.vcs.VcsConfiguration; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; +import com.intellij.openapi.vcs.ui.VcsCloneComponent; +import com.intellij.openapi.vcs.ui.VcsCloneComponentStub; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.StatusBar; @@ -339,4 +341,10 @@ public class SvnCheckoutProvider implements CheckoutProvider { return result; } } + + @NotNull + @Override + public VcsCloneComponent buildVcsCloneComponent(@NotNull Project project) { + return new VcsCloneComponentStub(this, "Checkout"); + } } \ No newline at end of file