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

Generated on 9 Dec 2016 for Hugintrunk by  doxygen 1.4.7