Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ProjectListBox.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
27 #ifdef _WIN32
28 #include "wx/msw/wrapwin.h"
29 #endif
30 #include "ProjectListBox.h"
31 
32 enum
33 {
34  ID_CHANGE_PREFIX=wxID_HIGHEST+200,
35  ID_RESET_PROJECT=wxID_HIGHEST+201,
36  ID_EDIT_PROJECT=wxID_HIGHEST+202,
37  ID_REMOVE_PROJECT=wxID_HIGHEST+203,
38  ID_CHANGE_USER_DEFINED=wxID_HIGHEST+204
39 };
40 
41 bool ProjectListBox::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
42 {
43  if (! wxListCtrl::Create(parent, id, pos, size, wxLC_REPORT | style) )
44  {
45  return false;
46  };
47  columns.Add(ID);
48  columns.Add(PROJECT);
49  columns.Add(PREFIX);
50  columns.Add(STATUS);
51  columns.Add(MODDATE);
52  columns.Add(FORMAT);
53  columns.Add(PROJECTION);
54  columns.Add(SIZE);
56 
57  this->InsertColumn(0,_("ID"));
58  this->InsertColumn(1,_("Project"));
59  this->InsertColumn(2,_("Output prefix"));
60  this->InsertColumn(3,_("Status"));
61  this->InsertColumn(4,_("Last modified"));
62  this->InsertColumn(5,_("Output format"));
63  this->InsertColumn(6,_("Projection"));
64  this->InsertColumn(7,_("Size"));
65  this->InsertColumn(8, _("User defined sequence"));
66 
67  //get saved width
68  for( int i=0; i < GetColumnCount() ; i++ )
69  {
70  int width = wxConfigBase::Get()->Read(wxString::Format(wxT("/BatchList/ColumnWidth%d"), columns[i] ), -1);
71  if(width != -1)
72  {
73  SetColumnWidth(i, width);
74  }
75  }
76  // connect event handler
77  Bind(wxEVT_LIST_COL_END_DRAG, &ProjectListBox::OnColumnWidthChange, this);
78  Bind(wxEVT_CONTEXT_MENU, &ProjectListBox::OnContextMenu, this);
79  Bind(wxEVT_CHAR, &ProjectListBox::OnChar, this);
80  Bind(wxEVT_MENU, &ProjectListBox::OnChangePrefix, this, ID_CHANGE_PREFIX);
81  Bind(wxEVT_MENU, &ProjectListBox::OnResetProject, this, ID_RESET_PROJECT);
82  Bind(wxEVT_MENU, &ProjectListBox::OnEditProject, this, ID_EDIT_PROJECT);
83  Bind(wxEVT_MENU, &ProjectListBox::OnRemoveProject, this, ID_REMOVE_PROJECT);
85  return true;
86 }
87 
88 //public methods:
89 
91 {
92  //if we have a command-line application
93  if(project->id < 0)
94  {
95  int i=columns.Index(PROJECT); //we find the project column
96  if(i != wxNOT_FOUND)
97  {
98  if(i==0)
99  {
100  this->InsertItem(this->GetItemCount(),project->path);
101  }
102  else
103  {
104  this->InsertItem(this->GetItemCount(),_T(""));
105  this->SetItem(this->GetItemCount()-1,i,project->path);
106  }
107  }
108  else //we insert an empty line
109  {
110  this->InsertItem(this->GetItemCount(),_T(""));
111  }
112  }
113  else
114  {
115  if(columns.GetCount()>0)
116  {
117  this->InsertItem(this->GetItemCount(),this->GetAttributeString(columns[0],project));
118  for(unsigned int i=1; i<columns.GetCount(); i++)
119  {
120  this->SetItem(this->GetItemCount()-1,i,this->GetAttributeString(columns[i],project));
121  }
122  }
123  else //we have no columns?
124  {
125  this->InsertItem(this->GetItemCount(),_T(""));
126  }
127  }
128 }
129 
130 void ProjectListBox::ChangePrefix(int index, wxString newPrefix)
131 {
132  int colIndex=columns.Index(PREFIX);
133  if(colIndex!=wxNOT_FOUND)
134  {
135  Project* project=m_batch->GetProject(index);
136  this->SetItem(index,colIndex,this->GetAttributeString(colIndex,project));
137  }
138 }
139 
140 void ProjectListBox::ChangeUserDefined(int index, wxString newUserDefined)
141 {
142  int colIndex = columns.Index(USERDEFINEDSEQUENCE);
143  if (colIndex != wxNOT_FOUND)
144  {
145  Project* project = m_batch->GetProject(index);
146  this->SetItem(index, colIndex, this->GetAttributeString(colIndex, project));
147  }
148 }
149 
151 {
152  SetItemState(index, 0, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);
153 }
154 
156 {
157  m_batch=batch;
158  for(int i=0; i<m_batch->GetProjectCount(); i++)
159  {
161  }
162 }
163 
165 {
166  int index=0;
167  while(index<this->GetItemCount())
168  {
169  if(GetText(index,0).Cmp(wxString::Format(_("%d"),id))==0)
170  {
171  return index;
172  }
173  index++;
174  }
175  return -1;
176 }
177 
179 {
180  int count = 0;
181  for(int i=0; i<this->GetItemCount(); i++)
182  {
183  if(path.Cmp(GetText(i,1))==0)
184  {
185  count++;
186  }
187  }
188  return count;
189 }
190 
192 {
193  long id=-1;
194  if(!GetText(index,0).ToLong(&id))
195  {
196  wxMessageBox(_("Error, cannot convert id"),_("Error"));
197  }
198  return (int)id;
199 }
200 
202 {
203  HuginBase::UIntSet selected;
204  for (int i = 0; i<GetItemCount(); i++)
205  {
206  if (GetItemState(i, wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED)
207  {
208  selected.insert(i);
209  };
210  };
211  return selected;
212 }
213 
214 wxString ProjectListBox::GetText(int row, int column)
215 {
216  wxListItem item;
217  item.SetId(row);
218  item.SetColumn(column);
219  item.SetMask(wxLIST_MASK_TEXT);
220  this->GetItem(item);
221  return item.GetText();
222 }
223 
224 void ProjectListBox::ReloadProject(int index, Project* project)
225 {
226  for(unsigned int i=0; i<columns.GetCount(); i++)
227  {
228  this->SetItem(index,i,this->GetAttributeString(columns[i],project));
229  }
230 }
231 
232 void ProjectListBox::Select(int index)
233 {
234  if(index>=0 && index<this->GetItemCount())
235  {
236  SetItemState(index,wxLIST_STATE_SELECTED,wxLIST_STATE_SELECTED);
237  };
238 }
239 
241 {
242  for(int i=0; i< this->GetColumnCount(); i++)
243  {
244  if(columns[i]==STATUS)
245  {
246  this->SetItem(index,i,_("File missing"));
247  }
248  if(columns[i]!=ID && columns[i]!=PROJECT && columns[i]!=PREFIX && columns[i]!=USERDEFINEDSEQUENCE)
249  {
250  this->SetItem(index,i,_T(""));
251  }
252  }
253 }
254 
256 {
257  wxString temp;
258  for(int i=0; i<GetColumnCount(); i++)
259  {
260  temp = GetText(index,i);
261  SetItem(index,i,GetText(index+1,i));
262  SetItem(index+1,i,temp);
263  }
264 }
265 
266 bool ProjectListBox::UpdateStatus(int index, Project* project)
267 {
268  bool change = false;
269  wxString newStatus;
270  for(int i=0; i< this->GetColumnCount(); i++)
271  {
272  if(columns[i]==STATUS)
273  {
274  newStatus = project->GetStatusText();
275  if(newStatus.Cmp(GetText(index,i))!=0)
276  {
277  change = true;
278  this->SetItem(index,i,newStatus);
279  }
280  }
281  }
282  return change;
283 }
284 
285 //private methods:
286 
288 {
289  wxString str;
290  switch(i)
291  {
292  case 0:
293  return wxString::Format(_T("%ld"),project->id);
294  case 1:
295  return project->path;
296  case 2:
297  if(project->target==Project::STITCHING)
298  {
299  //make prefix relative to project path
300  wxFileName prefix(project->prefix);
301  wxFileName projectFile(project->path);
302  prefix.MakeRelativeTo(projectFile.GetPath());
303  return prefix.GetFullPath();
304  }
305  else
306  {
307  return _("Assistant");
308  };
309  case 7:
310  return project->GetStatusText();
311  //all following cases default to an empty string if file is missing
312  case 3:
313  if(project->status!=Project::MISSING)
314  {
315  if (project->modDate.IsValid())
316  {
317  return project->modDate.Format();
318  };
319  };
320  return wxEmptyString;
321  case 4:
322  if(project->status!=Project::MISSING)
323  {
325  str = str+wxT(" (.")+wxString::FromAscii(project->options.outputImageType.c_str())+wxT(")");
326  return str;
327  };
328  return wxEmptyString;
329  case 5:
330  if(project->status!=Project::MISSING)
331  {
332  pano_projection_features proj;
333  if (panoProjectionFeaturesQuery(project->options.getProjection(), &proj))
334  {
335  wxString str2(proj.name, wxConvLocal);
336  return wxGetTranslation(str2);
337  }
338  else
339  {
340  return _T("");
341  }
342  };
343  return wxEmptyString;
344  case 6:
345  if(project->status!=Project::MISSING)
346  {
347  str = wxString() << project->options.getWidth();
348  str = str+_T("x");
349  str = str << project->options.getHeight();
350  return str;
351  }
352  return wxEmptyString;
353  case 8:
354  if (!project->userDefindSequence.IsEmpty())
355  {
356  return project->userDefindSequence;
357  };
358  return wxEmptyString;
359  default:
360  return _T("");
361  }
362 }
363 
364 wxString ProjectListBox::GetLongerFormatName(std::string str)
365 {
366  if(str=="tif")
367  {
368  return _T("TIFF");
369  }
370  else if(str=="jpg")
371  {
372  return _T("JPEG");
373  }
374  else if(str=="png")
375  {
376  return _T("PNG");
377  }
378  else if(str=="exr")
379  {
380  return _T("EXR");
381  }
382  else
383  {
384  return _T("");
385  }
386 }
387 
388 void ProjectListBox::OnColumnWidthChange(wxListEvent& event)
389 {
390  int col = event.GetColumn();
391  wxConfigBase::Get()->Write(wxString::Format(wxT("/BatchList/ColumnWidth%d"),columns[col]), GetColumnWidth(col));
392 }
393 
394 // functions for context menu
395 void ProjectListBox::OnContextMenu(wxContextMenuEvent& e)
396 {
397  const HuginBase::UIntSet selected(GetSelectedProjects());
398  wxPoint point = e.GetPosition();
399  // if from keyboard
400  if ((point.x == -1) && (point.y == -1))
401  {
402  wxSize size = GetSize();
403  point.x = size.x / 2;
404  point.y = size.y / 2;
405  }
406  else
407  {
408  point = ScreenToClient(point);
409  };
410  if (selected.size() == 1)
411  {
412  wxMenu menu;
413  menu.Append(ID_CHANGE_PREFIX, _("Change prefix"));
414  menu.Append(ID_CHANGE_USER_DEFINED, _("Change user defined sequence"));
415  menu.Append(ID_RESET_PROJECT, _("Reset project"));
416  menu.Append(ID_EDIT_PROJECT, _("Edit with Hugin"));
417  menu.Append(ID_REMOVE_PROJECT, _("Remove"));
418  PopupMenu(&menu, point.x, point.y);
419  }
420  else
421  {
422  if (selected.size() > 1)
423  {
424  wxMenu menu;
425  // check that all selected project have the same target
426  const Project::Target target = m_batch->GetProject(*(selected.begin()))->target;
427  bool isSameTarget = true;
428  for (const auto& i : selected)
429  {
430  if (m_batch->GetProject(i)->target != target)
431  {
432  isSameTarget = false;
433  break;
434  };
435  };
436  if (isSameTarget)
437  {
438  menu.Append(ID_CHANGE_USER_DEFINED, _("Change user defined sequence"));
439  };
440  menu.Append(ID_RESET_PROJECT, _("Reset project"));
441  menu.Append(ID_REMOVE_PROJECT, _("Remove"));
442  PopupMenu(&menu, point.x, point.y);
443  };
444  };
445 };
446 
447 void ProjectListBox::OnChar(wxKeyEvent& e)
448 {
449  switch (e.GetKeyCode())
450  {
451  case WXK_DELETE:
452  case WXK_NUMPAD_DELETE:
453  {
454  wxCommandEvent ev(wxEVT_TOOL, XRCID("tool_remove"));
455  GetParent()->GetEventHandler()->AddPendingEvent(ev);
456  };
457  break;
458  case WXK_INSERT:
459  case WXK_NUMPAD_INSERT:
460  {
461  wxCommandEvent ev(wxEVT_MENU, XRCID("menu_add"));
462  GetParent()->GetEventHandler()->AddPendingEvent(ev);
463  };
464  break;
465  case WXK_ESCAPE:
466  {
467  wxCommandEvent ev(wxEVT_TOOL, XRCID("tool_cancel"));
468  GetParent()->GetEventHandler()->AddPendingEvent(ev);
469  };
470  break;
471  default:
472  e.Skip();
473  };
474 }
475 void ProjectListBox::OnChangePrefix(wxCommandEvent& e)
476 {
477  wxCommandEvent ev(wxEVT_COMMAND_BUTTON_CLICKED, XRCID("button_prefix"));
478  GetParent()->GetEventHandler()->AddPendingEvent(ev);
479 };
480 
481 void ProjectListBox::OnResetProject(wxCommandEvent& e)
482 {
483  wxCommandEvent ev(wxEVT_COMMAND_BUTTON_CLICKED, XRCID("button_reset"));
484  GetParent()->GetEventHandler()->AddPendingEvent(ev);
485 };
486 
487 void ProjectListBox::OnEditProject(wxCommandEvent& e)
488 {
489  wxCommandEvent ev(wxEVT_COMMAND_BUTTON_CLICKED, XRCID("button_edit"));
490  GetParent()->GetEventHandler()->AddPendingEvent(ev);
491 };
492 
493 void ProjectListBox::OnRemoveProject(wxCommandEvent& e)
494 {
495  wxCommandEvent ev(wxEVT_COMMAND_TOOL_CLICKED, XRCID("tool_remove"));
496  GetParent()->GetEventHandler()->AddPendingEvent(ev);
497 };
498 
499 void ProjectListBox::OnChangeUserDefined(wxCommandEvent& e)
500 {
501  wxCommandEvent ev(wxEVT_COMMAND_BUTTON_CLICKED, XRCID("button_user_defined"));
502  GetParent()->GetEventHandler()->AddPendingEvent(ev);
503 }
504 
505 const wxString ProjectListBox::fileFormat[] = {_T("JPEG"),
506  _T("JPEG_m"),
507  _T("PNG"),
508  _T("PNG_m"),
509  _T("TIFF"),
510  _T("TIFF_m"),
511  _T("TIFF_mask"),
512  _T("TIFF_multilayer"),
513  _T("TIFF_multilayer_mask"),
514  _T("PICT"),
515  _T("PSD"),
516  _T("PSD_m"),
517  _T("PSD_mask"),
518  _T("PAN"),
519  _T("IVR"),
520  _T("IVR_java"),
521  _T("VRML"),
522  _T("QTVR"),
523  _T("HDR"),
524  _T("HDR_m"),
525  _T("EXR"),
526  _T("EXR_m"),
527  _T("FILEFORMAT_NULL")
528  };
529 
530 const wxString ProjectListBox::outputMode[] =
531 {
532  _T("OUTPUT_LDR"),
533  _T("OUTPUT_HDR")
534 };
535 
536 const wxString ProjectListBox::HDRMergeType[] =
537 {
538  _T("HDRMERGE_AVERAGE"),
539  _T("HDRMERGE_DEGHOST")
540 };
541 
542 const wxString ProjectListBox::blendingMechanism[] =
543 {
544  _T("NO_BLEND"),
545  _T("PTBLENDER_BLEND"),
546  _T("ENBLEND_BLEND"),
547  _T("SMARTBLEND_BLEND"),
548  _T("PTMASKER_BLEND")
549 };
550 
552 
554  : wxListCtrlXmlHandler()
555 {
556  AddWindowStyles();
557 }
558 
560 {
561  XRC_MAKE_INSTANCE(cp, ProjectListBox)
562 
563  cp->Create(m_parentAsWindow,
564  GetID(),
565  GetPosition(), GetSize(),
566  GetStyle(wxT("style")),
567  GetName());
568 
569  SetupWindow( cp);
570 
571  return cp;
572 }
573 
575 {
576  return IsOfClass(node, wxT("ProjectListBox"));
577 }
578 
580 
void OnResetProject(wxCommandEvent &e)
PanoramaOptions::ProjectionFormat getProjection() const
int GetProjectCount()
Returns number of projects in batch list.
Definition: Batch.cpp:301
wxString userDefindSequence
Definition: ProjectArray.h:73
static const wxString outputMode[]
void OnChangeUserDefined(wxCommandEvent &e)
void SetMissing(int index)
wxDateTime modDate
Definition: ProjectArray.h:75
Status status
Definition: ProjectArray.h:65
int GetProjectCountByPath(wxString path)
unsigned int getHeight() const
get panorama height
void Deselect(int index)
static const wxString HDRMergeType[]
void AppendProject(Project *project)
virtual wxObject * DoCreateResource()
wxString GetText(int row, int column)
void OnEditProject(wxCommandEvent &e)
HuginBase::PanoramaOptions options
Definition: ProjectArray.h:77
void ChangePrefix(int index, wxString newPrefix)
void ChangeUserDefined(int index, wxString newUserDefined)
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
int GetIndex(int id)
void Select(int index)
virtual bool CanHandle(wxXmlNode *node)
void OnContextMenu(wxContextMenuEvent &e)
Target target
Definition: ProjectArray.h:67
IMPLEMENT_DYNAMIC_CLASS(wxTreeListHeaderWindow, wxWindow)
bool UpdateStatus(int index, Project *project)
Batch processor for Hugin with GUI.
void OnRemoveProject(wxCommandEvent &e)
Project * GetProject(int index)
Returns project at index.
Definition: Batch.cpp:296
Definition: Batch.h:46
void OnChangePrefix(wxCommandEvent &e)
wxString path
Definition: ProjectArray.h:69
wxString GetLongerFormatName(std::string str)
static const wxString blendingMechanism[]
bool Create(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name=wxT("panel"))
unsigned int getWidth() const
HuginBase::UIntSet GetSelectedProjects()
wxString GetAttributeString(int i, Project *project)
static const wxString fileFormat[]
wxString GetStatusText()
void ReloadProject(int index, Project *project)
void OnChar(wxKeyEvent &e)
void Fill(Batch *batch)
IntArray columns
void OnColumnWidthChange(wxListEvent &event)
wxString prefix
Definition: ProjectArray.h:71
int GetProjectId(int index)
long id
Definition: ProjectArray.h:63
void SwapProject(int index)