1 /*
2 * This file is part of HexEditor plugin for Code::Blocks Studio
3 * Copyright (C) 2008-2009 Bartlomiej Swiecki
4 *
5 * HexEditor plugin is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * HexEditor pluging is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with HexEditor. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * $Revision: 10665 $
19 * $Id: SelectStoredExpressionDlg.cpp 10665 2016-01-17 13:58:48Z fuscated $
20 * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/plugins/contrib/HexEditor/SelectStoredExpressionDlg.cpp $
21 */
22 
23 #include "SelectStoredExpressionDlg.h"
24 #include <configmanager.h>
25 
26 //(*InternalHeaders(SelectStoredExpressionDlg)
27 #include <wx/string.h>
28 #include <wx/intl.h>
29 //*)
30 
31 //(*IdInit(SelectStoredExpressionDlg)
32 const long SelectStoredExpressionDlg::ID_LISTBOX1 = wxNewId();
33 const long SelectStoredExpressionDlg::ID_STATICTEXT1 = wxNewId();
34 const long SelectStoredExpressionDlg::ID_TEXTCTRL1 = wxNewId();
35 const long SelectStoredExpressionDlg::ID_BUTTON1 = wxNewId();
36 const long SelectStoredExpressionDlg::ID_BUTTON2 = wxNewId();
37 const long SelectStoredExpressionDlg::ID_BUTTON3 = wxNewId();
38 const long SelectStoredExpressionDlg::ID_BUTTON4 = wxNewId();
39 const long SelectStoredExpressionDlg::ID_TIMER1 = wxNewId();
40 //*)
41 
BEGIN_EVENT_TABLE(SelectStoredExpressionDlg,wxScrollingDialog)42 BEGIN_EVENT_TABLE(SelectStoredExpressionDlg,wxScrollingDialog)
43 	//(*EventTable(SelectStoredExpressionDlg)
44 	//*)
45 END_EVENT_TABLE()
46 
47 SelectStoredExpressionDlg::SelectStoredExpressionDlg(wxWindow* parent,const wxString& startingExpression)
48 {
49     m_Expression = startingExpression;
50     m_CacheChanged = false;
51 	BuildContent(parent);
52 	ReadExpressions();
53 	RecreateExpressionsList();
54 }
55 
BuildContent(wxWindow * parent)56 void SelectStoredExpressionDlg::BuildContent(wxWindow* parent)
57 {
58 	//(*Initialize(SelectStoredExpressionDlg)
59 	wxBoxSizer* BoxSizer3;
60 	wxBoxSizer* BoxSizer2;
61 	wxBoxSizer* BoxSizer1;
62 	wxStdDialogButtonSizer* StdDialogButtonSizer1;
63 	wxStaticBoxSizer* StaticBoxSizer1;
64 
65 	Create(parent, wxID_ANY, _("Stored Expressions"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER, _T("wxID_ANY"));
66 	BoxSizer1 = new wxBoxSizer(wxVERTICAL);
67 	StaticBoxSizer1 = new wxStaticBoxSizer(wxVERTICAL, this, _("Stored expressions"));
68 	m_Expressions = new wxListBox(this, ID_LISTBOX1, wxDefaultPosition, wxSize(292,119), 0, 0, 0, wxDefaultValidator, _T("ID_LISTBOX1"));
69 	StaticBoxSizer1->Add(m_Expressions, 1, wxALL|wxEXPAND, 5);
70 	BoxSizer2 = new wxBoxSizer(wxHORIZONTAL);
71 	StaticText1 = new wxStaticText(this, ID_STATICTEXT1, _("Filter:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1"));
72 	BoxSizer2->Add(StaticText1, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);
73 	m_Filter = new wxTextCtrl(this, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
74 	BoxSizer2->Add(m_Filter, 1, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);
75 	StaticBoxSizer1->Add(BoxSizer2, 0, wxBOTTOM|wxEXPAND, 5);
76 	BoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
77 	Button1 = new wxButton(this, ID_BUTTON1, _("New"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON1"));
78 	BoxSizer3->Add(Button1, 1, wxLEFT|wxALIGN_CENTER_VERTICAL, 5);
79 	Button2 = new wxButton(this, ID_BUTTON2, _("Clone"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON2"));
80 	BoxSizer3->Add(Button2, 1, wxLEFT|wxALIGN_CENTER_VERTICAL, 5);
81 	Button3 = new wxButton(this, ID_BUTTON3, _("Modify"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON3"));
82 	BoxSizer3->Add(Button3, 1, wxLEFT|wxALIGN_CENTER_VERTICAL, 5);
83 	Button4 = new wxButton(this, ID_BUTTON4, _("Delete"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON4"));
84 	BoxSizer3->Add(Button4, 1, wxLEFT|wxALIGN_CENTER_VERTICAL, 5);
85 	StaticBoxSizer1->Add(BoxSizer3, 0, wxBOTTOM|wxRIGHT|wxEXPAND, 5);
86 	BoxSizer1->Add(StaticBoxSizer1, 1, wxALL|wxEXPAND, 5);
87 	StdDialogButtonSizer1 = new wxStdDialogButtonSizer();
88 	StdDialogButtonSizer1->AddButton(new wxButton(this, wxID_OK, wxEmptyString));
89 	StdDialogButtonSizer1->AddButton(new wxButton(this, wxID_CANCEL, wxEmptyString));
90 	StdDialogButtonSizer1->Realize();
91 	BoxSizer1->Add(StdDialogButtonSizer1, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5);
92 	SetSizer(BoxSizer1);
93 	Timer1.SetOwner(this, ID_TIMER1);
94 	BoxSizer1->Fit(this);
95 	BoxSizer1->SetSizeHints(this);
96 
97 	Connect(ID_LISTBOX1,wxEVT_COMMAND_LISTBOX_SELECTED,(wxObjectEventFunction)&SelectStoredExpressionDlg::Onm_ExpressionsSelect);
98 	Connect(ID_LISTBOX1,wxEVT_COMMAND_LISTBOX_DOUBLECLICKED,(wxObjectEventFunction)&SelectStoredExpressionDlg::Onm_ExpressionsDClick);
99 	Connect(ID_TEXTCTRL1,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&SelectStoredExpressionDlg::Onm_FilterText);
100 	Connect(ID_TEXTCTRL1,wxEVT_COMMAND_TEXT_ENTER,(wxObjectEventFunction)&SelectStoredExpressionDlg::Onm_FilterTextEnter);
101 	Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&SelectStoredExpressionDlg::OnButton1Click);
102 	Connect(ID_BUTTON2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&SelectStoredExpressionDlg::OnButton2Click);
103 	Connect(ID_BUTTON3,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&SelectStoredExpressionDlg::OnButton3Click);
104 	Connect(ID_BUTTON4,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&SelectStoredExpressionDlg::OnButton4Click);
105 	Connect(ID_TIMER1,wxEVT_TIMER,(wxObjectEventFunction)&SelectStoredExpressionDlg::OnTimer1Trigger);
106 	//*)
107 
108 	Connect(wxID_OK,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&SelectStoredExpressionDlg::OnOkClick);
109 	Connect(wxID_CANCEL,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&SelectStoredExpressionDlg::OnCancelClick);
110 }
111 
~SelectStoredExpressionDlg()112 SelectStoredExpressionDlg::~SelectStoredExpressionDlg()
113 {
114 	//(*Destroy(SelectStoredExpressionDlg)
115 	//*)
116 }
117 
ReadExpressions()118 void SelectStoredExpressionDlg::ReadExpressions()
119 {
120     ConfigManager* mgr = Manager::Get()->GetConfigManager( _T("lib_finder") );
121 
122     const wxString basePath = _T("/storedexpressions");
123 
124     wxArrayString keys = mgr->EnumerateSubPaths( basePath );
125     for ( size_t i=0; i<keys.Count(); ++i )
126     {
127         wxString path = basePath + _T("/") + keys[i] + _T("/");
128         wxString name = mgr->Read( path + _T("name") );
129         wxString value = mgr->Read( path + _T("value") );
130 
131         if ( !name.IsEmpty() && !value.IsEmpty() )
132         {
133             m_Cache[ name ] = value;
134         }
135     }
136 }
137 
StoreExpressions()138 void SelectStoredExpressionDlg::StoreExpressions()
139 {
140     ConfigManager* mgr = Manager::Get()->GetConfigManager( _T("lib_finder") );
141 
142     const wxString basePath = _T("/storedexpressions");
143 
144     mgr->DeleteSubPath( _T("/storedexpressions") );
145 
146     int index = 0;
147     for ( CacheT::iterator i = m_Cache.begin(); i != m_Cache.end(); ++i )
148     {
149         wxString path = basePath + _T("/") + wxString::Format( _T("expr_%d"), index++ ) + _T("/");
150         mgr->Write( path + _T("name"),  i->first );
151         mgr->Write( path + _T("value"), i->second );
152     }
153 }
154 
RecreateExpressionsList(const wxString & selectionHint)155 void SelectStoredExpressionDlg::RecreateExpressionsList( const wxString& selectionHint )
156 {
157     m_Expressions->Clear();
158     wxString filter = m_Filter->GetValue();
159 
160     for ( CacheT::iterator i = m_Cache.begin(); i != m_Cache.end(); ++i )
161     {
162         const wxString& name = i->first;
163         const wxString& value = i->second;
164 
165         if ( filter.IsEmpty() || name.Find( filter ) != wxNOT_FOUND || value.Find( filter ) != wxNOT_FOUND )
166         {
167             wxString final = wxString::Format( _T("%s: %s"), name.c_str(), value.c_str() );
168             int thisIndex = m_Expressions->Append( final, new ListData( i ) );
169 
170             if ( !selectionHint.IsEmpty() && name == selectionHint )
171             {
172                 m_Expressions->Select( thisIndex );
173             }
174         }
175     }
176 
177     if ( m_Expressions->GetCount() > 0 && m_Expressions->GetSelection() == wxNOT_FOUND )
178     {
179         m_Expressions->SetSelection( 0 );
180     }
181 }
182 
OnButton1Click(wxCommandEvent &)183 void SelectStoredExpressionDlg::OnButton1Click(wxCommandEvent& /*event*/)
184 {
185     AddingExpression( wxEmptyString, m_Expression );
186 }
187 
AddingExpression(const wxString & defaultName,const wxString & defaultExpression)188 void SelectStoredExpressionDlg::AddingExpression( const wxString& defaultName, const wxString& defaultExpression )
189 {
190     wxString name = defaultName;
191     for (;;)
192     {
193         name = cbGetTextFromUser( _("Enter name for this expression"), _("New stored expression"), name );
194 
195         if ( name.IsEmpty() )
196         {
197             return;
198         }
199 
200         if ( m_Cache.find( name ) != m_Cache.end() )
201         {
202             int ret = cbMessageBox( _("Expression with such name already exists."
203                                       "Do you want to replace it ?"),
204                                     _("Duplicated expression"), wxYES_NO|wxCANCEL, this );
205 
206             if ( ret == wxID_CANCEL )
207             {
208                 return;
209             }
210 
211             if ( ret == wxID_YES )
212             {
213                 break;
214             }
215         }
216         else
217         {
218             break;
219         }
220     }
221 
222     wxString value = cbGetTextFromUser(
223         _("Enter expression"),
224         _("New stored expression"),
225         defaultExpression );
226 
227     if ( value.IsEmpty() )
228     {
229         return;
230     }
231 
232     // Delete filter if it won't show new expression
233     wxString filter = m_Filter->GetValue();
234     if ( !filter.IsEmpty() && name.Find( filter ) == wxNOT_FOUND && value.Find( filter ) == wxNOT_FOUND )
235     {
236         m_Filter->ChangeValue( wxEmptyString );
237     }
238 
239     m_Cache[ name ] = value;
240     m_CacheChanged = true;
241 
242 	RecreateExpressionsList( name );
243 }
244 
Onm_ExpressionsSelect(wxCommandEvent &)245 void SelectStoredExpressionDlg::Onm_ExpressionsSelect(wxCommandEvent& /*event*/)
246 {
247 }
248 
OnOkClick(wxCommandEvent & event)249 void SelectStoredExpressionDlg::OnOkClick(wxCommandEvent& event)
250 {
251     if ( m_Expressions->GetSelection() == wxNOT_FOUND )
252     {
253         return;
254     }
255 
256     StoreExpressionsQuery();
257     m_Expression = ( (ListData*)m_Expressions->GetClientObject( m_Expressions->GetSelection() ) )->GetValue();
258 
259     // Just to close the dialog properly
260     event.Skip();
261 }
262 
OnCancelClick(wxCommandEvent & event)263 void SelectStoredExpressionDlg::OnCancelClick(wxCommandEvent& event)
264 {
265     StoreExpressionsQuery();
266 
267     // Just to close the dialog properly
268     event.Skip();
269 }
270 
StoreExpressionsQuery()271 void SelectStoredExpressionDlg::StoreExpressionsQuery()
272 {
273     if ( m_CacheChanged )
274     {
275        int ret = cbMessageBox( _("Expressions has changed.\nDo you want to save them?\n"), _("Changed expressions"), wxYES_NO );
276        if ( ret == wxID_YES )
277        {
278            StoreExpressions();
279        }
280     }
281     m_CacheChanged = false;
282 }
283 
OnButton2Click(wxCommandEvent &)284 void SelectStoredExpressionDlg::OnButton2Click(wxCommandEvent& /*event*/)
285 {
286     ListData* data = GetSelection();
287     if ( !data ) return;
288 
289     AddingExpression( wxString::Format( _("Copy of %s"), data->GetKey().c_str() ), data->GetValue() );
290 }
291 
GetSelection()292 SelectStoredExpressionDlg::ListData * SelectStoredExpressionDlg::GetSelection()
293 {
294     if ( m_Expressions->GetSelection() == wxNOT_FOUND ) return 0;
295     return (ListData*)m_Expressions->GetClientObject( m_Expressions->GetSelection() );
296 }
297 
298 
OnButton3Click(wxCommandEvent &)299 void SelectStoredExpressionDlg::OnButton3Click(wxCommandEvent& /*event*/)
300 {
301     ListData* data = GetSelection();
302     if ( !data ) return;
303 
304     wxString value = cbGetTextFromUser(
305         _("Enter new expression"),
306         _("Modifying expression"),
307         data->GetValue() );
308 
309     wxString name = data->GetKey();
310 
311     if ( value.IsEmpty() )
312     {
313         return;
314     }
315 
316     // Delete filter if it won't show new expression
317     wxString filter = m_Filter->GetValue();
318     if ( !filter.IsEmpty() && name.Find( filter ) == wxNOT_FOUND && value.Find( filter ) == wxNOT_FOUND )
319     {
320         m_Filter->ChangeValue( wxEmptyString );
321     }
322 
323     m_Cache[ name ] = value;
324     m_CacheChanged = true;
325 
326 	RecreateExpressionsList( name );
327 }
328 
329 
Onm_FilterText(wxCommandEvent &)330 void SelectStoredExpressionDlg::Onm_FilterText(wxCommandEvent& /*event*/)
331 {
332     Timer1.Start( 1000, true );
333 }
334 
Onm_FilterTextEnter(wxCommandEvent &)335 void SelectStoredExpressionDlg::Onm_FilterTextEnter(wxCommandEvent& /*event*/)
336 {
337     FilterUpdated();
338 }
339 
OnTimer1Trigger(wxTimerEvent &)340 void SelectStoredExpressionDlg::OnTimer1Trigger(wxTimerEvent& /*event*/)
341 {
342     FilterUpdated();
343 }
344 
FilterUpdated()345 void SelectStoredExpressionDlg::FilterUpdated()
346 {
347     Timer1.Stop();
348     ListData* data = GetSelection();
349     wxString name;
350     if ( data ) name = data->GetKey();
351     RecreateExpressionsList( name );
352 }
353 
OnButton4Click(wxCommandEvent &)354 void SelectStoredExpressionDlg::OnButton4Click(wxCommandEvent& /*event*/)
355 {
356     ListData* data = GetSelection();
357     if ( !data ) return;
358     m_Cache.erase( data->GetKey() );
359     m_CacheChanged = true;
360     RecreateExpressionsList();
361 }
362 
Onm_ExpressionsDClick(wxCommandEvent & event)363 void SelectStoredExpressionDlg::Onm_ExpressionsDClick(wxCommandEvent& event)
364 {
365     OnOkClick( event );
366     EndDialog( wxID_OK );
367 }
368