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