1 /*
2 * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3 * http://www.gnu.org/licenses/lgpl-3.0.html
4 *
5 * $Revision: 11365 $
6 * $Id: editpathdlg.cpp 11365 2018-04-12 07:02:34Z fuscated $
7 * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/sdk/editpathdlg.cpp $
8 */
9
10 #include "sdk_precomp.h"
11
12 #ifndef CB_PRECOMP
13 #include <wx/intl.h>
14 #include <wx/xrc/xmlres.h>
15 #include <wx/textctrl.h>
16 #include <wx/button.h>
17 #include <wx/filename.h>
18 #include <wx/stattext.h>
19 #include "globals.h"
20 #include "manager.h"
21 #include "macrosmanager.h"
22 #include "uservarmanager.h"
23 #endif
24
25 #include "editpathdlg.h"
26 #include <wx/filedlg.h>
27 #include <wx/msgdlg.h>
28
29 // remember last path, when supplied path is empty
30 static wxString s_LastPath;
31
BEGIN_EVENT_TABLE(EditPathDlg,wxScrollingDialog)32 BEGIN_EVENT_TABLE(EditPathDlg, wxScrollingDialog)
33 EVT_UPDATE_UI(-1, EditPathDlg::OnUpdateUI)
34 EVT_BUTTON(XRCID("btnBrowse"), EditPathDlg::OnBrowse)
35 EVT_BUTTON(XRCID("btnOther"), EditPathDlg::OnOther)
36 END_EVENT_TABLE()
37
38 EditPathDlg::EditPathDlg(wxWindow* parent,
39 const wxString& path,
40 const wxString& basepath,
41 const wxString& title,
42 const wxString& message,
43 const bool wantDir,
44 const bool allowMultiSel,
45 const wxString& filter)
46 {
47 //ctor
48 wxXmlResource::Get()->LoadObject(this, parent, _T("dlgEditPath"),_T("wxScrollingDialog"));
49 XRCCTRL(*this, "wxID_OK", wxButton)->SetDefault();
50
51 XRCCTRL(*this, "txtPath", wxTextCtrl)->SetValue(path);
52 XRCCTRL(*this, "dlgEditPath", wxScrollingDialog)->SetTitle(title);
53
54 if (!wantDir) {
55 XRCCTRL(*this, "lblText", wxStaticText)->SetLabel(_("File:"));
56 }
57
58 m_Path = path;
59 m_WantDir = wantDir;
60 m_AllowMultiSel = allowMultiSel;
61 m_Message = message;
62 m_Basepath = basepath;
63 m_Filter = filter;
64 m_AskMakeRelative = true;
65 m_ShowCreateDirButton = false;
66 XRCCTRL(*this, "txtPath", wxTextCtrl)->SetFocus();
67
68 // Limit vertical resizing.
69 SetMinSize(wxSize(400, GetMinHeight()));
70 SetMaxSize(wxSize(-1, GetMinHeight()));
71 }
72
~EditPathDlg()73 EditPathDlg::~EditPathDlg()
74 {
75 //dtor
76 }
77
OnUpdateUI(cb_unused wxUpdateUIEvent & event)78 void EditPathDlg::OnUpdateUI(cb_unused wxUpdateUIEvent& event)
79 {
80 wxButton* btn = (wxButton*)FindWindow(wxID_OK);
81 if (btn)
82 btn->Enable(!XRCCTRL(*this, "txtPath", wxTextCtrl)->GetValue().IsEmpty());
83 }
84
OnBrowse(cb_unused wxCommandEvent & event)85 void EditPathDlg::OnBrowse(cb_unused wxCommandEvent& event)
86 {
87 wxFileName path;
88 wxArrayString multi;
89
90 wxString val = XRCCTRL(*this, "txtPath", wxTextCtrl)->GetValue();
91 int idx = val.Find(DEFAULT_ARRAY_SEP);
92 if (idx != -1)
93 val.Remove(idx);
94 wxFileName fname(val);
95
96 if (m_WantDir)
97 {
98 // try to "decode" custom var
99 wxString initial_val = val;
100 Manager::Get()->GetMacrosManager()->ReplaceEnvVars(val);
101 fname = val;
102 fname.MakeAbsolute(m_Basepath);
103 m_Path = fname.GetFullPath();
104
105 path = ChooseDirectory(this, m_Message, (m_Path.IsEmpty() ? s_LastPath : m_Path),
106 m_Basepath, false, m_ShowCreateDirButton);
107
108 if (path.GetFullPath().IsEmpty())
109 return;
110
111 // if it was a custom var, see if we can re-insert it
112 if (initial_val != val)
113 {
114 wxString tmp = path.GetFullPath();
115 if (tmp.Replace(val, initial_val) != 0)
116 {
117 // done here
118 XRCCTRL(*this, "txtPath", wxTextCtrl)->SetValue(tmp);
119 return;
120 }
121 }
122 }
123 else
124 {
125 wxFileDialog dlg(this, m_Message, (fname.GetPath().IsEmpty() ? s_LastPath : fname.GetPath()),
126 fname.GetFullName(), m_Filter, wxFD_CHANGE_DIR | (m_AllowMultiSel ? wxFD_MULTIPLE : 0) );
127
128 PlaceWindow(&dlg);
129 if (dlg.ShowModal() == wxID_OK)
130 {
131 if (m_AllowMultiSel)
132 dlg.GetPaths(multi);
133 else
134 path = dlg.GetPath();
135 }
136 else
137 return;
138 }
139
140 if (m_AllowMultiSel && multi.GetCount() != 0 && !multi[0].IsEmpty())
141 s_LastPath = multi[0];
142 else if (!path.GetFullPath().IsEmpty())
143 s_LastPath = path.GetFullPath();
144
145 wxString result;
146 if (m_AskMakeRelative && !m_Basepath.IsEmpty())
147 {
148 // ask the user if he wants it to be kept as relative
149 if (cbMessageBox(_("Keep this as a relative path?"),
150 _("Question"),
151 wxICON_QUESTION | wxYES_NO, this) == wxID_YES)
152 {
153 if (m_AllowMultiSel)
154 {
155 for (unsigned int i = 0; i < multi.GetCount(); ++i)
156 {
157 path = multi[i];
158 path.MakeRelativeTo(m_Basepath);
159 multi[i] = path.GetFullPath();
160 }
161 result = GetStringFromArray(multi);
162 }
163 else
164 {
165 path.MakeRelativeTo(m_Basepath);
166 result = path.GetFullPath();
167 }
168 }
169 else
170 {
171 if (m_AllowMultiSel)
172 result = GetStringFromArray(multi);
173 else
174 result = path.GetFullPath();
175 }
176 }
177 else // always absolute path
178 {
179 if (m_AllowMultiSel)
180 result = GetStringFromArray(multi);
181 else
182 result = path.GetFullPath();
183 }
184
185 // finally set the path
186 XRCCTRL(*this, "txtPath", wxTextCtrl)->SetValue(result);
187 }
188
OnOther(cb_unused wxCommandEvent & event)189 void EditPathDlg::OnOther(cb_unused wxCommandEvent& event)
190 {
191 UserVariableManager *userMgr = Manager::Get()->GetUserVariableManager();
192 wxTextCtrl *txtPath = XRCCTRL(*this, "txtPath", wxTextCtrl);
193
194 const wxString &user_var = userMgr->GetVariable(this, txtPath->GetValue());
195 if ( !user_var.IsEmpty() )
196 {
197 txtPath->SetValue(user_var);
198 m_WantDir = true;
199 }
200 }
201
EndModal(int retCode)202 void EditPathDlg::EndModal(int retCode)
203 {
204 // update m_Path
205 m_Path = XRCCTRL(*this, "txtPath", wxTextCtrl)->GetValue();
206 wxScrollingDialog::EndModal(retCode);
207 }
208