pgadmin3/utils/factory.cpp
2026-05-07 13:45:31 +05:00

431 lines
9.4 KiB
C++

//////////////////////////////////////////////////////////////////////////
//
// 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 <wx/imaglist.h>
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;
}