5151
5252theVCSs = VcsRegistry ()
5353
54- # convenience method for creating a menu bar according to a template
55- def createMenuBar (specs , radio , accel_group ):
56- menu_bar = Gtk .MenuBar .new ()
57- for label , spec in specs :
58- menu = Gtk .MenuItem .new_with_mnemonic (label )
59- menu .set_submenu (utils .createMenu (spec , radio , accel_group ))
60- menu .set_use_underline (True )
61- menu .show ()
62- menu_bar .append (menu )
63- return menu_bar
64-
65- # convenience method for packing buttons into a container according to a
66- # template
67- def appendButtons (box , size , specs ):
68- for spec in specs :
69- if len (spec ) > 0 :
70- button = Gtk .Button .new ()
71- button .set_relief (Gtk .ReliefStyle .NONE )
72- button .set_can_focus (False )
73- image = Gtk .Image .new ()
74- image .set_from_stock (spec [0 ], size )
75- button .add (image )
76- image .show ()
77- if len (spec ) > 2 :
78- button .connect ('clicked' , spec [1 ], spec [2 ])
79- if len (spec ) > 3 :
80- button .set_tooltip_text (spec [3 ])
81- box .pack_start (button , False , False , 0 )
82- button .show ()
83- else :
84- separator = Gtk .Separator .new (Gtk .Orientation .VERTICAL )
85- box .pack_start (separator , False , False , 5 )
86- separator .show ()
87-
88- # constructs a full URL for the named file
89- def path2url (path , proto = 'file' ):
90- r = [ proto , ':///' ]
91- s = os .path .abspath (path )
92- i = 0
93- while i < len (s ) and s [i ] == os .sep :
94- i += 1
95- for c in s [i :]:
96- if c == os .sep :
97- c = '/'
98- elif c == ':' and utils .isWindows ():
99- c = '|'
100- else :
101- v = ord (c )
102- if v <= 0x20 or v >= 0x7b or c in '$&+,/:;=?@"<>#%\\ ^[]`' :
103- c = '%%%02X' % (v , )
104- r .append (c )
105- return '' .join (r )
106-
107- # convenience method to request confirmation when closing the last tab
108- def confirmTabClose (parent ):
109- dialog = utils .MessageDialog (parent , Gtk .MessageType .WARNING , _ ('Closing this tab will quit %s.' ) % (constants .APP_NAME , ))
110- end = (dialog .run () == Gtk .ResponseType .OK )
111- dialog .destroy ()
112- return end
113-
11454# widget classed to create notebook tabs with labels and a close button
11555# use notebooktab.button.connect() to be notified when the button is pressed
11656# make this a Gtk.EventBox so signals can be connected for MMB and RMB button
@@ -169,18 +109,6 @@ def __init__(self, name=None, encoding=None, vcs=None, revision=None, label=None
169109 # to warn about changes to file on disk
170110 self .last_stat = None
171111
172- # assign user specified labels to the corresponding files
173- def assign_file_labels (items , labels ):
174- new_items = []
175- ss = labels [::- 1 ]
176- for name , data in items :
177- if ss :
178- s = ss .pop ()
179- else :
180- s = None
181- new_items .append ((name , data , s ))
182- return new_items
183-
184112# the main application class containing a set of file viewers
185113# this class displays tab for switching between viewers and dispatches menu
186114# commands to the current viewer
@@ -191,7 +119,7 @@ class FileDiffViewer(FileDiffViewer):
191119 class PaneHeader (Gtk .Box ):
192120 def __init__ (self ):
193121 Gtk .Box .__init__ (self , orientation = Gtk .Orientation .HORIZONTAL , spacing = 0 )
194- appendButtons (self , Gtk .IconSize .MENU , [
122+ _append_buttons (self , Gtk .IconSize .MENU , [
195123 [ Gtk .STOCK_OPEN , self .button_cb , 'open' , _ ('Open File...' ) ],
196124 [ Gtk .STOCK_REFRESH , self .button_cb , 'reload' , _ ('Reload File' ) ],
197125 [ Gtk .STOCK_SAVE , self .button_cb , 'save' , _ ('Save File' ) ],
@@ -430,9 +358,8 @@ def load(self, f, info):
430358 try :
431359 if rev is None :
432360 # load the contents of a plain file
433- fd = open (name , 'rb' )
434- s = fd .read ()
435- fd .close ()
361+ with open (name , 'rb' ) as fd :
362+ s = fd .read ()
436363 # get the file's modification times so we can detect changes
437364 stat = os .stat (name )
438365 else :
@@ -596,9 +523,8 @@ def save_file(self, f, save_as=False):
596523 encoded = codecs .encode ('' .join (ss ), encoding )
597524
598525 # write file
599- fd = open (name , 'wb' )
600- fd .write (encoded )
601- fd .close ()
526+ with open (name , 'wb' ) as fd :
527+ fd .write (encoded )
602528
603529 # make the edits look permanent
604530 self .openUndoBlock ()
@@ -691,8 +617,8 @@ def cursor_changed_cb(self, widget):
691617 footer .updateCursor (self , f )
692618
693619 # callback to display the format of a pane
694- def format_changed_cb (self , widget , f , format ):
695- self .footers [f ].setFormat (format )
620+ def format_changed_cb (self , widget , f , fmt ):
621+ self .footers [f ].setFormat (fmt )
696622
697623 def __init__ (self , rc_dir ):
698624 Gtk .Window .__init__ (self , type = Gtk .WindowType .TOPLEVEL )
@@ -888,13 +814,13 @@ def __init__(self, rc_dir):
888814 # build list of radio menu items so we can update them to match the
889815 # currently viewed pane
890816 self .radio_menus = radio_menus = {}
891- menu_bar = createMenuBar (menuspecs , radio_menus , accel_group )
817+ menu_bar = _create_menu_bar (menuspecs , radio_menus , accel_group )
892818 vbox .pack_start (menu_bar , False , False , 0 )
893819 menu_bar .show ()
894820
895821 # create button bar
896822 hbox = Gtk .Box .new (Gtk .Orientation .HORIZONTAL , 0 )
897- appendButtons (hbox , Gtk .IconSize .LARGE_TOOLBAR , [
823+ _append_buttons (hbox , Gtk .IconSize .LARGE_TOOLBAR , [
898824 [ DIFFUSE_STOCK_NEW_2WAY_MERGE , self .new_2_way_file_merge_cb , None , _ ('New 2-Way File Merge' ) ],
899825 [ DIFFUSE_STOCK_NEW_3WAY_MERGE , self .new_3_way_file_merge_cb , None , _ ('New 3-Way File Merge' ) ],
900826 [],
@@ -1096,9 +1022,16 @@ def remove_tab_cb(self, widget, data):
10961022 self .closed_tabs .append ((nb .page_num (data ), data , nb .get_tab_label (data )))
10971023 nb .remove (data )
10981024 nb .set_show_tabs (self .prefs .getBool ('tabs_always_show' ) or nb .get_n_pages () > 1 )
1099- elif not self .prefs .getBool ('tabs_warn_before_quit' ) or confirmTabClose ( self .get_toplevel () ):
1025+ elif not self .prefs .getBool ('tabs_warn_before_quit' ) or self ._confirm_tab_close ( ):
11001026 self .quit_cb (widget , data )
11011027
1028+ # convenience method to request confirmation when closing the last tab
1029+ def _confirm_tab_close (self ):
1030+ dialog = utils .MessageDialog (self .get_toplevel (), Gtk .MessageType .WARNING , _ ('Closing this tab will quit %s.' ) % (constants .APP_NAME , ))
1031+ end = (dialog .run () == Gtk .ResponseType .OK )
1032+ dialog .destroy ()
1033+ return end
1034+
11021035 # callback for RMB menu on notebook tabs
11031036 def notebooktab_pick_cb (self , widget , data ):
11041037 self .notebook .set_current_page (data )
@@ -1243,13 +1176,13 @@ def newLoadedFileDiffViewer(self, items):
12431176 # create a new viewer for 'items'
12441177 def createSingleTab (self , items , labels , options ):
12451178 if len (items ) > 0 :
1246- self .newLoadedFileDiffViewer (assign_file_labels (items , labels )).setOptions (options )
1179+ self .newLoadedFileDiffViewer (_assign_file_labels (items , labels )).setOptions (options )
12471180
12481181 # create a new viewer for each item in 'items'
12491182 def createSeparateTabs (self , items , labels , options ):
12501183 # all tabs inherit the first tab's revision and encoding specifications
12511184 items = [ (name , items [0 ][1 ]) for name , data in items ]
1252- for item in assign_file_labels (items , labels ):
1185+ for item in _assign_file_labels (items , labels ):
12531186 self .newLoadedFileDiffViewer ([ item ]).setOptions (options )
12541187
12551188 # create a new viewer for each modified file found in 'items'
@@ -1564,7 +1497,7 @@ def help_contents_cb(self, widget, data):
15641497 help_file = os .path .join (utils .bin_dir , '_' .join (parts ) + '.html' )
15651498 if os .path .isfile (help_file ):
15661499 # we found a help file
1567- help_url = path2url (help_file )
1500+ help_url = _path2url (help_file )
15681501 break
15691502 del parts [- 1 ]
15701503 else :
@@ -1592,7 +1525,7 @@ def help_contents_cb(self, widget, data):
15921525 d = 'C'
15931526 help_file = os .path .join (os .path .join (s , d ), 'diffuse.xml' )
15941527 if os .path .isfile (help_file ):
1595- args = [ browser , path2url (help_file , 'ghelp' ) ]
1528+ args = [ browser , _path2url (help_file , 'ghelp' ) ]
15961529 # spawnvp is not available on some systems, use spawnv instead
15971530 os .spawnv (os .P_NOWAIT , args [0 ], args )
15981531 return
@@ -1614,6 +1547,71 @@ def about_cb(self, widget, data):
16141547 dialog .run ()
16151548 dialog .destroy ()
16161549
1550+ # convenience method for creating a menu bar according to a template
1551+ def _create_menu_bar (specs , radio , accel_group ):
1552+ menu_bar = Gtk .MenuBar .new ()
1553+ for label , spec in specs :
1554+ menu = Gtk .MenuItem .new_with_mnemonic (label )
1555+ menu .set_submenu (utils .createMenu (spec , radio , accel_group ))
1556+ menu .set_use_underline (True )
1557+ menu .show ()
1558+ menu_bar .append (menu )
1559+ return menu_bar
1560+
1561+ # convenience method for packing buttons into a container according to a
1562+ # template
1563+ def _append_buttons (box , size , specs ):
1564+ for spec in specs :
1565+ if len (spec ) > 0 :
1566+ button = Gtk .Button .new ()
1567+ button .set_relief (Gtk .ReliefStyle .NONE )
1568+ button .set_can_focus (False )
1569+ image = Gtk .Image .new ()
1570+ image .set_from_stock (spec [0 ], size )
1571+ button .add (image )
1572+ image .show ()
1573+ if len (spec ) > 2 :
1574+ button .connect ('clicked' , spec [1 ], spec [2 ])
1575+ if len (spec ) > 3 :
1576+ button .set_tooltip_text (spec [3 ])
1577+ box .pack_start (button , False , False , 0 )
1578+ button .show ()
1579+ else :
1580+ separator = Gtk .Separator .new (Gtk .Orientation .VERTICAL )
1581+ box .pack_start (separator , False , False , 5 )
1582+ separator .show ()
1583+
1584+ # constructs a full URL for the named file
1585+ def _path2url (path , proto = 'file' ):
1586+ r = [ proto , ':///' ]
1587+ s = os .path .abspath (path )
1588+ i = 0
1589+ while i < len (s ) and s [i ] == os .sep :
1590+ i += 1
1591+ for c in s [i :]:
1592+ if c == os .sep :
1593+ c = '/'
1594+ elif c == ':' and utils .isWindows ():
1595+ c = '|'
1596+ else :
1597+ v = ord (c )
1598+ if v <= 0x20 or v >= 0x7b or c in '$&+,/:;=?@"<>#%\\ ^[]`' :
1599+ c = '%%%02X' % (v , )
1600+ r .append (c )
1601+ return '' .join (r )
1602+
1603+ # assign user specified labels to the corresponding files
1604+ def _assign_file_labels (items , labels ):
1605+ new_items = []
1606+ ss = labels [::- 1 ]
1607+ for name , data in items :
1608+ if ss :
1609+ s = ss .pop ()
1610+ else :
1611+ s = None
1612+ new_items .append ((name , data , s ))
1613+ return new_items
1614+
16171615GObject .signal_new ('title-changed' , Diffuse .FileDiffViewer , GObject .SignalFlags .RUN_LAST , GObject .TYPE_NONE , (str , ))
16181616GObject .signal_new ('status-changed' , Diffuse .FileDiffViewer , GObject .SignalFlags .RUN_LAST , GObject .TYPE_NONE , (str , ))
16191617GObject .signal_new ('title-changed' , Diffuse .FileDiffViewer .PaneHeader , GObject .SignalFlags .RUN_LAST , GObject .TYPE_NONE , ())
0 commit comments