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

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 e2f1023 was e2f1023, checked in by Gervaise Alina <gervyh@…>, 15 years ago

hide the close button for the last page

  • Property mode set to 100644
File size: 17.5 KB
Line 
1
2import numpy
3import string 
4import wx
5import wx.aui
6import wx.lib
7import wx.lib.agw.aui.auibook as agw_aui
8
9
10import basepage
11
12_BOX_WIDTH = 80
13
14
15class StateIterator(object):
16    """
17        Contains all saved state of a given page.
18        Provide position of the current state of a page, the first save state
19        and the last state for a given page.
20        Allow easy undo or redo for a given page 
21    """
22    def __init__(self):
23        self._current=0
24       
25   
26    def __iter__(self):
27        return self
28   
29   
30    def first(self):
31        self._current =0
32        return self._current
33   
34    def next(self, max ):
35        if self._current < max:
36            self._current += 1
37        return self._current
38   
39    def previous(self):
40        if self._current > 0:
41            self._current = self._current -1
42        return self._current
43   
44    def currentPosition(self):
45        return self._current
46   
47    def setPosition(self, value):
48        if value >=0:
49            self._current = int(value)
50       
51       
52   
53 
54class ListOfState(list):     
55    def __init__(self, *args, **kw):
56        list.__init__(self, *args, **kw)
57        self.iterator = StateIterator()
58       
59    def appendItem(self, x):
60        self.append(x)
61        self.iterator.setPosition(value= len(self)-1)
62       
63    def removeItem(self, x):
64        self.iterator.previous()
65        self.remove(x)
66       
67    def getPreviousItem(self):
68        position = self.iterator.previous()
69       
70        if position < 0:
71            return None
72        else:
73            return self[position]
74       
75    def getNextItem(self):
76        position = self.iterator.next(max= len(self)-1)
77        if position >= len(self):
78            return None
79        else:
80            return self[position]
81       
82    def getCurrentItem(self):
83        postion = self.iterator.currentPosition()
84        if postion >= 0 and position < len(self):
85            return self[postion]
86        else:
87            return None
88       
89    def getCurrentPosition(self):
90        return self.iterator.currentPosition()
91       
92
93       
94       
95       
96class PageInfo(object):
97    """
98        this class contains the minimum numbers of data members
99        a fitpage or model page need to be initialized.
100    """
101    data = None
102    model =  None
103    manager = None
104    event_owner= None
105    model_list_box = None
106    name = None
107    ## Internal name for the AUI manager
108    window_name = "Page"
109    ## Title to appear on top of the window
110    window_caption = "Page"
111   
112    def __init__(self, model=None,data=None, manager=None,
113                  event_owner=None,model_list_box=None , name=None):
114        """
115            Initialize data members
116        """
117        self.data = data
118        self.model= model
119        self.manager= manager
120        self.event_owner= event_owner
121        self.model_list_box = model_list_box
122        self.name=None
123        self.window_name = "Page"
124        self.window_caption = "Page"
125   
126class FitPanel(agw_aui.AuiNotebook):   
127
128    """
129        FitPanel class contains fields allowing to fit  models and  data
130        @note: For Fit to be performed the user should check at least one parameter
131        on fit Panel window.
132       
133    """
134    ## Internal name for the AUI manager
135    window_name = "Fit panel"
136    ## Title to appear on top of the window
137    window_caption = "Fit Panel "
138    CENTER_PANE = True
139   
140    def __init__(self, parent, *args, **kwargs):
141        agw_aui.AuiNotebook.__init__(self,parent,-1,
142                    style= agw_aui.AUI_NB_WINDOWLIST_BUTTON|
143                    agw_aui.AUI_NB_DEFAULT_STYLE|
144                    wx.CLIP_CHILDREN|
145                    agw_aui.AUI_NB_HIDE_ON_SINGLE_TAB)
146   
147        self.manager=None
148        self.parent=parent
149        self.event_owner=None
150       
151        pageClosedEvent = agw_aui.EVT_AUINOTEBOOK_PAGE_CLOSE
152        self.Bind(agw_aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.onClosePage)
153       
154        #dictionary of miodel {model class name, model class}
155        self.model_list_box={}
156        ##dictionary of page info
157        self.page_info_dict={}
158        ## save the title of the last page tab added
159        self.fit_page_name={}
160        ## list of existing fit page
161        self.list_fitpage_name=[]
162   
163        #model page info
164        self.model_page_number = None
165        ## fit page number for model plot
166        self.fit_page1D_number = None
167        self.fit_page2D_number = None
168        self.model_page = None
169        self.sim_page = None
170        self.default_page = None
171        self.check_first_data = False
172        ## get the state of a page
173        self.Bind(basepage.EVT_PAGE_INFO, self._onGetstate)
174        self.Bind(basepage.EVT_PREVIOUS_STATE, self._onUndo)
175        self.Bind(basepage.EVT_NEXT_STATE, self._onRedo)
176       
177        #add default page
178        from hint_fitpage import HintFitPage
179        self.hint_page = HintFitPage(self) 
180        self.AddPage(page=self.hint_page, caption="Hint")
181        #Add the first fit page
182        self.default_page = self.add_fit_page(data=None)
183       
184        # increment number for model name
185        self.count=0
186        #updating the panel
187        self.Update()
188        self.Center()
189       
190       
191    def onClosePage(self, event):
192        """
193             close page and remove all references to the closed page
194        """
195        nbr_page = self.GetPageCount()
196        if nbr_page == 1:
197            event.Veto()
198            return 
199        selected_page = self.GetPage(self.GetSelection())
200        #remove default page
201        if selected_page == self.default_page:
202            self.default_page = None
203            return 
204        #remove hint page
205        if selected_page == self.hint_page:
206            return
207        ## removing sim_page
208        if selected_page == self.sim_page :
209            self.manager.sim_page=None 
210            return
211       
212        ## closing other pages
213        state = selected_page.createMemento()
214        page_name = selected_page.window_name
215        page_finder = self.manager.get_page_finder() 
216        fitproblem = None
217        ## removing model page
218        if selected_page == self.model_page:
219            #fitproblem = selected_page.model.clone()
220            self.model_page = None
221            self.count =0
222            ## page on menu
223            #self.manager._add_page_onmenu(page_name, fitproblem)
224        else:
225            if selected_page in page_finder:
226       
227                #fitproblem= page_finder[selected_page].clone()
228                if self.GetPageIndex(selected_page)==self.fit_page1D_number:
229                    self.fit_page1D_number=None
230                if self.GetPageIndex(selected_page)==self.fit_page2D_number:
231                    self.fit_page2D_number=None
232                ## page on menu
233                #self.manager._add_page_onmenu(page_name, fitproblem)
234                del page_finder[selected_page]
235            ##remove the check box link to the model name of this page (selected_page)
236            try:
237                self.sim_page.draw_page()
238            except:
239                ## that page is already deleted no need to remove check box on
240                ##non existing page
241                pass
242               
243        #Delete the name of the page into the list of open page
244        if selected_page.window_name in self.list_fitpage_name:
245            self.list_fitpage_name.remove(selected_page.window_name)
246           
247       
248    def set_manager(self, manager):
249        """
250             set panel manager
251             @param manager: instance of plugin fitting
252        """
253        self.manager = manager
254
255       
256    def set_owner(self,owner):
257        """
258            set and owner for fitpanel
259            @param owner: the class responsible of plotting
260        """
261        self.event_owner = owner
262   
263    def set_model_list(self, dict):
264         """
265             copy a dictionary of model into its own dictionary
266             @param dict: dictionnary made of model name as key and model class
267             as value
268         """
269         self.model_list_box = dict
270       
271 
272    def get_current_page(self):
273        """
274            @return the current page selected
275        """
276        return self.GetPage(self.GetSelection() )
277   
278    def add_sim_page(self):
279        """
280            Add the simultaneous fit page
281        """
282        from simfitpage import SimultaneousFitPage
283        page_finder= self.manager.get_page_finder()
284        self.sim_page = SimultaneousFitPage(self,page_finder=page_finder, id=-1)
285       
286        self.AddPage(self.sim_page,caption="Simultaneous Fit",select=True)
287        self.sim_page.set_manager(self.manager)
288        return self.sim_page
289       
290       
291    def add_fit_page( self,data=None, reset=False ):
292        """
293            Add a fitting page on the notebook contained by fitpanel
294            @param data: data to fit
295            @return panel : page just added for further used. is used by fitting module
296        """   
297        if data is not None:
298            if data.is_data:
299                name = data.name
300            else:
301                if data.__class__.__name__=="Data2D":
302                    name = 'Model 2D Fit'
303                else:
304                    name = 'Model 1D Fit'
305            myinfo = PageInfo( data=data, name=name )
306            myinfo.model_list_box = self.model_list_box.get_list()
307            myinfo.event_owner = self.event_owner
308            myinfo.manager = self.manager
309            myinfo.window_name = name
310            myinfo.window_caption = name
311       
312        else :
313            name = "Fit Page" 
314            myinfo = PageInfo( data=data, name=name )
315       
316        if not name in self.list_fitpage_name:
317            # the first data loading
318            if not self.check_first_data and self.default_page is not None:
319                page_number = self.GetPageIndex(self.default_page)
320                self.SetPageText(page_number , name)
321                self.default_page.set_data(data)
322                self.default_page.set_page_info(page_info=myinfo)
323                self.default_page.initialize_combox()
324                if  data is not None:
325                    self.check_first_data = True
326                panel = self.default_page
327            else:
328                #if not name in self.fit_page_name :
329                from fitpage import FitPage
330                panel = FitPage(parent=self, page_info=myinfo)
331               
332                self.AddPage(page=panel, caption=name, select=True)
333                if name == 'Model 1D Fit':
334                    self.fit_page1D_number= self.GetPageIndex(panel)
335                if name =='Model 2D Fit':
336                    self.fit_page2D_number= self.GetPageIndex(panel)
337                   
338                self.list_fitpage_name.append(name)
339                if data is not None:
340                    if reset:
341                        if name in self.fit_page_name.keys():
342                            memento= self.fit_page_name[name][0]
343                            panel.reset_page(memento)
344                        else:
345                            self.fit_page_name[name]=ListOfState()
346                   
347                    #self.fit_page_name[name].appendItem(panel.createMemento())
348            #GetPage(self, page_idx)
349            return panel
350        elif name =='Model 1D Fit':
351            if self.fit_page1D_number!=None:
352                panel =self.GetPage(self.fit_page1D_number) 
353                #self.fit_page_name[name]=[]
354                self.fit_page_name[name]= ListOfState()
355                #self.fit_page_name[name].insert(0,panel.createMemento())
356                #self.fit_page_name[name].append(panel.createMemento())
357                return panel
358            return None
359        elif name =='Model 2D Fit':
360            if self.fit_page2D_number!=None:
361                panel =self.GetPage(self.fit_page2D_number) 
362                self.fit_page_name[name]=ListOfState()
363                #self.fit_page_name[name].append(panel.createMemento())
364                return panel
365            return None
366        return None
367       
368   
369    def add_model_page(self,model,page_title="Model", qmin=0.0001, qmax=0.13,
370                        npts=50, topmenu=False, reset=False):
371        """
372            Add a model page only one  to display any model selected from the menu or the page combo box.
373            when this page is closed than the user will be able to open a new one
374           
375            @param model: the model for which paramters will be changed
376            @param page_title: the name of the page
377            @param page_info: contains info about the state of the page
378            @param qmin: mimimum Q
379            @param qmax: maximum Q
380            @param npts: number of Q points
381        """
382        if topmenu==True:
383            ##first time to open model page
384            if self.count==0 :
385                #if not page_title in self.list_fitpage_name :
386                self._help_add_model_page(model=model, page_title=page_title,
387                                qmin=qmin, qmax=qmax, npts=npts, reset=reset)
388                self.count +=1
389            else:
390                self.model_page.select_model(model)
391                self.fit_page_name[page_title]=ListOfState()
392                #self.fit_page_name[page_title].insert(0,self.model_page.createMemento())
393     
394     
395     
396    def _close_fitpage(self,data):
397        """
398            close a fit page when its data is completely remove from the graph
399        """
400        name = data.name
401        for index in range(self.GetPageCount()):
402            if self.GetPageText(index)== name:
403                selected_page = self.GetPage(index) 
404   
405                if index ==self.fit_page1D_number:
406                    self.fit_page1D_number=None
407                if index ==self.fit_page2D_number:
408                    self.fit_page2D_number=None
409                if selected_page in self.manager.page_finder:
410                    del self.manager.page_finder[selected_page]
411                ##remove the check box link to the model name of this page (selected_page)
412                try:
413                    self.sim_page.draw_page()
414                except:
415                    ## that page is already deleted no need to remove check box on
416                    ##non existing page
417                    pass
418               
419                #Delete the name of the page into the list of open page
420                if selected_page.window_name in self.list_fitpage_name:
421                    self.list_fitpage_name.remove(selected_page.window_name)
422                self.DeletePage(index)
423                break
424       
425       
426    def  _onGetstate(self, event):
427        """
428            copy the state of a page
429        """
430        page= event.page
431        if page.window_name in self.fit_page_name:
432            self.fit_page_name[page.window_name].appendItem(page.createMemento()) 
433           
434    def _onUndo(self, event ):
435        """
436            return the previous state of a given page is available
437        """
438        page = event.page
439        if page.window_name in self.fit_page_name:
440            if self.fit_page_name[page.window_name].getCurrentPosition()==0:
441                state = None
442            else:
443                state = self.fit_page_name[page.window_name].getPreviousItem()
444                page._redo.Enable(True)
445            page.reset_page(state)
446       
447    def _onRedo(self, event ): 
448        """
449            return the next state available
450        """       
451        page = event.page
452        if page.window_name in self.fit_page_name:
453            length= len(self.fit_page_name[page.window_name])
454            if self.fit_page_name[page.window_name].getCurrentPosition()== length -1:
455                state = None
456                page._redo.Enable(False)
457                page._redo.Enable(True)
458            else:
459                state = self.fit_page_name[page.window_name].getNextItem()
460            page.reset_page(state) 
461               
462    def _help_add_model_page(self,model,page_title="Model", qmin=0.0001, 
463                             qmax=0.13, npts=50,reset= False):
464        """
465            #TODO: fill in description
466           
467            @param qmin: mimimum Q
468            @param qmax: maximum Q
469            @param npts: number of Q points
470        """
471        ## creating object that contaning info about model
472        myinfo = PageInfo(model= model ,name= page_title)
473        myinfo.model_list_box = self.model_list_box.get_list()
474        myinfo.event_owner = self.event_owner
475        myinfo.manager = self.manager
476        myinfo.window_name = page_title
477        myinfo.window_caption = page_title
478     
479        from modelpage import ModelPage
480        panel = ModelPage(self,myinfo)
481       
482        self.AddPage(page=panel, caption=page_title, select=True)
483
484        self.model_page_number=self.GetSelection()
485        self.model_page=self.GetPage(self.GetSelection())
486     
487        ##resetting page
488        if reset:
489            if page_title in self.fit_page_name.keys():
490
491                memento= self.fit_page_name[page_title][0]
492                panel.reset_page(memento)
493        else:
494            self.fit_page_name[page_title]=ListOfState()
495            #self.fit_page_name[page_title]=[]
496            #self.fit_page_name[page_title].insert(0,panel.createMemento())
497       
498 
Note: See TracBrowser for help on using the repository browser.