widgets: refactor DAG diff widgets to widgets.diff
[git-cola.git] / cola / stash / view.py
blob894ea2e70e11df736d8d987e14907e03e1f60ccd
1 """Provides the StashView dialog."""
3 from PyQt4 import QtCore
4 from PyQt4 import QtGui
5 from PyQt4.QtCore import SIGNAL
7 from cola import cmds
8 from cola import qt
9 from cola import qtutils
10 from cola import utils
11 from cola.i18n import N_
12 from cola.stash.model import ApplyStash, SaveStash, DropStash
13 from cola.widgets import defs
14 from cola.widgets.diff import DiffTextEdit
15 from cola.widgets.standard import Dialog
18 class StashView(Dialog):
19 def __init__(self, model, parent=None):
20 Dialog.__init__(self, parent=parent)
21 self.setAttribute(QtCore.Qt.WA_MacMetalStyle)
22 self.model = model
23 self.stashes = []
24 self.revids = []
25 self.names = []
27 self.setWindowModality(QtCore.Qt.WindowModal)
28 self.setWindowTitle(N_('Stash'))
29 if parent:
30 self.resize(parent.width(), 420)
31 else:
32 self.resize(700, 420)
34 self.stash_list = QtGui.QListWidget(self)
35 self.stash_text = DiffTextEdit(self)
37 self.button_apply =\
38 self.toolbutton(N_('Apply'),
39 N_('Apply the selected stash'),
40 qtutils.apply_icon())
41 self.button_save =\
42 self.toolbutton(N_('Save'),
43 N_('Save modified state to new stash'),
44 qtutils.save_icon())
45 self.button_drop = \
46 self.toolbutton(N_('Drop'),
47 N_('Drop the selected stash'),
48 qtutils.discard_icon())
49 self.button_close = \
50 self.pushbutton(N_('Close'),
51 N_('Close'), qtutils.close_icon())
53 self.keep_index = QtGui.QCheckBox(self)
54 self.keep_index.setText(N_('Keep Index'))
55 self.keep_index.setChecked(True)
57 # Arrange layouts
58 self.main_layt = QtGui.QVBoxLayout()
59 self.main_layt.setMargin(defs.margin)
60 self.main_layt.setSpacing(defs.spacing)
62 self.btn_layt = QtGui.QHBoxLayout()
63 self.btn_layt.setMargin(0)
64 self.btn_layt.setSpacing(defs.spacing)
66 self.splitter = QtGui.QSplitter()
67 self.splitter.setHandleWidth(defs.handle_width)
68 self.splitter.setOrientation(QtCore.Qt.Horizontal)
69 self.splitter.setChildrenCollapsible(True)
70 self.splitter.setStretchFactor(0, 1)
71 self.splitter.setStretchFactor(1, 1)
72 self.splitter.insertWidget(0, self.stash_list)
73 self.splitter.insertWidget(1, self.stash_text)
75 self.btn_layt.addWidget(self.button_save)
76 self.btn_layt.addWidget(self.button_apply)
77 self.btn_layt.addWidget(self.button_drop)
78 self.btn_layt.addWidget(self.keep_index)
79 self.btn_layt.addStretch()
80 self.btn_layt.addWidget(self.button_close)
82 self.main_layt.addWidget(self.splitter)
83 self.main_layt.addLayout(self.btn_layt)
84 self.setLayout(self.main_layt)
86 self.splitter.setSizes([self.width()/3, self.width()*2/3])
88 self.update_from_model()
89 self.update_actions()
91 self.setTabOrder(self.button_save, self.button_apply)
92 self.setTabOrder(self.button_apply, self.button_drop)
93 self.setTabOrder(self.button_drop, self.keep_index)
94 self.setTabOrder(self.keep_index, self.button_close)
96 self.connect(self.stash_list, SIGNAL('itemSelectionChanged()'),
97 self.item_selected)
99 qtutils.connect_button(self.button_apply, self.stash_apply)
100 qtutils.connect_button(self.button_save, self.stash_save)
101 qtutils.connect_button(self.button_drop, self.stash_drop)
102 qtutils.connect_button(self.button_close, self.close)
104 def close(self):
105 self.accept()
106 cmds.do(cmds.Rescan)
108 def toolbutton(self, text, tooltip, icon):
109 return qt.create_toolbutton(text=text, tooltip=tooltip, icon=icon)
111 def pushbutton(self, text, tooltip, icon):
112 btn = QtGui.QPushButton(self)
113 btn.setText(text)
114 btn.setToolTip(tooltip)
115 btn.setIcon(icon)
116 return btn
118 def selected_stash(self):
119 """Returns the stash name of the currently selected stash
121 list_widget = self.stash_list
122 stash_list = self.revids
123 return qtutils.selected_item(list_widget, stash_list)
125 def selected_name(self):
126 list_widget = self.stash_list
127 stash_list = self.names
128 return qtutils.selected_item(list_widget, stash_list)
130 def item_selected(self):
131 """Shows the current stash in the main view."""
132 self.update_actions()
133 selection = self.selected_stash()
134 if not selection:
135 return
136 diff_text = self.model.stash_diff(selection)
137 self.stash_text.setPlainText(diff_text)
139 def update_actions(self):
140 has_changes = self.model.has_stashable_changes()
141 has_stash = bool(self.selected_stash())
142 self.button_save.setEnabled(has_changes)
143 self.button_apply.setEnabled(has_stash)
144 self.button_drop.setEnabled(has_stash)
146 def update_from_model(self):
147 """Initiates git queries on the model and updates the view
149 stashes, revids, names = self.model.stash_info()
150 self.stashes = stashes
151 self.revids = revids
152 self.names = names
154 self.stash_list.clear()
155 self.stash_list.addItems(self.stashes)
157 def stash_apply(self):
158 """Applies the currently selected stash
160 selection = self.selected_stash()
161 if not selection:
162 return
163 index = self.keep_index.isChecked()
164 cmds.do(ApplyStash, selection, index)
165 self.accept()
166 cmds.do(cmds.Rescan)
168 def stash_save(self):
169 """Saves the worktree in a stash
171 This prompts the user for a stash name and creates
172 a git stash named accordingly.
175 stash_name, ok = qtutils.prompt(N_('Save Stash'),
176 N_('Enter a name for the stash'))
177 if not ok or not stash_name:
178 return
179 # Sanitize the stash name
180 stash_name = utils.sanitize(stash_name)
181 if stash_name in self.names:
182 qtutils.critical(N_('Error: Stash exists'),
183 N_('A stash named "%s" already exists') % stash_name)
184 return
186 keep_index = self.keep_index.isChecked()
187 cmds.do(SaveStash, stash_name, keep_index)
188 self.accept()
189 cmds.do(cmds.Rescan)
191 def stash_drop(self):
192 """Drops the currently selected stash
194 selection = self.selected_stash()
195 name = self.selected_name()
196 if not selection:
197 return
198 if not qtutils.confirm(N_('Drop Stash?'),
199 N_('Recovering a dropped stash is not possible.'),
200 N_('Drop the "%s" stash?') % name,
201 N_('Drop Stash'),
202 default=True,
203 icon=qtutils.discard_icon()):
204 return
205 cmds.do(DropStash, selection)
206 self.update_from_model()
207 self.stash_text.setPlainText('')