FOX/ObjCryst++  1.10.X (development)
wxRefinableObj.cpp
1 /* ObjCryst++ Object-Oriented Crystallographic Library
2  (c) 2000-2002 Vincent Favre-Nicolin vincefn@users.sourceforge.net
3  2000-2001 University of Geneva (Switzerland)
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 //#include <sstream> //for stringstream
20 #include <fstream>
21 
22 // wx headers, with or without precompilation
23 #include "wx/wxprec.h"
24 #ifdef __BORLANDC__
25  #pragma hdrstop
26 #endif
27 #ifndef WX_PRECOMP
28  #include "wx/wx.h"
29 #endif
30 
31 #include "ObjCryst/wxCryst/wxRefinableObj.h"
32 
33 #include "ObjCryst/wxCryst/wxRefinableObj.h"
34 #include "ObjCryst/Quirks/VFNStreamFormat.h"
35 
36 #include "ObjCryst/RefinableObj/GlobalOptimObj.h"
37 
38 //These are only for explicit instantiation
39 #include "ObjCryst/ObjCryst/Atom.h"
40 #include "ObjCryst/ObjCryst/Crystal.h"
41 #include "ObjCryst/ObjCryst/DiffractionDataSingleCrystal.h"
42 #include "ObjCryst/ObjCryst/PowderPattern.h"
43 #include "ObjCryst/ObjCryst/ScatteringPower.h"
44 #include "ObjCryst/ObjCryst/ZScatterer.h"
45 #include "ObjCryst/ObjCryst/ScatteringCorr.h"
46 #include "ObjCryst/ObjCryst/ReflectionProfile.h"
47 
48 //Fixes for Cygwin; where do those stupid macros come from ? Somewhere in wxMSW headers
49 #ifdef max
50 #undef max
51 #endif
52 #ifdef min
53 #undef min
54 #endif
55 #ifdef DrawText
56 #undef DrawText
57 #endif
58 
59 namespace ObjCryst
60 {
65 extern WXField *spLastWXFieldInputNotValidated;
67 //
68 // WXFieldRefPar
69 //
71 static const long ID_WXFIELD_REFPAR =WXCRYST_ID();
72 static const long ID_WXFIELD_REFPAR_FIXBUTTON =WXCRYST_ID();
73 static const long ID_WXFIELD_REFPAR_LIMITEDBUTTON=WXCRYST_ID();
74 static const long ID_REFPAR_POPUP_SET_LIMITS =WXCRYST_ID();
75 
76 BEGIN_EVENT_TABLE(WXFieldRefPar,wxWindow)
77  EVT_TEXT_ENTER(ID_WXFIELD, WXFieldRefPar::OnEnter)
78  EVT_TEXT(ID_WXFIELD, WXFieldRefPar::OnText)
79  EVT_CHECKBOX(ID_WXFIELD_REFPAR_FIXBUTTON, WXFieldRefPar::OnToggleFix)
80  EVT_CHECKBOX(ID_WXFIELD_REFPAR_LIMITEDBUTTON,WXFieldRefPar::OnToggleLimited)
81  EVT_RIGHT_DOWN( WXFieldRefPar::OnPopupMenu)
82  EVT_MENU(ID_REFPAR_POPUP_SET_LIMITS, WXFieldRefPar::OnPopupMenuChoice)
83 END_EVENT_TABLE()
84 
85 WXFieldRefPar::WXFieldRefPar(wxWindow *parent,const string& label,
86  RefinablePar *par, const int hsize,
87  const bool enableFixButton, const bool enableLimitedButton):
88 WXField(parent,label,ID_WXFIELD_REFPAR),mValue(0.),mpRefPar(par),mIsSelfUpdating(false),mFormat(_T("%8f"))
89 {
90  VFN_DEBUG_MESSAGE("WXFieldRefPar::WXFieldName():End",6)
91  if(enableFixButton)
92  {
93  this->SetLabel(label+"R");
94  mpButtonFix=new wxCheckBox(this,ID_WXFIELD_REFPAR_FIXBUTTON,_T("L"),wxDefaultPosition, wxDefaultSize);
95  //mpButtonFix->Fit();
96  mpButtonFix->SetToolTip(_T("Check this box to enable optimizing this parameter.\n")
97  _T("(some parameters may be automatically fixed for global optimization)"));
98  mpSizer->Add(mpButtonFix,0,wxALIGN_CENTER);
99  }else mpButtonFix=0;
100  if(enableLimitedButton)
101  {
102  mpButtonLimited=new wxCheckBox(this,ID_WXFIELD_REFPAR_LIMITEDBUTTON,_T(""),
103  wxDefaultPosition, wxSize(16,20));
104  mpButtonLimited->SetToolTip(_T("Check this box to use limits for this parameter"));
105  mpSizer->Add(mpButtonLimited,0,wxALIGN_CENTER);
106  }else mpButtonLimited=0;
107 
108  mpField=new wxTextCtrl(this,ID_WXFIELD,_T(""),
109  wxDefaultPosition,wxSize(hsize,-1),wxTE_PROCESS_ENTER,
110  wxTextValidator(wxFILTER_NUMERIC));
111  mpSizer->Add(mpField,0,wxALIGN_CENTER);
112 }
114 {
115  mpRefPar->WXNotifyDelete();
116 }
117 
118 void WXFieldRefPar::OnEnter(wxCommandEvent & WXUNUSED(event))
119 {
120  VFN_DEBUG_MESSAGE("WXFieldRefPar::OnEnter()",6)
122 }
123 void WXFieldRefPar::OnText(wxCommandEvent & WXUNUSED(event))
124 {
125  if(true==mIsSelfUpdating) return;
126  VFN_DEBUG_MESSAGE("WXFieldRefPar::OnEnter()",6)
127  if(spLastWXFieldInputNotValidated!=this)
128  {
130  spLastWXFieldInputNotValidated=this;
131  }
132 }
133 
134 void WXFieldRefPar::OnToggleFix(wxCommandEvent & WXUNUSED(event))
135 {
136  VFN_DEBUG_MESSAGE("WXFieldRefPar::OnToggleFix()",6)
137  if(0!=mpButtonFix) mpRefPar->SetIsFixed(!(mpButtonFix->GetValue()));
138  mpRefPar->Print();
139 }
140 
141 void WXFieldRefPar::OnToggleLimited(wxCommandEvent & WXUNUSED(event))
142 {
143  VFN_DEBUG_MESSAGE("WXFieldRefPar::OnToggleLimited()",6)
144  if(0!=mpButtonLimited) mpRefPar->SetIsLimited(mpButtonLimited->GetValue());
145  mpRefPar->Print();
146 }
147 
148 void WXFieldRefPar::OnPopupMenu(wxMouseEvent & WXUNUSED(event))
149 {
150  static wxMenu sWXFieldRefParPopupMenu;//("Refinable Parameter");
151  static bool needInitMenu=true;
152  if(needInitMenu)
153  {
154  needInitMenu=false;
155  sWXFieldRefParPopupMenu.Append(ID_REFPAR_POPUP_SET_LIMITS, _T("Change Limits"));
156  }
157  this->PopupMenu(&sWXFieldRefParPopupMenu,0,0);
158 }
159 
160 void WXFieldRefPar::OnPopupMenuChoice(wxCommandEvent& event)
161 {
162  VFN_DEBUG_MESSAGE("WXFieldRefPar::OnPopupMenuChoice()",7)
163  if(event.GetId()== ID_REFPAR_POPUP_SET_LIMITS)
164  {
165  double min,max;
166  {
167  wxString str;
168  str << mpRefPar->GetHumanMin();
169  wxTextEntryDialog limitDialog(this,_T("Enter the minimum value"),
170  _T("Minimum"),str,wxOK | wxCANCEL);
171  if(wxID_OK!=limitDialog.ShowModal())
172  {
173  VFN_DEBUG_EXIT("WXZScatterer::OnMenuSetLimits():Cancelled",6)
174  return;
175  }
176  limitDialog.GetValue().ToDouble(&min);
177  }
178  {
179  wxString str;
180  str << mpRefPar->GetHumanMax();
181  wxTextEntryDialog limitDialog(this,_T("Enter the maximum value"),
182  _T("Maximum"),str,wxOK | wxCANCEL);
183  if(wxID_OK!=limitDialog.ShowModal())
184  {
185  VFN_DEBUG_EXIT("WXZScatterer::OnMenuSetLimits():Cancelled",6)
186  return;
187  }
188  limitDialog.GetValue().ToDouble(&max);
189  }
190  if(max<=min)
191  {
192  wxMessageDialog dumbUser(this,_T("max <= min !!!"),
193  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
194  dumbUser.ShowModal();
195  return;
196  }
197  mpRefPar->SetHumanMin(min);
198  mpRefPar->SetHumanMax(max);
199  mpRefPar->SetIsLimited(true);
200  mpRefPar->Print();
201  }
202 }
203 
204 void WXFieldRefPar::CrystUpdate(const bool uui,const bool lock)
205 {
206  VFN_DEBUG_MESSAGE("WXFieldRefPar::CrystUpdate()",6)
207  if(lock) mMutex.Lock();
208  bool needUpdate=false;
209  if(wxThread::IsMain())
210  {
211  if(mpRefPar->IsUsed()!=this->IsShown()) needUpdate=true;
212  if(0!=mpButtonFix) if(mpButtonFix->GetValue()==mpRefPar->IsFixed()) needUpdate=true;
213  if(0!=mpButtonLimited) if(mpButtonLimited->GetValue()==mpRefPar->IsLimited()) needUpdate=true;
214  }
215  if(mValue!=mpRefPar->GetHumanValue()) needUpdate=true;
216  if(!needUpdate)
217  {
218  if(lock) mMutex.Unlock();
219  return;
220  }
221  mValueOld=mValue;
222  mValue=mpRefPar->GetHumanValue();
223  mNeedUpdateUI=true;
224  if(lock) mMutex.Unlock();
225  if(mNeedUpdateUI && wxThread::IsMain()) this->UpdateUI(lock);
226 }
227 
228 void WXFieldRefPar::UpdateUI(const bool lock)
229 {
230  VFN_DEBUG_MESSAGE("WXFieldRefPar::UpdateUI("<<lock<<")"<<"MainThread="<<wxThread::IsMain(),3)
231  if(lock) mMutex.Lock();
232  if(mNeedUpdateUI==false)
233  {
234  if(lock) mMutex.Unlock();
235  return;
236  }
237  if(false==mpRefPar->IsUsed()) this->Show(false);
238  else this->Show(true);
239 
240  if(mpField==0)
241  {
242  if(lock) mMutex.Unlock();
243  return;
244  }
245 
246  //mpField->SetValue(wxString::Printf("%f",mValue));
247  wxString tmp;
248  //if((abs(mValue)<100)&&(abs(mValue)>0.01)) tmp.Printf(_T("%6.4f"),mValue);
249  tmp.Printf(mFormat,mValue);
250  mIsSelfUpdating=true;
251  mpField->SetValue(tmp);
252  mIsSelfUpdating=false;
253  if(0!=mpButtonFix) mpButtonFix->SetValue(!(mpRefPar->IsFixed()));
254  if(0!=mpButtonLimited) mpButtonLimited->SetValue(mpRefPar->IsLimited());
255  mNeedUpdateUI=false;
256  if(lock) mMutex.Unlock();
257 }
258 
260 {
261  VFN_DEBUG_MESSAGE("WXFieldRefPar::Revert()",6)
262  wxMutexLocker mlock(mMutex);
263  mValue=mValueOld;
264  mNeedUpdateUI=true;
265 }
267 {
268  VFN_DEBUG_MESSAGE("WXFieldRefPar::ValidateUserInput()",6)
269  wxMutexLocker mlock(mMutex);
270  mValueOld=mValue;
271  wxString s=mpField->GetValue();
272  double tmp;
273  s.ToDouble(&tmp);
274  mValue=tmp;
275  mpRefPar->SetHumanValue(mValue);
276 }
277 
278 void WXFieldRefPar::SetToolTip(const wxString& tip){mpField->SetToolTip(tip);}
279 
280 void WXFieldRefPar::SetFormat(const wxString &format)
281 {
282  mFormat=format;
283 }
284 
286 //
287 // WXFieldOption
288 //
290 BEGIN_EVENT_TABLE(WXFieldOption,wxWindow)
291  EVT_CHOICE(ID_WXFIELD,WXFieldOption::OnChoice)
292 END_EVENT_TABLE()
293 
294 WXFieldOption::WXFieldOption(wxWindow *parent,
295  const int field_id,RefObjOpt* option):
296 WXField(parent,option->GetName(),field_id),
297 mChoice(-1),mChoiceOld(-1),mpOption(option),mpList(0)
298 {
299  wxString choices[20];//:TODO: dynamically choose correct number
300  for(int i=0;i<mpOption->GetNbChoice();i++)
301  choices[i]=wxString::FromAscii(mpOption->GetChoiceName(i).c_str());
302 
303  mpList= new wxChoice(this,ID_WXFIELD,wxDefaultPosition,wxDefaultSize,
304  mpOption->GetNbChoice(),choices);
305  mpSizer->Add(mpList,0,wxALIGN_CENTER);
306 }
307 WXFieldOption::~WXFieldOption()
308 {
309  mpOption->WXNotifyDelete();
310 }
311 void WXFieldOption::OnChoice(wxCommandEvent & WXUNUSED(event))
312 {
313  if(mChoice==mpList->GetSelection()) return;
314  mChoiceOld=mChoice;
315  mChoice=mpList->GetSelection();
316  mpOption->SetChoice(mChoice);
317 }
318 
319 void WXFieldOption::CrystUpdate(const bool uui,const bool lock)
320 {
321  VFN_DEBUG_MESSAGE("WXFieldOption::CrystUpdate("<<uui<<lock<<")",6)
322  if(lock) mMutex.Lock();
323  if(mChoice==mpOption->GetChoice())
324  {
325  if(lock) mMutex.Unlock();
326  return;
327  }
328  mChoice=mpOption->GetChoice();
329  mNeedUpdateUI=true;
330  if(lock) mMutex.Unlock();
331 }
332 
333 void WXFieldOption::UpdateUI(const bool lock)
334 {
335  VFN_DEBUG_MESSAGE("WXFieldOption::UpdateUI("<<lock<<")"<<"MainThread="<<wxThread::IsMain(),6)
336  if(lock) mMutex.Lock();
337  if(mNeedUpdateUI==false)
338  {
339  if(lock) mMutex.Unlock();
340  return;
341  }
342  mpList->SetSelection(mChoice);
343  mNeedUpdateUI=false;
344  if(lock) mMutex.Unlock();
345 }
346 
348 {
349  wxMutexLocker mlock(mMutex);
350  mChoice=mChoiceOld;
351  mNeedUpdateUI=true;
352 }
354 {
355 }
356 
357 void WXFieldOption::SetToolTip(const wxString& tip){mpList->SetToolTip(tip);}
358 
360 //
361 // WXRegistry
362 //
364 
365 template<class T> WXRegistry<T>::WXRegistry(wxWindow *parent,ObjRegistry<T>* reg):
366 WXCrystObj(parent,wxHORIZONTAL,false),mpRegistry(reg)
367 {
368  VFN_DEBUG_ENTRY("WXCrystRegistry::WXCrystRegistry(wxWindow*)",6)
369  #ifdef VFN_CRYST_MUTEX
370  cout <<"new CrystMutex("<<&mMutex<<")for WXCrystRegistry:"<<reg->GetName()<<endl;
371  #endif
372  wxStaticText* mpLabel=new wxStaticText(this,-1,wxString::FromAscii(reg->GetName().c_str()));
373  mpSizer->Add(mpLabel,0,wxALIGN_LEFT);
374  mpLabel->SetForegroundColour(wxColour(0,0,255));
375  VFN_DEBUG_EXIT("WXCrystRegistry::WXCrystRegistry(wxWindow*):End",6)
376 }
377 template<class T> WXRegistry<T>::~WXRegistry()
378 {
379  mpRegistry->WXNotifyDelete();
380  #ifdef VFN_CRYST_MUTEX
381  cout <<"Deleting CrystMutex("<<&mMutex<<")for WXCrystRegistry:"<<mpRegistry->GetName()<<endl;
382  #endif
383 }
384 template<class T> void WXRegistry<T>::Add(WXCrystObjBasic *obj)
385 {
386  VFN_DEBUG_ENTRY("WXCrystRegistry::AddWXCrystObj(WXCrystObj*)",6)
387  mList.Add(obj);
388  obj->Show(mIsExpanded);
389  this->AddChild(obj);
390  VFN_DEBUG_EXIT("WXCrystRegistry::AddWXCrystObj(WXCrystObj*)",6)
391 }
392 template<class T> void WXRegistry<T>::Remove(WXCrystObjBasic *obj)
393 {
394  if(obj==0) return;
395  VFN_DEBUG_ENTRY("WXCrystRegistry::RemoveWXCrystObj(WXCrystObj*)",6)
396  mList.Remove(obj);
397  //mpSizer->Detach((wxWindow*)obj);
398  obj->Destroy();
399  this->BottomLayout(0);
400  VFN_DEBUG_EXIT("WXCrystRegistry::RemoveWXCrystObj(WXCrystObj*):End",6)
401 }
402 
403 template<class T> bool WXRegistry<T>::OnChangeName(const int id)
404 {
405  VFN_DEBUG_MESSAGE("WXRegistry<T>::OnChangeName()",6)
406  if(id==ID_WXOBJ_NAME)
407  {
408  mpRegistry->SetName(mpWXTitle->GetValue());
409  return true;
410  }
411  return false;
412 }
413 
414 
415 //Explicit instantiation
416 template class WXRegistry<RefinableObj>;
417 template class WXRegistry<RefObjOpt>;
418 template class WXRegistry<Crystal>;
419 template class WXRegistry<Scatterer>;
420 template class WXRegistry<ScatteringPower>;
421 template class WXRegistry<ScatteringPowerAtom>;
422 template class WXRegistry<PowderPattern>;
425 template class WXRegistry<OptimizationObj>;
426 template class WXRegistry<XMLCrystTag>;
427 //template class WXRegistry<IOCrystTag>;//to be removed
428 template class WXRegistry<ZAtom>;
430 template class WXRegistry<TextureEllipsoid>;
431 template class WXRegistry<ReflectionProfile>;
433 //
434 // WXDialogChooseFromRegistry
435 //
437 template<class T> T* WXDialogChooseFromRegistry(ObjRegistry<T> &reg,wxWindow*parent,
438  const string &message,int &choice)
439 {
440  wxString* choices=new wxString[reg.GetNb()];
441  for(int i=0;i<reg.GetNb();i++)
442  *(choices+i)=wxString::FromAscii((reg.GetObj(i).GetClassName()+":"+reg.GetObj(i).GetName()).c_str());
443  #if wxCHECK_VERSION( 2, 9, 4 )
444  wxSingleChoiceDialog dialog
445  (parent,wxString::FromAscii(message.c_str()),_T("Choose"),reg.GetNb(),choices,(void**)NULL,wxOK | wxCANCEL);
446  #else
447  wxSingleChoiceDialog dialog
448  (parent,wxString::FromAscii(message.c_str()),_T("Choose"),reg.GetNb(),choices,NULL,wxOK | wxCANCEL);
449  #endif
450  dialog.SetSize(300,300);
451  if(wxID_OK!=dialog.ShowModal())
452  {
453  delete[] choices;
454  return 0;
455  }
456  delete[] choices;
457  choice=dialog.GetSelection();
458  return &(reg.GetObj(choice));
459 }
460 
461 template RefinableObj*
462  WXDialogChooseFromRegistry(ObjRegistry<RefinableObj> &,wxWindow*,const string &,int &);
463 template Crystal*
464  WXDialogChooseFromRegistry(ObjRegistry<Crystal> &,wxWindow*,const string &,int &);
465 template Scatterer*
466  WXDialogChooseFromRegistry(ObjRegistry<Scatterer> &,wxWindow*,const string &,int &);
467 template ScatteringPower*
468  WXDialogChooseFromRegistry(ObjRegistry<ScatteringPower> &,wxWindow*,const string &,int &);
469 template ScatteringPowerAtom*
470  WXDialogChooseFromRegistry(ObjRegistry<ScatteringPowerAtom> &,wxWindow*,
471  const string &,int &);
472 template ZAtom*
473  WXDialogChooseFromRegistry(ObjRegistry<ZAtom> &,wxWindow*,const string &,int &);
474 template PowderPattern*
475  WXDialogChooseFromRegistry(ObjRegistry<PowderPattern> &,wxWindow*,const string &,int &);
476 template PowderPatternComponent*
477  WXDialogChooseFromRegistry(ObjRegistry<PowderPatternComponent>&,wxWindow*,
478  const string&,int &);
479 template DiffractionDataSingleCrystal*
480  WXDialogChooseFromRegistry(ObjRegistry<DiffractionDataSingleCrystal>&,wxWindow*,
481  const string &,int &);
482 template OptimizationObj*
483  WXDialogChooseFromRegistry(ObjRegistry<OptimizationObj> &,wxWindow*,const string &,int &);
484 template XMLCrystTag*
485  WXDialogChooseFromRegistry(ObjRegistry<XMLCrystTag> &,wxWindow*,const string &,int &);
486 
487 
488 template<class T> const T* WXDialogChooseFromRegistry(const ObjRegistry<T> &reg,
489  wxWindow*parent,const string &message
490  ,int &choice)
491 {
492  wxString* choices=new wxString[reg.GetNb()];
493  for(int i=0;i<reg.GetNb();i++)
494  *(choices+i)=wxString::FromAscii((reg.GetObj(i).GetClassName()+":"+reg.GetObj(i).GetName()).c_str());
495  #if wxCHECK_VERSION( 2, 9, 4 )
496  wxSingleChoiceDialog dialog
497  (parent,wxString::FromAscii(message.c_str()),_T("Choose"),reg.GetNb(),choices,(void**)NULL,wxOK | wxCANCEL);
498  #else
499  wxSingleChoiceDialog dialog
500  (parent,wxString::FromAscii(message.c_str()),_T("Choose"),reg.GetNb(),choices,NULL,wxOK | wxCANCEL);
501  #endif
502  dialog.SetSize(300,300);
503  if(wxID_OK!=dialog.ShowModal())
504  {
505  delete[] choices;
506  return 0;
507  }
508  delete[] choices;
509  choice=dialog.GetSelection();
510  return &(reg.GetObj(choice));
511 }
512 
513 template const RefinableObj*
514  WXDialogChooseFromRegistry(const ObjRegistry<RefinableObj> &,wxWindow*,const string &,int &);
515 
516 template const Crystal*
517  WXDialogChooseFromRegistry(const ObjRegistry<Crystal> &,wxWindow*,const string &,int &);
518 
519 template const Scatterer*
520  WXDialogChooseFromRegistry(const ObjRegistry<Scatterer> &,wxWindow*,const string &,int &);
521 
522 template const ScatteringPower*
523  WXDialogChooseFromRegistry(const ObjRegistry<ScatteringPower> &,wxWindow*,
524  const string &,int &);
525 
526 template const ScatteringPowerAtom*
527  WXDialogChooseFromRegistry(const ObjRegistry<ScatteringPowerAtom> &,wxWindow*,
528  const string &,int &);
529 
530 template const ZAtom*
531  WXDialogChooseFromRegistry(const ObjRegistry<ZAtom> &,wxWindow*,const string &,int &);
532 
533 template const PowderPattern*
534  WXDialogChooseFromRegistry(const ObjRegistry<PowderPattern> &,wxWindow*,
535  const string &,int &);
536 
537 template const PowderPatternComponent*
538  WXDialogChooseFromRegistry(const ObjRegistry<PowderPatternComponent>&,wxWindow*,
539  const string&,int &);
540 
541 template const DiffractionDataSingleCrystal*
542  WXDialogChooseFromRegistry(const ObjRegistry<DiffractionDataSingleCrystal>&,wxWindow*,
543  const string &,int &);
544 
545 template const OptimizationObj*
546  WXDialogChooseFromRegistry(const ObjRegistry<OptimizationObj> &,wxWindow*,
547  const string &,int &);
548 
549 template const XMLCrystTag*
550  WXDialogChooseFromRegistry(const ObjRegistry<XMLCrystTag> &,wxWindow*,
551  const string &,int &);
552 
554 //
555 // WXRefinableObj
556 //
558 BEGIN_EVENT_TABLE(WXRefinableObj,wxWindow)
559  EVT_MENU(ID_REFOBJ_MENU_OBJ_SAVE, WXRefinableObj::OnMenuSave)
560  EVT_MENU(ID_REFOBJ_MENU_OBJ_LOAD, WXRefinableObj::OnMenuLoad)
561  EVT_MENU(ID_REFOBJ_MENU_PAR_FIXALL, WXRefinableObj::OnMenuFixAllPar)
562  EVT_MENU(ID_REFOBJ_MENU_PAR_UNFIXALL, WXRefinableObj::OnMenuUnFixAllPar)
563  EVT_MENU(ID_REFOBJ_MENU_PAR_RANDOMIZE, WXRefinableObj::OnMenuParRandomize)
564  EVT_UPDATE_UI(ID_CRYST_UPDATEUI, WXRefinableObj::OnUpdateUI)
565 END_EVENT_TABLE()
566 
567 WXRefinableObj::WXRefinableObj(wxWindow* parent, RefinableObj*obj):
568 WXCrystObj(parent,wxHORIZONTAL),mpRefinableObj(obj)
569 {
570  VFN_DEBUG_ENTRY("WXRefinableObj::WXRefinableObj():"<<obj->GetName(),6)
571  #ifdef VFN_CRYST_MUTEX
572  cout <<"new CrystMutex("<<&mMutex<<")for :"<<obj->GetClassName()<<":"<<obj->GetName()<<endl;
573  #endif
574  mpWXTitle->SetLabel(mpRefinableObj->GetClassName());
575 
576  // Menu
577  mpMenuBar=new WXCrystMenuBar(this,this);
578 
579  mpSizer->Add(mpMenuBar);
580  mList.Add(mpMenuBar);
581  //:TODO: Rather use a WXRegistry for the options ?
582  for(unsigned int i=0;i<mpRefinableObj->GetNbOption();i++)
583  {
584  VFN_DEBUG_MESSAGE("WXRefinableObj::WXRefinableObj():Adding option "<<i,6)
585  WXCrystObjBasic *opt=mpRefinableObj->GetOption(i).WXCreate(this);
586  mpSizer->Add(opt,0,wxALIGN_LEFT);
587  mList.Add(opt);
588  }
589  //this->BottomLayout(0);
590  //this->CrystUpdate(true,true);
591  VFN_DEBUG_EXIT("WXRefinableObj::WXRefinableObj()",6)
592 }
593 
594 WXRefinableObj::~WXRefinableObj()
595 {
596  VFN_DEBUG_MESSAGE("WXRefinableObj::~WXRefinableObj():"<<mpRefinableObj->GetName(),6)
597  mpRefinableObj->WXNotifyDelete();
598  #ifdef VFN_CRYST_MUTEX
599  cout <<"Deleting CrystMutex("<<&mMutex<<")for :"<<mpRefinableObj->GetClassName()
600  <<":"<<mpRefinableObj->GetName()<<endl;
601  #endif
602 }
603 
604 void WXRefinableObj::CrystUpdate(const bool uui,const bool lock)
605 {
606  VFN_DEBUG_ENTRY("WXRefinableObj::CrystUpdate("<<uui<<lock<<"):"<<mpRefinableObj->GetName(),6)
607  //if(lock) mMutex.Lock();
608  this->WXCrystObj::CrystUpdate(false,lock);
609  //if(lock) mMutex.Unlock();
610  if(uui)
611  {
612  if(true==wxThread::IsMain()) this->UpdateUI(lock);
613  else
614  {
615  wxUpdateUIEvent event(ID_CRYST_UPDATEUI);
616  wxPostEvent(this,event);
617  }
618  }
619  VFN_DEBUG_EXIT("WXRefinableObj::CrystUpdate():"<<mpRefinableObj->GetName(),6)
620 }
621 
623 {
624  VFN_DEBUG_MESSAGE("WXRefinableObj::OnChangeName()",6)
625  if(id==ID_WXOBJ_NAME)
626  {
627  VFN_DEBUG_MESSAGE("WXRefinableObj::OnChangeName():Changing RefinableObj Name",6)
628  mpRefinableObj->SetName(mpWXTitle->GetValue());
629  return true;
630  }
631  return false;
632 }
633 
634 void WXRefinableObj::OnMenuSave(wxCommandEvent & WXUNUSED(event))
635 {
636  VFN_DEBUG_MESSAGE("WXRefinableObj::OnButtonSave()",6)
637  wxFileDialog save(this,_T("Choose a file"),_T(""),_T(""),_T("*.xml"),wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
638  if(save.ShowModal() != wxID_OK) return;
639 
640  ofstream out(save.GetPath().ToAscii());
641  if(!out) return;//:TODO:
642  {
643  mpRefinableObj->XMLOutput(out);
644  }
645  out.close();
646 }
647 
648 void WXRefinableObj::OnMenuLoad(wxCommandEvent & WXUNUSED(event))
649 {
650  VFN_DEBUG_MESSAGE("WXRefinableObj::OnButtonLoad()",6)
651  wxFileDialog *open= new wxFileDialog(this,_T("Choose a file"),_T(""),_T(""),_T("*.xml"),
652  wxFD_OPEN | wxFD_FILE_MUST_EXIST);
653  if(open->ShowModal() != wxID_OK) return;
654 
655  ifstream fin(open->GetPath().ToAscii());
656  if(!fin) return;//:TODO:
657  {
658  XMLCrystTag tag(fin);//:TODO: load all tags and find the right ones for this class
659  mpRefinableObj->XMLInput(fin,tag);
660  }
661  fin.close();
662  open->Destroy();
663 }
664 
665 void WXRefinableObj::OnMenuFixAllPar(wxCommandEvent & WXUNUSED(event))
666 {
667  mpRefinableObj->FixAllPar();
668  this->CrystUpdate(true);
669 }
670 
671 void WXRefinableObj::OnMenuUnFixAllPar(wxCommandEvent & WXUNUSED(event))
672 {
673  mpRefinableObj->UnFixAllPar();
674  this->CrystUpdate(true);
675 }
676 
677 void WXRefinableObj::OnMenuParRandomize(wxCommandEvent & WXUNUSED(event))
678 {
679  mpRefinableObj->RandomizeConfiguration();
680  this->CrystUpdate(true);
681 }
682 
683 void WXRefinableObj::OnUpdateUI(wxUpdateUIEvent& event)
684 {
685  this->UpdateUI(true);
686  event.Skip();
687 }
688 void WXRefinableObj::UpdateUI(const bool lock)
689 {
690  VFN_DEBUG_ENTRY("WXRefinableObj::UpdateUI("<<lock<<")"<<"MainThread="<<wxThread::IsMain()<<":"<<mpRefinableObj->GetName(),6)
691  if(!mpRefinableObj->IsBeingRefined())
692  {
693  if(lock) mMutex.Lock();
694  mpWXTitle->SetValue(mpRefinableObj->GetName());
695  mpWXTitle->UpdateUI(false);
696  //mpSizer->SetItemMinSize
697  // (mpWXTitle, mpWXTitle->GetSize().GetWidth(),mpWXTitle->GetSize().GetHeight());
698  //mpWXTitle->Layout();
699  if(lock) mMutex.Unlock();
700  }
701  this->WXCrystObj::UpdateUI(lock);
702  VFN_DEBUG_EXIT("WXRefinableObj::UpdateUI()"<<mpRefinableObj->GetName(),6)
703 }
704 
705 }// namespace
T & GetObj(const unsigned int i)
Get object #i in the registry.
REAL GetHumanMin() const
Get the minimum value allowed (if limited)
T * WXDialogChooseFromRegistry(ObjRegistry< T > &reg, wxWindow *parent, const string &message, int &choice)
This function allows to pick up one object in a registry.
void Revert()
After a user entry, this allows to go back to the last value, if for some reason the entry was reject...
void SetValue(const string &)
This actually posts an UpdateUI event, so that it is safe to call it from a non-graphic thread...
Definition: wxCryst.cpp:467
void OnToggleLimited(wxCommandEvent &WXUNUSED(event))
Toggle the 'limited' status of the parameter.
void WXCrystValidateAllUserInput()
This function validates all user input (in a WXField) not yet taken into account, if needs be...
Definition: wxCryst.cpp:257
WX representation of a RefObj option. This displays the names of the different choices.
CrystMutex mMutex
Mutex used to lock data when preparing to update the UI in non-main thread.
Definition: wxCryst.h:189
long GetNb() const
Get the index of an object in the registry, from its name Warning: it can change if an object is remo...
bool IsBeingRefined() const
Is the object being refined ? (Can be refined by one algorithm at a time only.)
void FixAllPar()
Fix All parameters.
A field for a RefinablePar.
void OnPopupMenuChoice(wxCommandEvent &event)
Opens the popu menu, to allow changing limits.
bool mNeedUpdateUI
Do we need to update the display ?
Definition: wxCryst.h:187
void OnToggleFix(wxCommandEvent &WXUNUSED(event))
Toggle the 'fixed' status of the parameter.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
Definition: wxCryst.cpp:491
WXFieldName * mpWXTitle
The title.
Definition: wxCryst.h:273
This displays all components of a ObjCryst++ Registry.
This is the abstract base class for all fields, wether they contain a floating-point parameter...
Definition: wxCryst.h:291
wxString mFormat
Format to be used, default = _T("%8f")
const REAL & GetHumanValue() const
Current value of parameter, scaled if necessary (for angles) to a human-understandable value...
void OnPopupMenu(wxMouseEvent &event)
Opens the popu menu, to allow changing limits.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
Base class for options.
Definition: RefinableObj.h:550
const string GetValue() const
Get the current name.
Definition: wxCryst.cpp:481
void OnText(wxCommandEvent &WXUNUSED(event))
Records when text is entered (either from self-updating or user input)
void Revert()
After a user entry, this allows to go back to the last value, if for some reason the entry was reject...
~WXFieldRefPar()
When a new value is entered (must type it and then hit the 'enter' key).
wxBoxSizer * mpSizer
The horizontal sizer in which the title, button, fields, are put.
Definition: wxCryst.h:312
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
Base class for all displayed ObjCryst objects (with a title, and a sizer to stack objects)...
Definition: wxCryst.h:248
virtual void RandomizeConfiguration()
Randomize Configuration (before a global optimization).
virtual void ValidateUserInput()
This function shall be called when a new value has been entered.
virtual void XMLOutput(ostream &os, int indent=0) const
Output to stream in well-formed XML.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
void SetFormat(const wxString &format)
Set Format.
void SetHumanValue(const REAL &)
Current value of parameter, scaled if necessary (for angles) to a human-understandable value...
REAL GetHumanMax() const
Get the maximum value allowed (if limited)
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: Atom.cpp:47
void SetHumanMin(const REAL)
Set the minimum value allowed (if limited)
wxStaticText * mpLabel
The label.
Definition: wxCryst.h:314
virtual void SetToolTip(const wxString &tip)
Set tooltip for this window. It will be activated when going over the choice field.
WXField * spLastWXFieldInputNotValidated
This pointer records the last wxField in which something was enetered, so that it can be validated wh...
Definition: wxCryst.cpp:255
virtual const string & GetName() const
Name of the object.
void OnChoice(wxCommandEvent &WXUNUSED(event))
When a new value is entered.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
Definition: wxCryst.cpp:834
void SetHumanMax(const REAL)
Get the maximum value allowed (if limited)
bool IsUsed() const
Is the parameter used (if not, it is simply irrelevant in the model) ?
virtual void ValidateUserInput()
Does nothing. Any user input is directly validated (OnChoice).
virtual void SetToolTip(const wxString &tip)
Set tooltip for this window. It will be activated when going over the entry field.
void UnFixAllPar()
UnFix All parameters.
Object Registry.
Definition: RefinableObj.h:643
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
Definition: wxCryst.cpp:826
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
virtual void SetName(const string &name)
Name of the object.
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
virtual bool OnChangeName(const int id)
When a WXFieldName has been changed by the user, it is handled here.
virtual void XMLInput(istream &is, const XMLCrystTag &tag)
Input From stream.