1 // -*- c-basic-offset: 4 -*-
2 
3 /** @file CPDetectorDialog.cpp
4  *
5  *  @brief implementation of CPDetectorDialog class,
6  *         which allows changing options of CP detectors
7  *
8  *  @author Thomas Modes
9  *
10  */
11 
12 /*  This is free software; you can redistribute it and/or
13  *  modify it under the terms of the GNU General Public
14  *  License as published by the Free Software Foundation; either
15  *  version 2 of the License, or (at your option) any later version.
16  *
17  *  This software is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  *  Lesser General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public
23  *  License along with this software. If not, see
24  *  <http://www.gnu.org/licenses/>.
25  *
26  */
27 
28 #ifdef _WIN32
29 #include "wx/msw/wrapwin.h"
30  // Mingw define still DIFFERENCE, which conflicts with vigra, so disable it
31 #undef DIFFERENCE
32 #endif
33 #include "hugin/CPDetectorDialog.h"
34 #include "hugin_config.h"
35 #include "base_wx/huginConfig.h"
36 #include "hugin/config_defaults.h"
37 #include "hugin/huginApp.h"
38 
39 #if defined MAC_SELF_CONTAINED_BUNDLE
40   #include "base_wx/platform.h"
41   #include <wx/dir.h>
42   #include <CoreFoundation/CFBundle.h>
43 #endif
44 
45 // dialog for showing settings of one autopano setting
46 
BEGIN_EVENT_TABLE(CPDetectorDialog,wxDialog)47 BEGIN_EVENT_TABLE(CPDetectorDialog,wxDialog)
48     EVT_BUTTON(wxID_OK, CPDetectorDialog::OnOk)
49     EVT_BUTTON(XRCID("prefs_cpdetector_program_select"),CPDetectorDialog::OnSelectPath)
50     EVT_BUTTON(XRCID("prefs_cpdetector_program_descriptor_select"),CPDetectorDialog::OnSelectPathDescriptor)
51     EVT_BUTTON(XRCID("prefs_cpdetector_program_matcher_select"),CPDetectorDialog::OnSelectPathMatcher)
52     EVT_BUTTON(XRCID("prefs_cpdetector_program_stack_select"),CPDetectorDialog::OnSelectPathStack)
53     EVT_CHOICE(XRCID("prefs_cpdetector_type"),CPDetectorDialog::OnTypeChange)
54     EVT_CHOICEBOOK_PAGE_CHANGING(XRCID("choicebook_steps"),CPDetectorDialog::OnStepChanging)
55 END_EVENT_TABLE()
56 
57 CPDetectorDialog::CPDetectorDialog(wxWindow* parent)
58 {
59     wxXmlResource::Get()->LoadDialog(this, parent, wxT("cpdetector_dialog"));
60 #ifdef __WXMSW__
61     wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.ico"),wxBITMAP_TYPE_ICO);
62 #else
63     wxIcon myIcon(huginApp::Get()->GetXRCPath() + wxT("data/hugin.png"),wxBITMAP_TYPE_PNG);
64 #endif
65     SetIcon(myIcon);
66 
67     //restore frame position and size
68     RestoreFramePosition(this,wxT("CPDetectorDialog"));
69 
70     m_edit_desc = XRCCTRL(*this, "prefs_cpdetector_desc", wxTextCtrl);
71     m_edit_prog = XRCCTRL(*this, "prefs_cpdetector_program", wxTextCtrl);
72     m_edit_args = XRCCTRL(*this, "prefs_cpdetector_args", wxTextCtrl);
73     m_label_args_cleanup = XRCCTRL(*this, "prefs_cpdetector_args_label_cleanup", wxStaticText);
74     m_edit_args_cleanup = XRCCTRL(*this, "prefs_cpdetector_args_cleanup", wxTextCtrl);
75     m_edit_prog_descriptor = XRCCTRL(*this, "prefs_cpdetector_program_descriptor", wxTextCtrl);
76     m_edit_args_descriptor = XRCCTRL(*this, "prefs_cpdetector_args_descriptor", wxTextCtrl);
77     m_edit_prog_matcher = XRCCTRL(*this, "prefs_cpdetector_program_matcher", wxTextCtrl);
78     m_edit_args_matcher = XRCCTRL(*this, "prefs_cpdetector_args_matcher", wxTextCtrl);
79     m_edit_prog_stack = XRCCTRL(*this, "prefs_cpdetector_program_stack", wxTextCtrl);
80     m_edit_args_stack = XRCCTRL(*this, "prefs_cpdetector_args_stack", wxTextCtrl);
81     m_check_option = XRCCTRL(*this, "prefs_cpdetector_option", wxCheckBox);
82     m_cpdetector_type = XRCCTRL(*this, "prefs_cpdetector_type", wxChoice);
83     m_choice_step = XRCCTRL(*this, "choicebook_steps", wxChoicebook);
84     // enable auto completion
85     m_edit_prog->AutoCompleteFileNames();
86     m_edit_prog_descriptor->AutoCompleteFileNames();
87     m_edit_prog_matcher->AutoCompleteFileNames();
88     m_edit_prog_stack->AutoCompleteFileNames();
89     m_cpdetector_type->SetSelection(1);
90     ChangeType();
91 };
92 
~CPDetectorDialog()93 CPDetectorDialog::~CPDetectorDialog()
94 {
95     StoreFramePosition(this,wxT("CPDetectorDialog"));
96 };
97 
OnOk(wxCommandEvent & e)98 void CPDetectorDialog::OnOk(wxCommandEvent & e)
99 {
100 #ifdef __WXMAC__
101     if(m_cpdetector_type->GetSelection()==0)
102     {
103         wxMessageBox(_("Autopano from http://autopano.kolor.com is not available for OS X"),
104                      _("Using Autopano-Sift instead"),wxOK|wxICON_EXCLAMATION, this);
105         m_cpdetector_type->SetSelection(1);
106     };
107 #endif
108     bool valid=true;
109     valid=valid && (m_edit_desc->GetValue().Trim().Len()>0);
110     if(m_choice_step->GetSelection()==0)
111     {
112         //detector with one step
113         valid=valid && (m_edit_prog->GetValue().Trim().Len()>0);
114         valid=valid && (m_edit_args->GetValue().Trim().Len()>0);
115     }
116     else
117     {
118         //detector with two steps
119         valid=valid && (m_edit_prog_descriptor->GetValue().Trim().Len()>0);
120         valid=valid && (m_edit_prog_matcher->GetValue().Trim().Len()>0);
121         valid=valid && (m_edit_args_descriptor->GetValue().Trim().Len()>0);
122         valid=valid && (m_edit_args_matcher->GetValue().Trim().Len()>0);
123     };
124     if(CPDetectorSetting::ContainsStacks((CPDetectorType)(m_cpdetector_type->GetSelection())))
125         if(m_edit_prog_stack->GetValue().Trim().Len()>0)
126             valid=valid && (m_edit_args_stack->GetValue().Trim().Len()>0);
127     if(valid)
128         this->EndModal(wxOK);
129     else
130         wxMessageBox(_("At least one input field is empty.\nPlease check your inputs."),
131             _("Warning"),wxOK | wxICON_ERROR,this);
132 };
133 
UpdateFields(CPDetectorConfig * cpdet_config,int index)134 void CPDetectorDialog::UpdateFields(CPDetectorConfig* cpdet_config,int index)
135 {
136     m_edit_desc->SetValue(cpdet_config->settings[index].GetCPDetectorDesc());
137     //program names and arguments
138     if(cpdet_config->settings[index].IsTwoStepDetector())
139     {
140         m_choice_step->SetSelection(1);
141         m_edit_prog_descriptor->SetValue(cpdet_config->settings[index].GetProg());
142         m_edit_prog_matcher->SetValue(cpdet_config->settings[index].GetProgMatcher());
143         m_edit_args_descriptor->SetValue(cpdet_config->settings[index].GetArgs());
144         m_edit_args_matcher->SetValue(cpdet_config->settings[index].GetArgsMatcher());
145     }
146     else
147     {
148         m_choice_step->SetSelection(0);
149         m_edit_prog->SetValue(cpdet_config->settings[index].GetProg());
150         m_edit_args->SetValue(cpdet_config->settings[index].GetArgs());
151         if(cpdet_config->settings[index].IsCleanupPossible())
152         {
153             m_edit_args_cleanup->SetValue(cpdet_config->settings[index].GetArgsCleanup());
154         };
155     };
156     if(cpdet_config->settings[index].ContainsStacks())
157     {
158         m_edit_prog_stack->SetValue(cpdet_config->settings[index].GetProgStack());
159         m_edit_args_stack->SetValue(cpdet_config->settings[index].GetArgsStack());
160     };
161     m_cpdetector_type->SetSelection(cpdet_config->settings[index].GetType());
162     m_check_option->SetValue(cpdet_config->settings[index].GetOption());
163     ChangeType();
164 };
165 
UpdateSettings(CPDetectorConfig * cpdet_config,int index)166 void CPDetectorDialog::UpdateSettings(CPDetectorConfig* cpdet_config,int index)
167 {
168     cpdet_config->settings[index].SetCPDetectorDesc(m_edit_desc->GetValue().Trim());
169     cpdet_config->settings[index].SetType((CPDetectorType)m_cpdetector_type->GetSelection());
170     if(m_choice_step->GetSelection()==0)
171     {
172         cpdet_config->settings[index].SetProg(m_edit_prog->GetValue().Trim());
173         cpdet_config->settings[index].SetArgs(m_edit_args->GetValue().Trim());
174         if(cpdet_config->settings[index].IsCleanupPossible())
175         {
176             cpdet_config->settings[index].SetArgsCleanup(m_edit_args_cleanup->GetValue().Trim());
177         }
178         else
179         {
180             cpdet_config->settings[index].SetArgsCleanup(wxEmptyString);
181         };
182     }
183     else
184     {
185         cpdet_config->settings[index].SetProg(m_edit_prog_descriptor->GetValue().Trim());
186         cpdet_config->settings[index].SetArgs(m_edit_args_descriptor->GetValue().Trim());
187         cpdet_config->settings[index].SetProgMatcher(m_edit_prog_matcher->GetValue().Trim());
188         cpdet_config->settings[index].SetArgsMatcher(m_edit_args_matcher->GetValue().Trim());
189     };
190     if(cpdet_config->settings[index].ContainsStacks())
191     {
192         cpdet_config->settings[index].SetProgStack(m_edit_prog_stack->GetValue().Trim());
193         cpdet_config->settings[index].SetArgsStack(m_edit_args_stack->GetValue().Trim());
194     }
195     else
196     {
197         cpdet_config->settings[index].SetProgStack(wxEmptyString);
198         cpdet_config->settings[index].SetArgsStack(wxEmptyString);
199     }
200     cpdet_config->settings[index].SetOption(m_check_option->IsChecked());
201 };
202 
OnTypeChange(wxCommandEvent & e)203 void CPDetectorDialog::OnTypeChange(wxCommandEvent &e)
204 {
205     ChangeType();
206 };
207 
ChangeType()208 void CPDetectorDialog::ChangeType()
209 {
210     CPDetectorType type=(CPDetectorType)m_cpdetector_type->GetSelection();
211     if(type==CPDetector_AutoPano)
212     {
213         m_choice_step->SetSelection(0);
214         twoStepAllowed=false;
215     }
216     else
217     {
218         twoStepAllowed=true;
219     }
220     XRCCTRL(*this,"panel_stack",wxPanel)->Enable(CPDetectorSetting::ContainsStacks(type));
221     switch(type)
222     {
223         case CPDetector_AutoPanoSiftMultiRow:
224         case CPDetector_AutoPanoSiftMultiRowStack:
225             m_check_option->SetLabel(_("Try to connect all overlapping images."));
226             m_check_option->Enable(true);
227             m_check_option->Show(true);
228             XRCCTRL(*this, "prefs_cpdetector_no_option",wxStaticText)->Show(false);
229             break;
230         case CPDetector_AutoPanoSiftPreAlign:
231             m_check_option->SetLabel(_("Only work on image pairs without control points."));
232             m_check_option->Enable(true);
233             m_check_option->Show(true);
234             XRCCTRL(*this, "prefs_cpdetector_no_option",wxStaticText)->Show(false);
235             break;
236         default:
237             XRCCTRL(*this, "prefs_cpdetector_no_option",wxStaticText)->Show(true);
238             m_check_option->Enable(false);
239             m_check_option->Show(false);
240             break;
241     };
242     m_check_option->GetParent()->Layout();
243     bool cleanup_possible=CPDetectorSetting::IsCleanupPossible(type);
244     m_label_args_cleanup->Enable(cleanup_possible);
245     m_label_args_cleanup->Show(cleanup_possible);
246     m_edit_args_cleanup->Enable(cleanup_possible);
247     m_edit_args_cleanup->Show(cleanup_possible);
248     m_label_args_cleanup->GetParent()->Layout();
249     Layout();
250 };
251 
252 
ShowFileDialog(wxString & prog)253 bool CPDetectorDialog::ShowFileDialog(wxString & prog)
254 {
255     wxFileName executable(prog);
256 #ifdef MAC_SELF_CONTAINED_BUNDLE
257     wxString autopanoPath = MacGetPathToUserAppSupportAutoPanoFolder();
258 #endif
259     wxFileDialog dlg(this,_("Select control point detector program"),
260 #ifdef MAC_SELF_CONTAINED_BUNDLE
261             autopanoPath,
262 #else
263             executable.GetPath(),
264 #endif
265             executable.GetFullName(),
266 #ifdef __WXMSW__
267             _("Executables (*.exe,*.vbs,*.cmd, *.bat)|*.exe;*.vbs;*.cmd;*.bat"),
268 #else
269             wxT(""),
270 #endif
271             wxFD_OPEN, wxDefaultPosition);
272     if (dlg.ShowModal() == wxID_OK)
273     {
274         prog=dlg.GetPath();
275         return true;
276     }
277     else
278         return false;
279 };
280 
OnSelectPath(wxCommandEvent & e)281 void CPDetectorDialog::OnSelectPath(wxCommandEvent &e)
282 {
283     wxString prog=m_edit_prog->GetValue();
284     if (ShowFileDialog(prog))
285         m_edit_prog->SetValue(prog);
286 };
287 
OnSelectPathDescriptor(wxCommandEvent & e)288 void CPDetectorDialog::OnSelectPathDescriptor(wxCommandEvent &e)
289 {
290     wxString prog=m_edit_prog_descriptor->GetValue();
291     if (ShowFileDialog(prog))
292         m_edit_prog_descriptor->SetValue(prog);
293 };
294 
OnSelectPathMatcher(wxCommandEvent & e)295 void CPDetectorDialog::OnSelectPathMatcher(wxCommandEvent &e)
296 {
297     wxString prog=m_edit_prog_matcher->GetValue();
298     if (ShowFileDialog(prog))
299         m_edit_prog_matcher->SetValue(prog);
300 };
301 
OnSelectPathStack(wxCommandEvent & e)302 void CPDetectorDialog::OnSelectPathStack(wxCommandEvent &e)
303 {
304     wxString prog=m_edit_prog_stack->GetValue();
305     if (ShowFileDialog(prog))
306         m_edit_prog_stack->SetValue(prog);
307 };
308 
OnStepChanging(wxChoicebookEvent & e)309 void CPDetectorDialog::OnStepChanging(wxChoicebookEvent &e)
310 {
311     if(!twoStepAllowed && e.GetOldSelection()==0)
312     {
313         wxBell();
314         e.Veto();
315     };
316 };
317