Changeset d76c43a in sasview for src/sas/sasgui/guiframe


Ignore:
Timestamp:
Sep 20, 2017 4:39:48 PM (7 years ago)
Author:
GitHub <noreply@…>
Branches:
master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
Children:
fca1f50, 793713d
Parents:
ce0a245 (diff), f80b416e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Paul Kienzle <pkienzle@…> (09/20/17 16:39:48)
git-committer:
GitHub <noreply@…> (09/20/17 16:39:48)
Message:

Merge pull request #103 from SasView?/ticket-639-katex

Ticket 639 katex

Location:
src/sas/sasgui/guiframe
Files:
2 added
1 deleted
4 edited

Legend:

Unmodified
Added
Removed
  • src/sas/sasgui/guiframe/aboutbox.py

    r959eb01 rf2ea95a  
    3131      (os.path.isfile("%s/%s.pyc" % (path, 'local_config'))): 
    3232        fObj, path, descr = imp.find_module('local_config', [path]) 
    33         config = imp.load_module('local_config', fObj, path, descr)   
     33        config = imp.load_module('local_config', fObj, path, descr) 
    3434    else: 
    3535        # Try simply importing local_config 
    3636        import local_config as config 
    3737except: 
    38     # Didn't find local config, load the default  
     38    # Didn't find local config, load the default 
    3939    import config 
    4040 
     
    4242    """ 
    4343    Launches browser and opens specified url 
    44      
     44 
    4545    In some cases may require BROWSER environment variable to be set up. 
    46      
     46 
    4747    :param url: URL to open 
    48      
     48 
    4949    """ 
    5050    import webbrowser 
     
    5555    """ 
    5656    "About" Dialog 
    57      
     57 
    5858    Shows product name, current version, authors, and link to the product page. 
    5959    Current version is taken from version.py 
    60      
    61     """ 
    62      
     60 
     61    """ 
     62 
    6363    def __init__(self, *args, **kwds): 
    6464 
     
    6666        kwds["style"] = wx.DEFAULT_DIALOG_STYLE 
    6767        wx.Dialog.__init__(self, *args, **kwds) 
    68          
     68 
    6969        file_dir = os.path.dirname(__file__) 
    70          
     70 
    7171        # Mac doesn't display images with transparent background so well, 
    7272        # keep it for Windows 
    7373        image = file_dir + "/images/angles_flat.png" 
    74          
     74 
    7575        if os.path.isfile(config._corner_image): 
    7676            image = config._corner_image 
     
    8080        else: 
    8181            self.bitmap_logo = wx.StaticBitmap(self, -1, wx.Bitmap(image)) 
    82          
     82 
    8383        self.label_title = wx.StaticText(self, -1, config.__appname__) 
    8484        self.label_version = wx.StaticText(self, -1, "") 
     
    112112        #self.bitmap_button_danse = wx.BitmapButton(self, -1, wx.NullBitmap) 
    113113        self.bitmap_button_msu = wx.BitmapButton(self, -1, wx.NullBitmap) 
    114          
     114 
    115115        self.bitmap_button_isis = wx.BitmapButton(self, -1, wx.NullBitmap) 
    116116        self.bitmap_button_ess = wx.BitmapButton(self, -1, wx.NullBitmap) 
     
    119119        self.bitmap_button_tudelft = wx.BitmapButton(self, -1, wx.NullBitmap) 
    120120        self.bitmap_button_dls = wx.BitmapButton(self, -1, wx.NullBitmap) 
    121          
     121 
    122122        self.static_line_3 = wx.StaticLine(self, -1) 
    123123        self.button_OK = wx.Button(self, wx.ID_OK, "OK") 
     
    125125        self.__set_properties() 
    126126        self.__do_layout() 
    127          
     127 
    128128        self.Bind(wx.EVT_BUTTON, self.onNistLogo, self.bitmap_button_nist) 
    129129        self.Bind(wx.EVT_BUTTON, self.onUmdLogo, self.bitmap_button_umd) 
     
    145145        random.shuffle(config._authors) 
    146146        strLabel = ", ".join(config._authors) 
    147          
     147 
    148148        # display version and svn revison numbers 
    149149        verwords = config.__version__.split('.') 
     
    157157        self.label_version.SetLabel(config.__version__)#(version) 
    158158        self.label_svnrevision.SetLabel(build_num) 
    159          
     159 
    160160        # set bitmaps for logo buttons 
    161161        image = file_dir + "/images/nist_logo.png" 
    162162        if os.path.isfile(config._nist_logo): 
    163163            image = config._nist_logo 
    164         logo = wx.Bitmap(image)         
     164        logo = wx.Bitmap(image) 
    165165        self.bitmap_button_nist.SetBitmapLabel(logo) 
    166          
     166 
    167167        image = file_dir + "/images/umd_logo.png" 
    168168        if os.path.isfile(config._umd_logo): 
    169169            image = config._umd_logo 
    170         logo = wx.Bitmap(image)         
     170        logo = wx.Bitmap(image) 
    171171        self.bitmap_button_umd.SetBitmapLabel(logo) 
    172172 
     
    174174        if os.path.isfile(config._ornl_logo): 
    175175            image = config._ornl_logo 
    176         logo = wx.Bitmap(image)         
     176        logo = wx.Bitmap(image) 
    177177        self.bitmap_button_ornl.SetBitmapLabel(logo) 
    178178 
     
    181181        if os.path.isfile(config._sns_logo): 
    182182            image = config._sns_logo 
    183         logo = wx.Bitmap(image)         
     183        logo = wx.Bitmap(image) 
    184184        self.bitmap_button_sns.SetBitmapLabel(logo) 
    185          
     185 
    186186        image = file_dir + "/images/nsf_logo.png" 
    187187        if os.path.isfile(config._nsf_logo): 
    188188            image = config._nsf_logo 
    189         logo = wx.Bitmap(image)         
     189        logo = wx.Bitmap(image) 
    190190        self.bitmap_button_nsf.SetBitmapLabel(logo) 
    191191 
     
    196196        self.bitmap_button_danse.SetBitmapLabel(logo) 
    197197        """ 
    198         image = file_dir + "/images/utlogo.gif" 
     198        image = file_dir + "/images/utlogo.png" 
    199199        if os.path.isfile(config._inst_logo): 
    200200            image = config._inst_logo 
    201201        logo = wx.Bitmap(image) 
    202202        self.bitmap_button_msu.SetBitmapLabel(logo) 
    203          
     203 
    204204        image = file_dir + "/images/isis_logo.png" 
    205205        if os.path.isfile(config._isis_logo): 
    206206            image = config._isis_logo 
    207         logo = wx.Bitmap(image)         
     207        logo = wx.Bitmap(image) 
    208208        self.bitmap_button_isis.SetBitmapLabel(logo) 
    209209 
     
    213213        logo = wx.Bitmap(image) 
    214214        self.bitmap_button_ess.SetBitmapLabel(logo) 
    215          
     215 
    216216        image = file_dir + "/images/ill_logo.png" 
    217217        if os.path.isfile(config._ill_logo): 
     
    219219        logo = wx.Bitmap(image) 
    220220        self.bitmap_button_ill.SetBitmapLabel(logo) 
    221          
     221 
    222222        image = file_dir + "/images/ansto_logo.png" 
    223223        if os.path.isfile(config._ansto_logo): 
     
    225225        logo = wx.Bitmap(image) 
    226226        self.bitmap_button_ansto.SetBitmapLabel(logo) 
    227          
     227 
    228228        image = file_dir + "/images/tudelft_logo.png" 
    229229        if os.path.isfile(config._tudelft_logo): 
     
    231231        logo = wx.Bitmap(image) 
    232232        self.bitmap_button_tudelft.SetBitmapLabel(logo) 
    233          
     233 
    234234        image = file_dir + "/images/dls_logo.png" 
    235235        if os.path.isfile(config._dls_logo): 
     
    237237        logo = wx.Bitmap(image) 
    238238        self.bitmap_button_dls.SetBitmapLabel(logo) 
    239                  
     239 
    240240        # resize dialog window to fit version number nicely 
    241241        if wx.VERSION >= (2, 7, 2, 0): 
     
    244244            size = [self.GetBestFittingSize()[0], self.GetSize()[1]] 
    245245        self.Fit() 
    246          
     246 
    247247    def __set_properties(self): 
    248248        """ 
     
    310310        sizer_main.Add(self.static_line_2, 0, wx.EXPAND, 0) 
    311311 
    312         sizer_logos.Add(self.bitmap_button_msu, 0,  
     312        sizer_logos.Add(self.bitmap_button_msu, 0, 
    313313                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    314314        #sizer_logos.Add(self.bitmap_button_danse, 0, 
    315315        #                wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    316         #sizer_logos.Add(self.bitmap_button_nsf, 0,  
     316        #sizer_logos.Add(self.bitmap_button_nsf, 0, 
    317317        #                wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    318         sizer_logos.Add(self.bitmap_button_umd, 0,  
    319                         wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    320         sizer_logos.Add(self.bitmap_button_nist, 0,  
    321                         wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    322         #sizer_logos.Add(self.bitmap_button_sns, 0,  
     318        sizer_logos.Add(self.bitmap_button_umd, 0, 
     319                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     320        sizer_logos.Add(self.bitmap_button_nist, 0, 
     321                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     322        #sizer_logos.Add(self.bitmap_button_sns, 0, 
    323323        #                wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    324         sizer_logos.Add(self.bitmap_button_ornl, 0,  
    325                         wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    326         sizer_logos.Add(self.bitmap_button_isis, 0,  
    327                         wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    328         sizer_logos.Add(self.bitmap_button_ess, 0,  
    329                         wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    330         sizer_logos.Add(self.bitmap_button_ill, 0,  
    331                         wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    332         sizer_logos.Add(self.bitmap_button_ansto, 0,  
    333                         wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    334         sizer_logos.Add(self.bitmap_button_tudelft, 0,  
    335                         wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    336         sizer_logos.Add(self.bitmap_button_dls, 0,  
    337                         wx.LEFT|wx.ADJUST_MINSIZE, 2) 
    338                  
     324        sizer_logos.Add(self.bitmap_button_ornl, 0, 
     325                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     326        sizer_logos.Add(self.bitmap_button_isis, 0, 
     327                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     328        sizer_logos.Add(self.bitmap_button_ess, 0, 
     329                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     330        sizer_logos.Add(self.bitmap_button_ill, 0, 
     331                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     332        sizer_logos.Add(self.bitmap_button_ansto, 0, 
     333                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     334        sizer_logos.Add(self.bitmap_button_tudelft, 0, 
     335                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     336        sizer_logos.Add(self.bitmap_button_dls, 0, 
     337                        wx.LEFT|wx.ADJUST_MINSIZE, 2) 
     338 
    339339        sizer_logos.Add((10, 50), 0, wx.ADJUST_MINSIZE, 0) 
    340340        sizer_main.Add(sizer_logos, 0, wx.EXPAND, 0) 
    341341        sizer_main.Add(self.static_line_3, 0, wx.EXPAND, 0) 
    342342        sizer_button.Add((20, 40), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0) 
    343         sizer_button.Add(self.button_OK, 0,  
     343        sizer_button.Add(self.button_OK, 0, 
    344344                         wx.RIGHT|wx.ADJUST_MINSIZE|wx.CENTER, 10) 
    345345        sizer_main.Add(sizer_button, 0, wx.EXPAND, 0) 
     
    350350        # end wxGlade 
    351351 
    352     def onNistLogo(self, event):  
     352    def onNistLogo(self, event): 
    353353        """ 
    354354        """ 
     
    356356        launchBrowser(config._nist_url) 
    357357        event.Skip() 
    358          
    359     def onUmdLogo(self, event):  
     358 
     359    def onUmdLogo(self, event): 
    360360        """ 
    361361        """ 
     
    363363        launchBrowser(config._umd_url) 
    364364        event.Skip() 
    365          
    366     def onOrnlLogo(self, event):  
     365 
     366    def onOrnlLogo(self, event): 
    367367        """ 
    368368        """ 
     
    370370        launchBrowser(config._ornl_url) 
    371371        event.Skip() 
    372          
    373     def onSnsLogo(self, event):  
     372 
     373    def onSnsLogo(self, event): 
    374374        """ 
    375375        """ 
     
    377377        launchBrowser(config._sns_url) 
    378378        event.Skip() 
    379                  
    380     def onNsfLogo(self, event):  
     379 
     380    def onNsfLogo(self, event): 
    381381        """ 
    382382        """ 
     
    394394    def onUTLogo(self, event): 
    395395        """ 
    396         """  
     396        """ 
    397397        # wxGlade: DialogAbout.<event_handler> 
    398398        launchBrowser(config._inst_url) 
    399399        event.Skip() 
    400400 
    401     def onIsisLogo(self, event):  
     401    def onIsisLogo(self, event): 
    402402        """ 
    403403        """ 
     
    415415    def onIllLogo(self, event): 
    416416        """ 
    417         """  
     417        """ 
    418418        # wxGlade: DialogAbout.<event_handler> 
    419419        launchBrowser(config._ill_url) 
     
    422422    def onAnstoLogo(self, event): 
    423423        """ 
    424         """  
     424        """ 
    425425        # wxGlade: DialogAbout.<event_handler> 
    426426        launchBrowser(config._ansto_url) 
     
    429429    def onTudelftLogo(self, event): 
    430430        """ 
    431         """  
     431        """ 
    432432        # wxGlade: DialogAbout.<event_handler> 
    433433        launchBrowser(config._tudelft_url) 
     
    436436    def onDlsLogo(self, event): 
    437437        """ 
    438         """  
     438        """ 
    439439        # wxGlade: DialogAbout.<event_handler> 
    440440        launchBrowser(config._dls_url) 
     
    462462    app = MyApp(0) 
    463463    app.MainLoop() 
    464      
    465 ##### end of testing code #####################################################     
     464 
     465##### end of testing code ##################################################### 
  • src/sas/sasgui/guiframe/config.py

    rce2819b rf80b416e  
    7777_nsf_logo = os.path.join(icon_path, "nsf_logo.png") 
    7878_danse_logo = os.path.join(icon_path, "danse_logo.png") 
    79 _inst_logo = os.path.join(icon_path, "utlogo.gif") 
     79_inst_logo = os.path.join(icon_path, "utlogo.png") 
    8080_nist_url = "http://www.nist.gov/" 
    8181_umd_url = "http://www.umd.edu/" 
  • src/sas/sasgui/guiframe/documentation_window.py

    r6a455cd3 rf80b416e  
    1616import os 
    1717import logging 
    18 import wx 
    1918import webbrowser 
    2019import urllib 
    2120import sys 
    2221 
     22import wx 
     23try: 
     24    import wx.html2 as html 
     25    WX_SUPPORTS_HTML2 = True 
     26except ImportError: 
     27    WX_SUPPORTS_HTML2 = False 
     28 
     29from .gui_manager import get_app_dir 
     30 
     31# Don't use wx html renderer on windows. 
     32if os.name == 'nt': 
     33    WX_SUPPORTS_HTML2 = False 
     34 
    2335logger = logging.getLogger(__name__) 
    2436 
    2537SPHINX_DOC_ENV = "SASVIEW_DOC_PATH" 
    26 WX_SUPPORTS_HTML2 = True 
    27 try: 
    28     import wx.html2 as html 
    29 except: 
    30     WX_SUPPORTS_HTML2 = False 
    3138 
     39THREAD_STARTED = False 
     40def start_documentation_server(doc_root, port): 
     41    import thread 
     42    global THREAD_STARTED 
     43    if not THREAD_STARTED: 
     44        thread.start_new_thread(_documentation_server, (doc_root, port)) 
     45        THREAD_STARTED = True 
    3246 
    33 from gui_manager import get_app_dir 
     47def _documentation_server(doc_root, port): 
     48    from SimpleHTTPServer import SimpleHTTPRequestHandler 
     49    from SocketServer import TCPServer 
    3450 
     51    os.chdir(doc_root) 
     52    httpd = TCPServer(("127.0.0.1", port), SimpleHTTPRequestHandler, bind_and_activate=False) 
     53    httpd.allow_reuse_address = True 
     54    try: 
     55        httpd.server_bind() 
     56        httpd.server_activate() 
     57        httpd.serve_forever() 
     58    finally: 
     59        httpd.server_close() 
    3560 
    3661class DocumentationWindow(wx.Frame): 
     
    7095        #Note added June 21, 2015     PDB 
    7196        file_path = os.path.join(docs_path, path) 
    72         url = "file:///" + urllib.quote(file_path, r'/\:')+ url_instruction 
     97        if path.startswith('http'): 
     98            url = path 
     99        elif not os.path.exists(file_path): 
     100            url = "index.html" 
     101            logger.error("Could not find Sphinx documentation at %s -- has it been built?", 
     102                         file_path) 
     103        elif False: 
     104            start_documentation_server(docs_path, port=7999) 
     105            url = "http://127.0.0.1:7999/" + path.replace('\\', '/') + url_instruction 
     106        else: 
     107            url = "file:///" + urllib.quote(file_path, r'/\:')+ url_instruction 
    73108 
    74         if not os.path.exists(file_path): 
    75             logger.error("Could not find Sphinx documentation at %s \ 
    76             -- has it been built?", file_path) 
    77         #Commenting following 5 lines, so default browser is forced 
    78         #This is due to CDN mathjax discontinuation of service, intenal help 
    79         #browser should be back with qt version 
    80         #Note added by Wojtek Potrzebowski, July 4th 2017 
    81         # elif WX_SUPPORTS_HTML2: 
    82         #     # Complete HTML/CSS support! 
    83         #     self.view = html.WebView.New(self) 
    84         #     self.view.LoadURL(url) 
    85         #     self.Show() 
     109        #logger.info("showing url " + url) 
     110        if WX_SUPPORTS_HTML2: 
     111            # Complete HTML/CSS support! 
     112            self.view = html.WebView.New(self) 
     113            self.view.LoadURL(url) 
     114            self.Bind(html.EVT_WEBVIEW_ERROR, self.OnError, self.view) 
     115            self.Show() 
    86116        else: 
    87117            logger.error("No html2 support, popping up a web browser") 
     
    92122            webbrowser.open_new_tab(url) 
    93123 
     124    def OnError(self, evt): 
     125        logger.error("%d: %s", evt.GetInt(), evt.GetString()) 
     126 
    94127def main(): 
    95128    """ 
    96129    main loop function if running alone for testing. 
    97130    """ 
     131    url = "index.html" if len(sys.argv) <= 1 else sys.argv[1] 
    98132    app = wx.App() 
    99     DocumentationWindow(None, -1, "index.html", "", "Documentation",) 
     133    DocumentationWindow(None, -1, url, "", "Documentation",) 
    100134    app.MainLoop() 
    101135 
  • src/sas/sasgui/guiframe/media/graph_help.rst

    rf9b0c81 r5ed76f8  
    99 
    1010SasView generates three different types of graph window: one that displays *1D data* 
    11 (ie, I(Q) vs Q), one that displays *1D residuals* (ie, the difference between the 
    12 experimental data and the theory at the same Q values), and *2D color maps*. 
     11(i.e., $I(Q)$ vs $Q$), one that displays *1D residuals* (ie, the difference between the 
     12experimental data and the theory at the same $Q$ values), and *2D color maps*. 
    1313 
    1414Graph window options 
     
    4242plot window. 
    4343 
    44 .. note::  
     44.. note:: 
    4545    *If a residuals graph (when fitting data) is hidden, it will not show up 
    4646    after computation.* 
     
    138138style and size. *Remove Text* will remove the last annotation added. To change 
    139139the legend. *Window Title* allows a custom title to be entered instead of Graph 
    140 x.  
     140x. 
    141141 
    142142Changing scales 
     
    226226^^^^^^^^^^^^^^^^^^^ 
    227227 
    228 Linear fit performs a simple ( y(x)=ax+b ) linear fit within the plot window. 
     228Linear fit performs a simple $y(x)=ax+b$ linear fit within the plot window. 
    229229 
    230230In the *Dataset Menu* (see Invoking_the_dataset_menu_), select *Linear Fit*. A 
     
    234234 
    235235This option is most useful for performing simple Guinier, XS Guinier, and 
    236 Porod type analyses, for example, to estimate Rg, a rod diameter, or incoherent 
     236Porod type analyses, for example, to estimate $R_g$, a rod diameter, or incoherent 
    237237background level, respectively. 
    238238 
     
    319319^^^^^^^^^^^^^^^^^^^^^^^^^ 
    320320 
    321 This operation will perform an average in constant Q-rings around the (x,y) 
     321This operation will perform an average in constant $Q$ rings around the (x,y) 
    322322pixel location of the beam center. 
    323323 
     
    331331^^^^^^^^^^^^^^^^^^^^^^^ 
    332332 
    333 This operation averages in constant Q-arcs. 
    334  
    335 The width of the sector is specified in degrees (+/- |delta|\|phi|\) each side 
    336 of the central angle (|phi|\). 
    337  
    338 Annular average [|phi| View] 
    339 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    340  
    341 This operation performs an average between two Q-values centered on (0,0), 
     333This operation averages in constant $Q$ arcs. 
     334 
     335The width of the sector is specified in degrees ($\pm\delta|\phi|$) each side 
     336of the central angle $\phi$. 
     337 
     338Annular average [:math:`\phi`] 
     339^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
     340 
     341This operation performs an average between two $Q$ values centered on (0,0), 
    342342and averaged over a specified number of pixels. 
    343343 
    344 The data is returned as a function of angle (|phi|\) in degrees with zero 
     344The data is returned as a function of angle $\phi$ in degrees with zero 
    345345degrees at the 3 O'clock position. 
    346346 
     
    356356^^^^^^^^^^^^^^^^^^^ 
    357357 
    358 This operation computes an average I(Qx) for the region of interest. 
     358This operation computes an average $I(Q_x)$ for the region of interest. 
    359359 
    360360When editing the slicer parameters, the user can control the length and the 
    361361width the rectangular slicer. The averaged output is calculated from constant 
    362 bins with rectangular shape. The resultant Q values are nominal values, that 
     362bins with rectangular shape. The resultant $Q$ values are nominal values, that 
    363363is, the central value of each bin on the x-axis. 
    364364 
     
    366366^^^^^^^^^^^^^^^^^^^ 
    367367 
    368 This operation computes an average I(Qy) for the region of interest. 
     368This operation computes an average $I(Q_y)$ for the region of interest. 
    369369 
    370370When editing the slicer parameters, the user can control the length and the 
    371371width the rectangular slicer. The averaged output is calculated from constant 
    372 bins with rectangular shape. The resultant Q values are nominal values, that 
     372bins with rectangular shape. The resultant $Q$ values are nominal values, that 
    373373is, the central value of each bin on the x-axis. 
    374374 
Note: See TracChangeset for help on using the changeset viewer.