1 from PyQt4
import QtCore
2 from PyQt4
import QtGui
3 from PyQt4
.QtCore
import Qt
4 from PyQt4
.QtCore
import SIGNAL
9 from cola
import qtutils
10 from cola
import gitcfg
11 from cola
.git
import git
12 from cola
.widgets
import defs
13 from cola
.widgets
import text
16 class RemoteEditor(QtGui
.QDialog
):
17 def __init__(self
, parent
):
18 super(RemoteEditor
, self
).__init
__(parent
)
20 self
.setWindowTitle('Edit Remotes')
21 self
.setWindowModality(Qt
.WindowModal
)
23 self
.default_hint
= (''
24 'You can add and remote remote git repositories\n'
25 'using the Add(+) and Delete(-) buttons on the left side.')
28 self
.remotes
= QtGui
.QListWidget()
29 self
.remotes
.setToolTip(self
.tr(
30 'Remote git repositories - double-click to rename'))
32 self
.info
= text
.HintedTextEdit(self
.default_hint
)
33 self
.info
.setReadOnly(True)
34 self
.info
.enable_hint(True)
35 self
.info
.setFont(prefs
.diff_font())
36 font
= self
.info
.font()
37 metrics
= QtGui
.QFontMetrics(font
)
38 width
= metrics
.width('_' * 72)
39 height
= metrics
.height() * 13
40 self
.info
.setMinimumWidth(width
)
41 self
.info
.setMinimumHeight(height
)
42 self
.info_thread
= RemoteInfoThread(self
)
44 self
.cfg
= gitcfg
.instance()
45 self
.add_btn
= QtGui
.QToolButton()
46 self
.add_btn
.setIcon(qtutils
.icon('add.svg'))
47 self
.add_btn
.setToolTip(self
.tr('Add new remote git repository'))
49 self
.refresh_btn
= QtGui
.QToolButton()
50 self
.refresh_btn
.setIcon(qtutils
.icon('view-refresh.svg'))
51 self
.refresh_btn
.setToolTip(self
.tr('Refresh'))
53 self
.delete_btn
= QtGui
.QToolButton()
54 self
.delete_btn
.setIcon(qtutils
.icon('remove.svg'))
55 self
.delete_btn
.setToolTip(self
.tr('Delete remote'))
57 self
.close_btn
= QtGui
.QPushButton(self
.tr('Close'))
59 self
._top
_layout
= QtGui
.QSplitter()
60 self
._top
_layout
.setOrientation(Qt
.Horizontal
)
61 self
._top
_layout
.setHandleWidth(defs
.handle_width
)
62 self
._top
_layout
.addWidget(self
.remotes
)
63 self
._top
_layout
.addWidget(self
.info
)
64 width
= self
._top
_layout
.width()
65 self
._top
_layout
.setSizes([width
/4, width
*3/4])
67 self
._button
_layout
= QtGui
.QHBoxLayout()
68 self
._button
_layout
.addWidget(self
.add_btn
)
69 self
._button
_layout
.addWidget(self
.delete_btn
)
70 self
._button
_layout
.addWidget(self
.refresh_btn
)
71 self
._button
_layout
.addStretch()
72 self
._button
_layout
.addWidget(self
.close_btn
)
74 self
._layout
= QtGui
.QVBoxLayout()
75 self
._layout
.setMargin(defs
.margin
)
76 self
._layout
.setSpacing(defs
.spacing
)
77 self
._layout
.addWidget(self
._top
_layout
)
78 self
._layout
.addLayout(self
._button
_layout
)
79 self
.setLayout(self
._layout
)
83 qtutils
.connect_button(self
.add_btn
, self
.add
)
84 qtutils
.connect_button(self
.delete_btn
, self
.delete
)
85 qtutils
.connect_button(self
.refresh_btn
, self
.refresh
)
86 qtutils
.connect_button(self
.close_btn
, self
.close
)
88 self
.connect(self
.info_thread
, SIGNAL('info'),
91 self
.connect(self
.remotes
,
92 SIGNAL('itemChanged(QListWidgetItem*)'),
95 self
.connect(self
.remotes
, SIGNAL('itemSelectionChanged()'),
96 self
.selection_changed
)
99 prefix
= len('remote.')
101 remote_urls
= self
.cfg
.find('remote.*.url')
102 remotes
= [k
[prefix
:-suffix
] for k
in sorted(remote_urls
.keys())]
104 self
.remotes
.addItems(remotes
)
105 self
.remote_list
= remotes
106 for idx
, r
in enumerate(remotes
):
107 item
= self
.remotes
.item(idx
)
108 item
.setFlags(item
.flags() | Qt
.ItemIsEditable
)
111 widget
= AddRemoteWidget(self
)
112 if not widget
.add_remote():
114 name
= widget
.name
.value()
115 url
= widget
.url
.value()
116 status
, out
= git
.remote('add', name
, url
,
117 with_status
=True, with_stderr
=True)
119 qtutils
.critical('Error creating remote "%s"' % name
, out
)
123 remote
= qtutils
.selected_item(self
.remotes
, self
.remote_list
)
127 title
= 'Delete Remote'
128 question
= 'Delete remote?'
129 info
= unicode(self
.tr('Delete remote "%s"')) % remote
131 if not qtutils
.confirm(title
, question
, info
, ok_btn
):
134 status
, out
= git
.remote('rm', remote
,
135 with_status
=True, with_stderr
=True)
137 qtutils
.critical('Error deleting remote "%s"' % remote
, out
)
138 cola
.model().update_status()
140 self
.info
.set_hint(self
.default_hint
)
141 self
.info
.enable_hint(True)
144 def remote_renamed(self
, item
):
145 idx
= self
.remotes
.row(item
)
148 if idx
>= len(self
.remote_list
):
151 old_name
= self
.remote_list
[idx
]
152 new_name
= unicode(item
.text())
153 if new_name
== old_name
:
156 item
.setText(old_name
)
159 title
= 'Rename Remote'
160 question
= 'Rename remote?'
161 info
= unicode(self
.tr(
162 'Rename remote "%s" to "%s"?')) % (old_name
, new_name
)
165 if qtutils
.confirm(title
, question
, info
, ok_btn
):
166 git
.remote('rename', old_name
, new_name
)
167 self
.remote_list
[idx
] = new_name
169 item
.setText(old_name
)
171 def selection_changed(self
):
172 remote
= qtutils
.selected_item(self
.remotes
, self
.remote_list
)
175 self
.info
.set_hint('Gathering info for "%s"...' % remote
)
176 self
.info
.enable_hint(True)
178 self
.info_thread
.remote
= remote
179 self
.info_thread
.start()
182 class RemoteInfoThread(QtCore
.QThread
):
183 def __init__(self
, parent
):
184 super(RemoteInfoThread
, self
).__init
__(parent
)
191 status
, out
= git
.remote('show', remote
,
192 with_stderr
=True, with_status
=True)
193 out
= core
.decode(out
)
194 # This call takes a long time and we may have selected a
195 # different remote...
196 if remote
== self
.remote
:
197 self
.emit(SIGNAL('info'), out
)
202 class AddRemoteWidget(QtGui
.QDialog
):
203 def __init__(self
, parent
):
204 super(AddRemoteWidget
, self
).__init
__(parent
)
205 self
.setWindowModality(Qt
.WindowModal
)
207 self
.add_btn
= QtGui
.QPushButton(self
.tr('Add Remote'))
208 self
.add_btn
.setIcon(qtutils
.apply_icon())
210 self
.cancel_btn
= QtGui
.QPushButton(self
.tr('Cancel'))
212 diff_font
= prefs
.diff_font()
213 metrics
= QtGui
.QFontMetrics(diff_font
)
216 widget
= text
.HintedLineEdit(hint
)
217 widget
.setFont(diff_font
)
218 widget
.enable_hint(True)
219 widget
.setMinimumWidth(metrics
.width('_' * 32))
222 self
.name
= lineedit('Name for the new remote')
223 self
.url
= lineedit('git://git.example.com/repo.git')
225 self
._form
= QtGui
.QFormLayout()
226 self
._form
.setMargin(defs
.margin
)
227 self
._form
.setSpacing(defs
.spacing
)
228 self
._form
.addRow(self
.tr('Name'), self
.name
)
229 self
._form
.addRow(self
.tr('URL'), self
.url
)
231 self
._btn
_layout
= QtGui
.QHBoxLayout()
232 self
._btn
_layout
.setMargin(0)
233 self
._btn
_layout
.setSpacing(defs
.button_spacing
)
234 self
._btn
_layout
.addStretch()
235 self
._btn
_layout
.addWidget(self
.add_btn
)
236 self
._btn
_layout
.addWidget(self
.cancel_btn
)
238 self
._layout
= QtGui
.QVBoxLayout()
239 self
._layout
.setMargin(defs
.margin
)
240 self
._layout
.setSpacing(defs
.margin
)
241 self
._layout
.addLayout(self
._form
)
242 self
._layout
.addLayout(self
._btn
_layout
)
243 self
.setLayout(self
._layout
)
245 self
.connect(self
.name
, SIGNAL('textChanged(QString)'),
248 self
.connect(self
.url
, SIGNAL('textChanged(QString)'),
251 self
.add_btn
.setEnabled(False)
253 qtutils
.connect_button(self
.add_btn
, self
.accept
)
254 qtutils
.connect_button(self
.cancel_btn
, self
.reject
)
256 def validate(self
, dummy_text
):
257 name
= self
.name
.value()
258 url
= self
.url
.value()
259 self
.add_btn
.setEnabled(bool(name
) and bool(url
))
261 def add_remote(self
):
264 return self
.exec_() == QtGui
.QDialog
.Accepted
268 window
= RemoteEditor(qtutils
.active_window())
274 if __name__
== '__main__':
275 app
= cola
.app
.ColaApplication([])