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 // pgAdmin3.cpp - The application
9 //
10 //////////////////////////////////////////////////////////////////////////
11
12
13 #include "pgAdmin3.h"
14
15 // wxWindows headers
16 #include <wx/wx.h>
17 #include <wx/app.h>
18 #include <wx/cmdline.h>
19 #include <wx/dir.h>
20 #include <wx/file.h>
21 #include <wx/xrc/xmlres.h>
22 #include <wx/image.h>
23 #include <wx/imagjpeg.h>
24 #include <wx/imaggif.h>
25 #include <wx/imagpng.h>
26 #include <wx/fs_zip.h>
27 #include <wx/socket.h>
28 #include <wx/stdpaths.h>
29 #include <wx/clipbrd.h>
30 #include <wx/sysopt.h>
31
32 // wxOGL
33 #include <ogl/ogl.h>
34
35 // Windows headers
36 #ifdef __WXMSW__
37 #include <winsock.h>
38 #endif
39
40 // Linux headers
41 #ifdef __LINUX__
42 #include <signal.h>
43 #endif
44
45 #ifdef __WXGTK__
46 #include <wx/renderer.h>
47 #endif
48
49 // App headers
50 #include "copyright.h"
51 #include "version.h"
52 #include "utils/misc.h"
53 #include "utils/sysSettings.h"
54 #include "schema/pgServer.h"
55 #include "frm/frmMain.h"
56 #include "frm/frmConfig.h"
57 #include "frm/frmQuery.h"
58 #include "frm/frmStatus.h"
59 #ifdef DATABASEDESIGNER
60 #include "frm/frmDatabaseDesigner.h"
61 #endif
62 #include "frm/frmSplash.h"
63 #include "dlg/dlgSelectConnection.h"
64 #include "db/pgConn.h"
65 #include "utils/sysLogger.h"
66 #include "utils/registry.h"
67 #include "frm/frmHint.h"
68
69 #include "ctl/xh_calb.h"
70 #include "ctl/xh_timespin.h"
71 #include "ctl/xh_sqlbox.h"
72 #include "ctl/xh_ctlcombo.h"
73 #include "ctl/xh_ctltree.h"
74 #include "ctl/xh_ctlchecktreeview.h"
75 #include "ctl/xh_ctlcolourpicker.h"
76
77 #define DOC_DIR wxT("/docs")
78 #define UI_DIR wxT("/ui")
79 #define I18N_DIR wxT("/i18n")
80 #define BRANDING_DIR wxT("/branding")
81 #define PLUGINS_DIR wxT("/plugins.d")
82 #define SETTINGS_INI wxT("/settings.ini")
83
84 // Globals
85 frmMain *winMain = 0;
86 wxThread *updateThread = 0;
87
88 #if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT)
89 #include "utils/sshTunnel.h"
90 CSSHTunnelThread *pgadminTunnelThread = 0;
91 #endif
92
93 sysSettings *settings;
94 wxArrayInt existingLangs;
95 wxArrayString existingLangNames;
96 wxLocale *locale = 0;
97 pgAppearanceFactory *appearanceFactory = 0;
98
99 wxString pgBackupExecutable; // complete filename of PostgreSQL's pg_dump, pg_dumpall and pg_restore, if available
100 wxString pgBackupAllExecutable;
101 wxString pgRestoreExecutable;
102
103 wxString edbBackupExecutable; // complete filename of EnterpriseDB's pg_dump, pg_dumpall and pg_restore, if available
104 wxString edbBackupAllExecutable;
105 wxString edbRestoreExecutable;
106
107 wxString gpBackupExecutable; // complete filename of Greenplum's pg_dump, pg_dumpall and pg_restore, if available
108 wxString gpBackupAllExecutable;
109 wxString gpRestoreExecutable;
110
111 wxString loadPath; // Where the program is loaded from
112 wxString dataDir; // The program data directory
113 wxString docPath; // Where docs are stored
114 wxString uiPath; // Where ui data is stored
115 wxString i18nPath; // Where i18n data is stored
116 wxString brandingPath; // Where branding data is stored
117 wxString pluginsDir; // The plugins ini file directory
118 wxString settingsIni; // The settings.ini file
119
120 wxLog *logger;
121
122 bool dialogTestMode = false;
123
124 #define LANG_FILE wxT("pgadmin3.lng")
125
126 IMPLEMENT_APP(pgAdmin3)
127
128 #ifdef __WXMSW__
129 // Dynamically loaded EDB functions
130 PQGETOUTRESULT PQiGetOutResult;
131 PQPREPAREOUT PQiPrepareOut;
132 PQSENDQUERYPREPAREDOUT PQiSendQueryPreparedOut;
133 #endif
134
135 #ifdef __WXGTK__
136
137 class pgRendererNative : public wxDelegateRendererNative
138 {
139 public:
pgRendererNative()140 pgRendererNative() : wxDelegateRendererNative(wxRendererNative::GetDefault()) {}
141
DrawTreeItemButton(wxWindow * win,wxDC & dc,const wxRect & rect,int flags)142 void DrawTreeItemButton(wxWindow *win, wxDC &dc, const wxRect &rect, int flags)
143 {
144 GetGeneric().DrawTreeItemButton(win, dc, rect, flags);
145 }
146 };
147
148 #endif
149 #define CTL_LB 100
150 class frmDlgTest : public wxFrame
151 {
152 public:
153 frmDlgTest();
154 private:
155 void OnSelect(wxCommandEvent &ev);
156 wxListBox *dlgList;
157 DECLARE_EVENT_TABLE()
158 };
159
160
161 BEGIN_EVENT_TABLE(frmDlgTest, wxFrame)
162 EVT_LISTBOX_DCLICK(CTL_LB, frmDlgTest::OnSelect)
163 END_EVENT_TABLE();
164
165
frmDlgTest()166 frmDlgTest::frmDlgTest() : wxFrame(0, -1, wxT("pgAdmin III Translation test mode"))
167 {
168 dlgList = new wxListBox(this, CTL_LB, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SORT);
169
170 // unfortunately, the MemoryFS has no search functions implemented
171 // so we can't extract the names in the EMBED_XRC case
172
173 wxDir dir(uiPath);
174 wxString filename;
175
176 bool found = dir.GetFirst(&filename, wxT("*.xrc"));
177 while (found)
178 {
179 dlgList->Append(filename.Left(filename.Length() - 4));
180 found = dir.GetNext(&filename);
181 }
182 if (!dlgList->GetCount())
183 {
184 dlgList->Append(wxT("No xrc files in directory"));
185 dlgList->Append(uiPath);
186 dlgList->Disable();
187 }
188 }
189
190
OnSelect(wxCommandEvent & ev)191 void frmDlgTest::OnSelect(wxCommandEvent &ev)
192 {
193 wxString dlgName = dlgList->GetStringSelection();
194 if (!dlgName.IsEmpty())
195 {
196 pgDialog *dlg = new pgDialog;
197 dlg->SetFont(settings->GetSystemFont());
198 dlg->LoadResource(this, dlgName);
199 dlg->SetTitle(dlgName);
200 dlg->Show();
201 }
202 }
203
204
205 // The Application!
OnInit()206 bool pgAdmin3::OnInit()
207 {
208 // Force logging off until we're ready
209 wxLog *seLog = new wxLogStderr();
210 wxLog::SetActiveTarget(seLog);
211
212 // Setup the basic paths for the app installation. Required by settings!
213 InitAppPaths();
214
215 // Load the Settings
216 #ifdef __WXMSW__
217 settings = new sysSettings(wxT("pgAdmin III"));
218 #else
219 settings = new sysSettings(wxT("pgadmin3"));
220 #endif
221
222 // Setup additional helper paths etc. Requires settings!
223 InitXtraPaths();
224
225 locale = new wxLocale();
226 locale->AddCatalogLookupPathPrefix(i18nPath);
227
228 wxLanguage langId = (wxLanguage)settings->Read(wxT("LanguageId"), wxLANGUAGE_DEFAULT);
229 if (locale->Init(langId))
230 {
231 #ifdef __LINUX__
232 {
233 wxLogNull noLog;
234 locale->AddCatalog(wxT("fileutils"));
235 }
236 #endif
237 locale->AddCatalog(wxT("pgadmin3"));
238 }
239
240 #ifdef DATABASEDESIGNER
241 //Initialize Font
242 hdFontAttribute::InitFont();
243 #endif
244
245 long langCount = 0;
246 const wxLanguageInfo *langInfo;
247
248 wxString langfile = FileRead(i18nPath + wxT("/") LANG_FILE, 1);
249
250 if (!langfile.IsEmpty())
251 {
252 wxStringTokenizer tk(langfile, wxT("\n\r"));
253
254 while (tk.HasMoreTokens())
255 {
256 wxString line = tk.GetNextToken().Strip(wxString::both);
257 if (line.IsEmpty() || line.StartsWith(wxT("#")))
258 continue;
259
260 wxString englishName = line.BeforeFirst(',').Trim(true);
261 wxString translatedName = line.AfterFirst(',').Trim(false);
262
263 langInfo = wxLocale::FindLanguageInfo(englishName);
264 if (langInfo)
265 {
266 if (langInfo->CanonicalName == wxT("en_US") ||
267 (!langInfo->CanonicalName.IsEmpty() &&
268 wxDir::Exists(i18nPath + wxT("/") + langInfo->CanonicalName)))
269 {
270 existingLangs.Add(langInfo->Language);
271 existingLangNames.Add(translatedName);
272 langCount++;
273 }
274 }
275 }
276 }
277
278 static const wxCmdLineEntryDesc cmdLineDesc[] =
279 {
280 #if wxCHECK_VERSION(2, 9, 0)
281 // wxCmdLineEntryDesc is one of the few places in 2.9 where wxT()s have any effect...they break the build
282 {wxCMD_LINE_SWITCH, "v", "version", _("show the version, and quit"), wxCMD_LINE_VAL_NONE},
283 {wxCMD_LINE_SWITCH, "h", "help", _("show this help message, and quit"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
284 {wxCMD_LINE_OPTION, "s", "server", _("auto-connect to specified server"), wxCMD_LINE_VAL_STRING},
285 {wxCMD_LINE_SWITCH, "S", "serverstatus", _("open server status window"), wxCMD_LINE_VAL_NONE},
286 {wxCMD_LINE_OPTION, "Sc", "serverstatusconnect", _("connect server status window to database"), wxCMD_LINE_VAL_STRING},
287 {wxCMD_LINE_SWITCH, "q", "query", _("open query tool"), wxCMD_LINE_VAL_NONE},
288 {wxCMD_LINE_OPTION, "qc", "queryconnect", _("connect query tool to database"), wxCMD_LINE_VAL_STRING},
289 #ifdef DATABASEDESIGNER
290 {wxCMD_LINE_SWITCH, "d", "designer", _("open designer window"), wxCMD_LINE_VAL_NONE},
291 {wxCMD_LINE_OPTION, "dc", "designerconnectconnect", _("connect designer window to database"), wxCMD_LINE_VAL_STRING},
292 #endif
293 {wxCMD_LINE_OPTION, "f", "file", _("file to load into the query tool in -q or -qc mode"), wxCMD_LINE_VAL_STRING},
294 {wxCMD_LINE_OPTION, "cm", NULL, _("edit main configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE},
295 {wxCMD_LINE_OPTION, "ch", NULL, _("edit HBA configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE},
296 {wxCMD_LINE_OPTION, "cp", NULL, _("edit pgpass configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE},
297 {wxCMD_LINE_OPTION, "c", NULL, _("edit configuration files in cluster directory"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE},
298 {wxCMD_LINE_SWITCH, "t", NULL, _("dialog translation test mode"), wxCMD_LINE_VAL_NONE},
299 #else
300 {wxCMD_LINE_SWITCH, wxT("v"), wxT("version"), _("show the version, and quit"), wxCMD_LINE_VAL_NONE},
301 {wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), _("show the help message, and quit"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
302 {wxCMD_LINE_OPTION, wxT("s"), wxT("server"), _("auto-connect to specified server"), wxCMD_LINE_VAL_STRING},
303 {wxCMD_LINE_SWITCH, wxT("S"), wxT("serverstatus"), _("open server status window"), wxCMD_LINE_VAL_NONE},
304 {wxCMD_LINE_OPTION, wxT("Sc"), wxT("serverstatusconnect"), _("connect server status window to database"), wxCMD_LINE_VAL_STRING},
305 {wxCMD_LINE_SWITCH, wxT("q"), wxT("query"), _("open query tool"), wxCMD_LINE_VAL_NONE},
306 {wxCMD_LINE_OPTION, wxT("qc"), wxT("queryconnect"), _("connect query tool to database"), wxCMD_LINE_VAL_STRING},
307 #ifdef DATABASEDESIGNER
308 {wxCMD_LINE_SWITCH, wxT("d"), wxT("designer"), _("open designer window"), wxCMD_LINE_VAL_NONE},
309 {wxCMD_LINE_OPTION, wxT("dc"), wxT("designerconnectconnect"), _("connect designer window to database"), wxCMD_LINE_VAL_STRING},
310 #endif
311 {wxCMD_LINE_OPTION, wxT("f"), wxT("file"), _("file to load into the query tool in -q or -qc mode"), wxCMD_LINE_VAL_STRING},
312 {wxCMD_LINE_OPTION, wxT("cm"), NULL, _("edit main configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE},
313 {wxCMD_LINE_OPTION, wxT("ch"), NULL, _("edit HBA configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE},
314 {wxCMD_LINE_OPTION, wxT("cp"), NULL, _("edit pgpass configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE},
315 {wxCMD_LINE_OPTION, wxT("c"), NULL, _("edit configuration files in cluster directory"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE},
316 {wxCMD_LINE_SWITCH, wxT("t"), NULL, _("dialog translation test mode"), wxCMD_LINE_VAL_NONE},
317 #endif
318 {wxCMD_LINE_NONE}
319
320 };
321
322 frmConfig::tryMode configMode = frmConfig::NONE;
323 wxString configFile;
324
325 wxCmdLineParser cmdParser(cmdLineDesc, argc, argv);
326 if (cmdParser.Parse() != 0)
327 return false;
328
329 if (
330 (cmdParser.Found(wxT("q")) && cmdParser.Found(wxT("qc")))
331 || (cmdParser.Found(wxT("S")) && cmdParser.Found(wxT("Sc")))
332 #ifdef DATABASEDESIGNER
333 || (cmdParser.Found(wxT("d")) && cmdParser.Found(wxT("dc")))
334 #endif
335 )
336 {
337 cmdParser.Usage();
338 return false;
339 }
340
341 if (cmdParser.Found(wxT("cm"), &configFile))
342 configMode = frmConfig::MAINFILE;
343 else if (cmdParser.Found(wxT("ch"), &configFile))
344 configMode = frmConfig::HBAFILE;
345 else if (cmdParser.Found(wxT("cp"), &configFile))
346 configMode = frmConfig::PGPASSFILE;
347 else if (cmdParser.Found(wxT("c"), &configFile))
348 configMode = frmConfig::ANYFILE;
349
350 if (cmdParser.Found(wxT("t")))
351 dialogTestMode = true;
352
353 // Setup the image handlers and appearance factory before we do any GUI or config stuff
354 ::wxInitAllImageHandlers();
355
356 appearanceFactory = new pgAppearanceFactory();
357
358 if (cmdParser.Found(wxT("v")))
359 {
360 wxPrintf(wxT("%s %s\n"), appearanceFactory->GetLongAppName().c_str(), VERSION_STR);
361 return false;
362 }
363
364 // Setup logging
365 InitLogger();
366
367 wxString msg;
368 msg << wxT("# ") << appearanceFactory->GetLongAppName() << wxT(" Version ") << VERSION_STR << wxT(" Startup");
369 wxLogInfo(wxT("##############################################################"));
370 wxLogInfo(wxT("%s"), msg.c_str());
371 wxLogInfo(wxT("##############################################################"));
372
373 #ifdef PG_SSL
374 wxLogInfo(wxT("Compiled with dynamically linked SSL support"));
375 #endif
376
377 #ifdef __WXDEBUG__
378 wxLogInfo(wxT("Running a DEBUG build."));
379 #else
380 wxLogInfo(wxT("Running a RELEASE build."));
381 #endif
382
383 // Log the path info
384 wxLogInfo(wxT("i18n path : %s"), i18nPath.c_str());
385 wxLogInfo(wxT("UI path : %s"), uiPath.c_str());
386 wxLogInfo(wxT("Doc path : %s"), docPath.c_str());
387 wxLogInfo(wxT("Branding path : %s"), brandingPath.c_str());
388 wxLogInfo(wxT("Plugins path : %s"), pluginsDir.c_str());
389 wxLogInfo(wxT("Settings INI : %s"), settingsIni.c_str());
390
391 wxLogInfo(wxT("PG pg_dump : %s"), pgBackupExecutable.c_str());
392 wxLogInfo(wxT("PG pg_dumpall : %s"), pgBackupAllExecutable.c_str());
393 wxLogInfo(wxT("PG pg_restore : %s"), pgRestoreExecutable.c_str());
394
395 wxLogInfo(wxT("EDB pg_dump : %s"), edbBackupExecutable.c_str());
396 wxLogInfo(wxT("EDB pg_dumpall: %s"), edbBackupAllExecutable.c_str());
397 wxLogInfo(wxT("EDB pg_restore: %s"), edbRestoreExecutable.c_str());
398
399 wxLogInfo(wxT("Greenplum pg_dump : %s"), gpBackupExecutable.c_str());
400 wxLogInfo(wxT("Greenplum pg_dumpall: %s"), gpBackupAllExecutable.c_str());
401 wxLogInfo(wxT("Greenplum pg_restore: %s"), gpRestoreExecutable.c_str());
402
403 #ifdef __WXGTK__
404 static pgRendererNative *renderer = new pgRendererNative();
405 wxRendererNative::Get();
406 wxRendererNative::Set(renderer);
407 #endif
408
409 #ifdef __LINUX__
410 signal(SIGPIPE, SIG_IGN);
411 #endif
412
413 // Show the splash screen
414 // NOTE: We must *always* do this as in -q and -qc modes
415 // the splash screen becomes the top level window and
416 // allows the logon dialogs to be displayed!!
417 frmSplash *winSplash = new frmSplash((wxFrame *)NULL);
418 if (!winSplash)
419 wxLogError(__("Couldn't create the splash screen!"));
420 else
421 {
422 SetTopWindow(winSplash);
423 winSplash->Show();
424 winSplash->Update();
425 wxTheApp->Yield(true);
426 }
427
428 // Startup the windows sockets if required
429 InitNetwork();
430
431 wxFileSystem::AddHandler(new wxZipFSHandler);
432
433 // Setup the XML resources
434 wxXmlResource::Get()->InitAllHandlers();
435 wxXmlResource::Get()->AddHandler(new wxCalendarBoxXmlHandler);
436 wxXmlResource::Get()->AddHandler(new wxTimeSpinXmlHandler);
437 wxXmlResource::Get()->AddHandler(new ctlSQLBoxXmlHandler);
438 wxXmlResource::Get()->AddHandler(new ctlComboBoxXmlHandler);
439 wxXmlResource::Get()->AddHandler(new ctlTreeXmlHandler);
440 wxXmlResource::Get()->AddHandler(new ctlCheckTreeViewXmlHandler);
441 wxXmlResource::Get()->AddHandler(new ctlColourPickerXmlHandler);
442
443 InitXml();
444
445 wxOGLInitialize();
446
447 // Set some defaults
448 SetAppName(appearanceFactory->GetLongAppName());
449
450 // Setup the help paths
451 InitHelp();
452 wxLogInfo(wxT("PG Help : %s"), settings->GetPgHelpPath().c_str());
453 wxLogInfo(wxT("EDB Help : %s"), settings->GetEdbHelpPath().c_str());
454 wxLogInfo(wxT("Greenplum Help: %s"), settings->GetGpHelpPath().c_str());
455 wxLogInfo(wxT("Slony Help : %s"), settings->GetSlonyHelpPath().c_str());
456
457 #ifndef __WXDEBUG__
458 wxTheApp->Yield(true);
459 wxSleep(2);
460 #endif
461
462 #ifdef __WXMSW__
463 // Attempt to dynamically load PGgetOutResult from libpq. this
464 // is only present in EDB versions.
465 InitLibpq();
466 #endif
467
468 if (configMode)
469 {
470 if (configMode == frmConfig::ANYFILE && wxDir::Exists(configFile))
471 {
472 wxLogInfo(wxT("Starting in ANYFILE config editor mode, in directory: %s"), configFile.c_str());
473 frmConfig::Create(appearanceFactory->GetLongAppName(), configFile + wxT("/pg_hba.conf"), frmConfig::HBAFILE);
474 frmConfig::Create(appearanceFactory->GetLongAppName(), configFile + wxT("/postgresql.conf"), frmConfig::MAINFILE);
475 }
476 else
477 {
478 wxLogInfo(wxT("Starting in config editor mode, file: %s"), configFile.c_str());
479 frmConfig::Create(appearanceFactory->GetLongAppName(), configFile, configMode);
480 }
481 if (winSplash)
482 {
483 winSplash->Close();
484 delete winSplash;
485 winSplash = 0;
486 }
487 }
488
489 else
490 {
491 if (dialogTestMode)
492 {
493 wxLogInfo(wxT("Starting in dialog test mode."));
494 wxFrame *dtf = new frmDlgTest();
495 dtf->Show();
496 SetTopWindow(dtf);
497 }
498
499 else if ((cmdParser.Found(wxT("S")) || cmdParser.Found(wxT("Sc"))) && !cmdParser.Found(wxT("s")))
500 {
501 // -S specified, but not -s. Open the server status window but do *not* open the main window
502 pgConn *conn = NULL;
503 wxString connstr;
504 wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Server Status");
505
506 if (cmdParser.Found(wxT("S")))
507 {
508 wxLogInfo(wxT("Starting in server status mode (-S)."), configFile.c_str());
509
510 winSplash->Show(false);
511 dlgSelectConnection dlg(NULL, NULL);
512 dlg.CenterOnParent();
513
514 int rc = dlg.Go(conn, NULL);
515 if (rc != wxID_OK)
516 return false;
517 bool dummyRes;
518 conn = dlg.CreateConn(applicationname, dummyRes);
519 }
520 else if (cmdParser.Found(wxT("Sc"), &connstr))
521 {
522 wxLogInfo(wxT("Starting in server status connect mode (-Sc)."), configFile.c_str());
523 wxString host, database, username, rolename, tmps;
524 int sslmode = 0, port = 0;
525 wxStringTokenizer tkn(connstr, wxT(" "), wxTOKEN_STRTOK);
526 while (tkn.HasMoreTokens())
527 {
528 wxString str = tkn.GetNextToken();
529 if (str.StartsWith(wxT("hostaddr="), &host))
530 continue;
531 if (str.StartsWith(wxT("host="), &host))
532 continue;
533 if (str.StartsWith(wxT("dbname="), &database))
534 continue;
535 if (str.StartsWith(wxT("user="), &username))
536 continue;
537 if (str.StartsWith(wxT("role="), &rolename))
538 continue;
539 if (str.StartsWith(wxT("port="), &tmps))
540 {
541 port = StrToLong(tmps);
542 continue;
543 }
544 if (str.StartsWith(wxT("sslmode="), &tmps))
545 {
546 if (!tmps.Cmp(wxT("require")))
547 sslmode = 1;
548 else if (!tmps.Cmp(wxT("prefer")))
549 sslmode = 2;
550 else if (!tmps.Cmp(wxT("allow")))
551 sslmode = 3;
552 else if (!tmps.Cmp(wxT("disable")))
553 sslmode = 4;
554 else if (!tmps.Cmp(wxT("verify-ca")))
555 sslmode = 5;
556 else if (!tmps.Cmp(wxT("verify-full")))
557 sslmode = 6;
558 else
559 {
560 wxMessageBox(_("Unknown SSL mode: ") + tmps);
561 return false;
562 }
563 continue;
564 }
565 wxMessageBox(_("Unknown token in connection string: ") + str);
566 return false;
567 }
568 winSplash->Show(false);
569 dlgSelectConnection dlg(NULL, NULL);
570 dlg.CenterOnParent();
571 conn = dlg.CreateConn(host, database, username, port, rolename, sslmode, applicationname);
572 }
573 else
574 {
575 /* Can't happen.. */
576 return false;
577 }
578 if (!conn)
579 return false;
580
581 wxString txt = _("Server Status - ") + conn->GetName();
582 frmStatus *fq = new frmStatus(NULL, txt, conn);
583 fq->Go();
584 }
585
586 #ifdef DATABASEDESIGNER
587 else if ((cmdParser.Found(wxT("d")) || cmdParser.Found(wxT("dc"))) && !cmdParser.Found(wxT("s")))
588 {
589 // -d specified, but not -s. Open the designer window but do *not* open the main window
590 pgConn *conn = NULL;
591 wxString connstr;
592 wxString applicationname = _("pgAdmin - Database designer");
593
594 if (cmdParser.Found(wxT("d")))
595 {
596 wxLogInfo(wxT("Starting in designer mode (-d)."), configFile.c_str());
597
598 winSplash->Show(false);
599 dlgSelectConnection dlg(NULL, NULL);
600 dlg.CenterOnParent();
601
602 int rc = dlg.Go(conn, NULL);
603 if (rc != wxID_OK)
604 return false;
605 bool dummyRes;
606 conn = dlg.CreateConn(applicationname, dummyRes);
607 }
608 else if (cmdParser.Found(wxT("dc"), &connstr))
609 {
610 wxLogInfo(wxT("Starting in database designer connect mode (-dc)."), configFile.c_str());
611 wxString host, database, username, rolename, tmps;
612 int sslmode = 0, port = 0;
613 wxStringTokenizer tkn(connstr, wxT(" "), wxTOKEN_STRTOK);
614 while (tkn.HasMoreTokens())
615 {
616 wxString str = tkn.GetNextToken();
617 if (str.StartsWith(wxT("hostaddr="), &host))
618 continue;
619 if (str.StartsWith(wxT("host="), &host))
620 continue;
621 if (str.StartsWith(wxT("dbname="), &database))
622 continue;
623 if (str.StartsWith(wxT("user="), &username))
624 continue;
625 if (str.StartsWith(wxT("role="), &rolename))
626 continue;
627 if (str.StartsWith(wxT("port="), &tmps))
628 {
629 port = StrToLong(tmps);
630 continue;
631 }
632 if (str.StartsWith(wxT("sslmode="), &tmps))
633 {
634 if (!tmps.Cmp(wxT("require")))
635 sslmode = 1;
636 else if (!tmps.Cmp(wxT("prefer")))
637 sslmode = 2;
638 else if (!tmps.Cmp(wxT("allow")))
639 sslmode = 3;
640 else if (!tmps.Cmp(wxT("disable")))
641 sslmode = 4;
642 else if (!tmps.Cmp(wxT("verify-ca")))
643 sslmode = 5;
644 else if (!tmps.Cmp(wxT("verify-full")))
645 sslmode = 6;
646 else
647 {
648 wxMessageBox(_("Unknown SSL mode: ") + tmps);
649 return false;
650 }
651 continue;
652 }
653 wxMessageBox(_("Unknown token in connection string: ") + str);
654 return false;
655 }
656 winSplash->Show(false);
657 dlgSelectConnection dlg(NULL, NULL);
658 dlg.CenterOnParent();
659 conn = dlg.CreateConn(host, database, username, port, rolename, sslmode, applicationname);
660 }
661 else
662 {
663 /* Can't happen.. */
664 return false;
665 }
666 if (!conn)
667 return false;
668
669 frmDatabaseDesigner *fq = new frmDatabaseDesigner(NULL, wxEmptyString, conn);
670 fq->Go();
671 }
672 #endif
673
674 #ifdef __WXMAC__
675 else if (((cmdParser.Found(wxT("q")) || cmdParser.Found(wxT("qc"))) && !cmdParser.Found(wxT("s"))) || !macFileToOpen.IsEmpty())
676 #else
677 else if ((cmdParser.Found(wxT("q")) || cmdParser.Found(wxT("qc"))) && !cmdParser.Found(wxT("s")))
678 #endif
679 {
680 // -q specified, but not -s. Open a query tool but do *not* open the main window
681 pgConn *conn = NULL;
682 wxString connstr;
683 wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Query Tool");
684
685 #ifdef __WXMAC__
686 if (cmdParser.Found(wxT("q")) || !macFileToOpen.IsEmpty())
687 #else
688 if (cmdParser.Found(wxT("q")))
689 #endif
690 {
691 wxLogInfo(wxT("Starting in query tool mode (-q)."), configFile.c_str());
692
693 winSplash->Show(false);
694 dlgSelectConnection dlg(NULL, NULL);
695 dlg.CenterOnParent();
696
697 int rc = dlg.Go(conn, NULL);
698 if (rc != wxID_OK)
699 return false;
700 bool dummyRes;
701 conn = dlg.CreateConn(applicationname, dummyRes);
702 }
703 else if (cmdParser.Found(wxT("qc"), &connstr))
704 {
705 wxLogInfo(wxT("Starting in query tool connect mode (-qc)."), configFile.c_str());
706 wxString host, database, username, rolename, tmps;
707 int sslmode = 0, port = 0;
708 wxStringTokenizer tkn(connstr, wxT(" "), wxTOKEN_STRTOK);
709 while (tkn.HasMoreTokens())
710 {
711 wxString str = tkn.GetNextToken();
712 if (str.StartsWith(wxT("hostaddr="), &host))
713 continue;
714 if (str.StartsWith(wxT("host="), &host))
715 continue;
716 if (str.StartsWith(wxT("dbname="), &database))
717 continue;
718 if (str.StartsWith(wxT("user="), &username))
719 continue;
720 if (str.StartsWith(wxT("role="), &rolename))
721 continue;
722 if (str.StartsWith(wxT("port="), &tmps))
723 {
724 port = StrToLong(tmps);
725 continue;
726 }
727 if (str.StartsWith(wxT("sslmode="), &tmps))
728 {
729 if (!tmps.Cmp(wxT("require")))
730 sslmode = 1;
731 else if (!tmps.Cmp(wxT("prefer")))
732 sslmode = 2;
733 else if (!tmps.Cmp(wxT("allow")))
734 sslmode = 3;
735 else if (!tmps.Cmp(wxT("disable")))
736 sslmode = 4;
737 else if (!tmps.Cmp(wxT("verify-ca")))
738 sslmode = 5;
739 else if (!tmps.Cmp(wxT("verify-full")))
740 sslmode = 6;
741 else
742 {
743 wxMessageBox(_("Unknown SSL mode: ") + tmps);
744 return false;
745 }
746 continue;
747 }
748 wxMessageBox(_("Unknown token in connection string: ") + str);
749 return false;
750 }
751 winSplash->Show(false);
752 dlgSelectConnection dlg(NULL, NULL);
753 dlg.CenterOnParent();
754 conn = dlg.CreateConn(host, database, username, port, rolename, sslmode, applicationname);
755 }
756 else
757 {
758 /* Can't happen.. */
759 return false;
760 }
761 if (!conn)
762 return false;
763
764 wxString fn;
765 #ifdef __WXMAC__
766 if (!macFileToOpen.IsEmpty())
767 {
768 wxLogInfo(wxT("Mac file launch: %s."), macFileToOpen.c_str());
769 fn = macFileToOpen;
770 }
771 else
772 cmdParser.Found(wxT("f"), &fn);
773 #else
774 cmdParser.Found(wxT("f"), &fn);
775 #endif
776 if (!fn.IsEmpty())
777 {
778 wxLogInfo(wxT("Auto-loading file: %s"), fn.c_str());
779 }
780 frmQuery *fq = new frmQuery(NULL, wxEmptyString, conn, wxEmptyString, fn);
781 fq->Go();
782 }
783 else
784 {
785 // Create & show the main form
786 winMain = new frmMain(appearanceFactory->GetLongAppName());
787
788 if (!winMain)
789 wxLogFatalError(__("Couldn't create the main window!"));
790
791 winMain->Show();
792 SetTopWindow(winMain);
793
794 wxString str;
795 if (cmdParser.Found(wxT("s"), &str))
796 {
797 pgServer *srv = winMain->ConnectToServer(str, !cmdParser.Found(wxT("q")));
798 if (srv && cmdParser.Found(wxT("q")))
799 {
800 pgConn *conn;
801 wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Query Tool");
802 conn = srv->CreateConn(wxEmptyString, 0, applicationname);
803 if (conn)
804 {
805 wxString fn;
806 cmdParser.Found(wxT("f"), &fn);
807 if (!fn.IsEmpty())
808 {
809 wxLogInfo(wxT("Auto-loading file: %s"), fn.c_str());
810 }
811 frmQuery *fq = new frmQuery(winMain, wxEmptyString, conn, wxEmptyString, fn);
812 fq->Go();
813 winMain->AddFrame(fq);
814 }
815 }
816 }
817 }
818
819 SetExitOnFrameDelete(true);
820
821 if (winSplash)
822 {
823 winSplash->Close();
824 delete winSplash;
825 winSplash = 0;
826 }
827 }
828
829 return true;
830 }
831
832 // Not the Application!
OnExit()833 int pgAdmin3::OnExit()
834 {
835 if (updateThread)
836 {
837 updateThread->Delete();
838 delete updateThread;
839 }
840
841 // Delete the settings object to ensure settings are saved.
842 delete settings;
843
844 #ifdef __WXMSW__
845 WSACleanup();
846 #endif
847
848 wxTheClipboard->Flush();
849
850 return 1;
851 }
852
853 // On the Mac, this function is called before Init, if the finder launches the app
854 // via a registered filetype. Grab the filename here, and test for it in Init.
855 #ifdef __WXMAC__
MacOpenFile(const wxString & fileName)856 void pgAdmin3::MacOpenFile(const wxString &fileName)
857 {
858 macFileToOpen = fileName;
859 }
860 #endif
861
862 // Setup the paths for the application itself
InitAppPaths()863 void pgAdmin3::InitAppPaths()
864 {
865 i18nPath = LocatePath(I18N_DIR, false);
866 docPath = LocatePath(DOC_DIR, false);
867 uiPath = LocatePath(UI_DIR, false);
868 brandingPath = LocatePath(BRANDING_DIR, false);
869 pluginsDir = LocatePath(PLUGINS_DIR, false);
870 settingsIni = LocatePath(SETTINGS_INI, true);
871 }
872
873 // Setup the paths for the helper apps etc.
InitXtraPaths()874 void pgAdmin3::InitXtraPaths()
875 {
876 //////////////////////////////////
877 // Now setup the app helper paths
878 //////////////////////////////////
879
880 // Windows-only path prefixes
881 #ifdef __WXMSW__
882 wxString programFiles = wxGetenv(wxT("ProgramFiles"));
883 wxString programFilesX86 = wxGetenv(wxT("ProgramFiles(x86)"));
884
885 // If we install a 32-bit pgAdmin in a 64-bit machine,
886 // We will be getting the both values as "Drive:\Program Files(x86)".
887 // Since, all 32-bit applications return "ProgramFiles" as ProgramFiles(x86).
888 // In that case, we need can get the actual programFiles value,
889 // by reading the key "ProgramFilesDir" in location "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion".
890 //
891 if (::wxIsPlatform64Bit() && programFiles == programFilesX86)
892 {
893 // Don't want to lost the exisisting behaviour.
894 //
895 wxString tmp = programFiles;
896 programFiles = wxEmptyString;
897
898 pgRegKey::PGREGWOWMODE wowMode = pgRegKey::PGREG_WOW64;
899 pgRegKey *pgKey = pgRegKey::OpenRegKey(HKEY_LOCAL_MACHINE, wxT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"), pgRegKey::PGREG_READ, wowMode);
900
901 if (!(pgKey && pgKey->QueryValue(wxT("ProgramFilesDir"), programFiles)))
902 {
903 programFiles = tmp;
904 }
905
906 if(pgKey)
907 {
908 delete pgKey;
909 pgKey = NULL;
910 }
911 }
912 #endif
913
914 // First, check and invalidate the paths if they're no good.
915 #ifdef __WXMSW__
916 if (!isPgApp(settings->GetPostgresqlPath() + wxT("\\pg_dump.exe")))
917 settings->SetPostgresqlPath(wxEmptyString);
918
919 if (!isEdbApp(settings->GetEnterprisedbPath() + wxT("\\pg_dump.exe")))
920 settings->SetEnterprisedbPath(wxEmptyString);
921
922 if (!isGpApp(settings->GetGPDBPath() + wxT("\\pg_dump.exe")))
923 settings->SetGPDBPath(wxEmptyString);
924 #else
925 if (!isPgApp(settings->GetPostgresqlPath() + wxT("/pg_dump")))
926 settings->SetPostgresqlPath(wxEmptyString);
927
928 if (!isEdbApp(settings->GetEnterprisedbPath() + wxT("/pg_dump")))
929 settings->SetEnterprisedbPath(wxEmptyString);
930
931 if (!isGpApp(settings->GetGPDBPath() + wxT("/pg_dump")))
932 settings->SetGPDBPath(wxEmptyString);
933 #endif
934
935 // Now, if either path is empty, start a search for helpers
936 // If we find apps, record the appropriate path *only* if it's
937 // not already set
938 if (settings->GetPostgresqlPath().IsEmpty() || settings->GetEnterprisedbPath().IsEmpty())
939 {
940 wxPathList path;
941
942 // Look in the app directory for things first
943 path.Add(loadPath);
944
945 #ifdef __WXMSW__
946
947 // Look for a path 'hint' on Windows. This registry setting may
948 // be set by the Win32 PostgreSQL installer which will generally
949 // install pg_dump et al. in the PostgreSQL bindir rather than
950 // the pgAdmin directory.
951 wxRegKey hintKey(wxT("HKEY_LOCAL_MACHINE\\Software\\pgAdmin III"));
952 if (hintKey.HasValue(wxT("Helper Path")))
953 {
954 wxString hintPath;
955 hintKey.QueryValue(wxT("Helper Path"), hintPath);
956 path.Add(hintPath);
957 }
958
959 #else
960 #ifdef __WXMAC__
961
962 if (wxDir::Exists(dataDir))
963 path.Add(dataDir) ;
964
965 #endif
966 #endif
967
968 path.AddEnvList(wxT("PATH"));
969
970 #ifdef __WXMSW__
971 wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe"));
972 #else
973 wxFileName tmp = path.FindValidPath(wxT("pg_dump"));
974 #endif
975
976 if (tmp.FileExists())
977 {
978 if (isPgApp(tmp.GetFullPath()) && settings->GetPostgresqlPath().IsEmpty())
979 settings->SetPostgresqlPath(tmp.GetPath());
980 else if (isEdbApp(tmp.GetFullPath()) && settings->GetEnterprisedbPath().IsEmpty())
981 settings->SetEnterprisedbPath(tmp.GetPath());
982
983 }
984 }
985
986 if (settings->GetGPDBPath().IsEmpty())
987 {
988 wxPathList path;
989
990 #ifdef __WXMSW__
991
992 wxString GPhint = wxString(getenv( "GPHOME_CLIENTS" ), wxConvUTF8 );
993
994 if (GPhint.Length() > 1)
995 {
996 path.Add(GPhint + wxT("\\bin"));
997 path.Add(GPhint + wxT("\\lib"));
998 path.Add(GPhint);
999 }
1000
1001 GPhint = wxString(getenv( "GPHOME" ), wxConvUTF8 );
1002
1003 if (GPhint.Length() > 1)
1004 {
1005 path.Add(GPhint + wxT("\\bin"));
1006 path.Add(GPhint + wxT("\\lib"));
1007 path.Add(GPhint);
1008 }
1009
1010 #endif
1011 // Look in the app directory for things
1012 path.Add(loadPath);
1013
1014 #ifdef __WXMAC__
1015
1016 if (wxDir::Exists(dataDir))
1017 path.Add(dataDir) ;
1018 #endif
1019 path.AddEnvList(wxT("PATH"));
1020
1021 #ifdef __WXMSW__
1022 wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe"));
1023 #else
1024 wxFileName tmp = path.FindValidPath(wxT("pg_dump"));
1025 #endif
1026
1027 if (tmp.FileExists())
1028 {
1029 if (isGpApp(tmp.GetFullPath()) && settings->GetGPDBPath().IsEmpty())
1030 settings->SetGPDBPath(tmp.GetPath());
1031 }
1032 }
1033
1034 // Now, if either path is still empty, try a less intelligent search for each
1035
1036 // PostgreSQL
1037 if (settings->GetPostgresqlPath().IsEmpty())
1038 {
1039 wxPathList path;
1040
1041 #ifdef __WXMSW__
1042 path.Add(wxT("C:\\PostgresPlus\\8.3\\bin"));
1043
1044 if (!programFiles.IsEmpty())
1045 {
1046 path.Add(programFiles + wxT("\\PostgreSQL\\9.5\\bin"));
1047 path.Add(programFiles + wxT("\\PostgreSQL\\9.4\\bin"));
1048 path.Add(programFiles + wxT("\\PostgreSQL\\9.3\\bin"));
1049 path.Add(programFiles + wxT("\\PostgreSQL\\9.2\\bin"));
1050 path.Add(programFiles + wxT("\\PostgreSQL\\9.1\\bin"));
1051 path.Add(programFiles + wxT("\\PostgreSQL\\9.0\\bin"));
1052 path.Add(programFiles + wxT("\\PostgreSQL\\8.4\\bin"));
1053 path.Add(programFiles + wxT("\\PostgresPlus\\9.0SS\\bin"));
1054 path.Add(programFiles + wxT("\\PostgresPlus\\8.4SS\\bin"));
1055 }
1056
1057 if (!programFilesX86.IsEmpty())
1058 {
1059 path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.5\\bin"));
1060 path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.4\\bin"));
1061 path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.3\\bin"));
1062 path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.2\\bin"));
1063 path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.1\\bin"));
1064 path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.0\\bin"));
1065 path.Add(programFilesX86 + wxT("\\PostgreSQL\\8.4\\bin"));
1066 path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.0SS\\bin"));
1067 path.Add(programFilesX86 + wxT("\\PostgresPlus\\8.4SS\\bin"));
1068 }
1069
1070 wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe"));
1071 #else
1072 // Mac paths
1073 path.Add(wxT("/Library/PostgreSQL/9.5/bin"));
1074 path.Add(wxT("/Library/PostgreSQL/9.4/bin"));
1075 path.Add(wxT("/Library/PostgreSQL/9.3/bin"));
1076 path.Add(wxT("/Library/PostgreSQL/9.2/bin"));
1077 path.Add(wxT("/Library/PostgreSQL/9.1/bin"));
1078 path.Add(wxT("/Library/PostgreSQL/9.0/bin"));
1079 path.Add(wxT("/Library/PostgreSQL/8.4/bin"));
1080 path.Add(wxT("/Library/PostgresPlus/9.0SS/bin"));
1081 path.Add(wxT("/Library/PostgresPlus/8.4SS/bin"));
1082
1083 // Generic Unix paths
1084 path.Add(wxT("/opt/PostgreSQL/9.5/bin"));
1085 path.Add(wxT("/opt/PostgreSQL/9.4/bin"));
1086 path.Add(wxT("/opt/PostgreSQL/9.3/bin"));
1087 path.Add(wxT("/opt/PostgreSQL/9.2/bin"));
1088 path.Add(wxT("/opt/PostgreSQL/9.1/bin"));
1089 path.Add(wxT("/opt/PostgreSQL/9.0/bin"));
1090 path.Add(wxT("/opt/PostgreSQL/8.4/bin"));
1091 path.Add(wxT("/opt/PostgresPlus/9.0SS/bin"));
1092 path.Add(wxT("/opt/PostgresPlus/8.4SS/bin"));
1093 path.Add(wxT("/usr/local/pgsql/bin"));
1094 path.Add(wxT("/usr/local/bin"));
1095 path.Add(wxT("/usr/bin"));
1096 path.Add(wxT("/opt/local/pgsql/bin"));
1097 path.Add(wxT("/opt/local/bin"));
1098 path.Add(wxT("/opt/bin"));
1099
1100 wxFileName tmp = path.FindValidPath(wxT("pg_dump"));
1101 #endif
1102
1103 if (tmp.FileExists())
1104 {
1105 if (isPgApp(tmp.GetFullPath()))
1106 settings->SetPostgresqlPath(tmp.GetPath());
1107 }
1108 }
1109
1110 // EnterpriseDB
1111 if (settings->GetEnterprisedbPath().IsEmpty())
1112 {
1113 wxPathList path;
1114
1115 #ifdef __WXMSW__
1116 if (!programFiles.IsEmpty())
1117 {
1118 path.Add(programFiles + wxT("\\PostgresPlus\\9.5AS\\bin"));
1119 path.Add(programFiles + wxT("\\PostgresPlus\\9.4AS\\bin"));
1120 path.Add(programFiles + wxT("\\PostgresPlus\\9.3AS\\bin"));
1121 path.Add(programFiles + wxT("\\PostgresPlus\\9.2AS\\bin"));
1122 path.Add(programFiles + wxT("\\PostgresPlus\\9.1AS\\bin"));
1123 path.Add(programFiles + wxT("\\PostgresPlus\\9.0AS\\bin"));
1124 path.Add(programFiles + wxT("\\PostgresPlus\\8.4AS\\bin"));
1125 }
1126
1127 if (!programFilesX86.IsEmpty())
1128 {
1129 path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.5AS\\bin"));
1130 path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.4AS\\bin"));
1131 path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.3AS\\bin"));
1132 path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.2AS\\bin"));
1133 path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.1AS\\bin"));
1134 path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.0AS\\bin"));
1135 path.Add(programFilesX86 + wxT("\\PostgresPlus\\8.4AS\\bin"));
1136 }
1137
1138 wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe"));
1139 #else
1140 // Mac paths
1141 path.Add(wxT("/Library/PostgresPlus/9.5AS/bin"));
1142 path.Add(wxT("/Library/PostgresPlus/9.4AS/bin"));
1143 path.Add(wxT("/Library/PostgresPlus/9.3AS/bin"));
1144 path.Add(wxT("/Library/PostgresPlus/9.2AS/bin"));
1145 path.Add(wxT("/Library/PostgresPlus/9.1AS/bin"));
1146 path.Add(wxT("/Library/PostgresPlus/9.0AS/bin"));
1147 path.Add(wxT("/Library/PostgresPlus/8.4AS/bin"));
1148
1149 // Generic Unix paths
1150 path.Add(wxT("/opt/PostgresPlus/9.5AS/bin"));
1151 path.Add(wxT("/opt/PostgresPlus/9.4AS/bin"));
1152 path.Add(wxT("/opt/PostgresPlus/9.3AS/bin"));
1153 path.Add(wxT("/opt/PostgresPlus/9.2AS/bin"));
1154 path.Add(wxT("/opt/PostgresPlus/9.1AS/bin"));
1155 path.Add(wxT("/opt/PostgresPlus/9.0AS/bin"));
1156 path.Add(wxT("/opt/PostgresPlus/8.4AS/bin"));
1157 path.Add(wxT("/usr/local/enterpriseDB/bin"));
1158 path.Add(wxT("/usr/local/enterprisedb/bin"));
1159 path.Add(wxT("/usr/local/edb/bin"));
1160 path.Add(wxT("/usr/local/bin"));
1161 path.Add(wxT("/usr/bin"));
1162 path.Add(wxT("/opt/local/enterpriseDB/bin"));
1163 path.Add(wxT("/opt/local/enterprisedb/bin"));
1164 path.Add(wxT("/opt/local/edb/bin"));
1165 path.Add(wxT("/opt/local/bin"));
1166
1167 wxFileName tmp = path.FindValidPath(wxT("pg_dump"));
1168 #endif
1169
1170 if (tmp.FileExists())
1171 {
1172 if (isEdbApp(tmp.GetFullPath()))
1173 settings->SetEnterprisedbPath(tmp.GetPath());
1174 }
1175 }
1176
1177 // Greenplum
1178 if (settings->GetGPDBPath().IsEmpty())
1179 {
1180 wxPathList path;
1181
1182 #ifdef __WXMSW__
1183 // Ugly... Greenplum client releases have no predictable numbers, because the path is the server version
1184 if (!programFiles.IsEmpty())
1185 {
1186 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-5.0\\bin"));
1187 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.4\\bin"));
1188 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.3\\bin"));
1189 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.2\\bin"));
1190 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.1\\bin"));
1191 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.0\\bin"));
1192 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.3\\bin"));
1193 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.2\\bin"));
1194
1195 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-5.0\\lib"));
1196 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.4\\lib"));
1197 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.3\\lib"));
1198 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.2\\lib"));
1199 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.1\\lib"));
1200 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.0\\lib"));
1201 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.3\\lib"));
1202 path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.2\\lib"));
1203 }
1204
1205 if (!programFilesX86.IsEmpty())
1206 {
1207 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-5.0\\bin"));
1208 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.4\\bin"));
1209 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.3\\bin"));
1210 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.2\\bin"));
1211 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.1\\bin"));
1212 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.0\\bin"));
1213 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.3\\bin"));
1214 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.2\\bin"));
1215
1216 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-5.0\\lib"));
1217 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.4\\lib"));
1218 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.3\\lib"));
1219 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.2\\lib"));
1220 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.1\\lib"));
1221 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.0\\lib"));
1222 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.3\\lib"));
1223 path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.2\\lib"));
1224 }
1225
1226
1227 wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe"));
1228 #else
1229 // Mac paths
1230
1231 // Generic Unix paths
1232
1233 path.Add(wxT("/usr/local/greenplum-clients-5.0/bin"));
1234 path.Add(wxT("/opt/local/greenplum-clients-5.0/bin"));
1235 path.Add(wxT("/usr/local/greenplum-clients-4.4/bin"));
1236 path.Add(wxT("/opt/local/greenplum-clients-4.4/bin"));
1237 path.Add(wxT("/usr/local/greenplum-clients-4.3/bin"));
1238 path.Add(wxT("/opt/local/greenplum-clients-4.3/bin"));
1239 path.Add(wxT("/usr/local/greenplum-clients-4.2/bin"));
1240 path.Add(wxT("/opt/local/greenplum-clients-4.2/bin"));
1241 path.Add(wxT("/usr/local/greenplum-clients-4.1/bin"));
1242 path.Add(wxT("/opt/local/greenplum-clients-4.1/bin"));
1243 path.Add(wxT("/usr/local/greenplum-clients-4.0/bin"));
1244 path.Add(wxT("/opt/local/greenplum-clients-4.0/bin"));
1245 path.Add(wxT("/usr/local/greenplum-clients-3.3/bin"));
1246 path.Add(wxT("/opt/local/greenplum-clients-3.3/bin"));
1247 path.Add(wxT("/usr/local/greenplum-clients-3.2/bin"));
1248 path.Add(wxT("/opt/local/greenplum-clients-3.2/bin"));
1249
1250 path.Add(wxT("/usr/local/greenplum-clients-5.0/lib"));
1251 path.Add(wxT("/opt/local/greenplum-clients-5.0/lib"));
1252 path.Add(wxT("/usr/local/greenplum-clients-4.4/lib"));
1253 path.Add(wxT("/opt/local/greenplum-clients-4.4/lib"));
1254 path.Add(wxT("/usr/local/greenplum-clients-4.3/lib"));
1255 path.Add(wxT("/opt/local/greenplum-clients-4.3/lib"));
1256 path.Add(wxT("/usr/local/greenplum-clients-4.2/lib"));
1257 path.Add(wxT("/opt/local/greenplum-clients-4.2/lib"));
1258 path.Add(wxT("/usr/local/greenplum-clients-4.1/lib"));
1259 path.Add(wxT("/opt/local/greenplum-clients-4.1/lib"));
1260 path.Add(wxT("/usr/local/greenplum-clients-4.0/lib"));
1261 path.Add(wxT("/opt/local/greenplum-clients-4.0/lib"));
1262 path.Add(wxT("/usr/local/greenplum-clients-3.3/lib"));
1263 path.Add(wxT("/opt/local/greenplum-clients-3.3/lib"));
1264 path.Add(wxT("/usr/local/greenplum-clients-3.2/lib"));
1265 path.Add(wxT("/opt/local/greenplum-clients-3.2/lib"));
1266
1267
1268 wxFileName tmp = path.FindValidPath(wxT("pg_dump"));
1269 #endif
1270
1271 if (tmp.FileExists())
1272 {
1273 if (isGpApp(tmp.GetFullPath()))
1274 settings->SetGPDBPath(tmp.GetPath());
1275 }
1276 }
1277
1278 // Now setup and verify the paths for each individual helper
1279 #if defined(__WXMSW__)
1280 pgBackupExecutable = settings->GetPostgresqlPath() + wxT("\\pg_dump.exe");
1281 pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("\\pg_dumpall.exe");
1282 pgRestoreExecutable = settings->GetPostgresqlPath() + wxT("\\pg_restore.exe");
1283
1284 edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dump.exe");
1285 edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dumpall.exe");
1286 edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_restore.exe");
1287
1288 gpBackupExecutable = settings->GetGPDBPath() + wxT("\\pg_dump.exe");
1289 gpBackupAllExecutable = settings->GetGPDBPath() + wxT("\\pg_dumpall.exe");
1290 gpRestoreExecutable = settings->GetGPDBPath() + wxT("\\pg_restore.exe");
1291 #else
1292 pgBackupExecutable = settings->GetPostgresqlPath() + wxT("/pg_dump");
1293 pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("/pg_dumpall");
1294 pgRestoreExecutable = settings->GetPostgresqlPath() + wxT("/pg_restore");
1295
1296 edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dump");
1297 edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dumpall");
1298 edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("/pg_restore");
1299
1300 gpBackupExecutable = settings->GetGPDBPath() + wxT("/pg_dump");
1301 gpBackupAllExecutable = settings->GetGPDBPath() + wxT("/pg_dumpall");
1302 gpRestoreExecutable = settings->GetGPDBPath() + wxT("/pg_restore");
1303 #endif
1304
1305 if (!isPgApp(pgBackupExecutable))
1306 pgBackupExecutable = wxEmptyString;
1307 if (!isPgApp(pgBackupAllExecutable))
1308 pgBackupAllExecutable = wxEmptyString;
1309 if (!isPgApp(pgRestoreExecutable))
1310 pgRestoreExecutable = wxEmptyString;
1311
1312 if (!isEdbApp(edbBackupExecutable))
1313 edbBackupExecutable = wxEmptyString;
1314 if (!isEdbApp(edbBackupAllExecutable))
1315 edbBackupAllExecutable = wxEmptyString;
1316 if (!isEdbApp(edbRestoreExecutable))
1317 edbRestoreExecutable = wxEmptyString;
1318
1319 if (!isGpApp(gpBackupExecutable))
1320 gpBackupExecutable = wxEmptyString;
1321 if (!isGpApp(gpBackupAllExecutable))
1322 gpBackupAllExecutable = wxEmptyString;
1323 if (!isGpApp(gpRestoreExecutable))
1324 gpRestoreExecutable = wxEmptyString;
1325 }
1326
LocatePath(const wxString & pathToFind,const bool isFile)1327 wxString pgAdmin3::LocatePath(const wxString &pathToFind, const bool isFile)
1328 {
1329 loadPath = wxPathOnly(argv[0]);
1330
1331 if (loadPath.IsEmpty())
1332 loadPath = wxT(".");
1333
1334 loadPath = sanitizePath(loadPath);
1335
1336 #if defined(__WXMSW__)
1337
1338 // Search for the right paths. We check the following locations:
1339 //
1340 // 1) ./xxx - Running as a standalone install
1341 // 2) ../pgAdmin/xxx - Running in a pgInstaller 8.1 installation
1342 // (with the .exe and dlls in the main bin dir)
1343 // 3) ../xxx or ../../xxx - Running in a development environment
1344
1345 if (!isFile)
1346 {
1347 if (wxDir::Exists(loadPath + pathToFind))
1348 return sanitizePath(loadPath + pathToFind);
1349 else if (wxDir::Exists(loadPath + wxT("/../pgAdmin III") + pathToFind))
1350 return sanitizePath(loadPath + wxT("/../pgAdmin III") + pathToFind);
1351 else if (wxDir::Exists(loadPath + wxT("/..") + pathToFind))
1352 return sanitizePath(loadPath + wxT("/..") + pathToFind);
1353 else if (wxDir::Exists(loadPath + wxT("/../..") + pathToFind))
1354 return sanitizePath(loadPath + wxT("/../..") + pathToFind);
1355 else
1356 return wxEmptyString;
1357 }
1358 else
1359 {
1360 if (wxFile::Exists(loadPath + pathToFind))
1361 return sanitizePath(loadPath + pathToFind);
1362 else if (wxFile::Exists(loadPath + wxT("/../pgAdmin III") + pathToFind))
1363 return sanitizePath(loadPath + wxT("/../pgAdmin III") + pathToFind);
1364 else if (wxFile::Exists(loadPath + wxT("/..") + pathToFind))
1365 return sanitizePath(loadPath + wxT("/..") + pathToFind);
1366 else if (wxFile::Exists(loadPath + wxT("/../..") + pathToFind))
1367 return sanitizePath(loadPath + wxT("/../..") + pathToFind);
1368 else
1369 return wxEmptyString;
1370 }
1371
1372 #else
1373
1374 #ifdef __WXMAC__
1375 #if wxCHECK_VERSION(2, 9, 5)
1376 wxStandardPaths &stdPaths = wxStandardPaths::Get();
1377 #else
1378 // When using wxStandardPaths on OSX, wx default to the unix,
1379 // not to the mac variants. Therefore, we request wxStandardPathsCF
1380 // directly.
1381 wxStandardPathsCF stdPaths;
1382 #endif
1383 dataDir = stdPaths.GetDataDir();
1384
1385 #else // other *ixes
1386
1387 // Data path (defined by configure under Unix).
1388 #ifndef DATA_DIR
1389 #define DATA_DIR "./"
1390 #endif
1391
1392 dataDir = wxString::FromAscii(DATA_DIR);
1393 #endif
1394
1395 // On unix systems, the search path is as follows:
1396 //
1397 // 1) DATADIR/xxx - DATADIR being defined by configure
1398 // 2) ./../share/pgadmin3/xxx - The default 'make install' layout, but allowing for relocation
1399 // 3) ./xxx - Windows-style standalone install
1400 // 4) ./../xxx - Unix-style standalone install (with binaries in a bin directory)
1401
1402 if (!isFile)
1403 {
1404 if (wxDir::Exists(dataDir + pathToFind))
1405 return sanitizePath(dataDir + pathToFind);
1406 else if (wxDir::Exists(loadPath + wxT("/../share/pgadmin3") + pathToFind))
1407 return sanitizePath(loadPath + wxT("/../share/pgadmin3") + pathToFind);
1408 else if (wxDir::Exists(loadPath + pathToFind))
1409 return sanitizePath(loadPath + pathToFind);
1410 else if (wxDir::Exists(loadPath + wxT("/..") + pathToFind))
1411 return sanitizePath(loadPath + wxT("/..") + pathToFind);
1412 else
1413 return wxEmptyString;
1414 }
1415 else
1416 {
1417 if (wxFile::Exists(dataDir + pathToFind))
1418 return sanitizePath(dataDir + pathToFind);
1419 else if (wxFile::Exists(loadPath + wxT("/../share/pgadmin3") + pathToFind))
1420 return sanitizePath(loadPath + wxT("/../share/pgadmin3") + pathToFind);
1421 else if (wxFile::Exists(loadPath + pathToFind))
1422 return sanitizePath(loadPath + pathToFind);
1423 else if (wxFile::Exists(loadPath + wxT("/..") + pathToFind))
1424 return sanitizePath(loadPath + wxT("/..") + pathToFind);
1425 else
1426 return wxEmptyString;
1427 }
1428
1429 #endif
1430 }
1431
InitHelp()1432 void pgAdmin3::InitHelp()
1433 {
1434 // Windows-only path prefixes
1435 #ifdef __WXMSW__
1436 wxString programFiles = wxGetenv(wxT("ProgramFiles"));
1437 wxString programFilesX86 = wxGetenv(wxT("ProgramFiles(x86)"));
1438 #endif
1439
1440 // Search for external docs. As Windows and *nix etc
1441 // are likely to be very different, we'll #ifdef them all.
1442 wxPathList stdPaths, noPaths, pgPaths, edbPaths, gpPaths, slonyPaths;
1443 wxString sep = wxFileName::GetPathSeparator();
1444
1445 stdPaths.Add(docPath + sep + settings->GetCanonicalLanguageName());
1446 stdPaths.Add(docPath + sep + wxT("en_US"));
1447 stdPaths.Add(docPath);
1448
1449 #ifdef __WXMSW__
1450 if (!programFiles.IsEmpty())
1451 {
1452 pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.4\\doc"));
1453 pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.4\\doc\\html"));
1454 pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.3\\doc"));
1455 pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.3\\doc\\html"));
1456 pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.2\\doc"));
1457 pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.2\\doc\\html"));
1458 pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.1\\doc"));
1459 pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.1\\doc\\html"));
1460 pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.0\\doc"));
1461 pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.0\\doc\\html"));
1462 }
1463
1464 if (!programFilesX86.IsEmpty())
1465 {
1466 pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.4\\doc"));
1467 pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.4\\doc\\html"));
1468 pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.3\\doc"));
1469 pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.3\\doc\\html"));
1470 pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.2\\doc"));
1471 pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.2\\doc\\html"));
1472 pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.1\\doc"));
1473 pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.1\\doc\\html"));
1474 pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.0\\doc"));
1475 pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.0\\doc\\html"));
1476 }
1477
1478 // Note that EDB docs are online from 8.3.
1479 edbPaths.Add(wxT("C:\\EnterpriseDB\\8.2\\dbserver\\doc"));
1480 edbPaths.Add(wxT("C:\\EnterpriseDB\\8.2\\dbserver\\doc\\html"));
1481 edbPaths.Add(wxT("C:\\EnterpriseDB\\8.1\\dbserver\\doc"));
1482 edbPaths.Add(wxT("C:\\EnterpriseDB\\8.1\\dbserver\\doc\\html"));
1483 edbPaths.Add(wxT("C:\\EnterpriseDB\\8.0\\dbserver\\doc"));
1484 edbPaths.Add(wxT("C:\\EnterpriseDB\\8.0\\dbserver\\doc\\html"));
1485
1486 wxString GPhint = wxString(getenv( "GPHOME_CLIENTS" ), wxConvUTF8 );
1487
1488 if (GPhint.Length() > 1)
1489 {
1490 gpPaths.Add(GPhint + wxT("\\docs"));
1491 gpPaths.Add(GPhint);
1492 }
1493
1494 GPhint = wxString(getenv( "GPHOME" ), wxConvUTF8 );
1495
1496 if (GPhint.Length() > 1)
1497 {
1498 gpPaths.Add(GPhint + wxT("\\docs"));
1499 gpPaths.Add(GPhint);
1500 }
1501
1502 if (!programFiles.IsEmpty())
1503 {
1504 gpPaths.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.3\\docs"));
1505 gpPaths.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.2\\docs"));
1506 gpPaths.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.1.1.1\\docs"));
1507 }
1508
1509 if (!programFilesX86.IsEmpty())
1510 {
1511 gpPaths.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.3\\docs"));
1512 gpPaths.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.2\\docs"));
1513 gpPaths.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.1.1.1\\docs"));
1514 }
1515 ;
1516
1517
1518 #else
1519 pgPaths.Add(wxT("/usr/local/pgsql/doc"));
1520 pgPaths.Add(wxT("/usr/local/pgsql/doc/html"));
1521 pgPaths.Add(wxT("/usr/local/doc/postgresql"));
1522 pgPaths.Add(wxT("/usr/local/doc/postgresql/html"));
1523 pgPaths.Add(wxT("/usr/doc/postgresql"));
1524 pgPaths.Add(wxT("/usr/doc/postgresql/html"));
1525 pgPaths.Add(wxT("/opt/local/pgsql/doc"));
1526 pgPaths.Add(wxT("/opt/local/pgsql/doc/html"));
1527 pgPaths.Add(wxT("/opt/local/doc/postgresql"));
1528 pgPaths.Add(wxT("/opt/local/doc/postgresql/html"));
1529 pgPaths.Add(wxT("/opt/doc/postgresql"));
1530 pgPaths.Add(wxT("/opt/doc/postgresql/html"));
1531
1532 edbPaths.Add(wxT("/usr/local/enterpriseDB/doc"));
1533 edbPaths.Add(wxT("/usr/local/enterpriseDB/doc/html"));
1534 edbPaths.Add(wxT("/usr/local/enterprisedb/doc"));
1535 edbPaths.Add(wxT("/usr/local/enterprisedb/doc/html"));
1536 edbPaths.Add(wxT("/usr/local/edb/doc"));
1537 edbPaths.Add(wxT("/usr/local/edb/doc/html"));
1538 edbPaths.Add(wxT("/opt/local/enterpriseDB/doc"));
1539 edbPaths.Add(wxT("/opt/local/enterpriseDB/doc/html"));
1540 edbPaths.Add(wxT("/opt/local/enterprisedb/doc"));
1541 edbPaths.Add(wxT("/opt/local/enterprisedb/doc/html"));
1542 edbPaths.Add(wxT("/opt/local/edb/doc"));
1543 edbPaths.Add(wxT("/opt/local/edb/doc/html"));
1544
1545 wxArrayString gpFoundDirs;
1546 wxString pgDirname1 = wxString(wxT("/usr/local"));
1547 wxDir gpDir1(pgDirname1);
1548 if ( gpDir1.IsOpened() )
1549 {
1550 wxString gpfilename;
1551 bool pgcont = gpDir1.GetFirst(&gpfilename, wxT("greenplum-clients*"), wxDIR_DIRS);
1552 while ( pgcont )
1553 {
1554 gpFoundDirs.Add(wxString(pgDirname1 + wxT("/") + gpfilename));
1555 pgcont = gpDir1.GetNext(&gpfilename);
1556 }
1557 }
1558
1559 wxString pgDirname2 = wxString(wxT("/opt/local"));
1560 wxDir gpDir2(pgDirname2);
1561 if ( gpDir2.IsOpened() )
1562 {
1563 wxString gpfilename;
1564 bool pgcont = gpDir2.GetFirst(&gpfilename, wxT("greenplum-clients*"), wxDIR_DIRS);
1565 while ( pgcont )
1566 {
1567 gpFoundDirs.Add(wxString(pgDirname2 + wxT("/") + gpfilename));
1568 pgcont = gpDir2.GetNext(&gpfilename);
1569 }
1570 }
1571
1572 // make sure that the highest version number comes first
1573 gpFoundDirs.Sort(true);
1574 for (wxArrayString::iterator iter = gpFoundDirs.begin(); iter != gpFoundDirs.end(); ++iter)
1575 {
1576 wxLogMessage(*iter);
1577 pgPaths.Add(wxString(*iter));
1578 pgPaths.Add(wxString(*iter) + wxT("/html"));
1579 pgPaths.Add(wxString(*iter) + wxT("/docs"));
1580 }
1581
1582 #endif
1583
1584 // Slony will be installed into one of the DBMS directories
1585 slonyPaths.Add(pgPaths);
1586 slonyPaths.Add(edbPaths);
1587 slonyPaths.Add(gpPaths);
1588
1589 // First look for a chm, then a zip, then an hhp file. For PostgreSQL
1590 // and EnterpriseDB we'll then look for an index.html. No point for
1591 // Slony as we'd most likely find the DBMS's help.
1592
1593 wxString pgHelpPath = settings->GetPgHelpPath();
1594 wxString edbHelpPath = settings->GetEdbHelpPath();
1595 wxString gpHelpPath = settings->GetGpHelpPath();
1596 wxString slonyHelpPath = settings->GetSlonyHelpPath();
1597
1598 #if defined (__WXMSW__) || wxUSE_LIBMSPACK
1599 pgHelpPath = GenerateHelpPath(wxT("PostgreSQL.chm"), pgHelpPath, stdPaths, pgPaths);
1600 pgHelpPath = GenerateHelpPath(wxT("postgresql.chm"), pgHelpPath, stdPaths, pgPaths);
1601 pgHelpPath = GenerateHelpPath(wxT("postgres.chm"), pgHelpPath, stdPaths, pgPaths);
1602 pgHelpPath = GenerateHelpPath(wxT("pgsql.chm"), pgHelpPath, stdPaths, pgPaths);
1603
1604 edbHelpPath = GenerateHelpPath(wxT("EnterpriseDB.chm"), edbHelpPath, stdPaths, edbPaths);
1605 edbHelpPath = GenerateHelpPath(wxT("enterprisedb.chm"), edbHelpPath, stdPaths, edbPaths);
1606 edbHelpPath = GenerateHelpPath(wxT("edb.chm"), edbHelpPath, stdPaths, edbPaths);
1607
1608 gpHelpPath = GenerateHelpPath(wxT("Greenplum.chm"), gpHelpPath, stdPaths, gpPaths);
1609 gpHelpPath = GenerateHelpPath(wxT("GPDB.chm"), gpHelpPath, stdPaths, gpPaths);
1610 gpHelpPath = GenerateHelpPath(wxT("GPSQL.zip"), gpHelpPath, stdPaths, gpPaths);
1611 gpHelpPath = GenerateHelpPath(wxT("GPClientToolsWin.pdf"), gpHelpPath, stdPaths, gpPaths);
1612 gpHelpPath = GenerateHelpPath(wxT("GPClientTools.pdf"), gpHelpPath, stdPaths, gpPaths);
1613 gpHelpPath = GenerateHelpPath(wxT("GPUserGuide.pdf"), gpHelpPath, stdPaths, gpPaths);
1614
1615 slonyHelpPath = GenerateHelpPath(wxT("Slony-I.chm"), slonyHelpPath, stdPaths, slonyPaths);
1616 slonyHelpPath = GenerateHelpPath(wxT("slony-i.chm"), slonyHelpPath, stdPaths, slonyPaths);
1617 slonyHelpPath = GenerateHelpPath(wxT("slony1.chm"), slonyHelpPath, stdPaths, slonyPaths);
1618 slonyHelpPath = GenerateHelpPath(wxT("slony.chm"), slonyHelpPath, stdPaths, slonyPaths);
1619 #endif
1620
1621 pgHelpPath = GenerateHelpPath(wxT("PostgreSQL.zip"), pgHelpPath, stdPaths, pgPaths);
1622 pgHelpPath = GenerateHelpPath(wxT("postgresql.zip"), pgHelpPath, stdPaths, pgPaths);
1623 pgHelpPath = GenerateHelpPath(wxT("postgres.zip"), pgHelpPath, stdPaths, pgPaths);
1624 pgHelpPath = GenerateHelpPath(wxT("pgsql.zip"), pgHelpPath, stdPaths, pgPaths);
1625
1626 edbHelpPath = GenerateHelpPath(wxT("EnterpriseDB.zip"), edbHelpPath, stdPaths, edbPaths);
1627 edbHelpPath = GenerateHelpPath(wxT("enterprisedb.zip"), edbHelpPath, stdPaths, edbPaths);
1628 edbHelpPath = GenerateHelpPath(wxT("edb.zip"), edbHelpPath, stdPaths, edbPaths);
1629
1630 gpHelpPath = GenerateHelpPath(wxT("Greenplum.zip"), gpHelpPath, stdPaths, gpPaths);
1631 gpHelpPath = GenerateHelpPath(wxT("GPSQL.zip"), gpHelpPath, stdPaths, gpPaths);
1632
1633 slonyHelpPath = GenerateHelpPath(wxT("Slony-I.zip"), slonyHelpPath, stdPaths, slonyPaths);
1634 slonyHelpPath = GenerateHelpPath(wxT("slony-i.zip"), slonyHelpPath, stdPaths, slonyPaths);
1635 slonyHelpPath = GenerateHelpPath(wxT("slony1.zip"), slonyHelpPath, stdPaths, slonyPaths);
1636 slonyHelpPath = GenerateHelpPath(wxT("slony.zip"), slonyHelpPath, stdPaths, slonyPaths);
1637
1638 pgHelpPath = GenerateHelpPath(wxT("PostgreSQL.hhp"), pgHelpPath, stdPaths, pgPaths);
1639 pgHelpPath = GenerateHelpPath(wxT("postgresql.hhp"), pgHelpPath, stdPaths, pgPaths);
1640 pgHelpPath = GenerateHelpPath(wxT("postgres.hhp"), pgHelpPath, stdPaths, pgPaths);
1641 pgHelpPath = GenerateHelpPath(wxT("pgsql.hhp"), pgHelpPath, stdPaths, pgPaths);
1642
1643 edbHelpPath = GenerateHelpPath(wxT("EnterpriseDB.hhp"), edbHelpPath, stdPaths, edbPaths);
1644 edbHelpPath = GenerateHelpPath(wxT("enterprisedb.hhp"), edbHelpPath, stdPaths, edbPaths);
1645 edbHelpPath = GenerateHelpPath(wxT("edb.hhp"), edbHelpPath, stdPaths, edbPaths);
1646
1647 gpHelpPath = GenerateHelpPath(wxT("Greenplum.hhp"), gpHelpPath, stdPaths, gpPaths);
1648
1649 slonyHelpPath = GenerateHelpPath(wxT("Slony-I.hhp"), slonyHelpPath, stdPaths, slonyPaths);
1650 slonyHelpPath = GenerateHelpPath(wxT("slony-i.hhp"), slonyHelpPath, stdPaths, slonyPaths);
1651 slonyHelpPath = GenerateHelpPath(wxT("slony1.hhp"), slonyHelpPath, stdPaths, slonyPaths);
1652 slonyHelpPath = GenerateHelpPath(wxT("slony.hhp"), slonyHelpPath, stdPaths, slonyPaths);
1653
1654 pgHelpPath = GenerateHelpPath(wxT("index.html"), pgHelpPath, noPaths, pgPaths);
1655 pgHelpPath = GenerateHelpPath(wxT("index.html"), pgHelpPath, noPaths, pgPaths);
1656 pgHelpPath = GenerateHelpPath(wxT("index.html"), pgHelpPath, noPaths, pgPaths);
1657 pgHelpPath = GenerateHelpPath(wxT("index.html"), pgHelpPath, noPaths, pgPaths);
1658
1659 edbHelpPath = GenerateHelpPath(wxT("index.html"), edbHelpPath, noPaths, edbPaths);
1660 edbHelpPath = GenerateHelpPath(wxT("index.html"), edbHelpPath, noPaths, edbPaths);
1661 edbHelpPath = GenerateHelpPath(wxT("index.html"), edbHelpPath, noPaths, edbPaths);
1662
1663 gpHelpPath = GenerateHelpPath(wxT("index.html"), gpHelpPath, noPaths, gpPaths);
1664 gpHelpPath = GenerateHelpPath(wxT("GPUserGuide.pdf"), gpHelpPath, stdPaths, gpPaths);
1665
1666 // If either path ends in index.html, remove the filename because we
1667 // just want the path. In this case, we should also add file:/// on
1668 // non-Windows platforms.
1669 if (pgHelpPath.EndsWith(wxT("index.html")))
1670 {
1671 pgHelpPath = pgHelpPath.Left(pgHelpPath.Length() - 10);
1672 #ifndef __WXMSW__
1673 pgHelpPath = wxT("file:///") + pgHelpPath;
1674 #endif
1675 }
1676
1677 if (edbHelpPath.EndsWith(wxT("index.html")))
1678 {
1679 edbHelpPath = edbHelpPath.Left(edbHelpPath.Length() - 10);
1680 #ifndef __WXMSW__
1681 edbHelpPath = wxT("file:///") + edbHelpPath;
1682 #endif
1683 }
1684
1685 if (gpHelpPath.EndsWith(wxT("index.html")))
1686 {
1687 gpHelpPath = gpHelpPath.Left(gpHelpPath.Length() - 10);
1688 #ifndef __WXMSW__
1689 gpHelpPath = wxT("file:///") + gpHelpPath;
1690 #endif
1691 }
1692
1693 // Last resorts - if we still have no help by now, use the websites!
1694 if (pgHelpPath.IsEmpty())
1695 pgHelpPath = wxT("http://www.postgresql.org/docs/current/static/");
1696 if (edbHelpPath.IsEmpty())
1697 edbHelpPath = wxT("http://www.enterprisedb.com/docs/en/current/server/");
1698 if (gpHelpPath.IsEmpty())
1699 gpHelpPath = wxT("http://gpdb.docs.pivotal.io/");
1700 if (slonyHelpPath.IsEmpty())
1701 slonyHelpPath = wxT("http://www.slony.info/documentation/");
1702
1703 // OK, so set the values
1704 if (settings->GetPgHelpPath().IsEmpty())
1705 settings->SetPgHelpPath(pgHelpPath);
1706 if (settings->GetEdbHelpPath().IsEmpty())
1707 settings->SetEdbHelpPath(edbHelpPath);
1708 if (settings->GetGpHelpPath().IsEmpty())
1709 settings->SetGpHelpPath(gpHelpPath);
1710 if (settings->GetSlonyHelpPath().IsEmpty())
1711 settings->SetSlonyHelpPath(slonyHelpPath);
1712 }
1713
GenerateHelpPath(const wxString & file,const wxString & current,wxPathList stdPaths,wxPathList dbmsPaths)1714 wxString pgAdmin3::GenerateHelpPath(const wxString &file, const wxString ¤t, wxPathList stdPaths, wxPathList dbmsPaths)
1715 {
1716 // If we already have a value, don't change it.
1717 if (!current.IsEmpty())
1718 return current;
1719
1720 if (!stdPaths.FindValidPath(file).IsEmpty())
1721 return stdPaths.FindValidPath(file);
1722
1723 if (!dbmsPaths.FindValidPath(file).IsEmpty())
1724 return dbmsPaths.FindValidPath(file);
1725
1726 return wxEmptyString;
1727 }
1728
InitXml()1729 void pgAdmin3::InitXml()
1730 {
1731 #define chkXRC(id) XRCID(#id) == id
1732 wxASSERT_MSG(
1733 chkXRC(wxID_OK) &&
1734 chkXRC(wxID_CANCEL) &&
1735 chkXRC(wxID_HELP) &&
1736 chkXRC(wxID_APPLY) &&
1737 chkXRC(wxID_ADD) &&
1738 chkXRC(wxID_STOP) &&
1739 chkXRC(wxID_REMOVE) &&
1740 chkXRC(wxID_REFRESH) &&
1741 chkXRC(wxID_CLOSE),
1742 wxT("XRC ID not correctly assigned."));
1743 // if this assert fires, some event table uses XRCID(...) instead of wxID_... directly
1744
1745 #ifdef EMBED_XRC
1746 wxLogInfo(__("Using embedded XRC data."));
1747
1748 // resources are loaded from memory
1749 extern void InitXmlResource();
1750 InitXmlResource();
1751
1752 #else
1753 wxLogInfo(__("Using external XRC files."));
1754
1755 // for debugging, dialog resources are read from file
1756 wxXmlResource::Get()->Load(uiPath + wxT("/*.xrc"));
1757 #endif
1758
1759 }
1760
1761
InitLogger()1762 void pgAdmin3::InitLogger()
1763 {
1764 sysLogger::logFile = settings->GetLogFile();
1765 sysLogger::logLevel = settings->GetLogLevel();
1766
1767 logger = new sysLogger();
1768 wxLog::SetVerbose(true);
1769 wxLog::SetActiveTarget(logger);
1770 wxLog::Resume();
1771 }
1772
1773
InitNetwork()1774 void pgAdmin3::InitNetwork()
1775 {
1776 // Startup the windows sockets if required
1777 #ifdef __WXMSW__
1778 WSADATA wsaData;
1779 if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
1780 {
1781 wxLogFatalError(__("Cannot initialise the networking subsystem!"));
1782 }
1783 #endif
1784 wxSocketBase::Initialize();
1785
1786 pgConn::ExamineLibpqVersion();
1787 }
1788
1789 #include "images/pgAdmin3-16.pngc"
1790 #include "images/pgAdmin3-32.pngc"
1791 #include "images/splash.pngc"
1792
pgAppearanceFactory()1793 pgAppearanceFactory::pgAppearanceFactory()
1794 {
1795 is_branded = false;
1796
1797 // Setup the default branding options
1798 #ifdef __WIN32__
1799 splash_font_size = 8;
1800 #else
1801 #ifdef __WXMAC__
1802 splash_font_size = 11;
1803 #else
1804 splash_font_size = 9;
1805 #endif
1806 #endif
1807
1808 splash_pos_x = 128;
1809 splash_pos_y = 281;
1810 splash_pos_offset = 15;
1811
1812 large_icon = *pgAdmin3_32_png_img;
1813 small_icon = *pgAdmin3_16_png_img;
1814 splash_image = *splash_png_img;
1815
1816 splash_text_colour = wxColour(255, 255, 255);
1817 report_key_colour = wxColour(0, 154, 206);
1818
1819 long_appname = wxT("pgAdmin III");
1820 short_appname = wxT("pgadmin3");
1821 website_url = wxT("http://www.pgadmin.org/");
1822
1823 hide_enterprisedb_help = false;
1824 hide_greenplum_help = false;
1825
1826 // Attempt to overload branding information
1827 wxFileName brIni(brandingPath + wxT("/branding.ini"));
1828 if (brIni.FileExists())
1829 {
1830 wxString brCfg = FileRead(brIni.GetFullPath());
1831
1832 wxStringTokenizer tkz(brCfg, wxT("\r\n"));
1833
1834 while(tkz.HasMoreTokens())
1835 {
1836 wxString token = tkz.GetNextToken();
1837
1838 if (token.Trim() == wxEmptyString || token.StartsWith(wxT(";")))
1839 continue;
1840
1841 if (token.Lower().StartsWith(wxT("largeicon=")))
1842 {
1843 large_icon = wxImage(brandingPath + wxT("/") + token.AfterFirst('=').Trim());
1844 if (!large_icon.IsOk())
1845 large_icon = *pgAdmin3_32_png_img;
1846 else
1847 is_branded = true;
1848 }
1849 else if (token.Lower().StartsWith(wxT("smallicon=")))
1850 {
1851 small_icon = wxImage(brandingPath + wxT("/") + token.AfterFirst('=').Trim());
1852 if (!small_icon.IsOk())
1853 small_icon = *pgAdmin3_16_png_img;
1854 else
1855 is_branded = true;
1856 }
1857 else if (token.Lower().StartsWith(wxT("splashimage=")))
1858 {
1859 splash_image = wxImage(brandingPath + wxT("/") + token.AfterFirst('=').Trim());
1860 if (!splash_image.IsOk())
1861 splash_image = *splash_png_img;
1862 else
1863 is_branded = true;
1864 }
1865 else if (token.Lower().StartsWith(wxT("icon=")))
1866 {
1867 icon = token.AfterFirst('=').Trim();
1868 is_branded = true;
1869 }
1870 #ifdef __WIN32__
1871 else if (token.Lower().StartsWith(wxT("splashfontsizewin=")))
1872 #else
1873 #ifdef __WXMAC__
1874 else if (token.Lower().StartsWith(wxT("splashfontsizemac=")))
1875 #else
1876 else if (token.Lower().StartsWith(wxT("splashfontsizegtk=")))
1877 #endif
1878 #endif
1879 {
1880 token.AfterFirst('=').Trim().ToLong(&splash_font_size);
1881 is_branded = true;
1882 }
1883 else if (token.Lower().StartsWith(wxT("splashposx=")))
1884 {
1885 token.AfterFirst('=').Trim().ToLong(&splash_pos_x);
1886 is_branded = true;
1887 }
1888 else if (token.Lower().StartsWith(wxT("splashposy=")))
1889 {
1890 token.AfterFirst('=').Trim().ToLong(&splash_pos_y);
1891 is_branded = true;
1892 }
1893 else if (token.Lower().StartsWith(wxT("splashposoffset=")))
1894 {
1895 token.AfterFirst('=').Trim().ToLong(&splash_pos_offset);
1896 is_branded = true;
1897 }
1898 else if (token.Lower().StartsWith(wxT("splashtextcolour=")))
1899 {
1900 splash_text_colour = wxColor(token.AfterFirst('=').Trim());
1901 is_branded = true;
1902 }
1903 else if (token.Lower().StartsWith(wxT("shortappname=")))
1904 {
1905 short_appname = token.AfterFirst('=').Trim();
1906 is_branded = true;
1907 }
1908 else if (token.Lower().StartsWith(wxT("longappname=")))
1909 {
1910 long_appname = token.AfterFirst('=').Trim();
1911 is_branded = true;
1912 }
1913 else if (token.Lower().StartsWith(wxT("websiteurl=")))
1914 {
1915 website_url = token.AfterFirst('=').Trim();
1916 is_branded = true;
1917 }
1918 else if (token.Lower().StartsWith(wxT("reportkeycolour=")))
1919 {
1920 report_key_colour = wxColor(token.AfterFirst('=').Trim());
1921 is_branded = true;
1922 }
1923 else if (token.Lower().StartsWith(wxT("hideenterprisedbhelp=")))
1924 {
1925 if (token.AfterFirst('=').Trim() == wxT("1"))
1926 {
1927 hide_enterprisedb_help = true;
1928 is_branded = true;
1929 }
1930 }
1931 else if (token.Lower().StartsWith(wxT("hidegreenplumhelp=")))
1932 {
1933 if (token.AfterFirst('=').Trim() == wxT("1"))
1934 {
1935 hide_greenplum_help = true;
1936 is_branded = true;
1937 }
1938 }
1939 }
1940 }
1941
1942 #ifdef __WXMSW__
1943
1944 // Set the MUI cache value for the grouped task bar title,
1945 // otherwise we get the value from the resources which is
1946 // definitely not what we want in branded mode!
1947 wxRegKey *pRegKey = new wxRegKey(wxT("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\ShellNoRoam\\MUICache"));
1948 if(!pRegKey->Exists())
1949 pRegKey->Create();
1950
1951 #if wxCHECK_VERSION(2, 9, 5)
1952 wxStandardPaths &paths = wxStandardPaths::Get();
1953 #else
1954 wxStandardPaths paths;
1955 #endif
1956 //wxString tmp;
1957 //tmp.Printf(wxT("%s"), long_appname);
1958 pRegKey->SetValue(paths.GetExecutablePath(), GetLongAppName());
1959 delete pRegKey;
1960
1961 // Reset the image for the task bar group. This can only by
1962 // set per-exe name unfortunately. If we don't find an icon,
1963 // remove the registry value.
1964 wxString icon_path = brandingPath + wxT("\\") + icon;
1965
1966
1967 pRegKey = new wxRegKey(wxT("HKEY_CURRENT_USER\\Software\\Classes\\Applications\\") + wxFileName(paths.GetExecutablePath()).GetFullName());
1968 if(!pRegKey->Exists())
1969 pRegKey->Create();
1970
1971 if (wxFile::Exists(icon_path))
1972 {
1973 pRegKey->SetValue(wxT("TaskbarGroupIcon"), icon_path);
1974 }
1975 else
1976 {
1977 if (pRegKey->HasValue(wxT("TaskbarGroupIcon")))
1978 pRegKey->DeleteValue(wxT("TaskbarGroupIcon"));
1979 }
1980 delete pRegKey;
1981 #endif
1982 }
1983
SetIcons(wxDialog * dlg)1984 void pgAppearanceFactory::SetIcons(wxDialog *dlg)
1985 {
1986 wxIconBundle icons;
1987 icons.AddIcon(GetSmallIconImage());
1988 icons.AddIcon(GetBigIconImage());
1989 dlg->SetIcons(icons);
1990 }
1991
SetIcons(wxTopLevelWindow * dlg)1992 void pgAppearanceFactory::SetIcons(wxTopLevelWindow *dlg)
1993 {
1994 wxIconBundle icons;
1995 icons.AddIcon(GetSmallIconImage());
1996 icons.AddIcon(GetBigIconImage());
1997 dlg->SetIcons(icons);
1998 }
1999
GetSmallIconImage()2000 wxIcon pgAppearanceFactory::GetSmallIconImage()
2001 {
2002 wxIcon icon;
2003 icon.CopyFromBitmap(wxBitmap(small_icon));
2004 return icon;
2005 }
2006
GetBigIconImage()2007 wxIcon pgAppearanceFactory::GetBigIconImage()
2008 {
2009 wxIcon icon;
2010 icon.CopyFromBitmap(wxBitmap(large_icon));
2011 return icon;
2012 }
2013
GetSplashTextFont()2014 wxFont pgAppearanceFactory::GetSplashTextFont()
2015 {
2016 wxFont fnt(*wxNORMAL_FONT);
2017 fnt.SetPointSize(splash_font_size);
2018 return fnt;
2019 }
2020
2021 ////////////////////////////////////////////////////////////////////////////////
2022 // InitLibpq()
2023 //
2024 // Dynamically load EDB-specific functions from libpq
2025
2026 #ifdef __WXMSW__
InitLibpq()2027 void pgAdmin3::InitLibpq()
2028 {
2029 HINSTANCE hinstLib;
2030
2031 // Get a handle to the DLL module.
2032 hinstLib = LoadLibrary(TEXT("libpq"));
2033
2034 // If the handle is valid, try to get the function address.
2035 if (hinstLib != NULL)
2036 {
2037 PQiGetOutResult = (PQGETOUTRESULT) GetProcAddress(hinstLib, "PQgetOutResult");
2038 PQiPrepareOut = (PQPREPAREOUT) GetProcAddress(hinstLib, "PQprepareOut");
2039 PQiSendQueryPreparedOut = (PQSENDQUERYPREPAREDOUT) GetProcAddress(hinstLib, "PQsendQueryPreparedOut");
2040
2041 // If the function address is valid, call the function.
2042 if (PQiGetOutResult != NULL)
2043 wxLogInfo(wxT("Using runtime dynamically linked EDB libpq functions."));
2044 else
2045 wxLogInfo(wxT("EDB libpq functions are not available."));
2046 }
2047 }
2048 #endif
2049
2050