~ubuntu-branches/ubuntu/vivid/git-cola/vivid

« back to all changes in this revision

Viewing changes to cola/widgets/main.py

  • Committer: Package Import Robot
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2014-02-14 13:13:33 UTC
  • mfrom: (1.3.22)
  • Revision ID: package-import@ubuntu.com-20140214131333-xbklb7yd9jntikpm
Tags: 1.9.4-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
from cola import settings
18
18
from cola import utils
19
19
from cola import version
20
 
from cola.bookmarks import manage_bookmarks
21
20
from cola.git import git
22
21
from cola.git import STDOUT
23
22
from cola.i18n import N_
29
28
from cola.qtutils import connect_action_bool
30
29
from cola.qtutils import create_dock
31
30
from cola.qtutils import create_menu
32
 
from cola.qtutils import create_toolbutton
33
 
from cola.qtutils import options_icon
34
31
from cola.widgets import action
35
32
from cola.widgets import cfgactions
36
33
from cola.widgets import editremotes
 
34
from cola.widgets import merge
37
35
from cola.widgets import remote
38
36
from cola.widgets.about import launch_about_dialog
39
37
from cola.widgets.about import show_shortcuts
40
38
from cola.widgets.archive import GitArchiveDialog
 
39
from cola.widgets.bookmarks import manage_bookmarks
 
40
from cola.widgets.bookmarks import BookmarksWidget
41
41
from cola.widgets.browse import worktree_browser
42
42
from cola.widgets.browse import worktree_browser_widget
43
43
from cola.widgets.commitmsg import CommitMessageEditor
46
46
from cola.widgets.createbranch import create_new_branch
47
47
from cola.widgets.dag import git_dag
48
48
from cola.widgets.diff import DiffEditor
 
49
from cola.widgets.grep import grep
49
50
from cola.widgets.log import LogWidget
50
 
from cola.widgets import merge
 
51
from cola.widgets.patch import apply_patches
51
52
from cola.widgets.prefs import preferences
52
 
from cola.widgets.recent import browse_recent
 
53
from cola.widgets.recent import browse_recent_files
53
54
from cola.widgets.status import StatusWidget
54
55
from cola.widgets.search import search
55
56
from cola.widgets.standard import MainWindow
60
61
 
61
62
    def __init__(self, model, parent=None):
62
63
        MainWindow.__init__(self, parent)
 
64
        self.setAttribute(Qt.WA_MacMetalStyle)
 
65
 
63
66
        # Default size; this is thrown out when save/restore is used
64
 
        self.resize(987, 610)
65
67
        self.model = model
66
68
        self.prefs_model = prefs_model = prefs.PreferencesModel()
67
69
 
72
74
        # Keeps track of merge messages we've seen
73
75
        self.merge_message_hash = ''
74
76
 
75
 
        self.setAcceptDrops(True)
76
 
        self.setAttribute(Qt.WA_MacMetalStyle)
77
 
 
78
77
        cfg = gitcfg.instance()
79
78
        self.browser_dockable = (cfg.get('cola.browserdockable') or
80
79
                                 cfg.get('cola.classicdockable'))
95
94
        self.statusdockwidget = create_dock(N_('Status'), self)
96
95
        self.statusdockwidget.setWidget(self.statuswidget)
97
96
 
 
97
        # "Switch Repository" widget
 
98
        self.bookmarksdockwidget = create_dock(N_('Bookmarks'), self)
 
99
        self.bookmarkswidget = BookmarksWidget(parent=self.bookmarksdockwidget)
 
100
        self.bookmarksdockwidget.setWidget(self.bookmarkswidget)
 
101
 
98
102
        # "Commit Message Editor" widget
99
103
        self.position_label = QtGui.QLabel()
100
104
        font = qtutils.default_monospace_font()
101
105
        font.setPointSize(int(font.pointSize() * 0.8))
102
106
        self.position_label.setFont(font)
 
107
 
 
108
        # make the position label fixed size to avoid layout issues
 
109
        fm = self.position_label.fontMetrics()
 
110
        width = fm.width('999:999')
 
111
        height = self.position_label.sizeHint().height()
 
112
        self.position_label.setFixedSize(width, height)
 
113
 
103
114
        self.commitdockwidget = create_dock(N_('Commit'), self)
