Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SelectCropAspectRatioDialog.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
11 /* This is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This software is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public
22  * License along with this software. If not, see
23  * <http://www.gnu.org/licenses/>.
24  *
25  */
26 
28 #include "panoinc_WX.h"
29 #include "hugin/huginApp.h"
30 #include <wx/textfile.h>
31 #include "base_wx/wxutils.h"
32 
33 static const wxString separator = "@@@";
34 
36 {
37  wxXmlResource::Get()->LoadDialog(this, parent, "choice_aspect_dlg");
38  m_aspectList = XRCCTRL(*this, "aspect_listbox", wxListBox);
39  FillListBox();
40  XRCCTRL(*this, "wxID_OK", wxButton)->Bind(wxEVT_BUTTON, &SelectAspectRatioDialog::OnOk, this);
41  XRCCTRL(*this, "add_aspect_button", wxButton)->Bind(wxEVT_BUTTON, &SelectAspectRatioDialog::OnAddAspectRatio, this);
42  XRCCTRL(*this, "remove_aspect_button", wxButton)->Bind(wxEVT_BUTTON, &SelectAspectRatioDialog::OnRemoveAspectRatio, this);
43  m_aspectList->Bind(wxEVT_LISTBOX, &SelectAspectRatioDialog::OnListBoxSelect, this);
45  m_aspectList->SendSelectionChangedEvent(wxEVT_LISTBOX);
46  hugin_utils::RestoreFramePosition(this, "SelectCropAspectRatioDialog");
47 }
48 
50 {
51  // store frame position
52  hugin_utils::StoreFramePosition(this, "SelectCropAspectRatioDialog");
53  // store list of aspect ratios
55 }
56 
58 {
59  const int selection = m_aspectList->GetSelection();
60  if (selection != wxNOT_FOUND && selection < m_aspectRatios.size())
61  {
62  return m_aspectRatios[selection];
63  }
64  return 1.0;
65 }
66 
67 void SelectAspectRatioDialog::OnOk(wxCommandEvent& e)
68 {
69  const int selection = m_aspectList->GetSelection();
70  if (selection != wxNOT_FOUND)
71  {
72  EndModal(wxID_OK);
73  };
74 }
75 
77 bool CheckInputs(wxWindow* parent, wxTextCtrl* labelCtrl, wxTextCtrl* aspectRatioCtrl, double& value)
78 {
79  // the label should contain at least one character, trim whitespace
80  const wxString label = labelCtrl->GetValue().Trim(true).Trim(false);
81  if (label.IsEmpty() || label.Find(separator) != wxNOT_FOUND)
82  {
83  // empty label or label contains our separator
84  wxMessageBox(_("You must provide a valid label."), _("Warning"), wxOK | wxICON_ERROR, parent);
85  return false;
86  };
87  // check if it is a simple number
88  wxString valueString = aspectRatioCtrl->GetValue();
89  int pos = valueString.Find(":");
90  if (pos != wxNOT_FOUND)
91  {
92  // we have a : in the string, assume it is format value 1:value 2
93  if (pos > 0)
94  {
95  double val1, val2 = 0;
96  if (valueString.Mid(0, pos).ToDouble(&val1) && valueString.Mid(pos + 1).ToDouble(&val2))
97  {
98  if (val2 > 0.0001)
99  {
100  value = val1 / val2;
101  if (value > 1e-4 && value < 10000)
102  {
103  return true;
104  }
105  else
106  {
107  wxMessageBox(wxString::Format(_("The aspect ratio \"%s\" is not in the valid range."), aspectRatioCtrl->GetValue().c_str()), _("Warning"), wxOK | wxICON_ERROR, parent);
108  return false;
109  };
110  };
111  };
112  };
113  }
114  else
115  {
116  // try to read the string as a simple number
117  if (valueString.ToDouble(&value))
118  {
119  if (value > 1e-4 && value < 10000)
120  {
121  return true;
122  }
123  else
124  {
125  wxMessageBox(wxString::Format(_("The aspect ratio \"%s\" is not in the valid range."), aspectRatioCtrl->GetValue().c_str()), _("Warning"), wxOK | wxICON_ERROR, parent);
126  return false;
127  };
128  };
129  };
130  // not a valid input, issue warning
131  wxMessageBox(wxString::Format(_("The input \"%s\" is not a valid number."), aspectRatioCtrl->GetValue().c_str()), _("Warning"), wxOK | wxICON_ERROR, parent);
132  return false;
133 }
134 
136 {
137  wxDialog dlg;
138  wxXmlResource::Get()->LoadDialog(&dlg, this, "add_aspect_dlg");
139  wxTextCtrl* labelCtrl = XRCCTRL(dlg, "aspect_label_textctrl", wxTextCtrl);
140  wxTextCtrl* aspectRatioCtrl = XRCCTRL(dlg, "aspect_ratio_textctrl", wxTextCtrl);
141  aspectRatioCtrl->SetValue("2:1");
142  // check if input is valid when pressing ok
143  dlg.Bind(wxEVT_COMMAND_BUTTON_CLICKED, [labelCtrl, aspectRatioCtrl, &dlg](wxCommandEvent &e)
144  {
145  double val;
146  if (CheckInputs(&dlg, labelCtrl, aspectRatioCtrl, val))
147  {
148  dlg.EndModal(wxID_OK);
149  };
150  }, XRCID("wxID_OK"));
151  if (dlg.ShowModal() == wxID_OK)
152  {
153  double value;
154  if (CheckInputs(&dlg, labelCtrl, aspectRatioCtrl, value))
155  {
156  m_aspectRatioStrings.push_back(labelCtrl->GetValue().Trim(true).Trim(false));
157  m_aspectList->AppendString(m_aspectRatioStrings.back());
158  m_aspectRatios.push_back(value);
160  };
161  };
162 }
163 
165 {
166  const int selection = m_aspectList->GetSelection();
167  // selection should be valid and list should contain at least one item
168  if (selection != wxNOT_FOUND && selection < m_aspectRatioStrings.size() && m_aspectRatioStrings.size() > 1)
169  {
170  m_aspectRatioStrings.RemoveAt(selection);
171  m_aspectRatios.erase(m_aspectRatios.begin() + selection);
172  m_aspectList->Delete(selection);
173  m_aspectList->SetSelection(-1);
175  }
176  else
177  {
178  wxBell();
179  };
180 }
181 
183 {
185 };
186 
188 {
189  const int selection = m_aspectList->GetSelection();
190  // selection should be valid and list should contain at least one item
191  XRCCTRL(*this, "wxID_OK", wxButton)->Enable(selection != wxNOT_FOUND);
192  XRCCTRL(*this, "remove_aspect_button", wxButton)->Enable(selection != wxNOT_FOUND && m_aspectRatioStrings.size() > 1);
193 }
194 
196 {
198  if (m_aspectRatioStrings.IsEmpty())
199  {
200  // could not read from file, populate with default values
201  const auto addAspect = [this](const double v1, const double v2)
202  {
203  this->m_aspectRatioStrings.Add(wxString::Format("%.0f:%.0f", v1, v2));
204  this->m_aspectRatios.push_back(v1 / v2);
205  };
206  addAspect(2, 1);
207  addAspect(3, 1);
208  addAspect(4, 1);
209  addAspect(3, 2);
210  addAspect(4, 3);
211  addAspect(16, 9);
212  addAspect(1, 1);
213  };
214  // add to list
216 }
217 
219 {
220  return wxFileName(hugin_utils::GetUserAppDataDir(), "crop_aspectratio.txt");
221 }
222 
224 {
225  wxTextFile textFile(GetAspectRatioFilename().GetFullPath());
226  if (textFile.Exists())
227  {
228  // text file exists, open it
229  textFile.Open();
230  // iterate all lines
231  for (wxString line = textFile.GetFirstLine(); !textFile.Eof(); line = textFile.GetNextLine())
232  {
233  // remove whitespaces
234  line = line.Trim(true).Trim(false);
235  const size_t pos = line.Find(separator);
236  if (pos != wxNOT_FOUND && pos > 0 && pos + separator.length() < line.length())
237  {
238  const wxString aspectRatio = line.Mid(pos + separator.length());
239  if (aspectRatio.IsEmpty())
240  {
241  continue;
242  };
243  double ratio;
244  // read aspect ratio, use C locale
245  if (aspectRatio.ToCDouble(&ratio))
246  {
247  m_aspectRatioStrings.push_back(line.Mid(0, pos));
248  m_aspectRatios.push_back(ratio);
249  };
250  };
251  };
252  };
253 }
254 
256 {
257  wxTextFile textFile(GetAspectRatioFilename().GetFullPath());
258  if (textFile.Exists())
259  {
260  // text file exists, open it
261  textFile.Open();
262  }
263  else
264  {
265  // file does not exist, create a new one
266  textFile.Create();
267  }
268  // clear all existing items in file
269  textFile.Clear();
270  // write all items
271  for (size_t i = 0; i < m_aspectRatioStrings.size(); ++i)
272  {
273  // use C locale for writing to be on the safe side for number formatting
274  textFile.AddLine(m_aspectRatioStrings[i] + separator + wxString::FromCDouble(m_aspectRatios[i]));
275  };
276  // write to disc and close
277  textFile.Write();
278  textFile.Close();
279 }
bool CheckInputs(wxWindow *parent, wxTextCtrl *labelCtrl, wxTextCtrl *aspectRatioCtrl, double &value)
check the input of the add aspect ratio dialog
std::vector< double > m_aspectRatios
vector with values of all aspect ratios, ratio=width/height
static const wxString separator
void OnListBoxSelect(wxCommandEvent &e)
event handler for activation/deactivation of buttons if necessary
void OnOk(wxCommandEvent &e)
handler for Ok, check for valid inputs
wxArrayString m_aspectRatioStrings
array with names of all aspect ratios
static char * line
Definition: svm.cpp:2784
void LoadAspectRatios()
load aspect ratios from file
Definition of dialog for selecting and editing aspect ratios of crop.
void SaveAspectRatios()
save the aspect ratios to the file
double GetSelectedAspectRatio() const
returns the selected aspect ratio
void OnRemoveAspectRatio(wxCommandEvent &e)
handler for removing selected aspect ratio
void StoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Definition: wxutils.cpp:135
include file for the hugin project
void OnAddAspectRatio(wxCommandEvent &e)
handler for adding new aspect ratio setting
std::string GetUserAppDataDir()
returns the directory for user specific Hugin settings, e.g.
Definition: utils.cpp:497
wxListBox * m_aspectList
pointer to wxListBox of aspect ratios
wxFileName GetAspectRatioFilename() const
returns the file name for the list of aspect ratios
~SelectAspectRatioDialog()
destructor, save position and list of aspect ratios
SelectAspectRatioDialog(wxWindow *parent)
constructor, build dialog and load settings from file
void FillListBox()
read the settings from the file and add them to the list box if the file does not exist...
void RestoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Definition: wxutils.cpp:67
void ListBoxSelectionChanged()
implementation of activation/deactivation of buttons if necessary