cola: completely rework the cola user interface
[git-cola.git] / cola / qtutils.py
blob8dcc8397354e3e126f3dd244621ef28278afa79d
1 # Copyright (c) 2008 David Aguilar
2 import os
3 from PyQt4 import QtCore
4 from PyQt4 import QtGui
5 from PyQt4.QtCore import Qt
6 from PyQt4.QtGui import QClipboard
7 from PyQt4.QtGui import QFileDialog
8 from PyQt4.QtGui import QIcon
9 from PyQt4.QtGui import QTreeWidget
10 from PyQt4.QtGui import QListWidgetItem
11 from PyQt4.QtGui import QTreeWidgetItem
12 from PyQt4.QtGui import QMessageBox
14 from cola import utils
16 LOGGER = None
18 def log(output, quiet=True, doraise=False):
19 if not LOGGER:
20 return
21 LOGGER.log(output)
22 if quiet:
23 return
24 LOGGER.show()
25 if not doraise:
26 return
27 raise_logger()
29 def raise_logger():
30 LOGGER.raise_()
32 def input(msg, title=None):
33 if title is None:
34 title = msg
35 parent = QtGui.qApp.activeWindow()
36 result = QtGui.QInputDialog.getText(parent, msg, title)
37 return (unicode(result[0]), result[1])
39 def close_log_window():
40 LOGGER.hide()
41 LOGGER.done(0)
43 def show_output(output, **kwargs):
44 if not output: return
45 log(output, quiet=False)
47 def toggle_log_window():
48 if not LOGGER: return
49 if LOGGER.isVisible():
50 LOGGER.hide()
51 else:
52 LOGGER.show()
53 LOGGER.raise_()
55 def create_listwidget_item(text, filename):
56 icon = QIcon(filename)
57 item = QListWidgetItem()
58 item.setIcon(icon)
59 item.setText(text)
60 return item
62 def create_treewidget_item(text, filename):
63 icon = QIcon(filename)
64 item = QTreeWidgetItem()
65 item.setIcon(0, icon)
66 item.setText(0, text)
67 return item
69 def information(title, message=None):
70 """Launches a QMessageBox information with the
71 provided title and message."""
72 if message is None:
73 message = title
74 QMessageBox.information(QtGui.qApp.activeWindow(), title, message)
76 def get_selected_treeitem(tree_widget):
77 """Returns a(id_number, is_selected) for a QTreeWidget."""
78 id_number = None
79 selected = False
80 item = tree_widget.currentItem()
81 if item:
82 id_number = item.data(0, Qt.UserRole).toInt()[0]
83 selected = True
84 return(id_number, selected)
86 def get_selected_row(list_widget):
87 """Returns a(row_number, is_selected) tuple for a QListWidget."""
88 row = list_widget.currentRow()
89 item = list_widget.item(row)
90 selected = item is not None and item.isSelected()
91 return(row, selected)
93 def get_selection_list(listwidget, items):
94 """Returns an array of model items that correspond to
95 the selected QListWidget indices."""
96 selected = []
97 itemcount = listwidget.count()
98 widgetitems = [ listwidget.item(idx) for idx in range(itemcount) ]
100 for item, widgetitem in zip(items, widgetitems):
101 if widgetitem.isSelected():
102 selected.append(item)
103 return selected
105 def get_tree_selection(treeitem, items):
106 """Returns an array of model items that correspond to
107 the selected QListWidget indices."""
108 selected = []
109 itemcount = treeitem.childCount()
110 widgetitems = [ treeitem.child(idx) for idx in range(itemcount) ]
112 for item, widgetitem in zip(items[:len(widgetitems)], widgetitems):
113 if widgetitem.isSelected():
114 selected.append(item)
115 return selected
117 def get_selected_item(list_widget, items):
118 row, selected = get_selected_row(list_widget)
119 if selected and row < len(items):
120 return items[row]
121 else:
122 return None
124 def open_dialog(parent, title, filename=None):
125 qstr = QFileDialog.getOpenFileName(parent, parent.tr(title), filename)
126 return unicode(qstr)
128 def opendir_dialog(parent, title, directory):
129 flags = QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontResolveSymlinks
130 qstr = QFileDialog.getExistingDirectory(parent, parent.tr(title),
131 directory,
132 flags)
133 return unicode(qstr)
135 def save_dialog(parent, title, filename=''):
136 return unicode(QFileDialog.getSaveFileName(parent,
137 parent.tr(title),
138 filename))
140 def new_dir_dialog(parent, title, filename=''):
141 return unicode(QFileDialog.getSaveFileName(parent,
142 parent.tr(title),
143 filename,
144 os.getcwd(),
145 parent.tr('New Directory ()')))
147 def dir_dialog(parent, title, directory):
148 directory = QFileDialog.getExistingDirectory(parent, parent.tr(title), directory)
149 return unicode(directory)
151 def get_icon(filename):
152 icon = utils.get_icon(filename)
153 return QIcon(icon)
155 def question(parent, title, message, default=True):
156 """Launches a QMessageBox question with the provided title and message.
157 Passing "default=False" will make "No" the default choice."""
158 yes = QMessageBox.Yes
159 no = QMessageBox.No
160 buttons = yes | no
161 if default:
162 default = yes
163 else:
164 default = no
165 result = QMessageBox.question(parent, title, message, buttons, default)
166 return result == QMessageBox.Yes
168 def set_clipboard(text):
169 QtGui.qApp.clipboard().setText(text, QClipboard.Clipboard)
170 QtGui.qApp.clipboard().setText(text, QClipboard.Selection)
172 def set_selected_item(widget, idx):
173 if type(widget) is QTreeWidget:
174 item = widget.topLevelItem(idx)
175 if item:
176 widget.setItemSelected(item, True)
177 widget.setCurrentItem(item)
179 def add_items(widget, items):
180 for item in items: widget.addItem(item)
182 def set_items(widget, items):
183 widget.clear()
184 add_items(widget, items)
186 def tr(txt):
187 return unicode(QtGui.qApp.translate('', txt))
189 def get_icon_file(filename, staged=False, untracked=False):
190 if staged:
191 if os.path.exists(filename.encode('utf-8')):
192 icon_file = utils.get_icon('staged.png')
193 else:
194 icon_file = utils.get_icon('removed.png')
195 elif untracked:
196 icon_file = utils.get_icon('untracked.png')
197 else:
198 icon_file = utils.get_file_icon(filename)
199 return icon_file
201 def get_icon_for_file(filename, staged=False, untracked=False):
202 icon_file = get_icon_file(filename, staged=staged, untracked=untracked)
203 return get_icon(icon_file)
205 def create_listitem(filename, staged=False, untracked=False):
206 """Given a filename, return a QListWidgetItem suitable
207 for adding to a QListWidget. "staged" and "untracked"
208 controls whether to use the appropriate icons."""
209 icon_file = get_icon_file(filename, staged, untracked)
210 return create_listwidget_item(filename, icon_file)
212 def create_treeitem(filename, staged=False, untracked=False):
213 """Given a filename, return a QListWidgetItem suitable
214 for adding to a QListWidget. "staged" and "untracked"
215 controls whether to use the appropriate icons."""
216 icon_file = get_icon_file(filename, staged=staged, untracked=untracked)
217 return create_treewidget_item(filename, icon_file)
220 def create_txt_item(txt):
221 item = QListWidgetItem()
222 item.setText(txt)
223 return item
225 def update_file_icons(widget, items, staged=True,
226 untracked=False, offset=0):
227 """Populate a QListWidget with custom icon items."""
228 for idx, model_item in enumerate(items):
229 item = widget.item(idx+offset)
230 if item:
231 item.setIcon(get_icon_for_file(model_item, staged, untracked))
233 def update_listwidget(widget, items, staged=True,
234 untracked=False, append=False):
235 """Populate a QListWidget with custom icon items."""
236 if not append:
237 widget.clear()
238 add_items(widget, [ create_listitem(i, staged, untracked) for i in items ])
240 def set_listwidget_strings(widget, items):
241 widget.clear()
242 add_items(widget, [ create_txt_item(i) for i in items ])