Index: calculatorview/perspectives/calculator/calculator.py
===================================================================
--- calculatorview/perspectives/calculator/calculator.py	(revision a3498fa857a7f63171ba57ea9ded715304a8eb43)
+++ calculatorview/perspectives/calculator/calculator.py	(revision 378d2eb49e460bef02f1efdf593b6794a6e764b4)
@@ -106,7 +106,9 @@
             Returns a set of menu entries for tools
         """
-        id = wx.NewId()
         sld_help = "Provides computation related to Scattering Length density"
-        return [("SLD Calculator", sld_help, self.on_calculate_sld)]
+        slit_length_help = "Provides computation related to Scattering Length density"
+        return [("SLD Calculator", sld_help, self.on_calculate_sld),
+                ("Slit Side Calculator", slit_length_help,
+                     self.on_calculate_slit_size)]
               
     def on_calculate_sld(self, event):
@@ -117,5 +119,12 @@
         frame = SldWindow(base=self.parent)
         frame.Show(True) 
-      
+    
+    def on_calculate_slit_size(self, event):
+        """
+            Compute the slit size a given data
+        """
+        from slit_length_calculator_panel import SlitLengthCalculatorWindow
+        frame = SlitLengthCalculatorWindow(parent=self.parent)    
+        frame.Show(True)
         
     def on_perspective(self, event):
Index: calculatorview/perspectives/calculator/calculator_widgets.py
===================================================================
--- calculatorview/perspectives/calculator/calculator_widgets.py	(revision 378d2eb49e460bef02f1efdf593b6794a6e764b4)
+++ calculatorview/perspectives/calculator/calculator_widgets.py	(revision 378d2eb49e460bef02f1efdf593b6794a6e764b4)
@@ -0,0 +1,79 @@
+"""
+This software was developed by the University of Tennessee as part of the
+Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+project funded by the US National Science Foundation. 
+
+See the license text in license.txt
+
+copyright 2009, University of Tennessee
+"""
+import wx
+import os
+
+class InputTextCtrl(wx.TextCtrl):
+    """
+        Text control for model and fit parameters.
+        Binds the appropriate events for user interactions.
+    """
+    def __init__(self, *args, **kwds):
+        
+        wx.TextCtrl.__init__(self, *args, **kwds)
+        
+        ## Set to True when the mouse is clicked while the whole string is selected
+        full_selection = False
+        ## Call back for EVT_SET_FOCUS events
+        _on_set_focus_callback = None
+        # Bind appropriate events
+        self.Bind(wx.EVT_LEFT_UP, self._highlight_text)
+        self.Bind(wx.EVT_SET_FOCUS, self._on_set_focus)
+
+    def _on_set_focus(self, event):
+        """
+            Catch when the text control is set in focus to highlight the whole
+            text if necessary
+            @param event: mouse event
+        """
+        event.Skip()
+        self.full_selection = True
+        
+    def _highlight_text(self, event):
+        """
+            Highlight text of a TextCtrl only of no text has be selected
+            @param event: mouse event
+        """
+        # Make sure the mouse event is available to other listeners
+        event.Skip()
+        control  = event.GetEventObject()
+        if self.full_selection:
+            self.full_selection = False
+            # Check that we have a TextCtrl
+            if issubclass(control.__class__, wx.TextCtrl):
+                # Check whether text has been selected, 
+                # if not, select the whole string
+                (start, end) = control.GetSelection()
+                if start==end:
+                    control.SetSelection(-1,-1)
+
+class OutputTextCtrl(wx.TextCtrl):
+    """
+        Text control used to display outputs.
+        No editing allowed. The background is 
+        grayed out. User can't select text.
+    """
+    def __init__(self, *args, **kwds):
+        wx.TextCtrl.__init__(self, *args, **kwds)
+        self.SetEditable(False)
+        self.SetBackgroundColour(self.GetParent().GetBackgroundColour())
+        
+        # Bind to mouse event to avoid text highlighting
+        # The event will be skipped once the call-back
+        # is called.
+        self.Bind(wx.EVT_MOUSE_EVENTS, self._click)
+        
+    def _click(self, event):
+        """
+            Prevent further handling of the mouse event
+            by not calling Skip().
+        """ 
+        pass
+ 
Index: calculatorview/perspectives/calculator/load_thread.py
===================================================================
--- calculatorview/perspectives/calculator/load_thread.py	(revision 378d2eb49e460bef02f1efdf593b6794a6e764b4)
+++ calculatorview/perspectives/calculator/load_thread.py	(revision 378d2eb49e460bef02f1efdf593b6794a6e764b4)
@@ -0,0 +1,52 @@
+
+import time
+import sys
+
+
+from data_util.calcthread import CalcThread
+from DataLoader.loader import Loader
+        
+
+class DataReader(CalcThread):
+    """
+            Load a data given a filename
+    """
+    def __init__(self, path, filename='',completefn=None,
+                 updatefn   = None,
+                 yieldtime  = 0.01,
+                 worktime   = 0.01
+                 ):
+        CalcThread.__init__(self, completefn,
+                 updatefn,
+                 yieldtime,
+                 worktime)
+        self.filename = filename
+        self.path = path
+        #Instantiate a loader 
+        self.loader = Loader()
+        self.starttime = 0  
+        
+    def isquit(self):
+        """
+             @raise KeyboardInterrupt: when the thread is interrupted
+        """
+        try:
+            CalcThread.isquit(self)
+        except KeyboardInterrupt:
+            raise KeyboardInterrupt   
+        
+        
+    def compute(self):
+        """
+            read some data
+        """
+        self.starttime = time.time()
+        try:
+            data =  self.loader.load(self.path)
+            elapsed = time.time() - self.starttime
+            self.complete(data=data, filename=self.filename)
+        except KeyboardInterrupt:
+            # Thread was interrupted, just proceed and re-raise.
+            # Real code should not print, but this is an example...
+            raise
+      
Index: calculatorview/perspectives/calculator/slit_length_calculator_panel.py
===================================================================
--- calculatorview/perspectives/calculator/slit_length_calculator_panel.py	(revision 378d2eb49e460bef02f1efdf593b6794a6e764b4)
+++ calculatorview/perspectives/calculator/slit_length_calculator_panel.py	(revision 378d2eb49e460bef02f1efdf593b6794a6e764b4)
@@ -0,0 +1,228 @@
+"""
+   This software was developed by the University of Tennessee as part of the
+Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
+project funded by the US National Science Foundation. 
+
+See the license text in license.txt
+
+copyright 2008, 2009, University of Tennessee
+"""
+
+import wx
+import sys
+import os
+
+from DataLoader.readers.ascii_reader import Reader
+from sans.guicomm.events import StatusEvent  
+from sans.calculator.slit_length_calculator import SlitlengthCalculator  
+from calculator_widgets import OutputTextCtrl
+
+_BOX_WIDTH = 76
+#Slit length panel size 
+if sys.platform.count("win32") > 0:
+    PANEL_WIDTH = 500
+    PANEL_HEIGHT = 190
+    FONT_VARIANT = 0
+else:
+    PANEL_WIDTH = 530
+    PANEL_HEIGHT = 220
+    FONT_VARIANT = 1
+    
+
+class SlitLengthCalculatorPanel(wx.Panel):
+    """
+        Provides the slit length calculator GUI.
+    """
+    ## Internal nickname for the window, used by the AUI manager
+    window_name = "Slit Length Calculator"
+    ## Name to appear on the window title bar
+    window_caption = "Slit Length Calculator"
+    ## Flag to tell the AUI manager to put this panel in the center pane
+    CENTER_PANE = True
+    
+    def __init__(self, parent, id=-1, *args, **kwds):
+        wx.Panel.__init__(self, parent, id=id, *args, **kwds)
+        #Font size 
+        self.SetWindowVariant(variant=FONT_VARIANT)
+        #thread to read data 
+        self.reader = None
+        # Default location
+        self._default_save_location = os.getcwd()  
+        # Object that receive status event
+        self.parent = parent
+        self._do_layout()
+       
+    def _define_structure(self):
+        """
+            Define the main sizers building to build this application.
+        """
+        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
+        self.box_source = wx.StaticBox(self, -1,str("Slit Size Calculator"))
+        self.boxsizer_source = wx.StaticBoxSizer(self.box_source,
+                                                    wx.VERTICAL)
+        self.data_name_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.slit_size_sizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
+       
+    def _layout_data_name(self):
+        """
+            Fill the sizer containing data's name
+        """
+        data_name_txt = wx.StaticText(self, -1, 'Data: ')
+        self.data_name_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH*4,-1))
+        #control that triggers importing data
+        id = wx.NewId()
+        self.browse_button = wx.Button(self, id, "Browse")
+        hint_on_browse = "Click on this button to import data in this panel."
+        self.browse_button.SetToolTipString(hint_on_browse)
+        self.Bind(wx.EVT_BUTTON, self.on_load_data, id=id)
+        self.data_name_sizer.AddMany([(data_name_txt, 0, wx.LEFT, 15),
+                                      (self.data_name_tcl, 0, wx.LEFT, 10),
+                                      (self.browse_button, 0, wx.LEFT, 10)])
+    def _layout_slit_size(self):
+        """
+            Fill the sizer containing slit size information
+        """
+        slit_size_txt = wx.StaticText(self, -1, 'Slit Size: ')
+        self.slit_size_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1))
+        slit_size_hint = " Estimated slit size"
+        self.slit_size_tcl.SetToolTipString(slit_size_hint)
+        slit_size_unit_txt = wx.StaticText(self, -1, 'Unit: ')
+        self.slit_size_unit_tcl = OutputTextCtrl(self, -1, size=(_BOX_WIDTH,-1)) 
+        slit_size_unit_hint = "Slit size's unit"
+        self.slit_size_unit_tcl.SetToolTipString(slit_size_unit_hint)
+        self.slit_size_sizer.AddMany([(slit_size_txt, 0, wx.LEFT, 15),
+                                      (self.slit_size_tcl, 0, wx.LEFT, 10),
+                                      (slit_size_unit_txt, 0, wx.LEFT, 10),
+                                      (self.slit_size_unit_tcl, 0, wx.LEFT, 10)])
+    
+    def _layout_button(self):  
+        """
+            Do the layout for the button widgets
+        """ 
+        self.bt_close = wx.Button(self, wx.ID_CANCEL,'Close')
+        self.bt_close.Bind(wx.EVT_BUTTON, self.on_close)
+        self.bt_close.SetToolTipString("Apply current changes to the source.")
+        self.button_sizer.AddMany([(self.bt_close, 0, wx.LEFT, 390)])
+        
+    def _do_layout(self):
+        """
+            Draw window content
+        """
+        self._define_structure()
+        self._layout_data_name()
+        self._layout_slit_size()
+        self._layout_button()
+        self.boxsizer_source.AddMany([(self.data_name_sizer, 0,
+                                          wx.EXPAND|wx.TOP|wx.BOTTOM, 5),
+                                   (self.slit_size_sizer, 0,
+                                     wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        self.main_sizer.AddMany([(self.boxsizer_source, 0, wx.ALL, 10),
+                                  (self.button_sizer, 0,
+                                    wx.EXPAND|wx.TOP|wx.BOTTOM, 5)])
+        
+        self.SetSizer(self.main_sizer)
+        self.SetAutoLayout(True)
+        
+    def choose_data_file(self, location=None):
+        path = None
+        filename = ''
+        if location == None:
+            location = os.getcwd()
+        
+        wildcard = "SAXSess Data 1D (*.DAT, *.dat)|*.DAT" 
+        
+        dlg = wx.FileDialog(self, "Choose a file", location,"", wildcard, wx.OPEN)
+        if dlg.ShowModal() == wx.ID_OK:
+            path = dlg.GetPath()
+            filename = os.path.basename(path)
+        dlg.Destroy()
+        
+        return path, filename
+
+    def on_close(self, event):
+        """
+            close the window containing this panel
+        """
+        self.parent.Close()
+        
+    def on_load_data(self, event):
+        """
+            Open a file dialog to allow the user to select a given file.
+            The user can allow load file with extension .DAT or .dat.
+            Display the slit size corresponding to the loaded data.
+        """
+        path, filename = self.choose_data_file(location=self._default_save_location)
+        
+        if path is None or filename == '':
+            return 
+        self._default_save_location = path
+        try:
+            #Load data
+            from load_thread import DataReader
+            ## If a thread is already started, stop it
+            if self.reader is not None and self.reader.isrunning():
+                self.reader.stop()
+            if self.parent.parent is not None:
+                wx.PostEvent(self.parent.parent, StatusEvent(status="Loading...",
+                                type="progress"))
+            self.reader = DataReader(path=path,
+                                     filename=filename,
+                                    completefn=self.complete_loading,
+                                    updatefn=None)
+            self.reader.queue()
+        except:
+            if self.parent.parent is None:
+                return 
+            msg = "Slit Length Calculator: %s"%(sys.exc_value)
+            wx.PostEvent(self.parent.parent, StatusEvent(status=msg, type='stop'))
+            return 
+            
+    def complete_loading(self, data=None, filename=''):
+        """
+            Complete the loading and compute the slit size
+        """
+        if data is not None and data.__class__.__name__ == 'Data2D':
+            if self.parent.parent is None:
+                return 
+            msg = "Slit Length cannot be computed for 2D Data"
+            wx.PostEvent(self.parent.parent, StatusEvent(status=msg, type='stop'))
+            return 
+        self.data_name_tcl.SetValue(str(filename))
+        #compute the slit size
+        try:
+            x = data.x
+            y = data.y
+            if x == [] or  x is None or y == [] or y is None:
+                 msg = "The current data is empty please check x and y"
+                 raise ValueError, msg
+            slit_length_calculator = SlitlengthCalculator()
+            slit_length_calculator.set_data(x=x, y=y)
+            slit_length = slit_length_calculator.get_slit_length()
+        except:
+            if self.parent.parent is None:
+                return 
+            msg = "Slit Length Calculator: %s"%(sys.exc_value)
+            wx.PostEvent(self.parent.parent, StatusEvent(status=msg, type='stop'))
+            return 
+        self.slit_size_tcl.SetValue(str(slit_length))
+        #Display unit
+        self.slit_size_unit_tcl.SetValue('[Unknown]')
+        if self.parent.parent is None:
+            return 
+        msg = "Load Complete"
+        wx.PostEvent(self.parent.parent, StatusEvent(status=msg, type='stop'))
+    
+class SlitLengthCalculatorWindow(wx.Frame):
+    def __init__(self, parent=None, id=1, title="Slit Length Calculator"):
+        wx.Frame.__init__(self, parent, id, title, size=(PANEL_WIDTH,PANEL_HEIGHT))
+        self.parent = parent
+        self.panel = SlitLengthCalculatorPanel(parent=self)
+        self.Centre()
+        self.Show(True)
+        
+if __name__ == "__main__": 
+    app = wx.PySimpleApp()
+    frame = SlitLengthCalculatorWindow()    
+    frame.Show(True)
+    app.MainLoop()     
