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

Generated on 11 Feb 2016 for Hugintrunk by  doxygen 1.4.7