////////////////////////////////////////////////////////////////////////// // // pgAdmin III - PostgreSQL Tools // // Copyright (C) 2002 - 2016, The pgAdmin Development Team // This software is released under the PostgreSQL Licence // // factory.cpp - Object classes factory // ////////////////////////////////////////////////////////////////////////// // App headers #include "pgAdmin3.h" #include "ctl/ctlMenuToolbar.h" #include "schema/pgCollection.h" #include "frm/menu.h" #include "frm/frmMain.h" // wxWindows headers #include wxArrayPtrVoid *factoryArray = 0; #define FACTORY_OFFSET 100 pgaFactory::pgaFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm) { if (!factoryArray) factoryArray = new wxArrayPtrVoid; id = factoryArray->GetCount() + FACTORY_OFFSET; factoryArray->Add(this); collectionFactory = 0; smallIconId = -1; typeName = (wxChar *)tn; if (ns) newString = (wxChar *)ns; else newString = typeName; if (nls) newLongString = (wxChar *)nls; else newLongString = newString; metaType = PGM_UNKNOWN; if (img && img->IsOk()) { image = *img; iconId = addIcon(img); if (imgSm && imgSm->IsOk()) smallIconId = addIcon(imgSm); } else iconId = -1; } bool pgaFactory::WantSmallIcon() { #ifdef __WXMSW__ return true; #else return false; #endif } int pgaFactory::GetIconId() { if (WantSmallIcon() && smallIconId >= 0) return smallIconId; return iconId; } pgaFactory *pgaFactory::GetFactory(int id) { id -= FACTORY_OFFSET; if (id >= 0 && id < (int)factoryArray->GetCount()) return (pgaFactory *)factoryArray->Item(id);; return 0; } pgaFactory *pgaFactory::GetFactory(const wxString &name) { int i; pgaFactory *factory; for (i = FACTORY_OFFSET ; (factory = GetFactory(i)) != 0 ; i++) { if (name.Matches(factory->GetTypeName())) return factory; } return 0; } pgaFactory *pgaFactory::GetFactoryByMetaType(const int type) { int i; pgaFactory *factory; for (i = FACTORY_OFFSET ; (factory = GetFactory(i)) != 0 ; i++) { if (factory->GetMetaType() == type) return factory; } return 0; } #include "images/property.pngc" #include "images/statistics.pngc" wxArrayPtrVoid *deferredImagesArray = 0; int pgaFactory::addIcon(wxImage *img) { if (!imageList) { if (!deferredImagesArray) { //Setup the global imagelist deferredImagesArray = new wxArrayPtrVoid; deferredImagesArray->Add(property_png_img); deferredImagesArray->Add(statistics_png_img); } deferredImagesArray->Add(img); return deferredImagesArray->GetCount() - 1; } else { wxBitmap bmp(*img); wxIcon *ico = new wxIcon(); ico->CopyFromBitmap(bmp); return imageList->Add(*ico); } } void pgaFactory::RealizeImages() { if (!imageList && deferredImagesArray) { imageList = new wxImageList(16, 16, true, deferredImagesArray->GetCount()); size_t i; for (i = 0 ; i < deferredImagesArray->GetCount() ; i++) { wxImage *img = (wxImage *)deferredImagesArray->Item(i); wxBitmap bmp(*img); wxIcon *ico = new wxIcon(); ico->CopyFromBitmap(bmp); imageList->Add(*ico); } delete deferredImagesArray; deferredImagesArray = 0; } } void pgaFactory::RegisterMenu(wxWindow *w, wxObjectEventFunction func) { w->Connect(GetFactory(FACTORY_OFFSET)->GetId() + MNU_NEW, GetFactory(factoryArray->GetCount() + FACTORY_OFFSET - 1)->GetId() + MNU_NEW, wxEVT_COMMAND_MENU_SELECTED, func); } void pgaFactory::AppendMenu(wxMenu *menu) { if (menu && GetNewString()) { wxMenuItem *item = menu->Append(MNU_NEW + GetId(), wxGetTranslation(GetNewString()), wxGetTranslation(GetNewLongString())); if (image.IsOk()) { (void)item; // doesn't work? // item->SetBitmap(wxBitmap(image)); } } } int pgaFactory::GetMetaType() { if (IsCollection()) return ((pgaCollectionFactory *)this)->GetItemFactory()->GetMetaType(); return metaType; } pgaCollectionFactory::pgaCollectionFactory(pgaFactory *f, const wxChar *tn, wxImage *img, wxImage *imgSm) : pgaFactory(tn, f->GetNewString(), f->GetNewLongString()) { itemFactory = f; f->collectionFactory = this; if (img && img->IsOk()) { image = *img; iconId = addIcon(img); if (imgSm && imgSm->IsOk()) smallIconId = addIcon(imgSm); } else iconId = f->GetIconId(); } pgObject *pgaCollectionFactory::CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr) { if (itemFactory) return itemFactory->CreateObjects(obj, browser, restr); return 0; } dlgProperty *pgaCollectionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) { if (itemFactory) return itemFactory->CreateDialog(frame, node, parent); return 0; } //////////////////////////////////////////////// menuFactoryList::~menuFactoryList() { while (GetCount()) { delete (menuFactory *)Item(0); RemoveAt(0); } } actionFactory *menuFactoryList::GetFactory(int id, bool actionOnly) { id -= MNU_ACTION; if (id >= 0 && id < (int)GetCount()) { actionFactory *f = (actionFactory *)Item(id); if (f->IsAction() || !actionOnly) return f; } return 0; } void menuFactoryList::RegisterMenu(wxWindow *w, wxObjectEventFunction func) { w->Connect(MNU_ACTION, MNU_ACTION + GetCount() - 1, wxEVT_COMMAND_MENU_SELECTED, func); } void menuFactoryList::CheckMenu(pgObject *obj, wxMenuBar *menubar, ctlMenuToolbar *toolbar) { size_t id; for (id = MNU_ACTION ; id < GetCount() + MNU_ACTION ; id++) { actionFactory *f = GetFactory(id); if (f) { bool how = f->CheckEnable(obj); if (menubar->FindItem(id)) menubar->Enable(id, how); if (toolbar) toolbar->EnableTool(id, how); bool chk = f->CheckChecked(obj); wxMenuItem *itm = menubar->FindItem(id); if (itm && itm->IsCheckable()) menubar->Check(id, chk); } } for (id = 0 ; id < GetCount() ; id++) { actionFactory *f = (actionFactory *)Item(id); if (f->IsSubmenu()) EnableSubmenu(menubar, id + MNU_ACTION); } } void menuFactoryList::EnableSubmenu(wxMenuBar *menuBar, int id) { wxMenuItem *item = menuBar->FindItem(id); if (item) { wxMenu *menu = item->GetSubMenu(); wxASSERT(menu); if (!menu) return; size_t position; for (position = 0 ; position < menu->GetMenuItemCount() ; position++) { item = menu->FindItemByPosition(position); if (item && item->IsEnabled()) { menuBar->Enable(id, true); return; } } menuBar->Enable(id, false); } } void menuFactoryList::AppendEnabledMenus(wxMenuBar *menuBar, wxMenu *treeContextMenu) { size_t id; wxMenuItem *lastItem = 0; for (id = MNU_ACTION ; id < GetCount() + MNU_ACTION ; id++) { actionFactory *f = GetFactory(id, false); if (f->IsAction()) { if (f->GetContext()) { wxMenuItem *menuItem = menuBar->FindItem(id); if (menuItem && menuItem->IsEnabled()) { if (!menuItem->IsSubMenu()) { #if wxCHECK_VERSION(2, 9, 0) wxString lab = menuItem->GetItemLabelText(); #else wxString lab = menuItem->GetLabel(); // deprecated #endif lastItem = treeContextMenu->Append(id, lab, menuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL); if (menuItem->IsCheckable() && menuItem->IsChecked()) treeContextMenu->FindItem(id)->Check(); } else { /* Copy of submenu */ wxMenu *oldSubMenu = menuItem->GetSubMenu(); //skip append submenu Server if (winMain && (oldSubMenu == winMain->GetServerMenu())) continue; wxMenu *newSubMenu = new wxMenu(); size_t i; int itemCount = 0; wxMenuItem *singleMenuItem = 0; for (i = 0; i < oldSubMenu->GetMenuItemCount(); i++) { wxMenuItem *oldMenuItem = oldSubMenu->FindItemByPosition(i); if (oldMenuItem->IsEnabled()) { #if wxCHECK_VERSION(2, 9, 0) wxString oldLab = oldMenuItem->GetItemLabelText(); #else wxString oldLab = oldMenuItem->GetLabel(); // deprecated #endif newSubMenu->Append(oldMenuItem->GetId(), oldLab, oldMenuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL); if (oldMenuItem->IsCheckable() && oldMenuItem->IsChecked()) newSubMenu->FindItem(oldMenuItem->GetId())->Check(); itemCount++; singleMenuItem = oldMenuItem; } } if (itemCount > 1) { #if wxCHECK_VERSION(2, 9, 0) wxString lab = menuItem->GetItemLabelText(); #else wxString lab = menuItem->GetLabel(); // deprecated #endif lastItem = treeContextMenu->Append(id, lab, newSubMenu); } else { delete newSubMenu; if (itemCount) { #if wxCHECK_VERSION(2, 9, 0) wxString lab = singleMenuItem->GetItemLabelText(); #else wxString lab = singleMenuItem->GetLabel(); // deprecated #endif lastItem = treeContextMenu->Append(singleMenuItem->GetId(), lab, singleMenuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL); if (singleMenuItem->IsCheckable() && singleMenuItem->IsChecked()) treeContextMenu->FindItem(singleMenuItem->GetId())->Check(); } } } } } } else { if (lastItem && lastItem->GetId() >= 0) lastItem = treeContextMenu->AppendSeparator(); } } if (lastItem && lastItem->GetId() < 0) { treeContextMenu->Remove(lastItem); delete lastItem; } } menuFactory::menuFactory(menuFactoryList *list) { if (list) list->Add(this); } menuFactory::~menuFactory() { } actionFactory::actionFactory(menuFactoryList *list) : menuFactory(list) { if (list) id = list->GetCount() + MNU_ACTION - 1; else id = 0; context = false; }