1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // factory.cpp - Object classes factory
9 //
10 //////////////////////////////////////////////////////////////////////////
11
12 // App headers
13 #include "pgAdmin3.h"
14
15 #include "ctl/ctlMenuToolbar.h"
16 #include "schema/pgCollection.h"
17 #include "frm/menu.h"
18
19 // wxWindows headers
20 #include <wx/imaglist.h>
21
22 wxArrayPtrVoid *factoryArray = 0;
23
24 #define FACTORY_OFFSET 100
25
pgaFactory(const wxChar * tn,const wxChar * ns,const wxChar * nls,wxImage * img,wxImage * imgSm)26 pgaFactory::pgaFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm)
27 {
28 if (!factoryArray)
29 factoryArray = new wxArrayPtrVoid;
30 id = factoryArray->GetCount() + FACTORY_OFFSET;
31 factoryArray->Add(this);
32 collectionFactory = 0;
33 smallIconId = -1;
34 typeName = (wxChar *)tn;
35 if (ns)
36 newString = (wxChar *)ns;
37 else
38 newString = typeName;
39 if (nls)
40 newLongString = (wxChar *)nls;
41 else
42 newLongString = newString;
43 metaType = PGM_UNKNOWN;
44
45 if (img && img->IsOk())
46 {
47 image = *img;
48 iconId = addIcon(img);
49 if (imgSm && imgSm->IsOk())
50 smallIconId = addIcon(imgSm);
51 }
52 else
53 iconId = -1;
54 }
55
56
WantSmallIcon()57 bool pgaFactory::WantSmallIcon()
58 {
59 #ifdef __WXMSW__
60 return true;
61 #else
62 return false;
63 #endif
64 }
65
GetIconId()66 int pgaFactory::GetIconId()
67 {
68 if (WantSmallIcon() && smallIconId >= 0)
69 return smallIconId;
70
71 return iconId;
72 }
73
GetFactory(int id)74 pgaFactory *pgaFactory::GetFactory(int id)
75 {
76 id -= FACTORY_OFFSET;
77 if (id >= 0 && id < (int)factoryArray->GetCount())
78 return (pgaFactory *)factoryArray->Item(id);;
79
80 return 0;
81 }
82
83
GetFactory(const wxString & name)84 pgaFactory *pgaFactory::GetFactory(const wxString &name)
85 {
86 int i;
87 pgaFactory *factory;
88
89 for (i = FACTORY_OFFSET ; (factory = GetFactory(i)) != 0 ; i++)
90 {
91 if (name.Matches(factory->GetTypeName()))
92 return factory;
93 }
94 return 0;
95 }
96
GetFactoryByMetaType(const int type)97 pgaFactory *pgaFactory::GetFactoryByMetaType(const int type)
98 {
99 int i;
100 pgaFactory *factory;
101
102 for (i = FACTORY_OFFSET ; (factory = GetFactory(i)) != 0 ; i++)
103 {
104 if (factory->GetMetaType() == type)
105 return factory;
106 }
107 return 0;
108 }
109
110
111 #include "images/property.pngc"
112 #include "images/statistics.pngc"
113
114 wxArrayPtrVoid *deferredImagesArray = 0;
115
addIcon(wxImage * img)116 int pgaFactory::addIcon(wxImage *img)
117 {
118 if (!imageList)
119 {
120 if (!deferredImagesArray)
121 {
122 //Setup the global imagelist
123 deferredImagesArray = new wxArrayPtrVoid;
124
125 deferredImagesArray->Add(property_png_img);
126 deferredImagesArray->Add(statistics_png_img);
127 }
128
129 deferredImagesArray->Add(img);
130
131 return deferredImagesArray->GetCount() - 1;
132 }
133 else
134 {
135 wxBitmap bmp(*img);
136 wxIcon *ico = new wxIcon();
137 ico->CopyFromBitmap(bmp);
138 return imageList->Add(*ico);
139 }
140 }
141
RealizeImages()142 void pgaFactory::RealizeImages()
143 {
144 if (!imageList && deferredImagesArray)
145 {
146 imageList = new wxImageList(16, 16, true, deferredImagesArray->GetCount());
147 size_t i;
148 for (i = 0 ; i < deferredImagesArray->GetCount() ; i++)
149 {
150 wxImage *img = (wxImage *)deferredImagesArray->Item(i);
151 wxBitmap bmp(*img);
152 wxIcon *ico = new wxIcon();
153 ico->CopyFromBitmap(bmp);
154 imageList->Add(*ico);
155 }
156
157 delete deferredImagesArray;
158 deferredImagesArray = 0;
159 }
160 }
161
RegisterMenu(wxWindow * w,wxObjectEventFunction func)162 void pgaFactory::RegisterMenu(wxWindow *w, wxObjectEventFunction func)
163 {
164 w->Connect(GetFactory(FACTORY_OFFSET)->GetId() + MNU_NEW,
165 GetFactory(factoryArray->GetCount() + FACTORY_OFFSET - 1)->GetId() + MNU_NEW,
166 wxEVT_COMMAND_MENU_SELECTED, func);
167 }
168
169
AppendMenu(wxMenu * menu)170 void pgaFactory::AppendMenu(wxMenu *menu)
171 {
172 if (menu && GetNewString())
173 {
174 wxMenuItem *item = menu->Append(MNU_NEW + GetId(), wxGetTranslation(GetNewString()), wxGetTranslation(GetNewLongString()));
175 if (image.IsOk())
176 {
177 (void)item;
178 // doesn't work?
179 // item->SetBitmap(wxBitmap(image));
180 }
181 }
182 }
183
184
GetMetaType()185 int pgaFactory::GetMetaType()
186 {
187 if (IsCollection())
188 return ((pgaCollectionFactory *)this)->GetItemFactory()->GetMetaType();
189 return metaType;
190 }
191
192
pgaCollectionFactory(pgaFactory * f,const wxChar * tn,wxImage * img,wxImage * imgSm)193 pgaCollectionFactory::pgaCollectionFactory(pgaFactory *f, const wxChar *tn, wxImage *img, wxImage *imgSm)
194 : pgaFactory(tn, f->GetNewString(), f->GetNewLongString())
195 {
196 itemFactory = f;
197 f->collectionFactory = this;
198 if (img && img->IsOk())
199 {
200 image = *img;
201 iconId = addIcon(img);
202 if (imgSm && imgSm->IsOk())
203 smallIconId = addIcon(imgSm);
204 }
205 else
206 iconId = f->GetIconId();
207 }
208
209
CreateObjects(pgCollection * obj,ctlTree * browser,const wxString & restr)210 pgObject *pgaCollectionFactory::CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr)
211 {
212 if (itemFactory)
213 return itemFactory->CreateObjects(obj, browser, restr);
214 return 0;
215 }
216
217
CreateDialog(frmMain * frame,pgObject * node,pgObject * parent)218 dlgProperty *pgaCollectionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
219 {
220 if (itemFactory)
221 return itemFactory->CreateDialog(frame, node, parent);
222 return 0;
223 }
224
225
226 ////////////////////////////////////////////////
227
228
~menuFactoryList()229 menuFactoryList::~menuFactoryList()
230 {
231 while (GetCount())
232 {
233 delete (menuFactory *)Item(0);
234 RemoveAt(0);
235 }
236 }
237
GetFactory(int id,bool actionOnly)238 actionFactory *menuFactoryList::GetFactory(int id, bool actionOnly)
239 {
240 id -= MNU_ACTION;
241 if (id >= 0 && id < (int)GetCount())
242 {
243 actionFactory *f = (actionFactory *)Item(id);
244 if (f->IsAction() || !actionOnly)
245 return f;
246 }
247 return 0;
248 }
249
250
RegisterMenu(wxWindow * w,wxObjectEventFunction func)251 void menuFactoryList::RegisterMenu(wxWindow *w, wxObjectEventFunction func)
252 {
253 w->Connect(MNU_ACTION, MNU_ACTION + GetCount() - 1,
254 wxEVT_COMMAND_MENU_SELECTED, func);
255 }
256
257
CheckMenu(pgObject * obj,wxMenuBar * menubar,ctlMenuToolbar * toolbar)258 void menuFactoryList::CheckMenu(pgObject *obj, wxMenuBar *menubar, ctlMenuToolbar *toolbar)
259 {
260 size_t id;
261 for (id = MNU_ACTION ; id < GetCount() + MNU_ACTION ; id++)
262 {
263 actionFactory *f = GetFactory(id);
264 if (f)
265 {
266 bool how = f->CheckEnable(obj);
267 if (menubar->FindItem(id))
268 menubar->Enable(id, how);
269 if (toolbar)
270 toolbar->EnableTool(id, how);
271
272 bool chk = f->CheckChecked(obj);
273 wxMenuItem *itm = menubar->FindItem(id);
274 if (itm && itm->IsCheckable())
275 menubar->Check(id, chk);
276 }
277 }
278 for (id = 0 ; id < GetCount() ; id++)
279 {
280 actionFactory *f = (actionFactory *)Item(id);
281 if (f->IsSubmenu())
282 EnableSubmenu(menubar, id + MNU_ACTION);
283 }
284 }
285
286
EnableSubmenu(wxMenuBar * menuBar,int id)287 void menuFactoryList::EnableSubmenu(wxMenuBar *menuBar, int id)
288 {
289 wxMenuItem *item = menuBar->FindItem(id);
290 if (item)
291 {
292 wxMenu *menu = item->GetSubMenu();
293 wxASSERT(menu);
294 if (!menu)
295 return;
296
297 size_t position;
298 for (position = 0 ; position < menu->GetMenuItemCount() ; position++)
299 {
300 item = menu->FindItemByPosition(position);
301 if (item && item->IsEnabled())
302 {
303 menuBar->Enable(id, true);
304 return;
305 }
306 }
307
308 menuBar->Enable(id, false);
309 }
310 }
311
312
AppendEnabledMenus(wxMenuBar * menuBar,wxMenu * treeContextMenu)313 void menuFactoryList::AppendEnabledMenus(wxMenuBar *menuBar, wxMenu *treeContextMenu)
314 {
315 size_t id;
316 wxMenuItem *lastItem = 0;
317 for (id = MNU_ACTION ; id < GetCount() + MNU_ACTION ; id++)
318 {
319 actionFactory *f = GetFactory(id, false);
320 if (f->IsAction())
321 {
322 if (f->GetContext())
323 {
324 wxMenuItem *menuItem = menuBar->FindItem(id);
325 if (menuItem && menuItem->IsEnabled())
326 {
327 if (!menuItem->IsSubMenu())
328 {
329 #if wxCHECK_VERSION(2, 9, 0)
330 wxString lab = menuItem->GetItemLabelText();
331 #else
332 wxString lab = menuItem->GetLabel(); // deprecated
333 #endif
334 lastItem = treeContextMenu->Append(id, lab, menuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL);
335 if (menuItem->IsCheckable() && menuItem->IsChecked())
336 treeContextMenu->FindItem(id)->Check();
337 }
338 else
339 {
340 /* Copy of submenu */
341 wxMenu *oldSubMenu = menuItem->GetSubMenu();
342 wxMenu *newSubMenu = new wxMenu();
343
344 size_t i;
345 int itemCount = 0;
346 wxMenuItem *singleMenuItem = 0;
347 for (i = 0; i < oldSubMenu->GetMenuItemCount(); i++)
348 {
349 wxMenuItem *oldMenuItem = oldSubMenu->FindItemByPosition(i);
350 if (oldMenuItem->IsEnabled())
351 {
352 #if wxCHECK_VERSION(2, 9, 0)
353 wxString oldLab = oldMenuItem->GetItemLabelText();
354 #else
355 wxString oldLab = oldMenuItem->GetLabel(); // deprecated
356 #endif
357 newSubMenu->Append(oldMenuItem->GetId(), oldLab, oldMenuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL);
358 if (oldMenuItem->IsCheckable() && oldMenuItem->IsChecked())
359 newSubMenu->FindItem(oldMenuItem->GetId())->Check();
360
361 itemCount++;
362 singleMenuItem = oldMenuItem;
363 }
364 }
365 if (itemCount > 1)
366 {
367 #if wxCHECK_VERSION(2, 9, 0)
368 wxString lab = menuItem->GetItemLabelText();
369 #else
370 wxString lab = menuItem->GetLabel(); // deprecated
371 #endif
372 lastItem = treeContextMenu->Append(id, lab, newSubMenu);
373 }
374 else
375 {
376 delete newSubMenu;
377 if (itemCount)
378 {
379 #if wxCHECK_VERSION(2, 9, 0)
380 wxString lab = singleMenuItem->GetItemLabelText();
381 #else
382 wxString lab = singleMenuItem->GetLabel(); // deprecated
383 #endif
384 lastItem = treeContextMenu->Append(singleMenuItem->GetId(), lab, singleMenuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL);
385 if (singleMenuItem->IsCheckable() && singleMenuItem->IsChecked())
386 treeContextMenu->FindItem(singleMenuItem->GetId())->Check();
387 }
388 }
389 }
390 }
391 }
392 }
393 else
394 {
395 if (lastItem && lastItem->GetId() >= 0)
396 lastItem = treeContextMenu->AppendSeparator();
397 }
398 }
399
400 if (lastItem && lastItem->GetId() < 0)
401 {
402 treeContextMenu->Remove(lastItem);
403 delete lastItem;
404 }
405 }
406
407
menuFactory(menuFactoryList * list)408 menuFactory::menuFactory(menuFactoryList *list)
409 {
410 if (list)
411 list->Add(this);
412 }
413
~menuFactory()414 menuFactory::~menuFactory()
415 {
416 }
417
actionFactory(menuFactoryList * list)418 actionFactory::actionFactory(menuFactoryList *list) : menuFactory(list)
419 {
420 if (list)
421 id = list->GetCount() + MNU_ACTION - 1;
422 else
423 id = 0;
424 context = false;
425 }
426
427
428
429