PanoPanel.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00028 #include "hugin_config.h"
00029 #include <wx/stdpaths.h>
00030 
00031 #include "panoinc_WX.h"
00032 #include "panoinc.h"
00033 #include "base_wx/platform.h"
00034 #include "base_wx/PanoCommand.h"
00035 
00036 #include <hugin/config_defaults.h>
00037 
00038 #include "nona/Stitcher.h"
00039 #include "base_wx/wxPlatform.h"
00040 
00041 extern "C" {
00042 #include <pano13/queryfeature.h>
00043 }
00044 
00045 #include "base_wx/CommandHistory.h"
00046 #include "hugin/CPImageCtrl.h"
00047 #include "hugin/CPImagesComboBox.h"
00048 #include "hugin/PanoPanel.h"
00049 #include "hugin/MainFrame.h"
00050 #include "hugin/huginApp.h"
00051 #include "hugin/HDRMergeOptionDialog.h"
00052 #include "hugin/TextKillFocusHandler.h"
00053 #include "base_wx/MyProgressDialog.h"
00054 #include "hugin/config_defaults.h"
00055 #include "base_wx/platform.h"
00056 #include "base_wx/huginConfig.h"
00057 #include "base_wx/LensTools.h"
00058 #include "algorithms/basic/LayerStacks.h"
00059 #include "algorithms/basic/CalculateOptimalScale.h"
00060 #include "algorithms/basic/CalculateOptimalROI.h"
00061 #include "algorithms/nona/FitPanorama.h"
00062 #include "lensdb/LensDB.h"
00063 
00064 #define WX_BROKEN_SIZER_UNKNOWN
00065 
00066 BEGIN_EVENT_TABLE(PanoPanel, wxPanel)
00067     EVT_CHOICE ( XRCID("pano_choice_pano_type"),PanoPanel::ProjectionChanged )
00068     EVT_TEXT_ENTER( XRCID("pano_text_hfov"),PanoPanel::HFOVChanged )
00069     EVT_TEXT_ENTER( XRCID("pano_text_vfov"),PanoPanel::VFOVChanged )
00070     EVT_BUTTON ( XRCID("pano_button_calc_fov"), PanoPanel::DoCalcFOV)
00071     EVT_TEXT_ENTER ( XRCID("pano_val_width"),PanoPanel::WidthChanged )
00072     EVT_TEXT_ENTER ( XRCID("pano_val_height"),PanoPanel::HeightChanged )
00073     EVT_TEXT_ENTER ( XRCID("pano_val_roi_top"),PanoPanel::ROIChanged )
00074     EVT_TEXT_ENTER ( XRCID("pano_val_roi_bottom"),PanoPanel::ROIChanged )
00075     EVT_TEXT_ENTER ( XRCID("pano_val_roi_left"),PanoPanel::ROIChanged )
00076     EVT_TEXT_ENTER ( XRCID("pano_val_roi_right"),PanoPanel::ROIChanged )
00077     EVT_BUTTON ( XRCID("pano_button_opt_width"), PanoPanel::DoCalcOptimalWidth)
00078     EVT_BUTTON ( XRCID("pano_button_opt_roi"), PanoPanel::DoCalcOptimalROI)
00079     EVT_BUTTON ( XRCID("pano_button_stitch"),PanoPanel::OnDoStitch )
00080 
00081     EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_blended"), PanoPanel::OnOutputFilesChanged)
00082     EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_layers"), PanoPanel::OnOutputFilesChanged)
00083     EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_exposure_layers"), PanoPanel::OnOutputFilesChanged)
00084     EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_exposure_blended"), PanoPanel::OnOutputFilesChanged)
00085     EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_exposure_layers_fused"), PanoPanel::OnOutputFilesChanged)
00086     EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_stacks"), PanoPanel::OnOutputFilesChanged)
00087     EVT_CHECKBOX ( XRCID("pano_cb_ldr_output_exposure_remapped"), PanoPanel::OnOutputFilesChanged)
00088     EVT_CHECKBOX ( XRCID("pano_cb_hdr_output_blended"), PanoPanel::OnOutputFilesChanged)
00089     EVT_CHECKBOX ( XRCID("pano_cb_hdr_output_stacks"), PanoPanel::OnOutputFilesChanged)
00090     EVT_CHECKBOX ( XRCID("pano_cb_hdr_output_layers"), PanoPanel::OnOutputFilesChanged)
00091 
00092     EVT_CHOICE ( XRCID("pano_choice_remapper"),PanoPanel::RemapperChanged )
00093     EVT_BUTTON ( XRCID("pano_button_remapper_opts"),PanoPanel::OnRemapperOptions )
00094 
00095     EVT_CHOICE ( XRCID("pano_choice_fusion"),PanoPanel::FusionChanged )
00096     EVT_BUTTON ( XRCID("pano_button_fusion_opts"),PanoPanel::OnFusionOptions )
00097 
00098     EVT_CHOICE ( XRCID("pano_choice_hdrmerge"),PanoPanel::HDRMergeChanged )
00099     EVT_BUTTON ( XRCID("pano_button_hdrmerge_opts"),PanoPanel::OnHDRMergeOptions )
00100 
00101     EVT_CHOICE ( XRCID("pano_choice_blender"),PanoPanel::BlenderChanged )
00102     EVT_BUTTON ( XRCID("pano_button_blender_opts"),PanoPanel::OnBlenderOptions )
00103 
00104     EVT_CHOICE ( XRCID("pano_choice_file_format"),PanoPanel::FileFormatChanged )
00105     EVT_CHOICE ( XRCID("pano_choice_hdr_file_format"),PanoPanel::HDRFileFormatChanged )
00106 //    EVT_SPINCTRL ( XRCID("pano_output_normal_opts_jpeg_quality"),PanoPanel::OnJPEGQualitySpin )
00107     EVT_TEXT_ENTER ( XRCID("pano_output_normal_opts_jpeg_quality"),PanoPanel::OnJPEGQualityText )
00108     EVT_CHOICE ( XRCID("pano_output_normal_opts_tiff_compression"),PanoPanel::OnNormalTIFFCompression)
00109     EVT_CHOICE ( XRCID("pano_output_hdr_opts_tiff_compression"),PanoPanel::OnHDRTIFFCompression)
00110 
00111 END_EVENT_TABLE()
00112 
00113 PanoPanel::PanoPanel()
00114     : pano(0), m_guiLevel(GUI_SIMPLE), updatesDisabled(false)
00115 {
00116 
00117 }
00118 
00119 bool PanoPanel::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
00120                       long style, const wxString& name)
00121 {
00122     if (! wxPanel::Create(parent, id, pos, size, style, name)) {
00123         return false;
00124     }
00125 
00126     wxXmlResource::Get()->LoadPanel(this, wxT("panorama_panel"));
00127     wxPanel * panel = XRCCTRL(*this, "panorama_panel", wxPanel);
00128 
00129     wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
00130     topsizer->Add(panel, 1, wxEXPAND, 0);
00131     SetSizer(topsizer);
00132 
00133     // converts KILL_FOCUS events to usable TEXT_ENTER events
00134     // get gui controls
00135     m_ProjectionChoice = XRCCTRL(*this, "pano_choice_pano_type" ,wxChoice);
00136     DEBUG_ASSERT(m_ProjectionChoice);
00137 
00138     m_keepViewOnResize = true;
00139     m_hasStacks=false;
00140 
00141 #ifdef ThisNeverHappens
00142 // provide some translatable strings for the drop down menu
00143     wxLogMessage(_("Fisheye"));
00144     wxLogMessage(_("Stereographic"));
00145     wxLogMessage(_("Mercator"));
00146     wxLogMessage(_("Trans Mercator"));
00147     wxLogMessage(_("Sinusoidal"));
00148     wxLogMessage(_("Lambert Cylindrical Equal Area"));
00149     wxLogMessage(_("Lambert Equal Area Azimuthal"));
00150     wxLogMessage(_("Albers Equal Area Conic"));
00151     wxLogMessage(_("Miller Cylindrical"));
00152     wxLogMessage(_("Panini"));
00153     wxLogMessage(_("Architectural"));
00154     wxLogMessage(_("Orthographic"));
00155     wxLogMessage(_("Equisolid"));
00156     wxLogMessage(_("Equirectangular Panini"));
00157     wxLogMessage(_("Biplane"));
00158     wxLogMessage(_("Triplane"));
00159     wxLogMessage(_("Panini General"));
00160     wxLogMessage(_("Thoby Projection"));
00161     wxLogMessage(_("Hammer-Aitoff Equal Area"));
00162 #endif
00163 
00164     /* populate with all available projection types */
00165     int nP = panoProjectionFormatCount();
00166     for(int n=0; n < nP; n++) {
00167         pano_projection_features proj;
00168         if (panoProjectionFeaturesQuery(n, &proj)) {
00169             wxString str2(proj.name, wxConvLocal);
00170             m_ProjectionChoice->Append(wxGetTranslation(str2));
00171         }
00172     }
00173     m_HFOVText = XRCCTRL(*this, "pano_text_hfov" ,wxTextCtrl);
00174     DEBUG_ASSERT(m_HFOVText);
00175     m_CalcHFOVButton = XRCCTRL(*this, "pano_button_calc_fov" ,wxButton);
00176     DEBUG_ASSERT(m_CalcHFOVButton);
00177     m_HFOVText->PushEventHandler(new TextKillFocusHandler(this));
00178     m_VFOVText = XRCCTRL(*this, "pano_text_vfov" ,wxTextCtrl);
00179     DEBUG_ASSERT(m_VFOVText);
00180     m_VFOVText->PushEventHandler(new TextKillFocusHandler(this));
00181 
00182 
00183     m_WidthTxt = XRCCTRL(*this, "pano_val_width", wxTextCtrl);
00184     DEBUG_ASSERT(m_WidthTxt);
00185     m_WidthTxt->PushEventHandler(new TextKillFocusHandler(this));
00186     m_CalcOptWidthButton = XRCCTRL(*this, "pano_button_opt_width" ,wxButton);
00187     DEBUG_ASSERT(m_CalcOptWidthButton);
00188 
00189     m_HeightTxt = XRCCTRL(*this, "pano_val_height", wxTextCtrl);
00190     DEBUG_ASSERT(m_HeightTxt);
00191     m_HeightTxt->PushEventHandler(new TextKillFocusHandler(this));
00192 
00193     m_ROILeftTxt = XRCCTRL(*this, "pano_val_roi_left", wxTextCtrl);
00194     DEBUG_ASSERT(m_ROILeftTxt);
00195     m_ROILeftTxt->PushEventHandler(new TextKillFocusHandler(this));
00196 
00197     m_ROIRightTxt = XRCCTRL(*this, "pano_val_roi_right", wxTextCtrl);
00198     DEBUG_ASSERT(m_ROIRightTxt);
00199     m_ROIRightTxt->PushEventHandler(new TextKillFocusHandler(this));
00200 
00201     m_ROITopTxt = XRCCTRL(*this, "pano_val_roi_top", wxTextCtrl);
00202     DEBUG_ASSERT(m_ROITopTxt);
00203     m_ROITopTxt->PushEventHandler(new TextKillFocusHandler(this));
00204 
00205     m_ROIBottomTxt = XRCCTRL(*this, "pano_val_roi_bottom", wxTextCtrl);
00206     DEBUG_ASSERT(m_ROIBottomTxt);
00207     m_ROIBottomTxt->PushEventHandler(new TextKillFocusHandler(this));
00208     
00209     m_CalcOptROIButton = XRCCTRL(*this, "pano_button_opt_roi" ,wxButton);
00210     DEBUG_ASSERT(m_CalcOptROIButton);    
00211 
00212     m_RemapperChoice = XRCCTRL(*this, "pano_choice_remapper", wxChoice);
00213     DEBUG_ASSERT(m_RemapperChoice);
00214     m_FusionChoice = XRCCTRL(*this, "pano_choice_fusion", wxChoice);
00215     DEBUG_ASSERT(m_FusionChoice);
00216     m_HDRMergeChoice = XRCCTRL(*this, "pano_choice_hdrmerge", wxChoice);
00217     DEBUG_ASSERT(m_HDRMergeChoice);
00218     m_BlenderChoice = XRCCTRL(*this, "pano_choice_blender", wxChoice);
00219     DEBUG_ASSERT(m_BlenderChoice);
00220     FillBlenderList(m_BlenderChoice);
00221 
00222     m_StitchButton = XRCCTRL(*this, "pano_button_stitch", wxButton);
00223     DEBUG_ASSERT(m_StitchButton);
00224 
00225     m_FileFormatChoice = XRCCTRL(*this, "pano_choice_file_format", wxChoice);
00226     DEBUG_ASSERT(m_FileFormatChoice);
00227     m_FileFormatOptionsLabel = XRCCTRL(*this, "pano_output_ldr_format_options_label", wxStaticText);
00228     
00229     m_FileFormatJPEGQualityText = XRCCTRL(*this, "pano_output_normal_opts_jpeg_quality", wxTextCtrl);
00230     DEBUG_ASSERT(m_FileFormatJPEGQualityText);
00231     m_FileFormatJPEGQualityText->PushEventHandler(new TextKillFocusHandler(this));
00232 
00233     m_FileFormatTIFFCompChoice = XRCCTRL(*this, "pano_output_normal_opts_tiff_compression", wxChoice);
00234     DEBUG_ASSERT(m_FileFormatTIFFCompChoice);
00235 
00236     m_HDRFileFormatChoice = XRCCTRL(*this, "pano_choice_hdr_file_format", wxChoice);
00237     DEBUG_ASSERT(m_HDRFileFormatChoice);
00238     m_HDRFileFormatLabelTIFFCompression = XRCCTRL(*this, "pano_output_hdr_opts_tiff_compression_label", wxStaticText);
00239     DEBUG_ASSERT(m_HDRFileFormatLabelTIFFCompression);
00240     m_FileFormatHDRTIFFCompChoice = XRCCTRL(*this, "pano_output_hdr_opts_tiff_compression", wxChoice);
00241     DEBUG_ASSERT(m_FileFormatHDRTIFFCompChoice);
00242 
00243     m_pano_ctrls = XRCCTRL(*this, "pano_controls_panel", wxScrolledWindow);
00244     DEBUG_ASSERT(m_pano_ctrls);
00245     m_pano_ctrls->SetSizeHints(20, 20);
00246     m_pano_ctrls->FitInside();
00247     m_pano_ctrls->SetScrollRate(10, 10);
00248 
00249 
00250 /*
00251     // trigger creation of apropriate stitcher control, if
00252     // not already happend.
00253     if (! m_Stitcher) {
00254         wxCommandEvent dummy;
00255         StitcherChanged(dummy);
00256     }
00257 */
00258     DEBUG_TRACE("")
00259     return true;
00260 }
00261 
00262 void PanoPanel::Init(HuginBase::Panorama * panorama)
00263 {
00264     pano = panorama;
00265     // observe the panorama
00266     pano->addObserver(this);
00267     panoramaChanged(*panorama);
00268 }
00269 
00270 PanoPanel::~PanoPanel(void)
00271 {
00272     DEBUG_TRACE("dtor");
00273     wxConfigBase::Get()->Write(wxT("Stitcher/DefaultRemapper"),m_RemapperChoice->GetSelection());
00274 
00275     m_HFOVText->PopEventHandler(true);
00276     m_VFOVText->PopEventHandler(true);
00277     m_WidthTxt->PopEventHandler(true);
00278     m_HeightTxt->PopEventHandler(true);
00279     m_ROILeftTxt->PopEventHandler(true);
00280     m_ROIRightTxt->PopEventHandler(true);
00281     m_ROITopTxt->PopEventHandler(true);
00282     m_ROIBottomTxt->PopEventHandler(true);
00283     m_FileFormatJPEGQualityText->PopEventHandler(true);
00284     pano->removeObserver(this);
00285     DEBUG_TRACE("dtor end");
00286 }
00287 
00288 
00289 void PanoPanel::panoramaChanged (HuginBase::Panorama &pano)
00290 {
00291     DEBUG_TRACE("");
00292 
00293 #ifdef STACK_CHECK //Disabled for 0.7.0 release
00294     const bool hasStacks = StackCheck(pano);
00295 #else
00296     const bool hasStacks = false;
00297 #endif
00298 
00299     HuginBase::PanoramaOptions opt = pano.getOptions();
00300 
00301     // update all options for dialog and notebook tab
00302     UpdateDisplay(opt,hasStacks);
00303 
00304     m_oldOpt = opt;
00305 }
00306 
00307 
00308 bool PanoPanel::StackCheck(HuginBase::Panorama &pano)
00309 {
00310     DEBUG_TRACE("");
00311     HuginBase::PanoramaOptions opt = pano.getOptions();
00312 
00313     // Determine if there are stacks in the pano.
00314     HuginBase::UIntSet activeImages = pano.getActiveImages();
00315     HuginBase::UIntSet images = getImagesinROI(pano, activeImages);
00316     std::vector<HuginBase::UIntSet> hdrStacks = HuginBase::getHDRStacks(pano, images, pano.getOptions());
00317     DEBUG_DEBUG(hdrStacks.size() << ": HDR stacks detected");
00318     const bool hasStacks = (hdrStacks.size() != activeImages.size());
00319 
00320     // Only change the output types if the stack configuration has changed.
00321     bool isChanged = (hasStacks != m_hasStacks);
00322     if (isChanged) {
00323         if (hasStacks) {
00324             // Disable normal output formats
00325             opt.outputLDRBlended = false;
00326             opt.outputLDRLayers = false;
00327             // Ensure at least one fused output is enabled
00328             if (!(opt.outputLDRExposureBlended ||
00329                   opt.outputLDRExposureLayers ||
00330                   opt.outputLDRExposureRemapped ||
00331                   opt.outputHDRBlended ||
00332                   opt.outputHDRStacks ||
00333                   opt.outputHDRLayers)) {
00334                 opt.outputLDRExposureBlended = true;
00335             }
00336         } else {
00337             // Disable fused output formats
00338             opt.outputLDRExposureBlended = false;
00339             opt.outputLDRExposureLayers = false;
00340             opt.outputLDRExposureRemapped = false;
00341             opt.outputHDRBlended = false;
00342             opt.outputHDRStacks = false;
00343             opt.outputHDRLayers = false;
00344             // Ensure at least one normal output is enabled
00345             if (!(opt.outputLDRBlended || opt.outputLDRLayers)) {
00346                 opt.outputLDRBlended = true;
00347             }
00348         }
00349         pano.setOptions(opt);
00350     }
00351         
00352     m_hasStacks = hasStacks;
00353 
00354     return hasStacks;
00355 }
00356 
00357 
00358 void PanoPanel::UpdateDisplay(const HuginBase::PanoramaOptions & opt, const bool hasStacks)
00359 {
00360     Freeze();
00361 //    m_HFOVSpin->SetRange(1,opt.getMaxHFOV());
00362 //    m_VFOVSpin->SetRange(1,opt.getMaxVFOV());
00363 
00364     m_ProjectionChoice->SetSelection(opt.getProjection());
00365     m_keepViewOnResize = opt.fovCalcSupported(opt.getProjection());
00366 
00367     std::string val;
00368     val = hugin_utils::doubleToString(opt.getHFOV(),1);
00369     m_HFOVText->ChangeValue(wxString(val.c_str(), wxConvLocal));
00370     val = hugin_utils::doubleToString(opt.getVFOV(), 1);
00371     m_VFOVText->ChangeValue(wxString(val.c_str(), wxConvLocal));
00372 
00373     // disable VFOV edit field, due to bugs in setHeight(), setWidth()
00374     bool hasImages = pano->getActiveImages().size() > 0;
00375     m_VFOVText->Enable(m_keepViewOnResize);
00376     m_CalcOptWidthButton->Enable(m_keepViewOnResize && hasImages);
00377     m_CalcHFOVButton->Enable(m_keepViewOnResize && hasImages);
00378     m_CalcOptROIButton->Enable(hasImages);
00379 
00380     m_WidthTxt->ChangeValue(wxString::Format(wxT("%d"), opt.getWidth()));
00381     m_HeightTxt->ChangeValue(wxString::Format(wxT("%d"), opt.getHeight()));
00382 
00383     m_ROILeftTxt->ChangeValue(wxString::Format(wxT("%d"), opt.getROI().left() ));
00384     m_ROIRightTxt->ChangeValue(wxString::Format(wxT("%d"), opt.getROI().right() ));
00385     m_ROITopTxt->ChangeValue(wxString::Format(wxT("%d"), opt.getROI().top() ));
00386     m_ROIBottomTxt->ChangeValue(wxString::Format(wxT("%d"), opt.getROI().bottom() ));
00387 
00388     // output types
00389     XRCCTRL(*this, "pano_cb_ldr_output_blended", wxCheckBox)->SetValue(opt.outputLDRBlended);
00390     XRCCTRL(*this, "pano_cb_ldr_output_exposure_blended", wxCheckBox)->SetValue(opt.outputLDRExposureBlended);
00391     XRCCTRL(*this, "pano_cb_ldr_output_exposure_layers_fused", wxCheckBox)->SetValue(opt.outputLDRExposureLayersFused);
00392     XRCCTRL(*this, "pano_cb_hdr_output_blended", wxCheckBox)->SetValue(opt.outputHDRBlended);
00393     XRCCTRL(*this, "pano_cb_hdr_output_blended", wxCheckBox)->Show(opt.outputHDRBlended || m_guiLevel>GUI_SIMPLE);
00394 
00395     //remapped images
00396     XRCCTRL(*this, "pano_text_remapped_images", wxStaticText)->Show(opt.outputLDRLayers || opt.outputLDRExposureRemapped || opt.outputHDRLayers || m_guiLevel>GUI_SIMPLE);
00397     XRCCTRL(*this, "pano_cb_ldr_output_layers", wxCheckBox)->SetValue(opt.outputLDRLayers);
00398     XRCCTRL(*this, "pano_cb_ldr_output_layers", wxCheckBox)->Show(opt.outputLDRLayers || m_guiLevel>GUI_SIMPLE);
00399     XRCCTRL(*this, "pano_cb_ldr_output_exposure_remapped", wxCheckBox)->SetValue(opt.outputLDRExposureRemapped);
00400     XRCCTRL(*this, "pano_cb_ldr_output_exposure_remapped", wxCheckBox)->Show(opt.outputLDRExposureRemapped || m_guiLevel>GUI_SIMPLE);
00401     XRCCTRL(*this, "pano_cb_hdr_output_layers", wxCheckBox)->SetValue(opt.outputHDRLayers);
00402     XRCCTRL(*this, "pano_cb_hdr_output_layers", wxCheckBox)->Show(opt.outputHDRLayers || m_guiLevel>GUI_SIMPLE);
00403 
00404     //stacks
00405     XRCCTRL(*this, "pano_text_stacks", wxStaticText)->Show(opt.outputHDRStacks || opt.outputLDRStacks || m_guiLevel>GUI_SIMPLE);
00406     XRCCTRL(*this, "pano_cb_ldr_output_stacks", wxCheckBox)->SetValue(opt.outputLDRStacks);
00407     XRCCTRL(*this, "pano_cb_ldr_output_stacks", wxCheckBox)->Show(opt.outputLDRStacks || m_guiLevel>GUI_SIMPLE);
00408     XRCCTRL(*this, "pano_cb_hdr_output_stacks", wxCheckBox)->SetValue(opt.outputHDRStacks);
00409     XRCCTRL(*this, "pano_cb_hdr_output_stacks", wxCheckBox)->Show(opt.outputHDRStacks || m_guiLevel>GUI_SIMPLE);
00410 
00411     //layers
00412     XRCCTRL(*this, "pano_text_layers", wxStaticText)->Show(opt.outputLDRExposureLayers || m_guiLevel>GUI_SIMPLE);
00413     XRCCTRL(*this, "pano_cb_ldr_output_exposure_layers", wxCheckBox)->SetValue(opt.outputLDRExposureLayers);
00414     XRCCTRL(*this, "pano_cb_ldr_output_exposure_layers", wxCheckBox)->Show(opt.outputLDRExposureLayers || m_guiLevel>GUI_SIMPLE);
00415 
00416     bool anyOutputSelected = (opt.outputLDRBlended || 
00417                               opt.outputLDRLayers || 
00418                               opt.outputLDRExposureLayers || 
00419                               opt.outputLDRExposureBlended || 
00420                               opt.outputLDRExposureLayersFused || 
00421                               opt.outputLDRExposureRemapped || 
00422                               opt.outputLDRStacks ||
00423                               opt.outputHDRBlended || 
00424                               opt.outputHDRStacks || 
00425                               opt.outputHDRLayers);
00426     
00427     //do not let the user stitch unless there are active images and an output selected.
00428     bool any_output_possible = hasImages && anyOutputSelected;
00429     m_StitchButton->Enable(any_output_possible);
00430 
00431 #ifdef STACK_CHECK //Disabled for 0.7.0 release
00432     if (hasStacks) {
00433         XRCCTRL(*this,"pano_cb_ldr_output_blended",wxCheckBox)->Disable();
00434         XRCCTRL(*this,"pano_cb_ldr_output_layers",wxCheckBox)->Disable();
00435 
00436         XRCCTRL(*this,"pano_cb_ldr_output_exposure_layers",wxCheckBox)->Enable();
00437         XRCCTRL(*this,"pano_cb_ldr_output_exposure_blended",wxCheckBox)->Enable();
00438         XRCCTRL(*this,"pano_cb_ldr_output_exposure_remapped",wxCheckBox)->Enable();
00439         XRCCTRL(*this,"pano_cb_hdr_output_blended",wxCheckBox)->Enable();
00440         XRCCTRL(*this,"pano_cb_hdr_output_stacks",wxCheckBox)->Enable();
00441         XRCCTRL(*this,"pano_cb_hdr_output_layers",wxCheckBox)->Enable();
00442 
00443     } else {
00444         XRCCTRL(*this,"pano_cb_ldr_output_blended",wxCheckBox)->Enable();
00445         XRCCTRL(*this,"pano_cb_ldr_output_layers",wxCheckBox)->Enable();
00446 
00447         XRCCTRL(*this,"pano_cb_ldr_output_exposure_layers",wxCheckBox)->Disable();
00448         XRCCTRL(*this,"pano_cb_ldr_output_exposure_blended",wxCheckBox)->Disable();
00449         XRCCTRL(*this,"pano_cb_ldr_output_exposure_remapped",wxCheckBox)->Disable();
00450 
00451         XRCCTRL(*this,"pano_cb_hdr_output_blended",wxCheckBox)->Disable();
00452         XRCCTRL(*this,"pano_cb_hdr_output_stacks",wxCheckBox)->Disable();
00453         XRCCTRL(*this,"pano_cb_hdr_output_layers",wxCheckBox)->Disable();
00454     }
00455 #endif
00456 
00457     m_RemapperChoice->Show(m_guiLevel>GUI_SIMPLE);
00458     m_RemapperChoice->Enable(m_guiLevel>GUI_SIMPLE);
00459     XRCCTRL(*this, "pano_button_remapper_opts", wxButton)->Show(m_guiLevel>GUI_SIMPLE);
00460     XRCCTRL(*this, "pano_button_remapper_opts", wxButton)->Enable(m_guiLevel>GUI_SIMPLE);
00461     XRCCTRL(*this, "pano_text_remapper", wxStaticText)->Show(m_guiLevel>GUI_SIMPLE);
00462     XRCCTRL(*this, "pano_text_processing", wxStaticText)->Show(m_guiLevel>GUI_SIMPLE);
00463 
00464     bool blenderEnabled = (opt.outputLDRBlended || 
00465                           opt.outputLDRExposureBlended || 
00466                           opt.outputLDRExposureLayersFused || 
00467                           opt.outputLDRExposureLayers || 
00468                           opt.outputHDRBlended ) && m_guiLevel>GUI_SIMPLE;
00469 
00470     m_BlenderChoice->Enable(blenderEnabled);
00471     m_BlenderChoice->Show(m_guiLevel>GUI_SIMPLE);
00472     // select correct blending mechanism
00473     SelectListValue(m_BlenderChoice, opt.blendMode);
00474     XRCCTRL(*this, "pano_button_blender_opts", wxButton)->Enable(blenderEnabled);
00475     XRCCTRL(*this, "pano_button_blender_opts", wxButton)->Show(m_guiLevel>GUI_SIMPLE);
00476     XRCCTRL(*this, "pano_text_blender", wxStaticText)->Enable(blenderEnabled);
00477     XRCCTRL(*this, "pano_text_blender", wxStaticText)->Show(m_guiLevel>GUI_SIMPLE);
00478 
00479     bool fusionEnabled = (opt.outputLDRExposureBlended || opt.outputLDRExposureLayersFused || opt.outputLDRStacks) && m_guiLevel>GUI_SIMPLE;
00480     m_FusionChoice->Enable(fusionEnabled);
00481     m_FusionChoice->Show(m_guiLevel>GUI_SIMPLE);
00482     XRCCTRL(*this, "pano_button_fusion_opts", wxButton)->Enable(fusionEnabled);
00483     XRCCTRL(*this, "pano_button_fusion_opts", wxButton)->Show(m_guiLevel>GUI_SIMPLE);
00484     XRCCTRL(*this, "pano_text_fusion", wxStaticText)->Enable(fusionEnabled);
00485     XRCCTRL(*this, "pano_text_fusion", wxStaticText)->Show(m_guiLevel>GUI_SIMPLE);
00486 
00487     bool hdrMergeEnabled = (opt.outputHDRBlended || opt.outputHDRStacks) && m_guiLevel>GUI_SIMPLE;
00488     m_HDRMergeChoice->Enable(hdrMergeEnabled);
00489     m_HDRMergeChoice->Show(m_guiLevel>GUI_SIMPLE);
00490     XRCCTRL(*this, "pano_button_hdrmerge_opts", wxButton)->Enable(hdrMergeEnabled);
00491     XRCCTRL(*this, "pano_button_hdrmerge_opts", wxButton)->Show(m_guiLevel>GUI_SIMPLE);
00492     XRCCTRL(*this, "pano_text_hdrmerge", wxStaticText)->Enable(hdrMergeEnabled);
00493     XRCCTRL(*this, "pano_text_hdrmerge", wxStaticText)->Show(m_guiLevel>GUI_SIMPLE);
00494 
00495     // output file mode
00496     bool ldr_pano_enabled = opt.outputLDRBlended ||
00497                             opt.outputLDRExposureBlended ||
00498                             opt.outputLDRExposureLayersFused;
00499     
00500     XRCCTRL(*this, "pano_output_ldr_format_label", wxStaticText)->Enable(ldr_pano_enabled);
00501     m_FileFormatOptionsLabel->Enable(ldr_pano_enabled);
00502     m_FileFormatChoice->Enable(ldr_pano_enabled);
00503     m_FileFormatJPEGQualityText->Enable(ldr_pano_enabled);
00504     m_FileFormatTIFFCompChoice->Enable(ldr_pano_enabled);
00505     
00506     long i=0;
00507     if (opt.outputImageType == "tif") {
00508         i = 0;
00509         m_FileFormatOptionsLabel->Show();
00510         m_FileFormatOptionsLabel->SetLabel(_("Compression:"));
00511         m_FileFormatJPEGQualityText->Hide();
00512         m_FileFormatTIFFCompChoice->Show();
00513         if (opt.outputImageTypeCompression  == "PACKBITS") {
00514             m_FileFormatTIFFCompChoice->SetSelection(1);
00515         } else if (opt.outputImageTypeCompression == "LZW") {
00516             m_FileFormatTIFFCompChoice->SetSelection(2);
00517         } else if (opt.outputImageTypeCompression  == "DEFLATE") {
00518             m_FileFormatTIFFCompChoice->SetSelection(3);
00519         } else {
00520             m_FileFormatTIFFCompChoice->SetSelection(0);
00521         }
00522     } else if (opt.outputImageType == "jpg") {
00523         i = 1;
00524         m_FileFormatOptionsLabel->Show();
00525         m_FileFormatOptionsLabel->SetLabel(_("Quality:"));
00526         m_FileFormatJPEGQualityText->Show();
00527         m_FileFormatTIFFCompChoice->Hide();
00528         m_FileFormatJPEGQualityText->ChangeValue(wxString::Format(wxT("%d"), opt.quality));
00529     } else if (opt.outputImageType == "png") {
00530         m_FileFormatOptionsLabel->Hide();
00531         m_FileFormatJPEGQualityText->Hide();
00532         m_FileFormatTIFFCompChoice->Hide();
00533         i = 2;
00534     } else if (opt.outputImageType == "exr") {
00536         m_FileFormatOptionsLabel->Hide();
00537         m_FileFormatJPEGQualityText->Hide();
00538         m_FileFormatTIFFCompChoice->Hide();
00539         i = 3;
00540     } else
00541         wxLogError(wxT("INTERNAL error: unknown output image type"));
00542 
00543     m_FileFormatChoice->SetSelection(i);
00544 
00545     bool hdr_pano_enabled = opt.outputHDRBlended;
00546     
00547     XRCCTRL(*this, "pano_output_hdr_format_label", wxStaticText)->Enable(hdr_pano_enabled);
00548     XRCCTRL(*this, "pano_output_hdr_format_label", wxStaticText)->Show(hdr_pano_enabled || m_guiLevel>GUI_SIMPLE);
00549     m_HDRFileFormatChoice->Enable(hdr_pano_enabled);
00550     m_HDRFileFormatChoice->Show(hdr_pano_enabled || m_guiLevel>GUI_SIMPLE);
00551     m_HDRFileFormatLabelTIFFCompression->Enable(hdr_pano_enabled);
00552     m_HDRFileFormatLabelTIFFCompression->Show(hdr_pano_enabled || m_guiLevel>GUI_SIMPLE);
00553     m_FileFormatHDRTIFFCompChoice->Enable(hdr_pano_enabled);
00554     m_FileFormatHDRTIFFCompChoice->Show(hdr_pano_enabled || m_guiLevel>GUI_SIMPLE);
00555     
00556     i=0;
00557     if (opt.outputImageTypeHDR == "exr") {
00558         i = 0;
00559         m_HDRFileFormatLabelTIFFCompression->Hide();
00560         m_FileFormatHDRTIFFCompChoice->Hide();
00561     } else if (opt.outputImageTypeHDR == "tif") {
00562         i = 1;
00563         m_HDRFileFormatLabelTIFFCompression->Show();
00564         m_FileFormatHDRTIFFCompChoice->Show();
00565         if (opt.outputImageTypeHDRCompression  == "PACKBITS") {
00566             m_FileFormatHDRTIFFCompChoice->SetSelection(1);
00567         } else if (opt.outputImageTypeHDRCompression == "LZW") {
00568             m_FileFormatHDRTIFFCompChoice->SetSelection(2);
00569         } else if (opt.outputImageTypeHDRCompression  == "DEFLATE") {
00570             m_FileFormatHDRTIFFCompChoice->SetSelection(3);
00571         } else {
00572             m_FileFormatHDRTIFFCompChoice->SetSelection(0);
00573         }
00574     } else
00575         wxLogError(wxT("INTERNAL error: unknown hdr output image type"));
00576 
00577     m_HDRFileFormatChoice->SetSelection(i);
00578 
00579     m_pano_ctrls->FitInside();
00580     Layout();
00581     Thaw();
00582 
00583 #ifdef __WXMSW__
00584     this->Refresh(false);
00585 #endif
00586 }
00587 
00588 void PanoPanel::ProjectionChanged ( wxCommandEvent & e )
00589 {
00590     if (updatesDisabled) return;
00591     HuginBase::PanoramaOptions opt = pano->getOptions();
00592 //    PanoramaOptions::ProjectionFormat oldP = opt.getProjection();
00593 
00594     HuginBase::PanoramaOptions::ProjectionFormat newP = (HuginBase::PanoramaOptions::ProjectionFormat) m_ProjectionChoice->GetSelection();
00595 //    int w = opt.getWidth();
00596 //    int h = opt.getHeight();
00597     opt.setProjection(newP);
00598 
00599     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00600         new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00601         );
00602     DEBUG_DEBUG ("Projection changed: "  << newP)
00603 }
00604 
00605 void PanoPanel::HFOVChanged ( wxCommandEvent & e )
00606 {
00607     if (updatesDisabled) return;
00608     HuginBase::PanoramaOptions opt = pano->getOptions();
00609 
00610 
00611     wxString text = m_HFOVText->GetValue();
00612     DEBUG_INFO ("HFOV = " << text.mb_str(wxConvLocal) );
00613     if (text == wxT("")) {
00614         return;
00615     }
00616 
00617     double hfov;
00618     if (!hugin_utils::str2double(text, hfov)) {
00619         wxLogError(_("Value must be numeric."));
00620         return;
00621     }
00622 
00623     if ( hfov <=0 || hfov > opt.getMaxHFOV()) {
00624         wxLogError(wxString::Format(
00625             _("Invalid HFOV value. Maximum HFOV for this projection is %lf."),
00626             opt.getMaxHFOV()));
00627     }
00628     opt.setHFOV(hfov);
00629     // recalculate panorama height...
00630     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00631         new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00632         );
00633 
00634     DEBUG_INFO ( "new hfov: " << hfov )
00635 }
00636 
00637 void PanoPanel::VFOVChanged ( wxCommandEvent & e )
00638 {
00639     if (updatesDisabled) return;
00640     HuginBase::PanoramaOptions opt = pano->getOptions();
00641 
00642     wxString text = m_VFOVText->GetValue();
00643     DEBUG_INFO ("VFOV = " << text.mb_str(wxConvLocal) );
00644     if (text == wxT("")) {
00645         return;
00646     }
00647 
00648     double vfov;
00649     if (!hugin_utils::str2double(text, vfov)) {
00650         wxLogError(_("Value must be numeric."));
00651         return;
00652     }
00653 
00654     if ( vfov <=0 || vfov > opt.getMaxVFOV()) {
00655         wxLogError(wxString::Format(
00656             _("Invalid VFOV value. Maximum VFOV for this projection is %lf."),
00657             opt.getMaxVFOV()));
00658         vfov = opt.getMaxVFOV();
00659     }
00660     opt.setVFOV(vfov);
00661     // recalculate panorama height...
00662     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00663         new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00664         );
00665 
00666     DEBUG_INFO ( "new vfov: " << vfov )
00667 }
00668 
00669 /*
00670 void PanoPanel::VFOVChanged ( wxCommandEvent & e )
00671 {
00672     DEBUG_TRACE("")
00673     if (updatesDisabled) return;
00674     PanoramaOptions opt = pano->getOptions();
00675     int vfov = m_VFOVSpin->GetValue() ;
00676 
00677     if (vfov != opt.getVFOV()) {
00678         opt.setVFOV(vfov);
00679         GlobalCmdHist::getInstance().addCommand(
00680             new PanoCommand::SetPanoOptionsCmd( pano, opt )
00681             );
00682         DEBUG_INFO ( "new vfov: " << vfov << " => height: " << opt.getHeight() );
00683     } else {
00684         DEBUG_DEBUG("not setting same fov");
00685     }
00686 }
00687 */
00688 
00689 void PanoPanel::WidthChanged ( wxCommandEvent & e )
00690 {
00691     if (updatesDisabled) return;
00692     HuginBase::PanoramaOptions opt = pano->getOptions();
00693     long nWidth;
00694     if (m_WidthTxt->GetValue().ToLong(&nWidth)) {
00695         if (nWidth <= 0) return;
00696         opt.setWidth((unsigned int) nWidth, m_keepViewOnResize);
00697         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00698             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00699             );
00700         DEBUG_INFO(nWidth );
00701     } else {
00702         wxLogError(_("width needs to be an integer bigger than 0"));
00703     }
00704 }
00705 
00706 void PanoPanel::HeightChanged ( wxCommandEvent & e )
00707 {
00708     if (updatesDisabled) return;
00709     HuginBase::PanoramaOptions opt = pano->getOptions();
00710     long nHeight;
00711     if (m_HeightTxt->GetValue().ToLong(&nHeight)) {
00712         if(nHeight <= 0) return;
00713         opt.setHeight((unsigned int) nHeight);
00714         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00715                 new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00716                                                );
00717         DEBUG_INFO(nHeight);
00718     } else {
00719         wxLogError(_("height needs to be an integer bigger than 0"));
00720     }
00721 }
00722 
00723 void PanoPanel::ROIChanged ( wxCommandEvent & e )
00724 {
00725     if (updatesDisabled) return;
00726     HuginBase::PanoramaOptions opt = pano->getOptions();
00727     long left, right, top, bottom;
00728     if (!m_ROITopTxt->GetValue().ToLong(&top)) {
00729         wxLogError(_("Top needs to be an integer bigger than 0"));
00730         return;
00731     }
00732     if (!m_ROILeftTxt->GetValue().ToLong(&left)) {
00733         wxLogError(_("left needs to be an integer bigger than 0"));
00734         return;
00735     }
00736     if (!m_ROIRightTxt->GetValue().ToLong(&right)) {
00737         wxLogError(_("right needs to be an integer bigger than 0"));
00738         return;
00739     }
00740     if (!m_ROIBottomTxt->GetValue().ToLong(&bottom)) {
00741         wxLogError(_("bottom needs to be an integer bigger than 0"));
00742         return;
00743     }
00744     opt.setROI(vigra::Rect2D(left, top, right, bottom));
00745 
00746     // make sure that left is really to the left of right
00747     if(opt.getROI().width()<1) {
00748         wxLogError(_("Left boundary must be smaller than right."));
00749         UpdateDisplay(pano->getOptions(), false);
00750         return;
00751     }
00752     // make sure that top is really higher than bottom
00753     if(opt.getROI().height()<1) {
00754         wxLogError(_("Top boundary must be smaller than bottom."));
00755         UpdateDisplay(pano->getOptions(), false);
00756         return;
00757     }
00758 
00759     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00760             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00761                                            );
00762 }
00763 
00764 
00765 void PanoPanel::EnableControls(bool enable)
00766 {
00767 //    m_HFOVSpin->Enable(enable);
00768 //    m_VFOVSpin->Enable(enable);
00769     m_WidthTxt->Enable(enable);
00770     m_RemapperChoice->Enable(enable);
00771     m_BlenderChoice->Enable(enable);
00772 //    m_CalcHFOVButton->Enable(enable);
00773 //    m_CalcOptWidthButton->Enable(enable);
00774 //    m_CalcOptROIButton->Enable(enable);
00775 }
00776 
00777 void PanoPanel::RemapperChanged(wxCommandEvent & e)
00778 {
00779     int remapper = m_RemapperChoice->GetSelection();
00780     DEBUG_DEBUG("changing remapper to " << remapper);
00781 
00782     HuginBase::PanoramaOptions opt = pano->getOptions();
00783     if (remapper == 1) {
00784         opt.remapper = HuginBase::PanoramaOptions::PTMENDER;
00785     } else {
00786         opt.remapper = HuginBase::PanoramaOptions::NONA;
00787     }
00788 
00789     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00790             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00791             );
00792 }
00793 
00794 void PanoPanel::OnRemapperOptions(wxCommandEvent & e)
00795 {
00796     HuginBase::PanoramaOptions opt = pano->getOptions();
00797     if (opt.remapper == HuginBase::PanoramaOptions::NONA) {
00798         wxDialog dlg;
00799         wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("nona_options_dialog"));
00800         wxChoice * interpol_choice = XRCCTRL(dlg, "nona_choice_interpolator", wxChoice);
00801         wxCheckBox * cropped_cb = XRCCTRL(dlg, "nona_save_cropped", wxCheckBox);
00802         interpol_choice->SetSelection(opt.interpolator);
00803         cropped_cb->SetValue(opt.tiff_saveROI);
00804         dlg.CentreOnParent();
00805 
00806         if (dlg.ShowModal() == wxID_OK) {
00807             int interpol = interpol_choice->GetSelection();
00808             if (interpol >= 0) {
00809                 opt.interpolator = (vigra_ext::Interpolator) interpol;
00810             }
00811             opt.tiff_saveROI = cropped_cb->GetValue();
00812             PanoCommand::GlobalCmdHist::getInstance().addCommand(
00813                 new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00814                 );
00815         }
00816     } else {
00817         wxLogError(_(" PTmender options not yet implemented"));
00818     }
00819 }
00820 
00821 void PanoPanel::BlenderChanged(wxCommandEvent & e)
00822 {
00823     HuginBase::PanoramaOptions opt = pano->getOptions();
00824     opt.blendMode = static_cast<HuginBase::PanoramaOptions::BlendingMechanism>(GetSelectedValue(m_BlenderChoice));
00825 
00826     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00827             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00828             );
00829 }
00830 
00831 void PanoPanel::OnBlenderOptions(wxCommandEvent & e)
00832 {
00833     HuginBase::PanoramaOptions opt = pano->getOptions();
00834     if (opt.blendMode == HuginBase::PanoramaOptions::ENBLEND_BLEND) {
00835         wxDialog dlg;
00836         wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("enblend_options_dialog"));
00837         wxTextCtrl * enblend_opts_text = XRCCTRL(dlg, "blender_arguments_text", wxTextCtrl);
00838         enblend_opts_text->ChangeValue(wxString(opt.enblendOptions.c_str(), wxConvLocal));
00839         dlg.Bind(wxEVT_COMMAND_BUTTON_CLICKED, [](wxCommandEvent &) {MainFrame::Get()->DisplayHelp(wxT("Enblend.html")); }, wxID_HELP);
00840         dlg.CentreOnParent();
00841 
00842         if (dlg.ShowModal() == wxID_OK) {
00843             if (enblend_opts_text->GetValue().length() > 0) {
00844                 opt.enblendOptions = enblend_opts_text->GetValue().mb_str(wxConvLocal);
00845             }
00846             else
00847             {
00848                 opt.enblendOptions = wxConfigBase::Get()->Read(wxT("Enblend/Args"),wxT(HUGIN_ENBLEND_ARGS)).mb_str(wxConvLocal);
00849             };
00850             PanoCommand::GlobalCmdHist::getInstance().addCommand(
00851                 new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00852                 );
00853         }
00854     } 
00855     else
00856     {
00857         if (opt.blendMode == HuginBase::PanoramaOptions::INTERNAL_BLEND)
00858         {
00859             wxDialog dlg;
00860             wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("verdandi_options_dialog"));
00861             wxChoice * verdandiBlendModeChoice = XRCCTRL(dlg, "verdandi_blend_mode_choice", wxChoice);
00862             if (opt.verdandiOptions.find("--seam=blend")!=std::string::npos)
00863             {
00864                 verdandiBlendModeChoice->SetSelection(1);
00865             }
00866             else
00867             {
00868                 verdandiBlendModeChoice->SetSelection(0);
00869             };
00870             dlg.CentreOnParent();
00871 
00872             if (dlg.ShowModal() == wxID_OK)
00873             {
00874                 if (verdandiBlendModeChoice->GetSelection() == 1)
00875                 {
00876                     opt.verdandiOptions = "--seam=blend";
00877                 }
00878                 else
00879                 {
00880                     opt.verdandiOptions = "";
00881                 };
00882                 PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::SetPanoOptionsCmd(*pano, opt));
00883             };
00884         }
00885         else
00886         {
00887             wxLogError(_(" PTblender options not yet implemented"));
00888         };
00889     };
00890 }
00891 
00892 void PanoPanel::FusionChanged(wxCommandEvent & e)
00893 {
00894     int fusion = m_FusionChoice->GetSelection();
00895     DEBUG_DEBUG("changing stacking program to " << fusion);
00896 }
00897 
00898 void PanoPanel::OnFusionOptions(wxCommandEvent & e)
00899 {
00900     HuginBase::PanoramaOptions opt = pano->getOptions();
00901     wxDialog dlg;
00902     wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("enfuse_options_dialog"));
00903     wxTextCtrl * enfuse_opts_text = XRCCTRL(dlg, "enfuse_arguments_text", wxTextCtrl);
00904     enfuse_opts_text->ChangeValue(wxString(opt.enfuseOptions.c_str(), wxConvLocal));
00905     dlg.Bind(wxEVT_COMMAND_BUTTON_CLICKED, [](wxCommandEvent &) {MainFrame::Get()->DisplayHelp(wxT("Enfuse.html")); }, wxID_HELP);
00906     dlg.CentreOnParent();
00907 
00908     if (dlg.ShowModal() == wxID_OK) {
00909         if (enfuse_opts_text->GetValue().length() > 0) {
00910             opt.enfuseOptions = enfuse_opts_text->GetValue().mb_str(wxConvLocal);
00911         }
00912         else
00913         {
00914             opt.enfuseOptions = wxConfigBase::Get()->Read(wxT("Enfuse/Args"),wxT(HUGIN_ENFUSE_ARGS)).mb_str(wxConvLocal);
00915         };
00916         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00917             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00918             );
00919     }
00920 }
00921 
00922 
00923 void PanoPanel::HDRMergeChanged(wxCommandEvent & e)
00924 {
00925     int blender = m_HDRMergeChoice->GetSelection();
00926     DEBUG_DEBUG("changing HDR merger to " << blender);
00927 }
00928 
00929 void PanoPanel::OnHDRMergeOptions(wxCommandEvent & e)
00930 {
00931     HuginBase::PanoramaOptions opt = pano->getOptions();
00932     if (opt.hdrMergeMode == HuginBase::PanoramaOptions::HDRMERGE_AVERAGE) {
00933         HDRMergeOptionsDialog dlg(this);
00934         dlg.SetCommandLineArgument(wxString(opt.hdrmergeOptions.c_str(), wxConvLocal));
00935         if (dlg.ShowModal() == wxOK) 
00936         {
00937             opt.hdrmergeOptions=dlg.GetCommandLineArgument().mb_str(wxConvLocal);
00938             PanoCommand::GlobalCmdHist::getInstance().addCommand(
00939                 new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00940                 );
00941         }
00942     } else {
00943         wxLogError(_(" Options for this HDRMerge program not yet implemented"));
00944     }
00945 }
00946 
00947 
00948 
00949 void PanoPanel::DoCalcFOV(wxCommandEvent & e)
00950 {
00951     DEBUG_TRACE("");
00952     if (pano->getActiveImages().size() == 0) return;
00953 
00954     HuginBase::PanoramaOptions opt = pano->getOptions();
00955     HuginBase::CalculateFitPanorama fitPano(*pano);
00956     fitPano.run();
00957     opt.setHFOV(fitPano.getResultHorizontalFOV());
00958     opt.setHeight(hugin_utils::roundi(fitPano.getResultHeight()));
00959 
00960     DEBUG_INFO ( "hfov: " << opt.getHFOV() << "  w: " << opt.getWidth() << " h: " << opt.getHeight() << "  => vfov: " << opt.getVFOV()  << "  before update");
00961 
00962     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00963         new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00964         );
00965 
00966     HuginBase::PanoramaOptions opt2 = pano->getOptions();
00967     DEBUG_INFO ( "hfov: " << opt2.getHFOV() << "  w: " << opt2.getWidth() << " h: " << opt2.getHeight() << "  => vfov: " << opt2.getVFOV()  << "  after update");
00968 
00969 }
00970 
00971 void PanoPanel::DoCalcOptimalWidth(wxCommandEvent & e)
00972 {
00973     if (pano->getActiveImages().size() == 0) return;
00974 
00975     HuginBase::PanoramaOptions opt = pano->getOptions();
00976     double sizeFactor = 1.0;
00977     if (wxGetKeyState(WXK_COMMAND))
00978     {
00979         wxConfigBase::Get()->Read(wxT("/Assistant/panoDownsizeFactor"), &sizeFactor, HUGIN_ASS_PANO_DOWNSIZE_FACTOR);
00980     };
00981 
00982     unsigned width = hugin_utils::roundi(HuginBase::CalculateOptimalScale::calcOptimalScale(*pano) * opt.getWidth() * sizeFactor);
00983 
00984     if (width > 0) {
00985         opt.setWidth( width );
00986         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00987             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00988             );
00989     }
00990     DEBUG_INFO ( "new optimal width: " << opt.getWidth() );
00991 }
00992 
00993 
00994 void PanoPanel::DoCalcOptimalROI(wxCommandEvent & e)
00995 {
00996     DEBUG_INFO("Dirty ROI Calc\n");
00997     if (pano->getActiveImages().size() == 0)
00998     {
00999         return;
01000     };
01001 
01002     vigra::Rect2D newROI;
01003     {
01004         ProgressReporterDialog progress(0, _("Autocrop"), _("Calculating optimal crop"), this);
01005         HuginBase::CalculateOptimalROI cropPano(*pano, &progress);
01006         cropPano.run();
01007         if (cropPano.hasRunSuccessfully())
01008         {
01009             newROI = cropPano.getResultOptimalROI();
01010         };
01011     };
01012 
01013     //set the ROI - fail if the right/bottom is zero, meaning all zero
01014     if(!newROI.isEmpty())
01015     {
01016         HuginBase::PanoramaOptions opt = pano->getOptions();
01017         opt.setROI(newROI);
01018         PanoCommand::GlobalCmdHist::getInstance().addCommand(
01019             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01020             );
01021     };
01022 };
01023 
01024 void PanoPanel::DoStitch()
01025 {
01026     if (pano->getNrOfImages() == 0) {
01027         return;
01028     }
01029     
01030     if (!CheckGoodSize()) {
01031         // oversized pano and the user no longer wants to stitch.
01032         return;
01033     }
01034     if (!CheckHasImages())
01035     {
01036         // output ROI contains no images
01037         return;
01038     };
01039 
01040     // save project
01041     // copy pto file to temporary file
01042     wxString tempDir= wxConfigBase::Get()->Read(wxT("tempDir"),wxT(""));
01043     if(!tempDir.IsEmpty())
01044         if(tempDir.Last()!=wxFileName::GetPathSeparator())
01045             tempDir.Append(wxFileName::GetPathSeparator());
01046     wxString currentPTOfn = wxFileName::CreateTempFileName(tempDir+wxT("huginpto_"));
01047     if(currentPTOfn.size() == 0) {
01048         wxMessageBox(_("Could not create temporary project file"),_("Error"),
01049                 wxCANCEL | wxICON_ERROR,this);
01050         return;
01051     }
01052     DEBUG_DEBUG("tmp PTO file: " << (const char *)currentPTOfn.mb_str(wxConvLocal));
01053     // copy is not enough, need to adjust image path names...
01054     std::ofstream script(currentPTOfn.mb_str(HUGIN_CONV_FILENAME));
01055     HuginBase::UIntSet all;
01056     if (pano->getNrOfImages() > 0) {
01057         fill_set(all, 0, pano->getNrOfImages()-1);
01058     }
01059     pano->printPanoramaScript(script, pano->getOptimizeVector(), pano->getOptions(), all, false, "");
01060     script.close();
01061 
01062 //    wxCommandEvent dummy;
01063 //    MainFrame::Get()->OnSaveProject(dummy);
01064 
01065 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01066     // HuginStitchProject inside main bundle
01067     wxString hugin_stitch_project = MacGetPathToBundledAppMainExecutableFile(CFSTR("HuginStitchProject.app"));
01068     if(hugin_stitch_project == wxT(""))
01069     {
01070         DEBUG_ERROR("hugin_stitch_project could not be found in the bundle.");
01071         return;
01072     }
01073     hugin_stitch_project = hugin_utils::wxQuoteFilename(hugin_stitch_project);
01074 #elif defined __WXMAC__
01075     // HuginStitchProject installed in INSTALL_OSX_BUNDLE_DIR
01076     wxFileName hugin_stitch_project_app(wxT(INSTALL_OSX_BUNDLE_DIR), wxEmptyString);
01077     hugin_stitch_project_app.AppendDir(wxT("HuginStitchProject.app"));
01078     CFStringRef stitchProjectAppPath = MacCreateCFStringWithWxString(hugin_stitch_project_app.GetFullPath());
01079     wxString hugin_stitch_project = MacGetPathToMainExecutableFileOfBundle(stitchProjectAppPath);
01080     CFRelease(stitchProjectAppPath);
01081 #else
01082     wxString hugin_stitch_project = wxT("hugin_stitch_project");
01083 #endif
01084 
01085     // Derive a default output prefix from the project filename if set, otherwise default project filename
01086     wxFileName outputPrefix(getDefaultOutputName(MainFrame::Get()->getProjectName(), *pano));
01087     outputPrefix.Normalize();
01088 
01089     // Show a file save dialog so user can confirm/change the prefix.
01090     // (We don't have to worry about overwriting existing files, since hugin_switch_project checks this.)
01091     // TODO: The following code is similar to stitchApp::OnInit in hugin_switch_project.cpp. Should be refactored.
01092     // TODO: We should save the output prefix somewhere, so we can recall it as the default if the user stitches this project again.
01093     wxFileDialog dlg(this,_("Specify output prefix"),
01094                      outputPrefix.GetPath(), outputPrefix.GetName(), wxT(""),
01095                      wxFD_SAVE, wxDefaultPosition);
01096     if (dlg.ShowModal() != wxID_OK)
01097     {
01098         return;
01099     };
01100     while(containsInvalidCharacters(dlg.GetPath()))
01101     {
01102         wxArrayString list;
01103         list.Add(dlg.GetPath());
01104         ShowFilenameWarning(this, list);
01105         if(dlg.ShowModal()!=wxID_OK)
01106             return;
01107     };
01108     wxFileName prefix(dlg.GetPath());
01109     while (!prefix.IsDirWritable())
01110     {
01111         wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
01112 #ifdef __WXMSW__
01113             wxT("Hugin"),
01114 #else
01115             wxT(""),
01116 #endif
01117             wxOK | wxICON_INFORMATION);
01118         if (dlg.ShowModal() != wxID_OK)
01119         {
01120             return;
01121         };
01122         prefix = dlg.GetPath();
01123     };
01124     // check free space
01125     if (!CheckFreeSpace(prefix.GetPath()))
01126     {
01127         return;
01128     };
01129 
01130     wxString switches(wxT(" --delete -o "));
01131     if(wxConfigBase::Get()->Read(wxT("/Processor/overwrite"), HUGIN_PROCESSOR_OVERWRITE) == 1)
01132         switches=wxT(" --overwrite")+switches;
01133     wxString command = hugin_stitch_project + switches + hugin_utils::wxQuoteFilename(dlg.GetPath()) + wxT(" ") + hugin_utils::wxQuoteFilename(currentPTOfn);
01134     
01135     wxConfigBase::Get()->Flush();
01136 #ifdef __WXGTK__
01137     // work around a wxExecute bug/problem
01138     // (endless polling of fd 0 and 1 in hugin_stitch_project)
01139     wxProcess *my_process = new wxProcess(this);
01140     my_process->Redirect();
01141 
01142     // Delete itself once processes terminated.
01143     my_process->Detach();
01144     wxExecute(command,wxEXEC_ASYNC, my_process);
01145 #else
01146     wxExecute(command);
01147 #endif
01148     HuginBase::LensDB::SaveLensDataFromPano(*pano);
01149 }
01150 
01151 void PanoPanel::DoSendToBatch()
01152 {
01153     if (pano->getNrOfImages() == 0)
01154     {
01155         return;
01156     }
01157     
01158     if (!CheckGoodSize())
01159     {
01160         // oversized pano and the user no longer wants to stitch.
01161         return;
01162     }
01163     if( !CheckHasImages())
01164     {
01165         // output ROI contains no images
01166         return;
01167     };
01168 
01169     wxString switches(wxT(" "));
01170     if (wxConfigBase::Get()->Read(wxT("/Processor/start"), HUGIN_PROCESSOR_START) != 0)
01171     {
01172         switches += wxT("-b ");
01173     }
01174     if (wxConfigBase::Get()->Read(wxT("/Processor/overwrite"), HUGIN_PROCESSOR_OVERWRITE) != 0)
01175     {
01176         switches += wxT("-o ");
01177     }
01178     if (wxConfigBase::Get()->Read(wxT("/Processor/verbose"), HUGIN_PROCESSOR_VERBOSE) != 0)
01179     {
01180         switches += wxT("-v ");
01181     }
01182     if(pano->isDirty())
01183     {
01184         bool showDlg=wxConfigBase::Get()->Read(wxT("ShowSaveMessage"), 1l)==1;
01185         if(showDlg)
01186         {
01187             wxDialog dlg;
01188             wxXmlResource::Get()->LoadDialog(&dlg, NULL, wxT("stitch_message_dlg"));
01189             if(dlg.ShowModal())
01190             {
01191                 if(XRCCTRL(dlg, "stitch_dont_show_checkbox", wxCheckBox)->IsChecked())
01192                 {
01193                     wxConfigBase::Get()->Write(wxT("ShowSaveMessage"), 0l);
01194                 };
01195             };
01196         };
01197         wxCommandEvent dummy;
01198         MainFrame::Get()->OnSaveProject(dummy);
01199         //test if save was sucessful
01200         if(pano->isDirty())
01201         {
01202             return;
01203         };
01204     };
01205     wxString projectFile = MainFrame::Get()->getProjectName();
01206     if(wxFileName::FileExists(projectFile))
01207     {
01208         wxFileName outputPrefix(getDefaultOutputName(projectFile, *pano));
01209         outputPrefix.Normalize();
01210 
01211         // Show a file save dialog so user can confirm/change the prefix.
01212         // (We don't have to worry about overwriting existing files, since PTBatcherGUI checks this, or the overwrite flag was set.)
01213         wxFileDialog dlg(this,_("Specify output prefix"),
01214                          outputPrefix.GetPath(), outputPrefix.GetName(), wxT(""),
01215                          wxFD_SAVE, wxDefaultPosition);
01216         if (dlg.ShowModal() != wxID_OK)
01217         {
01218             return;
01219         };
01220         while(containsInvalidCharacters(dlg.GetPath()))
01221         {
01222             wxArrayString list;
01223             list.Add(dlg.GetPath());
01224             ShowFilenameWarning(this, list);
01225             if(dlg.ShowModal()!=wxID_OK)
01226                 return;
01227         };
01228         wxFileName prefix(dlg.GetPath());
01229         while (!prefix.IsDirWritable())
01230         {
01231             wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
01232 #ifdef __WXMSW__
01233                 wxT("Hugin"),
01234 #else
01235                 wxT(""),
01236 #endif
01237                 wxOK | wxICON_INFORMATION);
01238             if (dlg.ShowModal() != wxID_OK)
01239             {
01240                 return;
01241             };
01242             prefix = dlg.GetPath();
01243         };
01244         // check free space
01245         if (!CheckFreeSpace(prefix.GetPath()))
01246         {
01247             return;
01248         };
01249 
01250 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01251                 wxString cmd = MacGetPathToMainExecutableFileOfRegisteredBundle(CFSTR("net.sourceforge.hugin.PTBatcherGUI"));
01252                 if(cmd != wxT(""))
01253                 { 
01254                         //Found PTBatcherGui inside the (registered) PTBatcherGui bundle. Call it directly.
01255                         //We need to call the binary from it's own bundle and not from the hugin bundle otherwise we get no menu as OSX assumes that the hugin bundle
01256                         //will provide the menu
01257                         cmd = hugin_utils::wxQuoteString(cmd); 
01258             cmd += wxT(" ") + switches + hugin_utils::wxQuoteFilename(projectFile) + wxT(" ") + hugin_utils::wxQuoteFilename(dlg.GetPath());
01259                         wxExecute(cmd);
01260                 }
01261                 else
01262                 { //Can't find PTBatcherGui.app bundle. Use the most straightforward call possible to the bundle but this should actually not work either.
01263                                 wxMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), wxT("open")), _("Error"));
01264                 cmd = wxT("open -b net.sourceforge.hugin.PTBatcherGUI ")+hugin_utils::wxQuoteFilename(projectFile);
01265                                 wxExecute(cmd);
01266                 }
01267                 
01268 #else
01269         const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
01270         wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxT("PTBatcherGUI ") + switches + hugin_utils::wxQuoteFilename(projectFile) + wxT(" ") + hugin_utils::wxQuoteFilename(dlg.GetPath()));
01271 #endif
01272         HuginBase::LensDB::SaveLensDataFromPano(*pano);
01273     }
01274 };
01275 
01276 void PanoPanel::DoUserDefinedStitch(const wxString& settings)
01277 {
01278     if (pano->getNrOfImages() == 0)
01279     {
01280         return;
01281     }
01282 
01283     if (!CheckGoodSize())
01284     {
01285         // oversized pano and the user no longer wants to stitch.
01286         return;
01287     }
01288     if (!CheckHasImages())
01289     {
01290         // output ROI contains no images
01291         return;
01292     };
01293     wxFileName userOutputSequence;
01294     if (settings.IsEmpty())
01295     {
01296         // no filename given, ask user
01297         wxConfigBase* config = wxConfigBase::Get();
01298         wxString path = config->Read(wxT("/userDefinedOutputPath"), MainFrame::Get()->GetDataPath());
01299         wxFileDialog userOutputDlg(this, _("Select user defined output"),
01300             path, wxT(""), _("User defined output|*.executor"),
01301             wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST, wxDefaultPosition);
01302         if (userOutputDlg.ShowModal() != wxID_OK)
01303         {
01304             return;
01305         };
01306         // remember path for later
01307         config->Write(wxT("/userDefinedOutputPath"), userOutputDlg.GetDirectory());
01308         userOutputSequence = userOutputDlg.GetPath();
01309     }
01310     else
01311     {
01312         //filename given, check existance
01313         userOutputSequence = settings;
01314         if (!userOutputSequence.Exists())
01315         {
01316             wxMessageBox(wxString::Format(wxT("User defined output %s not found.\nStopping processing."), userOutputSequence.GetFullPath()), _("Warning"), wxOK | wxICON_INFORMATION);
01317             return;
01318         };
01319     };
01320 
01321     // create a copy, if we need to update the crop setting
01322     // save project
01323     // copy pto file to temporary file
01324     wxString tempDir = wxConfigBase::Get()->Read(wxT("tempDir"), wxT(""));
01325     if (!tempDir.IsEmpty())
01326     {
01327         if (tempDir.Last() != wxFileName::GetPathSeparator())
01328         {
01329             tempDir.Append(wxFileName::GetPathSeparator());
01330         }
01331     };
01332     wxString currentPTOfn = wxFileName::CreateTempFileName(tempDir + wxT("huginpto_"));
01333     if (currentPTOfn.size() == 0)
01334     {
01335         wxMessageBox(_("Could not create temporary project file"), _("Error"),
01336             wxCANCEL | wxICON_ERROR, this);
01337         return;
01338     }
01339     DEBUG_DEBUG("tmp PTO file: " << (const char *)currentPTOfn.mb_str(wxConvLocal));
01340     // copy is not enough, need to adjust image path names...
01341     std::ofstream script(currentPTOfn.mb_str(HUGIN_CONV_FILENAME));
01342     HuginBase::UIntSet all;
01343     fill_set(all, 0, pano->getNrOfImages() - 1);
01344     pano->printPanoramaScript(script, pano->getOptimizeVector(), pano->getOptions(), all, false, "");
01345     script.close();
01346 
01347     //    wxCommandEvent dummy;
01348     //    MainFrame::Get()->OnSaveProject(dummy);
01349 
01350 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01351     // HuginStitchProject inside main bundle
01352     wxString hugin_stitch_project = MacGetPathToBundledAppMainExecutableFile(CFSTR("HuginStitchProject.app"));
01353     if (hugin_stitch_project == wxT(""))
01354     {
01355         DEBUG_ERROR("hugin_stitch_project could not be found in the bundle.");
01356         return;
01357     }
01358     hugin_stitch_project = hugin_utils::wxQuoteFilename(hugin_stitch_project);
01359 #elif defined __WXMAC__
01360     // HuginStitchProject installed in INSTALL_OSX_BUNDLE_DIR
01361     wxFileName hugin_stitch_project_app(wxT(INSTALL_OSX_BUNDLE_DIR), wxEmptyString);
01362     hugin_stitch_project_app.AppendDir(wxT("HuginStitchProject.app"));
01363     CFStringRef stitchProjectAppPath = MacCreateCFStringWithWxString(hugin_stitch_project_app.GetFullPath());
01364     wxString hugin_stitch_project = MacGetPathToMainExecutableFileOfBundle(stitchProjectAppPath);
01365     CFRelease(stitchProjectAppPath);
01366 #else
01367     wxString hugin_stitch_project = wxT("hugin_stitch_project");
01368 #endif
01369 
01370     // Derive a default output prefix from the project filename if set, otherwise default project filename
01371     wxFileName outputPrefix(getDefaultOutputName(MainFrame::Get()->getProjectName(), *pano));
01372     outputPrefix.Normalize();
01373 
01374     // Show a file save dialog so user can confirm/change the prefix.
01375     // (We don't have to worry about overwriting existing files, since hugin_switch_project checks this.)
01376     // TODO: The following code is similar to stitchApp::OnInit in hugin_switch_project.cpp. Should be refactored.
01377     // TODO: We should save the output prefix somewhere, so we can recall it as the default if the user stitches this project again.
01378     wxFileDialog dlg(this, _("Specify output prefix"),
01379         outputPrefix.GetPath(), outputPrefix.GetName(), wxT(""),
01380         wxFD_SAVE, wxDefaultPosition);
01381     if (dlg.ShowModal() != wxID_OK)
01382     {
01383         return;
01384     };
01385     while (containsInvalidCharacters(dlg.GetPath()))
01386     {
01387         wxArrayString list;
01388         list.Add(dlg.GetPath());
01389         ShowFilenameWarning(this, list);
01390         if (dlg.ShowModal() != wxID_OK)
01391             return;
01392     };
01393     wxFileName prefix(dlg.GetPath());
01394     while (!prefix.IsDirWritable())
01395     {
01396         wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
01397 #ifdef __WXMSW__
01398             wxT("Hugin"),
01399 #else
01400             wxT(""),
01401 #endif
01402             wxOK | wxICON_INFORMATION);
01403         if (dlg.ShowModal() != wxID_OK)
01404         {
01405             return;
01406         };
01407         prefix = dlg.GetPath();
01408     };
01409     // check free space
01410     if (!CheckFreeSpace(prefix.GetPath()))
01411     {
01412         return;
01413     };
01414 
01415     wxString switches(wxT(" --user-defined-output=") + hugin_utils::wxQuoteFilename(userOutputSequence.GetFullPath()) + wxT(" --delete -o "));
01416     if (wxConfigBase::Get()->Read(wxT("/Processor/overwrite"), HUGIN_PROCESSOR_OVERWRITE) == 1)
01417         switches = wxT(" --overwrite") + switches;
01418     wxString command = hugin_stitch_project + switches + hugin_utils::wxQuoteFilename(dlg.GetPath()) + wxT(" ") + hugin_utils::wxQuoteFilename(currentPTOfn);
01419 
01420     wxConfigBase::Get()->Flush();
01421 #ifdef __WXGTK__
01422     // work around a wxExecute bug/problem
01423     // (endless polling of fd 0 and 1 in hugin_stitch_project)
01424     wxProcess *my_process = new wxProcess(this);
01425     my_process->Redirect();
01426 
01427     // Delete itself once processes terminated.
01428     my_process->Detach();
01429     wxExecute(command, wxEXEC_ASYNC, my_process);
01430 #else
01431     wxExecute(command);
01432 #endif
01433 }
01434 
01435 
01436 void PanoPanel::OnDoStitch ( wxCommandEvent & e )
01437 {
01438     long t;
01439     if(wxGetKeyState(WXK_COMMAND))
01440     {
01441         t=1;
01442     }
01443     else
01444     {
01445         wxConfigBase::Get()->Read(wxT("/Processor/gui"),&t,HUGIN_PROCESSOR_GUI);
01446     };
01447     switch (t)
01448     {
01449         // PTBatcher
01450         case 0:
01451             DoSendToBatch();
01452             break;
01453         // hugin_stitch_project
01454         case 1:
01455             DoStitch();
01456             break;
01457         // there is an error in the preferences
01458         default :
01459             // TODO: notify user and fix preferences misconfiguration
01460             break;
01461       }
01462 }
01463 
01464 void PanoPanel::FileFormatChanged(wxCommandEvent & e)
01465 {
01466 
01467     int fmt = m_FileFormatChoice->GetSelection();
01468     DEBUG_DEBUG("changing file format to " << fmt);
01469 
01470     HuginBase::PanoramaOptions opt = pano->getOptions();
01471     switch (fmt) {
01472         case 1:
01473             opt.outputImageType ="jpg";
01474             break;
01475         case 2:
01476             opt.outputImageType ="png";
01477             break;
01478         case 3:
01479             opt.outputImageType ="exr";
01480             break;
01481         default:
01482         case 0:
01483             opt.outputImageType ="tif";
01484             break;
01485     }
01486 
01487     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01488             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01489             );
01490 }
01491 
01492 void PanoPanel::HDRFileFormatChanged(wxCommandEvent & e)
01493 {
01494 
01495     int fmt = m_HDRFileFormatChoice->GetSelection();
01496     DEBUG_DEBUG("changing file format to " << fmt);
01497 
01498     HuginBase::PanoramaOptions opt = pano->getOptions();
01499     switch (fmt) {
01500         case 1:
01501             opt.outputImageTypeHDR ="tif";
01502             break;
01503         default:
01504         case 0:
01505             opt.outputImageTypeHDR ="exr";
01506             break;
01507     }
01508 
01509     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01510             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01511             );
01512 }
01513 
01514 void PanoPanel::OnJPEGQualityText(wxCommandEvent & e)
01515 {
01516     HuginBase::PanoramaOptions opt = pano->getOptions();
01517     long l = 100;
01518     m_FileFormatJPEGQualityText->GetValue().ToLong(&l);
01519     if (l < 0) l=1;
01520     if (l > 100) l=100;
01521     DEBUG_DEBUG("Setting jpeg quality to " << l);
01522     opt.quality = l;
01523     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01524             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01525             );
01526 }
01527 
01528 void PanoPanel::OnNormalTIFFCompression(wxCommandEvent & e)
01529 {
01530     HuginBase::PanoramaOptions opt = pano->getOptions();
01531     switch(e.GetSelection()) {
01532         case 0:
01533         default:
01534             opt.outputImageTypeCompression = "NONE";
01535             opt.tiffCompression = "NONE";
01536             break;
01537         case 1:
01538             opt.outputImageTypeCompression = "PACKBITS";
01539             opt.tiffCompression = "PACKBITS";
01540             break;
01541         case 2:
01542             opt.outputImageTypeCompression = "LZW";
01543             opt.tiffCompression = "LZW";
01544             break;
01545         case 3:
01546             opt.outputImageTypeCompression = "DEFLATE";
01547             opt.tiffCompression = "DEFLATE";
01548             break;
01549     }
01550     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01551             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01552             );
01553 }
01554 
01555 void PanoPanel::OnHDRTIFFCompression(wxCommandEvent & e)
01556 {
01557     HuginBase::PanoramaOptions opt = pano->getOptions();
01558     switch(e.GetSelection()) {
01559         case 0:
01560         default:
01561             opt.outputImageTypeHDRCompression = "NONE";
01562             break;
01563         case 1:
01564             opt.outputImageTypeHDRCompression = "PACKBITS";
01565             break;
01566         case 2:
01567             opt.outputImageTypeHDRCompression = "LZW";
01568             break;
01569         case 3:
01570             opt.outputImageTypeHDRCompression = "DEFLATE";
01571             break;
01572     }
01573     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01574             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01575             );
01576 }
01577 
01578 void PanoPanel::OnOutputFilesChanged(wxCommandEvent & e)
01579 {
01580     int id = e.GetId();
01581     HuginBase::PanoramaOptions opts = pano->getOptions();
01582 
01583     if (id == XRCID("pano_cb_ldr_output_blended") ) {
01584         opts.outputLDRBlended = e.IsChecked();
01585     } else if (id == XRCID("pano_cb_ldr_output_layers") ) {
01586         opts.outputLDRLayers = e.IsChecked();
01587     } else if (id == XRCID("pano_cb_ldr_output_exposure_layers") ) {
01588         opts.outputLDRExposureLayers = e.IsChecked();
01589     } else if (id == XRCID("pano_cb_ldr_output_exposure_blended") ) {
01590         opts.outputLDRExposureBlended = e.IsChecked();
01591     } else if (id == XRCID("pano_cb_ldr_output_exposure_layers_fused") ) {
01592         opts.outputLDRExposureLayersFused = e.IsChecked();
01593     } else if (id == XRCID("pano_cb_ldr_output_exposure_remapped") ) {
01594         opts.outputLDRExposureRemapped = e.IsChecked();
01595     } else if (id == XRCID("pano_cb_ldr_output_stacks") ) {
01596         opts.outputLDRStacks = e.IsChecked();
01597     } else if (id == XRCID("pano_cb_hdr_output_blended") ) {
01598         opts.outputHDRBlended = e.IsChecked();
01599     } else if (id == XRCID("pano_cb_hdr_output_stacks") ) {
01600         opts.outputHDRStacks = e.IsChecked();
01601     } else if (id == XRCID("pano_cb_hdr_output_layers") ) {
01602         opts.outputHDRLayers = e.IsChecked();
01603     }
01604     
01605     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01606             new PanoCommand::SetPanoOptionsCmd( *pano, opts )
01607         );
01608 }
01609 
01610 bool PanoPanel::CheckGoodSize()
01611 {
01612     const HuginBase::PanoramaOptions opts(pano->getOptions());
01613     const vigra::Rect2D cropped_region (opts.getROI());    
01614     // width and height of jpeg images has to be smaller than 65500 pixel
01615     if (opts.outputImageType == "jpg" &&
01616         (opts.outputLDRBlended || opts.outputLDRExposureBlended || opts.outputLDRExposureLayersFused) &&
01617         (cropped_region.width()>65500 || cropped_region.height()>65500)
01618         )
01619     {
01620         wxMessageBox(
01621             wxString::Format(_("The width and height of jpeg images has to be smaller than 65500 pixel. But you have requested a jpeg image with %dx%d pixel.\nThis is not supported by the jpeg file format.\nDecrease the canvas size on the stitch panel or select TIF or PNG as output format."), cropped_region.width(), cropped_region.height()),
01622 #ifdef _WIN32
01623             _("Hugin"),
01624 #else
01625             wxT(""),
01626 #endif
01627             wxICON_EXCLAMATION | wxOK);
01628         return false;
01629     };
01630     wxString message;
01631     unsigned long long int area = ((unsigned long int) cropped_region.width()) * ((unsigned long int) cropped_region.height());
01632     // Argh, more than half a gigapixel!
01633     if (area > 500000000)
01634     {
01635         message = wxString::Format(_("The panorama you are trying to stitch is %.1f gigapixels.\nIf this is too big, reduce the panorama Canvas Size and the cropped region and stitch from the Stitcher tab. Stitching a panorama this size could take a long time and a large amount of memory."),
01636             area / 1000000000.0);
01637     }
01638     else
01639     {
01640         if (cropped_region.width() > 32700 || cropped_region.height() > 32700)
01641         {
01642             message = _("The width or the height of the final panorama exceeds 32700 pixel.\nSome programs have problems to open or display such big images.\n\nIf this is too big, reduce the panorama Canvas Size or the cropped region.");
01643         };
01644     };
01645     if (!message.empty())
01646     {
01647         // Tell the user the stitch will be really big, and give them a
01648         // chance to reduce the size.
01649         wxMessageDialog dialog(this,
01650                 _("Are you sure you want to stitch such a large panorama?"),
01651 #ifdef _WIN32
01652                 _("Hugin"),
01653 #else
01654                 wxT(""),
01655 #endif
01656                 wxICON_EXCLAMATION | wxYES_NO);
01657         dialog.SetExtendedMessage(message);
01658         dialog.SetYesNoLabels(_("Stitch anyway"), _("Let me fix that"));
01659         switch (dialog.ShowModal())
01660         {
01661             case wxID_OK:
01662             case wxID_YES:
01663                 // Continue stitch.
01664                 return true;
01665                 break;
01666             default:
01667                 // bring the user towards the approptiate controls.
01668                 MainFrame* mainframe = MainFrame::Get();
01669                 if (!mainframe->IsShown())
01670                 {
01671                     mainframe->Show();
01672                 }
01673                 mainframe->ShowStitcherTab();
01674                 return false;
01675         }
01676     }
01677     // I see nothing wrong with this...
01678     return true;
01679 }
01680 
01681 bool PanoPanel::CheckHasImages()
01682 {
01683     HuginBase::UIntSet images=getImagesinROI(*pano, pano->getActiveImages());
01684     if(images.size()==0)
01685     {
01686         wxMessageBox(_("There are no active images in the output region.\nPlease check your settings, so that at least one image is in the output region."),
01687 #ifdef _WIN32
01688             _("Hugin"),
01689 #else
01690             wxT(""),
01691 #endif
01692             wxOK | wxICON_INFORMATION);
01693     };
01694     return images.size()>0;
01695 };
01696 
01697 bool PanoPanel::CheckFreeSpace(const wxString& folder)
01698 {
01699     wxLongLong freeSpace;
01700     if (wxGetDiskSpace(folder, NULL, &freeSpace))
01701     {
01702         // 4 channels, 16 bit per channel, assuming the we need the 10 fold space for all temporary space
01703         if (pano->getOptions().getROI().area() * 80 > freeSpace)
01704         {
01705             wxMessageDialog dialog(this,
01706                 wxString::Format(_("The folder \"%s\" has only %.1f MiB free. This is not enough for stitching the current panorama. Decrease the output size or select another output folder.\nAre you sure that you still want to stitch it?"), folder.c_str(), freeSpace / 1048576.0f),
01707 #ifdef _WIN32
01708                 _("Hugin"),
01709 #else
01710                 wxT(""),
01711 #endif
01712                 wxICON_EXCLAMATION | wxYES_NO);
01713             dialog.SetYesNoLabels(_("Stitch anyway"), _("Let me fix that"));
01714             if (dialog.ShowModal() == wxID_NO)
01715             {
01716                 // bring the user towards the approptiate controls.
01717                 MainFrame* mainframe = MainFrame::Get();
01718                 if (!mainframe->IsShown())
01719                 {
01720                     mainframe->Show();
01721                 }
01722                 mainframe->ShowStitcherTab();
01723                 return false;
01724             };
01725         };
01726     };
01727     return true;
01728 };
01729 
01730 void PanoPanel::SetGuiLevel(GuiLevel newGuiLevel)
01731 {
01732     m_guiLevel=newGuiLevel;
01733     UpdateDisplay(m_oldOpt, false);
01734 };
01735 
01736 IMPLEMENT_DYNAMIC_CLASS(PanoPanel, wxPanel)
01737 
01738 PanoPanelXmlHandler::PanoPanelXmlHandler()
01739                 : wxXmlResourceHandler()
01740 {
01741     AddWindowStyles();
01742 }
01743 
01744 wxObject *PanoPanelXmlHandler::DoCreateResource()
01745 {
01746     XRC_MAKE_INSTANCE(cp, PanoPanel)
01747 
01748     cp->Create(m_parentAsWindow,
01749                    GetID(),
01750                    GetPosition(), GetSize(),
01751                    GetStyle(wxT("style")),
01752                    GetName());
01753 
01754     SetupWindow( cp);
01755 
01756     return cp;
01757 }
01758 
01759 bool PanoPanelXmlHandler::CanHandle(wxXmlNode *node)
01760 {
01761     return IsOfClass(node, wxT("PanoPanel"));
01762 }
01763 
01764 IMPLEMENT_DYNAMIC_CLASS(PanoPanelXmlHandler, wxXmlResourceHandler)
01765 

Generated on 24 Apr 2017 for Hugintrunk by  doxygen 1.4.7