1 from PyQt4
import QtGui
2 from PyQt4
.QtCore
import Qt
3 from PyQt4
.QtCore
import SIGNAL
6 from cola
import gitcmds
7 from cola
import qtutils
8 from cola
.i18n
import N_
9 from cola
.models
import main
10 from cola
.widgets
import completion
11 from cola
.widgets
import defs
15 """Provides a dialog for merging branches"""
17 view
= MergeView(model
, qtutils
.active_window())
24 """Prompts before aborting a merge in progress
26 title
= N_('Abort Merge...')
27 txt
= N_('Aborting the current merge will cause '
28 '*ALL* uncommitted changes to be lost.\n'
29 'Recovering uncommitted changes is not possible.')
30 info_txt
= N_('Aborting the current merge?')
31 ok_txt
= N_('Abort Merge')
32 if qtutils
.confirm(title
, txt
, info_txt
, ok_txt
,
33 default
=False, icon
=qtutils
.icon('undo.svg')):
37 class MergeView(QtGui
.QDialog
):
38 """Provides a dialog for merging branches."""
40 def __init__(self
, model
, parent
=None):
41 QtGui
.QDialog
.__init
__(self
, parent
)
43 if parent
is not None:
44 self
.setWindowModality(Qt
.WindowModal
)
48 self
.title_label
= QtGui
.QLabel()
49 self
.revision_label
= QtGui
.QLabel()
50 self
.revision_label
.setText(N_('Revision To Merge'))
52 self
.revision
= completion
.GitRefLineEdit()
54 self
.radio_local
= QtGui
.QRadioButton()
55 self
.radio_local
.setText(N_('Local Branch'))
56 self
.radio_local
.setChecked(True)
57 self
.radio_remote
= QtGui
.QRadioButton()
58 self
.radio_remote
.setText(N_('Tracking Branch'))
59 self
.radio_tag
= QtGui
.QRadioButton()
60 self
.radio_tag
.setText(N_('Tag'))
62 self
.revisions
= QtGui
.QListWidget()
63 self
.revisions
.setAlternatingRowColors(True)
65 self
.button_viz
= QtGui
.QPushButton(self
)
66 self
.button_viz
.setText(N_('Visualize'))
68 self
.checkbox_squash
= QtGui
.QCheckBox(self
)
69 self
.checkbox_squash
.setText(N_('Squash'))
71 self
.checkbox_commit
= QtGui
.QCheckBox(self
)
72 self
.checkbox_commit
.setText(N_('Commit'))
73 self
.checkbox_commit
.setChecked(True)
74 self
.checkbox_commit_state
= True
76 self
.button_cancel
= QtGui
.QPushButton(self
)
77 self
.button_cancel
.setText(N_('Cancel'))
79 self
.button_merge
= QtGui
.QPushButton(self
)
80 self
.button_merge
.setText(N_('Merge'))
83 self
.revlayt
= QtGui
.QHBoxLayout()
84 self
.revlayt
.addWidget(self
.revision_label
)
85 self
.revlayt
.addWidget(self
.revision
)
86 self
.revlayt
.addStretch()
87 self
.revlayt
.addWidget(self
.title_label
)
89 self
.radiolayt
= QtGui
.QHBoxLayout()
90 self
.radiolayt
.addWidget(self
.radio_local
)
91 self
.radiolayt
.addWidget(self
.radio_remote
)
92 self
.radiolayt
.addWidget(self
.radio_tag
)
94 self
.buttonlayt
= QtGui
.QHBoxLayout()
95 self
.buttonlayt
.setSpacing(defs
.button_spacing
)
96 self
.buttonlayt
.addWidget(self
.button_viz
)
97 self
.buttonlayt
.addStretch()
98 self
.buttonlayt
.addWidget(self
.checkbox_squash
)
99 self
.buttonlayt
.addWidget(self
.checkbox_commit
)
100 self
.buttonlayt
.addWidget(self
.button_cancel
)
101 self
.buttonlayt
.addWidget(self
.button_merge
)
103 self
.mainlayt
= QtGui
.QVBoxLayout()
104 self
.mainlayt
.setMargin(defs
.margin
)
105 self
.mainlayt
.setSpacing(defs
.spacing
)
106 self
.mainlayt
.addLayout(self
.radiolayt
)
107 self
.mainlayt
.addWidget(self
.revisions
)
108 self
.mainlayt
.addLayout(self
.revlayt
)
109 self
.mainlayt
.addLayout(self
.buttonlayt
)
110 self
.setLayout(self
.mainlayt
)
112 self
.revision
.setFocus()
114 # Signal/slot connections
115 self
.connect(self
.revision
, SIGNAL('textChanged(QString)'),
118 self
.connect(self
.revisions
, SIGNAL('itemSelectionChanged()'),
119 self
.revision_selected
)
121 qtutils
.connect_button(self
.button_cancel
, self
.reject
)
122 qtutils
.connect_button(self
.checkbox_squash
, self
.toggle_squash
)
123 qtutils
.connect_button(self
.radio_local
, self
.update_revisions
)
124 qtutils
.connect_button(self
.radio_remote
, self
.update_revisions
)
125 qtutils
.connect_button(self
.radio_tag
, self
.update_revisions
)
126 qtutils
.connect_button(self
.button_merge
, self
.merge_revision
)
127 qtutils
.connect_button(self
.button_viz
, self
.viz_revision
)
130 model
.add_observer(model
.message_updated
, self
.update_all
)
133 def update_all(self
):
134 """Set the branch name for the window title and label."""
136 self
.update_revisions()
138 def update_title(self
, dummy_txt
=None):
139 branch
= self
.model
.currentbranch
140 revision
= unicode(self
.revision
.text())
142 txt
= (N_('Merge "%(revision)s" into "%(branch)s"') %
143 dict(revision
=revision
, branch
=branch
))
145 txt
= N_('Merge into "%s"') % branch
146 self
.title_label
.setText(txt
)
147 self
.setWindowTitle(txt
)
149 def toggle_squash(self
):
150 """Toggles the commit checkbox based on the squash checkbox."""
151 if self
.checkbox_squash
.isChecked():
152 self
.checkbox_commit_state
=\
153 self
.checkbox_commit
.checkState()
154 self
.checkbox_commit
.setCheckState(Qt
.Unchecked
)
155 self
.checkbox_commit
.setDisabled(True)
157 self
.checkbox_commit
.setDisabled(False)
158 oldstate
= self
.checkbox_commit_state
159 self
.checkbox_commit
.setCheckState(oldstate
)
161 def update_revisions(self
):
162 """Update the revision list whenever a radio button is clicked"""
163 self
.revisions
.clear()
164 self
.revisions
.addItems(self
.current_revisions())
166 def revision_selected(self
):
167 """Update the revision field when a list item is selected"""
168 revlist
= self
.current_revisions()
169 widget
= self
.revisions
170 row
, selected
= qtutils
.selected_row(widget
)
171 if selected
and row
< len(revlist
):
172 revision
= revlist
[row
]
173 self
.revision
.setText(revision
)
175 def current_revisions(self
):
176 """Retrieve candidate items to merge"""
177 if self
.radio_local
.isChecked():
178 return self
.model
.local_branches
179 elif self
.radio_remote
.isChecked():
180 return self
.model
.remote_branches
181 elif self
.radio_tag
.isChecked():
182 return self
.model
.tags
185 def viz_revision(self
):
186 """Launch a gitk-like viewer on the selection revision"""
187 revision
= unicode(self
.revision
.text())
189 qtutils
.information(N_('No Revision Specified'),
190 N_('You must specify a revision to view.'))
192 cmds
.do(cmds
.VisualizeRevision
, revision
)
194 def merge_revision(self
):
195 """Merge the selected revision/branch"""
196 revision
= unicode(self
.revision
.text())
198 qtutils
.information(N_('No Revision Specified'),
199 N_('You must specify a revision to merge.'))
202 do_commit
= self
.checkbox_commit
.isChecked()
203 squash
= self
.checkbox_squash
.isChecked()
204 cmds
.do(cmds
.Merge
, revision
, not(do_commit
), squash
)