File: wxFactory.cpp

package info (click to toggle)
wxastrocapture 1.8.1%2Bgit20140821.796e1a1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 42,212 kB
  • sloc: cpp: 43,421; sh: 733; perl: 246; makefile: 14
file content (545 lines) | stat: -rw-r--r-- 16,446 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
#include "wxFactory.h"

#include "wxIO/wxPortManager.h"
#include "wxIO/wxLongExpoPort.h"
#include "wxIO/wxGuiderPort.h"
#include "wxIO/wxPort.h"
#include "wxWebcam/fits/wxFitsKeyword.h"
#include "wxGuider.h"
#include "wxGuiderFileInterface.h"
#include "wxGuiderPortInterface.h"
#include "wxGuiderBridgeInterface.h"
#include "wxGuidingConfig.h"
#include "wxConfigPath.h"
#include <wx/stdpaths.h>
#include "wxWebcam/wxWebcam.h"
#include "wxWebcam/wxArtcam.h"

#include "BatchJobManager.h"

wxFactory* wxFactory::m_self = 0;

wxFactory* wxFactory::singleton()
{
   return m_self;
}

/// BM modified to use /.wxAstroCapture directory (due to GetUserDataDir())
/// the config file is named wxAstroCapture.conf per default?!
/// so make sure the old one is reallocated in the next setup !!!
wxFactory::wxFactory()
:m_config(_T("wxAstroCapture"),_T("Rustadgrenda"), wxEmptyString, wxEmptyString,
            wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_SUBDIR)
,m_camera(0)
,m_portManager(0)
,m_lePort(0)
,m_guidePort(0)
,m_index_port_entry(-1)
,m_capture_prefix(_T("wxAC"))
,m_guider(0)
,m_cntPointSize(CNT_HUGE)
,m_ftsSize(FTS_OFF)
,m_batchJobManager(0)
{
   m_self = this;


   Init();
}

wxFactory::~wxFactory()
{
   if (m_guider) delete m_guider;
   if (m_lePort) delete m_lePort;
   if (m_guidePort) delete m_guidePort;
   if (m_portManager) delete m_portManager;
   // don't delete cameras, it is not owned here

   m_policy_file.SaveToConfig(&m_config);
   m_policy_container.SaveToConfig(&m_config);
   if(m_batchJobManager) delete m_batchJobManager;
}

void wxFactory::Init()
{

   // Here we have to make sure the GetUserDataDir() exists
   // On Linux the config file is stored in this dir
   // ~/.appname on Linux
   // C:\Documents and Settings\username\Application Data\appname
   // We cannot rely on the OS or wx to create this directory

   wxString userDataDir = wxStandardPaths::Get().GetUserDataDir();
   wxString appname = m_config.GetAppName();
   userDataDir.Replace(wxT("wxastrocapture"),appname);
   if(!::wxDirExists(userDataDir)) {
      ::wxMkdir(userDataDir);
   }


   restoreFromConfig();
}

// enumerate any camera on the system
size_t wxFactory::EnumerateCameras(wxWindow* parent,wxArrayString& cameras, CameraTypeVector& ctypes)
{
    cameras.clear();
    ctypes.clear();

    // construct two temporary camera objects to help enumerate cameras
    wxWebcam* tmp1 = wxWebcam::Construct(parent);
    wxArtcam* tmp2 = wxArtcam::Construct(parent);

    size_t nweb = tmp1->EnumerateCameras(cameras);
    for(size_t i=0;i<nweb;i++)ctypes.push_back(ECT_Webcam);

    tmp2->EnumerateCameras(cameras);
    size_t nart = cameras.size() - nweb;
    for(size_t i=0;i<nart;i++)ctypes.push_back(ECT_Artcam);

    tmp1->Destroy();
    tmp2->Destroy();

    return (nweb+nart);
}

void wxFactory::setCamera(wxCamera* camera)
{
   if(wxWebcam* webcam = dynamic_cast<wxWebcam*>(camera))setWebcam(webcam);
   else if(wxArtcam* artcam = dynamic_cast<wxArtcam*>(camera))setArtcam(artcam);
}

void wxFactory::setWebcam(wxWebcam* webcam)
{
   // the camera is not owned here, any existing camera is deleted elsewhere
   m_camera = webcam;
}

void wxFactory::setArtcam(wxArtcam* artcam)
{
   // the camera is not owned here, any existing camera is deleted elsewhere
   m_camera = artcam;
}

