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
.widgets
import cfgactions
45 from cola
.widgets
import remote
46 from cola
.widgets
import standard
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 super(MainView
, self
).__init
__(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)
76 self
.setAttribute(Qt
.WA_MacMetalStyle
)
79 qtcompat
.set_common_dock_options(self
)
81 cfg
= gitcfg
.instance()
82 self
.classic_dockable
= cfg
.get('cola.browserdockable')
84 if self
.classic_dockable
:
85 self
.classicdockwidget
= create_dock('Browser', self
)
86 self
.classicwidget
= classic_widget(self
)
87 self
.classicdockwidget
.setWidget(self
.classicwidget
)
90 self
.actionsdockwidget
= create_dock('Action', self
)
91 self
.actionsdockwidgetcontents
= qt
.QFlowLayoutWidget(self
)
92 layout
= self
.actionsdockwidgetcontents
.layout()
93 self
.stage_button
= create_button(text
='Stage', layout
=layout
)
94 self
.unstage_button
= create_button(text
='Unstage', layout
=layout
)
95 self
.rescan_button
= create_button(text
='Rescan', layout
=layout
)
96 self
.fetch_button
= create_button(text
='Fetch...', layout
=layout
)
97 self
.push_button
= create_button(text
='Push...', layout
=layout
)
98 self
.pull_button
= create_button(text
='Pull...', layout
=layout
)
99 self
.stash_button
= create_button(text
='Stash...', layout
=layout
)
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
.diff_revision
)
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 'Browser...', 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_observer(model
.message_updated
, self
._update
_view
)
393 prefs_model
.add_observer(prefs_model
.message_config_updated
,
394 self
._config
_updated
)
396 # Set a default value
397 self
.show_cursor_position(1, 0)
399 # Add button callbacks
400 connect_button(self
.rescan_button
,
401 emit(self
, signals
.rescan_and_refresh
))
402 connect_button(self
.fetch_button
, remote
.fetch
)
403 connect_button(self
.push_button
, remote
.push
)
404 connect_button(self
.pull_button
, remote
.pull
)
405 connect_button(self
.stash_button
, stash
.stash
)
407 connect_button(self
.stage_button
, self
.stage
)
408 connect_button(self
.unstage_button
, self
.unstage
)
410 self
.connect(self
.commitmsgeditor
, SIGNAL('cursorPosition(int,int)'),
411 self
.show_cursor_position
)
412 self
.connect(self
, SIGNAL('update'), self
._update
_callback
)
413 self
.connect(self
, SIGNAL('apply_state'), self
.apply_state
)
414 self
.connect(self
, SIGNAL('install_config_actions'),
415 self
._install
_config
_actions
)
417 # Install .git-config-defined actions
418 self
._config
_task
= None
419 self
.install_config_actions()
421 # Restore saved settings
422 self
._gui
_state
_task
= None
423 self
._load
_gui
_state
()
425 log(0, version
.git_version_str() + '\ncola version ' + version
.version())
428 def closeEvent(self
, event
):
429 """Save state in the settings manager."""
430 qtutils
.save_state(self
)
431 standard
.MainWindow
.closeEvent(self
, event
)
434 mode
= property(lambda self
: self
.model
.mode
)
436 def _config_updated(self
, source
, config
, value
):
437 if config
== 'cola.fontdiff':
439 if not font
.fromString(value
):
441 qtutils
.logger().setFont(font
)
442 self
.diff_editor
.setFont(font
)
443 self
.commitmsgeditor
.setFont(font
)
445 elif config
== 'cola.tabwidth':
446 # variable-tab-width setting
447 self
.diff_editor
.set_tab_width(value
)
449 def install_config_actions(self
):
450 """Install .gitconfig-defined actions"""
451 self
._config
_task
= self
._start
_config
_actions
_task
()
453 def _start_config_actions_task(self
):
454 """Do the expensive "get_config_actions()" call in the background"""
455 class ConfigActionsTask(QtCore
.QRunnable
):
456 def __init__(self
, sender
):
457 QtCore
.QRunnable
.__init
__(self
)
458 self
._sender
= sender
460 names
= cfgactions
.get_config_actions()
461 self
._sender
.emit(SIGNAL('install_config_actions'), names
)
463 task
= ConfigActionsTask(self
)
464 QtCore
.QThreadPool
.globalInstance().start(task
)
467 def _install_config_actions(self
, names
):
468 """Install .gitconfig-defined actions"""
471 menu
= self
.actions_menu
474 menu
.addAction(name
, emit(self
, signals
.run_config_action
, name
))
476 def _update_view(self
):
477 self
.emit(SIGNAL('update'))
479 def _update_callback(self
):
480 """Update the title with the current branch and directory name."""
481 branch
= self
.model
.currentbranch
482 curdir
= core
.decode(os
.getcwd())
483 msg
= 'Repository: %s\nBranch: %s' % (curdir
, branch
)
484 self
.commitdockwidget
.setToolTip(msg
)
486 title
= '%s: %s' % (self
.model
.project
, branch
)
487 if self
.mode
== self
.model
.mode_amend
:
488 title
+= ' ** amending **'
489 self
.setWindowTitle(title
)
491 self
.commitmsgeditor
.set_mode(self
.mode
)
493 if not self
.model
.read_only() and self
.mode
!= self
.model
.mode_amend
:
494 # Check if there's a message file in .git/
495 merge_msg_path
= gitcmds
.merge_message_path()
496 if merge_msg_path
is None:
498 merge_msg_hash
= utils
.checksum(core
.decode(merge_msg_path
))
499 if merge_msg_hash
== self
.merge_message_hash
:
501 self
.merge_message_hash
= merge_msg_hash
502 cola
.notifier().broadcast(signals
.load_commit_message
,
503 core
.decode(merge_msg_path
))
505 def apply_state(self
, state
):
506 """Imports data for save/restore"""
507 # 1 is the widget version; change when widgets are added/removed
508 standard
.MainWindow
.apply_state(self
, state
)
509 qtutils
.apply_window_state(self
, state
, 1)
511 def export_state(self
):
512 """Exports data for save/restore"""
513 state
= standard
.MainWindow
.export_state(self
)
514 return qtutils
.export_window_state(self
, state
, self
.widget_version
)
516 def _load_gui_state(self
):
517 """Restores the gui from the preferences file."""
518 self
._gui
_state
_task
= self
._start
_gui
_state
_loading
_thread
()
520 def _start_gui_state_loading_thread(self
):
521 """Do expensive file reading and json decoding in the background"""
522 class LoadGUIStateTask(QtCore
.QRunnable
):
523 def __init__(self
, sender
):
524 QtCore
.QRunnable
.__init
__(self
)
525 self
._sender
= sender
527 state
= settings
.Settings().get_gui_state(self
._sender
)
528 self
._sender
.emit(SIGNAL('apply_state'), state
)
530 task
= LoadGUIStateTask(self
)
531 QtCore
.QThreadPool
.globalInstance().start(task
)
534 def setup_dockwidget_tools_menu(self
):
535 # Hotkeys for toggling the dock widgets
537 (self
.logdockwidget
, 'Alt+0'),
538 (self
.commitdockwidget
, 'Alt+1'),
539 (self
.statusdockwidget
, 'Alt+2'),
540 (self
.diffdockwidget
, 'Alt+3'),
541 (self
.actionsdockwidget
, 'Alt+4'),
543 for dockwidget
, shortcut
in dockwidgets
:
544 # Associate the action with the shortcut
545 action
= dockwidget
.toggleViewAction()
546 action
.setShortcut(shortcut
)
547 self
.tools_menu
.addAction(action
)
548 def showdock(show
, dockwidget
=dockwidget
):
551 dockwidget
.widget().setFocus(True)
554 self
.addAction(action
)
555 connect_action_bool(action
, showdock
)
557 # Create a new shortcut Shift+<shortcut> that gives focus
558 action
= QtGui
.QAction(self
)
559 action
.setShortcut('Shift+' + shortcut
)
560 def focusdock(dockwidget
=dockwidget
, showdock
=showdock
):
561 if dockwidget
.toggleViewAction().isChecked():
564 dockwidget
.toggleViewAction().trigger()
565 self
.addAction(action
)
566 connect_action(action
, focusdock
)
568 def save_archive(self
):
569 ref
= git
.rev_parse('HEAD')
571 GitArchiveDialog
.save(ref
, shortref
, self
)
574 """Stage selected files, or all files if no selection exists."""
575 paths
= cola
.selection_model().unstaged
577 cola
.notifier().broadcast(signals
.stage_modified
)
579 cola
.notifier().broadcast(signals
.stage
, paths
)
582 """Unstage selected files, or all files if no selection exists."""
583 paths
= cola
.selection_model().staged
585 cola
.notifier().broadcast(signals
.unstage_all
)
587 cola
.notifier().broadcast(signals
.unstage
, paths
)
589 def dragEnterEvent(self
, event
):
591 standard
.MainWindow
.dragEnterEvent(self
, event
)
592 event
.acceptProposedAction()
594 def dropEvent(self
, event
):
595 """Apply dropped patches with git-am"""
597 urls
= event
.mimeData().urls()
600 paths
= map(lambda x
: unicode(x
.path()), urls
)
601 patches
= [p
for p
in paths
if p
.endswith('.patch')]
602 dirs
= [p
for p
in paths
if os
.path
.isdir(p
)]
605 patches
.extend(self
._gather
_patches
(d
))
606 # Broadcast the patches to apply
607 cola
.notifier().broadcast(signals
.apply_patches
, patches
)
609 def _gather_patches(self
, path
):
610 """Find patches in a subdirectory"""
612 for root
, subdirs
, files
in os
.walk(path
):
613 for name
in [f
for f
in files
if f
.endswith('.patch')]:
614 patches
.append(os
.path
.join(root
, name
))
617 def show_cursor_position(self
, rows
, cols
):
618 display
= ' %02d:%02d ' % (rows
, cols
)
620 display
= ('<span style="color: white; '
621 ' background-color: red;"'
622 '>%s</span>' % display
)
624 display
= ('<span style="color: black; '
625 ' background-color: orange;"'
626 '>%s</span>' % display
)
628 display
= ('<span style="color: black; '
629 ' background-color: yellow;"'
630 '>%s</span>' % display
)
632 display
= ('<span style="color: grey;">%s</span>' % display
)
634 self
.position_label
.setText(display
)