PanoPanel.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00028 #include <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->SetValue(wxString(val.c_str(), wxConvLocal));
00370     val = hugin_utils::doubleToString(opt.getVFOV(), 1);
00371     m_VFOVText->SetValue(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->SetValue(wxString::Format(wxT("%d"), opt.getWidth()));
00381     m_HeightTxt->SetValue(wxString::Format(wxT("%d"), opt.getHeight()));
00382 
00383     m_ROILeftTxt->SetValue(wxString::Format(wxT("%d"), opt.getROI().left() ));
00384     m_ROIRightTxt->SetValue(wxString::Format(wxT("%d"), opt.getROI().right() ));
00385     m_ROITopTxt->SetValue(wxString::Format(wxT("%d"), opt.getROI().top() ));
00386     m_ROIBottomTxt->SetValue(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->SetValue(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->SetValue(wxString(opt.enblendOptions.c_str(), wxConvLocal));
00839         dlg.CentreOnParent();
00840 
00841         if (dlg.ShowModal() == wxID_OK) {
00842             if (enblend_opts_text->GetValue().length() > 0) {
00843                 opt.enblendOptions = enblend_opts_text->GetValue().mb_str(wxConvLocal);
00844             }
00845             else
00846             {
00847                 opt.enblendOptions = wxConfigBase::Get()->Read(wxT("Enblend/Args"),wxT(HUGIN_ENBLEND_ARGS)).mb_str(wxConvLocal);
00848             };
00849             PanoCommand::GlobalCmdHist::getInstance().addCommand(
00850                 new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00851                 );
00852         }
00853     } 
00854     else
00855     {
00856         if (opt.blendMode == HuginBase::PanoramaOptions::INTERNAL_BLEND)
00857         {
00858             wxDialog dlg;
00859             wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("verdandi_options_dialog"));
00860             wxChoice * verdandiBlendModeChoice = XRCCTRL(dlg, "verdandi_blend_mode_choice", wxChoice);
00861             if (opt.verdandiOptions.find("--seam=blend")!=std::string::npos)
00862             {
00863                 verdandiBlendModeChoice->SetSelection(1);
00864             }
00865             else
00866             {
00867                 verdandiBlendModeChoice->SetSelection(0);
00868             };
00869             dlg.CentreOnParent();
00870 
00871             if (dlg.ShowModal() == wxID_OK)
00872             {
00873                 if (verdandiBlendModeChoice->GetSelection() == 1)
00874                 {
00875                     opt.verdandiOptions = "--seam=blend";
00876                 }
00877                 else
00878                 {
00879                     opt.verdandiOptions = "";
00880                 };
00881                 PanoCommand::GlobalCmdHist::getInstance().addCommand(new PanoCommand::SetPanoOptionsCmd(*pano, opt));
00882             };
00883         }
00884         else
00885         {
00886             wxLogError(_(" PTblender options not yet implemented"));
00887         };
00888     };
00889 }
00890 
00891 void PanoPanel::FusionChanged(wxCommandEvent & e)
00892 {
00893     int fusion = m_FusionChoice->GetSelection();
00894     DEBUG_DEBUG("changing stacking program to " << fusion);
00895 }
00896 
00897 void PanoPanel::OnFusionOptions(wxCommandEvent & e)
00898 {
00899     HuginBase::PanoramaOptions opt = pano->getOptions();
00900     wxDialog dlg;
00901     wxXmlResource::Get()->LoadDialog(&dlg, this, wxT("enfuse_options_dialog"));
00902     wxTextCtrl * enfuse_opts_text = XRCCTRL(dlg, "enfuse_arguments_text", wxTextCtrl);
00903     enfuse_opts_text->SetValue(wxString(opt.enfuseOptions.c_str(), wxConvLocal));
00904     dlg.CentreOnParent();
00905 
00906     if (dlg.ShowModal() == wxID_OK) {
00907         if (enfuse_opts_text->GetValue().length() > 0) {
00908             opt.enfuseOptions = enfuse_opts_text->GetValue().mb_str(wxConvLocal);
00909         }
00910         else
00911         {
00912             opt.enfuseOptions = wxConfigBase::Get()->Read(wxT("Enfuse/Args"),wxT(HUGIN_ENFUSE_ARGS)).mb_str(wxConvLocal);
00913         };
00914         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00915             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00916             );
00917     }
00918 }
00919 
00920 
00921 void PanoPanel::HDRMergeChanged(wxCommandEvent & e)
00922 {
00923     int blender = m_HDRMergeChoice->GetSelection();
00924     DEBUG_DEBUG("changing HDR merger to " << blender);
00925 }
00926 
00927 void PanoPanel::OnHDRMergeOptions(wxCommandEvent & e)
00928 {
00929     HuginBase::PanoramaOptions opt = pano->getOptions();
00930     if (opt.hdrMergeMode == HuginBase::PanoramaOptions::HDRMERGE_AVERAGE) {
00931         HDRMergeOptionsDialog dlg(this);
00932         dlg.SetCommandLineArgument(wxString(opt.hdrmergeOptions.c_str(), wxConvLocal));
00933         if (dlg.ShowModal() == wxOK) 
00934         {
00935             opt.hdrmergeOptions=dlg.GetCommandLineArgument().mb_str(wxConvLocal);
00936             PanoCommand::GlobalCmdHist::getInstance().addCommand(
00937                 new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00938                 );
00939         }
00940     } else {
00941         wxLogError(_(" Options for this HDRMerge program not yet implemented"));
00942     }
00943 }
00944 
00945 
00946 
00947 void PanoPanel::DoCalcFOV(wxCommandEvent & e)
00948 {
00949     DEBUG_TRACE("");
00950     if (pano->getActiveImages().size() == 0) return;
00951 
00952     HuginBase::PanoramaOptions opt = pano->getOptions();
00953     HuginBase::CalculateFitPanorama fitPano(*pano);
00954     fitPano.run();
00955     opt.setHFOV(fitPano.getResultHorizontalFOV());
00956     opt.setHeight(hugin_utils::roundi(fitPano.getResultHeight()));
00957 
00958     DEBUG_INFO ( "hfov: " << opt.getHFOV() << "  w: " << opt.getWidth() << " h: " << opt.getHeight() << "  => vfov: " << opt.getVFOV()  << "  before update");
00959 
00960     PanoCommand::GlobalCmdHist::getInstance().addCommand(
00961         new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00962         );
00963 
00964     HuginBase::PanoramaOptions opt2 = pano->getOptions();
00965     DEBUG_INFO ( "hfov: " << opt2.getHFOV() << "  w: " << opt2.getWidth() << " h: " << opt2.getHeight() << "  => vfov: " << opt2.getVFOV()  << "  after update");
00966 
00967 }
00968 
00969 void PanoPanel::DoCalcOptimalWidth(wxCommandEvent & e)
00970 {
00971     if (pano->getActiveImages().size() == 0) return;
00972 
00973     HuginBase::PanoramaOptions opt = pano->getOptions();
00974     double sizeFactor = 1.0;
00975 #if wxCHECK_VERSION(2,9,4)
00976     if (wxGetKeyState(WXK_COMMAND))
00977 #else
00978     if (wxGetKeyState(WXK_CONTROL))
00979 #endif
00980     {
00981         wxConfigBase::Get()->Read(wxT("/Assistant/panoDownsizeFactor"), &sizeFactor, HUGIN_ASS_PANO_DOWNSIZE_FACTOR);
00982     };
00983 
00984     unsigned width = hugin_utils::roundi(HuginBase::CalculateOptimalScale::calcOptimalScale(*pano) * opt.getWidth() * sizeFactor);
00985 
00986     if (width > 0) {
00987         opt.setWidth( width );
00988         PanoCommand::GlobalCmdHist::getInstance().addCommand(
00989             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
00990             );
00991     }
00992     DEBUG_INFO ( "new optimal width: " << opt.getWidth() );
00993 }
00994 
00995 
00996 void PanoPanel::DoCalcOptimalROI(wxCommandEvent & e)
00997 {
00998     DEBUG_INFO("Dirty ROI Calc\n");
00999     if (pano->getActiveImages().size() == 0)
01000     {
01001         return;
01002     };
01003 
01004     vigra::Rect2D newROI;
01005     {
01006         ProgressReporterDialog progress(0, _("Autocrop"), _("Calculating optimal crop"), this);
01007         HuginBase::CalculateOptimalROI cropPano(*pano, &progress);
01008         cropPano.run();
01009         if (cropPano.hasRunSuccessfully())
01010         {
01011             newROI = cropPano.getResultOptimalROI();
01012         };
01013     };
01014 
01015     //set the ROI - fail if the right/bottom is zero, meaning all zero
01016     if(!newROI.isEmpty())
01017     {
01018         HuginBase::PanoramaOptions opt = pano->getOptions();
01019         opt.setROI(newROI);
01020         PanoCommand::GlobalCmdHist::getInstance().addCommand(
01021             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01022             );
01023     };
01024 };
01025 
01026 void PanoPanel::DoStitch()
01027 {
01028     if (pano->getNrOfImages() == 0) {
01029         return;
01030     }
01031     
01032     if (!CheckGoodSize()) {
01033         // oversized pano and the user no longer wants to stitch.
01034         return;
01035     }
01036     if (!CheckHasImages())
01037     {
01038         // output ROI contains no images
01039         return;
01040     };
01041 
01042     // save project
01043     // copy pto file to temporary file
01044     wxString tempDir= wxConfigBase::Get()->Read(wxT("tempDir"),wxT(""));
01045     if(!tempDir.IsEmpty())
01046         if(tempDir.Last()!=wxFileName::GetPathSeparator())
01047             tempDir.Append(wxFileName::GetPathSeparator());
01048     wxString currentPTOfn = wxFileName::CreateTempFileName(tempDir+wxT("huginpto_"));
01049     if(currentPTOfn.size() == 0) {
01050         wxMessageBox(_("Could not create temporary project file"),_("Error"),
01051                 wxCANCEL | wxICON_ERROR,this);
01052         return;
01053     }
01054     DEBUG_DEBUG("tmp PTO file: " << (const char *)currentPTOfn.mb_str(wxConvLocal));
01055     // copy is not enough, need to adjust image path names...
01056     std::ofstream script(currentPTOfn.mb_str(HUGIN_CONV_FILENAME));
01057     HuginBase::UIntSet all;
01058     if (pano->getNrOfImages() > 0) {
01059         fill_set(all, 0, pano->getNrOfImages()-1);
01060     }
01061     pano->printPanoramaScript(script, pano->getOptimizeVector(), pano->getOptions(), all, false, "");
01062     script.close();
01063 
01064 //    wxCommandEvent dummy;
01065 //    MainFrame::Get()->OnSaveProject(dummy);
01066 
01067 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01068     // HuginStitchProject inside main bundle
01069     wxString hugin_stitch_project = MacGetPathToBundledAppMainExecutableFile(CFSTR("HuginStitchProject.app"));
01070     if(hugin_stitch_project == wxT(""))
01071     {
01072         DEBUG_ERROR("hugin_stitch_project could not be found in the bundle.");
01073         return;
01074     }
01075     hugin_stitch_project = hugin_utils::wxQuoteFilename(hugin_stitch_project);
01076 #elif defined __WXMAC__
01077     // HuginStitchProject installed in INSTALL_OSX_BUNDLE_DIR
01078     wxFileName hugin_stitch_project_app(wxT(INSTALL_OSX_BUNDLE_DIR), wxEmptyString);
01079     hugin_stitch_project_app.AppendDir(wxT("HuginStitchProject.app"));
01080     CFStringRef stitchProjectAppPath = MacCreateCFStringWithWxString(hugin_stitch_project_app.GetFullPath());
01081     wxString hugin_stitch_project = MacGetPathToMainExecutableFileOfBundle(stitchProjectAppPath);
01082     CFRelease(stitchProjectAppPath);
01083 #else
01084     wxString hugin_stitch_project = wxT("hugin_stitch_project");
01085 #endif
01086 
01087     // Derive a default output prefix from the project filename if set, otherwise default project filename
01088     wxFileName outputPrefix(getDefaultOutputName(MainFrame::Get()->getProjectName(), *pano));
01089     outputPrefix.Normalize();
01090 
01091     // Show a file save dialog so user can confirm/change the prefix.
01092     // (We don't have to worry about overwriting existing files, since hugin_switch_project checks this.)
01093     // TODO: The following code is similar to stitchApp::OnInit in hugin_switch_project.cpp. Should be refactored.
01094     // TODO: We should save the output prefix somewhere, so we can recall it as the default if the user stitches this project again.
01095     wxFileDialog dlg(this,_("Specify output prefix"),
01096                      outputPrefix.GetPath(), outputPrefix.GetName(), wxT(""),
01097                      wxFD_SAVE, wxDefaultPosition);
01098     if (dlg.ShowModal() != wxID_OK)
01099     {
01100         return;
01101     };
01102     while(containsInvalidCharacters(dlg.GetPath()))
01103     {
01104         wxArrayString list;
01105         list.Add(dlg.GetPath());
01106         ShowFilenameWarning(this, list);
01107         if(dlg.ShowModal()!=wxID_OK)
01108             return;
01109     };
01110     wxFileName prefix(dlg.GetPath());
01111     while (!prefix.IsDirWritable())
01112     {
01113         wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
01114 #ifdef __WXMSW__
01115             wxT("Hugin"),
01116 #else
01117             wxT(""),
01118 #endif
01119             wxOK | wxICON_INFORMATION);
01120         if (dlg.ShowModal() != wxID_OK)
01121         {
01122             return;
01123         };
01124         prefix = dlg.GetPath();
01125     };
01126     // check free space
01127     if (!CheckFreeSpace(prefix.GetPath()))
01128     {
01129         return;
01130     };
01131 
01132     wxString switches(wxT(" --delete -o "));
01133     if(wxConfigBase::Get()->Read(wxT("/Processor/overwrite"), HUGIN_PROCESSOR_OVERWRITE) == 1)
01134         switches=wxT(" --overwrite")+switches;
01135     wxString command = hugin_stitch_project + switches + hugin_utils::wxQuoteFilename(dlg.GetPath()) + wxT(" ") + hugin_utils::wxQuoteFilename(currentPTOfn);
01136     
01137     wxConfigBase::Get()->Flush();
01138 #ifdef __WXGTK__
01139     // work around a wxExecute bug/problem
01140     // (endless polling of fd 0 and 1 in hugin_stitch_project)
01141     wxProcess *my_process = new wxProcess(this);
01142     my_process->Redirect();
01143 
01144     // Delete itself once processes terminated.
01145     my_process->Detach();
01146     wxExecute(command,wxEXEC_ASYNC, my_process);
01147 #else
01148     wxExecute(command);
01149 #endif
01150     HuginBase::LensDB::SaveLensDataFromPano(*pano);
01151 }
01152 
01153 void PanoPanel::DoSendToBatch()
01154 {
01155     if (pano->getNrOfImages() == 0)
01156     {
01157         return;
01158     }
01159     
01160     if (!CheckGoodSize())
01161     {
01162         // oversized pano and the user no longer wants to stitch.
01163         return;
01164     }
01165     if( !CheckHasImages())
01166     {
01167         // output ROI contains no images
01168         return;
01169     };
01170 
01171     wxString switches(wxT(" "));
01172     if (wxConfigBase::Get()->Read(wxT("/Processor/start"), HUGIN_PROCESSOR_START) != 0)
01173     {
01174         switches += wxT("-b ");
01175     }
01176     if (wxConfigBase::Get()->Read(wxT("/Processor/overwrite"), HUGIN_PROCESSOR_OVERWRITE) != 0)
01177     {
01178         switches += wxT("-o ");
01179     }
01180     if (wxConfigBase::Get()->Read(wxT("/Processor/verbose"), HUGIN_PROCESSOR_VERBOSE) != 0)
01181     {
01182         switches += wxT("-v ");
01183     }
01184     if(pano->isDirty())
01185     {
01186         bool showDlg=wxConfigBase::Get()->Read(wxT("ShowSaveMessage"), 1l)==1;
01187         if(showDlg)
01188         {
01189             wxDialog dlg;
01190             wxXmlResource::Get()->LoadDialog(&dlg, NULL, wxT("stitch_message_dlg"));
01191             if(dlg.ShowModal())
01192             {
01193                 if(XRCCTRL(dlg, "stitch_dont_show_checkbox", wxCheckBox)->IsChecked())
01194                 {
01195                     wxConfigBase::Get()->Write(wxT("ShowSaveMessage"), 0l);
01196                 };
01197             };
01198         };
01199         wxCommandEvent dummy;
01200         MainFrame::Get()->OnSaveProject(dummy);
01201         //test if save was sucessful
01202         if(pano->isDirty())
01203         {
01204             return;
01205         };
01206     };
01207     wxString projectFile = MainFrame::Get()->getProjectName();
01208     if(wxFileName::FileExists(projectFile))
01209     {
01210         wxFileName outputPrefix(getDefaultOutputName(projectFile, *pano));
01211         outputPrefix.Normalize();
01212 
01213         // Show a file save dialog so user can confirm/change the prefix.
01214         // (We don't have to worry about overwriting existing files, since PTBatcherGUI checks this, or the overwrite flag was set.)
01215         wxFileDialog dlg(this,_("Specify output prefix"),
01216                          outputPrefix.GetPath(), outputPrefix.GetName(), wxT(""),
01217                          wxFD_SAVE, wxDefaultPosition);
01218         if (dlg.ShowModal() != wxID_OK)
01219         {
01220             return;
01221         };
01222         while(containsInvalidCharacters(dlg.GetPath()))
01223         {
01224             wxArrayString list;
01225             list.Add(dlg.GetPath());
01226             ShowFilenameWarning(this, list);
01227             if(dlg.ShowModal()!=wxID_OK)
01228                 return;
01229         };
01230         wxFileName prefix(dlg.GetPath());
01231         while (!prefix.IsDirWritable())
01232         {
01233             wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
01234 #ifdef __WXMSW__
01235                 wxT("Hugin"),
01236 #else
01237                 wxT(""),
01238 #endif
01239                 wxOK | wxICON_INFORMATION);
01240             if (dlg.ShowModal() != wxID_OK)
01241             {
01242                 return;
01243             };
01244             prefix = dlg.GetPath();
01245         };
01246         // check free space
01247         if (!CheckFreeSpace(prefix.GetPath()))
01248         {
01249             return;
01250         };
01251 
01252 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01253                 wxString cmd = MacGetPathToMainExecutableFileOfRegisteredBundle(CFSTR("net.sourceforge.hugin.PTBatcherGUI"));
01254                 if(cmd != wxT(""))
01255                 { 
01256                         //Found PTBatcherGui inside the (registered) PTBatcherGui bundle. Call it directly.
01257                         //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
01258                         //will provide the menu
01259                         cmd = hugin_utils::wxQuoteString(cmd); 
01260             cmd += wxT(" ")+switches+hugin_utils::wxQuoteFilename(projectFile)+wxT(" ")+hugin_utils::wxQuoteFilename(dlg.GetPath());    
01261                         wxExecute(cmd);
01262                 }
01263                 else
01264                 { //Can't find PTBatcherGui.app bundle. Use the most straightforward call possible to the bundle but this should actually not work either.
01265                                 wxMessageBox(wxString::Format(_("External program %s not found in the bundle, reverting to system path"), wxT("open")), _("Error"));
01266                 cmd = wxT("open -b net.sourceforge.hugin.PTBatcherGUI ")+hugin_utils::wxQuoteFilename(projectFile);
01267                                 wxExecute(cmd);
01268                 }
01269                 
01270 #else
01271         const wxFileName exePath(wxStandardPaths::Get().GetExecutablePath());
01272         wxExecute(exePath.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + wxT("PTBatcherGUI ") + switches + hugin_utils::wxQuoteFilename(projectFile) + wxT(" ") + hugin_utils::wxQuoteFilename(dlg.GetPath()));
01273 #endif
01274         HuginBase::LensDB::SaveLensDataFromPano(*pano);
01275     }
01276 };
01277 
01278 void PanoPanel::DoUserDefinedStitch()
01279 {
01280     if (pano->getNrOfImages() == 0)
01281     {
01282         return;
01283     }
01284 
01285     if (!CheckGoodSize())
01286     {
01287         // oversized pano and the user no longer wants to stitch.
01288         return;
01289     }
01290     if (!CheckHasImages())
01291     {
01292         // output ROI contains no images
01293         return;
01294     };
01295     // create a copy, if we need to update the crop setting
01296     wxConfigBase* config = wxConfigBase::Get();
01297     wxString path = config->Read(wxT("/userDefinedOutputPath"), MainFrame::Get()->GetDataPath());
01298     wxFileDialog userOutputDlg(this, _("Select user defined output"),
01299         path, wxT(""), _("User defined output|*.executor"),
01300         wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST, wxDefaultPosition);
01301     if (userOutputDlg.ShowModal() != wxID_OK)
01302     {
01303         return;
01304     };
01305     // remember path for later
01306     config->Write(wxT("/userDefinedOutputPath"), userOutputDlg.GetDirectory());
01307 
01308     // save project
01309     // copy pto file to temporary file
01310     wxString tempDir = wxConfigBase::Get()->Read(wxT("tempDir"), wxT(""));
01311     if (!tempDir.IsEmpty())
01312     {
01313         if (tempDir.Last() != wxFileName::GetPathSeparator())
01314         {
01315             tempDir.Append(wxFileName::GetPathSeparator());
01316         }
01317     };
01318     wxString currentPTOfn = wxFileName::CreateTempFileName(tempDir + wxT("huginpto_"));
01319     if (currentPTOfn.size() == 0)
01320     {
01321         wxMessageBox(_("Could not create temporary project file"), _("Error"),
01322             wxCANCEL | wxICON_ERROR, this);
01323         return;
01324     }
01325     DEBUG_DEBUG("tmp PTO file: " << (const char *)currentPTOfn.mb_str(wxConvLocal));
01326     // copy is not enough, need to adjust image path names...
01327     std::ofstream script(currentPTOfn.mb_str(HUGIN_CONV_FILENAME));
01328     HuginBase::UIntSet all;
01329     fill_set(all, 0, pano->getNrOfImages() - 1);
01330     pano->printPanoramaScript(script, pano->getOptimizeVector(), pano->getOptions(), all, false, "");
01331     script.close();
01332 
01333     //    wxCommandEvent dummy;
01334     //    MainFrame::Get()->OnSaveProject(dummy);
01335 
01336 #if defined __WXMAC__ && defined MAC_SELF_CONTAINED_BUNDLE
01337     // HuginStitchProject inside main bundle
01338     wxString hugin_stitch_project = MacGetPathToBundledAppMainExecutableFile(CFSTR("HuginStitchProject.app"));
01339     if (hugin_stitch_project == wxT(""))
01340     {
01341         DEBUG_ERROR("hugin_stitch_project could not be found in the bundle.");
01342         return;
01343     }
01344     hugin_stitch_project = hugin_utils::wxQuoteFilename(hugin_stitch_project);
01345 #elif defined __WXMAC__
01346     // HuginStitchProject installed in INSTALL_OSX_BUNDLE_DIR
01347     wxFileName hugin_stitch_project_app(wxT(INSTALL_OSX_BUNDLE_DIR), wxEmptyString);
01348     hugin_stitch_project_app.AppendDir(wxT("HuginStitchProject.app"));
01349     CFStringRef stitchProjectAppPath = MacCreateCFStringWithWxString(hugin_stitch_project_app.GetFullPath());
01350     wxString hugin_stitch_project = MacGetPathToMainExecutableFileOfBundle(stitchProjectAppPath);
01351     CFRelease(stitchProjectAppPath);
01352 #else
01353     wxString hugin_stitch_project = wxT("hugin_stitch_project");
01354 #endif
01355 
01356     // Derive a default output prefix from the project filename if set, otherwise default project filename
01357     wxFileName outputPrefix(getDefaultOutputName(MainFrame::Get()->getProjectName(), *pano));
01358     outputPrefix.Normalize();
01359 
01360     // Show a file save dialog so user can confirm/change the prefix.
01361     // (We don't have to worry about overwriting existing files, since hugin_switch_project checks this.)
01362     // TODO: The following code is similar to stitchApp::OnInit in hugin_switch_project.cpp. Should be refactored.
01363     // TODO: We should save the output prefix somewhere, so we can recall it as the default if the user stitches this project again.
01364     wxFileDialog dlg(this, _("Specify output prefix"),
01365         outputPrefix.GetPath(), outputPrefix.GetName(), wxT(""),
01366         wxFD_SAVE, wxDefaultPosition);
01367     if (dlg.ShowModal() != wxID_OK)
01368     {
01369         return;
01370     };
01371     while (containsInvalidCharacters(dlg.GetPath()))
01372     {
01373         wxArrayString list;
01374         list.Add(dlg.GetPath());
01375         ShowFilenameWarning(this, list);
01376         if (dlg.ShowModal() != wxID_OK)
01377             return;
01378     };
01379     wxFileName prefix(dlg.GetPath());
01380     while (!prefix.IsDirWritable())
01381     {
01382         wxMessageBox(wxString::Format(_("You have no permissions to write in folder \"%s\".\nPlease select another folder for the final output."), prefix.GetPath().c_str()),
01383 #ifdef __WXMSW__
01384             wxT("Hugin"),
01385 #else
01386             wxT(""),
01387 #endif
01388             wxOK | wxICON_INFORMATION);
01389         if (dlg.ShowModal() != wxID_OK)
01390         {
01391             return;
01392         };
01393         prefix = dlg.GetPath();
01394     };
01395     // check free space
01396     if (!CheckFreeSpace(prefix.GetPath()))
01397     {
01398         return;
01399     };
01400 
01401     wxString switches(wxT(" --user-defined-output=") + hugin_utils::wxQuoteFilename(userOutputDlg.GetPath()) + wxT(" --delete -o "));
01402     if (wxConfigBase::Get()->Read(wxT("/Processor/overwrite"), HUGIN_PROCESSOR_OVERWRITE) == 1)
01403         switches = wxT(" --overwrite") + switches;
01404     wxString command = hugin_stitch_project + switches + hugin_utils::wxQuoteFilename(dlg.GetPath()) + wxT(" ") + hugin_utils::wxQuoteFilename(currentPTOfn);
01405 
01406     wxConfigBase::Get()->Flush();
01407 #ifdef __WXGTK__
01408     // work around a wxExecute bug/problem
01409     // (endless polling of fd 0 and 1 in hugin_stitch_project)
01410     wxProcess *my_process = new wxProcess(this);
01411     my_process->Redirect();
01412 
01413     // Delete itself once processes terminated.
01414     my_process->Detach();
01415     wxExecute(command, wxEXEC_ASYNC, my_process);
01416 #else
01417     wxExecute(command);
01418 #endif
01419 }
01420 
01421 
01422 void PanoPanel::OnDoStitch ( wxCommandEvent & e )
01423 {
01424     long t;
01425 #if wxCHECK_VERSION(2,9,4)
01426     if(wxGetKeyState(WXK_COMMAND))
01427 #else
01428     if(wxGetKeyState(WXK_CONTROL))
01429 #endif
01430     {
01431         t=1;
01432     }
01433     else
01434     {
01435         wxConfigBase::Get()->Read(wxT("/Processor/gui"),&t,HUGIN_PROCESSOR_GUI);
01436     };
01437     switch (t)
01438     {
01439         // PTBatcher
01440         case 0:
01441             DoSendToBatch();
01442             break;
01443         // hugin_stitch_project
01444         case 1:
01445             DoStitch();
01446             break;
01447         // there is an error in the preferences
01448         default :
01449             // TODO: notify user and fix preferences misconfiguration
01450             break;
01451       }
01452 }
01453 
01454 void PanoPanel::FileFormatChanged(wxCommandEvent & e)
01455 {
01456 
01457     int fmt = m_FileFormatChoice->GetSelection();
01458     DEBUG_DEBUG("changing file format to " << fmt);
01459 
01460     HuginBase::PanoramaOptions opt = pano->getOptions();
01461     switch (fmt) {
01462         case 1:
01463             opt.outputImageType ="jpg";
01464             break;
01465         case 2:
01466             opt.outputImageType ="png";
01467             break;
01468         case 3:
01469             opt.outputImageType ="exr";
01470             break;
01471         default:
01472         case 0:
01473             opt.outputImageType ="tif";
01474             break;
01475     }
01476 
01477     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01478             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01479             );
01480 }
01481 
01482 void PanoPanel::HDRFileFormatChanged(wxCommandEvent & e)
01483 {
01484 
01485     int fmt = m_HDRFileFormatChoice->GetSelection();
01486     DEBUG_DEBUG("changing file format to " << fmt);
01487 
01488     HuginBase::PanoramaOptions opt = pano->getOptions();
01489     switch (fmt) {
01490         case 1:
01491             opt.outputImageTypeHDR ="tif";
01492             break;
01493         default:
01494         case 0:
01495             opt.outputImageTypeHDR ="exr";
01496             break;
01497     }
01498 
01499     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01500             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01501             );
01502 }
01503 
01504 void PanoPanel::OnJPEGQualityText(wxCommandEvent & e)
01505 {
01506     HuginBase::PanoramaOptions opt = pano->getOptions();
01507     long l = 100;
01508     m_FileFormatJPEGQualityText->GetValue().ToLong(&l);
01509     if (l < 0) l=1;
01510     if (l > 100) l=100;
01511     DEBUG_DEBUG("Setting jpeg quality to " << l);
01512     opt.quality = l;
01513     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01514             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01515             );
01516 }
01517 
01518 void PanoPanel::OnNormalTIFFCompression(wxCommandEvent & e)
01519 {
01520     HuginBase::PanoramaOptions opt = pano->getOptions();
01521     switch(e.GetSelection()) {
01522         case 0:
01523         default:
01524             opt.outputImageTypeCompression = "NONE";
01525             opt.tiffCompression = "NONE";
01526             break;
01527         case 1:
01528             opt.outputImageTypeCompression = "PACKBITS";
01529             opt.tiffCompression = "PACKBITS";
01530             break;
01531         case 2:
01532             opt.outputImageTypeCompression = "LZW";
01533             opt.tiffCompression = "LZW";
01534             break;
01535         case 3:
01536             opt.outputImageTypeCompression = "DEFLATE";
01537             opt.tiffCompression = "DEFLATE";
01538             break;
01539     }
01540     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01541             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01542             );
01543 }
01544 
01545 void PanoPanel::OnHDRTIFFCompression(wxCommandEvent & e)
01546 {
01547     HuginBase::PanoramaOptions opt = pano->getOptions();
01548     switch(e.GetSelection()) {
01549         case 0:
01550         default:
01551             opt.outputImageTypeHDRCompression = "NONE";
01552             break;
01553         case 1:
01554             opt.outputImageTypeHDRCompression = "PACKBITS";
01555             break;
01556         case 2:
01557             opt.outputImageTypeHDRCompression = "LZW";
01558             break;
01559         case 3:
01560             opt.outputImageTypeHDRCompression = "DEFLATE";
01561             break;
01562     }
01563     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01564             new PanoCommand::SetPanoOptionsCmd( *pano, opt )
01565             );
01566 }
01567 
01568 void PanoPanel::OnOutputFilesChanged(wxCommandEvent & e)
01569 {
01570     int id = e.GetId();
01571     HuginBase::PanoramaOptions opts = pano->getOptions();
01572 
01573     if (id == XRCID("pano_cb_ldr_output_blended") ) {
01574         opts.outputLDRBlended = e.IsChecked();
01575     } else if (id == XRCID("pano_cb_ldr_output_layers") ) {
01576         opts.outputLDRLayers = e.IsChecked();
01577     } else if (id == XRCID("pano_cb_ldr_output_exposure_layers") ) {
01578         opts.outputLDRExposureLayers = e.IsChecked();
01579     } else if (id == XRCID("pano_cb_ldr_output_exposure_blended") ) {
01580         opts.outputLDRExposureBlended = e.IsChecked();
01581     } else if (id == XRCID("pano_cb_ldr_output_exposure_layers_fused") ) {
01582         opts.outputLDRExposureLayersFused = e.IsChecked();
01583     } else if (id == XRCID("pano_cb_ldr_output_exposure_remapped") ) {
01584         opts.outputLDRExposureRemapped = e.IsChecked();
01585     } else if (id == XRCID("pano_cb_ldr_output_stacks") ) {
01586         opts.outputLDRStacks = e.IsChecked();
01587     } else if (id == XRCID("pano_cb_hdr_output_blended") ) {
01588         opts.outputHDRBlended = e.IsChecked();
01589     } else if (id == XRCID("pano_cb_hdr_output_stacks") ) {
01590         opts.outputHDRStacks = e.IsChecked();
01591     } else if (id == XRCID("pano_cb_hdr_output_layers") ) {
01592         opts.outputHDRLayers = e.IsChecked();
01593     }
01594     
01595     PanoCommand::GlobalCmdHist::getInstance().addCommand(
01596             new PanoCommand::SetPanoOptionsCmd( *pano, opts )
01597         );
01598 }
01599 
01600 bool PanoPanel::CheckGoodSize()
01601 {
01602     const HuginBase::PanoramaOptions opts(pano->getOptions());
01603     const vigra::Rect2D cropped_region (opts.getROI());    
01604     // width and height of jpeg images has to be smaller than 65500 pixel
01605     if (opts.outputImageType == "jpg" &&
01606         (opts.outputLDRBlended || opts.outputLDRExposureBlended || opts.outputLDRExposureLayersFused) &&
01607         (cropped_region.width()>65500 || cropped_region.height()>65500)
01608         )
01609     {
01610         wxMessageBox(
01611             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()),
01612 #ifdef _WIN32
01613             _("Hugin"),
01614 #else
01615             wxT(""),
01616 #endif
01617             wxICON_EXCLAMATION | wxOK);
01618         return false;
01619     };
01620     wxString message;
01621     unsigned long long int area = ((unsigned long int) cropped_region.width()) * ((unsigned long int) cropped_region.height());
01622     // Argh, more than half a gigapixel!
01623     if (area > 500000000)
01624     {
01625         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."),
01626             area / 1000000000.0);
01627     }
01628     else
01629     {
01630         if (cropped_region.width() > 32700 || cropped_region.height() > 32700)
01631         {
01632             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.");
01633         };
01634     };
01635     if (!message.empty())
01636     {
01637         // Tell the user the stitch will be really big, and give them a
01638         // chance to reduce the size.
01639 #if wxCHECK_VERSION(2,9,0)
01640         wxMessageDialog dialog(this,
01641                 _("Are you sure you want to stitch such a large panorama?"),
01642 #ifdef _WIN32
01643                 _("Hugin"),
01644 #else
01645                 wxT(""),
01646 #endif
01647                 wxICON_EXCLAMATION | wxYES_NO);
01648         dialog.SetExtendedMessage(message);
01649         dialog.SetYesNoLabels(_("Stitch anyway"), _("Let me fix that"));
01650 #else // replacement for old wxWidgets versions.
01651         // wxMessageDialog derives from wxDialog, but I don't understand
01652         // why because on most platforms wxMessageDialog uses the native
01653         // message box, and trying to make descriptive buttons through
01654         // wxDialog::CreateStdButtonSizer causes a crash on wxGTK.
01655         // Descriptive buttons are recommended by the Windows, Gnome, KDE,
01656         // and Apple user interface guidelines.
01657         // Due to this wxWidgets WTF, the buttons will are labeled Yes and
01658         // No on wxWidgets 2.8 and earlier. This makes it a little
01659         // confusing, and it is more likely someone will just click yes
01660         // without reading the message and then wonder why their computer
01661         // has ground to a halt.
01665         message.Prepend(wxT("\n\n"));
01666         message=_("Are you sure you want to stitch such a large panorama?")+message;
01667         wxMessageDialog dialog(this, message,
01668 #ifdef _WIN32
01669                 _("Hugin"),
01670 #else
01671                 wxT(""),
01672 #endif
01673                 wxICON_EXCLAMATION | wxYES_NO);
01674 #endif
01675         switch (dialog.ShowModal())
01676         {
01677             case wxID_OK:
01678             case wxID_YES:
01679                 // Continue stitch.
01680                 return true;
01681                 break;
01682             default:
01683                 // bring the user towards the approptiate controls.
01684                 MainFrame* mainframe = MainFrame::Get();
01685                 if (!mainframe->IsShown())
01686                 {
01687                     mainframe->Show();
01688                 }
01689                 mainframe->ShowStitcherTab();
01690                 return false;
01691         }
01692     }
01693     // I see nothing wrong with this...
01694     return true;
01695 }
01696 
01697 bool PanoPanel::CheckHasImages()
01698 {
01699     HuginBase::UIntSet images=getImagesinROI(*pano, pano->getActiveImages());
01700     if(images.size()==0)
01701     {
01702         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."),
01703 #ifdef _WIN32
01704             _("Hugin"),
01705 #else
01706             wxT(""),
01707 #endif
01708             wxOK | wxICON_INFORMATION);
01709     };
01710     return images.size()>0;
01711 };
01712 
01713 bool PanoPanel::CheckFreeSpace(const wxString& folder)
01714 {
01715     wxLongLong freeSpace;
01716     if (wxGetDiskSpace(folder, NULL, &freeSpace))
01717     {
01718         // 4 channels, 16 bit per channel, assuming the we need the 10 fold space for all temporary space
01719         if (pano->getOptions().getROI().area() * 80 > freeSpace)
01720         {
01721 #if wxCHECK_VERSION(2,9,0)
01722             wxMessageDialog dialog(this,
01723                 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),
01724 #ifdef _WIN32
01725                 _("Hugin"),
01726 #else
01727                 wxT(""),
01728 #endif
01729                 wxICON_EXCLAMATION | wxYES_NO);
01730             dialog.SetYesNoLabels(_("Stitch anyway"), _("Let me fix that"));
01731 #else // replacement for old wxWidgets versions.
01732             wxMessageDialog dialog(this,
01733                 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),
01734 #ifdef _WIN32
01735                 _("Hugin"),
01736 #else
01737                 wxT(""),
01738 #endif
01739                 wxICON_EXCLAMATION | wxYES_NO);
01740 #endif
01741             if (dialog.ShowModal() == wxID_NO)
01742             {
01743                 // bring the user towards the approptiate controls.
01744                 MainFrame* mainframe = MainFrame::Get();
01745                 if (!mainframe->IsShown())
01746                 {
01747                     mainframe->Show();
01748                 }
01749                 mainframe->ShowStitcherTab();
01750                 return false;
01751             };
01752         };
01753     };
01754     return true;
01755 };
01756 
01757 void PanoPanel::SetGuiLevel(GuiLevel newGuiLevel)
01758 {
01759     m_guiLevel=newGuiLevel;
01760     UpdateDisplay(m_oldOpt, false);
01761 };
01762 
01763 IMPLEMENT_DYNAMIC_CLASS(PanoPanel, wxPanel)
01764 
01765 PanoPanelXmlHandler::PanoPanelXmlHandler()
01766                 : wxXmlResourceHandler()
01767 {
01768     AddWindowStyles();
01769 }
01770 
01771 wxObject *PanoPanelXmlHandler::DoCreateResource()
01772 {
01773     XRC_MAKE_INSTANCE(cp, PanoPanel)
01774 
01775     cp->Create(m_parentAsWindow,
01776                    GetID(),
01777                    GetPosition(), GetSize(),
01778                    GetStyle(wxT("style")),
01779                    GetName());
01780 
01781     SetupWindow( cp);
01782 
01783     return cp;
01784 }
01785 
01786 bool PanoPanelXmlHandler::CanHandle(wxXmlNode *node)
01787 {
01788     return IsOfClass(node, wxT("PanoPanel"));
01789 }
01790 
01791 IMPLEMENT_DYNAMIC_CLASS(PanoPanelXmlHandler, wxXmlResourceHandler)
01792 

Generated on 3 May 2016 for Hugintrunk by  doxygen 1.4.7