bool wxFactory::restoreFromConfig()
{
   if(!m_config.Read(_T("CaptureFolder"),&m_capture_folder)) {
      m_capture_folder = wxGetHomeDir();
   }

   m_config.Read(_T("CapturePrefix"),&m_capture_prefix,m_capture_prefix);

   int ifont_size(2),ifont_size_def(2);
   m_config.Read(_T("FrameCounterFontSize"),&ifont_size,ifont_size_def);
   wxFactory::FrameCounterSize font_size = wxFactory::CNT_OFF;
   switch(ifont_size) {
      case 0:  {font_size = wxFactory::CNT_OFF;     break; }
      case 1:  {font_size = wxFactory::CNT_SMALL;   break; }
      case 2:  {font_size = wxFactory::CNT_MEDIUM;  break; }
      case 3:  {font_size = wxFactory::CNT_LARGE;   break; }
      case 4:  {font_size = wxFactory::CNT_HUGE;    break; }
      default: {font_size = wxFactory::CNT_MEDIUM;}
   };
   SetFrameCounterFontSize(font_size);

   int iframe_timestamp,iframe_timestamp_def(0);
   m_config.Read(_T("FrameTimeStampSize"),&iframe_timestamp,iframe_timestamp_def);
   wxFactory::FrameTimeStampSize fts_size = FrameTimeStampFontSize();
   switch(iframe_timestamp) {
      case 0:  {fts_size = wxFactory::FTS_OFF;     break; }
      case 1:  {fts_size = wxFactory::FTS_SMALL;   break; }
      case 2:  {fts_size = wxFactory::FTS_MEDIUM;  break; }
      default: {fts_size = wxFactory::FTS_MEDIUM;}
   };
   SetFrameTimeStampFontSize(fts_size);

   //20100703:BM - added new settings
   ifont_size=2; ifont_size_def=2;
   m_config.Read(_T("FpsFontSize"),&ifont_size,ifont_size_def);
   wxFactory::FrameCounterSize ffont_size = wxFactory::CNT_OFF;
   switch(ifont_size) {
      case 0:  {ffont_size = wxFactory::CNT_OFF;     break; }
      case 1:  {ffont_size = wxFactory::CNT_SMALL;   break; }
      case 2:  {ffont_size = wxFactory::CNT_MEDIUM;  break; }
      case 3:  {ffont_size = wxFactory::CNT_LARGE;   break; }
      case 4:  {ffont_size = wxFactory::CNT_HUGE;    break; }
      default: {ffont_size = wxFactory::CNT_MEDIUM;}
   };
   wxF()->SetFpsFontSize(ffont_size);

   //20100703:BM - added new settings
   int iperf_level,iperf_level_def(0);
   m_config.Read(_T("PerformanceLevel"),&iperf_level,iperf_level_def);
   wxFactory::PerfPollIntervall perf_level = wxFactory::PPL_LOW;
   switch(iperf_level) {
      case 0:  {perf_level = wxFactory::PPL_LOW;   break; }
      case 1:  {perf_level = wxFactory::PPL_MID;   break; }
      case 2:  {perf_level = wxFactory::PPL_HIGH;  break; }
      default: {perf_level = wxFactory::PPL_LOW;}
   };
   wxF()->SetPerformanceLevel(perf_level);

   // Set the chosen guider interface
   setGuiderInterface(wxGuidingConfig::getGuiderInterface());

   // restore name policies
   m_policy_file.RestoreFromConfig(&m_config);
   m_policy_container.RestoreFromConfig(&m_config);

   // Do not instantiate the guide port yet
   // wait until someone asks for it, see guidePort().
   // This is because if the guide port is a serial port, it may be in use
   // from another program at this stage (typically for GOTO purposes).
   // We don't want error messages each time we start the program because of
   // a busy guide port that we may not even want to use in this session.

   return true;
}

wxWebcam*  wxFactory::webcam()
{
   return dynamic_cast<wxWebcam*>(m_camera);
}

wxArtcam*  wxFactory::artcam()
{
   return dynamic_cast<wxArtcam*>(m_camera);;
}

wxCamera*  wxFactory::cam()
{
   return m_camera;
}

wxConfig*  wxFactory::config()
{
   return &m_config;
}

wxLongExpoPort*    wxFactory::lePort()
{
   if(!m_lePort) {
      m_lePort = new wxLongExpoPort();

      // restore long exposure port info
      m_lePort->RestoreFromConfigLongExpo(&m_config);
   }

   return m_lePort;
}

void wxFactory::lePortRelease(bool force_release)
{
   if(m_lePort) {

      bool release_port = true;

      // Release the LE port only if no webcam is connected
      if(wxWebcam* webcam = this->webcam()) {
         // we have a webcam, is it connected?
         if(webcam->IsConnected()) {
            // cannot release port
            if(!force_release)release_port = false;
         }
      }

      if(release_port) {
         delete m_lePort; // delete implies a PClose()
         m_lePort = 0;
      }
   }
}

wxGuiderPort*    wxFactory::guidePort()
{
   if(!m_guidePort) {
      m_guidePort = new wxGuiderPort();

      // restore guider port info
      m_guidePort->RestoreFromConfigGuidePort(&m_config);
   }

   return m_guidePort;
}

