2626import webbrowser
2727
2828from gettext import gettext as _
29- from typing import Optional
29+ from typing import List , Optional
3030from urllib .parse import urlparse
3131
3232from diffuse import constants
3535from diffuse .preferences import Preferences
3636from diffuse .resources import theResources
3737from diffuse .utils import LineEnding
38+ from diffuse .vcs .vcs_interface import VcsInterface
3839from diffuse .vcs .vcs_registry import VcsRegistry
39- from diffuse .widgets import FileDiffViewerBase
40- from diffuse .widgets import createMenu , LINE_MODE , CHAR_MODE , ALIGN_MODE
40+ from diffuse .widgets import FileDiffViewerBase , EditMode
41+ from diffuse .widgets import createMenu
4142
4243import gi # type: ignore
4344gi .require_version ('GObject' , '2.0' )
5758# make this a Gtk.EventBox so signals can be connected for MMB and RMB button
5859# presses.
5960class NotebookTab (Gtk .EventBox ):
60- def __init__ (self , name , stock ) :
61+ def __init__ (self , name : str , stock : str ) -> None :
6162 Gtk .EventBox .__init__ (self )
6263 self .set_visible_window (False )
6364 hbox = Gtk .Box .new (Gtk .Orientation .HORIZONTAL , 0 )
@@ -66,13 +67,16 @@ def __init__(self, name, stock):
6667 image .set_from_stock (stock , Gtk .IconSize .MENU )
6768 hbox .pack_start (image , False , False , 5 )
6869 image .show ()
69- self .label = label = Gtk .Label .new (name )
70+
71+ label = Gtk .Label .new (name )
7072 # left justify the widget
7173 label .set_xalign (0.0 )
7274 label .set_yalign (0.5 )
7375 hbox .pack_start (label , True , True , 0 )
7476 label .show ()
75- self .button = button = Gtk .Button .new ()
77+ self .label = label
78+
79+ button = Gtk .Button .new ()
7680 button .set_relief (Gtk .ReliefStyle .NONE )
7781 image = Gtk .Image .new ()
7882 image .set_from_stock (Gtk .STOCK_CLOSE , Gtk .IconSize .MENU )
@@ -81,13 +85,15 @@ def __init__(self, name, stock):
8185 button .set_tooltip_text (_ ('Close Tab' ))
8286 hbox .pack_start (button , False , False , 0 )
8387 button .show ()
88+ self .button = button
89+
8490 self .add (hbox )
8591 hbox .show ()
8692
87- def get_text (self ):
93+ def get_text (self ) -> str :
8894 return self .label .get_text ()
8995
90- def set_text (self , s ) :
96+ def set_text (self , s : str ) -> None :
9197 self .label .set_text (s )
9298
9399
@@ -99,7 +105,7 @@ def __init__(self, name=None, encoding=None, vcs=None, revision=None, label=None
99105 # name of codec used to translate the file contents to unicode text
100106 self .encoding = encoding
101107 # the VCS object
102- self .vcs = vcs
108+ self .vcs : VcsInterface = vcs
103109 # revision used to retrieve file from the VCS
104110 self .revision = revision
105111 # alternate text to display instead of the actual file name
@@ -147,7 +153,7 @@ def button_cb(self, widget, s):
147153 self .emit (s )
148154
149155 # creates an appropriate title for the pane header
150- def updateTitle (self ):
156+ def updateTitle (self ) -> None :
151157 ss = []
152158 info = self .info
153159 if info .label is not None :
@@ -166,7 +172,7 @@ def updateTitle(self):
166172 self .emit ('title_changed' )
167173
168174 # set num edits
169- def setEdits (self , has_edits ) :
175+ def setEdits (self , has_edits : bool ) -> None :
170176 if self .has_edits != has_edits :
171177 self .has_edits = has_edits
172178 self .updateTitle ()
@@ -198,8 +204,8 @@ def __init__(self) -> None:
198204 self .show_all ()
199205
200206 # set the cursor label
201- def updateCursor (self , viewer , f ) :
202- if viewer .mode == CHAR_MODE and viewer .current_pane == f :
207+ def updateCursor (self , viewer : FileDiffViewerBase , f : int ) -> None :
208+ if viewer .mode == EditMode . CHAR and viewer .current_pane == f :
203209 # # TODO: Find a fix for the column bug (resizing issue when editing a line)
204210 # j = viewer.current_char
205211 # if j > 0:
@@ -212,7 +218,7 @@ def updateCursor(self, viewer, f):
212218 self .cursor .set_text (s )
213219
214220 # set the format label
215- def setFormat (self , s ) :
221+ def setFormat (self , s : LineEnding ) -> None :
216222 v = []
217223 if s & LineEnding .DOS_FORMAT :
218224 v .append ('DOS' )
@@ -223,19 +229,19 @@ def setFormat(self, s):
223229 self .format .set_text ('/' .join (v ))
224230
225231 # set the format label
226- def setEncoding (self , s ) :
232+ def setEncoding (self , s : str ) -> None :
227233 if s is None :
228234 s = ''
229235 self .encoding .set_text (s )
230236
231- def __init__ (self , n , prefs , title ) :
232- FileDiffViewerBase .__init__ (self , n , prefs )
237+ def __init__ (self , n : int , prefs : Preferences , title : str ) -> None :
238+ super () .__init__ (n , prefs )
233239
234240 self .title = title
235- self .status = ''
241+ self .status : Optional [ str ] = ''
236242
237- self .headers = []
238- self .footers = []
243+ self .headers : List [ Diffuse . FileDiffViewer . PaneHeader ] = []
244+ self .footers : List [ Diffuse . FileDiffViewer . PaneFooter ] = []
239245 for i in range (n ):
240246 # pane header
241247 w = Diffuse .FileDiffViewer .PaneHeader ()
@@ -272,7 +278,7 @@ def __init__(self, n, prefs, title):
272278
273279 # convenience method to request confirmation before loading a file if
274280 # it will cause existing edits to be lost
275- def loadFromInfo (self , f , info ) :
281+ def loadFromInfo (self , f : int , info : FileInfo ) -> None :
276282 if self .headers [f ].has_edits :
277283 # warn users of any unsaved changes they might lose
278284 dialog = Gtk .MessageDialog (
@@ -358,7 +364,7 @@ def setEncoding(self, f, encoding):
358364 # load a new file into pane 'f'
359365 # 'info' indicates the name of the file and how to retrieve it from the
360366 # version control system if applicable
361- def load (self , f , info ) :
367+ def load (self , f : int , info : FileInfo ) -> None :
362368 name = info .name
363369 encoding = info .encoding
364370 stat = None
@@ -371,20 +377,20 @@ def load(self, f, info):
371377 if rev is None :
372378 # load the contents of a plain file
373379 with open (name , 'rb' ) as fd :
374- s = fd .read ()
380+ contents = fd .read ()
375381 # get the file's modification times so we can detect changes
376382 stat = os .stat (name )
377383 else :
378384 if info .vcs is None :
379385 raise IOError ('Not under version control.' )
380386 fullname = os .path .abspath (name )
381387 # retrieve the revision from the version control system
382- s = info .vcs .getRevision (self .prefs , fullname , rev )
388+ contents = info .vcs .getRevision (self .prefs , fullname , rev )
383389 # convert file contents to unicode
384390 if encoding is None :
385- s , encoding = self .prefs .convertToUnicode (s )
391+ s , encoding = self .prefs .convertToUnicode (contents )
386392 else :
387- s = str (s , encoding = encoding )
393+ s = str (contents , encoding = encoding )
388394 ss = utils .splitlines (s )
389395 except (IOError , OSError , UnicodeDecodeError , LookupError ):
390396 # FIXME: this can occur before the toplevel window is drawn
@@ -408,7 +414,7 @@ def load(self, f, info):
408414 self .setSyntax (syntax )
409415
410416 # load a new file into pane 'f'
411- def open_file (self , f , reload = False ):
417+ def open_file (self , f : int , reload : bool = False ) -> None :
412418 h = self .headers [f ]
413419 info = h .info
414420 if not reload :
@@ -487,7 +493,7 @@ def focus_in(self, widget, event):
487493 pass
488494
489495 # save contents of pane 'f' to file
490- def save_file (self , f , save_as = False ):
496+ def save_file (self , f : int , save_as : bool = False ) -> bool :
491497 h = self .headers [f ]
492498 info = h .info
493499 name , encoding , rev , label = info .name , info .encoding , info .revision , info .label
@@ -642,15 +648,15 @@ def mode_changed_cb(self, widget):
642648 self .updateStatus ()
643649
644650 # update the viewer's current status message
645- def updateStatus (self ):
646- if self .mode == LINE_MODE :
651+ def updateStatus (self ) -> None :
652+ if self .mode == EditMode . LINE :
647653 s = _ (
648654 'Press the enter key or double click to edit. Press the space bar or use the '
649655 'RMB menu to manually align.'
650656 )
651- elif self .mode == CHAR_MODE :
657+ elif self .mode == EditMode . CHAR :
652658 s = _ ('Press the escape key to finish editing.' )
653- elif self .mode == ALIGN_MODE :
659+ elif self .mode == EditMode . ALIGN :
654660 s = _ (
655661 'Select target line and press the space bar to align. Press the escape key to '
656662 'cancel.'
@@ -661,7 +667,7 @@ def updateStatus(self):
661667 self .emit ('status_changed' , s )
662668
663669 # gets the status bar text
664- def getStatus (self ):
670+ def getStatus (self ) -> Optional [ str ] :
665671 return self .status
666672
667673 # callback to display the cursor in a pane
@@ -674,7 +680,7 @@ def format_changed_cb(self, widget, f, fmt):
674680 self .footers [f ].setFormat (fmt )
675681
676682 def __init__ (self , rc_dir ):
677- Gtk . Window . __init__ (self , type = Gtk .WindowType .TOPLEVEL )
683+ super (). __init__ (type = Gtk .WindowType .TOPLEVEL )
678684
679685 self .prefs = Preferences (os .path .join (rc_dir , 'prefs' ))
680686 # number of created viewers (used to label some tabs)
@@ -702,8 +708,8 @@ def __init__(self, rc_dir):
702708 self .connect ('window-state-event' , self .window_state_cb )
703709
704710 # search history is application wide
705- self .search_pattern = None
706- self .search_history = []
711+ self .search_pattern : Optional [ str ] = None
712+ self .search_history : List [ str ] = []
707713
708714 self .connect ('delete-event' , self .delete_cb )
709715 accel_group = Gtk .AccelGroup ()
@@ -968,7 +974,7 @@ def window_state_cb(self, window, event):
968974 )
969975
970976 # load state information that should persist across sessions
971- def loadState (self , statepath ) :
977+ def loadState (self , statepath : str ) -> None :
972978 if os .path .isfile (statepath ):
973979 try :
974980 f = open (statepath , 'r' )
@@ -998,7 +1004,7 @@ def loadState(self, statepath):
9981004 self .maximize ()
9991005
10001006 # save state information that should persist across sessions
1001- def saveState (self , statepath ) :
1007+ def saveState (self , statepath : str ) -> None :
10021008 try :
10031009 ss = []
10041010 for k , v in self .bool_state .items ():
@@ -1025,7 +1031,7 @@ def _confirmClose_toggle_cb(self, cell, path, model):
10251031
10261032 # returns True if the list of viewers can be closed. The user will be
10271033 # given a chance to save any modified files before this method completes.
1028- def confirmCloseViewers (self , viewers ) :
1034+ def confirmCloseViewers (self , viewers : List [ FileDiffViewer ]) -> bool :
10291035 # make a list of modified files
10301036 model = Gtk .ListStore .new ([
10311037 GObject .TYPE_BOOLEAN ,
@@ -1144,12 +1150,12 @@ def notebooktab_button_press_cb(self, widget, event, data):
11441150 menu .popup (None , None , None , event .button , event .time )
11451151
11461152 # update window's title
1147- def updateTitle (self , viewer ) :
1153+ def updateTitle (self , viewer : FileDiffViewer ) -> None :
11481154 title = self .notebook .get_tab_label (viewer ).get_text ()
11491155 self .set_title (f'{ title } - { constants .APP_NAME } ' )
11501156
11511157 # update the message in the status bar
1152- def setStatus (self , s ) :
1158+ def setStatus (self , s : Optional [ str ]) -> None :
11531159 sb = self .statusbar
11541160 context = sb .get_context_id ('Message' )
11551161 sb .pop (context )
@@ -1358,7 +1364,7 @@ def delete_cb(self, widget, event):
13581364 return True
13591365
13601366 # returns the currently focused viewer
1361- def getCurrentViewer (self ) -> Optional [ Gtk . Widget ] :
1367+ def getCurrentViewer (self ) -> FileDiffViewer :
13621368 return self .notebook .get_nth_page (self .notebook .get_current_page ())
13631369
13641370 # callback for the open file menu item
@@ -1504,7 +1510,7 @@ def quit_cb(self, widget, data):
15041510
15051511 # request search parameters if force=True and then perform a search in the
15061512 # current viewer pane
1507- def find (self , force , reverse ) :
1513+ def find (self , force : bool , reverse : bool ) -> None :
15081514 viewer = self .getCurrentViewer ()
15091515 if force or self .search_pattern is None :
15101516 # construct search dialog
0 commit comments