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 
32 static const wxString separator = "@@@";
33 
35 {
36  wxXmlResource::Get()->LoadDialog(this, parent, "choice_aspect_dlg");
37  m_aspectList = XRCCTRL(*this, "aspect_listbox", wxListBox);
38  FillListBox();
39  XRCCTRL(*this, "wxID_OK", wxButton)->Bind(wxEVT_BUTTON, &SelectAspectRatioDialog::OnOk, this);
40  XRCCTRL(*this, "add_aspect_button", wxButton)->Bind(wxEVT_BUTTON, &SelectAspectRatioDialog::OnAddAspectRatio, this);
41  XRCCTRL(*this, "remove_aspect_button", wxButton)->Bind(wxEVT_BUTTON, &SelectAspectRatioDialog::OnRemoveAspectRatio, this);
42  m_aspectList->Bind(wxEVT_LISTBOX, &SelectAspectRatioDialog::OnListBoxSelect, this);
44  m_aspectList->SendSelectionChangedEvent(wxEVT_LISTBOX);
45  RestoreFramePosition(this, "SelectCropAspectRatioDialog");
46 }
47 
49 {
50  // store frame position
51  StoreFramePosition(this, "SelectCropAspectRatioDialog");
52  // store list of aspect ratios
54 }
55 
57 {
58  const int selection = m_aspectList->GetSelection();
59  if (selection != wxNOT_FOUND && selection < m_aspectRatios.size())
60  {
61  return m_aspectRatios[selection];
62  }
63  return 1.0;
64 }
65 
66 void SelectAspectRatioDialog::OnOk(wxCommandEvent& e)
67 {
68  const int selection = m_aspectList->GetSelection();
69  if (selection != wxNOT_FOUND)
70  {
71  EndModal(wxID_OK);
72  };
73 }
74 
76 bool CheckInputs(wxWindow* parent, wxTextCtrl* labelCtrl, wxTextCtrl* aspectRatioCtrl, double& value)
77 {
78  // the label should contain at least one character, trim whitespace
79  const wxString label = labelCtrl->GetValue().Trim(true).Trim(false);
80  if (label.IsEmpty() || label.Find(separator) != wxNOT_FOUND)
81  {
82  // empty label or label contains our separator
83  wxMessageBox(_("You must provide a valid label."), _("Warning"), wxOK | wxICON_ERROR, parent);
84  return false;
85  };
86  // check if it is a simple number
87  wxString valueString = aspectRatioCtrl->GetValue();
88  int pos = valueString.Find(":");
89  if (pos != wxNOT_FOUND)
90  {
91  // we have a : in the string, assume it is format value 1:value 2
92  if (pos > 0)
93  {
94  double val1, val2 = 0;
95  if (valueString.Mid(0, pos).ToDouble(&val1) && valueString.Mid(pos + 1).ToDouble(&val2))
96  {
97  if (val2 > 0.0001)
98  {
99  value = val1 / val2;
100  if (value > 1e-4 && value < 10000)
101  {
102  return true;
103  }
104  else
105  {
106  wxMessageBox(wxString::Format(_("The aspect ratio \"%s\" is not in the valid range."), aspectRatioCtrl->GetValue().c_str()), _("Warning"), wxOK | wxICON_ERROR, parent);
107  return false;
108  };
109  };
110  };
111  };
112  }
113  else
114  {
115  // try to read the string as a simple number
116  if (valueString.ToDouble(&value))
117  {
118  if (value > 1e-4 && value < 10000)
119  {
120  return true;
121  }
122  else
123  {
124  wxMessageBox(wxString::Format(_("The aspect ratio \"%s\" is not in the valid range."), aspectRatioCtrl->GetValue().c_str()), _("Warning"), wxOK | wxICON_ERROR, parent);
125  return false;
126  };
127  };
128  };
129  // not a valid input, issue warning
130  wxMessageBox(wxString::Format(_("The input \"%s\" is not a valid number."), aspectRatioCtrl->GetValue().c_str()), _("Warning"), wxOK | wxICON_ERROR, parent);
131  return false;
132 }
133 
135 {
136  wxDialog dlg;
137  wxXmlResource::Get()->LoadDialog(&dlg, this, "add_aspect_dlg");
138  wxTextCtrl* labelCtrl = XRCCTRL(dlg, "aspect_label_textctrl", wxTextCtrl);
139  wxTextCtrl* aspectRatioCtrl = XRCCTRL(dlg, "aspect_ratio_textctrl", wxTextCtrl);
140  aspectRatioCtrl->SetValue("2:1");
141  // check if input is valid when pressing ok
142  dlg.Bind(wxEVT_COMMAND_BUTTON_CLICKED, [labelCtrl, aspectRatioCtrl, &dlg](wxCommandEvent &e)
143  {
144  double val;
145  if (CheckInputs(&dlg, labelCtrl, aspectRatioCtrl, val))
146  {
147  dlg.EndModal(wxID_OK);
148  };
149  }, XRCID("wxID_OK"));
150  if (dlg.ShowModal() == wxID_OK)
151  {
152  double value;
153  if (CheckInputs(&dlg, labelCtrl, aspectRatioCtrl, value))
154  {
155  m_aspectRatioStrings.push_back(labelCtrl->GetValue().Trim(true).Trim(false));
156  m_aspectList->AppendString(m_aspectRatioStrings.back());
157  m_aspectRatios.push_back(value);
159  };
160  };
161 }
162 
164 {
165  const int selection = m_aspectList->GetSelection();
166  // selection should be valid and list should contain at least one item
167  if (selection != wxNOT_FOUND && selection < m_aspectRatioStrings.size() && m_aspectRatioStrings.size() > 1)
168  {
169  m_aspectRatioStrings.RemoveAt(selection);
170  m_aspectRatios.erase(m_aspectRatios.begin() + selection);
171  m_aspectList->Delete(selection);
172  m_aspectList->SetSelection(-1);
174  }
175  else
176  {
177  wxBell();
178  };
179 }
180 
182 {
184 };
185 
187 {
188  const int selection = m_aspectList->GetSelection();
189  // selection should be valid and list should contain at least one item
190  XRCCTRL(*this, "wxID_OK", wxButton)->Enable(selection != wxNOT_FOUND);
191  XRCCTRL(*this, "remove_aspect_button", wxButton)->Enable(selection != wxNOT_FOUND && m_aspectRatioStrings.size() > 1);
192 }
193 
195 {
197  if (m_aspectRatioStrings.IsEmpty())
198  {
199  // could not read from file, populate with default values
200  const auto addAspect = [this](const double v1, const double v2)
201  {
202  this->m_aspectRatioStrings.Add(wxString::Format("%.0f:%.0f", v1, v2));
203  this->m_aspectRatios.push_back(v1 / v2);
204  };
205  addAspect(2, 1);
206  addAspect(3, 1);
207  addAspect(4, 1);
208  addAspect(3, 2);
209  addAspect(4, 3);
210  addAspect(16, 9);
211  addAspect(1, 1);
212  };
213  // add to list
215 }
216 
218 {
219  return wxFileName(hugin_utils::GetUserAppDataDir(), "crop_aspectratio.txt");
220 }
221 
223 {
224  wxTextFile textFile(GetAspectRatioFilename().GetFullPath());
225  if (textFile.Exists())
226  {
227  // text file exists, open it
228  textFile.Open();
229  // iterate all lines
230  for (wxString line = textFile.GetFirstLine(); !textFile.Eof(); line = textFile.GetNextLine())
231  {
232  // remove whitespaces
233  line = line.Trim(true).Trim(false);
234  const size_t pos = line.Find(separator);
235  if (pos != wxNOT_FOUND && pos > 0 && pos + separator.length() < line.length())
236  {
237  const wxString aspectRatio = line.Mid(pos + separator.length());
238  if (aspectRatio.IsEmpty())
239  {
240  continue;
241  };
242  double ratio;
243  // read aspect ratio, use C locale
244  if (aspectRatio.ToCDouble(&ratio))
245  {
246  m_aspectRatioStrings.push_back(line.Mid(0, pos));
247  m_aspectRatios.push_back(ratio);
248  };
249  };
250  };
251  };
252 }
253 
255 {
256  wxTextFile textFile(GetAspectRatioFilename().GetFullPath());
257  if (textFile.Exists())
258  {
259  // text file exists, open it
260  textFile.Open();
261  }
262  else
263  {
264  // file does not exist, create a new one
265  textFile.Create();
266  }
267  // clear all existing items in file
268  textFile.Clear();
269  // write all items
270  for (size_t i = 0; i < m_aspectRatioStrings.size(); ++i)
271  {
272  // use C locale for writing to be on the safe side for number formatting
273  textFile.AddLine(m_aspectRatioStrings[i] + separator + wxString::FromCDouble(m_aspectRatios[i]));
274  };
275  // write to disc and close
276  textFile.Write();
277  textFile.Close();
278 }
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
void StoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Store window size and position in configfile/registry.
Definition: LensCalApp.cpp:210
Definition of dialog for selecting and editing aspect ratios of crop.
void RestoreFramePosition(wxTopLevelWindow *frame, const wxString &basename)
Restore window size and position from configfile/registry.
Definition: LensCalApp.cpp:156
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
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 ListBoxSelectionChanged()
implementation of activation/deactivation of buttons if necessary