1 """This view provides the main git-cola user interface.
5 from PyQt4
import QtCore
6 from PyQt4
import QtGui
7 from PyQt4
.QtCore
import Qt
8 from PyQt4
.QtCore
import SIGNAL
12 from cola
import gitcmds
13 from cola
import guicmds
14 from cola
import merge
15 from cola
import settings
16 from cola
import signals
17 from cola
import gitcfg
18 from cola
import qtutils
19 from cola
import qtcompat
21 from cola
import resources
22 from cola
import stash
23 from cola
import utils
24 from cola
import version
25 from cola
.bookmarks
import manage_bookmarks
26 from cola
.classic
import cola_classic
27 from cola
.classic
import classic_widget
28 from cola
.dag
import git_dag
29 from cola
.git
import git
30 from cola
.prefs
import diff_font
31 from cola
.prefs
import PreferencesModel
32 from cola
.prefs
import preferences
33 from cola
.qt
import create_button
34 from cola
.qt
import create_dock
35 from cola
.qt
import create_menu
36 from cola
.qtutils
import add_action
37 from cola
.qtutils
import connect_action
38 from cola
.qtutils
import connect_action_bool
39 from cola
.qtutils
import connect_button
40 from cola
.qtutils
import emit
41 from cola
.qtutils
import log
42 from cola
.qtutils
import relay_signal
43 from cola
.qtutils
import tr
44 from cola
.views
import standard
45 from cola
.widgets
import cfgactions
46 from cola
.widgets
import remote
47 from cola
.widgets
.about
import launch_about_dialog
48 from cola
.widgets
.about
import show_shortcuts
49 from cola
.widgets
.archive
import GitArchiveDialog
50 from cola
.widgets
.commitmsg
import CommitMessageEditor
51 from cola
.widgets
.compare
import compare_branches
52 from cola
.widgets
.createtag
import create_tag
53 from cola
.widgets
.createbranch
import create_new_branch
54 from cola
.widgets
.diff
import DiffEditor
55 from cola
.widgets
.recent
import browse_recent
56 from cola
.widgets
.status
import StatusWidget
57 from cola
.widgets
.search
import search
60 class MainView(standard
.MainWindow
):
61 def __init__(self
, model
, parent
):
62 standard
.MainWindow
.__init
__(self
, parent
)
63 # Default size; this is thrown out when save/restore is used
66 self
.prefs_model
= prefs_model
= PreferencesModel()
68 # Internal field used by import/export_state().
69 # Change this whenever dockwidgets are removed.
70 self
.widget_version
= 1
72 # Keeps track of merge messages we've seen
73 self
.merge_message_hash
= ''
75 self
.setAcceptDrops(True)
78 qtcompat
.set_common_dock_options(self
)
80 self
.classic_dockable
= gitcfg
.instance().get('cola.classicdockable')
82 if self
.classic_dockable
:
83 self
.classicdockwidget
= create_dock('Classic', self
)
84 self
.classicwidget
= classic_widget(self
)
85 self
.classicdockwidget
.setWidget(self
.classicwidget
)
88 self
.actionsdockwidget
= create_dock('Action', self
)
89 self
.actionsdockwidgetcontents
= qt
.QFlowLayoutWidget(self
)
90 layout
= self
.actionsdockwidgetcontents
.layout()
91 self
.stage_button
= create_button(text
='Stage', layout
=layout
)
92 self
.unstage_button
= create_button(text
='Unstage', layout
=layout
)
93 self
.rescan_button
= create_button(text
='Rescan', layout
=layout
)
94 self
.fetch_button
= create_button(text
='Fetch...', layout
=layout
)
95 self
.push_button
= create_button(text
='Push...', layout
=layout
)
96 self
.pull_button
= create_button(text
='Pull...', layout
=layout
)
97 self
.stash_button
= create_button(text
='Stash...', layout
=layout
)
98 self
.alt_button
= create_button(text
='Exit Diff Mode', layout
=layout
)
99 self
.alt_button
.hide()
101 self
.actionsdockwidget
.setWidget(self
.actionsdockwidgetcontents
)
103 # "Repository Status" widget
104 self
.statusdockwidget
= create_dock('Status', self
)
105 self
.statusdockwidget
.setWidget(StatusWidget(self
))
107 # "Commit Message Editor" widget
108 self
.position_label
= QtGui
.QLabel()
109 font
= qtutils
.default_monospace_font()
110 font
.setPointSize(int(font
.pointSize() * 0.8))
111 self
.position_label
.setFont(font
)
112 self
.commitdockwidget
= create_dock('Commit', self
)
113 titlebar
= self
.commitdockwidget
.titleBarWidget()
114 titlebar
.add_corner_widget(self
.position_label
)
116 self
.commitmsgeditor
= CommitMessageEditor(model
, self
)
117 relay_signal(self
, self
.commitmsgeditor
, SIGNAL(signals
.amend_mode
))
118 relay_signal(self
, self
.commitmsgeditor
, SIGNAL(signals
.signoff
))
119 relay_signal(self
, self
.commitmsgeditor
,
120 SIGNAL(signals
.load_previous_message
))
121 self
.commitdockwidget
.setWidget(self
.commitmsgeditor
)
123 # "Command Output" widget
124 logwidget
= qtutils
.logger()
125 logwidget
.setFont(diff_font())
126 self
.logdockwidget
= create_dock('Console', self
)
127 self
.logdockwidget
.setWidget(logwidget
)
129 # "Diff Viewer" widget
130 self
.diffdockwidget
= create_dock('Diff', self
)
131 self
.diff_editor
= DiffEditor(self
.diffdockwidget
)
132 self
.diffdockwidget
.setWidget(self
.diff_editor
)
135 self
.menu_unstage_all
= add_action(self
,
136 'Unstage All', emit(self
, signals
.unstage_all
))
137 self
.menu_unstage_all
.setIcon(qtutils
.icon('remove.svg'))
139 self
.menu_unstage_selected
= add_action(self
,
140 'Unstage From Commit', emit(self
, signals
.unstage_selected
))
141 self
.menu_unstage_selected
.setIcon(qtutils
.icon('remove.svg'))
143 self
.menu_show_diffstat
= add_action(self
,
144 'Diffstat', emit(self
, signals
.diffstat
), 'Alt+D')
146 self
.menu_stage_modified
= add_action(self
,
147 'Stage Changed Files To Commit',
148 emit(self
, signals
.stage_modified
), 'Alt+A')
149 self
.menu_stage_modified
.setIcon(qtutils
.icon('add.svg'))
151 self
.menu_stage_untracked
= add_action(self
,
152 'Stage All Untracked', emit(self
, signals
.stage_untracked
), 'Alt+U')
153 self
.menu_stage_untracked
.setIcon(qtutils
.icon('add.svg'))
155 self
.menu_export_patches
= add_action(self
,
156 'Export Patches...', guicmds
.export_patches
, 'Alt+E')
157 self
.menu_preferences
= add_action(self
,
158 'Preferences', lambda: preferences(model
=prefs_model
),
159 QtGui
.QKeySequence
.Preferences
, 'Ctrl+O')
161 self
.menu_rescan
= add_action(self
,
162 'Rescan', emit(self
, signals
.rescan_and_refresh
), 'Ctrl+R')
163 self
.menu_rescan
.setIcon(qtutils
.reload_icon())
165 self
.menu_browse_recent
= add_action(self
,
166 'Recently Modified Files...', browse_recent
, 'Shift+Ctrl+E')
168 self
.menu_cherry_pick
= add_action(self
,
169 'Cherry-Pick...', guicmds
.cherry_pick
, 'Ctrl+P')
171 self
.menu_load_commitmsg
= add_action(self
,
172 'Load Commit Message...', guicmds
.load_commitmsg
)
174 self
.menu_save_tarball
= add_action(self
,
175 'Save As Tarball/Zip...', self
.save_archive
)
177 self
.menu_quit
= add_action(self
,
178 'Quit', self
.close
, 'Ctrl+Q')
179 self
.menu_manage_bookmarks
= add_action(self
,
180 'Bookmarks...', manage_bookmarks
)
181 self
.menu_grep
= add_action(self
,
182 'Grep', guicmds
.grep
)
183 self
.menu_merge_local
= add_action(self
,
184 'Merge...', merge
.local_merge
)
186 self
.menu_merge_abort
= add_action(self
,
187 'Abort Merge...', merge
.abort_merge
)
189 self
.menu_fetch
= add_action(self
,
190 'Fetch...', remote
.fetch
)
191 self
.menu_push
= add_action(self
,
192 'Push...', remote
.push
)
193 self
.menu_pull
= add_action(self
,
194 'Pull...', remote
.pull
)
196 self
.menu_open_repo
= add_action(self
,
197 'Open...', guicmds
.open_repo
)
198 self
.menu_open_repo
.setIcon(qtutils
.open_icon())
200 self
.menu_stash
= add_action(self
,
201 'Stash...', stash
.stash
, 'Alt+Shift+S')
203 self
.menu_clone_repo
= add_action(self
,
204 'Clone...', guicmds
.clone_repo
)
205 self
.menu_clone_repo
.setIcon(qtutils
.git_icon())
207 self
.menu_help_docs
= add_action(self
,
208 'Documentation', resources
.show_html_docs
,
209 QtGui
.QKeySequence
.HelpContents
)
211 self
.menu_help_shortcuts
= add_action(self
,
212 'Keyboard Shortcuts',
214 QtCore
.Qt
.Key_Question
)
216 self
.menu_visualize_current
= add_action(self
,
217 'Visualize Current Branch...',
218 emit(self
, signals
.visualize_current
))
219 self
.menu_visualize_all
= add_action(self
,
220 'Visualize All Branches...',
221 emit(self
, signals
.visualize_all
))
222 self
.menu_search_commits
= add_action(self
,
224 self
.menu_browse_branch
= add_action(self
,
225 'Browse Current Branch...', guicmds
.browse_current
)
226 self
.menu_browse_other_branch
= add_action(self
,
227 'Browse Other Branch...', guicmds
.browse_other
)
228 self
.menu_load_commitmsg_template
= add_action(self
,
229 'Get Commit Message Template',
230 emit(self
, signals
.load_commit_template
))
231 self
.menu_help_about
= add_action(self
,
232 'About', launch_about_dialog
)
234 self
.menu_branch_diff
= add_action(self
,
235 'SHA-1...', guicmds
.branch_diff
)
236 self
.menu_diff_expression
= add_action(self
,
237 'Expression...', guicmds
.diff_expression
)
238 self
.menu_branch_compare
= add_action(self
,
239 'Branches...', compare_branches
)
241 self
.menu_create_tag
= add_action(self
,
242 'Create Tag...', create_tag
)
244 self
.menu_create_branch
= add_action(self
,
245 'Create...', create_new_branch
, 'Ctrl+B')
247 self
.menu_delete_branch
= add_action(self
,
248 'Delete...', guicmds
.branch_delete
)
250 self
.menu_checkout_branch
= add_action(self
,
251 'Checkout...', guicmds
.checkout_branch
, 'Alt+B')
252 self
.menu_rebase_branch
= add_action(self
,
253 'Rebase...', guicmds
.rebase
)
254 self
.menu_branch_review
= add_action(self
,
255 'Review...', guicmds
.review_branch
)
257 self
.menu_classic
= add_action(self
,
258 'Cola Classic...', cola_classic
)
259 self
.menu_classic
.setIcon(qtutils
.git_icon())
261 self
.menu_dag
= add_action(self
,
262 'DAG...', lambda: git_dag(self
.model
))
263 self
.menu_dag
.setIcon(qtutils
.git_icon())
266 status_tree
= self
.statusdockwidget
.widget().tree
267 self
.addAction(status_tree
.up
)
268 self
.addAction(status_tree
.down
)
269 self
.addAction(status_tree
.process_selection
)
270 self
.addAction(status_tree
.launch_difftool
)
272 # Create the application menu
273 self
.menubar
= QtGui
.QMenuBar(self
)
276 self
.file_menu
= create_menu('&File', self
.menubar
)
277 self
.file_menu
.addAction(self
.menu_preferences
)
278 self
.file_menu
.addSeparator()
279 self
.file_menu
.addAction(self
.menu_open_repo
)
280 self
.file_menu
.addAction(self
.menu_clone_repo
)
281 self
.file_menu
.addAction(self
.menu_manage_bookmarks
)
282 self
.file_menu
.addSeparator()
283 self
.file_menu
.addAction(self
.menu_rescan
)
284 self
.file_menu
.addSeparator()
285 self
.file_menu
.addAction(self
.menu_browse_recent
)
286 self
.file_menu
.addSeparator()
287 self
.file_menu
.addAction(self
.menu_load_commitmsg
)
288 self
.file_menu
.addAction(self
.menu_load_commitmsg_template
)
289 self
.file_menu
.addSeparator()
290 self
.file_menu
.addAction(self
.menu_save_tarball
)
291 self
.file_menu
.addAction(self
.menu_quit
)
293 self
.menubar
.addAction(self
.file_menu
.menuAction())
296 self
.commit_menu
= create_menu('Co&mmit', self
.menubar
)
297 self
.commit_menu
.setTitle(tr('Commit@@verb'))
298 self
.commit_menu
.addAction(self
.menu_stage_modified
)
299 self
.commit_menu
.addAction(self
.menu_stage_untracked
)
300 self
.commit_menu
.addSeparator()
301 self
.commit_menu
.addAction(self
.menu_unstage_all
)
302 self
.commit_menu
.addAction(self
.menu_unstage_selected
)
303 self
.commit_menu
.addSeparator()
304 self
.commit_menu
.addAction(self
.menu_search_commits
)
306 self
.menubar
.addAction(self
.commit_menu
.menuAction())
309 self
.branch_menu
= create_menu('B&ranch', self
.menubar
)
310 self
.branch_menu
.addAction(self
.menu_branch_review
)
311 self
.branch_menu
.addSeparator()
312 self
.branch_menu
.addAction(self
.menu_create_branch
)
313 self
.branch_menu
.addAction(self
.menu_checkout_branch
)
314 self
.branch_menu
.addAction(self
.menu_rebase_branch
)
315 self
.branch_menu
.addAction(self
.menu_delete_branch
)
316 self
.branch_menu
.addSeparator()
317 self
.branch_menu
.addAction(self
.menu_browse_branch
)
318 self
.branch_menu
.addAction(self
.menu_browse_other_branch
)
319 self
.branch_menu
.addSeparator()
320 self
.branch_menu
.addAction(self
.menu_visualize_current
)
321 self
.branch_menu
.addAction(self
.menu_visualize_all
)
323 self
.menubar
.addAction(self
.branch_menu
.menuAction())
326 self
.actions_menu
= create_menu('Act&ions', self
.menubar
)
327 self
.actions_menu
.addAction(self
.menu_merge_local
)
328 self
.actions_menu
.addAction(self
.menu_stash
)
329 self
.actions_menu
.addSeparator()
330 self
.actions_menu
.addAction(self
.menu_fetch
)
331 self
.actions_menu
.addAction(self
.menu_push
)
332 self
.actions_menu
.addAction(self
.menu_pull
)
333 self
.actions_menu
.addSeparator()
334 self
.actions_menu
.addAction(self
.menu_create_tag
)
335 self
.actions_menu
.addSeparator()
336 self
.actions_menu
.addAction(self
.menu_export_patches
)
337 self
.actions_menu
.addAction(self
.menu_cherry_pick
)
338 self
.actions_menu
.addSeparator()
339 self
.actions_menu
.addAction(self
.menu_merge_abort
)
340 self
.actions_menu
.addAction(self
.menu_grep
)
342 self
.menubar
.addAction(self
.actions_menu
.menuAction())
345 self
.diff_menu
= create_menu('&Diff', self
.menubar
)
346 self
.diff_menu
.addAction(self
.menu_branch_diff
)
347 self
.diff_menu
.addAction(self
.menu_diff_expression
)
348 self
.diff_menu
.addAction(self
.menu_branch_compare
)
349 self
.diff_menu
.addSeparator()
350 self
.diff_menu
.addAction(self
.menu_show_diffstat
)
352 self
.menubar
.addAction(self
.diff_menu
.menuAction())
355 self
.tools_menu
= create_menu('&Tools', self
.menubar
)
356 self
.tools_menu
.addAction(self
.menu_classic
)
357 self
.tools_menu
.addAction(self
.menu_dag
)
358 self
.tools_menu
.addSeparator()
359 if self
.classic_dockable
:
360 self
.tools_menu
.addAction(self
.classicdockwidget
.toggleViewAction())
362 self
.setup_dockwidget_tools_menu()
363 self
.menubar
.addAction(self
.tools_menu
.menuAction())
366 self
.help_menu
= create_menu('&Help', self
.menubar
)
367 self
.help_menu
.addAction(self
.menu_help_docs
)
368 self
.help_menu
.addAction(self
.menu_help_shortcuts
)
369 self
.help_menu
.addAction(self
.menu_help_about
)
371 self
.menubar
.addAction(self
.help_menu
.menuAction())
374 self
.setMenuBar(self
.menubar
)
376 # Arrange dock widgets
377 top
= Qt
.TopDockWidgetArea
378 bottom
= Qt
.BottomDockWidgetArea
380 self
.addDockWidget(top
, self
.commitdockwidget
)
381 if self
.classic_dockable
:
382 self
.addDockWidget(top
, self
.classicdockwidget
)
383 self
.addDockWidget(top
, self
.statusdockwidget
)
384 self
.addDockWidget(top
, self
.actionsdockwidget
)
385 self
.addDockWidget(bottom
, self
.logdockwidget
)
386 if self
.classic_dockable
:
387 self
.tabifyDockWidget(self
.classicdockwidget
, self
.commitdockwidget
)
388 self
.tabifyDockWidget(self
.logdockwidget
, self
.diffdockwidget
)
390 # Listen for model notifications
391 model
.add_message_observer(model
.message_mode_changed
,
394 model
.add_message_observer(model
.message_updated
,
397 prefs_model
.add_message_observer(prefs_model
.message_config_updated
,
398 self
._config
_updated
)
400 # Set a default value
401 self
.show_cursor_position(1, 0)
403 # Add button callbacks
404 connect_button(self
.rescan_button
,
405 emit(self
, signals
.rescan_and_refresh
))
406 connect_button(self
.alt_button
, emit(self
, signals
.reset_mode
))
407 connect_button(self
.fetch_button
, remote
.fetch
)
408 connect_button(self
.push_button
, remote
.push
)
409 connect_button(self
.pull_button
, remote
.pull
)
410 connect_button(self
.stash_button
, stash
.stash
)
412 connect_button(self
.stage_button
, self
.stage
)
413 connect_button(self
.unstage_button
, self
.unstage
)
415 self
.connect(self
.commitmsgeditor
, SIGNAL('cursorPosition(int,int)'),
416 self
.show_cursor_position
)
417 self
.connect(self
, SIGNAL('update'), self
._update
_callback
)
418 self
.connect(self
, SIGNAL('apply_state'), self
.apply_state
)
419 self
.connect(self
, SIGNAL('install_config_actions'),
420 self
._install
_config
_actions
)
422 # Install .git-config-defined actions
423 self
._config
_task
= None
424 self
.install_config_actions()
426 # Restore saved settings
427 self
._gui
_state
_task
= None
428 self
._load
_gui
_state
()
430 log(0, version
.git_version_str() + '\ncola version ' + version
.version())
433 def closeEvent(self
, event
):
434 """Save state in the settings manager."""
435 qtutils
.save_state(self
)
436 standard
.MainWindow
.closeEvent(self
, event
)
439 mode
= property(lambda self
: self
.model
.mode
)
441 def _mode_changed(self
, mode
):
442 """React to mode changes; hide/show the "Exit Diff Mode" button."""
443 if mode
in (self
.model
.mode_review
,
444 self
.model
.mode_diff
,
445 self
.model
.mode_diff_expr
):
446 height
= self
.stage_button
.minimumHeight()
447 self
.alt_button
.setMinimumHeight(height
)
448 self
.alt_button
.show()
450 self
.alt_button
.setMinimumHeight(1)
451 self
.alt_button
.hide()
453 def _config_updated(self
, source
, config
, value
):
454 if config
== 'cola.fontdiff':
456 if not font
.fromString(value
):
458 qtutils
.logger().setFont(font
)
459 self
.diff_editor
.setFont(font
)
460 self
.commitmsgeditor
.setFont(font
)
462 elif config
== 'cola.tabwidth':
463 # variable-tab-width setting
464 self
.diff_editor
.set_tab_width(value
)
466 def install_config_actions(self
):
467 """Install .gitconfig-defined actions"""
468 self
._config
_task
= self
._start
_config
_actions
_task
()
470 def _start_config_actions_task(self
):
471 """Do the expensive "get_config_actions()" call in the background"""
472 class ConfigActionsTask(QtCore
.QRunnable
):
473 def __init__(self
, sender
):
474 QtCore
.QRunnable
.__init
__(self
)
475 self
._sender
= sender
477 names
= cfgactions
.get_config_actions()
478 self
._sender
.emit(SIGNAL('install_config_actions'), names
)
480 task
= ConfigActionsTask(self
)
481 QtCore
.QThreadPool
.globalInstance().start(task
)
484 def _install_config_actions(self
, names
):
485 """Install .gitconfig-defined actions"""
488 menu
= self
.actions_menu
491 menu
.addAction(name
, emit(self
, signals
.run_config_action
, name
))
493 def _update_view(self
):
494 self
.emit(SIGNAL('update'))
496 def _update_callback(self
):
497 """Update the title with the current branch and directory name."""
498 branch
= self
.model
.currentbranch
499 curdir
= core
.decode(os
.getcwd())
500 msg
= 'Repository: %s\nBranch: %s' % (curdir
, branch
)
501 self
.commitdockwidget
.setToolTip(msg
)
503 title
= '%s: %s' % (self
.model
.project
, branch
)
504 if self
.mode
in (self
.model
.mode_diff
, self
.model
.mode_diff_expr
):
505 title
+= ' *** diff mode***'
506 elif self
.mode
== self
.model
.mode_review
:
507 title
+= ' *** review mode***'
508 elif self
.mode
== self
.model
.mode_amend
:
509 title
+= ' *** amending ***'
510 self
.setWindowTitle(title
)
512 self
.commitmsgeditor
.set_mode(self
.mode
)
514 if not self
.model
.read_only() and self
.mode
!= self
.model
.mode_amend
:
515 # Check if there's a message file in .git/
516 merge_msg_path
= gitcmds
.merge_message_path()
517 if merge_msg_path
is None:
519 merge_msg_hash
= utils
.checksum(core
.decode(merge_msg_path
))
520 if merge_msg_hash
== self
.merge_message_hash
:
522 self
.merge_message_hash
= merge_msg_hash
523 cola
.notifier().broadcast(signals
.load_commit_message
,
524 core
.decode(merge_msg_path
))
526 def apply_state(self
, state
):
527 """Imports data for save/restore"""
528 # 1 is the widget version; change when widgets are added/removed
529 standard
.MainWindow
.apply_state(self
, state
)
530 qtutils
.apply_window_state(self
, state
, 1)
532 def export_state(self
):
533 """Exports data for save/restore"""
534 state
= standard
.MainWindow
.export_state(self
)
535 return qtutils
.export_window_state(self
, state
, self
.widget_version
)
537 def _load_gui_state(self
):
538 """Restores the gui from the preferences file."""
539 self
._gui
_state
_task
= self
._start
_gui
_state
_loading
_thread
()
541 def _start_gui_state_loading_thread(self
):
542 """Do expensive file reading and json decoding in the background"""
543 class LoadGUIStateTask(QtCore
.QRunnable
):
544 def __init__(self
, sender
):
545 QtCore
.QRunnable
.__init
__(self
)
546 self
._sender
= sender
548 state
= settings
.Settings().get_gui_state(self
._sender
)
549 self
._sender
.emit(SIGNAL('apply_state'), state
)
551 task
= LoadGUIStateTask(self
)
552 QtCore
.QThreadPool
.globalInstance().start(task
)
555 def setup_dockwidget_tools_menu(self
):
556 # Hotkeys for toggling the dock widgets
558 (self
.logdockwidget
, 'Alt+0'),
559 (self
.commitdockwidget
, 'Alt+1'),
560 (self
.statusdockwidget
, 'Alt+2'),
561 (self
.diffdockwidget
, 'Alt+3'),
562 (self
.actionsdockwidget
, 'Alt+4'),
564 for dockwidget
, shortcut
in dockwidgets
:
565 # Associate the action with the shortcut
566 action
= dockwidget
.toggleViewAction()
567 action
.setShortcut(shortcut
)
568 self
.tools_menu
.addAction(action
)
569 def showdock(show
, dockwidget
=dockwidget
):
572 dockwidget
.widget().setFocus(True)
575 self
.addAction(action
)
576 connect_action_bool(action
, showdock
)
578 # Create a new shortcut Shift+<shortcut> that gives focus
579 action
= QtGui
.QAction(self
)
580 action
.setShortcut('Shift+' + shortcut
)
581 def focusdock(dockwidget
=dockwidget
, showdock
=showdock
):
582 if dockwidget
.toggleViewAction().isChecked():
585 dockwidget
.toggleViewAction().trigger()
586 self
.addAction(action
)
587 connect_action(action
, focusdock
)
589 def save_archive(self
):
590 ref
= git
.rev_parse('HEAD')
592 GitArchiveDialog
.save(ref
, shortref
, self
)
595 """Stage selected files, or all files if no selection exists."""
596 paths
= cola
.selection_model().unstaged
598 cola
.notifier().broadcast(signals
.stage_modified
)
600 cola
.notifier().broadcast(signals
.stage
, paths
)
603 """Unstage selected files, or all files if no selection exists."""
604 paths
= cola
.selection_model().staged
606 cola
.notifier().broadcast(signals
.unstage_all
)
608 cola
.notifier().broadcast(signals
.unstage
, paths
)
610 def dragEnterEvent(self
, event
):
612 standard
.MainWindow
.dragEnterEvent(self
, event
)
613 event
.acceptProposedAction()
615 def dropEvent(self
, event
):
616 """Apply dropped patches with git-am"""
618 urls
= event
.mimeData().urls()
621 paths
= map(lambda x
: unicode(x
.path()), urls
)
622 patches
= [p
for p
in paths
if p
.endswith('.patch')]
623 dirs
= [p
for p
in paths
if os
.path
.isdir(p
)]
626 patches
.extend(self
._gather
_patches
(d
))
627 # Broadcast the patches to apply
628 cola
.notifier().broadcast(signals
.apply_patches
, patches
)
630 def _gather_patches(self
, path
):
631 """Find patches in a subdirectory"""
633 for root
, subdirs
, files
in os
.walk(path
):
634 for name
in [f
for f
in files
if f
.endswith('.patch')]:
635 patches
.append(os
.path
.join(root
, name
))
638 def show_cursor_position(self
, rows
, cols
):
639 display
= ' %02d:%02d ' % (rows
, cols
)
641 display
= ('<span style="color: white; '
642 ' background-color: red;"'
643 '>%s</span>' % display
)
645 display
= ('<span style="color: black; '
646 ' background-color: orange;"'
647 '>%s</span>' % display
)
649 display
= ('<span style="color: black; '
650 ' background-color: yellow;"'
651 '>%s</span>' % display
)
653 display
= ('<span style="color: grey;">%s</span>' % display
)
655 self
.position_label
.setText(display
)