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