3333"""
3434
3535import argparse
36+ import copy
3637from dataclasses import dataclass
3738import difflib
3839import logging
@@ -113,6 +114,11 @@ def __init__(self, **kwargs: Any) -> None:
113114 text = "Choose Text File" ,
114115 command = lambda : self .choose_file (html = False ),
115116 ).grid (row = 1 , column = 1 , sticky = "EW" , padx = (5 , 0 ))
117+ ttk .Button (
118+ fn_frame ,
119+ text = "Switch File" ,
120+ command = self .switch_file ,
121+ ).grid (row = 0 , column = 2 , rowspan = 2 , sticky = "NSEW" , padx = (5 , 0 ))
116122
117123 frame = ttk .Frame (self .custom_frame )
118124 frame .grid (row = 1 , column = 0 , sticky = "NSEW" )
@@ -290,7 +296,7 @@ def display_entries(
290296 self , auto_select_line : bool = True , complete_msg : bool = True
291297 ) -> None :
292298 """Display entries and convert flag chars to Tk tags"""
293- super ().display_entries ()
299+ super ().display_entries (auto_select_line , complete_msg )
294300
295301 for left , right , tag in [
296302 (FLAG_CH_HTML_L , FLAG_CH_HTML_R , HighlightTag .PPCOMP_HTML ),
@@ -311,6 +317,53 @@ def display_entries(
311317
312318 start = end_idx
313319
320+ def switch_file (self ) -> None :
321+ """Switch between text and HTML file, then re-display dialog."""
322+ # Save entries, because loading file will clear this dialog & hence the entries
323+ save_entries = copy .deepcopy (self .entries )
324+ save_sel_idx = self .current_entry_index ()
325+ # Check if currently HTML loaded
326+ html_loaded = os .path .splitext (the_file ().filename )[1 ].lower () in (
327+ ".htm" ,
328+ ".html" ,
329+ "xhtml" ,
330+ )
331+ new_file = preferences .get (
332+ PrefKey .PPCOMP_TEXT_FILE if html_loaded else PrefKey .PPCOMP_HTML_FILE
333+ )
334+ if not (new_file and os .path .isfile (new_file )):
335+ logger .error (f"File { new_file } does not exist" )
336+ return
337+ the_file ().open_file (new_file )
338+
339+ # Create a new checker, with its own dialog
340+ checker = PPcompChecker ()
341+ for entry in save_entries :
342+ # Is it a diff?
343+ if entry .text_range :
344+ # Swap text/HTML ranges
345+ match = re .match (r"(\d+\.\d+)(:.+)" , entry .text )
346+ assert match is not None
347+ entry .text = f"{ entry .text_range .start .index ()} { match .group (2 )} "
348+ entry .text_range = IndexRange (match .group (1 ), match .group (1 ))
349+ # Add entry to new dialog using saved & modified entry from old dialog
350+ checker .dialog .add_entry (
351+ entry .text ,
352+ entry .text_range ,
353+ entry .hilite_start ,
354+ entry .hilite_end ,
355+ entry .entry_type ,
356+ entry .error_prefix ,
357+ entry .ep_index ,
358+ entry .severity ,
359+ )
360+ else :
361+ # Not a diff - must be a header ("FOOTNOTES")
362+ checker .dialog .add_header (entry .text )
363+ checker .dialog .display_entries ()
364+ if save_sel_idx is not None :
365+ checker .dialog .select_entry_by_index (save_sel_idx )
366+
314367
315368class PPcompChecker :
316369 """PPcomp checker."""
0 commit comments