bool wxFactory::setGuiderInterface(wxGuider::guider_interface intfc)
{
   delete m_guider;
   m_guider = 0;

   switch(intfc) {
      case wxGuider::PORT_INTERFACE:   { m_guider = new wxGuiderPortInterface(); break; }
      case wxGuider::BRIDGE_INTERFACE: { m_guider = new wxGuiderBridgeInterface(); break; }
      default:                         { m_guider = new wxGuiderFileInterface(); break; }
   };

   if(m_guider) {
      // save interface type to configuration
      wxGuidingConfig::saveGuiderInterface();
      return true;
   }
   return false;
}

wxGuider*  wxFactory::guider()
{
   if(!m_guider)setGuiderInterface(wxGuider::FILE_INTERFACE);
   return m_guider;
}

wxString  wxFactory::captureFolder()
{
   return m_capture_folder;
}

wxString  wxFactory::capturePrefix()
{
   return m_capture_prefix;
}

// returns the portmanager
wxPortManager* wxFactory::portManager()
{
   if(!m_portManager) m_portManager = new wxPortManager();

   return m_portManager;
}

bool  wxFactory::setCaptureFolder(const wxString& folder, const wxString& prefix)
{
    m_capture_folder = folder;
    m_capture_prefix = prefix;
    m_config.Write(_T("CaptureFolder"),m_capture_folder);
    m_config.Write(_T("CapturePrefix"),m_capture_prefix);

    // Mark the name policy objects dirty so they get recomputed
    if(m_policy_file.IsActiveItem(wxT("prefix")))m_policy_file.CommitName();
    if(m_policy_container.IsActiveItem(wxT("prefix")))m_policy_container.CommitName();
    return true;
}

EVideoSampleFormat wxFactory::sampleFormat()
{
   int format,defVal(EVF_YUV); // see captypes.h EVideoSampleFormat
   m_config.Read(_T("CaptureFormat"),&format,defVal);
   EVideoSampleFormat EVformat = (EVideoSampleFormat)format;
   return EVformat;
}

EContainerFormat wxFactory::containerFormat()
{
   int format,defVal(ECF_AVI); // see captypes.h EContainerFormat
   m_config.Read(_T("ContainerFormat"),&format,defVal);
   EContainerFormat ECformat = (EContainerFormat)format;
   return ECformat;
}

bool wxFactory::saveFitsHeaderEntries(wxPropGrid::Entries& entries)
{
   wxString FitsHeader = wxT("FitsHeader");
   // remove any existing content
   m_config.DeleteGroup(FitsHeader);

   // recreate the group and write to it
   wxConfigPath config(&m_config,FitsHeader);

   int counter = 0;
   wxPropGrid::Entries::iterator ie = entries.begin();
   while(ie != entries.end()) {
      wxString keyword;
      keyword.Printf(wxT("key%03i"),++counter);
      wxString value   = ie->keyword + wxT('/') + ie->value + wxT('/') + ie->comment;
      ie++;
      m_config.Write(keyword,value);
   }
   return true;
}

bool wxFactory::getFitsHeaderValue(const wxString& kw, wxString& value)
{
   wxPropGrid::Entries entries;
   getFitsHeaderEntries(entries);
   wxPropGrid::Entries::iterator i = entries.begin();
   while(i != entries.end()) {
      if(kw == i->keyword) {
         value = i->value;
         value.Trim(true);
         value.Trim(false);
         return true;
      }
      i++;
   }
   return false;
}

bool wxFactory::saveFitsHeaderValue(const wxString& kw, wxString& value)
{
   wxPropGrid::Entries entries;
   getFitsHeaderEntries(entries);
   wxPropGrid::Entries::iterator i = entries.begin();
   while(i != entries.end()) {
      if(kw == i->keyword) {
         i->value = value;
         saveFitsHeaderEntries(entries);
         return true;
      }
      i++;
   }
   return false;
}