104
115
        titlebar = self.commitdockwidget.titleBarWidget()
105
116
        titlebar.add_corner_widget(self.position_label)
119
130
        self.diffeditor = DiffEditor(self.diffdockwidget)
120
131
        self.diffdockwidget.setWidget(self.diffeditor)
121
132
 
122
 
        # "Diff Options" tool menu
123
 
        self.diff_ignore_space_at_eol_action = add_action(self,
124
 
                N_('Ignore changes in whitespace at EOL'),
125
 
                self._update_diff_opts)
126
 
        self.diff_ignore_space_at_eol_action.setCheckable(True)
127
 
 
128
 
        self.diff_ignore_space_change_action = add_action(self,
129
 
                N_('Ignore changes in amount of whitespace'),
130
 
                self._update_diff_opts)
131
 
        self.diff_ignore_space_change_action.setCheckable(True)
132
 
 
133
 
        self.diff_ignore_all_space_action = add_action(self,
134
 
                N_('Ignore all whitespace'),
135
 
                self._update_diff_opts)
136
 
        self.diff_ignore_all_space_action.setCheckable(True)
137
 
 
138
 
        self.diff_function_context_action = add_action(self,
139
 
                N_('Show whole surrounding functions of changes'),
140
 
                self._update_diff_opts)
141
 
        self.diff_function_context_action.setCheckable(True)
142
 
 
143
 
        self.diffopts_button = create_toolbutton(text=N_('Options'),
144
 
                                                 icon=options_icon(),
145
 
                                                 tooltip=N_('Diff Options'))
146
 
        self.diffopts_menu = create_menu(N_('Diff Options'),
147
 
                                         self.diffopts_button)
148
 
 
149
 
        self.diffopts_menu.addAction(self.diff_ignore_space_at_eol_action)
150
 
        self.diffopts_menu.addAction(self.diff_ignore_space_change_action)
151
 
        self.diffopts_menu.addAction(self.diff_ignore_all_space_action)
152
 
        self.diffopts_menu.addAction(self.diff_function_context_action)
153
 
        self.diffopts_button.setMenu(self.diffopts_menu)
154
 
        self.diffopts_button.setPopupMode(QtGui.QToolButton.InstantPopup)
155
 
 
156
 
        titlebar = self.diffdockwidget.titleBarWidget()
157
 
        titlebar.add_corner_widget(self.diffopts_button)
158
 
 
159
133
        # All Actions
