source: sasview/sansview/perspectives/fitting/fitpanel.py @ f95301b

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since f95301b was f95301b, checked in by Gervaise Alina <gervyh@…>, 13 years ago

work on saving state

  • Property mode set to 100644
File size: 13.7 KB
RevLine 
[e2f1023]1
2import numpy
3import string 
[d89f09b]4import wx
[6bbeacd4]5import wx.lib.flatnotebook as fnb
[a93f525]6
[340c2b3]7from sans.guiframe.panel_base import PanelBase
[3cd5806]8from sans.guiframe.events import PanelOnFocusEvent
[6bbeacd4]9from sans.guiframe.events import StatusEvent
[cfc0913]10import basepage
[6bbeacd4]11import models
[330573d]12_BOX_WIDTH = 80
13
14
[6bbeacd4]15class FitPanel(fnb.FlatNotebook, PanelBase):   
[925a30e]16
[d89f09b]17    """
[5062bbf]18    FitPanel class contains fields allowing to fit  models and  data
19   
20    :note: For Fit to be performed the user should check at least one parameter
[d89f09b]21        on fit Panel window.
22       
23    """
24    ## Internal name for the AUI manager
25    window_name = "Fit panel"
26    ## Title to appear on top of the window
27    window_caption = "Fit Panel "
[2139c3f]28    CENTER_PANE = True
[7437880]29   
[6bbeacd4]30    def __init__(self, parent, manager=None, *args, **kwargs):
[5062bbf]31        """
32        """
[6bbeacd4]33        fnb.FlatNotebook.__init__(self, parent, -1,
[3244cbe1]34                    style= wx.aui.AUI_NB_WINDOWLIST_BUTTON|
35                    wx.aui.AUI_NB_DEFAULT_STYLE|
36                    wx.CLIP_CHILDREN)
[3cd5806]37        PanelBase.__init__(self, parent)
[6bbeacd4]38        self.SetWindowStyleFlag(style=fnb.FNB_FANCY_TABS)
39        self._manager = manager
[340c2b3]40        self.parent = parent
41        self.event_owner = None
[d89f09b]42        #dictionary of miodel {model class name, model class}
[6bbeacd4]43        self.menu_mng = models.ModelManager()
[b2d9826]44        self.model_list_box = self.menu_mng.get_model_list()
[6bbeacd4]45        #pageClosedEvent = fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING
46        self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING , self.on_close_page)
47         ## save the title of the last page tab added
[2f189dc]48        self.fit_page_name = {}
[cfc0913]49        ## list of existing fit page
[2f189dc]50        self.opened_pages = {}
51        #page of simultaneous fit
[ffa69b6]52        self.sim_page = None
[cfc0913]53        ## get the state of a page
54        self.Bind(basepage.EVT_PAGE_INFO, self._onGetstate)
[330573d]55        self.Bind(basepage.EVT_PREVIOUS_STATE, self._onUndo)
[fe496eeb]56        self.Bind(basepage.EVT_NEXT_STATE, self._onRedo)
[90a7bbd]57        self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.on_page_changing)
[3cd5806]58       
[9b18735]59        #add default pages
60        self.add_default_pages()
[6bbeacd4]61   
[b2d9826]62    def update_model_list(self):
63        """
64        """
65        self.model_list_box = self.menu_mng.update()
66        return self.model_list_box
67       
68       
[6bbeacd4]69    def get_page_by_id(self, id): 
70        """
71        """
72        if id not in self.opened_pages:
73            msg = "Fitpanel cannot find ID: %s in self.opened_pages" % str(id)
74            raise ValueError, msg
75        else:
76            return self.opened_pages[id]
[31b0c47]77       
[90a7bbd]78    def on_page_changing(self, event):
[6bbeacd4]79        """
80        """
[90a7bbd]81        pos = self.GetSelection()
82        if pos != -1:
83            selected_page = self.GetPage(pos)
84            wx.PostEvent(self.parent, PanelOnFocusEvent(panel=selected_page))
[6bbeacd4]85           
[3cd5806]86    def on_set_focus(self, event):
87        """
88        """
89        pos = self.GetSelection()
[90a7bbd]90        if pos != -1:
91            selected_page = self.GetPage(pos)
92            wx.PostEvent(self.parent, PanelOnFocusEvent(panel=selected_page))
[3cd5806]93       
[c8deee5]94    def get_data(self):
95        """
96        get the data in the current page
97        """
98        pos = self.GetSelection()
[90a7bbd]99        if pos != -1:
100            selected_page = self.GetPage(pos)
101            return selected_page.get_data()
[c8deee5]102   
[e88ebfd]103    def set_model_state(state):
104        """
105        receive a state to reset the model in the current page
106        """
107        pos = self.GetSelection()
108        if pos != -1:
109            selected_page = self.GetPage(pos)
110            selected_page.set_model_state(state)
111           
[c8deee5]112    def get_state(self):
113        """
114         return the state of the current selected page
115        """
116        pos = self.GetSelection()
[90a7bbd]117        if pos != -1:
118            selected_page = self.GetPage(pos)
119            return selected_page.get_state()
[c8deee5]120   
[9b18735]121    def add_default_pages(self):
122        """
123        Add default pages such as a hint page and an empty fit page
124        """
125        #add default page
126        from hint_fitpage import HintFitPage
127        self.hint_page = HintFitPage(self) 
[6bbeacd4]128        self.AddPage(self.hint_page,"Hint")
[3cd5806]129        self.hint_page.set_manager(self._manager)
[6bbeacd4]130 
[ac2dc0e]131    def close_all(self):
132        """
[8897d66]133        remove all pages, used when a svs file is opened
134        """
[90a7bbd]135       
[8897d66]136        #get number of pages
137        nop = self.GetPageCount()
138        #use while-loop, for-loop will not do the job well.
139        while (nop>0):
140            #delete the first page until no page exists
141            page = self.GetPage(0)
[90a7bbd]142            if self._manager.parent.panel_on_focus == page:
143                self._manager.parent.panel_on_focus = None
[8897d66]144            self._close_helper(selected_page=page)
145            self.DeletePage(0)
146            nop = nop - 1
[90a7bbd]147           
[ac2dc0e]148        ## save the title of the last page tab added
149        self.fit_page_name = {}
150        ## list of existing fit page
151        self.opened_pages = {} 
152         
[31b0c47]153    def set_state(self, state):
154        """
[5062bbf]155        Restore state of the panel
[31b0c47]156        """
157        page_is_opened = False
158        if state is not None:
[f95301b]159            for id, panel in self.opened_pages.iteritems():
[31b0c47]160                #Don't return any panel is the exact same page is created
[6bbeacd4]161                if id == panel.id:
[31b0c47]162                    # the page is still opened
163                    panel.reset_page(state=state)
[645f9b6]164                    panel.save_current_state() 
[31b0c47]165                    page_is_opened = True
166            if not page_is_opened:
[9f391af]167                panel = self._manager.add_fit_page(data=state.data)
[31b0c47]168                # add data associated to the page created
169                if panel is not None: 
[6bbeacd4]170                    self._manager.store_page(page=panel.id, data=state.data)
[31b0c47]171                    panel.reset_page(state=state)
[645f9b6]172                    panel.save_current_state()
[31b0c47]173                   
[90a7bbd]174    def clear_panel(self):
[9b18735]175        """
176        Clear and close all panels, used by guimanager
177        """
[90a7bbd]178       
179        #close all panels only when svs file opened
180        self.close_all()
181        self._manager.mypanels = []
182       
[9b18735]183                       
[ac2dc0e]184    def on_close_page(self, event=None):
[51d47b5]185        """
[5062bbf]186        close page and remove all references to the closed page
[51d47b5]187        """
[d361b462]188        nbr_page = self.GetPageCount()
[a93f525]189        if nbr_page == 1:
[ac2dc0e]190           
[d361b462]191            event.Veto()
192            return 
[51d47b5]193        selected_page = self.GetPage(self.GetSelection())
[2f189dc]194        self._close_helper(selected_page=selected_page)
[9853ad0]195       
[2f189dc]196    def close_page_with_data(self, deleted_data):
197        """
[5062bbf]198        close a fit page when its data is completely remove from the graph
[2f189dc]199        """
[784e2fa]200        if deleted_data is None:
201            return
[2f189dc]202        for index in range(self.GetPageCount()):
203            selected_page = self.GetPage(index) 
204            if hasattr(selected_page,"get_data"):
205                data = selected_page.get_data()
[ac2dc0e]206               
[784e2fa]207                if data is None:
208                    #the fitpanel exists and only the initial fit page is open
209                    #with no selected data
210                    return
[2f189dc]211                if data.name == deleted_data.name:
212                    self._close_helper(selected_page)
213                    self.DeletePage(index)
214                    break
[d89f09b]215       
216    def set_manager(self, manager):
217        """
[5062bbf]218        set panel manager
219       
220        :param manager: instance of plugin fitting
221       
[d89f09b]222        """
[c8deee5]223        self._manager = manager
[3cd5806]224        for pos in range(self.GetPageCount()):
225            page = self.GetPage(pos)
226            if page is not None:
227                page.set_manager(self._manager)
[a93f525]228
[ffa69b6]229    def set_model_list(self, dict):
[c77d859]230         """
[5062bbf]231         copy a dictionary of model into its own dictionary
232         
233         :param dict: dictionnary made of model name as key and model class
[c77d859]234             as value
235         """
236         self.model_list_box = dict
[51d47b5]237       
[c77d859]238    def get_current_page(self):
239        """
[5062bbf]240        :return: the current page selected
241       
[c77d859]242        """
[6bbeacd4]243        return self.GetPage(self.GetSelection())
[c77d859]244   
[51d47b5]245    def add_sim_page(self):
[925a30e]246        """
[5062bbf]247        Add the simultaneous fit page
[925a30e]248        """
[51d47b5]249        from simfitpage import SimultaneousFitPage
[c8deee5]250        page_finder= self._manager.get_page_finder()
[b28717b]251        self.sim_page = SimultaneousFitPage(self,page_finder=page_finder, id=-1)
[6bbeacd4]252        self.sim_page.id = wx.NewId()
253        self.AddPage(self.sim_page,"Simultaneous Fit", True)
[c8deee5]254        self.sim_page.set_manager(self._manager)
[51d47b5]255        return self.sim_page
[d89f09b]256       
[6bbeacd4]257 
[2f189dc]258    def add_empty_page(self):
[9853ad0]259        """
[5062bbf]260        add an empty page
[9853ad0]261        """
[2f189dc]262        from fitpage import FitPage
[6bbeacd4]263        panel = FitPage(parent=self)
264        panel.id = wx.NewId()
265        panel.populate_box(dict=self.model_list_box)
[c8deee5]266        panel.set_manager(self._manager)
[ae4ade7]267        caption = str(panel.window_name) + " " + str(self._manager.index_model)
268        self.AddPage(panel, caption, select=True)
[6bbeacd4]269        self.opened_pages[panel.id] = panel
[2f189dc]270        return panel
271   
[8ee56a9]272    def delete_data(self, data):
273        """
274        Delete the given data
275        """
276        if data is None:
277            return None
[6bbeacd4]278    def set_data(self, data):
[2f189dc]279        """
[5062bbf]280        Add a fitting page on the notebook contained by fitpanel
281       
282        :param data: data to fit
283       
284        :return panel : page just added for further used. is used by fitting module
285       
[2f189dc]286        """
287        if data is None:
288            return None
[6bbeacd4]289        for page in self.opened_pages.values():
290            #check if the selected data existing in the fitpanel
291            pos = self.GetPageIndex(page)
292            if page.get_data() is None:
[a5701e6]293                enable2D = page.get_view_mode()
294                if (data.__class__.__name__ == "Data2D" and enable2D)\
295                or (data.__class__.__name__ == "Data1D" and not enable2D):
296                    page.set_data(data)
297                    self.SetPageText(pos, str(data.name))
298                    self.SetSelection(pos)
299                    return page
[ae4ade7]300               
[6bbeacd4]301            elif page.get_data().id == data.id:
302                msg = "Data already existing in the fitting panel"
303                wx.PostEvent(self._manager.parent, 
304                             StatusEvent(status=msg, info='warning')) 
305                self.SetSelection(pos)
306                return page
[9b18735]307       
[6bbeacd4]308        page = self.add_empty_page()
[9f391af]309        pos = self.GetPageIndex(page)
[6bbeacd4]310        page.id = wx.NewId()
311        page.set_data(data)
312        self.SetPageText(pos, str(data.name))
313        self.opened_pages[page.id] = page
[ae4ade7]314       
[6bbeacd4]315        return page
316       
317    def _onGetstate(self, event):
[cfc0913]318        """
[5062bbf]319        copy the state of a page
[cfc0913]320        """
[6bbeacd4]321        page = event.page
322        if page.id in self.fit_page_name:
323           self.fit_page_name[page.id].appendItem(page.createMemento()) 
[cfc0913]324           
[330573d]325    def _onUndo(self, event ):
326        """
[5062bbf]327        return the previous state of a given page is available
[330573d]328        """
329        page = event.page
[6bbeacd4]330        if page.id in self.fit_page_name:
331            if self.fit_page_name[page.id].getCurrentPosition()==0:
[330573d]332                state = None
333            else:
[6bbeacd4]334                state = self.fit_page_name[page.id].getPreviousItem()
[fe496eeb]335                page._redo.Enable(True)
[330573d]336            page.reset_page(state)
[fe496eeb]337       
[2f189dc]338    def _onRedo(self, event): 
[fe496eeb]339        """
[5062bbf]340        return the next state available
[fe496eeb]341        """       
342        page = event.page
[6bbeacd4]343        if page.id in self.fit_page_name:
344            length= len(self.fit_page_name[page.id])
345            if self.fit_page_name[page.id].getCurrentPosition()== length -1:
[fe496eeb]346                state = None
347                page._redo.Enable(False)
[3b9e023]348                page._redo.Enable(True)
[fe496eeb]349            else:
[6bbeacd4]350                state =self.fit_page_name[page.id].getNextItem()
[fe496eeb]351            page.reset_page(state) 
[2f189dc]352                 
353    def _close_helper(self, selected_page):
[3f1af74]354        """
[5062bbf]355        Delete the given page from the notebook
[3f1af74]356        """
[2f189dc]357        #remove hint page
[9f391af]358        if selected_page == self.hint_page:
[2f189dc]359            return
360        ## removing sim_page
361        if selected_page == self.sim_page :
[c8deee5]362            self._manager.sim_page=None 
[2f189dc]363            return
[b787e68c]364       
[2f189dc]365        ## closing other pages
366        state = selected_page.createMemento()
367        page_name = selected_page.window_name
[c8deee5]368        page_finder = self._manager.get_page_finder() 
[2f189dc]369        fitproblem = None
370        ## removing fit page
[c6036f5]371        data = selected_page.get_data()
372        #Don' t remove plot for 2D
373        flag = True
374        if data.__class__.__name__ == 'Data2D':
375            flag = False
[2f189dc]376        if selected_page in page_finder:
377            #Delete the name of the page into the list of open page
[6bbeacd4]378            for id, list in self.opened_pages.iteritems():
[2f189dc]379                #Don't return any panel is the exact same page is created
[6bbeacd4]380               
381                if flag and selected_page.id == id:
382                    self._manager.remove_plot(id, theory=False)
[2f189dc]383                    break 
384            del page_finder[selected_page]
385        ##remove the check box link to the model name of this page (selected_page)
386        try:
387            self.sim_page.draw_page()
388        except:
389            ## that page is already deleted no need to remove check box on
390            ##non existing page
391            pass
392               
393        #Delete the name of the page into the list of open page
[6bbeacd4]394        for id, list in self.opened_pages.iteritems():
[2f189dc]395            #Don't return any panel is the exact same page is created
[6bbeacd4]396           
397            if selected_page.id == id:
[9f391af]398                del self.opened_pages[selected_page.id]
[2f189dc]399                break 
[0aeabc6]400     
[b787e68c]401 
Note: See TracBrowser for help on using the repository browser.