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

Generated on 31 Jul 2015 for Hugintrunk by  doxygen 1.4.7