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

Generated on 29 Aug 2015 for Hugintrunk by  doxygen 1.4.7