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