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 &current, 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