widgets.remote: retain focus when showing remote messages
[git-cola.git] / cola / widgets / submodules.py
blobdf844e5dfa1dd9ca63f37dac841d42b5d89adfa6
1 """Provides widgets related to submodules"""
3 from qtpy import QtWidgets
4 from qtpy.QtCore import Qt
5 from qtpy.QtCore import Signal
7 from .. import cmds
8 from .. import compat
9 from .. import core
10 from .. import qtutils
11 from .. import icons
12 from ..i18n import N_
13 from ..widgets import defs
14 from ..widgets import standard
15 from ..widgets import text
18 def add_submodule(context, parent):
19 """Add a new submodule"""
20 dlg = AddSubmodule(parent)
21 dlg.show()
22 if dlg.exec_() == standard.Dialog.Accepted:
23 cmd = dlg.get(context)
24 cmd.do()
27 class SubmodulesWidget(QtWidgets.QFrame):
28 def __init__(self, context, parent):
29 super().__init__(parent)
30 self.context = context
31 self.setToolTip(N_('Submodules'))
33 self.tree = SubmodulesTreeWidget(context, parent=self)
34 self.setFocusProxy(self.tree)
36 self.main_layout = qtutils.vbox(defs.no_margin, defs.spacing, self.tree)
37 self.setLayout(self.main_layout)
39 # Titlebar buttons
40 self.add_button = qtutils.create_action_button(
41 tooltip=N_('Add Submodule'), icon=icons.add()
43 self.refresh_button = qtutils.create_action_button(
44 tooltip=N_('Refresh'), icon=icons.sync()
47 self.open_parent_button = qtutils.create_action_button(
48 tooltip=N_('Open Parent'), icon=icons.repo()
51 self.button_layout = qtutils.hbox(
52 defs.no_margin,
53 defs.spacing,
54 self.add_button,
55 self.open_parent_button,
56 self.refresh_button,
58 self.corner_widget = QtWidgets.QWidget(self)
59 self.corner_widget.setLayout(self.button_layout)
60 titlebar = parent.titleBarWidget()
61 titlebar.add_corner_widget(self.corner_widget)
63 # Connections
64 qtutils.connect_button(self.add_button, self.add_submodule)
65 qtutils.connect_button(self.refresh_button, self.tree.update_model.emit)
66 qtutils.connect_button(
67 self.open_parent_button, cmds.run(cmds.OpenParentRepo, context)
70 def add_submodule(self):
71 add_submodule(self.context, self)
74 class AddSubmodule(standard.Dialog):
75 """Add a new submodule"""
77 def __init__(self, parent):
78 super().__init__(parent=parent)
80 hint = N_('git://git.example.com/repo.git')
81 tooltip = N_('Submodule URL (can be relative, ex: ../repo.git)')
82 self.url_text = text.HintedDefaultLineEdit(hint, tooltip=tooltip, parent=self)
84 hint = N_('path/to/submodule')
85 tooltip = N_('Submodule path within the current repository (optional)')
86 self.path_text = text.HintedDefaultLineEdit(hint, tooltip=tooltip, parent=self)
88 hint = N_('Branch name')
89 tooltip = N_('Submodule branch to track (optional)')
90 self.branch_text = text.HintedDefaultLineEdit(
91 hint, tooltip=tooltip, parent=self
94 self.depth_spinbox = standard.SpinBox(
95 mini=0, maxi=compat.maxint, value=0, parent=self
97 self.depth_spinbox.setToolTip(
98 N_(
99 'Create a shallow clone with history truncated to the '
100 'specified number of revisions. 0 performs a full clone.'
104 hint = N_('Reference URL')
105 tooltip = N_('Reference repository to use when cloning (optional)')
106 self.reference_text = text.HintedDefaultLineEdit(
107 hint, tooltip=tooltip, parent=self
110 self.add_button = qtutils.ok_button(N_('Add Submodule'), enabled=False)
111 self.close_button = qtutils.close_button()
113 self.form_layout = qtutils.form(
114 defs.no_margin,
115 defs.button_spacing,
116 (N_('URL'), self.url_text),
117 (N_('Path'), self.path_text),
118 (N_('Branch'), self.branch_text),
119 (N_('Depth'), self.depth_spinbox),
120 (N_('Reference Repository'), self.reference_text),
122 self.button_layout = qtutils.hbox(
123 defs.no_margin,
124 defs.button_spacing,
125 qtutils.STRETCH,
126 self.close_button,
127 self.add_button,
130 self.main_layout = qtutils.vbox(
131 defs.large_margin, defs.spacing, self.form_layout, self.button_layout
133 self.setLayout(self.main_layout)
134 self.init_size(parent=qtutils.active_window())
135 # pylint: disable=no-member
136 self.url_text.textChanged.connect(lambda x: self._update_widgets())
137 qtutils.connect_button(self.add_button, self.accept)
138 qtutils.connect_button(self.close_button, self.close)
140 def _update_widgets(self):
141 value = self.url_text.value()
142 self.add_button.setEnabled(bool(value))
144 def get(self, context):
145 return cmds.SubmoduleAdd(
146 context,
147 self.url_text.value(),
148 self.path_text.value(),
149 self.branch_text.value(),
150 self.depth_spinbox.value(),
151 self.reference_text.value(),
155 # pylint: disable=too-many-ancestors
156 class SubmodulesTreeWidget(standard.TreeWidget):
157 update_model = Signal()
159 def __init__(self, context, parent=None):
160 standard.TreeWidget.__init__(self, parent=parent)
162 model = context.model
163 self.context = context
165 self.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
166 self.setHeaderHidden(True)
167 # UI
168 self._active = False
169 self.list_helper = BuildItem()
170 # Connections
171 # pylint: disable=no-member
172 self.itemDoubleClicked.connect(self.tree_double_clicked)
173 model.submodules_changed.connect(self.refresh, type=Qt.QueuedConnection)
174 self.update_model.connect(
175 model.update_submodules_list, type=Qt.QueuedConnection
178 def refresh(self):
179 if not self._active:
180 return
181 submodules = self.context.model.submodules_list
182 items = [self.list_helper.get(entry) for entry in submodules]
183 self.clear()
184 if items:
185 self.addTopLevelItems(items)
187 def showEvent(self, event):
188 """Defer updating widgets until the widget is visible"""
189 if not self._active:
190 self._active = True
191 self.update_model.emit()
192 return super().showEvent(event)
194 def tree_double_clicked(self, item, _column):
195 path = core.abspath(item.path)
196 cmds.do(cmds.OpenRepo, self.context, path)
199 class BuildItem:
200 def __init__(self):
201 self.state_folder_map = {}
202 self.state_folder_map[''] = icons.folder()
203 self.state_folder_map['+'] = icons.staged()
204 self.state_folder_map['-'] = icons.modified()
205 self.state_folder_map['U'] = icons.merge()
207 def get(self, entry):
208 """entry: same as returned from list_submodule"""
209 name = entry[2]
210 path = entry[2]
211 tip = path + '\n' + entry[1]
212 if entry[3]:
213 tip += f'\n({entry[3]})'
214 icon = self.state_folder_map[entry[0]]
215 return SubmodulesTreeWidgetItem(name, path, tip, icon)
218 class SubmodulesTreeWidgetItem(QtWidgets.QTreeWidgetItem):
219 def __init__(self, name, path, tip, icon):
220 QtWidgets.QTreeWidgetItem.__init__(self)
221 self.path = path
223 self.setIcon(0, icon)
224 self.setText(0, name)
225 self.setToolTip(0, tip)