160
 
        self.menu_unstage_all = add_action(self,
 
134
        self.unstage_all_action = add_action(self,
161
135
                N_('Unstage All'), cmds.run(cmds.UnstageAll))
162
 
        self.menu_unstage_all.setIcon(qtutils.icon('remove.svg'))
 
136
        self.unstage_all_action.setIcon(qtutils.icon('remove.svg'))
163
137
 
164
 
        self.menu_unstage_selected = add_action(self,
 
138
        self.unstage_selected_action = add_action(self,
165
139
                N_('Unstage From Commit'), cmds.run(cmds.UnstageSelected))
166
 
        self.menu_unstage_selected.setIcon(qtutils.icon('remove.svg'))
 
140
        self.unstage_selected_action.setIcon(qtutils.icon('remove.svg'))
167
141
 
168
 
        self.menu_show_diffstat = add_action(self,
 
142
        self.show_diffstat_action = add_action(self,
169
143
                N_('Diffstat'), cmds.run(cmds.Diffstat), 'Alt+D')
170
144
 
171
 
        self.menu_stage_modified = add_action(self,
 
145
        self.stage_modified_action = add_action(self,
172
146
                N_('Stage Changed Files To Commit'),
173
147
                cmds.run(cmds.StageModified), 'Alt+A')
174
 
        self.menu_stage_modified.setIcon(qtutils.icon('add.svg'))
 
148
        self.stage_modified_action.setIcon(qtutils.icon('add.svg'))
175
149
 
176
 
        self.menu_stage_untracked = add_action(self,
 
150
        self.stage_untracked_action = add_action(self,
177
151
                N_('Stage All Untracked'),
178
152
                cmds.run(cmds.StageUntracked), 'Alt+U')
179
 
        self.menu_stage_untracked.setIcon(qtutils.icon('add.svg'))
180
 
 
181
 
        self.menu_export_patches = add_action(self,
 
153
        self.stage_untracked_action.setIcon(qtutils.icon('add.svg'))
 
154
 
 
155
        self.apply_patches_action = add_action(self,
 
156
                N_('Apply Patches...'), apply_patches)
 
157
 
 
158
        self.export_patches_action = add_action(self,
182
159
                N_('Export Patches...'), guicmds.export_patches, 'Alt+E')
183
160
 
184
 
        self.new_repository = add_action(self,
 
161
        self.new_repository_action = add_action(self,
185
162
                N_('New Repository...'), guicmds.open_new_repo)
186
 
        self.new_repository.setIcon(qtutils.new_icon())
 
163
        self.new_repository_action.setIcon(qtutils.new_icon())
187
164
 
188
 
        self.menu_preferences = add_action(self,
 
165
        self.preferences_action = add_action(self,
189
166
                N_('Preferences'), self.preferences,
190
167
                QtGui.QKeySequence.Preferences, 'Ctrl+O')
191
168
 
192
 
        self.menu_edit_remotes = add_action(self,
193
 
                N_('Edit Remotes...'), lambda: editremotes.edit().exec_())
194
 
        self.menu_rescan = add_action(self,
 
169
        self.edit_remotes_action = add_action(self,
 
170
                N_('Edit Remotes...'), lambda: editremotes.remote_editor().exec_())
 
171
        self.rescan_action = add_action(self,
195
172
                cmds.Refresh.name(),
196
173
                cmds.run(cmds.Refresh),
197
174
                cmds.Refresh.SHORTCUT)
198
 
        self.menu_rescan.setIcon(qtutils.reload_icon())
 
175
        self.rescan_action.setIcon(qtutils.reload_icon())
199
176
 
200
 
        self.menu_browse_recent = add_action(self,
 
177
        self.browse_recently_modified_action = add_action(self,
201
178
                N_('Recently Modified Files...'),
202
 
                browse_recent, 'Shift+Ctrl+E')
 
179
                browse_recent_files, 'Shift+Ctrl+E')
203
180
 
204
 
        self.menu_cherry_pick = add_action(self,
 
181
        self.cherry_pick_action = add_action(self,
205
182
                N_('Cherry-Pick...'),
206
183
                guicmds.cherry_pick, 'Ctrl+P')
207
184
 
208
 
        self.menu_load_commitmsg = add_action(self,
 
185
        self.load_commitmsg_action = add_action(self,
209
186
                N_('Load Commit Message...'), guicmds.load_commitmsg)
210
187
 
211
 
        self.menu_save_tarball = add_action(self,
 
188
        self.save_tarball_action = add_action(self,
212
189
                N_('Save As Tarball/Zip...'), self.save_archive)
213
190
 
214
 
        self.menu_quit = add_action(self,
 
191
        self.quit_action = add_action(self,
215
192
                N_('Quit'), self.close, 'Ctrl+Q')
216
 
        self.menu_manage_bookmarks = add_action(self,
217
 
                N_('Bookmarks...'), manage_bookmarks)
218
 
        self.menu_grep = add_action(self,
219
 
                N_('Grep'), guicmds.grep, 'Ctrl+G')
220
 
        self.menu_merge_local = add_action(self,
 
193
        self.manage_bookmarks_action = add_action(self,
 
194
                N_('Bookmarks...'), self.manage_bookmarks)
 
195
        self.grep_action = add_action(self,
 
196
                N_('Grep'), grep, 'Ctrl+G')
 
197
        self.merge_local_action = add_action(self,
221
198
                N_('Merge...'), merge.local_merge)
222
199
 
223
 
        self.menu_merge_abort = add_action(self,
 
200
        self.merge_abort_action = add_action(self,
224
201
                N_('Abort Merge...'), merge.abort_merge)
225
202
 
226
 
        self.menu_fetch = add_action(self,
 
203
        self.fetch_action = add_action(self,
227
204
                N_('Fetch...'), remote.fetch)
228
 
        self.menu_push = add_action(self,
 
205
        self.push_action = add_action(self,
229
206
                N_('Push...'), remote.push)
230
 
        self.menu_pull = add_action(self,
 
207
        self.pull_action = add_action(self,
231
208
                N_('Pull...'), remote.pull)
232
209
 
233
 
        self.menu_open_repo = add_action(self,
 
210
        self.open_repo_action = add_action(self,
234
211
                N_('Open...'), guicmds.open_repo)
235
 
        self.menu_open_repo.setIcon(qtutils.open_icon())
236
 
 
237
 
        self.menu_stash = add_action(self,
 
212
        self.open_repo_action.setIcon(qtutils.open_icon())
 
213
 
 
214
        self.open_repo_new_action = add_action(self,
 
215
                N_('Open in New Window...'), guicmds.open_repo_in_new_window)
 
216
        self.open_repo_new_action.setIcon(qtutils.open_icon())
 
217
 
 
218
        self.stash_action = add_action(self,
238
219
                N_('Stash...'), stash, 'Alt+Shift+S')
239
220
 
240
 
        self.menu_clone_repo = add_action(self,
 
221
        self.clone_repo_action = add_action(self,
241
222
                N_('Clone...'), guicmds.clone_repo)
242
 
        self.menu_clone_repo.setIcon(qtutils.git_icon())
 
223
        self.clone_repo_action.setIcon(qtutils.git_icon())
243
224
 
244
 
        self.menu_help_docs = add_action(self,
 
225
        self.help_docs_action = add_action(self,
245
226
                N_('Documentation'), resources.show_html_docs,
246
227
                QtGui.QKeySequence.HelpContents)
247
228
 
248
 
        self.menu_help_shortcuts = add_action(self,
 
229
        self.help_shortcuts_action = add_action(self,
249
230
                N_('Keyboard Shortcuts'),
250
231
                show_shortcuts,
251
232
                QtCore.Qt.Key_Question)
252
233
 
253
 
        self.menu_visualize_current = add_action(self,
 
234
        self.visualize_current_action = add_action(self,
254
235
                N_('Visualize Current Branch...'),
255
236
                cmds.run(cmds.VisualizeCurrent))
256
 
        self.menu_visualize_all = add_action(self,
 
237
        self.visualize_all_action = add_action(self,
257
238
                N_('Visualize All Branches...'),
258
239
                cmds.run(cmds.VisualizeAll))
259
 
        self.menu_search_commits = add_action(self,
 
240
        self.search_commits_action = add_action(self,
260
241
                N_('Search...'), search)
261
 
        self.menu_browse_branch = add_action(self,
 
242
        self.browse_branch_action = add_action(self,
262
243
                N_('Browse Current Branch...'), guicmds.browse_current)
263
 
        self.menu_browse_other_branch = add_action(self,
 
244
        self.browse_other_branch_action = add_action(self,
264
245
                N_('Browse Other Branch...'), guicmds.browse_other)
265
 
        self.menu_load_commitmsg_template = add_action(self,
 
246
        self.load_commitmsg_template_action = add_action(self,
266
247
                N_('Get Commit Message Template'),
267
248
                cmds.run(cmds.LoadCommitMessageFromTemplate))
268
 
        self.menu_help_about = add_action(self,
 
249
        self.help_about_action = add_action(self,
269
250
                N_('About'), launch_about_dialog)
270
251
 
271
 
        self.menu_diff_expression = add_action(self,
 
252
        self.diff_expression_action = add_action(self,
272
253
                N_('Expression...'), guicmds.diff_expression)
273
 
        self.menu_branch_compare = add_action(self,
 
254
        self.branch_compare_action = add_action(self,
274
255
                N_('Branches...'), compare_branches)
275
256
 
276
 
        self.menu_create_tag = add_action(self,
 
257
        self.create_tag_action = add_action(self,
277
258
                N_('Create Tag...'), create_tag)
278
259
 
279
 
        self.menu_create_branch = add_action(self,
 
260
        self.create_branch_action = add_action(self,
280
261
                N_('Create...'), create_new_branch, 'Ctrl+B')
281
262
 
282
 
        self.menu_delete_branch = add_action(self,
 
263
        self.delete_branch_action = add_action(self,
283
264
                N_('Delete...'), guicmds.delete_branch)
284
265
 
285
 
        self.menu_delete_remote_branch = add_action(self,
 
266
        self.delete_remote_branch_action = add_action(self,
286
267
                N_('Delete Remote Branch...'), guicmds.delete_remote_branch)
287
268
 
288
 
        self.menu_checkout_branch = add_action(self,
 
269
        self.checkout_branch_action = add_action(self,
289
270
                N_('Checkout...'), guicmds.checkout_branch, 'Alt+B')
290
 
        self.menu_branch_review = add_action(self,
 
271
        self.branch_review_action = add_action(self,
291
272
                N_('Review...'), guicmds.review_branch)
292
273
 
293
 
        self.menu_browse = add_action(self,
 
274
        self.browse_action = add_action(self,
294
275
                N_('Browser...'), worktree_browser)
295
 
        self.menu_browse.setIcon(qtutils.git_icon())
 
276
        self.browse_action.setIcon(qtutils.git_icon())
296
277
 
297
 
        self.menu_dag = add_action(self,
 
278
        self.dag_action = add_action(self,
298
279
                N_('DAG...'), lambda: git_dag(self.model).show())
299
 
        self.menu_dag.setIcon(qtutils.git_icon())
 
280
        self.dag_action.setIcon(qtutils.git_icon())
300
281
 
301
282
        self.rebase_start_action = add_action(self,
302
283
                N_('Start Interactive Rebase...'), self.rebase_start)
314
295
                N_('Abort'), self.rebase_abort)
315
296
 
316
297
        # Relayed actions
 
298
        status_tree = self.statusdockwidget.widget().tree
 
299
        self.addAction(status_tree.revert_unstaged_edits_action)
317
300
        if not self.browser_dockable:
318
301
            # These shortcuts conflict with those from the
319
302
            # 'Browser' widget so don't register them when
320
303
            # the browser is a dockable tool.
321
 
            status_tree = self.statusdockwidget.widget().tree
322
304
            self.addAction(status_tree.up)
323
305
            self.addAction(status_tree.down)
324
306
            self.addAction(status_tree.process_selection)
331
313
 
332
314
        # File Menu
333
315
        self.file_menu = create_menu(N_('File'), self.menubar)
334
 
        self.file_menu.addAction(self.new_repository)
335
 
        self.file_menu.addAction(self.menu_open_repo)
336
 
        self.menu_open_recent = self.file_menu.addMenu(N_('Open Recent'))
337
 
        self.file_menu.addSeparator()
338
 
        self.file_menu.addAction(self.menu_clone_repo)
339
 
        self.file_menu.addAction(self.menu_manage_bookmarks)
340
 
        self.file_menu.addSeparator()
341
 
        self.file_menu.addAction(self.menu_edit_remotes)
342
 
        self.file_menu.addAction(self.menu_rescan)
343
 
        self.file_menu.addSeparator()
344
 
        self.file_menu.addAction(self.menu_browse_recent)
345
 
        self.file_menu.addSeparator()
346
 
        self.file_menu.addAction(self.menu_load_commitmsg)
347
 
        self.file_menu.addAction(self.menu_load_commitmsg_template)
348
 
        self.file_menu.addSeparator()
349
 
        self.file_menu.addAction(self.menu_save_tarball)
350
 
        self.file_menu.addAction(self.menu_export_patches)
351
 
        self.file_menu.addSeparator()
352
 
        self.file_menu.addAction(self.menu_preferences)
353
 
        self.file_menu.addAction(self.menu_quit)
 
316
        self.open_recent_menu = self.file_menu.addMenu(N_('Open Recent'))
 
317
        self.open_recent_menu.setIcon(qtutils.open_icon())
 
318
        self.file_menu.addAction(self.open_repo_action)
 
319
        self.file_menu.addAction(self.open_repo_new_action)
 
320
        self.file_menu.addAction(self.clone_repo_action)
 
321
        self.file_menu.addAction(self.new_repository_action)
 
322
        self.file_menu.addSeparator()
 
323
        self.file_menu.addAction(self.rescan_action)
 
324
        self.file_menu.addAction(self.edit_remotes_action)
 
325
        self.file_menu.addAction(self.browse_recently_modified_action)
 
326
        self.file_menu.addAction(self.manage_bookmarks_action)
 
327
        self.file_menu.addSeparator()
 
328
        self.file_menu.addAction(self.load_commitmsg_action)
 
329
        self.file_menu.addAction(self.load_commitmsg_template_action)
 
330
        self.file_menu.addSeparator()
 
331
        self.file_menu.addAction(self.apply_patches_action)
 
332
        self.file_menu.addAction(self.export_patches_action)
 
333
        self.file_menu.addAction(self.save_tarball_action)
 
334
        self.file_menu.addSeparator()
 
335
        self.file_menu.addAction(self.preferences_action)
 
336
        self.file_menu.addAction(self.quit_action)
354
337
        self.menubar.addAction(self.file_menu.menuAction())
355
338
 
356
339
        # Actions menu
357
340
        self.actions_menu = create_menu(N_('Actions'), self.menubar)
358
 
        self.actions_menu.addAction(self.menu_fetch)
359
 
        self.actions_menu.addAction(self.menu_push)
360
 
        self.actions_menu.addAction(self.menu_pull)
361
 
        self.actions_menu.addAction(self.menu_stash)
362
 
        self.actions_menu.addSeparator()
363
 
        self.actions_menu.addAction(self.menu_create_tag)
364
 
        self.actions_menu.addAction(self.menu_cherry_pick)
365
 
        self.actions_menu.addAction(self.menu_merge_local)
366
 
        self.actions_menu.addAction(self.menu_merge_abort)
367
 
        self.actions_menu.addSeparator()
368
 
        self.actions_menu.addAction(self.menu_grep)
369
 
        self.actions_menu.addAction(self.menu_search_commits)
 
341
        self.actions_menu.addAction(self.fetch_action)
 
342
        self.actions_menu.addAction(self.push_action)
 
343
        self.actions_menu.addAction(self.pull_action)
 
344
        self.actions_menu.addAction(self.stash_action)
 
345
        self.actions_menu.addSeparator()
 
346
        self.actions_menu.addAction(self.create_tag_action)
 
347
        self.actions_menu.addAction(self.cherry_pick_action)
 
348
        self.actions_menu.addAction(self.merge_local_action)
 
349
        self.actions_menu.addAction(self.merge_abort_action)
 
350
        self.actions_menu.addSeparator()
 
351
        self.actions_menu.addAction(self.grep_action)
 
352
        self.actions_menu.addAction(self.search_commits_action)
370
353
        self.menubar.addAction(self.actions_menu.menuAction())
371
354
 
372
355
        # Index Menu
373
356
        self.commit_menu = create_menu(N_('Index'), self.menubar)
374
357
        self.commit_menu.setTitle(N_('Index'))
375
 
        self.commit_menu.addAction(self.menu_stage_modified)
376
 
        self.commit_menu.addAction(self.menu_stage_untracked)
 
358
        self.commit_menu.addAction(self.stage_modified_action)
 
359
        self.commit_menu.addAction(self.stage_untracked_action)
377
360
        self.commit_menu.addSeparator()
378
 
        self.commit_menu.addAction(self.menu_unstage_all)
379
 
        self.commit_menu.addAction(self.menu_unstage_selected)
 
361
        self.commit_menu.addAction(self.unstage_all_action)
 
362
        self.commit_menu.addAction(self.unstage_selected_action)
380
363
        self.menubar.addAction(self.commit_menu.menuAction())
381
364
 
382
365
        # Diff Menu
383
366
        self.diff_menu = create_menu(N_('Diff'), self.menubar)
384
 
        self.diff_menu.addAction(self.menu_diff_expression)
385
 
        self.diff_menu.addAction(self.menu_branch_compare)
 
367
        self.diff_menu.addAction(self.diff_expression_action)
 
368
        self.diff_menu.addAction(self.branch_compare_action)
386
369
        self.diff_menu.addSeparator()
387
 
        self.diff_menu.addAction(self.menu_show_diffstat)
 
370
        self.diff_menu.addAction(self.show_diffstat_action)
388
371
        self.menubar.addAction(self.diff_menu.menuAction())
389
372
 
390
373
        # Branch Menu
391
374
        self.branch_menu = create_menu(N_('Branch'), self.menubar)
392
 
        self.branch_menu.addAction(self.menu_branch_review)
393
 
        self.branch_menu.addSeparator()
394
 
        self.branch_menu.addAction(self.menu_create_branch)
395
 
        self.branch_menu.addAction(self.menu_checkout_branch)
396
 
        self.branch_menu.addAction(self.menu_delete_branch)
397
 
        self.branch_menu.addAction(self.menu_delete_remote_branch)
398
 
        self.branch_menu.addSeparator()
399
 
        self.branch_menu.addAction(self.menu_browse_branch)
400
 
        self.branch_menu.addAction(self.menu_browse_other_branch)
401
 
        self.branch_menu.addSeparator()
402
 
        self.branch_menu.addAction(self.menu_visualize_current)
403
 
        self.branch_menu.addAction(self.menu_visualize_all)
 
375
        self.branch_menu.addAction(self.branch_review_action)
 
376
        self.branch_menu.addSeparator()
 
377
        self.branch_menu.addAction(self.create_branch_action)
 
378
        self.branch_menu.addAction(self.checkout_branch_action)
 
379
        self.branch_menu.addAction(self.delete_branch_action)
 
380
        self.branch_menu.addAction(self.delete_remote_branch_action)
 
381
        self.branch_menu.addSeparator()
 
382
        self.branch_menu.addAction(self.browse_branch_action)
 
383
        self.branch_menu.addAction(self.browse_other_branch_action)
 
384
        self.branch_menu.addSeparator()
 
385
        self.branch_menu.addAction(self.visualize_current_action)
 
386
        self.branch_menu.addAction(self.visualize_all_action)
404
387
        self.menubar.addAction(self.branch_menu.menuAction())
405
388
 
406
389
        # Rebase menu
416
399
 
417
400
        # View Menu
418
401
        self.view_menu = create_menu(N_('View'), self.menubar)
419
 
        self.view_menu.addAction(self.menu_browse)
420
 
        self.view_menu.addAction(self.menu_dag)
 
402
        self.view_menu.addAction(self.browse_action)
 
403
        self.view_menu.addAction(self.dag_action)
421
404
        self.view_menu.addSeparator()
422
405
        if self.browser_dockable:
423
406
            self.view_menu.addAction(self.browserdockwidget.toggleViewAction())
429
412
 
430
413
        # Help Menu
431
414
        self.help_menu = create_menu(N_('Help'), self.menubar)
432
 
        self.help_menu.addAction(self.menu_help_docs)
433
 
        self.help_menu.addAction(self.menu_help_shortcuts)
434
 
        self.help_menu.addAction(self.menu_help_about)
 
415
        self.help_menu.addAction(self.help_docs_action)
 
416
        self.help_menu.addAction(self.help_shortcuts_action)
 
417
        self.help_menu.addAction(self.help_about_action)
435
418
        self.menubar.addAction(self.help_menu.menuAction())
436
419
 
437
420
        # Set main menu
447
430
            self.addDockWidget(left, self.browserdockwidget)
448
431
            self.tabifyDockWidget(self.browserdockwidget, self.commitdockwidget)
449
432
        self.addDockWidget(left, self.diffdockwidget)
 
433
        self.addDockWidget(right, self.statusdockwidget)
 
434
        self.addDockWidget(right, self.bookmarksdockwidget)
450
435
        self.addDockWidget(bottom, self.actionsdockwidget)
451
436
        self.addDockWidget(bottom, self.logdockwidget)
452
437
        self.tabifyDockWidget(self.actionsdockwidget, self.logdockwidget)
453
438
 
454
 
        self.addDockWidget(right, self.statusdockwidget)
455
439
 
456
440
        # Listen for model notifications
457
441
        model.add_observer(model.message_updated, self._update)
463
447
        # Set a default value
464
448
        self.show_cursor_position(1, 0)
465
449
 
466
 
        self.connect(self.menu_open_recent, SIGNAL('aboutToShow()'),
 
450
        self.connect(self.open_recent_menu, SIGNAL('aboutToShow()'),
467
451
                     self.build_recent_menu)
468
452
 
469
453
        self.connect(self.commitmsgeditor, SIGNAL('cursorPosition(int,int)'),
470
454
                     self.show_cursor_position)
 
455
 
 
456
        self.connect(self.diffeditor, SIGNAL('diff_options_updated()'),
 
457
                     self.statuswidget.refresh)
 
458
 
471
459
        self.connect(self, SIGNAL('update'), self._update_callback)
472
460
        self.connect(self, SIGNAL('install_config_actions'),
473
461
                     self._install_config_actions)
477
465
        self.install_config_actions()
478
466
 
479
467
        # Restore saved settings
480
 
        if not qtutils.apply_state(self):
 
468
        if not self.restore_state():
 
469
            self.resize(987, 610)
481
470
            self.set_initial_size()
482
471
 
483
472
        self.statusdockwidget.widget().setFocus()
501
490
 
502
491
    def build_recent_menu(self):
503
492
        recent = settings.Settings().recent
504
 
        menu = self.menu_open_recent
 
493
        cmd = cmds.OpenRepo
 
494
        menu = self.open_recent_menu
505
495
        menu.clear()
506
496
        for r in recent:
507
497
            name = os.path.basename(r)
508
498
            directory = os.path.dirname(r)
509
499
            text = '%s %s %s' % (name, unichr(0x2192), directory)
510
 
            menu.addAction(text, cmds.run(cmds.OpenRepo, r))
 
500
            menu.addAction(text, cmds.run(cmd, r))
511
501
 
512
502
    # Accessors
513
503
    mode = property(lambda self: self.model.mode)
644
634
            (optkey + '+2', self.statusdockwidget),
645
635
            (optkey + '+3', self.diffdockwidget),
646
636
            (optkey + '+4', self.actionsdockwidget),
 
637
            (optkey + '+5', self.bookmarksdockwidget),
647
638
        )
648
639
        for shortcut, dockwidget in dockwidgets:
649
640
            # Associate the action with the shortcut
670
661
            self.addAction(toggleview)
671
662
            connect_action(toggleview, focusdock)
672
663
 
673
 
    def _update_diff_opts(self):
674
 
        space_at_eol = self.diff_ignore_space_at_eol_action.isChecked()
675
 
        space_change = self.diff_ignore_space_change_action.isChecked()
676
 
        all_space = self.diff_ignore_all_space_action.isChecked()
677
 
        function_context = self.diff_function_context_action.isChecked()
678
 
 
679
 
        gitcmds.update_diff_overrides(space_at_eol,
680
 
                                      space_change,
681
 
                                      all_space,
682
 
                                      function_context)
683
 
        self.statuswidget.refresh()
684
 
 
685
664
    def preferences(self):
686
665
        return preferences(model=self.prefs_model, parent=self)
687
666
 
688
667
    def save_archive(self):
689
668
        ref = git.rev_parse('HEAD')[STDOUT]
690
669
        shortref = ref[:7]
691
 
        GitArchiveDialog.save(ref, shortref, self)
692
 
 
693
 
    def dragEnterEvent(self, event):
694
 
        """Accepts drops"""
695
 
        MainWindow.dragEnterEvent(self, event)
696
 
        event.acceptProposedAction()
697
 
 
698
 
    def dropEvent(self, event):
699
 
        """Apply dropped patches with git-am"""
700
 
        event.accept()
701
 
        urls = event.mimeData().urls()
702
 
        if not urls:
703
 
            return
704
 
        paths = map(lambda x: unicode(x.path()), urls)
705
 
        patches = [p for p in paths if p.endswith('.patch')]
706
 
        dirs = [p for p in paths if os.path.isdir(p)]
707
 
        dirs.sort()
708
 
        for d in dirs:
709
 
            patches.extend(self._gather_patches(d))
710
 
        cmds.do(cmds.ApplyPatches, patches)
711
 
 
712
 
    def _gather_patches(self, path):
713
 
        """Find patches in a subdirectory"""
714
 
        patches = []
715
 
        for root, subdirs, files in os.walk(path):
716
 
            for name in [f for f in files if f.endswith('.patch')]:
717
 
                patches.append(os.path.join(root, name))
718
 
        return patches
 
670
        GitArchiveDialog.save_hashed_objects(ref, shortref, self)
719
671
 
720
672
    def show_cursor_position(self, rows, cols):
721
673
        display = ' %02d:%02d ' % (rows, cols)
736
688
 
737
689
        self.position_label.setText(display)
738
690
 
 
691
    def manage_bookmarks(self):
 
692
        manage_bookmarks()
 
693
        self.bookmarkswidget.refresh()
 
694
 
739
695
    def rebase_start(self):
740
696
        branch = guicmds.choose_ref(N_('Select New Upstream'),
741
697
                                    N_('Interactive Rebase'))