////////////////////////////////////////////////////////////////////////// // // pgAdmin III - PostgreSQL Tools // // Copyright (C) 2002 - 2016, The pgAdmin Development Team // This software is released under the PostgreSQL Licence // // frmDatabaseDesigner.cpp - The database designer form // ////////////////////////////////////////////////////////////////////////// #include "pgAdmin3.h" // wxWindows headers #include #include #include #include #include // App headers #include "frm/frmMain.h" #include "frm/frmDatabaseDesigner.h" #include "ctl/ctlMenuToolbar.h" #include "schema/pgObject.h" #include "schema/pgDatabase.h" #include "ctl/ctlSQLBox.h" #include "dlg/dlgSelectConnection.h" #include "utils/sysSettings.h" // Designer headers #include "dd/dditems/figures/ddColumnKindIcon.h" #include "hotdraw/figures/hdPolyLineFigure.h" #include "hotdraw/figures/hdSimpleTextFigure.h" #include "dd/dditems/figures/ddTableFigure.h" #include "hotdraw/figures/hdRectangleFigure.h" #include "hotdraw/figures/hdBitmapFigure.h" #include "hotdraw/tools/hdConnectionCreationTool.h" #include "dd/ddmodel/ddModelBrowser.h" #include "dd/ddmodel/ddDBReverseEngineering.h" #include "dd/ddmodel/ddGenerationWizard.h" #include "dd/ddmodel/ddDatabaseDesign.h" #include "dd/ddmodel/ddDrawingView.h" #include "dd/dditems/figures/ddTextTableItemFigure.h" #include "dd/dditems/figures/ddColumnFigure.h" #include "dd/dditems/figures/ddTableFigure.h" #include "dd/dditems/utilities/ddTableNameDialog.h" #include "dd/dditems/figures/xml/ddXmlStorage.h" // Icons #include "images/ddmodel-32.pngc" #include "images/file_new.pngc" #include "images/table.pngc" #include "images/ddRemoveTable2.pngc" #include "images/continue.pngc" #include "images/ddnewdiagram.pngc" #include "images/ddgendiagram.pngc" #include "images/help.pngc" #include "images/file_save.pngc" #include "images/file_open.pngc" #include "images/conversion.pngc" BEGIN_EVENT_TABLE(frmDatabaseDesigner, pgFrame) EVT_COMBOBOX(CTL_DDCONNECTION, frmDatabaseDesigner::OnChangeConnection) EVT_MENU(MNU_NEW, frmDatabaseDesigner::OnNewModel) EVT_MENU(MNU_ADDTABLE, frmDatabaseDesigner::OnAddTable) EVT_MENU(MNU_DELETETABLE, frmDatabaseDesigner::OnDeleteTable) EVT_MENU(MNU_ADDCOLUMN, frmDatabaseDesigner::OnAddColumn) EVT_MENU(MNU_GENERATEDIAGRAM, frmDatabaseDesigner::OnDiagramGeneration) EVT_MENU(MNU_GENERATEMODEL, frmDatabaseDesigner::OnModelGeneration) EVT_MENU(MNU_SAVEMODEL, frmDatabaseDesigner::OnModelSave) EVT_MENU(MNU_SAVEMODELAS, frmDatabaseDesigner::OnModelSaveAs) EVT_MENU(MNU_LOADMODEL, frmDatabaseDesigner::OnModelLoad) EVT_MENU(MNU_NEWDIAGRAM, frmDatabaseDesigner::OnAddDiagram) EVT_MENU(MNU_DELDIAGRAM, frmDatabaseDesigner::OnDeleteDiagram) EVT_MENU(MNU_RENDIAGRAM, frmDatabaseDesigner::OnRenameDiagram) EVT_MENU(MNU_TOGGLEDDSQL, frmDatabaseDesigner::OnToggleSQLWindow) EVT_MENU(MNU_TOGGLEMBROWSER, frmDatabaseDesigner::OnToggleModelBrowser) EVT_MENU(CTL_IMPSCHEMA, frmDatabaseDesigner::OnImportSchema) EVT_AUINOTEBOOK_PAGE_CLOSE(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnDeleteDiagramTab) EVT_AUINOTEBOOK_PAGE_CLOSED(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnDeletedDiagramTab) EVT_AUINOTEBOOK_BUTTON(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnClickDiagramTab) EVT_AUINOTEBOOK_BG_DCLICK(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnAddDiagram2) EVT_CLOSE( frmDatabaseDesigner::OnClose) END_EVENT_TABLE() frmDatabaseDesigner::frmDatabaseDesigner(frmMain *form, const wxString &_title, pgConn *conn) : pgFrame(NULL, _title) { mainForm = form; SetTitle(wxT("Database Designer")); SetIcon(wxIcon(*ddmodel_32_png_ico)); loading = true; closing = false; RestorePosition(100, 100, 600, 500, 450, 300); SetMinSize(wxSize(450, 300)); // connection connection = conn; // notify wxAUI which frame to use manager.SetManagedWindow(this); manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG); SetFont(settings->GetSystemFont()); // Set File menu fileMenu = new wxMenu(); fileMenu->Append(MNU_NEW, _("&New database design\tCtrl-N"), _("Create a new database design")); fileMenu->AppendSeparator(); fileMenu->Append(MNU_LOADMODEL, _("&Open Model..."), _("Open an existing database design from a file")); fileMenu->Append(MNU_SAVEMODEL, _("&Save Model"), _("Save changes at database design")); fileMenu->Append(MNU_SAVEMODELAS, _("&Save Model As..."), _("Save database design at new file")); fileMenu->AppendSeparator(); fileMenu->Append(CTL_IMPSCHEMA, _("&Import Tables..."), _("Import tables from database schema to database designer model")); fileMenu->AppendSeparator(); fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit database designer window")); // Set Diagram menu diagramMenu = new wxMenu(); diagramMenu->Append(MNU_NEWDIAGRAM, _("&New model diagram"), _("Create a new diagram")); diagramMenu->Append(MNU_DELDIAGRAM, _("&Delete selected model diagram..."), _("Delete selected diagram")); diagramMenu->Append(MNU_RENDIAGRAM, _("&Rename selected model diagram..."), _("Rename selected diagram")); // Set View menu viewMenu = new wxMenu(); viewMenu->AppendCheckItem(MNU_TOGGLEMBROWSER, _("&Model Browser"), _("Show / Hide Model Browser Window")); viewMenu->AppendCheckItem(MNU_TOGGLEDDSQL, _("&SQL Window"), _("Show / Hide SQL Window")); viewMenu->Check(MNU_TOGGLEDDSQL, true); viewMenu->Check(MNU_TOGGLEMBROWSER, true); // Set Help menu helpMenu = new wxMenu(); helpMenu->Append(MNU_CONTENTS, _("&Help"), _("Open the helpfile.")); helpMenu->Append(MNU_HELP, _("&SQL Help\tF1"), _("Display help on SQL commands.")); // Set menu bar menuBar = new wxMenuBar(); menuBar->Append(fileMenu, _("&File")); menuBar->Append(diagramMenu, _("&Diagram")); menuBar->Append(viewMenu, _("&View")); menuBar->Append(helpMenu, _("&Help")); SetMenuBar(menuBar); // Set status bar int iWidths[6] = {0, -1, 40, 150, 80, 80}; CreateStatusBar(6); SetStatusBarPane(-1); SetStatusWidths(6, iWidths); // Set toolbar toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); toolBar->SetToolBitmapSize(wxSize(16, 16)); toolBar->AddTool(MNU_NEW, _("New Model"), *file_new_png_bmp, _("Create new model"), wxITEM_NORMAL); toolBar->AddTool(MNU_NEWDIAGRAM, _("New Diagram"), *ddnewdiagram_png_bmp, _("Add new diagram"), wxITEM_NORMAL); toolBar->AddSeparator(); toolBar->AddTool(MNU_LOADMODEL, _("Open Model"), *file_open_png_bmp, _("Open existing model"), wxITEM_NORMAL); toolBar->AddTool(MNU_SAVEMODEL, _("Save Model"), *file_save_png_bmp, _("Save current model"), wxITEM_NORMAL); toolBar->AddSeparator(); toolBar->AddTool(MNU_ADDTABLE, _("Add Table"), *table_png_bmp, _("Add empty table to the current model"), wxITEM_NORMAL); toolBar->AddTool(MNU_DELETETABLE, _("Delete Table"), wxBitmap(*ddRemoveTable2_png_img), _("Delete selected table"), wxITEM_NORMAL); toolBar->AddTool(MNU_ADDCOLUMN, _("Add Column"), *table_png_bmp, _("Add new column to the selected table"), wxITEM_NORMAL); toolBar->AddSeparator(); toolBar->AddTool(MNU_GENERATEMODEL, _("Generate Model"), *continue_png_bmp, _("Generate SQL for the current model"), wxITEM_NORMAL); toolBar->AddTool(MNU_GENERATEDIAGRAM, _("Generate Diagram"), *ddgendiagram_png_bmp, _("Generate SQL for the current diagram"), wxITEM_NORMAL); toolBar->AddSeparator(); toolBar->AddTool(CTL_IMPSCHEMA, _("Import Tables from database..."), *conversion_png_ico, _("Import tables from database schema to database designer model"), wxITEM_NORMAL); toolBar->AddSeparator(); toolBar->AddTool(MNU_HELP, _("Help"), *help_png_bmp, _("Display help"), wxITEM_NORMAL); toolBar->Realize(); // Create notebook for diagrams diagrams = new ctlAuiNotebook(this, CTL_DDNOTEBOOK, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON | wxAUI_NB_CLOSE_ON_ALL_TABS); // Now, the scratchpad sqltext = new ctlSQLBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSIMPLE_BORDER | wxTE_RICH2); //Now, the Objects Browser wxSizer *browserSizer = new wxBoxSizer(wxHORIZONTAL); browserPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); // Add the database designer design = new ddDatabaseDesign(diagrams, this); // Create database model browser modelBrowser = new ddModelBrowser(browserPanel, DD_BROWSER, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSIMPLE_BORDER, design); design->registerBrowser(modelBrowser); // Set browser Sizers browserSizer->Add(modelBrowser, 1, wxEXPAND); browserPanel->SetSizer(browserSizer); browserSizer->SetSizeHints(browserPanel); // Add view to notebook diagrams->AddPage(design->createDiagram(diagrams, _("unnamed"), false)->getView(), _("unnamed")); // Add the database selection bar and schema selector wxSizer *connectionSizer = new wxBoxSizer(wxHORIZONTAL); connectionPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1)); cbConnection = new wxBitmapComboBox(connectionPanel, CTL_DDCONNECTION, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxArrayString(), wxCB_READONLY | wxCB_DROPDOWN); if(conn) cbConnection->Append(conn->GetName(), CreateBitmap(GetServerColour(conn)), (void *)conn); cbConnection->Append(_(""), wxNullBitmap, (void *) NULL); connectionSizer->Add(cbConnection, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1); connectionSizer->AddSpacer(5); connectionPanel->SetSizer(connectionSizer); connectionSizer->SetSizeHints(connectionPanel); // Add the panes manager.AddPane(diagrams, wxAuiPaneInfo().Center(). Name(wxT("sqlQuery")).Caption(_("Database Designer")). CaptionVisible(true).CloseButton(false).MaximizeButton(true). Dockable(true).Movable(true)); manager.AddPane(browserPanel, wxAuiPaneInfo().Left(). Name(wxT("ModelBrowser")).Caption(_("Model Browser")). CaptionVisible(true).CloseButton(true).MinimizeButton(true). MinSize(wxSize(140, 100)).BestSize(wxSize(200, 200))); manager.AddPane(sqltext, wxAuiPaneInfo().Bottom(). Name(wxT("sqlText")).Caption(_("SQL query")). CaptionVisible(true).CloseButton(true).MaximizeButton(true).MinimizeButton(true). MinSize(wxSize(200, 100)).BestSize(wxSize(350, 150))); manager.AddPane(toolBar, wxAuiPaneInfo().Top(). Name(wxT("toolBar")).Caption(_("Tool bar")). ToolbarPane(). LeftDockable(false).RightDockable(false)); manager.AddPane(connectionPanel, wxAuiPaneInfo().Name(wxT("databaseBar")) .Caption(_("Connection bar")).ToolbarPane().Top(). LeftDockable(false).RightDockable(false)); // Update the AUI manager manager.Update(); //Update browser info modelBrowser->SetSize(browserPanel->GetSize()); previousChanged = true; setModelChanged(false); SetStatusText(wxString(wxT("Ready")), 1); } frmDatabaseDesigner::~frmDatabaseDesigner() { closing = true; // Save form's position SavePosition(); // Uninitialize wxAUIManager manager.UnInit(); if (mainForm) mainForm->RemoveFrame(this); if(modelBrowser) delete modelBrowser; if(browserPanel) delete browserPanel; if(diagrams) delete diagrams; if(design) delete design; if (connection) { if (connection->IsAlive()) delete connection; } } void frmDatabaseDesigner::Go() { cbConnection->SetSelection(0L); if (connection) { wxCommandEvent event; OnChangeConnection(event); } loading = false; Show(true); } void frmDatabaseDesigner::setModelChanged(bool value) { previousChanged = changed; changed = value; // optimization to avoid unneeded operations // false changed for false don't trigger it, but false changed to true trigger it. if (previousChanged != changed) { wxMenuItem *itemMenu = fileMenu->FindItem(MNU_SAVEMODEL); if (value) { itemMenu->Enable(true); toolBar->EnableTool(MNU_SAVEMODEL, true); setExtendedTitle(); } else { itemMenu->Enable(false); toolBar->EnableTool(MNU_SAVEMODEL, false); setExtendedTitle(); } } } void frmDatabaseDesigner::OnClose(wxCloseEvent &event) { closing = true; // Ask what to do with old model if (changed) { int answer = wxMessageBox(_("Save model changes?"), _("Confirm"), wxYES_NO | wxCANCEL); if (answer == wxYES) { if (lastFile.IsEmpty()) { wxFileDialog openFileDialog( this, _("Save model"), wxT(""), wxT(""), wxT("*.pgd"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition); if (openFileDialog.ShowModal() == wxID_OK) { wxString path; path.append(openFileDialog.GetDirectory()); path.append(wxFileName::GetPathSeparator()); path.append(openFileDialog.GetFilename()); if(!path.Lower().Matches(wxT("*.pgd"))) path.append(wxT(".pgd")); lastFile = path; } } if (!lastFile.IsEmpty()) { design->writeXmlModel(lastFile); setModelChanged(false); setExtendedTitle(); } } else if (answer == wxCANCEL) { event.Veto(); return; } } Hide(); Destroy(); } void frmDatabaseDesigner::setExtendedTitle() { wxString title = wxT("Database Design"); wxString chgStr; if (changed) chgStr = wxT(" *"); if (lastFile.IsEmpty()) SetTitle(title + chgStr); else SetTitle(title + wxT(" - [") + lastFile + wxT("]") + chgStr); } void frmDatabaseDesigner::OnAddTable(wxCommandEvent &event) { if (diagrams->GetPageCount() > 0) { hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); ddTableNameDialog *newTableDialog = new ddTableNameDialog( this, wxEmptyString, wxEmptyString, NULL ); bool done = false, existsTable; int answer; do { answer = newTableDialog->ShowModal(); existsTable = design->getTable(newTableDialog->GetValue1()) != NULL; if (answer == wxID_OK && !newTableDialog->GetValue1().IsEmpty() && !existsTable) { ddTableFigure *newTable = new ddTableFigure(newTableDialog->GetValue1(), view->getIdx(), rand() % 90 + 200, rand() % 90 + 140); design->addTableToView(view->getIdx(), newTable); design->refreshDraw(view->getIdx()); setModelChanged(true); setExtendedTitle(); done = true; } else if(existsTable && answer == wxID_OK) { wxMessageBox(_("You have to change the table name because there is already a table with that name in this model."), _("Table already existing"), wxICON_EXCLAMATION | wxOK); } } while (answer != wxID_CANCEL && !done); delete newTableDialog; } } void frmDatabaseDesigner::OnDeleteTable(wxCommandEvent &event) { if (diagrams->GetPageCount() > 0) { hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); view->getDrawing()->deleteSelectedFigures(); setModelChanged(true); setExtendedTitle(); } } void frmDatabaseDesigner::OnAddColumn(wxCommandEvent &event) { if (diagrams->GetPageCount() > 0) { hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); ddTableFigure *table = design->getSelectedTable(view->getIdx()); wxTextEntryDialog nameDialog (this, wxT("New column name"), wxT("Add a column"), wxT("NewColumn")); int answer; wxString tmpString; if (table) { bool again; do { again = false; answer = nameDialog.ShowModal(); if (answer == wxID_OK) { tmpString = nameDialog.GetValue(); if(table->getColByName(tmpString) == NULL) { table->addColumn(view->getIdx(), new ddColumnFigure(tmpString, table)); setModelChanged(true); setExtendedTitle(); } else { wxString msg(wxT("Error trying to add new column '")); msg.Append(tmpString); msg.Append(wxT("' column name already in use")); wxMessageDialog info( this, msg , wxT("Column name already in use"), wxNO_DEFAULT | wxOK | wxICON_EXCLAMATION); again = true; info.ShowModal(); } } } while(again); } view->Refresh(); } else { wxMessageBox(_("Warning about adding a column to a table without a diagram"), _("Please create a model diagram first"), wxICON_EXCLAMATION | wxOK); } } void frmDatabaseDesigner::OnNewModel(wxCommandEvent &event) { hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); if (changed) { // Ask what to do with old model int answer = wxMessageBox(_("Save model changes?"), _("Confirm"), wxYES_NO | wxCANCEL); if (answer == wxYES) { if (!lastFile.IsEmpty()) OnModelSave(event); else OnModelSaveAs(event); } else if (answer == wxCANCEL) return; } // Clean treeview, notebook, and sql pane design->emptyModel(); while (diagrams->GetPageCount() > 0) { diagrams->RemovePage(0); design->deleteDiagram(0); } sqltext->SetText(wxEmptyString); // Add new diagram diagrams->AddPage(design->createDiagram(diagrams, _("unnamed"), false)->getView(), _("unnamed")); // Misc lastFile = wxEmptyString; setModelChanged(false); setExtendedTitle(); UpdateToolbar(); } void frmDatabaseDesigner::OnDiagramGeneration(wxCommandEvent &event) { wxString errors; if(!design->validateModel(errors)) { wxMessageDialog dialog(this, errors , wxT("Errors detected in the database model"), wxOK | wxICON_EXCLAMATION | wxSTAY_ON_TOP); dialog.ShowModal(); } else { hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); ddGenerationWizard *generationWizard = new ddGenerationWizard(this, design, connection); //Set pre-select tables [diagram] generationWizard->preSelTables = design->getDiagramTables(view->getIdx()); //Call generation wizard generationWizard->RunWizard(generationWizard->GetFirstPage()); sqltext->SetText(generationWizard->DDL); delete generationWizard; } } void frmDatabaseDesigner::OnModelGeneration(wxCommandEvent &event) { wxString errors; if(!design->validateModel(errors)) { wxMessageDialog dialog(this, errors , wxT("Errors detected in the database model"), wxOK | wxICON_EXCLAMATION | wxSTAY_ON_TOP); dialog.ShowModal(); } else { ddGenerationWizard *generationWizard = new ddGenerationWizard(this, design, connection); //Set pre-select tables [model] disable //generationWizard->preSelTables = design->getModelTables(); //Call generation wizard generationWizard->RunWizard(generationWizard->GetFirstPage()); sqltext->SetText(generationWizard->DDL); delete generationWizard; } } void frmDatabaseDesigner::OnModelSaveAs(wxCommandEvent &event) { wxFileDialog openFileDialog( this, _("Save model"), wxT(""), wxT(""), wxT("*.pgd"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition); if (openFileDialog.ShowModal() == wxID_OK) { wxString path; path.append( openFileDialog.GetDirectory() ); path.append( wxFileName::GetPathSeparator() ); path.append( openFileDialog.GetFilename() ); if(!path.Lower().Matches(wxT("*.pgd"))) path.append(wxT(".pgd")); lastFile = path; setModelChanged(false); setExtendedTitle(); design->writeXmlModel(path); } } void frmDatabaseDesigner::OnModelSave(wxCommandEvent &event) { if (lastFile != wxEmptyString) { design->writeXmlModel(lastFile); setModelChanged(false); setExtendedTitle(); } else { OnModelSaveAs(event); } } void frmDatabaseDesigner::OnModelLoad(wxCommandEvent &event) { if(changed) { // Ask what to do with old model int answer = wxMessageBox(_("Save model changes?"), _("Confirm"), wxYES_NO | wxCANCEL); if (answer == wxYES) { if (lastFile != wxEmptyString) OnModelSave(event); else OnModelSaveAs(event); } if(answer == wxCANCEL) return; } //Open Model wxFileDialog openFileDialog(this, _("Open model"), wxT(""), wxT(""), wxT("*.pgd"), wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition); if (openFileDialog.ShowModal() == wxID_OK) { wxString path; path.append(openFileDialog.GetDirectory()); path.append(wxFileName::GetPathSeparator()); path.append(openFileDialog.GetFilename()); if(!path.Lower().Matches(wxT("*.pgd"))) path.append(wxT(".pgd")); lastFile = path; // Clean treeview, notebook, and sql pane design->emptyModel(); while(diagrams->GetPageCount() > 0) { diagrams->RemovePage(0); design->deleteDiagram(0); } sqltext->SetText(wxEmptyString); // Read model from xml file design->readXmlModel(path, diagrams); setModelChanged(false); setExtendedTitle(); } } void frmDatabaseDesigner::OnAddDiagram(wxCommandEvent &event) { wxString newName = wxGetTextFromUser(_("New Diagram Name"), _("Diagram Name"), _("unnamed"), this); if (!newName.IsEmpty()) { diagrams->AddPage(design->createDiagram(diagrams, newName, false)->getView(), newName); setModelChanged(true); } UpdateToolbar(); } void frmDatabaseDesigner::OnAddDiagram2(wxAuiNotebookEvent &event) { wxCommandEvent evt; OnAddDiagram(evt); } void frmDatabaseDesigner::OnDeleteDiagram(wxCommandEvent &event) { hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); int diagramIndex = view->getIdx(); diagrams->RemovePage(diagrams->GetSelection()); design->deleteDiagram(diagramIndex); setModelChanged(true); UpdateToolbar(); } void frmDatabaseDesigner::OnRenameDiagram(wxCommandEvent &event) { hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); int diagramIndex = view->getIdx(); wxString msg; msg.Printf(_("Rename diagram %s to:"), diagrams->GetPageText(diagramIndex).c_str()); wxString name = wxGetTextFromUser(msg, _("Rename diagram..."), diagrams->GetPageText(diagramIndex), this); if(!name.IsEmpty() && !name.IsSameAs(diagrams->GetPageText(diagramIndex), false)) { view->getDrawing()->setName(name); diagrams->SetPageText(diagramIndex, name); setModelChanged(true); } } void frmDatabaseDesigner::OnDeleteDiagramTab(wxAuiNotebookEvent &event) { deletedTab = event.GetSelection(); wxAuiNotebook *ctrl = (wxAuiNotebook *)event.GetEventObject(); hdDrawingView *view = (hdDrawingView *) ctrl->GetPage(event.GetSelection()); wxString msg; msg.Printf(_("Are you sure you want to delete diagram \"%s\" from model?"), view->getDrawing()->getName().c_str()); int res = wxMessageBox(msg, wxT("Delete diagram?"), wxYES_NO | wxNO_DEFAULT, this); if (res != wxYES) { event.Veto(); } else { setModelChanged(true); } UpdateToolbar(); } void frmDatabaseDesigner::OnDeletedDiagramTab(wxAuiNotebookEvent &event) { //don't delete view when deleting diagram because it was deleted before by EVT_AUINOTEBOOK_PAGE_CLOSE event //option possible will be wxAuiPaneInfo().DestroyOnClose(false) but should be tried in a future design->deleteDiagram(deletedTab, false); UpdateToolbar(); } void frmDatabaseDesigner::OnClickDiagramTab(wxAuiNotebookEvent &event) { //This event is not working by unknown reason right now. wxLogError(wxT("WTF?")); } void frmDatabaseDesigner::UpdateToolbar() { toolBar->EnableTool(MNU_ADDTABLE, diagrams->GetPageCount() > 0); toolBar->EnableTool(MNU_DELETETABLE, diagrams->GetPageCount() > 0); if (diagrams->GetPageCount() > 0) { hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); ddTableFigure *table = design->getSelectedTable(view->getIdx()); toolBar->EnableTool(MNU_ADDCOLUMN, table != NULL); } toolBar->EnableTool(MNU_GENERATEMODEL, diagrams->GetPageCount() > 0); toolBar->EnableTool(MNU_GENERATEDIAGRAM, diagrams->GetPageCount() > 0); } wxColour frmDatabaseDesigner::GetServerColour(pgConn *connection) { wxColour tmp = wxNullColour; if (mainForm != NULL) { ctlTree *browser = mainForm->GetBrowser(); wxTreeItemIdValue foldercookie, servercookie; wxTreeItemId folderitem, serveritem; pgObject *object; pgServer *server; folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); while (folderitem) { if (browser->ItemHasChildren(folderitem)) { serveritem = browser->GetFirstChild(folderitem, servercookie); while (serveritem) { object = browser->GetObject(serveritem); if (object && object->IsCreatedBy(serverFactory)) { server = (pgServer *)object; if (server->GetConnected() && server->GetConnection()->GetHost() == connection->GetHost() && server->GetConnection()->GetPort() == connection->GetPort()) { tmp = wxColour(server->GetColour()); } } serveritem = browser->GetNextChild(folderitem, servercookie); } } folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); } } return tmp; } wxBitmap frmDatabaseDesigner::CreateBitmap(const wxColour &colour) { const int w = 10, h = 10; wxMemoryDC dc; wxBitmap bmp(w, h); dc.SelectObject(bmp); if (colour == wxNullColour) dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW))); else dc.SetBrush(wxBrush(colour)); dc.DrawRectangle(0, 0, w, h); return bmp; } void frmDatabaseDesigner::OnChangeConnection(wxCommandEvent &event) { // On Solaris, this event seems to get fired when the form closes(!!) if(!IsVisible() && !loading) return; unsigned int sel = cbConnection->GetSelection(); if (sel == cbConnection->GetCount() - 1) { // new Connection dlgSelectConnection dlg(this, mainForm); int rc = dlg.Go(connection, cbConnection); if (rc == wxID_OK) { bool createdNewConn; wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Database Designer"); pgConn *newconn = dlg.CreateConn(applicationname, createdNewConn); if (newconn && createdNewConn) { cbConnection->Insert(newconn->GetName(), CreateBitmap(GetServerColour(newconn)), sel); cbConnection->SetClientData(sel, (void *)newconn); cbConnection->SetSelection(sel); OnChangeConnection(event); } else rc = wxID_CANCEL; } if (rc != wxID_OK) { unsigned int i; for (i = 0 ; i < sel ; i++) { if (cbConnection->GetClientData(i) == connection) { cbConnection->SetSelection(i); break; } } } } else { connection = (pgConn *)cbConnection->GetClientData(sel); setExtendedTitle(); } } void frmDatabaseDesigner::OnImportSchema(wxCommandEvent &WXUNUSED(event)) { ddDBReverseEngineering *importTableWizard = new ddDBReverseEngineering(this, design, connection); importTableWizard->RunWizard(importTableWizard->GetFirstPage()); delete importTableWizard; } void frmDatabaseDesigner::OnToggleModelBrowser(wxCommandEvent &event) { if (viewMenu->IsChecked(MNU_TOGGLEMBROWSER)) manager.GetPane(wxT("ModelBrowser")).Show(true); else manager.GetPane(wxT("ModelBrowser")).Show(false); manager.Update(); } void frmDatabaseDesigner::OnToggleSQLWindow(wxCommandEvent &event) { if (viewMenu->IsChecked(MNU_TOGGLEDDSQL)) manager.GetPane(wxT("sqlText")).Show(true); else manager.GetPane(wxT("sqlText")).Show(false); manager.Update(); } /////////////////////////////////////////////////////// bool databaseDesignerBaseFactory::CheckEnable(pgObject *obj) { return obj && obj->GetDatabase() && obj->GetDatabase()->GetConnected(); } wxWindow *databaseDesignerBaseFactory::StartDialogDesigner(frmMain *form, pgObject *obj, const wxString &sql) { if(obj) { pgDatabase *db = obj->GetDatabase(); wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Database designer"); pgConn *conn = NULL; if(db) { conn = db->CreateConn(applicationname); if (conn) { frmDatabaseDesigner *fd = new frmDatabaseDesigner(form, wxEmptyString, conn); fd->Go(); return fd; } } } frmDatabaseDesigner *fd = new frmDatabaseDesigner(form, wxEmptyString, NULL); fd->Go(); return fd; } databaseDesignerFactory::databaseDesignerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : databaseDesignerBaseFactory(list) { mnu->Append(id, _("&Database Designer\tCtrl-F"), _("Create database designs")); toolbar->AddTool(id, _("Database Designer\tCtrl-F"), wxBitmap(*ddmodel_32_png_img), _("Create database designs."), wxITEM_NORMAL); } wxWindow *databaseDesignerFactory::StartDialog(frmMain *form, pgObject *obj) { wxString qry; if (settings->GetStickySql()) qry = obj->GetSql(form->GetBrowser()); return StartDialogDesigner(form, obj, qry); }