bool wxFactory::getFitsHeaderEntries(wxPropGrid::Entries& entries)
{
   wxString FitsHeader = wxT("FitsHeader");
   if(m_config.HasGroup(FitsHeader)) {

      wxConfigPath config(&m_config,FitsHeader);

      // a wxWidgets bug prevents use of GetFirstEntry()/GetNextEntry().
      // They work only the next time the application is started.
      // Instead we use Read() with a generated key, until it fails

      int counter = 0;
      bool value_found = true;
      while(value_found) {
         wxString keyword;
         keyword.Printf(wxT("key%03i"),++counter);
         wxString value;
         if(value_found = m_config.Read(keyword,&value,wxT("//"))) {

            // find the first forward slash and extract the FITS keyword
            int s1 = value.Find('/');
            wxString keyword = value.Mid(0,s1);

            // extract the remaining string
            value = value.Mid(s1+1);

            // find the second forward slash separating value and comment
            int s2 = value.Find('/');
            wxString val = value.Mid(0,s2);
            wxString comment = value.Mid(s2+1);

            // push the entry
            entries.push_back(wxPropGrid::Entry(keyword,val,comment));
         }
      }
   }
   else {
      // nothing in configuration, push empty entries
      entries.push_back(wxPropGrid::Entry(wxT("OBSERVER"),wxT(""),wxT("Observer name")));
      entries.push_back(wxPropGrid::Entry(wxT("SITELAT"),wxT(""),wxT("The site latitude (deg)")));
      entries.push_back(wxPropGrid::Entry(wxT("SITELONG"),wxT(""),wxT("The site longitude (deg)")));
      entries.push_back(wxPropGrid::Entry(wxT("TELESCOP"),wxT(""),wxT("Data acquisition telescope")));
      entries.push_back(wxPropGrid::Entry(wxT("INSTRUME"),wxT(""),wxT("Name of instrument (camera)")));
      entries.push_back(wxPropGrid::Entry(wxT("PSZX"),wxT(""),wxT("Size of a pixel in X direction [m]")));
      entries.push_back(wxPropGrid::Entry(wxT("PSZY"),wxT(""),wxT("Size of a pixel in Y direction [m]")));
      entries.push_back(wxPropGrid::Entry(wxT("FILTER"),wxT(""),wxT("Filter used")));
      entries.push_back(wxPropGrid::Entry(wxT("OBJECT"),wxT("Object"),wxT("Object of observation")));
      entries.push_back(wxPropGrid::Entry(wxT("IMAGETYP"),wxT(""),wxT("LIGHT, BIAS, FLAT or DARK")));
      entries.push_back(wxPropGrid::Entry(wxT("COMMENT"),wxT(""),wxT("Any Comment")));

      // Also save these values to config immediately
      saveFitsHeaderEntries(entries);
   }

   return true;
}

bool wxFactory::getFitsKeywordList(wxFitsKeywordList& kwlist)
{
   wxPropGrid::Entries entries;
   if(getFitsHeaderEntries(entries)) {

	  // convert the grid entries to wxFitsKeywords and add to list
	  wxPropGrid::Entries::iterator ie = entries.begin();
      while(ie != entries.end()) {
         const wxString& keyword = ie->keyword;
         const wxString& value   = ie->value;
         const wxString& comment = ie->comment;

         wxFitsKeyword::EFitsKeyword ekw = wxFitsKeyword::lookupKeyword(keyword);
         if(ekw != wxFitsKeyword::EF_UNDEFINED && value.Length() != 0) {
            if(ekw == wxFitsKeyword::EF_PSZX || ekw == wxFitsKeyword::EF_PSZY ) {

			      // these are of double type
               double dval = 0.0;
               if(value.ToDouble(&dval)) kwlist += wxFitsKeyword(ekw,dval,4,comment);
            }
            else {

			      // normal string type
               kwlist += wxFitsKeyword(ekw,value,comment);
            }
         }
         ie++;
      }

      return true;
   }
   return false;
}


wxNamePolicyFile*       wxFactory::getNamePolicyFile()
{
   return &m_policy_file;
}

wxNamePolicyContainer*  wxFactory::getNamePolicyContainer()
{
   return &m_policy_container;
}


void wxFactory::SetFrameCounterFontSize(FrameCounterSize font_size)
{
   m_cntPointSize = font_size;
}

wxFactory::FrameCounterSize wxFactory::FrameCounterFontSize() const
{
   return m_cntPointSize;
}

void wxFactory::SetFrameTimeStampFontSize(FrameTimeStampSize fts_size)
{
   m_ftsSize = fts_size;
}

wxFactory::FrameTimeStampSize wxFactory::FrameTimeStampFontSize() const
{
   return m_ftsSize;
}


//20100703:BM - added new settings
// FrameCounterSize enum used for the FPS indication
void wxFactory::SetFpsFontSize(FrameCounterSize font_size)
{
   m_fpsPointSize = font_size;
}

wxFactory::FrameCounterSize wxFactory::FpsFontSize() const
{
   return m_fpsPointSize;
}

//20100703:BM - added new settings
// defines the polling interval and the max reachable FPS (level is also poll IV millisec here)
void wxFactory::SetPerformanceLevel(PerfPollIntervall font_size)
{
   m_camPollIntervall = font_size;
}

wxFactory::PerfPollIntervall wxFactory::PerformanceLevel() const
{
   return m_camPollIntervall;
}



BatchJobManager* wxFactory::batchJobManager()
{
   if(!m_batchJobManager) m_batchJobManager = new BatchJobManager();
   return m_batchJobManager;
}