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