1 /*******************************************************
2 Copyright (C) 2014 Gabriele-V
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 ********************************************************/
18
19 #include "mmSimpleDialogs.h"
20 #include "constants.h"
21 #include "mmex.h"
22 #include "paths.h"
23 #include "util.h"
24
25 #include "model/Model_Account.h"
26 #include "model/Model_Setting.h"
27
28 #include <wx/richtooltip.h>
29
30 //mmSingleChoiceDialog
mmSingleChoiceDialog()31 mmSingleChoiceDialog::mmSingleChoiceDialog()
32 {
33 }
mmSingleChoiceDialog(wxWindow * parent,const wxString & message,const wxString & caption,const wxArrayString & choices)34 mmSingleChoiceDialog::mmSingleChoiceDialog(wxWindow *parent, const wxString& message,
35 const wxString& caption, const wxArrayString& choices)
36 {
37 wxSingleChoiceDialog::Create(parent, message, caption, choices);
38 fix_translation();
39 }
mmSingleChoiceDialog(wxWindow * parent,const wxString & message,const wxString & caption,const Model_Account::Data_Set & accounts)40 mmSingleChoiceDialog::mmSingleChoiceDialog(wxWindow* parent, const wxString& message,
41 const wxString& caption, const Model_Account::Data_Set& accounts)
42 {
43 wxArrayString choices;
44 for (const auto & item : accounts) choices.Add(item.ACCOUNTNAME);
45 wxSingleChoiceDialog::Create(parent, message, caption, choices);
46 fix_translation();
47 }
fix_translation()48 void mmSingleChoiceDialog::fix_translation()
49 {
50 wxButton* ok = (wxButton*)FindWindow(wxID_OK);
51 if (ok) ok->SetLabel(_("&OK "));
52 wxButton* ca = (wxButton*)FindWindow(wxID_CANCEL);
53 if (ca) ca->SetLabel(wxGetTranslation(g_CancelLabel));
54 }
55
56 // mmDialogComboBoxAutocomplete
mmDialogComboBoxAutocomplete()57 mmDialogComboBoxAutocomplete::mmDialogComboBoxAutocomplete()
58 {
59 }
mmDialogComboBoxAutocomplete(wxWindow * parent,const wxString & message,const wxString & caption,const wxString & defaultText,const wxArrayString & choices)60 mmDialogComboBoxAutocomplete::mmDialogComboBoxAutocomplete(wxWindow *parent, const wxString& message, const wxString& caption,
61 const wxString& defaultText, const wxArrayString& choices)
62 {
63 long style = wxCAPTION | wxRESIZE_BORDER | wxCLOSE_BOX;
64 Default = defaultText;
65 Choices = choices;
66 Message = message;
67 Create(parent, wxID_STATIC, caption, wxDefaultPosition, wxSize(300, 100), style);
68 }
69
Create(wxWindow * parent,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)70 bool mmDialogComboBoxAutocomplete::Create(wxWindow* parent, wxWindowID id,
71 const wxString& caption, const wxPoint& pos, const wxSize& size, long style)
72 {
73 wxDialog::Create(parent, id, caption, pos, size, style);
74 const wxSizerFlags flags = wxSizerFlags().Align(wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL).Border(wxLEFT | wxRIGHT, 15);
75
76 wxBoxSizer* Sizer = new wxBoxSizer(wxVERTICAL);
77 this->SetSizer(Sizer);
78
79 Sizer->AddSpacer(10);
80 wxStaticText* headerText = new wxStaticText(this, wxID_STATIC, Message);
81 Sizer->Add(headerText, flags);
82 Sizer->AddSpacer(15);
83 cbText_ = new wxComboBox(this, wxID_STATIC, Default, wxDefaultPosition, wxSize(150, -1), Choices);
84 cbText_->AutoComplete(Choices);
85 Sizer->Add(cbText_, wxSizerFlags(flags).Expand());
86 Sizer->AddSpacer(20);
87 wxSizer* Button = CreateButtonSizer(wxOK | wxCANCEL);
88 Sizer->Add(Button, flags);
89 Sizer->AddSpacer(10);
90
91 cbText_->SetFocus();
92 GetSizer()->Fit(this);
93 GetSizer()->SetSizeHints(this);
94 Centre();
95 return true;
96 }
97
selectLanguageDlg(wxWindow * parent,const wxString & langPath,bool verbose)98 const wxString mmDialogs::selectLanguageDlg(wxWindow *parent, const wxString &langPath, bool verbose)
99 {
100 wxString lang;
101
102 wxArrayString lang_files;
103 wxFileName fn(langPath, "");
104 fn.AppendDir("en");
105 size_t cnt = wxDir::GetAllFiles(fn.GetPath(), &lang_files, "*.mo");
106
107 if (!cnt)
108 {
109 if (verbose)
110 {
111 wxString s = wxString::Format("Can't find language files (.mo) at \"%s\"", fn.GetPath());
112
113 wxMessageDialog dlg(parent, s, "Error", wxOK | wxICON_ERROR);
114 dlg.ShowModal();
115 }
116
117 return lang;
118 }
119
120 for (size_t i = 0; i < cnt; ++i)
121 {
122 wxFileName fname(lang_files[i]);
123 lang_files[i] = fname.GetName().Left(1).Upper() + fname.GetName().SubString(1, fname.GetName().Len());
124 }
125
126 lang_files.Sort(CaseInsensitiveCmp);
127 lang = wxGetSingleChoice("Please choose language", "Languages", lang_files, parent);
128
129 return lang.Lower();
130 }
131
132 /*
133 locale.AddCatalog(lang) calls wxLogWarning and returns true for corrupted .mo file,
134 so I should use locale.IsLoaded(lang) also.
135 */
mmSelectLanguage(mmGUIApp * app,wxWindow * window,bool forced_show_dlg,bool save_setting)136 const wxString mmDialogs::mmSelectLanguage(mmGUIApp *app, wxWindow* window, bool forced_show_dlg, bool save_setting)
137 {
138 wxString lang;
139
140 const wxString langPath = mmex::getPathShared(mmex::LANG_DIR);
141 wxLocale &locale = app->getLocale();
142
143 if (wxDir::Exists(langPath))
144 {
145 locale.AddCatalogLookupPathPrefix(langPath);
146 }
147 else
148 {
149 if (forced_show_dlg)
150 {
151 wxMessageDialog dlg(window
152 , wxString::Format(_("Directory of language files does not exist:\n%s"), langPath)
153 , _("Error"), wxOK | wxICON_ERROR);
154 dlg.ShowModal();
155 }
156
157 return lang;
158 }
159
160 if (!forced_show_dlg)
161 {
162 lang = Model_Setting::instance().GetStringSetting(LANGUAGE_PARAMETER, "english");
163 if (!lang.empty() && locale.AddCatalog(lang) && locale.IsLoaded(lang))
164 {
165 mmOptions::instance().language_ = lang;
166 return lang;
167 }
168 }
169
170 lang = selectLanguageDlg(window, langPath, forced_show_dlg);
171
172 if (save_setting && !lang.empty())
173 {
174 bool ok = locale.AddCatalog(lang) && locale.IsLoaded(lang);
175 if (!ok) lang.clear(); // bad .mo file
176 mmOptions::instance().language_ = lang;
177 Model_Setting::instance().Set(LANGUAGE_PARAMETER, lang);
178 }
179
180 return lang;
181 }
182
183 /* Error Messages --------------------------------------------------------*/
MessageError(wxWindow * parent,const wxString & message,const wxString & messageheader)184 void mmErrorDialogs::MessageError(wxWindow *parent
185 , const wxString &message, const wxString &messageheader)
186 {
187 wxMessageDialog msgDlg(parent, message, messageheader, wxOK | wxICON_ERROR);
188 msgDlg.ShowModal();
189 }
190
MessageWarning(wxWindow * parent,const wxString & message,const wxString & messageheader)191 void mmErrorDialogs::MessageWarning(wxWindow *parent
192 , const wxString &message, const wxString &messageheader)
193 {
194 wxMessageDialog msgDlg(parent, message, messageheader, wxOK | wxICON_WARNING);
195 msgDlg.ShowModal();
196 }
197
MessageInvalid(wxWindow * parent,const wxString & message)198 void mmErrorDialogs::MessageInvalid(wxWindow *parent, const wxString &message)
199 {
200 const wxString& msg = wxString::Format(_("Entry %s is invalid"), message);
201 MessageError(parent, msg, _("Invalid Entry"));
202 }
203
InvalidCategory(wxWindow * button)204 void mmErrorDialogs::InvalidCategory(wxWindow *button)
205 {
206 wxRichToolTip tip(_("Invalid Category"),
207 _("Please use this button for category selection\nor use the 'Split' checkbox for multiple categories.")
208 + "\n");
209 tip.SetIcon(wxICON_WARNING);
210 tip.ShowFor(button);
211 }
212
InvalidFile(wxWindow * object,bool open)213 void mmErrorDialogs::InvalidFile(wxWindow *object, bool open)
214 {
215 const wxString& errorHeader = open ? _("Unable to open file.") : _("File name is empty.");
216 wxString errorMessage = _("Please select the file for this operation.");
217
218 const wxString errorTips = _("Selection can be made by using Search button.");
219 errorMessage = errorMessage + "\n\n" + errorTips + "\n";
220
221 wxRichToolTip tip(errorHeader, errorMessage);
222 tip.SetIcon(wxICON_WARNING);
223 tip.ShowFor(object);
224 }
225
InvalidAccount(wxWindow * object,bool transfer)226 void mmErrorDialogs::InvalidAccount(wxWindow *object, bool transfer)
227 {
228 const wxString& errorHeader = _("Invalid Account");
229 wxString errorMessage;
230 if (!transfer)
231 errorMessage = _("Please select the account for this transaction.");
232 else
233 errorMessage = _("Please specify which account the transfer is going to.");
234
235 wxString errorTips = _("Selection can be made by using the dropdown button.");
236 errorMessage = errorMessage + "\n\n" + errorTips + "\n";
237
238 wxRichToolTip tip(errorHeader, errorMessage);
239 tip.SetIcon(wxICON_WARNING);
240 tip.ShowFor(object);
241 }
242
InvalidPayee(wxWindow * object)243 void mmErrorDialogs::InvalidPayee(wxWindow *object)
244 {
245 const wxString& errorHeader = _("Invalid Payee");
246 const wxString& errorMessage = (_("Please type in a new payee,\nor make a selection using the dropdown button.")
247 + "\n");
248 wxRichToolTip tip(errorHeader, errorMessage);
249 tip.SetIcon(wxICON_WARNING);
250 tip.ShowFor(object);
251 }
252
InvalidName(wxTextCtrl * textBox)253 void mmErrorDialogs::InvalidName(wxTextCtrl *textBox)
254 {
255 const wxString& errorHeader = _("Invalid Name");
256 const wxString& errorMessage = (_("Please type in a non empty name.")
257 + "\n");
258 wxRichToolTip tip(errorHeader, errorMessage);
259 tip.SetIcon(wxICON_WARNING);
260 tip.ShowFor((wxWindow*)textBox);
261 }
262