////////////////////////////////////////////////////////////////////////// // // pgAdmin III - PostgreSQL Tools // // Copyright (C) 2002 - 2016, The pgAdmin Development Team // This software is released under the PostgreSQL Licence // // dlgSelectConnection.cpp - Connect to a database // ////////////////////////////////////////////////////////////////////////// // App headers #include "pgAdmin3.h" // wxWindows headers #include #include // App headers #include "frm/frmMain.h" #include "dlg/dlgSelectConnection.h" #include "dlg/dlgConnect.h" #include "schema/pgServer.h" #include "images/connect.pngc" #define CTRLID_CBSERVER 4242 #define CTRLID_CBDATABASE 4243 #define CTRLID_CBUSERNAME 4244 #define CTRLID_CBROLENAME 4245 #define CTRLID_CBGROUP 4246 BEGIN_EVENT_TABLE(dlgSelectConnection, DialogWithHelp) EVT_COMBOBOX(CTRLID_CBGROUP, dlgSelectConnection::OnChangeGroup) EVT_COMBOBOX(CTRLID_CBSERVER, dlgSelectConnection::OnChangeServer) EVT_COMBOBOX(CTRLID_CBDATABASE, dlgSelectConnection::OnChangeDatabase) EVT_TEXT(CTRLID_CBSERVER, dlgSelectConnection::OnTextChange) EVT_TEXT(CTRLID_CBDATABASE, dlgSelectConnection::OnTextChange) EVT_TEXT(CTRLID_CBUSERNAME, dlgSelectConnection::OnTextChange) EVT_BUTTON (wxID_OK, dlgSelectConnection::OnOK) EVT_BUTTON (wxID_CANCEL, dlgSelectConnection::OnCancel) END_EVENT_TABLE() #define stUsername CTRL_STATIC("stUsername") dlgSelectConnection::dlgSelectConnection(wxWindow *parent, frmMain *form) : DialogWithHelp(form) { long style = wxCB_DROPDOWN; remoteServer = NULL; SetFont(settings->GetSystemFont()); LoadResource(parent, wxT("dlgSelectConnection")); SetIcon(*connect_png_ico); RestorePosition(); if (form != NULL) style |= wxCB_READONLY; cbGroup = new wxComboBox(this, CTRLID_CBGROUP, wxEmptyString, ConvertDialogToPixels(wxPoint(70, 5)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); cbServer = new ctlComboBoxFix(this, CTRLID_CBSERVER, ConvertDialogToPixels(wxPoint(70, 20)), ConvertDialogToPixels(wxSize(135, 12)), style); cbDatabase = new wxComboBox(this, CTRLID_CBDATABASE, wxEmptyString, ConvertDialogToPixels(wxPoint(70, 35)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); cbUsername = new wxComboBox(this, CTRLID_CBUSERNAME, wxEmptyString, ConvertDialogToPixels(wxPoint(70, 50)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); cbRolename = new wxComboBox(this, CTRLID_CBROLENAME, wxEmptyString, ConvertDialogToPixels(wxPoint(70, 75)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); if (form == NULL) { cbServer->SetValue(settings->Read(wxT("QuickConnect/server"), wxEmptyString)); cbGroup->SetValue(settings->Read(wxT("QuickConnect/group"), wxEmptyString)); cbDatabase->SetValue(settings->Read(wxT("QuickConnect/database"), wxEmptyString)); cbUsername->SetValue(settings->Read(wxT("QuickConnect/username"), wxEmptyString)); cbRolename->SetValue(settings->Read(wxT("QuickConnect/rolename"), wxEmptyString)); } else { wxTreeItemIdValue foldercookie, servercookie; wxTreeItemId folderitem, serveritem; ctlTree *browser = mainForm->GetBrowser(); folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); cbGroup->Append(""); while (folderitem) { wxString grp=browser->GetItemText(folderitem); cbGroup->Append(grp); folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); } } btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0); } dlgSelectConnection::~dlgSelectConnection() { SavePosition(); } wxString dlgSelectConnection::GetHelpPage() const { return wxT("connect"); } void dlgSelectConnection::OnChangeGroup(wxCommandEvent &ev) { int sel = cbGroup->GetCurrentSelection(); if (sel >= 0) { bool found=BuildServerCombo(currconn); if (!found) cbServer->SetSelection(0); OnChangeServer(ev); } } void dlgSelectConnection::OnChangeServer(wxCommandEvent &ev) { int item; wxString olddatabase, oldusername; if (!GetServer()) return; // Keep old value for these comboboxes so that we can restore them if needed olddatabase = cbDatabase->GetValue(); oldusername = cbUsername->GetValue(); // Clear the comboboxes cbDatabase->Clear(); cbUsername->Clear(); cbRolename->Clear(); int sel = cbServer->GetCurrentSelection(); if (sel >= 0) { remoteServer = (pgServer *)cbServer->wxItemContainer::GetClientData(sel); if (!remoteServer->GetConnected()) { remoteServer->Connect(mainForm, remoteServer->GetStorePwd()); if (!remoteServer->GetConnected()) { wxLogError(wxT("%s"), remoteServer->GetLastError().c_str()); return; } } if (remoteServer->GetConnected()) { pgSetIterator set1(remoteServer->GetConnection(), wxT("SELECT DISTINCT datname\n") wxT(" FROM pg_database db\n") wxT(" WHERE datallowconn ORDER BY datname")); item = 0; int item2 = -1; wxString v; while(set1.RowsLeft()) { v = set1.GetVal(wxT("datname")); cbDatabase->Append(v); if (v == olddatabase) item = cbDatabase->GetCount() - 1; else if (v.StartsWith("template") || v == "postgres") continue; else if (item2 == -1) item2 = cbDatabase->GetCount() - 1; } if (cbDatabase->GetCount()) if (item2>=0) {cbDatabase->SetSelection(item2);} else {cbDatabase->SetSelection(item);} pgSetIterator set2(remoteServer->GetConnection(), wxT("SELECT DISTINCT usename\n") wxT("FROM pg_user db\n") wxT("ORDER BY usename")); item = 0; while(set2.RowsLeft()) { cbUsername->Append(set2.GetVal(wxT("usename"))); if (set2.GetVal(wxT("usename")) == oldusername) item = cbUsername->GetCount() - 1; } if (cbUsername->GetCount()) cbUsername->SetSelection(item); if (remoteServer->GetConnection()->BackendMinimumVersion(8, 1)) { pgSetIterator set3(remoteServer->GetConnection(), wxT("SELECT DISTINCT rolname\n") wxT("FROM pg_roles db\n") wxT("ORDER BY rolname")); cbRolename->Append(wxEmptyString); while(set3.RowsLeft()) cbRolename->Append(set3.GetVal(wxT("rolname"))); cbRolename->Enable(true); } else cbRolename->Disable(); cbRolename->SetValue(wxEmptyString); } } OnChangeDatabase(ev); } wxString dlgSelectConnection::GetDatabase() { return cbDatabase->GetValue(); } wxString dlgSelectConnection::GetServerName() { return cbServer->GetValue(); } void dlgSelectConnection::OnChangeDatabase(wxCommandEvent &ev) { btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0); } void dlgSelectConnection::OnTextChange(wxCommandEvent &ev) { btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0); } void dlgSelectConnection::OnOK(wxCommandEvent &ev) { #ifdef __WXGTK__ if (!btnOK->IsEnabled()) return; #endif if (cbDatabase->GetCurrentSelection() == wxNOT_FOUND || cbServer->GetCurrentSelection() == wxNOT_FOUND) remoteServer = NULL; EndModal(wxID_OK); } void dlgSelectConnection::OnCancel(wxCommandEvent &ev) { EndModal(wxID_CANCEL); } pgConn *dlgSelectConnection::CreateConn(wxString &applicationname, bool &createdNew) { /* gcc requires that we store this in temporary variables for some reason... */ wxString serv = cbServer->GetValue(); wxString db = cbDatabase->GetValue(); createdNew = true; long port = 0; if (serv.Find(':') > 0) { if (!serv.Mid(serv.Find(':') + 1).ToLong(&port)) { wxMessageBox(_("Invalid port number specified.")); return NULL; } serv = serv.Mid(0, serv.Find(':')); } wxString user = cbUsername->GetValue(); wxString role = cbRolename->GetValue(); if (cbConnection) { /* Check if selected combination already exists */ for (unsigned int index = 0; index < cbConnection->GetCount() - 1; index++) { pgConn *conn = (pgConn *)cbConnection->GetClientData(index); if (conn && conn->GetHost() == serv && conn->GetPort() == port && conn->GetUser() == user && conn->GetRole() == role && conn->GetDbname() == db) { createdNew = false; return conn; } } } int sslmode = remoteServer ? remoteServer->GetSSL() : 0; wxString addconnstr; if (remoteServer) { addconnstr = remoteServer->GetConnStr(); } return CreateConn(serv, db, user, port, role, addconnstr, sslmode, applicationname, true); } pgConn *dlgSelectConnection::CreateConn(wxString &server, wxString &dbname, wxString &username, int port, wxString &rolename, wxString &addconnstr, int sslmode, wxString &applicationname, bool writeMRU) { pgConn *newconn; newconn = new pgConn(server, wxEmptyString, wxEmptyString, dbname, username, wxT(""), port, rolename, addconnstr, sslmode, 0, applicationname); if (newconn->GetStatus() != PGCONN_OK && newconn->GetLastError().Cmp(wxString(PQnoPasswordSupplied, wxConvUTF8)) == 0) { /* Needs password */ delete newconn; newconn = NULL; wxString txt; txt.Printf(_("Please enter password for user %s\non server %s"), username.c_str(), server.c_str()); dlgConnect dlg(NULL, txt, false); if (dlg.Go() != wxID_OK) return NULL; newconn = new pgConn(server, wxEmptyString, wxEmptyString, dbname, username, dlg.GetPassword(), port, rolename, addconnstr, sslmode, 0, applicationname); } if (newconn) { if (newconn->GetStatus() != PGCONN_OK) { wxMessageBox(wxT("Connection failed: ") + newconn->GetLastError()); return NULL; } if (writeMRU) { settings->Write(wxT("QuickConnect/server"), cbServer->GetValue()); settings->Write(wxT("QuickConnect/group"), cbGroup->GetValue()); settings->Write(wxT("QuickConnect/database"), cbDatabase->GetValue()); settings->Write(wxT("QuickConnect/username"), cbUsername->GetValue()); settings->Write(wxT("QuickConnect/rolename"), cbRolename->GetValue()); } } return newconn; } bool dlgSelectConnection::BuildServerCombo(pgConn *conn) { bool foundServer = false; if (mainForm != NULL) { ctlTree *browser = mainForm->GetBrowser(); wxTreeItemIdValue foldercookie, servercookie; wxTreeItemId folderitem, serveritem; pgObject *object; pgServer *server; wxString grp; cbServer->Clear(); if (cbGroup->GetCurrentSelection() != wxNOT_FOUND) { grp=cbGroup->GetValue(); } folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); while (folderitem) { bool isGroup=true; if (grp.Length()>0) if (browser->GetItemText(folderitem)!=grp ) isGroup=false; if (browser->ItemHasChildren(folderitem) && isGroup) { serveritem = browser->GetFirstChild(folderitem, servercookie); while (serveritem) { object = browser->GetObject(serveritem); if (object && object->IsCreatedBy(serverFactory)) { server = (pgServer *)object; cbServer->Append(server->GetIdentifier(), (void *)server); if (server->GetConnected() && server->GetConnection()->GetHost() == conn->GetHost() && server->GetConnection()->GetPort() == conn->GetPort()) { cbServer->SetSelection(cbServer->GetCount() - 1); remoteServer = server; foundServer = true; } } serveritem = browser->GetNextChild(folderitem, servercookie); } } folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); } } cbServer->SetFocus(); wxCommandEvent ev; OnChangeServer(ev); if (foundServer) { unsigned int index = 0; for (; index < cbDatabase->GetCount(); index++) { if (cbDatabase->GetString(index) == conn->GetDbname()) { cbDatabase->SetSelection(index); break; } } for (index = 0; index < cbUsername->GetCount(); index++) { if (cbUsername->GetString(index) == conn->GetUser()) { cbUsername->SetSelection(index); break; } } for (index = 0; index < cbRolename->GetCount(); index++) { if (cbRolename->GetString(index) == conn->GetRole()) { cbRolename->SetSelection(index); break; } } } return foundServer; } int dlgSelectConnection::Go(pgConn *conn, wxBitmapComboBox *cb) { bool foundServer = false; cbConnection = cb; currconn=conn; foundServer = BuildServerCombo(conn); return ShowModal(); }