bookmarks: factor out an apply_fn() helper to eliminate duplicate logic
[git-cola.git] / cola / widgets / bookmarks.py
blob26e9c1a2c07c52debb3a45d42b3c6ccb1d93ac5c
1 """Provides widgets related to bookmarks"""
3 from __future__ import division, absolute_import, unicode_literals
5 import os
7 from PyQt4 import QtCore
8 from PyQt4 import QtGui
9 from PyQt4.QtCore import SIGNAL
11 from cola import cmds
12 from cola import core
13 from cola import git
14 from cola import hotkeys
15 from cola import icons
16 from cola import qtutils
17 from cola import utils
18 from cola.i18n import N_
19 from cola.models import prefs
20 from cola.settings import Settings
21 from cola.widgets import defs
22 from cola.widgets import standard
25 BOOKMARKS = 0
26 RECENT_REPOS = 1
29 class BookmarksWidget(QtGui.QWidget):
31 def __init__(self, style=BOOKMARKS, parent=None):
32 QtGui.QWidget.__init__(self, parent)
34 self.style = style
35 self.settings = Settings()
36 self.tree = BookmarksTreeWidget(style, self.settings, parent=self)
38 self.add_button = qtutils.create_action_button(
39 tooltip=N_('Add'), icon=icons.add())
41 self.delete_button = qtutils.create_action_button(tooltip=N_('Delete'),
42 icon=icons.remove())
44 self.open_button = qtutils.create_action_button(tooltip=N_('Open'),
45 icon=icons.repo())
47 self.button_group = utils.Group(self.delete_button, self.open_button)
48 self.button_group.setEnabled(False)
50 self.setFocusProxy(self.tree)
51 if style == BOOKMARKS:
52 self.setToolTip(N_('Favorite repositories'))
53 elif style == RECENT_REPOS:
54 self.setToolTip(N_('Recent repositories'))
55 self.add_button.hide()
57 self.button_layout = qtutils.hbox(defs.no_margin, defs.spacing,
58 self.open_button, self.add_button,
59 self.delete_button)
61 self.main_layout = qtutils.vbox(defs.no_margin, defs.spacing, self.tree)
62 self.setLayout(self.main_layout)
64 self.corner_widget = QtGui.QWidget(self)
65 self.corner_widget.setLayout(self.button_layout)
66 titlebar = parent.titleBarWidget()
67 titlebar.add_corner_widget(self.corner_widget)
69 qtutils.connect_button(self.add_button, self.tree.add_bookmark)
70 qtutils.connect_button(self.delete_button, self.tree.delete_bookmark)
71 qtutils.connect_button(self.open_button, self.tree.open_repo)
73 self.connect(self.tree, SIGNAL('itemSelectionChanged()'),
74 self.tree_item_selection_changed)
76 QtCore.QTimer.singleShot(0, self.reload_bookmarks)
78 def reload_bookmarks(self):
79 # Called once after the GUI is initialized
80 self.settings.load()
81 self.tree.refresh()
83 def tree_item_selection_changed(self):
84 enabled = bool(self.tree.selected_item())
85 self.button_group.setEnabled(enabled)
88 class BookmarksTreeWidget(standard.TreeWidget):
90 def __init__(self, style, settings, parent=None):
91 standard.TreeWidget.__init__(self, parent=parent)
92 self.style = style
93 self.settings = settings
95 self.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
96 self.setHeaderHidden(True)
98 self.open_action = qtutils.add_action(self,
99 N_('Open'), self.open_repo, hotkeys.OPEN, *hotkeys.ACCEPT)
101 self.open_new_action = qtutils.add_action(self,
102 N_('Open in New Window'), self.open_new_repo, hotkeys.NEW)
104 self.open_default_action = qtutils.add_action(self,
105 cmds.OpenDefaultApp.name(), self.open_default,
106 hotkeys.PRIMARY_ACTION)
108 self.launch_editor_action = qtutils.add_action(self,
109 cmds.Edit.name(), self.launch_editor, hotkeys.EDIT)
111 self.launch_terminal_action = qtutils.add_action(self,
112 cmds.LaunchTerminal.name(), self.launch_terminal,
113 hotkeys.TERMINAL)
115 self.copy_action = qtutils.add_action(self,
116 N_('Copy'), self.copy, hotkeys.COPY)
118 self.connect(self, SIGNAL('itemSelectionChanged()'),
119 self.item_selection_changed)
121 self.connect(self, SIGNAL('itemDoubleClicked(QTreeWidgetItem*,int)'),
122 self.tree_double_clicked)
124 self.action_group = utils.Group(self.open_action,
125 self.open_new_action,
126 self.copy_action,
127 self.launch_editor_action,
128 self.launch_terminal_action,
129 self.open_default_action)
130 self.action_group.setEnabled(False)
132 def refresh(self):
133 icon = icons.folder()
134 settings = self.settings
136 # bookmarks
137 if self.style == BOOKMARKS:
138 items = [BookmarksTreeWidgetItem(path, icon)
139 for path in settings.bookmarks]
141 if prefs.sort_bookmarks():
142 items.sort()
143 elif self.style == RECENT_REPOS:
144 # recent items
145 items = [BookmarksTreeWidgetItem(path, icon)
146 for path in settings.recent]
147 else:
148 items = []
149 self.clear()
150 self.addTopLevelItems(items)
152 def contextMenuEvent(self, event):
153 menu = QtGui.QMenu(self)
154 menu.addAction(self.open_action)
155 menu.addAction(self.open_new_action)
156 menu.addAction(self.open_default_action)
157 menu.addSeparator()
158 menu.addAction(self.copy_action)
159 menu.addAction(self.launch_editor_action)
160 menu.addAction(self.launch_terminal_action)
161 menu.exec_(self.mapToGlobal(event.pos()))
163 def apply_fn(self, fn, *args, **kwargs):
164 item = self.selected_item()
165 if item:
166 fn(item, *args, **kwargs)
168 def copy(self):
169 self.apply_fn(lambda item: qtutils.set_clipboard(item.path))
171 def open_default(self):
172 self.apply_fn(lambda item: cmds.do(cmds.OpenDefaultApp, [item.path]))
174 def open_repo(self):
175 self.apply_fn(lambda item: cmds.do(cmds.OpenRepo, item.path))
177 def open_new_repo(self):
178 self.apply_fn(lambda item: cmds.do(cmds.OpenNewRepo, item.path))
180 def launch_editor(self):
181 self.apply_fn(lambda item: cmds.do(cmds.Edit, [item.path]))
183 def launch_terminal(self):
184 self.apply_fn(lambda item: cmds.do(cmds.LaunchTerminal, item.path))
186 def item_selection_changed(self):
187 enabled = bool(self.selected_item())
188 self.action_group.setEnabled(enabled)
190 def tree_double_clicked(self, item, column):
191 cmds.do(cmds.OpenRepo, item.path)
193 def add_bookmark(self):
194 path, ok = qtutils.prompt(N_('Path to git repository'),
195 title=N_('Enter Git Repository'),
196 text=core.getcwd())
197 if not ok:
198 return
199 normpath = utils.expandpath(path)
200 if git.is_git_worktree(normpath):
201 self.settings.add_bookmark(normpath)
202 self.settings.save()
203 self.refresh()
204 else:
205 qtutils.critical(N_('Error'),
206 N_('%s is not a Git repository.') % path)
208 def delete_bookmark(self):
209 """Removes a bookmark from the bookmarks list"""
210 item = self.selected_item()
211 if not item:
212 return
213 if self.style == BOOKMARKS:
214 cmd = cmds.RemoveBookmark
215 elif self.style == RECENT_REPOS:
216 cmd = cmds.RemoveRecent
217 else:
218 return
219 ok, status, out, err = cmds.do(cmd, self.settings, item.path,
220 icon=icons.discard())
221 if ok:
222 self.refresh()
225 class BookmarksTreeWidgetItem(QtGui.QTreeWidgetItem):
227 def __init__(self, path, icon):
228 QtGui.QTreeWidgetItem.__init__(self)
229 self.path = path
230 self.setIcon(0, icon)
231 normpath = os.path.normpath(path)
232 basename = os.path.basename(normpath)
233 self.setText(0, basename)
234 self.setToolTip(0, path)