00001
00002
00027 #include <config.h>
00028 #include "panoinc_WX.h"
00029 #include "panoinc.h"
00030
00031 #include <algorithm>
00032 #include <utility>
00033 #include <functional>
00034
00035 #include "base_wx/wxPlatform.h"
00036 #include "hugin/CPListFrame.h"
00037 #include "hugin/MainFrame.h"
00038 #include "hugin/CommandHistory.h"
00039 #include "hugin/huginApp.h"
00040
00041 using namespace PT;
00042 using namespace std;
00043 using namespace hugin_utils;
00044
00045 class DelKeyHandler: public wxEvtHandler
00046 {
00047 public:
00048 DelKeyHandler(CPListFrame & list)
00049 : m_list(list)
00050 {
00051 }
00052
00053 void OnKey(wxKeyEvent & e)
00054 {
00055 switch(e.m_keyCode)
00056 {
00057 case WXK_DELETE:
00058 m_list.DeleteSelected();
00059 break;
00060 case 1:
00061 m_list.SelectAll();
00062 break;
00063 default:
00064 e.Skip();
00065 }
00066 }
00067
00068 private:
00069 CPListFrame & m_list;
00070
00071 DECLARE_EVENT_TABLE()
00072
00073 };
00074
00075 BEGIN_EVENT_TABLE(DelKeyHandler, wxEvtHandler)
00076 EVT_CHAR(DelKeyHandler::OnKey)
00077 END_EVENT_TABLE()
00078
00079 static Panorama * g_pano;
00080
00081 #if wxCHECK_VERSION(2,9,2)
00082 #define COMPARETYPEITEM wxIntPtr
00083 #define COMPARETYPESORTDATA wxIntPtr
00084 #else
00085 #if wxCHECK_VERSION(2,9,0)
00086 #define COMPARETYPEITEM long
00087 #define COMPARETYPESORTDATA wxIntPtr
00088 #else
00089 #define COMPARETYPEITEM long
00090 #define COMPARETYPESORTDATA long
00091 #endif
00092 #endif
00093
00094 static int wxCALLBACK compareError(COMPARETYPEITEM item1, COMPARETYPEITEM item2, COMPARETYPESORTDATA sortData)
00095 {
00096 const ControlPoint &p1 = g_pano->getCtrlPoint(item1);
00097 const ControlPoint &p2 = g_pano->getCtrlPoint(item2);
00098 if (p1.error < p2.error)
00099 return -1;
00100 else if (p1.error > p2.error)
00101 return 1;
00102 else
00103 return 0;
00104 }
00105
00106 static int wxCALLBACK compareErrorGreater(COMPARETYPEITEM item1, COMPARETYPEITEM item2, COMPARETYPESORTDATA sortData)
00107 {
00108 const ControlPoint &p1 = g_pano->getCtrlPoint(item1);
00109 const ControlPoint &p2 = g_pano->getCtrlPoint(item2);
00110 if (p1.error > p2.error)
00111 return -1;
00112 else if (p1.error < p2.error)
00113 return 1;
00114 else
00115 return 0;
00116 }
00117
00118 static int wxCALLBACK compareCPNr(COMPARETYPEITEM item1, COMPARETYPEITEM item2, COMPARETYPESORTDATA sortData)
00119 {
00120 if (item1 < item2)
00121 return -1;
00122 else if (item1 > item2)
00123 return 1;
00124 else
00125 return 0;
00126 }
00127
00128 static int wxCALLBACK compareCPNrGreater(COMPARETYPEITEM p1, COMPARETYPEITEM p2, COMPARETYPESORTDATA sortData)
00129 {
00130 if (p1 > p2)
00131 return -1;
00132 else if (p1 < p2)
00133 return 1;
00134 else
00135 return 0;
00136 }
00137
00138 static int wxCALLBACK compareImg1Nr(COMPARETYPEITEM item1, COMPARETYPEITEM item2, COMPARETYPESORTDATA sortData)
00139 {
00140 const ControlPoint &p1 = g_pano->getCtrlPoint(item1);
00141 const ControlPoint &p2 = g_pano->getCtrlPoint(item2);
00142 if (p1.image1Nr < p2.image1Nr)
00143 return -1;
00144 else if (p1.image1Nr > p2.image1Nr)
00145 return 1;
00146 else
00147 return 0;
00148 }
00149
00150 static int wxCALLBACK compareImg1NrGreater(COMPARETYPEITEM item1, COMPARETYPEITEM item2, COMPARETYPESORTDATA sortData)
00151 {
00152 const ControlPoint &p1 = g_pano->getCtrlPoint(item1);
00153 const ControlPoint &p2 = g_pano->getCtrlPoint(item2);
00154 if (p1.image1Nr > p2.image1Nr)
00155 return -1;
00156 else if (p1.image1Nr < p2.image1Nr)
00157 return 1;
00158 else
00159 return 0;
00160 }
00161
00162 static int wxCALLBACK compareImg2Nr(COMPARETYPEITEM item1, COMPARETYPEITEM item2, COMPARETYPESORTDATA sortData)
00163 {
00164 const ControlPoint &p1 = g_pano->getCtrlPoint(item1);
00165 const ControlPoint &p2 = g_pano->getCtrlPoint(item2);
00166 if (p1.image2Nr < p2.image2Nr)
00167 return -1;
00168 else if (p1.image2Nr > p2.image2Nr)
00169 return 1;
00170 else
00171 return 0;
00172 }
00173
00174 static int wxCALLBACK compareImg2NrGreater(COMPARETYPEITEM item1, COMPARETYPEITEM item2, COMPARETYPESORTDATA sortData)
00175 {
00176 const ControlPoint &p1 = g_pano->getCtrlPoint(item1);
00177 const ControlPoint &p2 = g_pano->getCtrlPoint(item2);
00178 if (p1.image2Nr > p2.image2Nr)
00179 return -1;
00180 else if (p1.image2Nr < p2.image2Nr)
00181 return 1;
00182 else
00183 return 0;
00184 }
00185
00186 static int wxCALLBACK compareMode(COMPARETYPEITEM item1, COMPARETYPEITEM item2, COMPARETYPESORTDATA sortData)
00187 {
00188 const ControlPoint &p1 = g_pano->getCtrlPoint(item1);
00189 const ControlPoint &p2 = g_pano->getCtrlPoint(item2);
00190 if (p1.mode < p2.mode)
00191 return -1;
00192 else if (p1.mode > p2.mode)
00193 return 1;
00194 else
00195 return 0;
00196 }
00197
00198 static int wxCALLBACK compareModeGreater(COMPARETYPEITEM item1, COMPARETYPEITEM item2, COMPARETYPESORTDATA sortData)
00199 {
00200 const ControlPoint &p1 = g_pano->getCtrlPoint(item1);
00201 const ControlPoint &p2 = g_pano->getCtrlPoint(item2);
00202 if (p1.mode > p2.mode)
00203 return -1;
00204 else if (p1.mode < p2.mode)
00205 return 1;
00206 else
00207 return 0;
00208 }
00209
00210 #if 0
00211
00212 struct compareError
00213 {
00214 bool operator()(const pair<int, ControlPoint> &p1, const pair<int, ControlPoint> &p2)
00215 { return p1.second.error < p2.second.error; }
00216 };
00217
00218
00219 struct compareErrorGreater
00220 {
00221 bool operator()(const pair<int, ControlPoint> &p1, const pair<int, ControlPoint> &p2)
00222 { return p1.second.error > p2.second.error; }
00223 };
00224
00225 struct compareImg1Nr
00226 {
00227 bool operator()(const pair<int, ControlPoint> &p1, const pair<int, ControlPoint> &p2)
00228 { return p1.second.image1Nr < p2.second.image1Nr; }
00229 };
00230
00231 struct compareImg1NrGreater
00232 {
00233 bool operator()(const pair<int, ControlPoint> &p1, const pair<int, ControlPoint> &p2)
00234 { return p1.second.image1Nr > p2.second.image1Nr; }
00235 };
00236
00237 struct compareImg2Nr
00238 {
00239 bool operator()(const pair<int, ControlPoint> &p1, const pair<int, ControlPoint> &p2)
00240 { return p1.second.image2Nr < p2.second.image2Nr; }
00241 };
00242
00243 struct compareImg2NrGreater
00244 {
00245 bool operator()(const pair<int, ControlPoint> &p1, const pair<int, ControlPoint> &p2)
00246 { return p1.second.image2Nr > p2.second.image2Nr; }
00247 };
00248
00249 struct compareMode
00250 {
00251 bool operator()(const pair<int, ControlPoint> &p1, const pair<int, ControlPoint> &p2)
00252 { return p1.second.mode < p2.second.mode; }
00253 };
00254
00255 struct compareModeGreater
00256 {
00257 bool operator()(const pair<int, ControlPoint> &p1, const pair<int, ControlPoint> &p2)
00258 { return p1.second.mode > p2.second.mode; }
00259 };
00260
00261 #endif
00262
00263 BEGIN_EVENT_TABLE(CPListFrame, wxFrame)
00264 EVT_CLOSE(CPListFrame::OnClose)
00265 EVT_LIST_ITEM_SELECTED(XRCID("cp_list_frame_list"), CPListFrame::OnCPListSelectionChanged)
00266 EVT_LIST_ITEM_DESELECTED(XRCID("cp_list_frame_list"), CPListFrame::OnCPListSelectionChanged)
00267 EVT_LIST_COL_CLICK(XRCID("cp_list_frame_list"), CPListFrame::OnCPListHeaderClick)
00268 EVT_LIST_COL_END_DRAG(XRCID("cp_list_frame_list"), CPListFrame::OnColumnWidthChange)
00269 EVT_BUTTON(XRCID("cp_list_delete"), CPListFrame::OnDeleteButton)
00270 EVT_BUTTON(XRCID("cp_list_select"), CPListFrame::OnSelectButton)
00271 EVT_BUTTON(XRCID("cp_list_finetune"), CPListFrame::OnFineTuneButton)
00272
00273 END_EVENT_TABLE()
00274
00275
00276 CPListFrame::CPListFrame(MainFrame * parent, Panorama & pano)
00277 : m_mainFrame(parent), m_pano(pano),m_verbose(false),
00278 m_sortCol(0), m_sortAscend(true), m_freeze(false)
00279 {
00280 DEBUG_TRACE("");
00281 bool ok = wxXmlResource::Get()->LoadFrame(this, parent, wxT("cp_list_frame"));
00282 DEBUG_ASSERT(ok);
00283 m_list = XRCCTRL(*this, "cp_list_frame_list", wxListCtrl);
00284 DEBUG_ASSERT(m_list);
00285
00286 wxConfigBase * config = wxConfigBase::Get();
00287 m_verbose = (config->Read(wxT("/CPListFrame/verbose"),0l) != 0);
00288
00289 #ifdef __WXMSW__
00290
00291 this->SetBackgroundColour(XRCCTRL(*this, "cp_list_select", wxButton)->GetBackgroundColour());
00292 #endif
00293 #ifdef __WXMSW__
00294 wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
00295 #else
00296 wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
00297 #endif
00298 SetIcon(myIcon);
00299
00300 if (m_verbose) {
00301
00302 m_list->InsertColumn( 0, _("#"), wxLIST_FORMAT_RIGHT, 25);
00303 m_list->InsertColumn( 1, _("Left Img."), wxLIST_FORMAT_RIGHT, 65);
00304 m_list->InsertColumn( 2, _("x"), wxLIST_FORMAT_RIGHT, 40);
00305 m_list->InsertColumn( 3, _("y"), wxLIST_FORMAT_RIGHT, 40);
00306 m_list->InsertColumn( 4, _("Right Img."), wxLIST_FORMAT_RIGHT, 65);
00307 m_list->InsertColumn( 5, _("x"), wxLIST_FORMAT_RIGHT, 40);
00308 m_list->InsertColumn( 6, _("y"), wxLIST_FORMAT_RIGHT, 40);
00309 m_list->InsertColumn( 7, _("Alignment"), wxLIST_FORMAT_LEFT, 80);
00310 m_list->InsertColumn( 8, _("Distance"), wxLIST_FORMAT_RIGHT, 80);
00311 } else {
00312 m_list->InsertColumn( 0, _("G CP#"), wxLIST_FORMAT_RIGHT, 25);
00313 m_list->InsertColumn( 1, _("Left Img."), wxLIST_FORMAT_RIGHT, 65);
00314 m_list->InsertColumn( 2, _("Right Img."), wxLIST_FORMAT_RIGHT, 65);
00315 m_list->InsertColumn( 3, _("P CP#"), wxLIST_FORMAT_RIGHT, 25);
00316 m_list->InsertColumn( 4, _("Alignment"), wxLIST_FORMAT_LEFT, 80);
00317 m_list->InsertColumn( 5, _("Distance"), wxLIST_FORMAT_RIGHT, 80);
00318 }
00319
00320
00321 for ( int j=0; j < m_list->GetColumnCount() ; j++ )
00322 {
00323
00324 int width = wxConfigBase::Get()->Read(wxString::Format( wxT("/CPListFrame/ColumnWidth%d"), j ), -1);
00325 if(width != -1)
00326 m_list->SetColumnWidth(j, width);
00327 }
00328
00329
00330 SetSizeHints(200, 300);
00331
00332
00333 RestoreFramePosition(this, wxT("CPListFrame"));
00334
00335 m_list->PushEventHandler(new DelKeyHandler(*this));
00336
00337 m_list->Show();
00338
00339 m_pano.addObserver(this);
00340
00341 g_pano = & m_pano;
00342
00343
00344 UIntSet dummy;
00345 panoramaImagesChanged(m_pano, dummy);
00346
00347
00348
00349
00350
00351
00352
00353 DEBUG_TRACE("ctor end");
00354 }
00355
00356 CPListFrame::~CPListFrame()
00357 {
00358 DEBUG_TRACE("dtor");
00359
00360 m_list->PopEventHandler(true);
00361
00362 StoreFramePosition(this, wxT("CPListFrame"));
00363
00364 wxConfigBase * config = wxConfigBase::Get();
00365
00366 if ( (!this->IsIconized()) && (!this->IsMaximized()) && this->IsShown()) {
00367 DEBUG_DEBUG("IsShown()");
00368 config->Write(wxT("/CPListFrame/isShown"), 1l);
00369 } else {
00370 DEBUG_DEBUG(" not shown ");
00371 config->Write(wxT("/CPListFrame/isShown"), 0l);
00372 }
00373
00374 config->Flush();
00375 m_pano.removeObserver(this);
00376 DEBUG_TRACE("dtor end");
00377 }
00378
00379 void CPListFrame::panoramaImagesChanged(PT::Panorama &pano, const PT::UIntSet & imgNr)
00380 {
00381 DEBUG_TRACE("");
00382 const CPVector & cpv = pano.getCtrlPoints();
00383 unsigned int nrCP = cpv.size();
00384 unsigned int nrItems = m_list->GetItemCount();
00385 DEBUG_TRACE("nr CP:" << nrCP << " nr listentries:" << nrItems);
00386
00387 m_list->Freeze();
00388
00389
00390 for (int i=nrItems-1; i>=(int)nrCP; i--)
00391 {
00392 m_list->DeleteItem(i);
00393 }
00394
00395
00396 if ( nrCP >= nrItems ) {
00397 for (int i=0; i < (int) nrCP; i++) {
00398 if (i >= (int) nrItems) {
00399
00400 m_list->InsertItem(i, wxString::Format(wxT("%d"),i));
00401 }
00402 }
00403 }
00404
00405 updateList();
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 m_list->Thaw();
00419 }
00420
00421 void CPListFrame::SetCPItem(int i, const ControlPoint & p)
00422 {
00423 DEBUG_ASSERT(i < m_list->GetItemCount());
00424 wxString mode;
00425 switch (p.mode) {
00426 case ControlPoint::X_Y:
00427 mode = _("normal");
00428 break;
00429 case ControlPoint::X:
00430 mode = _("vert. Line");
00431 break;
00432 case ControlPoint::Y:
00433 mode = _("horiz. Line");
00434 break;
00435 default:
00436 mode = wxString::Format(_("Line %d"), p.mode);
00437 break;
00438 }
00439
00440
00441 string pairId = makePairId(p.image1Nr,p.image2Nr);
00442 if (m_localIds.count(pairId)) {
00443 m_localIds[pairId]++;
00444 } else {
00445 m_localIds[pairId] = 0;
00446 }
00447
00448 int localId = m_localIds[pairId];
00449 DEBUG_INFO ("Global ID: " << i << " -> Local ID: " << localId);
00450
00451 if (m_verbose) {
00452 m_list->SetItem(i,0,wxString::Format(wxT("%d"),i));
00453 m_list->SetItem(i,1,wxString::Format(wxT("%d"),p.image1Nr));
00454 m_list->SetItem(i,2,wxString::Format(wxT("%.1f"),p.x1));
00455 m_list->SetItem(i,3,wxString::Format(wxT("%.1f"),p.y1));
00456 m_list->SetItem(i,4,wxString::Format(wxT("%d"),p.image2Nr));
00457 m_list->SetItem(i,5,wxString::Format(wxT("%.1f"),p.x2));
00458 m_list->SetItem(i,6,wxString::Format(wxT("%.1f"),p.y2));
00459 m_list->SetItem(i,7,mode);
00460 m_list->SetItem(i,8,wxString::Format(wxT("%.2f"),p.error));
00461 } else {
00462 m_list->SetItem(i,0,wxString::Format(wxT("%d"),i));
00463 m_list->SetItem(i,1,wxString::Format(wxT("%d"),p.image1Nr));
00464 m_list->SetItem(i,2,wxString::Format(wxT("%d"),p.image2Nr));
00465 m_list->SetItem(i,3,wxString::Format(wxT("%d"),localId));
00466 m_list->SetItem(i,4,mode);
00467 m_list->SetItem(i,5,wxString::Format(wxT("%.2f"),p.error));
00468 }
00469 }
00470
00471
00472 void CPListFrame::updateList()
00473 {
00474 const CPVector & cps = m_pano.getCtrlPoints();
00475
00476 int sortCol = m_sortCol;
00477 bool sortAscend = m_sortAscend;
00478
00479
00480
00481
00482 m_sortCol = 0;
00483 m_sortAscend = true;
00484
00485
00486
00487 m_localIds.clear();
00488
00489 SortList();
00490
00491 int nrCP = cps.size();
00492 for (int i=0; i < (int) nrCP; i++) {
00493 SetCPItem(i,cps[i]);
00494 m_list->SetItemData(i, i);
00495 m_list->SetItemState(i, 0, wxLIST_STATE_SELECTED);
00496 }
00497
00498 #if 0
00499
00500 vector<pair<int,ControlPoint> > cpv(nrCP);
00501 for (int i=0; i < nrCP; ++i) {
00502 cpv[i] = make_pair(i,cps[i]);
00503 }
00504 #endif
00505
00506 m_sortCol = sortCol;
00507 m_sortAscend = sortAscend;
00508 SortList();
00509 }
00510
00511 void CPListFrame::SortList()
00512 {
00513
00514 if (m_list->GetItemCount() == 0) return;
00515
00516 int colNumber = 0;
00517 int colLeftImg = 1;
00518 int colRightImg = 4;
00519 int colMode = 7;
00520 int colError = 8;
00521
00522 int colPairCP = 3;
00523
00524 if (!m_verbose) {
00525 colRightImg = 2;
00526 colMode = 4;
00527 colError = 5;
00528 }
00529
00530 DEBUG_TRACE("sorting column " << m_sortCol);
00531 if (m_sortCol == colNumber) {
00532 if (m_sortAscend) {
00533 m_list->SortItems(&compareCPNr, 0);
00534
00535 } else {
00536 m_list->SortItems(&compareCPNrGreater, 0);
00537
00538 }
00539 } else if (m_sortCol == colLeftImg) {
00540 if (m_sortAscend) {
00541 m_list->SortItems(&compareImg1Nr, 0);
00542
00543 } else {
00544 m_list->SortItems(&compareImg1NrGreater, 0);
00545
00546 }
00547 } else if (m_sortCol == colRightImg) {
00548 if (m_sortAscend) {
00549 m_list->SortItems(&compareImg2Nr, 0);
00550
00551 } else {
00552 m_list->SortItems(&compareImg2NrGreater, 0);
00553
00554 }
00555 } else if (m_sortCol == colMode) {
00556 if (m_sortAscend) {
00557 m_list->SortItems(&compareMode, 0);
00558
00559 } else {
00560 m_list->SortItems(&compareModeGreater, 0);
00561
00562 }
00563 } else if (m_sortCol == colError) {
00564 if (m_sortAscend) {
00565 m_list->SortItems(&compareError, 0);
00566
00567 } else {
00568 m_list->SortItems(&compareErrorGreater, 0);
00569
00570 }
00571 } else if (m_sortCol == colPairCP) {
00572 DEBUG_DEBUG("Skip sort of pair control points");
00573 } else {
00574 DEBUG_ERROR("Unknown sorting column: " << m_sortCol);
00575 }
00576 }
00577
00578 void CPListFrame::OnCPListHeaderClick(wxListEvent & e)
00579 {
00580
00581
00582 int newCol = e.GetColumn();
00583 if (m_sortCol == newCol) {
00584 m_sortAscend = ! m_sortAscend;
00585 } else {
00586 m_sortCol = newCol;
00587 m_sortAscend = true;
00588 }
00589 SortList();
00590 }
00591
00592 void CPListFrame::OnClose(wxCloseEvent& event)
00593 {
00594 DEBUG_DEBUG("OnClose");
00595 m_mainFrame->OnCPListFrameClosed();
00596 DEBUG_DEBUG("closing");
00597 Destroy();
00598 }
00599
00600 void CPListFrame::OnDeleteButton(wxCommandEvent & e)
00601 {
00602 DeleteSelected();
00603 }
00604
00605 #if 0
00606 void CPListFrame::OnSelectOutliers
00607 {
00608
00609
00610 }
00611 #endif
00612
00613 void CPListFrame::OnSelectButton(wxCommandEvent & e)
00614 {
00615
00616
00617 m_freeze = true;
00618 const CPVector & cps = m_pano.getCtrlPoints();
00619
00620 double mean_error = 0;
00621 double squared_error = 0;
00622 double max_error = 0;
00623 CPVector::const_iterator it;
00624 for (it = cps.begin() ; it != cps.end(); it++) {
00625 mean_error += (*it).error;
00626 squared_error += (*it).error * (*it).error;
00627 if ((*it).error > max_error) {
00628 max_error = (*it).error;
00629 }
00630 }
00631 mean_error = mean_error / cps.size();
00632 double std_dev = sqrt(squared_error/cps.size());
00633
00634
00635
00636
00637 double threshold = mean_error + std_dev;
00638 wxString t;
00639 do
00640 {
00641 t=wxGetTextFromUser(_("Enter minimum control point error.\nAll points with a higher error will be selected"), _("Select Control Points"),
00642 doubleTowxString(threshold,2));
00643
00644 if (t == wxEmptyString) {
00645
00646 return;
00647 }
00648 } while (!str2double(t,threshold));
00649
00650 bool invert = threshold < 0;
00651 if (invert) {
00652 threshold = -threshold;
00653 }
00654
00655 m_list->Freeze();
00656 int sortCol = m_sortCol;
00657 bool sortAscend = m_sortAscend;
00658
00659 long row = -1;
00660 for(;;) {
00661 row = m_list->GetNextItem(row,
00662 wxLIST_NEXT_ALL);
00663 if (row < 0) {
00664 break;
00665 }
00666 unsigned int cpNr = (unsigned int) m_list->GetItemData(row);
00667 if ( ((cps[cpNr].error > threshold ) && (!invert))
00668 || ((cps[cpNr].error < threshold ) && (invert)) )
00669 {
00670
00671 DEBUG_DEBUG("selecting row: " << row << " cpNr: " << cpNr);
00672
00673 m_list->SetItemState(row, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
00674 } else {
00675 m_list->SetItemState(row, 0, wxLIST_STATE_SELECTED);
00676 }
00677 } while (row != -1);
00678
00679 m_list->Thaw();
00680
00681 m_freeze = false;
00682 }
00683
00684 void CPListFrame::DeleteSelected()
00685 {
00686 DEBUG_DEBUG("Delete pressed");
00687
00688
00689 int nSelected = m_list->GetSelectedItemCount();
00690 DEBUG_DEBUG(nSelected << " point selected, deleting them");
00691 if (nSelected == 0) {
00692 wxBell();
00693 return;
00694 }
00695
00696 UIntSet selected;
00697 long item = -1;
00698 for(;;) {
00699 item = m_list->GetNextItem(item,
00700 wxLIST_NEXT_ALL,
00701 wxLIST_STATE_SELECTED);
00702
00703 m_list->SetItemState(item, 0, wxLIST_STATE_SELECTED);
00704 if (item < 0) {
00705 break;
00706 }
00707 DEBUG_DEBUG("scheduling point " << item << " for deletion");
00708 selected.insert((unsigned int) (m_list->GetItemData(item)));
00709 }
00710 DEBUG_DEBUG("about to delete " << selected.size() << " points");
00711 GlobalCmdHist::getInstance().addCommand(
00712 new PT::RemoveCtrlPointsCmd(m_pano,selected)
00713 );
00714
00715 item = m_list->GetNextItem(item,
00716 wxLIST_NEXT_ALL);
00717 if (item >=0) {
00718 int cp = m_list->GetItemData(item);
00719 m_mainFrame->ShowCtrlPoint((unsigned int) cp);
00720 }
00721 }
00722
00723 void CPListFrame::SelectAll()
00724 {
00725 unsigned int nrItems = m_list->GetItemCount();
00726 for (unsigned int i=0; i < nrItems ; i++)
00727 {
00728 m_list->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
00729 }
00730 };
00731
00732 void CPListFrame::OnFineTuneButton(wxCommandEvent & e)
00733 {
00734 DEBUG_WARN("Not yet implemented");
00735 }
00736
00737
00738 void CPListFrame::OnColumnWidthChange( wxListEvent & e )
00739 {
00740 int colNum = e.GetColumn();
00741 wxConfigBase::Get()->Write( wxString::Format(wxT("/CPListFrame/ColumnWidth%d"),colNum), m_list->GetColumnWidth(colNum) );
00742 }
00743
00744
00745 void CPListFrame::OnCPListSelectionChanged(wxListEvent & e)
00746 {
00747 DEBUG_TRACE(e.GetIndex());
00748 int itemsSelected = m_list->GetSelectedItemCount();
00749 DEBUG_DEBUG("selected control points: " << itemsSelected);
00750 if (1 == itemsSelected) {
00751 int cp = m_list->GetItemData(e.GetIndex());
00752 m_mainFrame->ShowCtrlPoint((unsigned int) cp);
00753 } else if (0 == itemsSelected) {
00754 DEBUG_DEBUG("nothing to do");
00755 } else if (itemsSelected > 1) {
00756 DEBUG_DEBUG("Multiselection nothing to do");
00757 }
00758
00759 }
00760
00761
00762 std::string CPListFrame::makePairId(unsigned int id1, unsigned int id2)
00763 {
00764
00765
00766 std::ostringstream oss;
00767
00768 if (id1 < id2) {
00769 oss << id1 << "_" << id2;
00770 } else if (id2 < id1) {
00771 oss << id2 << "_" << id1;
00772 } else {
00773
00774 oss << id1;
00775 }
00776 return oss.str();
00777 }