ImagesTree.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00010 /*  This program is free software; you can redistribute it and/or
00011  *  modify it under the terms of the GNU General Public
00012  *  License as published by the Free Software Foundation; either
00013  *  version 2 of the License, or (at your option) any later version.
00014  *
00015  *  This software is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  *  General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public
00021  *  License along with this software; if not, write to the Free Software
00022  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  */
00025 
00026 #include <config.h>
00027 #include "panoinc_WX.h"
00028 #include "panoinc.h"
00029 
00030 #include "base_wx/wxPlatform.h"
00031 #include "hugin/ImagesTree.h"
00032 #include "base_wx/wxImageCache.h"
00033 #include "base_wx/platform.h"
00034 #include "hugin_base/algorithms/basic/LayerStacks.h"
00035 #include <panodata/ImageVariableGroup.h>
00036 #include <panodata/StandardImageVariableGroups.h>
00037 #include "hugin/CommandHistory.h"
00038 #include <hugin_utils/stl_utils.h>
00039 #include "hugin/ImageVariableDialog.h"
00040 #include "hugin/huginApp.h"
00041 
00042 using namespace PT;
00043 using namespace hugin_utils;
00044 
00045 enum
00046 {
00047     ID_LINK=wxID_HIGHEST+230,
00048     ID_UNLINK,
00049     ID_EDIT,
00050     ID_SELECT_ALL,
00051     ID_UNSELECT_ALL,
00052     ID_SELECT_LENS_STACK,
00053     ID_UNSELECT_LENS_STACK,
00054     ID_OPERATION_START=wxID_HIGHEST+300
00055 };
00056 
00057 BEGIN_EVENT_TABLE(ImagesTreeCtrl, wxTreeListCtrl)
00058     EVT_LIST_COL_END_DRAG(-1, ImagesTreeCtrl::OnColumnWidthChange)
00059     EVT_TREE_ITEM_MENU(-1, ImagesTreeCtrl::OnContextMenu)
00060     EVT_LIST_COL_RIGHT_CLICK(-1, ImagesTreeCtrl::OnHeaderContextMenu)
00061     EVT_MENU(ID_LINK, ImagesTreeCtrl::OnLinkImageVariables)
00062     EVT_MENU(ID_UNLINK, ImagesTreeCtrl::OnUnlinkImageVariables)
00063     EVT_MENU(ID_EDIT, ImagesTreeCtrl::OnEditImageVariables)
00064     EVT_MENU(ID_SELECT_ALL, ImagesTreeCtrl::OnSelectAll)
00065     EVT_MENU(ID_UNSELECT_ALL, ImagesTreeCtrl::OnUnselectAll)
00066     EVT_MENU(ID_SELECT_LENS_STACK, ImagesTreeCtrl::OnSelectLensStack)
00067     EVT_MENU(ID_UNSELECT_LENS_STACK, ImagesTreeCtrl::OnUnselectLensStack)
00068     EVT_MENU_RANGE(ID_OPERATION_START, ID_OPERATION_START+50, ImagesTreeCtrl::OnExecuteOperation)
00069     EVT_TREE_BEGIN_DRAG(-1, ImagesTreeCtrl::OnBeginDrag)
00070     EVT_LEFT_UP(ImagesTreeCtrl::OnEndDrag)
00071     EVT_LEFT_DOWN(ImagesTreeCtrl::OnLeftDown)
00072     EVT_LEFT_DCLICK(ImagesTreeCtrl::OnLeftDblClick)
00073     EVT_TREE_KEY_DOWN(-1, ImagesTreeCtrl::OnChar)
00074     EVT_TREE_BEGIN_LABEL_EDIT(-1, ImagesTreeCtrl::OnBeginEdit)
00075     EVT_TREE_END_LABEL_EDIT(-1, ImagesTreeCtrl::OnEndEdit)
00076 END_EVENT_TABLE()
00077 
00078 class ImagesTreeData : public wxTreeItemData
00079 {
00080 public:
00081     ImagesTreeData(const long& nr) : m_nr(nr) { };
00082     const long GetImgNr() const { return m_nr;};
00083     void SetImgNr(long newImgNr) { m_nr=newImgNr;};
00084     const long GetGroupNr() const { return -(m_nr+1);};
00085     const bool IsGroup() const { return (m_nr<0); };
00086 
00087 private:
00088     long m_nr;
00089 };
00090 
00091 // Define a constructor for the Images Panel
00092 ImagesTreeCtrl::ImagesTreeCtrl()
00093 {
00094     m_pano = NULL;
00095     m_groupMode=GROUP_NONE;
00096     m_guiLevel=GUI_SIMPLE;
00097     m_dragging=false;
00098     m_displayMode=DISPLAY_GENERAL;
00099     m_optimizerMode=false;
00100     m_needsUpdate=true;
00101 }
00102 
00103 bool ImagesTreeCtrl::Create(wxWindow* parent, wxWindowID id,
00104                         const wxPoint& pos,
00105                         const wxSize& size,
00106                         long style,
00107                         const wxString& name)
00108 {
00109     DEBUG_TRACE("List");
00110     if (! wxTreeListCtrl::Create(parent, id, pos, size, style | wxTR_DEFAULT_STYLE|wxTR_HIDE_ROOT|wxTR_NO_LINES|wxTR_FULL_ROW_HIGHLIGHT|wxTR_ROW_LINES|wxTR_LINES_AT_ROOT|wxTR_MULTIPLE) )
00111     {
00112         return false;
00113     }
00114 
00115     DEBUG_TRACE("Tree, adding columns");
00116     m_configClassName = wxT("/ImagesTree");
00117     CreateColumns();
00118     DEBUG_TRACE("");
00119     m_degDigits = wxConfigBase::Get()->Read(wxT("/General/DegreeFractionalDigits"),1);
00120     m_pixelDigits = wxConfigBase::Get()->Read(wxT("/General/PixelFractionalDigits"),1);
00121     m_distDigits = wxConfigBase::Get()->Read(wxT("/General/DistortionFractionalDigits"),3);
00122     //create root
00123     m_root=AddRoot(wxT("root"));
00124     return true;
00125 }
00126 
00127 void ImagesTreeCtrl::CreateColumns()
00128 {
00129     size_t counter=0;
00130 #define ADDCOLUMN(header, mapName, width, align, isEditable, IVE, tooltip) \
00131     AddColumn(header, width, align, -1, true, false, tooltip);\
00132     m_columnMap[mapName]=counter;\
00133     m_columnVector.push_back(mapName);\
00134     if(isEditable)\
00135     {\
00136         m_editableColumns.insert(counter);\
00137     };\
00138     m_variableVector.push_back(IVE);\
00139     counter++;
00140     ADDCOLUMN(wxT("#"), "imgNr", 35, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Image number"))
00141     ADDCOLUMN(_("Filename"), "filename", 200, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Filename"))
00142     ADDCOLUMN(_("Width"), "width", 60, wxALIGN_RIGHT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Image width"))
00143     ADDCOLUMN(_("Height"), "height", 60, wxALIGN_RIGHT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Image height"))
00144     ADDCOLUMN(_("Anchor"), "anchor", 60, wxALIGN_RIGHT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Anchor image for position and/or exposure"))
00145     ADDCOLUMN(_("# Ctrl Pnts"), "cps", 60, wxALIGN_RIGHT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Number of control points in this image"))
00146     ADDCOLUMN(_("Lens no."), "lensNr", 60, wxALIGN_RIGHT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Assigned lens number"))
00147     ADDCOLUMN(_("Stack no."), "stackNr", 60, wxALIGN_RIGHT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Assigned stack number"))
00148 
00149     ADDCOLUMN(_("Maker"), "maker", 100, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Camera maker"))
00150     ADDCOLUMN(_("Model"), "model", 100, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Camera model"))
00151     ADDCOLUMN(_("Lens"), "lens", 100, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Used lens"))
00152     ADDCOLUMN(_("Capture date"), "date", 100, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Date, image was taken"))
00153     ADDCOLUMN(_("Focal length"), "focallength", 80, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Focal length"))
00154     ADDCOLUMN(_("Aperture"), "aperture", 50, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Aperture"))
00155     ADDCOLUMN(_("Shutter Speed"), "time", 50, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Shutter speed"))
00156     ADDCOLUMN(_("ISO"), "iso", 50, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("ISO speed"))
00157 
00158     ADDCOLUMN(_("Yaw (y)"), "y", 60, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_Yaw, _("Yaw"))
00159     ADDCOLUMN(_("Pitch (p)"), "p", 60, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_Yaw, _("Pitch"))
00160     ADDCOLUMN(_("Roll (r)"), "r", 60, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_Yaw, _("Roll"))
00161     ADDCOLUMN(wxT("X (TrX)"), "TrX", 60, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_Yaw, _("Camera translation X"))
00162     ADDCOLUMN(wxT("Y (TrY)"), "TrY", 60, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_Yaw, _("Camera translation Y"))
00163     ADDCOLUMN(wxT("Z (TrZ)"), "TrZ", 60, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_Yaw, _("Camera translation Z"))
00164     ADDCOLUMN(_("Plane yaw"), "Tpy", 60, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_Yaw, _("Translation remap plane yaw"))
00165     ADDCOLUMN(_("Plane pitch"), "Tpp", 60, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_Yaw, _("Translation remap plane pitch"))
00166     ADDCOLUMN(_("Camera translation"), "cam_trans", 60, wxALIGN_LEFT, true, HuginBase::ImageVariableGroup::IVE_Yaw, _("Camera translation"))
00167 
00168     ADDCOLUMN(_("Lens type (f)"), "projection", 100, wxALIGN_LEFT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Lens type (rectilinear, fisheye, equirectangular, ...)"))
00169     ADDCOLUMN(_("Hfov (v)"), "v", 80, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_HFOV, _("Horizontal field of view (v)"))
00170     ADDCOLUMN(wxT("a"), "a", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_RadialDistortion, _("Radial distortion (a)"))
00171     ADDCOLUMN(wxT("b"), "b", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_RadialDistortion, _("Radial distortion (b, barrel)"))
00172     ADDCOLUMN(wxT("c"), "c", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_RadialDistortion, _("Radial distortion (c)"))
00173     ADDCOLUMN(wxT("d"), "d", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_RadialDistortionCenterShift, _("Horizontal image center shift (d)"))
00174     ADDCOLUMN(wxT("e"), "e", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_RadialDistortionCenterShift, _("Vertical image center shift (e)"))
00175     ADDCOLUMN(wxT("g"), "g", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_Shear, _("Horizontal image shearing (g)"))
00176     ADDCOLUMN(wxT("t"), "t", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_Shear, _("Vertical image shearing (t)"))
00177 
00178     ADDCOLUMN(wxT("EV"), "Eev", 50, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_ExposureValue, _("Exposure value (Eev)"))
00179     ADDCOLUMN(wxT("Er"), "Er", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_WhiteBalanceRed, _("Red multiplier (Er)"))
00180     ADDCOLUMN(wxT("Eb"), "Eb", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_WhiteBalanceBlue, _("Blue multiplier (Eb)"))
00181     ADDCOLUMN(wxT("Vb"), "Vb", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_RadialVigCorrCoeff, _("Vignetting (Vb, Vc, Vd)"))
00182     ADDCOLUMN(wxT("Vc"), "Vc", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_RadialVigCorrCoeff, _("Vignetting (Vb, Vc, Vd)"))
00183     ADDCOLUMN(wxT("Vd"), "Vd", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_RadialVigCorrCoeff, _("Vignetting (Vb, Vc, Vd)"))
00184     ADDCOLUMN(wxT("Vx"), "Vx", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_RadialVigCorrCenterShift, _("Horizontal vignetting center shift (Vx)"))
00185     ADDCOLUMN(wxT("Vy"), "Vy", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_RadialVigCorrCenterShift, _("Vertical vignetting center shift (Vy)"))
00186     ADDCOLUMN(_("Response type"), "response", 80, wxALIGN_RIGHT, false, HuginBase::ImageVariableGroup::IVE_Filename, _("Camera response type"))
00187     ADDCOLUMN(wxT("Ra"), "Ra", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_EMoRParams, _("Camera response parameter"))
00188     ADDCOLUMN(wxT("Rb"), "Rb", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_EMoRParams, _("Camera response parameter"))
00189     ADDCOLUMN(wxT("Rc"), "Rc", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_EMoRParams, _("Camera response parameter"))
00190     ADDCOLUMN(wxT("Rd"), "Rd", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_EMoRParams, _("Camera response parameter"))
00191     ADDCOLUMN(wxT("Re"), "Re", 40, wxALIGN_RIGHT, true, HuginBase::ImageVariableGroup::IVE_EMoRParams, _("Camera response parameter"))
00192 
00193     //empty column to have enough space on the right side
00194     AddColumn(wxEmptyString,10);
00195 
00196     //get saved width
00197     for ( int j=0; j < GetColumnCount() ; j++ )
00198     {
00199         // -1 is auto
00200         int width = wxConfigBase::Get()->Read(wxString::Format(m_configClassName+wxT("/ColumnWidth%d"), j ), -1);
00201         if(width != -1)
00202             SetColumnWidth(j, width);
00203     }
00204 };
00205 
00206 void ImagesTreeCtrl::Init(PT::Panorama * panorama)
00207 {
00208     m_pano = panorama;
00209     m_pano->addObserver(this);
00210     
00212     m_variable_groups = new HuginBase::StandardImageVariableGroups(*m_pano);
00213     DEBUG_ASSERT(m_variable_groups);
00214     
00215 #ifdef __WXMAC__
00216     SetDropTarget(new PanoDropTarget(*m_pano, true));
00217 #endif
00218 }
00219 
00220 ImagesTreeCtrl::~ImagesTreeCtrl(void)
00221 {
00222     DEBUG_TRACE("");
00223     m_pano->removeObserver(this);
00224     delete m_variable_groups;
00225 };
00226 
00227 void ImagesTreeCtrl::panoramaChanged(PT::Panorama & pano)
00228 {
00229     if(m_optimizerMode)
00230     {
00231         Freeze();
00232         UpdateOptimizerVariables();
00233         Thaw();
00234     };
00235     if(m_needsUpdate && (m_groupMode==GROUP_OUTPUTLAYERS || m_groupMode==GROUP_OUTPUTSTACK))
00236     {
00237         UIntSet imgs;
00238         fill_set(imgs, 0, pano.getNrOfImages()-1);
00239         panoramaImagesChanged(pano, imgs);
00240     };
00241     m_needsUpdate=true;
00242 };
00243 
00244 void ImagesTreeCtrl::panoramaImagesChanged(Panorama &pano, const UIntSet &changed)
00245 {
00246     DEBUG_TRACE("");
00247 
00248     Freeze();
00249     UIntSet changedImgs(changed);
00250     // Make sure the part numbers are up to date before writing them to the table.
00251     size_t oldLensCount=m_variable_groups->getLenses().getNumberOfParts();
00252     size_t oldStackCount=m_variable_groups->getStacks().getNumberOfParts();
00253     m_variable_groups->update();
00254     //if the number of lenses or stacks have changed we need to update all images
00255     //because the changed images set contains only the list of the changed imagges
00256     //but not these images where the stack or lens number has changed because
00257     //an images has been inserted
00258     if(pano.getNrOfImages()>0)
00259     {
00260         if(m_variable_groups->getLenses().getNumberOfParts()!=oldLensCount ||
00261             m_variable_groups->getStacks().getNumberOfParts()!=oldStackCount)
00262         {
00263             fill_set(changedImgs, 0, pano.getNrOfImages()-1);
00264         };
00265     };
00266     if(m_optimizerMode)
00267     {
00268         if(m_groupMode==GROUP_NONE && m_pano->getNrOfImages()>m_variable_groups->getStacks().getNumberOfParts())
00269         {
00270             SetGroupMode(GROUP_STACK);
00271         };
00272         if(m_groupMode==GROUP_STACK && m_pano->getNrOfImages()==m_variable_groups->getStacks().getNumberOfParts())
00273         {
00274             SetGroupMode(GROUP_NONE);
00275         };
00276     };
00277     if(m_groupMode==GROUP_NONE)
00278     {
00279         UIntSet imgs;
00280         if(m_pano->getNrOfImages()>0)
00281         {
00282             fill_set(imgs,0,m_pano->getNrOfImages()-1);
00283         };
00284         UpdateGroup(m_root,imgs,changedImgs);
00285     }
00286     else
00287     {
00288         std::vector<UIntSet> imageGroups;
00289         switch (m_groupMode)
00290         {
00291             case GROUP_LENS:
00292                 {
00293                     HuginBase::ImageVariableGroup& lenses=m_variable_groups->getLenses();
00294                     imageGroups.resize(lenses.getNumberOfParts());
00295                     for(size_t i=0;i<m_pano->getNrOfImages();i++)
00296                     {
00297                         imageGroups[lenses.getPartNumber(i)].insert(i);
00298                     };
00299                 };
00300                 break;
00301             case GROUP_STACK:
00302                 {
00303                     HuginBase::ImageVariableGroup& stacks=m_variable_groups->getStacks();
00304                     imageGroups.resize(stacks.getNumberOfParts());
00305                     for(size_t i=0;i<m_pano->getNrOfImages();i++)
00306                     {
00307                         imageGroups[stacks.getPartNumber(i)].insert(i);
00308                     };
00309                 };
00310                 break;
00311             case GROUP_OUTPUTSTACK:
00312                 imageGroups=getHDRStacks(*m_pano,m_pano->getActiveImages(), m_pano->getOptions());
00313                 m_needsUpdate=false;
00314                 break;
00315             case GROUP_OUTPUTLAYERS:
00316                 imageGroups=getExposureLayers(*m_pano,m_pano->getActiveImages(), m_pano->getOptions());
00317                 m_needsUpdate=false;
00318                 break;
00319         };
00320 
00321         size_t nrItems=GetChildrenCount(m_root,false);
00322         if(nrItems!=imageGroups.size())
00323         {
00324             if(nrItems<imageGroups.size())
00325             {
00326                 for(size_t i=nrItems;i<imageGroups.size();i++)
00327                 {
00328                     AppendItem(m_root,wxEmptyString,-1,-1,new ImagesTreeData(-(long)i-1));
00329                 };
00330             }
00331             else
00332             {
00333                 while(GetChildrenCount(m_root,false)>imageGroups.size())
00334                 {
00335                     wxTreeItemIdValue cookie;
00336                     wxTreeItemId item=GetLastChild(m_root,cookie);
00337                     Delete(item);
00338                 };
00339             };
00340         };
00341 
00342         wxTreeItemIdValue cookie;
00343         wxTreeItemId item=GetFirstChild(m_root, cookie);
00344         size_t i=0;
00345         while(item.IsOk())
00346         {
00347             UpdateGroup(item,imageGroups[i++],changedImgs);
00348             UpdateGroupText(item);
00349             item=GetNextChild(m_root, cookie);
00350         };
00351     };
00352 
00353     Thaw();
00354 
00355     // HACK! need to notify clients anyway... send dummy event..
00356     // lets hope our clients query for the selected images with GetSelected()
00357     // and do not try to interpret the event.
00358     wxListEvent e;
00359     e.SetEventType(wxEVT_COMMAND_LIST_ITEM_SELECTED);
00360     e.m_itemIndex = -1;
00361     GetEventHandler()->ProcessEvent(e);
00362 }
00363 
00364 wxString getProjectionString(const SrcPanoImage& img)
00365 {
00366     wxString ps;
00367     switch(img.getProjection())
00368     {
00369         case SrcPanoImage::RECTILINEAR:          ps << _("Normal (rectilinear)"); break;
00370         case SrcPanoImage::PANORAMIC:            ps << _("Panoramic (cylindrical)"); break;
00371         case SrcPanoImage::CIRCULAR_FISHEYE:     ps << _("Circular fisheye"); break;
00372         case SrcPanoImage::FULL_FRAME_FISHEYE:   ps << _("Full frame fisheye"); break;
00373         case SrcPanoImage::EQUIRECTANGULAR:      ps << _("Equirectangular"); break;
00374         case SrcPanoImage::FISHEYE_ORTHOGRAPHIC: ps << _("Orthographic"); break;
00375         case SrcPanoImage::FISHEYE_STEREOGRAPHIC:ps << _("Stereographic"); break;
00376         case SrcPanoImage::FISHEYE_EQUISOLID:    ps << _("Equisolid"); break;
00377         case SrcPanoImage::FISHEYE_THOBY:        ps << _("Fisheye Thoby"); break;
00378     }
00379     return ps;
00380 };
00381 
00382 wxString getResponseString(const SrcPanoImage& img)
00383 {
00384     wxString s;
00385     switch(img.getResponseType())
00386     {
00387         case HuginBase::BaseSrcPanoImage::RESPONSE_EMOR:
00388             s=_("custom (EMoR)");
00389             break;
00390         case HuginBase::BaseSrcPanoImage::RESPONSE_LINEAR:
00391             s=_("Linear");
00392             break;
00393     };
00394     return s;
00395 };
00396 
00397 void ImagesTreeCtrl::UpdateImageText(wxTreeItemId item)
00398 {
00399     ImagesTreeData* itemData=(ImagesTreeData*)GetItemData(item);
00400     wxString s;
00401     size_t imgNr=itemData->GetImgNr();
00402     const SrcPanoImage & img = m_pano->getImage(imgNr);
00403     wxFileName fn(wxString (img.getFilename().c_str(), HUGIN_CONV_FILENAME));
00404 
00405     SetItemText(item, m_columnMap["imgNr"], wxString::Format(wxT("%d"), imgNr));
00406     SetItemText(item, m_columnMap["filename"], fn.GetFullName() );
00407     SetItemText(item, m_columnMap["width"], wxString::Format(wxT("%d"), img.getSize().width()));
00408     SetItemText(item, m_columnMap["height"], wxString::Format(wxT("%d"), img.getSize().height()));
00409 
00410     wxChar flags[] = wxT("--");
00411     if (m_pano->getOptions().optimizeReferenceImage == imgNr)
00412     {
00413         flags[0]='A';
00414     }
00415     if (m_pano->getOptions().colorReferenceImage == imgNr)
00416     {
00417         flags[1]='C';
00418     }
00419     SetItemText(item, m_columnMap["anchor"], wxString(flags, wxConvLocal));
00420     std::vector<unsigned int> cps = m_pano->getCtrlPointsForImage(imgNr);
00421     SetItemText(item, m_columnMap["cps"], wxString::Format(wxT("%d"), cps.size()));
00422     unsigned int stackNumber = m_variable_groups->getStacks().getPartNumber(imgNr);
00423     SetItemText(item, m_columnMap["stackNr"], wxString::Format(wxT("%d"), stackNumber));
00424     unsigned int lensNr=m_variable_groups->getLenses().getPartNumber(imgNr);
00425     SetItemText(item, m_columnMap["lensNr"], wxString::Format(wxT("%d"), lensNr));
00426 
00427     SetItemText(item, m_columnMap["maker"], wxString(img.getExifMake().c_str(), wxConvLocal));
00428     SetItemText(item, m_columnMap["model"], wxString(img.getExifModel().c_str(), wxConvLocal));
00429     SetItemText(item, m_columnMap["lens"], wxString(img.getExifLens().c_str(), wxConvLocal));
00430     struct tm exifdatetime;
00431     if(img.getExifDateTime(&exifdatetime)==0)
00432     {
00433         wxDateTime s_datetime=wxDateTime(exifdatetime);
00434         s=s_datetime.Format();
00435     }
00436     else
00437     {
00438         s = wxString(img.getExifDate().c_str(),wxConvLocal);
00439     }
00440     SetItemText(item, m_columnMap["date"], s);
00441 
00442     if(img.getExifFocalLength()>0.0)
00443     {
00444         if(img.getExifFocalLength35()>0.0)
00445         {
00446             s = wxString::Format(wxT("%0.1f mm (%0.0f mm)"),img.getExifFocalLength(),img.getExifFocalLength35());
00447         }
00448         else
00449         {
00450             s = wxString::Format(wxT("%0.1f mm"),img.getExifFocalLength());
00451         };
00452     }
00453     else
00454     {
00455         s = wxEmptyString;
00456     };
00457     SetItemText(item, m_columnMap["focallength"], s);
00458 
00459     if(img.getExifAperture()>0)
00460     {
00461         s=wxString::Format(wxT("F%.1f"),img.getExifAperture());
00462     }
00463     else
00464     {
00465         s=wxEmptyString;
00466     };
00467     SetItemText(item, m_columnMap["aperture"], s);
00468 
00469     if(img.getExifExposureTime()>0.5)
00470     {
00471         if(img.getExifExposureTime()>=1.0) 
00472         {
00473             if(img.getExifExposureTime()>=10.0) 
00474             {
00475                 s=wxString::Format(wxT("%3.0f s"),img.getExifExposureTime());
00476             }
00477             else
00478             {
00479                 s=wxString::Format(wxT("%1.1f s"),img.getExifExposureTime());
00480             }
00481         }
00482         else
00483         {
00484             s=wxString::Format(wxT("%1.2f s"),img.getExifExposureTime());
00485         }
00486     }
00487     else
00488     {
00489         if (img.getExifExposureTime() > 1e-9)
00490         {
00491             s=wxString::Format(wxT("1/%0.0f s"),1.0/img.getExifExposureTime());
00492         } 
00493         else
00494         {
00495             //Sanity
00496             s=wxT("");
00497         }
00498     }
00499     SetItemText(item, m_columnMap["time"], s);
00500 
00501     if(img.getExifISO()>0)
00502     {
00503         s=wxString::Format(wxT("%0.0f"),img.getExifISO());
00504     }
00505     else
00506     {
00507         s=wxEmptyString;
00508     };
00509     SetItemText(item, m_columnMap["iso"], s);
00510 
00511     if(m_groupMode==GROUP_STACK && img.YawisLinked())
00512     {
00513         SetItemText(item, m_columnMap["y"], wxEmptyString);
00514         SetItemText(item, m_columnMap["p"], wxEmptyString);
00515         SetItemText(item, m_columnMap["r"], wxEmptyString);
00516         SetItemText(item, m_columnMap["TrX"], wxEmptyString);
00517         SetItemText(item, m_columnMap["TrY"], wxEmptyString);
00518         SetItemText(item, m_columnMap["TrZ"], wxEmptyString);
00519         SetItemText(item, m_columnMap["Tpy"], wxEmptyString);
00520         SetItemText(item, m_columnMap["Tpp"], wxEmptyString);
00521         SetItemText(item, m_columnMap["cam_trans"], wxEmptyString);
00522     }
00523     else
00524     {
00525         SetItemText(item, m_columnMap["y"], doubleTowxString(img.getYaw(), m_degDigits));
00526         SetItemText(item, m_columnMap["p"], doubleTowxString(img.getPitch(), m_degDigits));
00527         SetItemText(item, m_columnMap["r"], doubleTowxString(img.getRoll(), m_degDigits));
00528         SetItemText(item, m_columnMap["TrX"], doubleTowxString(img.getX(), m_degDigits));
00529         SetItemText(item, m_columnMap["TrY"], doubleTowxString(img.getY(), m_degDigits));
00530         SetItemText(item, m_columnMap["TrZ"], doubleTowxString(img.getZ(), m_degDigits));
00531         SetItemText(item, m_columnMap["Tpy"], doubleTowxString(img.getTranslationPlaneYaw(), m_degDigits));
00532         SetItemText(item, m_columnMap["Tpp"], doubleTowxString(img.getTranslationPlanePitch(), m_degDigits));
00533         wxString text=_("not active");
00534         if(img.getX()!=0.0 || img.getY()!=0.0 || img.getZ()!=0.0 || img.getTranslationPlaneYaw()!=0.0 || img.getTranslationPlanePitch()!=0.0)
00535         {
00536             text=_("active");
00537         };
00538         text.Prepend(wxT(" "));
00539         SetItemText(item, m_columnMap["cam_trans"], text);
00540     };
00541 
00542     if(m_groupMode==GROUP_LENS)
00543     {
00544         SetItemText(item, m_columnMap["projection"], wxEmptyString);
00545         SetItemText(item, m_columnMap["response"], wxEmptyString);
00546     }
00547     else
00548     {
00549         SetItemText(item, m_columnMap["projection"], getProjectionString(img));
00550         SetItemText(item, m_columnMap["response"], getResponseString(img));
00551     };
00552 
00553     if(m_groupMode==GROUP_LENS && img.HFOVisLinked())
00554     {
00555         SetItemText(item, m_columnMap["v"], wxEmptyString);
00556     }
00557     else
00558     {
00559         SetItemText(item, m_columnMap["v"], doubleTowxString(img.getHFOV(), m_degDigits));
00560     };
00561 
00562     if(m_groupMode==GROUP_LENS && img.RadialDistortionisLinked())
00563     {
00564         SetItemText(item, m_columnMap["a"], wxEmptyString);
00565         SetItemText(item, m_columnMap["b"], wxEmptyString);
00566         SetItemText(item, m_columnMap["c"], wxEmptyString);
00567     }
00568     else
00569     {
00570         std::vector<double> dist=img.getRadialDistortion();
00571         SetItemText(item, m_columnMap["a"], doubleTowxString(dist[0],m_distDigits));
00572         SetItemText(item, m_columnMap["b"], doubleTowxString(dist[1],m_distDigits));
00573         SetItemText(item, m_columnMap["c"], doubleTowxString(dist[2],m_distDigits));
00574     };
00575 
00576     if(m_groupMode==GROUP_LENS && img.RadialDistortionCenterShiftisLinked())
00577     {
00578         SetItemText(item, m_columnMap["d"], wxEmptyString);
00579         SetItemText(item, m_columnMap["e"], wxEmptyString);
00580     }
00581     else
00582     {
00583         hugin_utils::FDiff2D p=img.getRadialDistortionCenterShift();
00584         SetItemText(item, m_columnMap["d"], doubleTowxString(p.x,m_pixelDigits));
00585         SetItemText(item, m_columnMap["e"], doubleTowxString(p.y,m_pixelDigits));
00586     };
00587 
00588     if(m_groupMode==GROUP_LENS && img.ShearisLinked())
00589     {
00590         SetItemText(item, m_columnMap["g"], wxEmptyString);
00591         SetItemText(item, m_columnMap["t"], wxEmptyString);
00592     }
00593     else
00594     {
00595         hugin_utils::FDiff2D p=img.getShear();
00596         SetItemText(item, m_columnMap["g"], doubleTowxString(p.x,m_distDigits));
00597         SetItemText(item, m_columnMap["t"], doubleTowxString(p.y,m_distDigits));
00598     };
00599 
00600     if(m_groupMode==GROUP_LENS && img.ExposureValueisLinked())
00601     {
00602         SetItemText(item, m_columnMap["Eev"], wxEmptyString);
00603     }
00604     else
00605     {
00606         SetItemText(item, m_columnMap["Eev"], doubleTowxString(img.getExposureValue(), m_pixelDigits));
00607     };
00608 
00609     if(m_groupMode==GROUP_LENS && img.WhiteBalanceRedisLinked())
00610     {
00611         SetItemText(item, m_columnMap["Er"], wxEmptyString);
00612     }
00613     else
00614     {
00615         SetItemText(item, m_columnMap["Er"], doubleTowxString(img.getWhiteBalanceRed(), m_pixelDigits));
00616     };
00617 
00618     if(m_groupMode==GROUP_LENS && img.WhiteBalanceBlueisLinked())
00619     {
00620         SetItemText(item, m_columnMap["Eb"], wxEmptyString);
00621     }
00622     else
00623     {
00624         SetItemText(item, m_columnMap["Eb"], doubleTowxString(img.getWhiteBalanceBlue(), m_pixelDigits));
00625     };
00626 
00627     if(m_groupMode==GROUP_LENS && img.RadialVigCorrCoeffisLinked())
00628     {
00629         SetItemText(item, m_columnMap["Vb"], wxEmptyString);
00630         SetItemText(item, m_columnMap["Vc"], wxEmptyString);
00631         SetItemText(item, m_columnMap["Vd"], wxEmptyString);
00632     }
00633     else
00634     {
00635         std::vector<double> dist=img.getRadialVigCorrCoeff();
00636         SetItemText(item, m_columnMap["Vb"], doubleTowxString(dist[1],m_distDigits));
00637         SetItemText(item, m_columnMap["Vc"], doubleTowxString(dist[2],m_distDigits));
00638         SetItemText(item, m_columnMap["Vd"], doubleTowxString(dist[3],m_distDigits));
00639     };
00640 
00641     if(m_groupMode==GROUP_LENS && img.RadialVigCorrCenterShiftisLinked())
00642     {
00643         SetItemText(item, m_columnMap["Vx"], wxEmptyString);
00644         SetItemText(item, m_columnMap["Vy"], wxEmptyString);
00645     }
00646     else
00647     {
00648         hugin_utils::FDiff2D p=img.getRadialVigCorrCenterShift();
00649         SetItemText(item, m_columnMap["Vx"], doubleTowxString(p.x,m_distDigits));
00650         SetItemText(item, m_columnMap["Vy"], doubleTowxString(p.y,m_distDigits));
00651     };
00652 
00653     if(m_groupMode==GROUP_LENS && img.EMoRParamsisLinked())
00654     {
00655         SetItemText(item, m_columnMap["Ra"], wxEmptyString);
00656         SetItemText(item, m_columnMap["Rb"], wxEmptyString);
00657         SetItemText(item, m_columnMap["Rc"], wxEmptyString);
00658         SetItemText(item, m_columnMap["Rd"], wxEmptyString);
00659         SetItemText(item, m_columnMap["Re"], wxEmptyString);
00660     }
00661     else
00662     {
00663         std::vector<float> vec=img.getEMoRParams();
00664         SetItemText(item, m_columnMap["Ra"], doubleTowxString(vec[0],m_distDigits));
00665         SetItemText(item, m_columnMap["Rb"], doubleTowxString(vec[1],m_distDigits));
00666         SetItemText(item, m_columnMap["Rc"], doubleTowxString(vec[2],m_distDigits));
00667         SetItemText(item, m_columnMap["Rd"], doubleTowxString(vec[3],m_distDigits));
00668         SetItemText(item, m_columnMap["Re"], doubleTowxString(vec[4],m_distDigits));
00669     };
00670 };
00671 
00672 void ImagesTreeCtrl::UpdateGroupText(wxTreeItemId item)
00673 {
00674     ImagesTreeData* itemData=(ImagesTreeData*)GetItemData(item);
00675     switch(m_groupMode)
00676     {
00677         case GROUP_LENS:
00678             SetItemText(item, 1, wxString::Format(_("Lens %d"),itemData->GetGroupNr()));
00679             break;
00680         case GROUP_STACK:
00681             SetItemText(item, 1, wxString::Format(_("Stack %d"),itemData->GetGroupNr()));
00682             break;
00683         case GROUP_OUTPUTSTACK:
00684             SetItemText(item, 1, wxString::Format(_("Output stack %d"),itemData->GetGroupNr()));
00685             break;
00686         case GROUP_OUTPUTLAYERS:
00687             SetItemText(item, 1, wxString::Format(_("Output exposure layer %d"),itemData->GetGroupNr()));
00688             break;
00689     };
00690     SetItemBold(item,1,true);
00691     wxTreeItemIdValue cookie;
00692     wxTreeItemId childItem=GetFirstChild(item,cookie);
00693     if(childItem.IsOk())
00694     {
00695         ImagesTreeData* data=(ImagesTreeData*)GetItemData(childItem);
00696         const SrcPanoImage& img=m_pano->getImage(data->GetImgNr());
00697 
00698         if(m_groupMode==GROUP_STACK && img.YawisLinked())
00699         {
00700             SetItemText(item, m_columnMap["y"], doubleTowxString(img.getYaw(), m_degDigits));
00701             SetItemText(item, m_columnMap["p"], doubleTowxString(img.getPitch(), m_degDigits));
00702             SetItemText(item, m_columnMap["r"], doubleTowxString(img.getRoll(), m_degDigits));
00703             SetItemText(item, m_columnMap["TrX"], doubleTowxString(img.getX(), m_degDigits));
00704             SetItemText(item, m_columnMap["TrY"], doubleTowxString(img.getY(), m_degDigits));
00705             SetItemText(item, m_columnMap["TrZ"], doubleTowxString(img.getZ(), m_degDigits));
00706             SetItemText(item, m_columnMap["Tpy"], doubleTowxString(img.getTranslationPlaneYaw(), m_degDigits));
00707             SetItemText(item, m_columnMap["Tpp"], doubleTowxString(img.getTranslationPlanePitch(), m_degDigits));
00708             wxString text=_("not active");
00709             if(img.getX()!=0.0 || img.getY()!=0.0 || img.getZ()!=0.0 || img.getTranslationPlaneYaw()!=0.0 || img.getTranslationPlanePitch()!=0.0)
00710             {
00711                 text=_("active");
00712             };
00713             text.Prepend(wxT(" "));
00714             SetItemText(item, m_columnMap["cam_trans"], text);
00715         }
00716         else
00717         {
00718             SetItemText(item, m_columnMap["y"], wxEmptyString);
00719             SetItemText(item, m_columnMap["p"], wxEmptyString);
00720             SetItemText(item, m_columnMap["r"], wxEmptyString);
00721             SetItemText(item, m_columnMap["TrX"], wxEmptyString);
00722             SetItemText(item, m_columnMap["TrY"], wxEmptyString);
00723             SetItemText(item, m_columnMap["TrZ"], wxEmptyString);
00724             SetItemText(item, m_columnMap["Tpy"], wxEmptyString);
00725             SetItemText(item, m_columnMap["Tpp"], wxEmptyString);
00726             SetItemText(item, m_columnMap["cam_trans"], wxEmptyString);
00727         };
00728 
00729         if(m_groupMode==GROUP_LENS)
00730         {
00731             SetItemText(item, m_columnMap["projection"], getProjectionString(img));
00732             SetItemText(item, m_columnMap["response"], getResponseString(img));
00733         }
00734         else
00735         {
00736             SetItemText(item, m_columnMap["projection"], wxEmptyString);
00737             SetItemText(item, m_columnMap["response"], wxEmptyString);
00738         };
00739 
00740         if(m_groupMode==GROUP_LENS && img.HFOVisLinked())
00741         {
00742             SetItemText(item, m_columnMap["v"], doubleTowxString(img.getHFOV(), m_degDigits));
00743         }
00744         else
00745         {
00746             SetItemText(item, m_columnMap["v"], wxEmptyString);
00747         };
00748 
00749         if(m_groupMode==GROUP_LENS && img.RadialDistortionisLinked())
00750         {
00751             std::vector<double> dist=img.getRadialDistortion();
00752             SetItemText(item, m_columnMap["a"], doubleTowxString(dist[0],m_distDigits));
00753             SetItemText(item, m_columnMap["b"], doubleTowxString(dist[1],m_distDigits));
00754             SetItemText(item, m_columnMap["c"], doubleTowxString(dist[2],m_distDigits));
00755         }
00756         else
00757         {
00758             SetItemText(item, m_columnMap["a"], wxEmptyString);
00759             SetItemText(item, m_columnMap["b"], wxEmptyString);
00760             SetItemText(item, m_columnMap["c"], wxEmptyString);
00761         };
00762 
00763         if(m_groupMode==GROUP_LENS && img.RadialDistortionCenterShiftisLinked())
00764         {
00765             hugin_utils::FDiff2D p=img.getRadialDistortionCenterShift();
00766             SetItemText(item, m_columnMap["d"], doubleTowxString(p.x,m_pixelDigits));
00767             SetItemText(item, m_columnMap["e"], doubleTowxString(p.y,m_pixelDigits));
00768         }
00769         else
00770         {
00771             SetItemText(item, m_columnMap["d"], wxEmptyString);
00772             SetItemText(item, m_columnMap["e"], wxEmptyString);
00773         };
00774 
00775         if(m_groupMode==GROUP_LENS && img.ShearisLinked())
00776         {
00777             hugin_utils::FDiff2D p=img.getShear();
00778             SetItemText(item, m_columnMap["g"], doubleTowxString(p.x,m_distDigits));
00779             SetItemText(item, m_columnMap["t"], doubleTowxString(p.y,m_distDigits));
00780         }
00781         else
00782         {
00783             SetItemText(item, m_columnMap["g"], wxEmptyString);
00784             SetItemText(item, m_columnMap["t"], wxEmptyString);
00785         };
00786 
00787         if(m_groupMode==GROUP_LENS && img.ExposureValueisLinked())
00788         {
00789             SetItemText(item, m_columnMap["Eev"], doubleTowxString(img.getExposureValue(), m_pixelDigits));
00790         }
00791         else
00792         {
00793             SetItemText(item, m_columnMap["Eev"], wxEmptyString);
00794         };
00795 
00796         if(m_groupMode==GROUP_LENS && img.WhiteBalanceRedisLinked())
00797         {
00798             SetItemText(item, m_columnMap["Er"], doubleTowxString(img.getWhiteBalanceRed(), m_pixelDigits));
00799         }
00800         else
00801         {
00802             SetItemText(item, m_columnMap["Er"], wxEmptyString);
00803         };
00804 
00805         if(m_groupMode==GROUP_LENS && img.WhiteBalanceBlueisLinked())
00806         {
00807             SetItemText(item, m_columnMap["Eb"], doubleTowxString(img.getWhiteBalanceBlue(), m_pixelDigits));
00808         }
00809         else
00810         {
00811             SetItemText(item, m_columnMap["Eb"], wxEmptyString);
00812         };
00813 
00814         if(m_groupMode==GROUP_LENS && img.RadialVigCorrCoeffisLinked())
00815         {
00816             std::vector<double> dist=img.getRadialVigCorrCoeff();
00817             SetItemText(item, m_columnMap["Vb"], doubleTowxString(dist[1],m_distDigits));
00818             SetItemText(item, m_columnMap["Vc"], doubleTowxString(dist[2],m_distDigits));
00819             SetItemText(item, m_columnMap["Vd"], doubleTowxString(dist[3],m_distDigits));
00820         }
00821         else
00822         {
00823             SetItemText(item, m_columnMap["Vb"], wxEmptyString);
00824             SetItemText(item, m_columnMap["Vc"], wxEmptyString);
00825             SetItemText(item, m_columnMap["Vd"], wxEmptyString);
00826         };
00827 
00828         if(m_groupMode==GROUP_LENS && img.RadialVigCorrCenterShiftisLinked())
00829         {
00830             hugin_utils::FDiff2D p=img.getRadialVigCorrCenterShift();
00831             SetItemText(item, m_columnMap["Vx"], doubleTowxString(p.x,m_distDigits));
00832             SetItemText(item, m_columnMap["Vy"], doubleTowxString(p.y,m_distDigits));
00833         }
00834         else
00835         {
00836             SetItemText(item, m_columnMap["Vx"], wxEmptyString);
00837             SetItemText(item, m_columnMap["Vy"], wxEmptyString);
00838         };
00839 
00840         if(m_groupMode==GROUP_LENS && img.EMoRParamsisLinked())
00841         {
00842             std::vector<float> vec=img.getEMoRParams();
00843             SetItemText(item, m_columnMap["Ra"], doubleTowxString(vec[0],m_distDigits));
00844             SetItemText(item, m_columnMap["Rb"], doubleTowxString(vec[1],m_distDigits));
00845             SetItemText(item, m_columnMap["Rc"], doubleTowxString(vec[2],m_distDigits));
00846             SetItemText(item, m_columnMap["Rd"], doubleTowxString(vec[3],m_distDigits));
00847             SetItemText(item, m_columnMap["Re"], doubleTowxString(vec[4],m_distDigits));
00848         }
00849         else
00850         {
00851             SetItemText(item, m_columnMap["Ra"], wxEmptyString);
00852             SetItemText(item, m_columnMap["Rb"], wxEmptyString);
00853             SetItemText(item, m_columnMap["Rc"], wxEmptyString);
00854             SetItemText(item, m_columnMap["Rd"], wxEmptyString);
00855             SetItemText(item, m_columnMap["Re"], wxEmptyString);
00856         };
00857     };
00858 };
00859 
00860 void ImagesTreeCtrl::UpdateGroup(wxTreeItemId parent, const UIntSet imgs, UIntSet& changed)
00861 {
00862     size_t nrItems=GetChildrenCount(parent,false);
00863     bool forceUpdate=false;
00864     if(nrItems!=imgs.size())
00865     {
00866         forceUpdate=true;
00867         if(nrItems<imgs.size())
00868         {
00869             for(size_t i=nrItems;i<imgs.size();i++)
00870             {
00871                 AppendItem(parent,wxEmptyString,-1,-1,new ImagesTreeData(-1));
00872             };
00873         }
00874         else
00875         {
00876             while(GetChildrenCount(parent,false)>imgs.size())
00877             {
00878                 wxTreeItemIdValue cookie;
00879                 wxTreeItemId item=GetLastChild(parent,cookie);
00880                 Delete(item);
00881             };
00882         };
00883     };
00884     //now update values
00885     wxTreeItemIdValue cookie;
00886     wxTreeItemId item=GetFirstChild(parent,cookie);
00887     UIntSet::const_iterator it=imgs.begin();
00888     while(item.IsOk())
00889     {
00890         ImagesTreeData* data=(ImagesTreeData*)GetItemData(item);
00891         if(it==imgs.end())
00892         {
00893             break;
00894         };
00895         bool needsUpdate=false;
00896         if(data->GetImgNr()!=*it)
00897         {
00898             data->SetImgNr(*it);
00899             needsUpdate=true;
00900         }
00901         else
00902         {
00903             if(set_contains(changed,*it))
00904             {
00905                 needsUpdate=true;
00906             };
00907         };
00908         if(needsUpdate || forceUpdate)
00909         {
00910             UpdateImageText(item);
00911             changed.erase(*it);
00912         };
00913         item=GetNextChild(parent, cookie);
00914         it++;
00915     };
00916 };
00917 
00918 void ImagesTreeCtrl::UpdateOptimizerVariables()
00919 {
00920     HuginBase::OptimizeVector optVec=m_pano->getOptimizeVector();
00921     wxFont font1=GetItemFont(m_root);
00922     wxFont font2(font1);
00923     font2.SetUnderlined(true);
00924     font2.SetWeight(wxFONTWEIGHT_BOLD);
00925     wxTreeItemIdValue cookie;
00926     wxTreeItemId item=GetFirstChild(m_root, cookie);
00927     while(item.IsOk())
00928     {
00929         ImagesTreeData* data=(ImagesTreeData*)GetItemData(item);
00930         UIntSet imgNrs;
00931         if(data->IsGroup())
00932         {
00933             wxTreeItemIdValue childCookie;
00934             wxTreeItemId child=GetFirstChild(item, childCookie);
00935             while(child.IsOk())
00936             {
00937                 data=(ImagesTreeData*)GetItemData(child);
00938                 imgNrs.insert(data->GetImgNr());
00939                 child=GetNextChild(item, childCookie);
00940             };
00941         }
00942         else
00943         {
00944             imgNrs.insert(data->GetImgNr());
00945         };
00946         if(imgNrs.size()>0)
00947         {
00948             for(size_t i=0;i<GetColumnCount();i++)
00949             {
00950                 if(set_contains(m_editableColumns,i))
00951                 {
00952                     bool opt=false;
00953                     for(UIntSet::const_iterator it=imgNrs.begin(); it!=imgNrs.end() && !opt;it++)
00954                     {
00955                         if(m_columnVector[i]=="cam_trans")
00956                         {
00957                             opt=set_contains(optVec[*it], "TrX") &&
00958                                 set_contains(optVec[*it], "TrY") &&
00959                                 set_contains(optVec[*it], "TrZ") &&
00960                                 set_contains(optVec[*it], "Tpy") &&
00961                                 set_contains(optVec[*it], "Tpp");
00962                         }
00963                         else
00964                         {
00965                             opt=set_contains(optVec[*it], m_columnVector[i]);
00966                         };
00967                     };
00968                     if(opt)
00969                     {
00970                         SetItemFont(item,i,font2);
00971                     }
00972                     else
00973                     {
00974                         SetItemFont(item,i,font1);
00975                     };
00976                 };
00977             };
00978         };
00979         item=GetNext(item);
00980     };
00981 };
00982 
00983 HuginBase::UIntSet ImagesTreeCtrl::GetSelectedImages()
00984 {
00985     wxArrayTreeItemIds selected;
00986     UIntSet imgs;
00987     if(GetSelections (selected)>0)
00988     {
00989         for(size_t i=0;i<selected.size();i++)
00990         {
00991             ImagesTreeData* data=(ImagesTreeData*)GetItemData(selected[i]);
00992             if(data->IsGroup())
00993             {
00994                 wxTreeItemIdValue cookie;
00995                 wxTreeItemId item=GetFirstChild(selected[i],cookie);
00996                 while(item.IsOk())
00997                 {
00998                     data=(ImagesTreeData*)GetItemData(item);
00999                     imgs.insert(data->GetImgNr());
01000                     item=GetNextChild(selected[i], cookie);
01001                 };
01002             }
01003             else
01004             {
01005                 imgs.insert(data->GetImgNr());
01006             };
01007         };
01008     }
01009     return imgs;
01010 };
01011 
01012 void ImagesTreeCtrl::OnColumnWidthChange( wxListEvent & e )
01013 {
01014     if(m_configClassName != wxT(""))
01015     {
01016         int colNum = e.GetColumn();
01017         wxConfigBase::Get()->Write( m_configClassName+wxString::Format(wxT("/ColumnWidth%d"),colNum), GetColumnWidth(colNum) );
01018     }
01019 }
01020 
01021 void ImagesTreeCtrl::SetGuiLevel(GuiLevel newSetting)
01022 {
01023     m_guiLevel=newSetting;
01024     //update visible column
01025     SetDisplayMode(m_displayMode);
01026 };
01027 
01028 void ImagesTreeCtrl::SetOptimizerMode()
01029 {
01030     m_optimizerMode=true;
01031     for(UIntSet::const_iterator it=m_editableColumns.begin(); it!=m_editableColumns.end(); it++)
01032     {
01033         if(m_columnVector[*it]!="cam_trans")
01034         {
01035             SetColumnEditable(*it,true);
01036         };
01037     };
01038 };
01039 
01040 void ImagesTreeCtrl::SetGroupMode(GroupMode newGroup)
01041 {
01042     if(newGroup!=m_groupMode)
01043     {
01044         m_groupMode=newGroup;
01045         if(m_groupMode==GROUP_NONE)
01046         {
01047             SetWindowStyle(GetWindowStyle() | wxTR_NO_LINES);
01048         }
01049         else
01050         {
01051             SetWindowStyle(GetWindowStyle() & ~wxTR_NO_LINES);
01052         };
01053         DeleteChildren(m_root);
01054         UIntSet imgs;
01055         if(m_pano->getNrOfImages()>0)
01056         {
01057             fill_set(imgs,0,m_pano->getNrOfImages()-1);
01058         };
01059         panoramaImagesChanged(*m_pano,imgs);
01060         ExpandAll(m_root);
01061     };
01062 };
01063 
01064 void ImagesTreeCtrl::SetDisplayMode(DisplayMode newMode)
01065 {
01066     m_displayMode=newMode;
01067 
01068     SetColumnShown(m_columnMap["width"], m_displayMode==DISPLAY_GENERAL);
01069     SetColumnShown(m_columnMap["height"], m_displayMode==DISPLAY_GENERAL);
01070     SetColumnShown(m_columnMap["anchor"], m_displayMode==DISPLAY_GENERAL);
01071     SetColumnShown(m_columnMap["cps"], m_displayMode==DISPLAY_GENERAL);
01072     SetColumnShown(m_columnMap["lensNr"], m_displayMode==DISPLAY_GENERAL);
01073     SetColumnShown(m_columnMap["stackNr"], m_displayMode==DISPLAY_GENERAL && m_guiLevel>=GUI_ADVANCED);
01074 
01075     SetColumnShown(m_columnMap["maker"], m_displayMode==DISPLAY_EXIF);
01076     SetColumnShown(m_columnMap["model"], m_displayMode==DISPLAY_EXIF);
01077     SetColumnShown(m_columnMap["lens"], m_displayMode==DISPLAY_EXIF);
01078     SetColumnShown(m_columnMap["date"], m_displayMode==DISPLAY_EXIF);
01079     SetColumnShown(m_columnMap["focallength"], m_displayMode==DISPLAY_EXIF);
01080     SetColumnShown(m_columnMap["aperture"], m_displayMode==DISPLAY_EXIF);
01081     SetColumnShown(m_columnMap["time"], m_displayMode==DISPLAY_EXIF);
01082     SetColumnShown(m_columnMap["iso"], m_displayMode==DISPLAY_EXIF);
01083 
01084     SetColumnShown(m_columnMap["y"], m_displayMode==DISPLAY_POSITION);
01085     SetColumnShown(m_columnMap["p"], m_displayMode==DISPLAY_POSITION);
01086     SetColumnShown(m_columnMap["r"], m_displayMode==DISPLAY_POSITION);
01087     SetColumnShown(m_columnMap["TrX"], m_displayMode==DISPLAY_POSITION && m_guiLevel==GUI_EXPERT);
01088     SetColumnShown(m_columnMap["TrY"], m_displayMode==DISPLAY_POSITION && m_guiLevel==GUI_EXPERT);
01089     SetColumnShown(m_columnMap["TrZ"], m_displayMode==DISPLAY_POSITION && m_guiLevel==GUI_EXPERT);
01090     SetColumnShown(m_columnMap["Tpy"], m_displayMode==DISPLAY_POSITION && m_guiLevel==GUI_EXPERT);
01091     SetColumnShown(m_columnMap["Tpp"], m_displayMode==DISPLAY_POSITION && m_guiLevel==GUI_EXPERT);
01092     SetColumnShown(m_columnMap["cam_trans"], m_displayMode==DISPLAY_POSITION && m_guiLevel==GUI_EXPERT);
01093 
01094     SetColumnShown(m_columnMap["projection"], m_displayMode==DISPLAY_LENS);
01095     SetColumnShown(m_columnMap["v"], m_displayMode==DISPLAY_LENS);
01096     SetColumnShown(m_columnMap["a"], m_displayMode==DISPLAY_LENS);
01097     SetColumnShown(m_columnMap["b"], m_displayMode==DISPLAY_LENS);
01098     SetColumnShown(m_columnMap["c"], m_displayMode==DISPLAY_LENS);
01099     SetColumnShown(m_columnMap["d"], m_displayMode==DISPLAY_LENS);
01100     SetColumnShown(m_columnMap["e"], m_displayMode==DISPLAY_LENS);
01101     SetColumnShown(m_columnMap["g"], m_displayMode==DISPLAY_LENS && m_guiLevel>=GUI_EXPERT);
01102     SetColumnShown(m_columnMap["t"], m_displayMode==DISPLAY_LENS && m_guiLevel>=GUI_EXPERT);
01103 
01104     SetColumnShown(m_columnMap["Eev"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_IMAGES);
01105     SetColumnShown(m_columnMap["Er"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_IMAGES);
01106     SetColumnShown(m_columnMap["Eb"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_IMAGES);
01107     SetColumnShown(m_columnMap["Vb"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES);
01108     SetColumnShown(m_columnMap["Vc"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES);
01109     SetColumnShown(m_columnMap["Vd"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES);
01110     SetColumnShown(m_columnMap["Vx"], (m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES) && m_guiLevel>=GUI_ADVANCED);
01111     SetColumnShown(m_columnMap["Vy"], (m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES) && m_guiLevel>=GUI_ADVANCED);
01112     SetColumnShown(m_columnMap["response"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES);
01113     SetColumnShown(m_columnMap["Ra"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES);
01114     SetColumnShown(m_columnMap["Rb"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES);
01115     SetColumnShown(m_columnMap["Rc"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES);
01116     SetColumnShown(m_columnMap["Rd"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES);
01117     SetColumnShown(m_columnMap["Re"], m_displayMode==DISPLAY_PHOTOMETRICS || m_displayMode==DISPLAY_PHOTOMETRICS_LENSES);
01118 
01119     Refresh();
01120 };
01121 
01122 void ImagesTreeCtrl::OnContextMenu(wxTreeEvent & e)
01123 {
01124     m_selectedColumn=e.GetInt();
01125     wxMenu menu;
01126     bool allowMenuExtension=true;
01127     if(e.GetItem().IsOk())
01128     {
01129         //click on item
01130         if(set_contains(m_editableColumns,m_selectedColumn))
01131         {
01132             bool emptyText=GetItemText(e.GetItem(),m_selectedColumn).IsEmpty();
01133             ImagesTreeData* data=(ImagesTreeData*)GetItemData(e.GetItem());
01134             if((m_groupMode==GROUP_LENS && m_variableVector[m_selectedColumn]!=HuginBase::ImageVariableGroup::IVE_Yaw) ||
01135                (m_groupMode==GROUP_STACK && m_variableVector[m_selectedColumn]==HuginBase::ImageVariableGroup::IVE_Yaw) )
01136             {
01137                 if(data->IsGroup())
01138                 {
01139                     if(emptyText)
01140                     {
01141                         menu.Append(ID_LINK,_("Link"));
01142                     }
01143                     else
01144                     {
01145                         menu.Append(ID_UNLINK, _("Unlink"));
01146                     };
01147                 }
01148                 else
01149                 {
01150                     if(emptyText)
01151                     {
01152                         menu.Append(ID_UNLINK,_("Unlink"));
01153                     }
01154                     else
01155                     {
01156                         menu.Append(ID_LINK, _("Link"));
01157                     };
01158                 };
01159                 menu.AppendSeparator();
01160             };
01161             if(m_optimizerMode)
01162             {
01163                 if(data->IsGroup() == emptyText)
01164                 {
01165                     if(m_groupMode==GROUP_LENS && m_variableVector[m_selectedColumn]!=HuginBase::ImageVariableGroup::IVE_Yaw)
01166                     {
01167                         menu.Append(ID_SELECT_LENS_STACK, _("Select all for current lens"));
01168                         menu.Append(ID_UNSELECT_LENS_STACK, _("Unselect all for current lens"));
01169                     };
01170                     if(m_groupMode==GROUP_STACK && m_variableVector[m_selectedColumn]==HuginBase::ImageVariableGroup::IVE_Yaw)
01171                     {
01172                         menu.Append(ID_SELECT_LENS_STACK, _("Select all for current stack"));
01173                         menu.Append(ID_UNSELECT_LENS_STACK, _("Unselect all for current stack"));
01174                     };
01175                 };
01176                 if(m_columnVector[m_selectedColumn]!="cam_trans")
01177                 {
01178                     menu.Append(ID_SELECT_ALL, _("Select all"));
01179                 };
01180                 menu.Append(ID_UNSELECT_ALL, _("Unselect all"));
01181                 menu.AppendSeparator();
01182             }
01183         };
01184         menu.Append(ID_EDIT, _("Edit image variables..."));
01185     }
01186     else
01187     {
01188         if(m_optimizerMode && set_contains(m_editableColumns, e.GetInt()))
01189         {
01190             if(m_columnVector[m_selectedColumn]!="cam_trans")
01191             {
01192                 menu.Append(ID_SELECT_ALL, _("Select all"));
01193             };
01194             menu.Append(ID_UNSELECT_ALL, _("Unselect all"));
01195             allowMenuExtension=false;
01196         }
01197     };
01198     if(allowMenuExtension)
01199     {
01200         if(menu.GetMenuItemCount()>0)
01201         {
01202             menu.AppendSeparator();
01203         };
01204         int id=ID_OPERATION_START;
01205         m_menuOperation.clear();
01206         GenerateSubMenu(&menu, PanoOperation::GetImagesOperationVector(), id);
01207         wxMenu* subMenu=new wxMenu();
01208         GenerateSubMenu(subMenu, PanoOperation::GetLensesOperationVector(), id);
01209         if(subMenu->GetMenuItemCount()>0)
01210         {
01211             menu.Append(-1,_("Lens"), subMenu);
01212         }
01213         else
01214         {
01215             delete subMenu;
01216         };
01217         if(m_guiLevel>GUI_SIMPLE)
01218         {
01219             subMenu=new wxMenu();
01220             GenerateSubMenu(subMenu, PanoOperation::GetStacksOperationVector(), id);
01221             if(subMenu->GetMenuItemCount()>0)
01222             {
01223                 menu.Append(-1,_("Stacks"), subMenu);
01224             }
01225             else
01226             {
01227                 delete subMenu;
01228             };
01229         };
01230         subMenu=new wxMenu();
01231         GenerateSubMenu(subMenu, PanoOperation::GetControlPointsOperationVector(), id);
01232         if(subMenu->GetMenuItemCount()>0)
01233         {
01234             menu.Append(-1, _("Control points"), subMenu);
01235         }
01236         else
01237         {
01238             delete subMenu;
01239         };
01240         subMenu=new wxMenu();
01241         GenerateSubMenu(subMenu, PanoOperation::GetResetOperationVector(), id);
01242         if(subMenu->GetMenuItemCount()>0)
01243         {
01244             menu.Append(-1, _("Reset"), subMenu);
01245         }
01246         else
01247         {
01248             delete subMenu;
01249         };
01250     };
01251     if(menu.GetMenuItemCount()>0)
01252     {
01253         PopupMenu(&menu);
01254     };
01255     e.Skip();
01256 };
01257 
01258 void ImagesTreeCtrl::GenerateSubMenu(wxMenu* menu, PanoOperation::PanoOperationVector* operations, int& id)
01259 {
01260     UIntSet imgs=GetSelectedImages();
01261     for(size_t i=0; i<operations->size(); i++)
01262     {
01263         if((*operations)[i]->IsEnabled(*m_pano, imgs, m_guiLevel))
01264         {
01265             menu->Append(id, (*operations)[i]->GetLabel());
01266             m_menuOperation[id]=(*operations)[i];
01267             id++;
01268         }
01269     };
01270 };
01271 
01272 void ImagesTreeCtrl::OnHeaderContextMenu(wxListEvent & e)
01273 {
01274     m_selectedColumn=e.GetColumn();
01275     wxMenu menu;
01276     if(m_optimizerMode && set_contains(m_editableColumns, m_selectedColumn))
01277     {
01278         menu.Append(ID_SELECT_ALL, _("Select all"));
01279         menu.Append(ID_UNSELECT_ALL, _("Unselect all"));
01280         PopupMenu(&menu);
01281     };
01282     e.Skip();
01283 };
01284 
01285 void ImagesTreeCtrl::UnLinkImageVariables(bool linked)
01286 {
01287     UIntSet images=GetSelectedImages();
01288     if(images.size()>0 && m_variableVector[m_selectedColumn]!=HuginBase::ImageVariableGroup::IVE_Filename)
01289     {
01290         std::set<HuginBase::ImageVariableGroup::ImageVariableEnum> variables;
01291         variables.insert(m_variableVector[m_selectedColumn]);
01292         if(m_variableVector[m_selectedColumn]==HuginBase::ImageVariableGroup::IVE_Yaw)
01293         {
01294             variables.insert(HuginBase::ImageVariableGroup::IVE_Pitch);
01295             variables.insert(HuginBase::ImageVariableGroup::IVE_Roll);
01296             variables.insert(HuginBase::ImageVariableGroup::IVE_X);
01297             variables.insert(HuginBase::ImageVariableGroup::IVE_Y);
01298             variables.insert(HuginBase::ImageVariableGroup::IVE_Z);
01299             variables.insert(HuginBase::ImageVariableGroup::IVE_TranslationPlaneYaw);
01300             variables.insert(HuginBase::ImageVariableGroup::IVE_TranslationPlanePitch);
01301         };
01302         if(m_groupMode==GROUP_LENS)
01303         {
01304             GlobalCmdHist::getInstance().addCommand(
01305                 new PT::ChangePartImagesLinkingCmd(*m_pano, images, variables, linked, HuginBase::StandardImageVariableGroups::getLensVariables())
01306             );
01307         }
01308         else
01309         {
01310             GlobalCmdHist::getInstance().addCommand(
01311                 new PT::ChangePartImagesLinkingCmd(*m_pano, images, variables, linked, HuginBase::StandardImageVariableGroups::getStackVariables())
01312             );
01313         };
01314     };
01315 };
01316 
01317 void ImagesTreeCtrl::OnLinkImageVariables(wxCommandEvent &e)
01318 {
01319     UnLinkImageVariables(true);
01320 };
01321 
01322 void ImagesTreeCtrl::OnUnlinkImageVariables(wxCommandEvent &e)
01323 {
01324     UnLinkImageVariables(false);
01325 };
01326 
01327 void ImagesTreeCtrl::OnEditImageVariables(wxCommandEvent &e)
01328 {
01329     UIntSet imgs=GetSelectedImages();
01330     if(imgs.size()>0)
01331     {
01332         ImageVariableDialog dlg(this, m_pano, imgs);
01333         dlg.SetGuiLevel(m_guiLevel);
01334         switch(m_displayMode)
01335         {
01336             case DISPLAY_LENS:
01337                 dlg.SelectTab(1);
01338                 break;
01339             case DISPLAY_PHOTOMETRICS:
01340             case DISPLAY_PHOTOMETRICS_IMAGES:
01341             case DISPLAY_PHOTOMETRICS_LENSES:
01342                 if(m_selectedColumn==m_columnMap["response"] ||
01343                     m_selectedColumn==m_columnMap["Ra"] ||
01344                     m_selectedColumn==m_columnMap["Rb"] ||
01345                     m_selectedColumn==m_columnMap["Rc"] ||
01346                     m_selectedColumn==m_columnMap["Rd"] ||
01347                     m_selectedColumn==m_columnMap["Re"] )
01348                 {
01349                     dlg.SelectTab(3);
01350                 }
01351                 else
01352                 {
01353                     dlg.SelectTab(2);
01354                 };
01355                 break;
01356             default:
01357                 break;
01358         };
01359         dlg.ShowModal();
01360     };
01361 };
01362 
01363 void ImagesTreeCtrl::OnBeginDrag(wxTreeEvent &e)
01364 {
01365 #if wxCHECK_VERSION(2,9,4)
01366     bool ctrlPressed=wxGetKeyState(WXK_COMMAND);
01367 #else
01368     bool ctrlPressed=wxGetKeyState(WXK_CONTROL);
01369 #endif
01370     if(m_pano->getNrOfImages()>0 && !m_dragging)
01371     {
01372         m_draggingImages=GetSelectedImages();
01373         if(m_draggingImages.size()>0)
01374         {
01375             if((m_groupMode==GROUP_NONE && m_draggingImages.size()==1 && !ctrlPressed) ||
01376                 m_groupMode==GROUP_LENS || m_groupMode==GROUP_STACK)
01377             {
01378                 e.Allow();
01379                 SetCursor(wxCURSOR_HAND);
01380                 m_dragging=true;
01381             };
01382         };
01383     };
01384 };
01385 
01386 void ImagesTreeCtrl::OnEndDrag(wxMouseEvent &e)
01387 {
01388     //we can't use wxEVT_TREE_END_DRAG because this event is fire several times, e.g. when
01389     // the mouse leaves the area of the tree
01390     // so we are listing to left mouse up, as described in documentation
01391     if(m_dragging)
01392     {
01393         SetCursor(wxCURSOR_ARROW);
01394         m_dragging=false;
01395         wxTreeItemId item=HitTest(e.GetPosition());
01396         if(m_groupMode==GROUP_NONE)
01397         {
01398             size_t img1=*m_draggingImages.begin();
01399             size_t img2=-1;
01400             if(item.IsOk())
01401             {
01402                 ImagesTreeData* data=(ImagesTreeData*)GetItemData(item);
01403                 img2=data->GetImgNr();
01404             }
01405             else
01406             {
01407                 //we are checking the points above, if we find then
01408                 // an item, the user drop it below the last item, if not
01409                 // the drop happened right beside the item
01410                 wxPoint pos(e.GetPosition());
01411                 pos.y-=10;
01412                 while(pos.y>0)
01413                 {
01414                     item=HitTest(pos);
01415                     if(item.IsOk())
01416                     {
01417                         img2=m_pano->getNrOfImages()-1;
01418                         break;
01419                     };
01420                     pos.y-=10;
01421                 };
01422             };
01423             if(img2!=-1)
01424             {
01425                 if(img1!=img2)
01426                 {
01427                     GlobalCmdHist::getInstance().addCommand(
01428                         new PT::MoveImageCmd(*m_pano, img1, img2)
01429                     );
01430                 };
01431             };
01432         }
01433         else
01434         {
01435             //dragging to stack/lenses
01436             if(item.IsOk())
01437             {
01438                 ImagesTreeData* data=(ImagesTreeData*)GetItemData(item);
01439                 long groupNr=-1;
01440                 if(data->IsGroup())
01441                 {
01442                     groupNr=data->GetGroupNr();
01443                 }
01444                 else
01445                 {
01446                     item=GetItemParent(item);
01447                     if(item.IsOk())
01448                     {
01449                         data=(ImagesTreeData*)GetItemData(item);
01450                         groupNr=data->GetGroupNr();
01451                     };
01452                 };
01453                 if(groupNr>=0)
01454                 {
01455                     if(m_groupMode==GROUP_LENS)
01456                     {
01457                         GlobalCmdHist::getInstance().addCommand(
01458                             new PT::ChangePartNumberCmd(*m_pano, m_draggingImages, groupNr, HuginBase::StandardImageVariableGroups::getLensVariables())
01459                         );
01460                     }
01461                     else
01462                     {
01463                         GlobalCmdHist::getInstance().addCommand(
01464                             new PT::ChangePartNumberCmd(*m_pano, m_draggingImages, groupNr, HuginBase::StandardImageVariableGroups::getStackVariables())
01465                         );
01466                     };
01467                 };
01468             }
01469             else // item not ok, drop not on existing item, create new lens/stack
01470             {
01471                 if(m_groupMode==GROUP_LENS)
01472                 {
01473                     GlobalCmdHist::getInstance().addCommand(
01474                         new PT::NewPartCmd(*m_pano, m_draggingImages, HuginBase::StandardImageVariableGroups::getLensVariables())
01475                     );
01476                 }
01477                 else
01478                 {
01479                     GlobalCmdHist::getInstance().addCommand(
01480                         new PT::NewPartCmd(*m_pano, m_draggingImages, HuginBase::StandardImageVariableGroups::getStackVariables())
01481                     );
01482                 }
01483             };
01484         }
01485         m_draggingImages.clear();
01486     }
01487     else
01488     {
01489         e.Skip();
01490     };
01491 };
01492 
01493 void ImagesTreeCtrl::OnLeftDown(wxMouseEvent &e)
01494 {
01495     if(!m_dragging && m_optimizerMode)
01496     {
01497         if(e.LeftDown() && e.CmdDown())
01498         {
01499             int flags;
01500             int col;
01501             wxTreeItemId item=HitTest(e.GetPosition(),flags,col);
01502             if(item.IsOk())
01503             {
01504                 if(set_contains(m_editableColumns, col))
01505                 {
01506                     if(!GetItemText(item, col).IsEmpty())
01507                     {
01508                         HuginBase::UIntSet imgs;
01509                         ImagesTreeData* data=(ImagesTreeData*)GetItemData(item);
01510                         if(data->IsGroup())
01511                         {
01512                             wxTreeItemIdValue cookie;
01513                             wxTreeItemId childItem=GetFirstChild(item,cookie);
01514                             while(childItem.IsOk())
01515                             {
01516                                 data=(ImagesTreeData*)GetItemData(childItem);
01517                                 imgs.insert(data->GetImgNr());
01518                                 childItem=GetNextChild(item, cookie);
01519                             };
01520                         }
01521                         else
01522                         {
01523                             imgs.insert(data->GetImgNr());
01524                         };
01525                         HuginBase::OptimizeVector optVec=m_pano->getOptimizeVector();
01526                         std::set<std::string> var;
01527                         if(m_columnVector[col]=="cam_trans")
01528                         {
01529                             var.insert("TrX");
01530                             var.insert("TrY");
01531                             var.insert("TrZ");
01532                             var.insert("Tpy");
01533                             var.insert("Tpp");
01534                         }
01535                         else
01536                         {
01537                             var.insert(m_columnVector[col]);
01538                             if(m_columnVector[col]=="Tpy" || m_columnVector[col]=="Tpp")
01539                             {
01540                                 var.insert("Tpy");
01541                                 var.insert("Tpp");
01542                             };
01543                             if(m_columnVector[col]=="Vb" || m_columnVector[col]=="Vc" || m_columnVector[col]=="Vd")
01544                             {
01545                                 var.insert("Vb");
01546                                 var.insert("Vc");
01547                                 var.insert("Vd");
01548                             };
01549                             if(m_columnVector[col]=="Vx" || m_columnVector[col]=="Vy")
01550                             {
01551                                 var.insert("Vx");
01552                                 var.insert("Vy");
01553                             };
01554                             if(m_columnVector[col]=="Ra" || m_columnVector[col]=="Rb" || m_columnVector[col]=="Rc" || 
01555                                m_columnVector[col]=="Rd" || m_columnVector[col]=="Re")
01556                             {
01557                                 var.insert("Ra");
01558                                 var.insert("Rb");
01559                                 var.insert("Rc");
01560                                 var.insert("Rd");
01561                                 var.insert("Re");
01562                             };
01563                         };
01564                         bool deactivate=false;
01565                         for(std::set<std::string>::const_iterator varIt=var.begin(); varIt!=var.end(); varIt++)
01566                         {
01567                             //search, if image variable is marked for optimise for at least one image of group
01568                             for(HuginBase::UIntSet::const_iterator imgIt=imgs.begin(); imgIt!=imgs.end() && !deactivate; imgIt++)
01569                             {
01570                                 if(set_contains(optVec[*imgIt], *varIt))
01571                                 {
01572                                     deactivate=true;
01573                                 };
01574                             };
01575                         };
01576                         // now deactivate or activate the image variable for optimisation
01577                         if(deactivate)
01578                         {
01579                             for(std::set<std::string>::const_iterator varIt=var.begin(); varIt!=var.end(); varIt++)
01580                             {
01581                                 for(HuginBase::UIntSet::const_iterator imgIt=imgs.begin(); imgIt!=imgs.end(); imgIt++)
01582                                 {
01583                                     optVec[*imgIt].erase(*varIt);
01584                                 };
01585                             }
01586                         }
01587                         else
01588                         {
01589                             for(std::set<std::string>::const_iterator varIt=var.begin(); varIt!=var.end(); varIt++)
01590                             {
01591                                 for(HuginBase::UIntSet::const_iterator imgIt=imgs.begin(); imgIt!=imgs.end(); imgIt++)
01592                                 {
01593                                     optVec[*imgIt].insert(*varIt);
01594                                 };
01595                             };
01596                         };
01597                         GlobalCmdHist::getInstance().addCommand(
01598                             new PT::UpdateOptimizeVectorCmd(*m_pano, optVec)
01599                         );
01600                         return;
01601                     };
01602                 };
01603             };
01604         };
01605     };
01606     e.Skip();
01607 };
01608 
01609 void ImagesTreeCtrl::SelectAllParameters(bool select, bool allImages)
01610 {
01611     std::set<std::string> imgVars;
01612     std::string var=m_columnVector[m_selectedColumn];
01613     if(var=="cam_trans")
01614     {
01615         imgVars.insert("TrX");
01616         imgVars.insert("TrY");
01617         imgVars.insert("TrZ");
01618         imgVars.insert("Tpy");
01619         imgVars.insert("Tpp");
01620     }
01621     else
01622     {
01623         imgVars.insert(var);
01624         if(var=="Vb" || var=="Vc" || var=="Vd")
01625         {
01626             imgVars.insert("Vb");
01627             imgVars.insert("Vc");
01628             imgVars.insert("Vd");
01629         };
01630         if(var=="Vx" || var=="Vy")
01631         {
01632             imgVars.insert("Vx");
01633             imgVars.insert("Vy");
01634         };
01635         if(var=="Ra" || var=="Rb" || var=="Rc" || var=="Rd" || var=="Re")
01636         {
01637             imgVars.insert("Ra");
01638             imgVars.insert("Rb");
01639             imgVars.insert("Rc");
01640             imgVars.insert("Rd");
01641             imgVars.insert("Re");
01642         };
01643 
01644     };
01645 
01646     UIntSet imgs;
01647     if(allImages)
01648     {
01649         fill_set(imgs, 0, m_pano->getNrOfImages()-1);
01650     }
01651     else
01652     {
01653         wxArrayTreeItemIds selectedItem;
01654         if(GetSelections(selectedItem)>0)
01655         {
01656             for(size_t i=0;i<selectedItem.size();i++)
01657             {
01658                 ImagesTreeData* data=(ImagesTreeData*)GetItemData(selectedItem[i]);
01659                 wxTreeItemId startItem;
01660                 if(data->IsGroup())
01661                 {
01662                     startItem=selectedItem[i];
01663                 }
01664                 else
01665                 {
01666                     startItem=GetItemParent(selectedItem[i]);
01667                 };
01668                 wxTreeItemIdValue cookie;
01669                 wxTreeItemId item=GetFirstChild(startItem,cookie);
01670                 while(item.IsOk())
01671                 {
01672                     data=(ImagesTreeData*)GetItemData(item);
01673                     imgs.insert(data->GetImgNr());
01674                     item=GetNextChild(startItem, cookie);
01675                 };
01676             };
01677         };
01678     };
01679 
01680     OptimizeVector optVec=m_pano->getOptimizeVector();
01681     for(UIntSet::iterator img=imgs.begin(); img!=imgs.end(); img++)
01682     {
01683         for(std::set<std::string>::const_iterator it=imgVars.begin(); it!=imgVars.end(); it++)
01684         {
01685             if(select)
01686             {
01687                 if((*it=="y" || *it=="p" || *it=="r" || *it=="TrX" || *it=="TrY" || *it=="TrZ" || *it=="Tpy" || *it=="Tpp") && 
01688                     *img==m_pano->getOptions().optimizeReferenceImage)
01689                 {
01690                     optVec[*img].erase(*it);
01691                     continue;
01692                 };
01693                 if((*it=="Eev" || *it=="Er" || *it=="Eb") && *img==m_pano->getOptions().colorReferenceImage)
01694                 {
01695                     optVec[*img].erase(*it);
01696                     continue;
01697                 };
01698                 optVec[*img].insert(*it);
01699             }
01700             else
01701             {
01702                 optVec[*img].erase(*it);
01703             };
01704         };
01705     };
01706     GlobalCmdHist::getInstance().addCommand(
01707         new PT::UpdateOptimizeVectorCmd(*m_pano, optVec)
01708     );
01709 };
01710 
01711 void ImagesTreeCtrl::OnSelectAll(wxCommandEvent &e)
01712 {
01713     SelectAllParameters(true, true);
01714 };
01715 
01716 void ImagesTreeCtrl::OnUnselectAll(wxCommandEvent &e)
01717 {
01718     SelectAllParameters(false, true);
01719 };
01720 
01721 void ImagesTreeCtrl::OnSelectLensStack(wxCommandEvent &e)
01722 {
01723     SelectAllParameters(true, false);
01724 };
01725 
01726 void ImagesTreeCtrl::OnUnselectLensStack(wxCommandEvent &e)
01727 {
01728     SelectAllParameters(false, false);
01729 };
01730 
01731 void ImagesTreeCtrl::OnChar(wxTreeEvent &e)
01732 {
01733     switch(e.GetKeyCode())
01734     {
01735         case WXK_INSERT:
01736             {
01737                 wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, XRCID("action_add_images"));
01738                 MainFrame::Get()->GetEventHandler()->AddPendingEvent(ev);
01739                 break;
01740             };
01741         case WXK_DELETE:
01742             {
01743                 HuginBase::UIntSet imgs=GetSelectedImages();
01744                 if(imgs.size()>0)
01745                 {
01746                     GlobalCmdHist::getInstance().addCommand(
01747                         new PT::RemoveImagesCmd(*m_pano, imgs)
01748                     );
01749                 };
01750                 break;
01751             };
01752         case 1: //Ctrl+A
01753             {
01754                 SelectAll();
01755                 break;
01756             }
01757         default:
01758             e.Skip();
01759     };
01760 };
01761 
01762 void ImagesTreeCtrl::OnBeginEdit(wxTreeEvent &e)
01763 {
01764     m_editOldString=GetItemText(e.GetItem(), e.GetInt());
01765     if(m_editOldString.IsEmpty())
01766     {
01767         e.Veto();
01768     }
01769     else
01770     {
01771         ImagesTreeData* data=(ImagesTreeData*)GetItemData(e.GetItem());
01772         if(data->IsGroup())
01773         {
01774             wxTreeItemIdValue cookie;
01775             wxTreeItemId item=GetFirstChild(e.GetItem(), cookie);
01776             data=(ImagesTreeData*)GetItemData(item);
01777         };
01778         m_editVal=m_pano->getImage(data->GetImgNr()).getVar(m_columnVector[e.GetInt()]);
01779         SetItemText(e.GetItem(), e.GetInt(), doubleTowxString(m_editVal));
01780         e.Allow();
01781     };
01782 };
01783 
01784 void ImagesTreeCtrl::OnEndEdit(wxTreeEvent &e)
01785 {
01786     if(e.IsEditCancelled())
01787     {
01788         //restore old string
01789         SetItemText(e.GetItem(), e.GetInt(), m_editOldString);
01790         Refresh();
01791     }
01792     else
01793     {
01794         double val;
01795         if(!str2double(e.GetLabel(),val))
01796         {
01797             //restore old string
01798             SetItemText(e.GetItem(), e.GetInt(), m_editOldString);
01799             Refresh();
01800             e.Veto();
01801         }
01802         else
01803         {
01804             //only update if value was changed
01805             if(val!=m_editVal)
01806             {
01807                 ImagesTreeData* data=(ImagesTreeData*)GetItemData(e.GetItem());
01808                 if(data->IsGroup())
01809                 {
01810                     wxTreeItemIdValue cookie;
01811                     wxTreeItemId item=GetFirstChild(e.GetItem(), cookie);
01812                     data=(ImagesTreeData*)GetItemData(item);
01813                 };
01814                 UIntSet imgs;
01815                 imgs.insert(data->GetImgNr());
01816                 if(m_columnVector[e.GetInt()]=="v")
01817                 {
01818                     if(m_pano->getImage(data->GetImgNr()).getProjection()==SrcPanoImage::FISHEYE_ORTHOGRAPHIC && val>190)
01819                     {
01820                         if(wxMessageBox(
01821                             wxString::Format(_("You have given a field of view of %.2f degrees.\n But the orthographic projection is limited to a field of view of 180 degress.\nDo you want still use that high value?"), val),
01822 #ifdef __WXMSW__
01823                             _("Hugin"),
01824 #else
01825                             wxT(""),
01826 #endif
01827                             wxICON_EXCLAMATION | wxYES_NO)==wxNO)
01828                         {
01829                             //restore old string
01830                             SetItemText(e.GetItem(), e.GetInt(), m_editOldString);
01831                             Refresh();
01832                             e.Veto();
01833                             e.Skip();
01834                             return;
01835                         };
01836                     };
01837                 };
01838                 Variable var(m_columnVector[e.GetInt()], val);
01839                 GlobalCmdHist::getInstance().addCommand(
01840                     new PT::SetVariableCmd(*m_pano, imgs, var)
01841                 );
01842                 //we need to veto the event otherwise the internal
01843                 //function does update the text to the full number
01844                 e.Veto();
01845             }
01846             else
01847             {
01848                 //restore old string
01849                 SetItemText(e.GetItem(), e.GetInt(), m_editOldString);
01850                 Refresh();
01851             };
01852         };
01853     };
01854     e.Skip();
01855 };
01856 
01857 void ImagesTreeCtrl::OnExecuteOperation(wxCommandEvent & e)
01858 {
01859     PanoOperation::PanoOperation* op=m_menuOperation[e.GetId()];
01860     PT::PanoCommand* cmd=op->GetCommand(this,*m_pano, GetSelectedImages(), m_guiLevel);
01861     if(cmd!=NULL)
01862     {
01863         GlobalCmdHist::getInstance().addCommand(cmd);
01864     };
01865 };
01866 
01867 void ImagesTreeCtrl::OnLeftDblClick(wxMouseEvent &e)
01868 {
01869     if(!m_optimizerMode)
01870     {
01871         int flags;
01872         int col;
01873         wxTreeItemId item=HitTest(e.GetPosition(), flags, col);
01874         m_selectedColumn=col;
01875         wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, ID_EDIT);
01876         GetEventHandler()->AddPendingEvent(commandEvent);
01877     };
01878     e.Skip();
01879 };
01880 
01881 IMPLEMENT_DYNAMIC_CLASS(ImagesTreeCtrl, wxTreeListCtrl)
01882 
01883 ImagesTreeCtrlXmlHandler::ImagesTreeCtrlXmlHandler()
01884     : wxTreeListCtrlXmlHandler()
01885 {
01886 }
01887 
01888 wxObject *ImagesTreeCtrlXmlHandler::DoCreateResource()
01889 {
01890     XRC_MAKE_INSTANCE(cp, ImagesTreeCtrl)
01891 
01892     cp->Create(m_parentAsWindow,
01893                GetID(),
01894                GetPosition(), GetSize(),
01895                GetStyle(wxT("style")),
01896                GetName());
01897 
01898     SetupWindow( cp);
01899 
01900     return cp;
01901 }
01902 
01903 bool ImagesTreeCtrlXmlHandler::CanHandle(wxXmlNode *node)
01904 {
01905     return IsOfClass(node, wxT("ImagesTreeList"));
01906 }
01907 
01908 IMPLEMENT_DYNAMIC_CLASS(ImagesTreeCtrlXmlHandler, wxTreeListCtrlXmlHandler)
01909 
01910       

Generated on Wed Oct 1 01:25:35 2014 for Hugintrunk by  doxygen 1.3.9.1