Code::Blocks  SVN r11506
associations.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  *
5  * $Revision: 10854 $
6  * $Id: associations.cpp 10854 2016-05-18 22:20:45Z d_anselmi $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/src/associations.cpp $
8  */
9 
10 #include <sdk.h>
11 #ifndef CB_PRECOMP
12  #include <wx/radiobox.h>
13  #include <wx/xrc/xmlres.h>
14 #endif
15 #include "associations.h"
16 #include "appglobals.h"
17 #include <manager.h>
18 #include <configmanager.h>
19 #include <filefilters.h>
20 #include <wx/checklst.h>
21 
22 const Associations::Assoc knownTypes[] =
23 {
24 /*
25  { Extension (wxString), Description (wxString), IconIndex (int) }
26  Note: "index" is the index of the icon resource in "resources.rc"
27  Keep all indices in sync with icon indices in "resources.rc"!
28 */
29  { FileFilters::CODEBLOCKS_EXT, _T("project file"), 1 },
30  { FileFilters::WORKSPACE_EXT, _T("workspace file"), 11 },
31 
32  { FileFilters::C_EXT, _T("C source file"), 3 },
33 
34  { FileFilters::CC_EXT, _T("C++ source file"), 4 },
35  { FileFilters::CPP_EXT, _T("C++ source file"), 4 },
36  { FileFilters::CXX_EXT, _T("C++ source file"), 4 },
37  { FileFilters::INL_EXT, _T("C++ source file"), 4 },
38 
39  { FileFilters::TPP_EXT, _T("C++ template source file"), 4 },
40  { FileFilters::TCC_EXT, _T("C++ template source file"), 4 },
41 
42  { FileFilters::H_EXT, _T("Header file"), 5 },
43  { FileFilters::HH_EXT, _T("Header file"), 5 },
44  { FileFilters::HPP_EXT, _T("Header file"), 5 },
45  { FileFilters::HXX_EXT, _T("Header file"), 5 },
46 
47  { FileFilters::JAVA_EXT, _T("Java source file"), 6 },
48  { _T("cg"), _T("cg source file"), 7 },
49  { FileFilters::D_EXT, _T("D source file"), 8 },
50  { FileFilters::RESOURCE_EXT, _T("resource file"), 10 },
51  { FileFilters::XRCRESOURCE_EXT, _T("XRC resource file"), 10 },
52 
53  { FileFilters::ASM_EXT, _T("ASM source file"), 2 },
54  { FileFilters::S_EXT, _T("ASM source file"), 2 },
55  { FileFilters::SS_EXT, _T("ASM source file"), 2 },
56  { FileFilters::S62_EXT, _T("ASM source file"), 2 },
57 
58  { FileFilters::F_EXT, _T("Fortran source file"), 9 },
59  { FileFilters::F77_EXT, _T("Fortran source file"), 9 },
60  { FileFilters::F90_EXT, _T("Fortran source file"), 9 },
61  { FileFilters::F95_EXT, _T("Fortran source file"), 9 },
62 
63  { FileFilters::DEVCPP_EXT, _T("Dev-CPP project file"), 21 },
64  { FileFilters::MSVC6_EXT, _T("MS Visual C++ project file"), 22 },
65  { FileFilters::MSVC6_WORKSPACE_EXT, _T("MS Visual C++ workspace file"), 23 }
66  //{ _T("proj"), _T("XCODE Project file"), 24 }
67 };
68 
69 inline void DoSetAssociation(const wxString& executable, int index)
70 {
71  Associations::DoSetAssociation(knownTypes[index].ext, knownTypes[index].descr, executable, knownTypes[index].index);
72 };
73 
74 inline bool DoCheckAssociation(const wxString& executable, int index)
75 {
76  return Associations::DoCheckAssociation(knownTypes[index].ext, knownTypes[index].descr, executable, knownTypes[index].index);
77 };
78 
80 {
81  return sizeof(knownTypes)/sizeof(Associations::Assoc);
82 }
83 
85 {
86  wxChar name[MAX_PATH] = {0};
87  GetModuleFileName(0L, name, MAX_PATH);
88 
89  ::DoSetAssociation(name, 0);
90  ::DoSetAssociation(name, 1);
91 
92  UpdateChanges();
93 }
94 
96 {
97  SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0L, 0L);
98 }
99 
101 {
102  wxChar name[MAX_PATH] = {0};
103  GetModuleFileName(0L, name, MAX_PATH);
104 
105  for (int i = 0; i <= 12; ++i) // beware, the number 12 is hardcoded ;)
106  ::DoSetAssociation(name, i);
107 
108  UpdateChanges();
109 }
110 
112 {
113  wxChar name[MAX_PATH] = {0};
114  GetModuleFileName(0L, name, MAX_PATH);
115 
116  for (unsigned int i = 0; i < CountAssocs(); ++i)
117  ::DoSetAssociation(name, i);
118 
119  UpdateChanges();
120 }
121 
123 {
124  wxChar name[MAX_PATH] = {0};
125  GetModuleFileName(0L, name, MAX_PATH);
126 
127  for (unsigned int i = 0; i < CountAssocs(); ++i)
128  DoClearAssociation(knownTypes[i].ext);
129 
130  UpdateChanges();
131 }
132 
134 {
135  wxChar name[MAX_PATH] = {0};
136  GetModuleFileName(0L, name, MAX_PATH);
137 
138  bool result = true;
139 
140  for (int i = 0; i <= 12; ++i) // beware, the number 12 is hardcoded ;)
141  result &= ::DoCheckAssociation(name, i);
142 
143  return result;
144 }
145 
146 void Associations::DoSetAssociation(const wxString& ext, const wxString& descr, const wxString& exe, int icoNum)
147 {
148  wxString BaseKeyName(_T("HKEY_CURRENT_USER\\Software\\Classes\\"));
150  BaseKeyName = _T("HKEY_CLASSES_ROOT\\");
151 
152  wxString node(_T("CodeBlocks.") + ext);
153 
154  wxRegKey key; // defaults to HKCR
155  key.SetName(BaseKeyName + _T(".") + ext);
156  key.Create();
157  key = _T("CodeBlocks.") + ext;
158 
159  key.SetName(BaseKeyName + node);
160  key.Create();
161  key = descr;
162 
163  key.SetName(BaseKeyName + node + _T("\\DefaultIcon"));
164  key.Create();
165  key = exe + wxString::Format(_T(",%d"), icoNum);
166 
167  key.SetName(BaseKeyName + node + _T("\\shell\\open\\command"));
168  key.Create();
169  key = _T("\"") + exe + _T("\" \"%1\"");
170 
171  key.SetName(BaseKeyName + node + _T("\\shell\\open\\ddeexec"));
172  key.Create();
173  key = _T("[Open(\"%1\")]");
174 
175  key.SetName(BaseKeyName + node + _T("\\shell\\open\\ddeexec\\application"));
176  key.Create();
177  key = DDE_SERVICE;
178 
179  key.SetName(BaseKeyName + node + _T("\\shell\\open\\ddeexec\\ifexec"));
180  key.Create();
181  key = _T("[IfExec_Open(\"%1\")]");;
182 
183  key.SetName(BaseKeyName + node + _T("\\shell\\open\\ddeexec\\topic"));
184  key.Create();
185  key = DDE_TOPIC;
186 
188  {
189  wxString batchbuildargs = Manager::Get()->GetConfigManager(_T("app"))->Read(_T("/batch_build_args"), appglobals::DefaultBatchBuildArgs);
190  key.SetName(BaseKeyName + node + _T("\\shell\\Build\\command"));
191  key.Create();
192  key = _T("\"") + exe + _T("\" ") + batchbuildargs + _T(" --build \"%1\"");
193 
194  key.SetName(BaseKeyName + node + _T("\\shell\\Rebuild (clean)\\command"));
195  key.Create();
196  key = _T("\"") + exe + _T("\" ") + batchbuildargs + _T(" --rebuild \"%1\"");
197  }
198 }
199 
201 {
202  wxString BaseKeyName(_T("HKEY_CURRENT_USER\\Software\\Classes\\"));
204  BaseKeyName = _T("HKEY_CLASSES_ROOT\\");
205 
206  wxRegKey key; // defaults to HKCR
207  key.SetName(BaseKeyName + _T(".") + ext);
208  if (key.Exists())
209  {
210  wxString s;
211  #if wxCHECK_VERSION(3, 0, 0)
212  if (key.QueryValue(wxEmptyString, s) && s.StartsWith(_T("CodeBlocks")))
213  #else
214  if (key.QueryValue(NULL, s) && s.StartsWith(_T("CodeBlocks")))
215  #endif
216  key.DeleteSelf();
217  }
218 
219  key.SetName(BaseKeyName + _T("CodeBlocks.") + ext);
220  if (key.Exists())
221  key.DeleteSelf();
222 }
223 
224 bool Associations::DoCheckAssociation(const wxString& ext, cb_unused const wxString& descr, const wxString& exe, int icoNum)
225 {
226  wxString BaseKeyName(_T("HKEY_CURRENT_USER\\Software\\Classes\\"));
227 
229  BaseKeyName = _T("HKEY_CLASSES_ROOT\\");
230 
231  wxRegKey key; // defaults to HKCR
232  key.SetName(BaseKeyName + _T(".") + ext);
233  if (!key.Exists())
234  return false;
235 
236  key.SetName(BaseKeyName + _T("CodeBlocks.") + ext);
237  if (!key.Exists())
238  return false;
239 
240  key.SetName(BaseKeyName + _T("CodeBlocks.") + ext + _T("\\DefaultIcon"));
241  if (!key.Exists())
242  return false;
243  wxString strVal;
244  if (!key.QueryValue(wxEmptyString, strVal))
245  return false;
246  if (strVal != wxString::Format(_T("%s,%d"), exe.c_str(), icoNum))
247  return false;
248 
249  key.SetName(BaseKeyName + _T("CodeBlocks.") + ext + _T("\\shell\\open\\command"));
250  if (!key.Open())
251  return false;
252  if (!key.QueryValue(wxEmptyString, strVal))
253  return false;
254  if (strVal != wxString::Format(_T("\"%s\" \"%%1\""), exe.c_str()))
255  return false;
256 
257  key.SetName(BaseKeyName + _T("CodeBlocks.") + ext + _T("\\shell\\open\\ddeexec"));
258  if (!key.Open())
259  return false;
260  if (!key.QueryValue(wxEmptyString, strVal))
261  return false;
262  if (strVal != _T("[Open(\"%1\")]"))
263  return false;
264 
265  key.SetName(BaseKeyName + _T("CodeBlocks.") + ext + _T("\\shell\\open\\ddeexec\\application"));
266  if (!key.Open())
267  return false;
268  if (!key.QueryValue(wxEmptyString, strVal))
269  return false;
270  if (strVal != DDE_SERVICE)
271  return false;
272 
273  key.SetName(BaseKeyName + _T("CodeBlocks.") + ext + _T("\\shell\\open\\ddeexec\\ifexec"));
274  if (!key.Open())
275  return false;
276  if (!key.QueryValue(wxEmptyString, strVal))
277  return false;
278  if (strVal != _T("[IfExec_Open(\"%1\")]"))
279  return false;
280 
281  key.SetName(BaseKeyName + _T("CodeBlocks.") + ext + _T("\\shell\\open\\ddeexec\\topic"));
282  if (!key.Open())
283  return false;
284  if (!key.QueryValue(wxEmptyString, strVal))
285  return false;
286  if (strVal != DDE_TOPIC)
287  return false;
288 
290  {
291  wxString batchbuildargs = Manager::Get()->GetConfigManager(_T("app"))->Read(_T("/batch_build_args"), appglobals::DefaultBatchBuildArgs);
292  key.SetName(BaseKeyName + _T("CodeBlocks.") + ext + _T("\\shell\\Build\\command"));
293  if (!key.Open())
294  return false;
295  if (!key.QueryValue(wxEmptyString, strVal))
296  return false;
297  if (strVal != _T("\"") + exe + _T("\" ") + batchbuildargs + _T(" --build \"%1\""))
298  return false;
299 
300  key.SetName(BaseKeyName + _T("CodeBlocks.") + ext + _T("\\shell\\Rebuild (clean)\\command"));
301  if (!key.Open())
302  return false;
303  if (!key.QueryValue(wxEmptyString, strVal))
304  return false;
305  if (strVal != _T("\"") + exe + _T("\" ") + batchbuildargs + _T(" --rebuild \"%1\""))
306  return false;
307  }
308 
309  return true;
310 }
311 
312 
313 
314 BEGIN_EVENT_TABLE(ManageAssocsDialog, wxScrollingDialog)
315  EVT_BUTTON(XRCID("wxID_OK"), ManageAssocsDialog::OnApply)
316  EVT_BUTTON(XRCID("wxID_CANCEL"), ManageAssocsDialog::OnCancel)
317  EVT_BUTTON(XRCID("clearAll"), ManageAssocsDialog::OnClearAll)
318 END_EVENT_TABLE()
319 
320 
321 
323 {
324  wxXmlResource::Get()->LoadObject(this, parent, _T("dlgManageAssocs"),_T("wxScrollingDialog"));
325 
326  list = XRCCTRL(*this, "checkList", wxCheckListBox);
327  assert(list);
328 
329  wxString d(_T("."));
330 
331  wxChar exe[MAX_PATH] = {0};
332  GetModuleFileName(0L, exe, MAX_PATH);
333 
334  for (unsigned int i = 0; i < Associations::CountAssocs(); ++i)
335  {
336  list->Append(d + knownTypes[i].ext + _T(" (") + knownTypes[i].descr + _T(")"));
337  list->Check(i, Associations::DoCheckAssociation(knownTypes[i].ext, knownTypes[i].descr, exe, knownTypes[i].index));
338  }
339 
340  CentreOnParent();
341 }
342 
344 {
345  wxChar name[MAX_PATH] = {0};
346  GetModuleFileName(0L, name, MAX_PATH);
347 
348  for (size_t i = 0; i < list->GetCount(); ++i)
349  {
350  if (list->IsChecked(i))
351  ::DoSetAssociation(name, i);
352  else
353  Associations::DoClearAssociation(knownTypes[i].ext);
354  }
355 
357  EndModal(0);
358 }
359 
361 {
362  EndModal(0);
363 }
364 
366 {
369  EndModal(0);
370 }
371 
372 BEGIN_EVENT_TABLE(AskAssocDialog, wxScrollingDialog)
373  EVT_BUTTON(XRCID("wxID_OK"), AskAssocDialog::OnOK)
375  EVT_CHAR_HOOK(AskAssocDialog::OnCharHook)
376 END_EVENT_TABLE()
377 
379 {
380  wxXmlResource::Get()->LoadObject(this, parent, _T("askAssoc"),_T("wxScrollingDialog"));
381  SetEscapeId(wxID_NONE);
382 }
383 
384 void AskAssocDialog::OnOK(cb_unused wxCommandEvent& event)
385 {
386  EndModal(XRCCTRL(*this, "choice", wxRadioBox)->GetSelection());
387 }
388 
389 void AskAssocDialog::OnESC(cb_unused wxCommandEvent& event)
390 {
392 }
393 
395 {
396  if ( event.GetKeyCode() == WXK_ESCAPE )
397  Close(); //wxDialog::Close() send button event with id wxID_CANCEL (wxWidgets 2.8)
398  else if ( (event.GetKeyCode() == WXK_RETURN) || (event.GetKeyCode() == WXK_NUMPAD_ENTER) )
399  EndModal(XRCCTRL(*this, "choice", wxRadioBox)->GetSelection());
400 
401  event.Skip();
402 }
void EndModal(int retCode)
Definition: sc_dialog.cpp:112
int GetKeyCode() const
const DLLIMPORT wxString TCC_EXT
const DLLIMPORT wxString CODEBLOCKS_EXT
const DLLIMPORT wxString F95_EXT
#define ASC_ASSOC_DLG_NO_ONLY_NOW
Definition: associations.h:71
ConfigManager * GetConfigManager(const wxString &name_space) const
Definition: manager.cpp:474
void OnCancel(wxCommandEvent &event)
void OnApply(wxCommandEvent &event)
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
Definition: manager.cpp:182
DLLIMPORT windows_version_t WindowsVersion()
Definition: globals.cpp:1338
const Associations::Assoc knownTypes[]
const DLLIMPORT wxString H_EXT
const DLLIMPORT wxString INL_EXT
void OnClearAll(wxCommandEvent &event)
const DLLIMPORT wxString DEVCPP_EXT
const DLLIMPORT wxString HPP_EXT
const DLLIMPORT wxString JAVA_EXT
wxCStrData c_str() const
void DoSetAssociation(const wxString &executable, int index)
#define _T(string)
bool QueryValue(const wxString &szValue, wxString &strValue, bool raw) const
const DLLIMPORT wxString S62_EXT
const DLLIMPORT wxString HXX_EXT
const DLLIMPORT wxString C_EXT
const DLLIMPORT wxString MSVC6_EXT
const DLLIMPORT wxString F77_EXT
const DLLIMPORT wxString TPP_EXT
bool IsChecked(unsigned int item) const
bool DoCheckAssociation(const wxString &executable, int index)
const DLLIMPORT wxString F_EXT
wxUSE_UNICODE_dependent wxChar
const DLLIMPORT wxString D_EXT
const DLLIMPORT wxString MSVC6_WORKSPACE_EXT
const DLLIMPORT wxString SS_EXT
void DeleteSelf()
const DLLIMPORT wxString F90_EXT
const DLLIMPORT wxString WORKSPACE_EXT
bool IsSameAs(const wxString &s, bool caseSensitive=true) const
void UpdateChanges()
const DLLIMPORT wxString CC_EXT
wxString Read(const wxString &key, const wxString &defaultVal=wxEmptyString)
const DLLIMPORT wxString S_EXT
void SetBatchBuildOnly()
wxString wxEmptyString
void DoClearAssociation(const wxString &ext)
const DLLIMPORT wxString CXX_EXT
void OnOK(wxCommandEvent &event)
void DoSetAssociation(const wxString &ext, const wxString &descr, const wxString &exe, int icoNum)
wxCheckListBox * list
Definition: associations.h:58
void OnESC(wxCommandEvent &event)
const DLLIMPORT wxString XRCRESOURCE_EXT
bool Exists() const
bool Create(bool bOkIfExists=true)
const DLLIMPORT wxString HH_EXT
#define DDE_TOPIC
Definition: associations.h:23
bool StartsWith(const wxString &prefix, wxString *rest=NULL) const
const wxString DefaultBatchBuildArgs
Definition: appglobals.cpp:72
bool Open(AccessMode mode=Write)
const DLLIMPORT wxString CPP_EXT
static wxXmlResource * Get()
bool DoCheckAssociation(const wxString &ext, const wxString &descr, const wxString &exe, int icoNum)
const DLLIMPORT wxString ASM_EXT
void SetName(const wxString &strKey)
#define DDE_SERVICE
Definition: associations.h:19
#define NULL
Definition: prefix.cpp:59
const DLLIMPORT wxString RESOURCE_EXT
static wxString Format(const wxString &format,...)
wxObject * LoadObject(wxWindow *parent, const wxString &name, const wxString &classname)
virtual unsigned int GetCount() const
unsigned int CountAssocs()
void OnCharHook(wxKeyEvent &event)