]> git.saurik.com Git - wxWidgets.git/blame - samples/db/dbtest.cpp
don't use unneeded logBuf member variable; show the changed cell value in OnCellValue...
[wxWidgets.git] / samples / db / dbtest.cpp
CommitLineData
108106cf
JS
1///////////////////////////////////////////////////////////////////////////////
2// Name: dbtest.cpp
be5a51fb 3// Purpose: wxWidgets database demo app
108106cf
JS
4// Author: George Tasker
5// Modified by:
6// Created: 1998
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Remstar International, Inc.
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12/*
e70e8f4c 13 * SYNOPSIS START
108106cf 14
e70e8f4c
GT
15 This sample program demonstrates the cross-platform ODBC database classes
16 donated by the development team at Remstar International.
108106cf 17
e70e8f4c 18 The table this sample is based on is developer contact table, and shows
f6bcfd97 19 some of the simple uses of the database classes wxDb and wxDbTable.
108106cf 20
e70e8f4c 21 * SYNOPSIS END
108106cf
JS
22 */
23
108106cf
JS
24#include "wx/wxprec.h"
25
26#ifdef __BORLANDC__
27#pragma hdrstop
28#endif //__BORLANDC__
29
30#ifndef WX_PRECOMP
fb86524f 31#include "wx/wx.h"
108106cf
JS
32#endif //WX_PRECOMP
33
52ad8c7d 34#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMAC__)
7e616b10
RR
35#include "db.xpm"
36#endif
37
5b077d48 38#include <stdio.h> /* Included strictly for reading the text file with the database parameters */
108106cf 39
fb86524f
GD
40//#include "wx/db.h" /* Required in the file which will get the data source connection */
41//#include "wx/dbtable.h" /* Has the wxDbTable object from which all data objects will inherit their data table functionality */
108106cf 42
3fe813a9 43//extern wxDbList WXDLLEXPORT *PtrBegDbList; /* from db.cpp, used in getting back error results from db connections */
108106cf 44
9b12bd99 45#if wxUSE_GRID
fb86524f
GD
46#include "wx/grid.h"
47#include "wx/generic/gridctrl.h"
48#include "wx/dbgrid.h"
f21b2fd8
GT
49
50#define CHOICEINT
51#endif
52
5b077d48
RR
53#include "dbtest.h" /* Header file for this demonstration program */
54#include "listdb.h" /* Code to support the "Lookup" button on the editor dialog */
1fc5dd6f
JS
55
56IMPLEMENT_APP(DatabaseDemoApp)
57
049977d0
GT
58extern wxChar ListDB_Selection[]; /* Used to return the first column value for the selected line from the listDB routines */
59extern wxChar ListDB_Selection2[]; /* Used to return the second column value for the selected line from the listDB routines */
108106cf 60
da1e87c4
GT
61#ifdef wxODBC_BLOB_SUPPORT
62 #include "wx/file.h"
63 #include "wx/mstream.h"
64 #include "wx/image.h"
65 #include "wx/bitmap.h"
66 #include "wx/statbmp.h"
67#endif
5d59e67a
GT
68
69#if !wxUSE_ODBC
70 #error Sample cannot be compiled unless setup.h has wxUSE_ODBC set to 1
71#endif
72
73
aaf0836c 74bool DataTypeSupported(wxDb *pDb, SWORD datatype, wxString *nativeDataTypeName)
3fe813a9
GT
75{
76 wxDbSqlTypeInfo sqlTypeInfo;
77
6d841efd 78 bool breakpoint = false;
3fe813a9 79
aaf0836c 80 *nativeDataTypeName = wxEmptyString;
3fe813a9 81 if (pDb->GetDataTypeInfo(datatype, sqlTypeInfo))
aaf0836c
GT
82 {
83 *nativeDataTypeName = sqlTypeInfo.TypeName;
6d841efd 84 breakpoint = true;
aaf0836c 85 }
3fe813a9
GT
86
87 return breakpoint;
88
89} // GetDataTypesSupported();
90
91
92
93void CheckSupportForAllDataTypes(wxDb *pDb)
94{
aaf0836c
GT
95 wxString nativeDataTypeName;
96
74de91cc 97 wxLogMessage(wxT("\nThe following datatypes are supported by the\ndatabase you are currently connected to:"));
3fe813a9 98#ifdef SQL_C_BINARY
aaf0836c
GT
99 if (DataTypeSupported(pDb,SQL_C_BINARY, &nativeDataTypeName))
100 {
74de91cc 101 nativeDataTypeName = wxT("SQL_C_BINARY (") + nativeDataTypeName;
9b12bd99 102 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
103 wxLogMessage(nativeDataTypeName);
104 }
3fe813a9
GT
105#endif
106#ifdef SQL_C_BIT
aaf0836c
GT
107 if (DataTypeSupported(pDb,SQL_C_BIT, &nativeDataTypeName))
108 {
74de91cc 109 nativeDataTypeName = wxT("SQL_C_BIT (") + nativeDataTypeName;
9b12bd99 110 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
111 wxLogMessage(nativeDataTypeName);
112 }
3fe813a9
GT
113#endif
114#ifdef SQL_C_BOOKMARK
aaf0836c
GT
115 if (DataTypeSupported(pDb,SQL_C_BOOKMARK, &nativeDataTypeName))
116 {
74de91cc 117 nativeDataTypeName = wxT("SQL_C_BOOKMARK (") + nativeDataTypeName;
9b12bd99 118 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
119 wxLogMessage(nativeDataTypeName);
120 }
3fe813a9
GT
121#endif
122#ifdef SQL_C_CHAR
aaf0836c
GT
123 if (DataTypeSupported(pDb,SQL_C_CHAR, &nativeDataTypeName))
124 {
74de91cc 125 nativeDataTypeName = wxT("SQL_C_CHAR (") + nativeDataTypeName;
9b12bd99 126 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
127 wxLogMessage(nativeDataTypeName);
128 }
3fe813a9
GT
129#endif
130#ifdef SQL_C_DATE
aaf0836c
GT
131 if (DataTypeSupported(pDb,SQL_C_DATE, &nativeDataTypeName))
132 {
74de91cc 133 nativeDataTypeName = wxT("SQL_C_DATE (") + nativeDataTypeName;
9b12bd99 134 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
135 wxLogMessage(nativeDataTypeName);
136 }
3fe813a9
GT
137#endif
138#ifdef SQL_C_DEFAULT
aaf0836c
GT
139 if (DataTypeSupported(pDb,SQL_C_DEFAULT, &nativeDataTypeName))
140 {
74de91cc 141 nativeDataTypeName = wxT("SQL_C_DEFAULT (") + nativeDataTypeName;
9b12bd99 142 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
143 wxLogMessage(nativeDataTypeName);
144 }
3fe813a9
GT
145#endif
146#ifdef SQL_C_DOUBLE
aaf0836c
GT
147 if (DataTypeSupported(pDb,SQL_C_DOUBLE, &nativeDataTypeName))
148 {
74de91cc 149 nativeDataTypeName = wxT("SQL_C_DOUBLE (") + nativeDataTypeName;
9b12bd99 150 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
151 wxLogMessage(nativeDataTypeName);
152 }
3fe813a9
GT
153#endif
154#ifdef SQL_C_FLOAT
aaf0836c
GT
155 if (DataTypeSupported(pDb,SQL_C_FLOAT, &nativeDataTypeName))
156 {
74de91cc 157 nativeDataTypeName = wxT("SQL_C_FLOAT (") + nativeDataTypeName;
9b12bd99 158 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
159 wxLogMessage(nativeDataTypeName);
160 }
3fe813a9
GT
161#endif
162#ifdef SQL_C_GUID
aaf0836c
GT
163 if (DataTypeSupported(pDb,SQL_C_GUID, &nativeDataTypeName))
164 {
74de91cc 165 nativeDataTypeName = wxT("SQL_C_GUID (") + nativeDataTypeName;
9b12bd99 166 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
167 wxLogMessage(nativeDataTypeName);
168 }
3fe813a9
GT
169#endif
170#ifdef SQL_C_INTERVAL_DAY
aaf0836c
GT
171 if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY, &nativeDataTypeName))
172 {
74de91cc 173 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY (") + nativeDataTypeName;
9b12bd99 174 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
175 wxLogMessage(nativeDataTypeName);
176 }
3fe813a9
GT
177#endif
178#ifdef SQL_C_INTERVAL_DAY_TO_HOUR
aaf0836c
GT
179 if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_HOUR, &nativeDataTypeName))
180 {
74de91cc 181 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY_TO_HOUR (") + nativeDataTypeName;
9b12bd99 182 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
183 wxLogMessage(nativeDataTypeName);
184 }
3fe813a9
GT
185#endif
186#ifdef SQL_C_INTERVAL_DAY_TO_MINUTE
aaf0836c
GT
187 if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_MINUTE, &nativeDataTypeName))
188 {
74de91cc 189 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY_TO_MINUTE (") + nativeDataTypeName;
9b12bd99 190 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
191 wxLogMessage(nativeDataTypeName);
192 }
3fe813a9
GT
193#endif
194#ifdef SQL_C_INTERVAL_DAY_TO_SECOND
aaf0836c
GT
195 if (DataTypeSupported(pDb,SQL_C_INTERVAL_DAY_TO_SECOND, &nativeDataTypeName))
196 {
74de91cc 197 nativeDataTypeName = wxT("SQL_C_INTERVAL_DAY_TO_SECOND (") + nativeDataTypeName;
9b12bd99 198 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
199 wxLogMessage(nativeDataTypeName);
200 }
3fe813a9
GT
201#endif
202#ifdef SQL_C_INTERVAL_HOUR
aaf0836c
GT
203 if (DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR, &nativeDataTypeName))
204 {
74de91cc 205 nativeDataTypeName = wxT("SQL_C_INTERVAL_HOUR (") + nativeDataTypeName;
9b12bd99 206 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
207 wxLogMessage(nativeDataTypeName);
208 }
3fe813a9
GT
209#endif
210#ifdef SQL_C_INTERVAL_HOUR_TO_MINUTE
aaf0836c
GT
211 if (DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR_TO_MINUTE, &nativeDataTypeName))
212 {
74de91cc 213 nativeDataTypeName = wxT("SQL_C_INTERVAL_HOUR_TO_MINUTE (") + nativeDataTypeName;
9b12bd99 214 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
215 wxLogMessage(nativeDataTypeName);
216 }
3fe813a9
GT
217#endif
218#ifdef SQL_C_INTERVAL_HOUR_TO_SECOND
aaf0836c
GT
219 if (DataTypeSupported(pDb,SQL_C_INTERVAL_HOUR_TO_SECOND, &nativeDataTypeName))
220 {
74de91cc 221 nativeDataTypeName = wxT("SQL_C_INTERVAL_HOUR_TO_SECOND (") + nativeDataTypeName;
9b12bd99 222 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
223 wxLogMessage(nativeDataTypeName);
224 }
3fe813a9
GT
225#endif
226#ifdef SQL_C_INTERVAL_MINUTE
aaf0836c
GT
227 if (DataTypeSupported(pDb,SQL_C_INTERVAL_MINUTE, &nativeDataTypeName))
228 {
74de91cc 229 nativeDataTypeName = wxT("SQL_C_INTERVAL_MINUTE (") + nativeDataTypeName;
9b12bd99 230 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
231 wxLogMessage(nativeDataTypeName);
232 }
3fe813a9
GT
233#endif
234#ifdef SQL_C_INTERVAL_MINUTE_TO_SECOND
aaf0836c
GT
235 if (DataTypeSupported(pDb,SQL_C_INTERVAL_MINUTE_TO_SECOND, &nativeDataTypeName))
236 {
74de91cc 237 nativeDataTypeName = wxT("SQL_C_INTERVAL_MINUTE_TO_SECOND (") + nativeDataTypeName;
9b12bd99 238 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
239 wxLogMessage(nativeDataTypeName);
240 }
3fe813a9
GT
241#endif
242#ifdef SQL_C_INTERVAL_MONTH
aaf0836c
GT
243 if (DataTypeSupported(pDb,SQL_C_INTERVAL_MONTH, &nativeDataTypeName))
244 {
74de91cc 245 nativeDataTypeName = wxT("SQL_C_INTERVAL_MONTH (") + nativeDataTypeName;
9b12bd99 246 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
247 wxLogMessage(nativeDataTypeName);
248 }
3fe813a9
GT
249#endif
250#ifdef SQL_C_INTERVAL_SECOND
aaf0836c
GT
251 if (DataTypeSupported(pDb,SQL_C_INTERVAL_SECOND, &nativeDataTypeName))
252 {
74de91cc 253 nativeDataTypeName = wxT("SQL_C_INTERVAL_SECOND (") + nativeDataTypeName;
9b12bd99 254 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
255 wxLogMessage(nativeDataTypeName);
256 }
3fe813a9
GT
257#endif
258#ifdef SQL_C_INTERVAL_YEAR
aaf0836c
GT
259 if (DataTypeSupported(pDb,SQL_C_INTERVAL_YEAR, &nativeDataTypeName))
260 {
74de91cc 261 nativeDataTypeName = wxT("SQL_C_INTERVAL_YEAR (") + nativeDataTypeName;
9b12bd99 262 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
263 wxLogMessage(nativeDataTypeName);
264 }
3fe813a9
GT
265#endif
266#ifdef SQL_C_INTERVAL_YEAR_TO_MONTH
aaf0836c
GT
267 if (DataTypeSupported(pDb,SQL_C_INTERVAL_YEAR_TO_MONTH, &nativeDataTypeName))
268 {
74de91cc 269 nativeDataTypeName = wxT("SQL_C_INTERVAL_YEAR_TO_MONTH (") + nativeDataTypeName;
9b12bd99 270 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
271 wxLogMessage(nativeDataTypeName);
272 }
3fe813a9
GT
273#endif
274#ifdef SQL_C_LONG
aaf0836c
GT
275 if (DataTypeSupported(pDb,SQL_C_LONG, &nativeDataTypeName))
276 {
74de91cc 277 nativeDataTypeName = wxT("SQL_C_LONG (") + nativeDataTypeName;
9b12bd99 278 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
279 wxLogMessage(nativeDataTypeName);
280 }
3fe813a9
GT
281#endif
282#ifdef SQL_C_NUMERIC
aaf0836c
GT
283 if (DataTypeSupported(pDb,SQL_C_NUMERIC, &nativeDataTypeName))
284 {
74de91cc 285 nativeDataTypeName = wxT("SQL_C_NUMERIC (") + nativeDataTypeName;
9b12bd99 286 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
287 wxLogMessage(nativeDataTypeName);
288 }
3fe813a9
GT
289#endif
290#ifdef SQL_C_SBIGINT
aaf0836c
GT
291 if (DataTypeSupported(pDb,SQL_C_SBIGINT, &nativeDataTypeName))
292 {
74de91cc 293 nativeDataTypeName = wxT("SQL_C_SBIGINT (") + nativeDataTypeName;
9b12bd99 294 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
295 wxLogMessage(nativeDataTypeName);
296 }
3fe813a9
GT
297#endif
298#ifdef SQL_C_SHORT
aaf0836c
GT
299 if (DataTypeSupported(pDb,SQL_C_SHORT, &nativeDataTypeName))
300 {
74de91cc 301 nativeDataTypeName = wxT("SQL_C_SHORT (") + nativeDataTypeName;
9b12bd99 302 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
303 wxLogMessage(nativeDataTypeName);
304 }
3fe813a9
GT
305#endif
306#ifdef SQL_C_SLONG
aaf0836c
GT
307 if (DataTypeSupported(pDb,SQL_C_SLONG, &nativeDataTypeName))
308 {
74de91cc 309 nativeDataTypeName = wxT("SQL_C_SLONG (") + nativeDataTypeName;
9b12bd99 310 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
311 wxLogMessage(nativeDataTypeName);
312 }
3fe813a9
GT
313#endif
314#ifdef SQL_C_SSHORT
aaf0836c
GT
315 if (DataTypeSupported(pDb,SQL_C_SSHORT, &nativeDataTypeName))
316 {
74de91cc 317 nativeDataTypeName = wxT("SQL_C_SSHORT (") + nativeDataTypeName;
9b12bd99 318 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
319 wxLogMessage(nativeDataTypeName);
320 }
3fe813a9
GT
321#endif
322#ifdef SQL_C_STINYINT
aaf0836c
GT
323 if (DataTypeSupported(pDb,SQL_C_STINYINT, &nativeDataTypeName))
324 {
74de91cc 325 nativeDataTypeName = wxT("SQL_C_STINYINT (") + nativeDataTypeName;
9b12bd99 326 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
327 wxLogMessage(nativeDataTypeName);
328 }
3fe813a9
GT
329#endif
330#ifdef SQL_C_TIME
aaf0836c
GT
331 if (DataTypeSupported(pDb,SQL_C_TIME, &nativeDataTypeName))
332 {
74de91cc 333 nativeDataTypeName = wxT("SQL_C_TIME (") + nativeDataTypeName;
9b12bd99 334 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
335 wxLogMessage(nativeDataTypeName);
336 }
3fe813a9
GT
337#endif
338#ifdef SQL_C_TIMESTAMP
aaf0836c
GT
339 if (DataTypeSupported(pDb,SQL_C_TIMESTAMP, &nativeDataTypeName))
340 {
74de91cc 341 nativeDataTypeName = wxT("SQL_C_TIMESTAMP (") + nativeDataTypeName;
9b12bd99 342 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
343 wxLogMessage(nativeDataTypeName);
344 }
3fe813a9
GT
345#endif
346#ifdef SQL_C_TINYINT
aaf0836c
GT
347 if (DataTypeSupported(pDb,SQL_C_TINYINT, &nativeDataTypeName))
348 {
74de91cc 349 nativeDataTypeName = wxT("SQL_C_TINYINT (") + nativeDataTypeName;
9b12bd99 350 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
351 wxLogMessage(nativeDataTypeName);
352 }
3fe813a9
GT
353#endif
354#ifdef SQL_C_TYPE_DATE
aaf0836c
GT
355 if (DataTypeSupported(pDb,SQL_C_TYPE_DATE, &nativeDataTypeName))
356 {
74de91cc 357 nativeDataTypeName = wxT("SQL_C_TYPE_DATE (") + nativeDataTypeName;
9b12bd99 358 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
359 wxLogMessage(nativeDataTypeName);
360 }
3fe813a9
GT
361#endif
362#ifdef SQL_C_TYPE_TIME
aaf0836c
GT
363 if (DataTypeSupported(pDb,SQL_C_TYPE_TIME, &nativeDataTypeName))
364 {
74de91cc 365 nativeDataTypeName = wxT("SQL_C_TYPE_TIME (") + nativeDataTypeName;
9b12bd99 366 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
367 wxLogMessage(nativeDataTypeName);
368 }
3fe813a9
GT
369#endif
370#ifdef SQL_C_TYPE_TIMESTAMP
aaf0836c
GT
371 if (DataTypeSupported(pDb,SQL_C_TYPE_TIMESTAMP, &nativeDataTypeName))
372 {
74de91cc 373 nativeDataTypeName = wxT("SQL_C_TYPE_TIMESTAMP (") + nativeDataTypeName;
9b12bd99 374 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
375 wxLogMessage(nativeDataTypeName);
376 }
3fe813a9
GT
377#endif
378#ifdef SQL_C_UBIGINT
aaf0836c
GT
379 if (DataTypeSupported(pDb,SQL_C_UBIGINT, &nativeDataTypeName))
380 {
74de91cc 381 nativeDataTypeName = wxT("SQL_C_UBIGINT (") + nativeDataTypeName;
9b12bd99 382 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
383 wxLogMessage(nativeDataTypeName);
384 }
3fe813a9
GT
385#endif
386#ifdef SQL_C_ULONG
aaf0836c
GT
387 if (DataTypeSupported(pDb,SQL_C_ULONG, &nativeDataTypeName))
388 {
74de91cc 389 nativeDataTypeName = wxT("SQL_C_ULONG (") + nativeDataTypeName;
9b12bd99 390 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
391 wxLogMessage(nativeDataTypeName);
392 }
3fe813a9
GT
393#endif
394#ifdef SQL_C_USHORT
aaf0836c
GT
395 if (DataTypeSupported(pDb,SQL_C_USHORT, &nativeDataTypeName))
396 {
74de91cc 397 nativeDataTypeName = wxT("SQL_C_USHORT (") + nativeDataTypeName;
9b12bd99 398 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
399 wxLogMessage(nativeDataTypeName);
400 }
3fe813a9
GT
401#endif
402#ifdef SQL_C_UTINYINT
aaf0836c
GT
403 if (DataTypeSupported(pDb,SQL_C_UTINYINT, &nativeDataTypeName))
404 {
74de91cc 405 nativeDataTypeName = wxT("SQL_C_UTINYINT (") + nativeDataTypeName;
9b12bd99 406 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
407 wxLogMessage(nativeDataTypeName);
408 }
3fe813a9
GT
409#endif
410#ifdef SQL_C_VARBOOKMARK
aaf0836c
GT
411 if (DataTypeSupported(pDb,SQL_C_VARBOOKMARK, &nativeDataTypeName))
412 {
74de91cc 413 nativeDataTypeName = wxT("SQL_C_VARBOOKMARK (") + nativeDataTypeName;
9b12bd99 414 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
415 wxLogMessage(nativeDataTypeName);
416 }
3fe813a9 417#endif
da1e87c4
GT
418#ifdef SQL_C_WXCHAR
419 if (DataTypeSupported(pDb,SQL_C_WXCHAR, &nativeDataTypeName))
420 {
421 nativeDataTypeName = wxT("SQL_C_WXCHAR (") + nativeDataTypeName;
422 nativeDataTypeName += wxT(")\n");
423 wxLogMessage(nativeDataTypeName);
424 }
425#endif
3fe813a9
GT
426
427// Extended SQL types
428#ifdef SQL_DATE
aaf0836c
GT
429 if (DataTypeSupported(pDb,SQL_DATE, &nativeDataTypeName))
430 {
74de91cc 431 nativeDataTypeName = wxT("SQL_DATE (") + nativeDataTypeName;
9b12bd99 432 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
433 wxLogMessage(nativeDataTypeName);
434 }
3fe813a9
GT
435#endif
436#ifdef SQL_INTERVAL
aaf0836c
GT
437 if (DataTypeSupported(pDb,SQL_INTERVAL, &nativeDataTypeName))
438 {
74de91cc 439 nativeDataTypeName = wxT("SQL_INTERVAL (") + nativeDataTypeName;
9b12bd99 440 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
441 wxLogMessage(nativeDataTypeName);
442 }
3fe813a9
GT
443#endif
444#ifdef SQL_TIME
aaf0836c
GT
445 if (DataTypeSupported(pDb,SQL_TIME, &nativeDataTypeName))
446 {
74de91cc 447 nativeDataTypeName = wxT("SQL_TIME (") + nativeDataTypeName;
9b12bd99 448 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
449 wxLogMessage(nativeDataTypeName);
450 }
3fe813a9
GT
451#endif
452#ifdef SQL_TIMESTAMP
aaf0836c
GT
453 if (DataTypeSupported(pDb,SQL_TIMESTAMP, &nativeDataTypeName))
454 {
74de91cc 455 nativeDataTypeName = wxT("SQL_TIMESTAMP (") + nativeDataTypeName;
9b12bd99 456 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
457 wxLogMessage(nativeDataTypeName);
458 }
3fe813a9
GT
459#endif
460#ifdef SQL_LONGVARCHAR
aaf0836c
GT
461 if (DataTypeSupported(pDb,SQL_LONGVARCHAR, &nativeDataTypeName))
462 {
74de91cc 463 nativeDataTypeName = wxT("SQL_LONGVARCHAR (") + nativeDataTypeName;
9b12bd99 464 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
465 wxLogMessage(nativeDataTypeName);
466 }
3fe813a9
GT
467#endif
468#ifdef SQL_BINARY
aaf0836c
GT
469 if (DataTypeSupported(pDb,SQL_BINARY, &nativeDataTypeName))
470 {
74de91cc 471 nativeDataTypeName = wxT("SQL_BINARY (") + nativeDataTypeName;
9b12bd99 472 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
473 wxLogMessage(nativeDataTypeName);
474 }
3fe813a9
GT
475#endif
476#ifdef SQL_VARBINARY
aaf0836c
GT
477 if (DataTypeSupported(pDb,SQL_VARBINARY, &nativeDataTypeName))
478 {
74de91cc 479 nativeDataTypeName = wxT("SQL_VARBINARY (") + nativeDataTypeName;
9b12bd99 480 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
481 wxLogMessage(nativeDataTypeName);
482 }
3fe813a9
GT
483#endif
484#ifdef SQL_LONGVARBINARY
aaf0836c
GT
485 if (DataTypeSupported(pDb,SQL_LONGVARBINARY, &nativeDataTypeName))
486 {
74de91cc 487 nativeDataTypeName = wxT("SQL_LOGVARBINARY (") + nativeDataTypeName;
9b12bd99 488 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
489 wxLogMessage(nativeDataTypeName);
490 }
3fe813a9
GT
491#endif
492#ifdef SQL_BIGINT
aaf0836c
GT
493 if (DataTypeSupported(pDb,SQL_BIGINT, &nativeDataTypeName))
494 {
74de91cc 495 nativeDataTypeName = wxT("SQL_BIGINT (") + nativeDataTypeName;
9b12bd99 496 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
497 wxLogMessage(nativeDataTypeName);
498 }
3fe813a9
GT
499#endif
500#ifdef SQL_TINYINT
aaf0836c
GT
501 if (DataTypeSupported(pDb,SQL_TINYINT, &nativeDataTypeName))
502 {
74de91cc 503 nativeDataTypeName = wxT("SQL_TINYINT (") + nativeDataTypeName;
9b12bd99 504 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
505 wxLogMessage(nativeDataTypeName);
506 }
3fe813a9
GT
507#endif
508#ifdef SQL_BIT
aaf0836c
GT
509 if (DataTypeSupported(pDb,SQL_BIT, &nativeDataTypeName))
510 {
74de91cc 511 nativeDataTypeName = wxT("SQL_BIT (") + nativeDataTypeName;
9b12bd99 512 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
513 wxLogMessage(nativeDataTypeName);
514 }
3fe813a9
GT
515#endif
516#ifdef SQL_GUID
aaf0836c
GT
517 if (DataTypeSupported(pDb,SQL_GUID, &nativeDataTypeName))
518 {
74de91cc 519 nativeDataTypeName = wxT("SQL_GUID (") + nativeDataTypeName;
9b12bd99 520 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
521 wxLogMessage(nativeDataTypeName);
522 }
3fe813a9
GT
523#endif
524
525#ifdef SQL_CHAR
aaf0836c
GT
526 if (DataTypeSupported(pDb,SQL_CHAR, &nativeDataTypeName))
527 {
74de91cc 528 nativeDataTypeName = wxT("SQL_CHAR (") + nativeDataTypeName;
9b12bd99 529 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
530 wxLogMessage(nativeDataTypeName);
531 }
3fe813a9
GT
532#endif
533#ifdef SQL_INTEGER
aaf0836c
GT
534 if (DataTypeSupported(pDb,SQL_INTEGER, &nativeDataTypeName))
535 {
74de91cc 536 nativeDataTypeName = wxT("SQL_INTEGER (") + nativeDataTypeName;
9b12bd99 537 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
538 wxLogMessage(nativeDataTypeName);
539 }
3fe813a9
GT
540#endif
541#ifdef SQL_SMALLINT
aaf0836c
GT
542 if (DataTypeSupported(pDb,SQL_SMALLINT, &nativeDataTypeName))
543 {
74de91cc 544 nativeDataTypeName = wxT("SQL_SAMLLINT (") + nativeDataTypeName;
9b12bd99 545 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
546 wxLogMessage(nativeDataTypeName);
547 }
3fe813a9
GT
548#endif
549#ifdef SQL_REAL
aaf0836c
GT
550 if (DataTypeSupported(pDb,SQL_REAL, &nativeDataTypeName))
551 {
74de91cc 552 nativeDataTypeName = wxT("SQL_REAL (") + nativeDataTypeName;
9b12bd99 553 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
554 wxLogMessage(nativeDataTypeName);
555 }
3fe813a9
GT
556#endif
557#ifdef SQL_DOUBLE
aaf0836c
GT
558 if (DataTypeSupported(pDb,SQL_DOUBLE, &nativeDataTypeName))
559 {
74de91cc 560 nativeDataTypeName = wxT("SQL_DOUBLE (") + nativeDataTypeName;
9b12bd99 561 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
562 wxLogMessage(nativeDataTypeName);
563 }
3fe813a9
GT
564#endif
565#ifdef SQL_NUMERIC
aaf0836c
GT
566 if (DataTypeSupported(pDb,SQL_NUMERIC, &nativeDataTypeName))
567 {
74de91cc 568 nativeDataTypeName = wxT("SQL_NUMERIC (") + nativeDataTypeName;
9b12bd99 569 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
570 wxLogMessage(nativeDataTypeName);
571 }
3fe813a9
GT
572#endif
573#ifdef SQL_DATE
aaf0836c
GT
574 if (DataTypeSupported(pDb,SQL_DATE, &nativeDataTypeName))
575 {
74de91cc 576 nativeDataTypeName = wxT("SQL_DATE (") + nativeDataTypeName;
9b12bd99 577 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
578 wxLogMessage(nativeDataTypeName);
579 }
3fe813a9
GT
580#endif
581#ifdef SQL_TIME
aaf0836c
GT
582 if (DataTypeSupported(pDb,SQL_TIME, &nativeDataTypeName))
583 {
74de91cc 584 nativeDataTypeName = wxT("SQL_TIME (") + nativeDataTypeName;
9b12bd99 585 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
586 wxLogMessage(nativeDataTypeName);
587 }
3fe813a9
GT
588#endif
589#ifdef SQL_TIMESTAMP
aaf0836c
GT
590 if (DataTypeSupported(pDb,SQL_TIMESTAMP, &nativeDataTypeName))
591 {
74de91cc 592 nativeDataTypeName = wxT("SQL_TIMESTAMP (") + nativeDataTypeName;
9b12bd99 593 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
594 wxLogMessage(nativeDataTypeName);
595 }
3fe813a9
GT
596#endif
597#ifdef SQL_VARCHAR
aaf0836c
GT
598 if (DataTypeSupported(pDb,SQL_VARCHAR, &nativeDataTypeName))
599 {
74de91cc 600 nativeDataTypeName = wxT("SQL_VARCHAR (") + nativeDataTypeName;
9b12bd99 601 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
602 wxLogMessage(nativeDataTypeName);
603 }
3fe813a9
GT
604#endif
605
3fe813a9
GT
606// UNICODE
607#ifdef SQL_C_TCHAR
aaf0836c
GT
608 if (DataTypeSupported(pDb,SQL_C_TCHAR, &nativeDataTypeName))
609 {
74de91cc 610 nativeDataTypeName = wxT("SQL_C_TCHAR (") + nativeDataTypeName;
9b12bd99 611 nativeDataTypeName += wxT(")\n");
aaf0836c
GT
612 wxLogMessage(nativeDataTypeName);
613 }
3fe813a9 614#endif
fcf3321f
GT
615#ifdef SQL_WVARCHAR
616 if (DataTypeSupported(pDb,SQL_WVARCHAR, &nativeDataTypeName))
617 {
618 nativeDataTypeName = wxT("SQL_WVARCHAR (") + nativeDataTypeName;
619 nativeDataTypeName += wxT(")\n");
620 wxLogMessage(nativeDataTypeName);
621 }
622#endif
623#ifdef SQL_WCHAR
624 if (DataTypeSupported(pDb,SQL_WCHAR, &nativeDataTypeName))
625 {
626 nativeDataTypeName = wxT("SQL_WCHAR (") + nativeDataTypeName;
627 nativeDataTypeName += wxT(")\n");
628 wxLogMessage(nativeDataTypeName);
629 }
630#endif
3f030b48 631
9b12bd99 632 wxLogMessage(wxT("Done\n"));
3fe813a9
GT
633} // CheckSupportForAllDataTypes()
634
635
1fc5dd6f 636bool DatabaseDemoApp::OnInit()
108106cf 637{
ea24eeb2
GT
638 DbConnectInf = NULL;
639 Contact = NULL;
049977d0 640
e70e8f4c 641 // Create the main frame window
da1e87c4 642 DemoFrame = new DatabaseDemoFrame(NULL, wxT("wxWidgets Database Demo"), wxPoint(50, 50), wxSize(537, 530));
e70e8f4c
GT
643
644 // Give it an icon
645 DemoFrame->SetIcon(wxICON(db));
646
647 // Make a menubar
648 wxMenu *file_menu = new wxMenu;
74de91cc 649 file_menu->Append(FILE_CREATE_ID, wxT("&Create CONTACT table"));
94613352
GT
650 file_menu->Append(FILE_RECREATE_TABLE, wxT("&Recreate CONTACT table"));
651 file_menu->Append(FILE_RECREATE_INDEXES, wxT("&Recreate CONTACT indexes"));
9b12bd99 652#if wxUSE_GRID
f21b2fd8
GT
653 file_menu->Append(FILE_DBGRID_TABLE, wxT("&Open DB Grid example"));
654#endif
94613352 655 file_menu->Append(FILE_EXIT, wxT("E&xit"));
e70e8f4c
GT
656
657 wxMenu *edit_menu = new wxMenu;
94613352 658 edit_menu->Append(EDIT_PARAMETERS, wxT("&Parameters..."));
e70e8f4c 659
ea24eeb2
GT
660 wxMenu *help_menu = new wxMenu;
661 help_menu->Append(HELP_ABOUT, wxT("&About"));
e70e8f4c
GT
662
663 wxMenuBar *menu_bar = new wxMenuBar;
94613352
GT
664 menu_bar->Append(file_menu, wxT("&File"));
665 menu_bar->Append(edit_menu, wxT("&Edit"));
ea24eeb2 666 menu_bar->Append(help_menu, wxT("&Help"));
e70e8f4c
GT
667 DemoFrame->SetMenuBar(menu_bar);
668
e70e8f4c
GT
669 params.ODBCSource[0] = 0;
670 params.UserName[0] = 0;
671 params.Password[0] = 0;
672 params.DirPath[0] = 0;
673
da1e87c4
GT
674#ifdef wxODBC_BLOB_SUPPORT
675 wxInitAllImageHandlers();
676 wxImage::InitStandardHandlers();
677 wxBitmap::InitStandardHandlers();
678#endif
679
3ca6a5f0 680 // Show the frame
6d841efd 681 DemoFrame->Show(true);
3ca6a5f0 682
049977d0
GT
683 // Passing NULL for the SQL environment handle causes
684 // the wxDbConnectInf constructor to obtain a handle
685 // for you.
686 //
687 // WARNING: Be certain that you do not free this handle
688 // directly with SQLFreeEnv(). Use either the
689 // method ::FreeHenv() or delete the DbConnectInf.
925e9792 690 DbConnectInf = new wxDbConnectInf(NULL, params.ODBCSource, params.UserName,
049977d0
GT
691 params.Password, params.DirPath);
692
693 if (!DbConnectInf || !DbConnectInf->GetHenv())
694 {
695 wxMessageBox(wxT("Unable to define data source connection info."), wxT("DB CONNECTION ERROR..."),wxOK | wxICON_EXCLAMATION);
ea24eeb2 696 wxDELETE(DbConnectInf);
049977d0
GT
697 }
698
3fe813a9
GT
699 if (!ReadParamFile(params))
700 DemoFrame->BuildParameterDialog(NULL);
701
702 if (!wxStrlen(params.ODBCSource))
703 {
ea24eeb2 704 wxDELETE(DbConnectInf);
6d841efd 705 return(false);
3fe813a9
GT
706 }
707
708 DbConnectInf->SetDsn(params.ODBCSource);
709 DbConnectInf->SetUserID(params.UserName);
710 DbConnectInf->SetPassword(params.Password);
711 DbConnectInf->SetDefaultDir(params.DirPath);
712
049977d0
GT
713 READONLY_DB = wxDbGetConnection(DbConnectInf);
714 if (READONLY_DB == 0)
715 {
716 wxMessageBox(wxT("Unable to connect to the data source.\n\nCheck the name of your data source to verify it has been correctly entered/spelled.\n\nWith some databases, the user name and password must\nbe created with full rights to the CONTACT table prior to making a connection\n(using tools provided by the database manufacturer)"), wxT("DB CONNECTION ERROR..."),wxOK | wxICON_EXCLAMATION);
717 DemoFrame->BuildParameterDialog(NULL);
ea24eeb2 718 wxDELETE(DbConnectInf);
049977d0 719 wxMessageBox(wxT("Now exiting program.\n\nRestart program to try any new settings."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
6d841efd 720 return(false);
049977d0
GT
721 }
722
723 DemoFrame->BuildEditorDialog();
724
725 // Show the frame
726 DemoFrame->Refresh();
727
6d841efd 728 return true;
049977d0
GT
729} // DatabaseDemoApp::OnInit()
730
731
f369dd4f
GT
732/*
733* Remove CR or CR/LF from a character string.
734*/
74de91cc 735wxChar* wxRemoveLineTerminator(wxChar* aString)
f369dd4f 736{
74de91cc
JS
737 int len = wxStrlen(aString);
738 while (len > 0 && (aString[len-1] == wxT('\r') || aString[len-1] == wxT('\n'))) {
739 aString[len-1] = wxT('\0');
f369dd4f
GT
740 len--;
741 }
742 return aString;
743}
744
745
049977d0
GT
746bool DatabaseDemoApp::ReadParamFile(Cparameters &params)
747{
e70e8f4c 748 FILE *paramFile;
74de91cc 749 if ((paramFile = wxFopen(PARAM_FILENAME, wxT("r"))) == NULL)
e70e8f4c
GT
750 {
751 wxString tStr;
51e298bb 752 tStr.Printf(wxT("Unable to open the parameter file '%s' for reading.\n\nYou must specify the data source, user name, and\npassword that will be used and save those settings."),PARAM_FILENAME.c_str());
94613352 753 wxMessageBox(tStr,wxT("File I/O Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c 754
6d841efd 755 return false;
e70e8f4c
GT
756 }
757
94613352 758 wxChar buffer[1000+1];
74de91cc 759 wxFgets(buffer, sizeof(params.ODBCSource), paramFile);
f369dd4f 760 wxRemoveLineTerminator(buffer);
f6bcfd97 761 wxStrcpy(params.ODBCSource,buffer);
e70e8f4c 762
74de91cc 763 wxFgets(buffer, sizeof(params.UserName), paramFile);
f369dd4f 764 wxRemoveLineTerminator(buffer);
f6bcfd97 765 wxStrcpy(params.UserName,buffer);
e70e8f4c 766
74de91cc 767 wxFgets(buffer, sizeof(params.Password), paramFile);
f369dd4f 768 wxRemoveLineTerminator(buffer);
f6bcfd97 769 wxStrcpy(params.Password,buffer);
e70e8f4c 770
74de91cc 771 wxFgets(buffer, sizeof(params.DirPath), paramFile);
f369dd4f 772 wxRemoveLineTerminator(buffer);
f6bcfd97 773 wxStrcpy(params.DirPath,buffer);
e70e8f4c
GT
774
775 fclose(paramFile);
776
6d841efd 777 return true;
049977d0 778} // DatabaseDemoApp::ReadParamFile()
e70e8f4c 779
049977d0 780
74de91cc 781bool DatabaseDemoApp::WriteParamFile(Cparameters &WXUNUSED(params))
049977d0
GT
782{
783 FILE *paramFile;
74de91cc 784 if ((paramFile = wxFopen(PARAM_FILENAME, wxT("wt"))) == NULL)
e70e8f4c 785 {
049977d0 786 wxString tStr;
51e298bb 787 tStr.Printf(wxT("Unable to write/overwrite '%s'."),PARAM_FILENAME.c_str());
049977d0 788 wxMessageBox(tStr,wxT("File I/O Error..."),wxOK | wxICON_EXCLAMATION);
6d841efd 789 return false;
e70e8f4c
GT
790 }
791
74de91cc
JS
792 wxFputs(wxGetApp().params.ODBCSource, paramFile);
793 wxFputc(wxT('\n'), paramFile);
794 wxFputs(wxGetApp().params.UserName, paramFile);
795 wxFputc(wxT('\n'), paramFile);
796 wxFputs(wxGetApp().params.Password, paramFile);
797 wxFputc(wxT('\n'), paramFile);
798 wxFputs(wxGetApp().params.DirPath, paramFile);
799 wxFputc(wxT('\n'), paramFile);
049977d0 800 fclose(paramFile);
108106cf 801
6d841efd 802 return true;
049977d0
GT
803} // DatabaseDemoApp::WriteParamFile()
804
805
806void DatabaseDemoApp::CreateDataTable(bool recreate)
807{
6d841efd 808 bool Ok = true;
049977d0
GT
809 if (recreate)
810 Ok = (wxMessageBox(wxT("Any data currently residing in the table will be erased.\n\nAre you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
811
812 if (!Ok)
813 return;
814
815 wxBeginBusyCursor();
816
6d841efd 817 bool success = true;
049977d0 818
ea24eeb2 819 Contact->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
049977d0
GT
820
821 if (!Contact->CreateTable(recreate))
822 {
823 wxEndBusyCursor();
824 wxString tStr;
f21b2fd8 825 tStr = wxT("Error creating CONTACTS table.\nTable was not created.\n\n");
74de91cc 826 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8
GT
827 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
828
6d841efd 829 success = false;
049977d0
GT
830 }
831 else
832 {
69a2b59d 833 if (!Contact->CreateIndexes(recreate))
049977d0
GT
834 {
835 wxEndBusyCursor();
836 wxString tStr;
f21b2fd8 837 tStr = wxT("Error creating CONTACTS indexes.\nIndexes will be unavailable.\n\n");
74de91cc 838 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8
GT
839 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
840
6d841efd 841 success = false;
049977d0
GT
842 }
843 }
844 while (wxIsBusy())
845 wxEndBusyCursor();
846
049977d0
GT
847 if (success)
848 wxMessageBox(wxT("Table and index(es) were successfully created."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
849} // DatabaseDemoApp::CreateDataTable()
108106cf 850
3ca6a5f0 851
1fc5dd6f 852BEGIN_EVENT_TABLE(DatabaseDemoFrame, wxFrame)
74de91cc 853 EVT_MENU(FILE_CREATE_ID, DatabaseDemoFrame::OnCreate)
3ca6a5f0
BP
854 EVT_MENU(FILE_RECREATE_TABLE, DatabaseDemoFrame::OnRecreateTable)
855 EVT_MENU(FILE_RECREATE_INDEXES, DatabaseDemoFrame::OnRecreateIndexes)
9b12bd99 856#if wxUSE_GRID
f21b2fd8
GT
857 EVT_MENU(FILE_DBGRID_TABLE, DatabaseDemoFrame::OnDbGridTable)
858#endif
1fc5dd6f
JS
859 EVT_MENU(FILE_EXIT, DatabaseDemoFrame::OnExit)
860 EVT_MENU(EDIT_PARAMETERS, DatabaseDemoFrame::OnEditParameters)
ea24eeb2 861 EVT_MENU(HELP_ABOUT, DatabaseDemoFrame::OnAbout)
1fc5dd6f
JS
862 EVT_CLOSE(DatabaseDemoFrame::OnCloseWindow)
863END_EVENT_TABLE()
108106cf 864
3ca6a5f0 865
108106cf 866// DatabaseDemoFrame constructor
1fc5dd6f 867DatabaseDemoFrame::DatabaseDemoFrame(wxFrame *frame, const wxString& title,
3ca6a5f0 868 const wxPoint& pos, const wxSize& size):
6d841efd 869 wxFrame(frame, wxID_ANY, title, pos, size)
108106cf 870{
3ca6a5f0
BP
871 // Put any code in necessary for initializing the main frame here
872 pEditorDlg = NULL;
873 pParamDlg = NULL;
3f030b48 874
f07941fc 875#if wxUSE_LOG
3f030b48 876 delete wxLog::SetActiveTarget(new wxLogStderr);
f07941fc 877#endif // wxUSE_LOG
3f030b48 878
3ca6a5f0
BP
879} // DatabaseDemoFrame constructor
880
3f030b48
GT
881DatabaseDemoFrame::~DatabaseDemoFrame()
882{
f07941fc 883#if wxUSE_LOG
3f030b48 884 delete wxLog::SetActiveTarget(NULL);
f07941fc 885#endif // wxUSE_LOG
3f030b48
GT
886} // DatabaseDemoFrame destructor
887
108106cf 888
74de91cc 889void DatabaseDemoFrame::OnCreate(wxCommandEvent& WXUNUSED(event))
1fc5dd6f 890{
6d841efd 891 wxGetApp().CreateDataTable(false);
3ca6a5f0
BP
892} // DatabaseDemoFrame::OnCreate()
893
894
74de91cc 895void DatabaseDemoFrame::OnRecreateTable(wxCommandEvent& WXUNUSED(event))
3ca6a5f0 896{
6d841efd 897 wxGetApp().CreateDataTable(true);
3ca6a5f0
BP
898} // DatabaseDemoFrame::OnRecreate()
899
900
74de91cc 901void DatabaseDemoFrame::OnRecreateIndexes(wxCommandEvent& WXUNUSED(event))
3ca6a5f0 902{
69a2b59d
GT
903 wxGetApp().Contact->GetDb()->RollbackTrans(); // Make sure the current cursor is in a known/stable state
904
6d841efd 905 if (!wxGetApp().Contact->CreateIndexes(true))
3ca6a5f0 906 {
ea24eeb2
GT
907 while (wxIsBusy())
908 wxEndBusyCursor();
909 wxString tStr;
f21b2fd8 910 tStr = wxT("Error creating CONTACTS indexes.\nNew indexes will be unavailable.\n\n");
74de91cc 911 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8
GT
912 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
913
3ca6a5f0 914 }
69a2b59d 915 else
ea24eeb2 916 wxMessageBox(wxT("Index(es) were successfully recreated."),wxT("Notice..."),wxOK | wxICON_INFORMATION);
3ca6a5f0 917
3ca6a5f0 918} // DatabaseDemoFrame::OnRecreateIndexes()
108106cf 919
ea24eeb2 920
9b12bd99 921#if wxUSE_GRID
74de91cc 922void DatabaseDemoFrame::OnDbGridTable(wxCommandEvent& WXUNUSED(event))
f21b2fd8
GT
923{
924 DbGridFrame *frame = new DbGridFrame(this);
925 if (frame->Initialize())
926 {
927 frame->Show();
928 }
929}
930#endif
931
74de91cc 932void DatabaseDemoFrame::OnExit(wxCommandEvent& WXUNUSED(event))
108106cf 933{
3f755e2d 934 Close();
3ca6a5f0
BP
935} // DatabaseDemoFrame::OnExit()
936
108106cf 937
74de91cc 938void DatabaseDemoFrame::OnEditParameters(wxCommandEvent& WXUNUSED(event))
1fc5dd6f 939{
e70e8f4c
GT
940 if ((pEditorDlg->mode != mCreate) && (pEditorDlg->mode != mEdit))
941 BuildParameterDialog(this);
942 else
94613352 943 wxMessageBox(wxT("Cannot change database parameters while creating or editing a record"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
3ca6a5f0
BP
944} // DatabaseDemoFrame::OnEditParameters()
945
1fc5dd6f 946
74de91cc 947void DatabaseDemoFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1fc5dd6f 948{
be5a51fb 949 wxMessageBox(wxT("wxWidgets sample program for database classes\n\nContributed on 27 July 1998"),wxT("About..."),wxOK | wxICON_INFORMATION);
3ca6a5f0
BP
950} // DatabaseDemoFrame::OnAbout()
951
108106cf 952
049977d0
GT
953// Put any additional checking necessary to make certain it is alright
954// to close the program here that is not done elsewhere
1fc5dd6f 955void DatabaseDemoFrame::OnCloseWindow(wxCloseEvent& event)
108106cf 956{
3f755e2d 957 // Clean up time
3ca6a5f0 958 if (pEditorDlg && pEditorDlg->Close())
3f755e2d
GT
959 pEditorDlg = NULL;
960 else
f6bcfd97 961 {
3ca6a5f0
BP
962 if (pEditorDlg)
963 {
964 event.Veto();
965 return;
966 }
f6bcfd97
BP
967 }
968
ea24eeb2
GT
969 wxDELETE(wxGetApp().Contact);
970
3ca6a5f0
BP
971 // This function will close all the connections to the database that have been
972 // previously cached.
973 wxDbCloseConnections();
974
049977d0
GT
975 // Deletion of the wxDbConnectInf instance must be the LAST thing done that
976 // has anything to do with the database. Deleting this before disconnecting,
977 // freeing/closing connections, etc will result in a crash!
ea24eeb2 978 wxDELETE(wxGetApp().DbConnectInf);
3f755e2d 979
1fc5dd6f 980 this->Destroy();
3f755e2d 981
e3065973 982} // DatabaseDemoFrame::OnCloseWindow()
108106cf
JS
983
984
108106cf
JS
985void DatabaseDemoFrame::BuildEditorDialog()
986{
3ca6a5f0 987 pEditorDlg = NULL;
e70e8f4c 988 pEditorDlg = new CeditorDlg(this);
3ca6a5f0
BP
989 if (pEditorDlg)
990 {
991 pEditorDlg->Initialize();
992 if (!pEditorDlg->initialized)
993 {
994 pEditorDlg->Close();
973f2539 995 pEditorDlg = NULL;
94613352 996 wxMessageBox(wxT("Unable to initialize the editor dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
049977d0 997 Close();
3ca6a5f0 998 }
925e9792 999 }
3ca6a5f0
BP
1000 else
1001 {
94613352 1002 wxMessageBox(wxT("Unable to create the editor dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
049977d0 1003 Close();
3ca6a5f0 1004 }
108106cf
JS
1005} // DatabaseDemoFrame::BuildEditorDialog()
1006
1007
1008void DatabaseDemoFrame::BuildParameterDialog(wxWindow *parent)
1009{
e70e8f4c 1010 pParamDlg = new CparameterDlg(parent);
108106cf 1011
e70e8f4c 1012 if (!pParamDlg)
94613352 1013 wxMessageBox(wxT("Unable to create the parameter dialog for some reason"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
108106cf
JS
1014} // DatabaseDemoFrame::BuildParameterDialog()
1015
1016
1017/*
f6bcfd97 1018 * Constructor note: If no wxDb object is passed in, a new connection to the database
108106cf
JS
1019 * is created for this instance of Ccontact. This can be a slow process depending
1020 * on the database engine being used, and some database engines have a limit on the
925e9792
WS
1021 * number of connections (either hard limits, or license restricted) so care should
1022 * be used to use as few connections as is necessary.
e70e8f4c 1023 *
925e9792
WS
1024 * IMPORTANT: Objects which share a wxDb pointer are ALL acted upon whenever a member
1025 * function of pDb is called (i.e. CommitTrans() or RollbackTrans(), so if modifying
108106cf
JS
1026 * or creating a table objects which use the same pDb, know that all the objects
1027 * will be committed or rolled back when any of the objects has this function call made.
1028 */
049977d0 1029Ccontact::Ccontact (wxDb *pwxDb) : wxDbTable(pwxDb ? pwxDb : wxDbGetConnection(wxGetApp().DbConnectInf),
c3677ad3 1030 CONTACT_TABLE_NAME, CONTACT_NO_COLS, (const wxString &)wxEmptyString,
049977d0 1031 !wxDB_QUERY_ONLY, wxGetApp().DbConnectInf->GetDefaultDir())
108106cf 1032{
e70e8f4c
GT
1033 // This is used to represent whether the database connection should be released
1034 // when this instance of the object is deleted. If using the same connection
925e9792 1035 // for multiple instance of database objects, then the connection should only be
e70e8f4c 1036 // released when the last database instance using the connection is deleted
f6bcfd97 1037 freeDbConn = !pwxDb;
925e9792 1038
3fe813a9
GT
1039 if (GetDb())
1040 GetDb()->SetSqlLogging(sqlLogON);
1041
e70e8f4c 1042 SetupColumns();
108106cf
JS
1043
1044} // Ccontact Constructor
1045
1046
1047void Ccontact::Initialize()
1048{
e70e8f4c
GT
1049 Name[0] = 0;
1050 Addr1[0] = 0;
1051 Addr2[0] = 0;
1052 City[0] = 0;
1053 State[0] = 0;
1054 PostalCode[0] = 0;
1055 Country[0] = 0;
1056 JoinDate.year = 1980;
1057 JoinDate.month = 1;
1058 JoinDate.day = 1;
1059 JoinDate.hour = 0;
1060 JoinDate.minute = 0;
1061 JoinDate.second = 0;
1062 JoinDate.fraction = 0;
1063 NativeLanguage = langENGLISH;
6d841efd 1064 IsDeveloper = false;
e70e8f4c
GT
1065 Contributions = 0;
1066 LinesOfCode = 0L;
da1e87c4
GT
1067 BlobSize = 0L;
1068 memset(Picture, 0, MAX_PICTURE_SIZE);
108106cf
JS
1069} // Ccontact::Initialize
1070
1071
1072Ccontact::~Ccontact()
1073{
e70e8f4c
GT
1074 if (freeDbConn)
1075 {
f6bcfd97 1076 if (!wxDbFreeConnection(GetDb()))
e70e8f4c
GT
1077 {
1078 wxString tStr;
f21b2fd8
GT
1079 tStr = wxT("Unable to Free the Ccontact data table handle\n\n");
1080
74de91cc 1081 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1082 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
1083 }
1084 }
108106cf
JS
1085} // Ccontract destructor
1086
1087
1088/*
f6bcfd97 1089 * Handles setting up all the connections for the interface from the wxDbTable
925e9792 1090 * functions to interface to the data structure used to store records in
108106cf
JS
1091 * memory, and for all the column definitions that define the table structure
1092 */
f21b2fd8 1093void Ccontact::SetupColumns()
108106cf 1094{
e70e8f4c
GT
1095 // NOTE: Columns now are 8 character names, as that is all dBase can support. Longer
1096 // names can be used for other database engines
da1e87c4
GT
1097 SetColDefs ( 0,wxT("NAME"), DB_DATA_TYPE_VARCHAR, Name, SQL_C_WXCHAR, sizeof(Name), true, true); // Primary index
1098 SetColDefs ( 1,wxT("ADDRESS1"), DB_DATA_TYPE_VARCHAR, Addr1, SQL_C_WXCHAR, sizeof(Addr1), false,true);
1099 SetColDefs ( 2,wxT("ADDRESS2"), DB_DATA_TYPE_VARCHAR, Addr2, SQL_C_WXCHAR, sizeof(Addr2), false,true);
1100 SetColDefs ( 3,wxT("CITY"), DB_DATA_TYPE_VARCHAR, City, SQL_C_WXCHAR, sizeof(City), false,true);
1101 SetColDefs ( 4,wxT("STATE"), DB_DATA_TYPE_VARCHAR, State, SQL_C_WXCHAR, sizeof(State), false,true);
1102 SetColDefs ( 5,wxT("POSTCODE"), DB_DATA_TYPE_VARCHAR, PostalCode, SQL_C_WXCHAR, sizeof(PostalCode), false,true);
1103 SetColDefs ( 6,wxT("COUNTRY"), DB_DATA_TYPE_VARCHAR, Country, SQL_C_WXCHAR, sizeof(Country), false,true);
6d841efd
WS
1104 SetColDefs ( 7,wxT("JOINDATE"), DB_DATA_TYPE_DATE, &JoinDate, SQL_C_TIMESTAMP, sizeof(JoinDate), false,true);
1105 SetColDefs ( 8,wxT("IS_DEV"), DB_DATA_TYPE_INTEGER, &IsDeveloper, SQL_C_BOOLEAN(IsDeveloper), sizeof(IsDeveloper), false,true);
1106 SetColDefs ( 9,wxT("CONTRIBS"), DB_DATA_TYPE_INTEGER, &Contributions, SQL_C_UTINYINT, sizeof(Contributions), false,true);
1107 SetColDefs (10,wxT("LINE_CNT"), DB_DATA_TYPE_INTEGER, &LinesOfCode, SQL_C_ULONG, sizeof(LinesOfCode), false,true);
1108 SetColDefs (11,wxT("LANGUAGE"), DB_DATA_TYPE_INTEGER, &NativeLanguage, SQL_C_ENUM, sizeof(NativeLanguage), false,true);
dd5b579c 1109#ifdef wxODBC_BLOB_SUPPORT
da1e87c4
GT
1110 SetColDefs (12,wxT("PICSIZE"), DB_DATA_TYPE_INTEGER, &BlobSize, SQL_C_ULONG, sizeof(BlobSize), false,true);
1111 SetColDefs (13,wxT("PICTURE"), DB_DATA_TYPE_BLOB, Picture, SQL_C_BINARY, sizeof(Picture), false,true);
3fe813a9 1112#endif
108106cf
JS
1113} // Ccontact::SetupColumns
1114
1115
69a2b59d 1116bool Ccontact::CreateIndexes(bool recreate)
108106cf 1117{
925e9792 1118 // This index could easily be accomplished with an "orderBy" clause,
e70e8f4c
GT
1119 // but is done to show how to construct a non-primary index.
1120 wxString indexName;
f6bcfd97 1121 wxDbIdxDef idxDef[2];
108106cf 1122
74de91cc 1123 wxStrcpy(idxDef[0].ColName, wxT("IS_DEV"));
6d841efd 1124 idxDef[0].Ascending = true;
108106cf 1125
74de91cc 1126 wxStrcpy(idxDef[1].ColName, wxT("NAME"));
6d841efd 1127 idxDef[1].Ascending = true;
108106cf 1128
f6bcfd97 1129 indexName = GetTableName();
74de91cc 1130 indexName += wxT("_IDX1");
108106cf 1131
6d841efd
WS
1132 return CreateIndex(indexName.c_str(), true, 2, idxDef, recreate);
1133
108106cf
JS
1134} // Ccontact::CreateIndexes()
1135
1136
1137/*
1138 * Having a function to do a query on the primary key (and possibly others) is
1139 * very efficient and tighter coding so that it is available where ever the object
1140 * is. Great for use with multiple tables when not using views or outer joins
1141 */
049977d0 1142bool Ccontact::FetchByName(const wxString &name)
108106cf 1143{
24e2b35d 1144 whereStr.Printf(wxT("NAME = '%s'"),name.c_str());
f6bcfd97 1145 SetWhereClause(whereStr.c_str());
da1e87c4 1146 SetOrderByClause(wxEmptyString);
108106cf 1147
e70e8f4c 1148 if (!Query())
6d841efd 1149 return(false);
108106cf 1150
e70e8f4c
GT
1151 // Fetch the record
1152 return(GetNext());
108106cf
JS
1153
1154} // Ccontact::FetchByName()
1155
1156
1157/*
1158 *
1159 * ************* DIALOGS ***************
1160 *
1161 */
1162
1163
1164/* CeditorDlg constructor
1165 *
1166 * Creates the dialog used for creating/editing/deleting/copying a Ccontact object.
1167 * This dialog actually is drawn in the main frame of the program
1168 *
1169 * An instance of Ccontact is created - "Contact" - which is used to hold the Ccontact
1170 * object that is currently being worked with.
1171 */
925e9792 1172
f6fcbb63 1173BEGIN_EVENT_TABLE(CeditorDlg, wxPanel)
6d841efd 1174 EVT_BUTTON(wxID_ANY, CeditorDlg::OnButton)
3f755e2d 1175 EVT_CLOSE(CeditorDlg::OnCloseWindow)
f6fcbb63 1176END_EVENT_TABLE()
925e9792 1177
da1e87c4 1178CeditorDlg::CeditorDlg(wxWindow *parent) : wxPanel (parent, 0, 0, 537, 530)
108106cf 1179{
e70e8f4c
GT
1180 // Since the ::OnCommand() function is overridden, this prevents the widget
1181 // detection in ::OnCommand() until all widgets have been initialized to prevent
1182 // uninitialized pointers from crashing the program
6d841efd 1183 widgetPtrsSet = false;
e70e8f4c 1184
6d841efd 1185 initialized = false;
e70e8f4c 1186
3fe813a9
GT
1187 SetMode(mView);
1188
6d841efd 1189 Show(false);
108106cf
JS
1190} // CeditorDlg constructor
1191
1192
e3065973 1193void CeditorDlg::OnCloseWindow(wxCloseEvent& event)
108106cf 1194{
e70e8f4c 1195 // Clean up time
3f755e2d 1196 if ((mode != mCreate) && (mode != mEdit))
e70e8f4c 1197 {
e70e8f4c
GT
1198 this->Destroy();
1199 }
1200 else
1201 {
94613352 1202 wxMessageBox(wxT("Must finish processing the current record being created/modified before exiting"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
e70e8f4c
GT
1203 event.Veto();
1204 }
e3065973 1205} // CeditorDlg::OnCloseWindow()
108106cf
JS
1206
1207
3ca6a5f0 1208void CeditorDlg::OnButton(wxCommandEvent &event)
f6fcbb63 1209{
3ca6a5f0
BP
1210 wxWindow *win = (wxWindow*) event.GetEventObject();
1211 OnCommand( *win, event );
1212} // CeditorDlg::OnButton()
f6fcbb63 1213
65d7ddc4 1214
74de91cc 1215void CeditorDlg::OnCommand(wxWindow& win, wxCommandEvent& WXUNUSED(event))
108106cf 1216{
e70e8f4c 1217 wxString widgetName;
925e9792 1218
e70e8f4c
GT
1219 widgetName = win.GetName();
1220
1221 if (!widgetPtrsSet)
1222 return;
1223
1224 if (widgetName == pCreateBtn->GetName())
1225 {
ea24eeb2 1226 wxGetApp().Contact->Initialize();
e70e8f4c
GT
1227 PutData();
1228 SetMode( mCreate );
da1e87c4 1229 pNameTxt->SetValue(wxEmptyString);
e70e8f4c
GT
1230 pNameTxt->SetFocus();
1231 return;
1232 }
1233
1234 if (widgetName == pEditBtn->GetName())
1235 {
ea24eeb2 1236 saveName = wxGetApp().Contact->Name;
e70e8f4c
GT
1237 SetMode( mEdit );
1238 pNameTxt->SetFocus();
1239 return;
1240 }
1241
1242 if (widgetName == pCopyBtn->GetName())
1243 {
1244 SetMode(mCreate);
da1e87c4 1245 pNameTxt->SetValue(wxEmptyString);
e70e8f4c
GT
1246 pNameTxt->SetFocus();
1247 return;
1248 }
1249
1250 if (widgetName == pDeleteBtn->GetName())
1251 {
94613352 1252 bool Ok = (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
e70e8f4c
GT
1253
1254 if (!Ok)
1255 return;
1256
ea24eeb2 1257 if (Ok && wxGetApp().Contact->Delete())
e70e8f4c 1258 {
925e9792
WS
1259 // NOTE: Deletions are not finalized until a CommitTrans() is performed.
1260 // If the commit were not performed, the program will continue to
e70e8f4c 1261 // show the table contents as if they were deleted until this instance
925e9792 1262 // of Ccontact is deleted. If the Commit wasn't performed, the
e70e8f4c
GT
1263 // database will automatically Rollback the changes when the database
1264 // connection is terminated
ea24eeb2 1265 wxGetApp().Contact->GetDb()->CommitTrans();
e70e8f4c
GT
1266
1267 // Try to get the row that followed the just deleted row in the orderBy sequence
1268 if (!GetNextRec())
1269 {
1270 // There was now row (in sequence) after the just deleted row, so get the
1271 // row which preceded the just deleted row
1272 if (!GetPrevRec())
1273 {
1274 // There are now no rows remaining, so clear the dialog widgets
ea24eeb2 1275 wxGetApp().Contact->Initialize();
e70e8f4c
GT
1276 PutData();
1277 }
1278 }
1279 SetMode(mode); // force reset of button enable/disable
1280 }
1281 else
1282 // Delete failed
ea24eeb2 1283 wxGetApp().Contact->GetDb()->RollbackTrans();
e70e8f4c
GT
1284
1285 SetMode(mView);
1286 return;
1287 }
1288
1289 if (widgetName == pSaveBtn->GetName())
1290 {
1291 Save();
1292 return;
1293 }
1294
1295 if (widgetName == pCancelBtn->GetName())
1296 {
94613352 1297 bool Ok = (wxMessageBox(wxT("Are you sure?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
e70e8f4c
GT
1298
1299 if (!Ok)
1300 return;
1301
51e298bb 1302 if (saveName.empty())
e70e8f4c 1303 {
ea24eeb2 1304 wxGetApp().Contact->Initialize();
e70e8f4c
GT
1305 PutData();
1306 SetMode(mView);
1307 return;
1308 }
1309 else
1310 {
1311 // Requery previous record
ea24eeb2 1312 if (wxGetApp().Contact->FetchByName(saveName))
e70e8f4c
GT
1313 {
1314 PutData();
1315 SetMode(mView);
1316 return;
1317 }
1318 }
1319
1320 // Previous record not available, retrieve first record in table
ea24eeb2
GT
1321 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1322 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
e70e8f4c 1323 {
ea24eeb2
GT
1324 wxGetApp().Contact->whereStr = wxT("NAME = (SELECT MIN(NAME) FROM ");
1325 wxGetApp().Contact->whereStr += wxGetApp().Contact->GetTableName();
1326 wxGetApp().Contact->whereStr += wxT(")");
1327 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
e70e8f4c
GT
1328 }
1329 else
da1e87c4 1330 wxGetApp().Contact->SetWhereClause(wxEmptyString);
e70e8f4c 1331
ea24eeb2 1332 if (!wxGetApp().Contact->Query())
e70e8f4c
GT
1333 {
1334 wxString tStr;
f21b2fd8 1335 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 1336 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1337 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
925e9792 1338
e70e8f4c
GT
1339 SetMode(mView);
1340 return;
1341 }
ea24eeb2 1342 if (wxGetApp().Contact->GetNext()) // Successfully read first record
e70e8f4c
GT
1343 {
1344 PutData();
1345 SetMode(mView);
1346 return;
1347 }
1348 // No contacts are available, clear dialog
ea24eeb2 1349 wxGetApp().Contact->Initialize();
e70e8f4c
GT
1350 PutData();
1351 SetMode(mView);
1352 return;
1353 } // Cancel Button
1354
1355 if (widgetName == pPrevBtn->GetName())
1356 {
1357 if (!GetPrevRec())
1358 wxBell();
1359 return;
1360 } // Prev Button
1361
1362 if (widgetName == pNextBtn->GetName())
1363 {
1364 if (!GetNextRec())
1365 wxBell();
1366 return;
1367 } // Next Button
1368
1369 if (widgetName == pQueryBtn->GetName())
1370 {
1371 // Display the query dialog box
94613352 1372 wxChar qryWhere[DB_MAX_WHERE_CLAUSE_LEN+1];
ea24eeb2 1373 wxStrcpy(qryWhere, (const wxChar*) wxGetApp().Contact->qryWhereStr);
c3677ad3 1374 wxChar *tblName[] = {(wxChar *)CONTACT_TABLE_NAME.c_str(), 0};
ea24eeb2 1375 new CqueryDlg(GetParent(), wxGetApp().Contact->GetDb(), tblName, qryWhere);
e70e8f4c
GT
1376
1377 // Query the first record in the new record set and
1378 // display it, if the query string has changed.
ea24eeb2 1379 if (wxStrcmp(qryWhere, (const wxChar*) wxGetApp().Contact->qryWhereStr))
e70e8f4c 1380 {
ea24eeb2 1381 wxGetApp().Contact->whereStr.Empty();
74de91cc 1382 wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
e70e8f4c 1383
ea24eeb2
GT
1384 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1385 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
e70e8f4c 1386 {
ea24eeb2
GT
1387 wxGetApp().Contact->whereStr = wxT("NAME = (SELECT MIN(NAME) FROM ");
1388 wxGetApp().Contact->whereStr += CONTACT_TABLE_NAME;
e70e8f4c 1389 }
925e9792 1390
e70e8f4c 1391 // Append the query where string (if there is one)
ea24eeb2 1392 wxGetApp().Contact->qryWhereStr = qryWhere;
f6bcfd97 1393 if (wxStrlen(qryWhere))
e70e8f4c 1394 {
ea24eeb2
GT
1395 wxGetApp().Contact->whereStr += wxT(" WHERE ");
1396 wxGetApp().Contact->whereStr += wxGetApp().Contact->qryWhereStr;
e70e8f4c
GT
1397 }
1398 // Close the expression with a right paren
ea24eeb2 1399 wxGetApp().Contact->whereStr += wxT(")");
e70e8f4c 1400 // Requery the table
ea24eeb2
GT
1401 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
1402 if (!wxGetApp().Contact->Query())
e70e8f4c
GT
1403 {
1404 wxString tStr;
f21b2fd8 1405 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 1406 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8
GT
1407 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
1408
e70e8f4c
GT
1409 return;
1410 }
1411 // Display the first record from the query set
ea24eeb2
GT
1412 if (!wxGetApp().Contact->GetNext())
1413 wxGetApp().Contact->Initialize();
e70e8f4c
GT
1414 PutData();
1415 }
1416
1417 // Enable/Disable the reset button
51e298bb 1418 pResetBtn->Enable(!wxGetApp().Contact->qryWhereStr.empty());
e70e8f4c
GT
1419
1420 return;
1421 } // Query button
1422
1423
1424 if (widgetName == pResetBtn->GetName())
1425 {
1426 // Clear the additional where criteria established by the query feature
da1e87c4 1427 wxGetApp().Contact->qryWhereStr = wxEmptyString;
ea24eeb2 1428 wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
e70e8f4c 1429
ea24eeb2
GT
1430 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1431 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
e70e8f4c 1432 {
ea24eeb2
GT
1433 wxGetApp().Contact->whereStr = wxT("NAME = (SELECT MIN(NAME) FROM ");
1434 wxGetApp().Contact->whereStr += CONTACT_TABLE_NAME;
1435 wxGetApp().Contact->whereStr += wxT(")");
e70e8f4c
GT
1436 }
1437
ea24eeb2
GT
1438 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr.c_str());
1439 if (!wxGetApp().Contact->Query())
e70e8f4c
GT
1440 {
1441 wxString tStr;
f21b2fd8 1442 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 1443 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1444 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
1445 return;
1446 }
ea24eeb2
GT
1447 if (!wxGetApp().Contact->GetNext())
1448 wxGetApp().Contact->Initialize();
e70e8f4c 1449 PutData();
6d841efd 1450 pResetBtn->Enable(false);
e70e8f4c
GT
1451
1452 return;
1453 } // Reset button
1454
1455
1456 if (widgetName == pNameListBtn->GetName())
1457 {
c3677ad3
GT
1458 new ClookUpDlg(/* wxWindow *parent */ this,
1459 /* const wxString &windowTitle */ wxT("Select contact name"),
1460 /* const wxString &tableName */ CONTACT_TABLE_NAME,
1461 /* const wxString &dispCol1 */ wxT("NAME"),
1462 /* const wxString &dispCol2 */ wxT("JOINDATE"),
1463 /* const wxString &where */ wxT(""),
1464 /* const wxString &orderBy */ wxT("NAME"),
1465 /* wxDb *pDb */ wxGetApp().READONLY_DB,
1466 /* const wxString &defDir */ wxGetApp().DbConnectInf->GetDefaultDir(),
21971771
GT
1467 /* bool distinctValues*/ true,
1468 wxEmptyString, 20);
e70e8f4c 1469
f6bcfd97 1470 if (ListDB_Selection && wxStrlen(ListDB_Selection))
e70e8f4c 1471 {
94613352 1472 wxString w = wxT("NAME = '");
e70e8f4c 1473 w += ListDB_Selection;
94613352 1474 w += wxT("'");
049977d0 1475 GetRec(w);
e70e8f4c
GT
1476 }
1477
1478 return;
1479 }
3f030b48
GT
1480
1481 if (widgetName == pDataTypesBtn->GetName())
1482 {
1483 CheckSupportForAllDataTypes(wxGetApp().READONLY_DB);
74de91cc 1484 wxMessageBox(wxT("Support datatypes was dumped to stdout."));
3f030b48
GT
1485 return;
1486 } // Data types Button
1487
1488 if (widgetName == pDbDiagsBtn->GetName())
1489 {
1490 DisplayDbDiagnostics(wxGetApp().READONLY_DB);
74de91cc 1491 wxMessageBox(wxT("Diagnostics info was dumped to stdout."));
69a2b59d
GT
1492 return;
1493 }
1494
1495 if (widgetName == pCatalogBtn->GetName())
1496 {
da1e87c4 1497 if (wxGetApp().Contact->GetDb()->Catalog(wxEmptyString, wxT("catalog.txt")))
74de91cc 1498 wxMessageBox(wxT("The file 'catalog.txt' was created."));
69a2b59d 1499 else
856e0fa4 1500 wxMessageBox(wxT("Creation of the file 'catalog.txt' failed."));
3f030b48
GT
1501 return;
1502 }
1503
da1e87c4
GT
1504#ifdef wxODBC_BLOB_SUPPORT
1505 if (widgetName == pChooseImageBtn->GetName())
1506 {
1507 OnSelectPict();
1508 }
1509
1510 if (widgetName == pShowImageBtn->GetName())
1511 {
1512 OnShowImage();
1513 }
1514#endif
1515
108106cf
JS
1516} // CeditorDlg::OnCommand()
1517
1518
3ca6a5f0
BP
1519bool CeditorDlg::Initialize()
1520{
925e9792 1521 // Create the data structure and a new database connection.
3ca6a5f0
BP
1522 // (As there is not a pDb being passed in the constructor, a new database
1523 // connection is created)
ea24eeb2 1524 wxGetApp().Contact = new Ccontact();
3ca6a5f0 1525
ea24eeb2 1526 if (!wxGetApp().Contact)
3ca6a5f0 1527 {
94613352 1528 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
6d841efd 1529 return false;
3ca6a5f0
BP
1530 }
1531
925e9792 1532 // Check if the table exists or not. If it doesn't, ask the user if they want to
3ca6a5f0 1533 // create the table. Continue trying to create the table until it exists, or user aborts
c3677ad3 1534 while (!wxGetApp().Contact->GetDb()->TableExists(CONTACT_TABLE_NAME,
925e9792 1535 wxGetApp().DbConnectInf->GetUserID(),
049977d0 1536 wxGetApp().DbConnectInf->GetDefaultDir()))
3ca6a5f0
BP
1537 {
1538 wxString tStr;
51e298bb 1539 tStr.Printf(wxT("Unable to open the table '%s'. The table may\nneed to be created.\n\nDo you wish to try to create/clear the table?\n\n"),CONTACT_TABLE_NAME.c_str());
f21b2fd8 1540 bool createTable = (wxMessageBox(tStr.c_str(),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
3ca6a5f0
BP
1541
1542 if (!createTable)
1543 {
1544// Close();
6d841efd 1545 return false;
3ca6a5f0
BP
1546 }
1547 else
6d841efd 1548 wxGetApp().CreateDataTable(false);
3ca6a5f0
BP
1549 }
1550
1551 // Tables must be "opened" before anything other than creating/deleting table can be done
ea24eeb2 1552 if (!wxGetApp().Contact->Open())
3ca6a5f0
BP
1553 {
1554 // Table does exist, or there was some problem opening it. Currently this should
973f2539 1555 // never fail, except in the case of the table not exisiting or the current
3ca6a5f0 1556 // user has insufficent privileges to access the table
3fe813a9 1557#if 1
3ca6a5f0
BP
1558// This code is experimenting with a new function that will hopefully be available
1559// in the 2.4 release. This check will determine whether the open failing was due
1560// to the table not existing, or the users privileges being insufficient to
1561// open the table.
ea24eeb2
GT
1562 if (!wxGetApp().Contact->GetDb()->TablePrivileges(CONTACT_TABLE_NAME, wxT("SELECT"),
1563 wxGetApp().Contact->GetDb()->GetUsername(),
69a2b59d
GT
1564 wxGetApp().Contact->GetDb()->GetUsername(),
1565 wxGetApp().DbConnectInf->GetDefaultDir()))
3ca6a5f0
BP
1566 {
1567 wxString tStr;
51e298bb 1568 tStr.Printf(wxT("Unable to open the table '%s' (likely due to\ninsufficient privileges of the logged in user).\n\n"),CONTACT_TABLE_NAME.c_str());
f21b2fd8 1569
74de91cc 1570 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1571 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
3ca6a5f0 1572 }
925e9792 1573 else
3ca6a5f0 1574#endif
ea24eeb2
GT
1575 if (!wxGetApp().Contact->GetDb()->TableExists(CONTACT_TABLE_NAME,
1576 wxGetApp().Contact->GetDb()->GetUsername(),
3fe813a9 1577 wxGetApp().DbConnectInf->GetDefaultDir()))
3ca6a5f0
BP
1578 {
1579 wxString tStr;
51e298bb 1580 tStr.Printf(wxT("Unable to open the table '%s' as the table\ndoes not appear to exist in the tablespace available\nto the currently logged in user.\n\n"),CONTACT_TABLE_NAME.c_str());
74de91cc 1581 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1582 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
3ca6a5f0
BP
1583 }
1584
6d841efd 1585 return false;
3ca6a5f0
BP
1586 }
1587
1588 // Build the dialog
1589
da1e87c4
GT
1590 (void)new wxStaticBox(this, EDITOR_DIALOG_FN_GROUP, wxEmptyString, wxPoint(15, 1), wxSize(497, 69), 0, wxT("FunctionGrp"));
1591 (void)new wxStaticBox(this, EDITOR_DIALOG_SEARCH_GROUP, wxEmptyString, wxPoint(417, 1), wxSize(95, 242), 0, wxT("SearchGrp"));
94613352
GT
1592
1593 pCreateBtn = new wxButton(this, EDITOR_DIALOG_CREATE, wxT("&Create"), wxPoint( 25, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CreateBtn"));
1594 pEditBtn = new wxButton(this, EDITOR_DIALOG_EDIT, wxT("&Edit"), wxPoint(102, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("EditBtn"));
1595 pDeleteBtn = new wxButton(this, EDITOR_DIALOG_DELETE, wxT("&Delete"), wxPoint(179, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("DeleteBtn"));
1596 pCopyBtn = new wxButton(this, EDITOR_DIALOG_COPY, wxT("Cop&y"), wxPoint(256, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CopyBtn"));
1597 pSaveBtn = new wxButton(this, EDITOR_DIALOG_SAVE, wxT("&Save"), wxPoint(333, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("SaveBtn"));
1598 pCancelBtn = new wxButton(this, EDITOR_DIALOG_CANCEL, wxT("C&ancel"), wxPoint(430, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CancelBtn"));
1599 pPrevBtn = new wxButton(this, EDITOR_DIALOG_PREV, wxT("<< &Prev"), wxPoint(430, 81), wxSize( 70, 35), 0, wxDefaultValidator, wxT("PrevBtn"));
1600 pNextBtn = new wxButton(this, EDITOR_DIALOG_NEXT, wxT("&Next >>"), wxPoint(430, 121), wxSize( 70, 35), 0, wxDefaultValidator, wxT("NextBtn"));
1601 pQueryBtn = new wxButton(this, EDITOR_DIALOG_QUERY, wxT("&Query"), wxPoint(430, 161), wxSize( 70, 35), 0, wxDefaultValidator, wxT("QueryBtn"));
1602 pResetBtn = new wxButton(this, EDITOR_DIALOG_RESET, wxT("&Reset"), wxPoint(430, 200), wxSize( 70, 35), 0, wxDefaultValidator, wxT("ResetBtn"));
6d841efd 1603 pNameMsg = new wxStaticText(this, EDITOR_DIALOG_NAME_MSG, wxT("Name:"), wxPoint( 17, 80), wxDefaultSize, 0, wxT("NameMsg"));
da1e87c4 1604 pNameTxt = new wxTextCtrl(this, EDITOR_DIALOG_NAME_TEXT, wxEmptyString, wxPoint( 17, 97), wxSize(308, 25), 0, wxDefaultValidator, wxT("NameTxt"));
94613352 1605 pNameListBtn = new wxButton(this, EDITOR_DIALOG_LOOKUP, wxT("&Lookup"), wxPoint(333, 97), wxSize( 70, 24), 0, wxDefaultValidator, wxT("LookupBtn"));
6d841efd 1606 pAddress1Msg = new wxStaticText(this, EDITOR_DIALOG_ADDRESS1_MSG, wxT("Address:"), wxPoint( 17, 130), wxDefaultSize, 0, wxT("Address1Msg"));
da1e87c4 1607 pAddress1Txt = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT, wxEmptyString, wxPoint( 17, 147), wxSize(308, 25), 0, wxDefaultValidator, wxT("Address1Txt"));
6d841efd 1608 pAddress2Msg = new wxStaticText(this, EDITOR_DIALOG_ADDRESS2_MSG, wxT("Address:"), wxPoint( 17, 180), wxDefaultSize, 0, wxT("Address2Msg"));
da1e87c4 1609 pAddress2Txt = new wxTextCtrl(this, EDITOR_DIALOG_ADDRESS2_TEXT, wxEmptyString, wxPoint( 17, 197), wxSize(308, 25), 0, wxDefaultValidator, wxT("Address2Txt"));
6d841efd 1610 pCityMsg = new wxStaticText(this, EDITOR_DIALOG_CITY_MSG, wxT("City:"), wxPoint( 17, 230), wxDefaultSize, 0, wxT("CityMsg"));
da1e87c4 1611 pCityTxt = new wxTextCtrl(this, EDITOR_DIALOG_CITY_TEXT, wxEmptyString, wxPoint( 17, 247), wxSize(225, 25), 0, wxDefaultValidator, wxT("CityTxt"));
6d841efd 1612 pStateMsg = new wxStaticText(this, EDITOR_DIALOG_STATE_MSG, wxT("State:"), wxPoint(250, 230), wxDefaultSize, 0, wxT("StateMsg"));
da1e87c4 1613 pStateTxt = new wxTextCtrl(this, EDITOR_DIALOG_STATE_TEXT, wxEmptyString, wxPoint(250, 247), wxSize(153, 25), 0, wxDefaultValidator, wxT("StateTxt"));
6d841efd 1614 pCountryMsg = new wxStaticText(this, EDITOR_DIALOG_COUNTRY_MSG, wxT("Country:"), wxPoint( 17, 280), wxDefaultSize, 0, wxT("CountryMsg"));
da1e87c4 1615 pCountryTxt = new wxTextCtrl(this, EDITOR_DIALOG_COUNTRY_TEXT, wxEmptyString, wxPoint( 17, 297), wxSize(225, 25), 0, wxDefaultValidator, wxT("CountryTxt"));
6d841efd 1616 pPostalCodeMsg = new wxStaticText(this, EDITOR_DIALOG_POSTAL_MSG, wxT("Postal Code:"),wxPoint(250, 280), wxDefaultSize, 0, wxT("PostalCodeMsg"));
da1e87c4 1617 pPostalCodeTxt = new wxTextCtrl(this, EDITOR_DIALOG_POSTAL_TEXT, wxEmptyString, wxPoint(250, 297), wxSize(153, 25), 0, wxDefaultValidator, wxT("PostalCodeTxt"));
3ca6a5f0
BP
1618
1619 wxString choice_strings[5];
94613352
GT
1620 choice_strings[0] = wxT("English");
1621 choice_strings[1] = wxT("French");
1622 choice_strings[2] = wxT("German");
1623 choice_strings[3] = wxT("Spanish");
1624 choice_strings[4] = wxT("Other");
3ca6a5f0 1625
422d0ff0 1626 pNativeLangChoice = new wxChoice(this, EDITOR_DIALOG_LANG_CHOICE, wxPoint( 17, 346), wxSize(277, wxDefaultCoord), 5, choice_strings);
6d841efd 1627 pNativeLangMsg = new wxStaticText(this, EDITOR_DIALOG_LANG_MSG, wxT("Native language:"), wxPoint( 17, 330), wxDefaultSize, 0, wxT("NativeLangMsg"));
3ca6a5f0
BP
1628
1629 wxString radio_strings[2];
94613352
GT
1630 radio_strings[0] = wxT("No");
1631 radio_strings[1] = wxT("Yes");
6d841efd
WS
1632 pDeveloperRadio = new wxRadioBox(this,EDITOR_DIALOG_DEVELOPER, wxT("Developer:"), wxPoint(303, 330), wxDefaultSize, 2, radio_strings, 2, wxHORIZONTAL);
1633 pJoinDateMsg = new wxStaticText(this, EDITOR_DIALOG_JOIN_MSG, wxT("Date joined:"), wxPoint( 17, 380), wxDefaultSize, 0, wxT("JoinDateMsg"));
da1e87c4 1634 pJoinDateTxt = new wxTextCtrl(this, EDITOR_DIALOG_JOIN_TEXT, wxEmptyString, wxPoint( 17, 397), wxSize(150, 25), 0, wxDefaultValidator, wxT("JoinDateTxt"));
6d841efd 1635 pContribMsg = new wxStaticText(this, EDITOR_DIALOG_CONTRIB_MSG,wxT("Contributions:"), wxPoint(175, 380), wxDefaultSize, 0, wxT("ContribMsg"));
da1e87c4 1636 pContribTxt = new wxTextCtrl(this, EDITOR_DIALOG_CONTRIB_TEXT, wxEmptyString, wxPoint(175, 397), wxSize(120, 25), 0, wxDefaultValidator, wxT("ContribTxt"));
6d841efd 1637 pLinesMsg = new wxStaticText(this, EDITOR_DIALOG_LINES_MSG, wxT("Lines of code:"), wxPoint(303, 380), wxDefaultSize, 0, wxT("LinesMsg"));
da1e87c4 1638 pLinesTxt = new wxTextCtrl(this, EDITOR_DIALOG_LINES_TEXT, wxEmptyString, wxPoint(303, 397), wxSize(100, 25), 0, wxDefaultValidator, wxT("LinesTxt"));
3ca6a5f0 1639
69a2b59d 1640 pCatalogBtn = new wxButton(this, EDITOR_DIALOG_CATALOG, wxT("Catalo&g"), wxPoint(430, 287), wxSize( 70, 35), 0, wxDefaultValidator, wxT("CatalogBtn"));
3f030b48
GT
1641 pDataTypesBtn = new wxButton(this, EDITOR_DIALOG_DATATYPES, wxT("Data&types"), wxPoint(430, 337), wxSize( 70, 35), 0, wxDefaultValidator, wxT("DataTypesBtn"));
1642 pDbDiagsBtn = new wxButton(this, EDITOR_DIALOG_DB_DIAGS, wxT("DB Dia&gs"), wxPoint(430, 387), wxSize( 70, 35), 0, wxDefaultValidator, wxT("DbDiagsBtn"));
1643
da1e87c4
GT
1644#ifdef wxODBC_BLOB_SUPPORT
1645 pPictureMsg = new wxStaticText(this, EDITOR_DIALOG_PIC_MSG, wxT("Picture:"), wxPoint( 17,430), wxDefaultSize, 0, wxT("PicMsg"));
1646 pPictSizeMsg = new wxStaticText(this, EDITOR_DIALOG_PICSIZE_MSG, wxT("Picture Bytes:"), wxPoint(175,430), wxDefaultSize, 0, wxT("PicSizeMsg"));
1647 pChooseImageBtn = new wxButton(this, EDITOR_DIALOG_PIC_BROWSE, wxT("Select..."), wxPoint( 17,447), wxSize( 70, 24), 0, wxDefaultValidator, wxT("PicBrowseBtn"));
1648 pShowImageBtn = new wxButton(this, EDITOR_DIALOG_PIC_SHOW, wxT("Show..."), wxPoint( 97,447), wxSize( 70, 24), 0, wxDefaultValidator, wxT("PictShowBtn"));
1649 pPictSizeTxt = new wxTextCtrl(this, EDITOR_DIALOG_PIC_SIZE_TEXT, wxEmptyString, wxPoint(175,447), wxSize(120, 25), 0, wxDefaultValidator, wxT("PictSizeTxt"));
1650#endif
1651
51e298bb 1652 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
3ca6a5f0 1653 // handle all widget processing
6d841efd 1654 widgetPtrsSet = true;
3ca6a5f0 1655
925e9792 1656 // Setup the orderBy and where clauses to return back a single record as the result set,
3ca6a5f0
BP
1657 // as there will only be one record being shown on the dialog at a time, this optimizes
1658 // network traffic by only returning a one row result
925e9792 1659
ea24eeb2 1660 wxGetApp().Contact->SetOrderByClause(wxT("NAME")); // field name to sort by
3ca6a5f0
BP
1661
1662 // The wxString "whereStr" is not a member of the wxDbTable object, it is a member variable
1663 // specifically in the Ccontact class. It is used here for simpler construction of a varying
1664 // length string, and then after the string is built, the wxDbTable member variable "where" is
1665 // assigned the pointer to the constructed string.
1666 //
925e9792 1667 // The constructed where clause below has a sub-query within it "SELECT MIN(NAME) FROM %s"
3ca6a5f0 1668 // to achieve a single row (in this case the first name in alphabetical order).
925e9792 1669
ea24eeb2
GT
1670 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
1671 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
3ca6a5f0 1672 {
ea24eeb2
GT
1673 wxGetApp().Contact->whereStr.Printf(wxT("NAME = (SELECT MIN(NAME) FROM %s)"),
1674 wxGetApp().Contact->GetTableName().c_str());
94613352 1675 // NOTE: (const wxChar*) returns a pointer which may not be valid later, so this is short term use only
ea24eeb2 1676 wxGetApp().Contact->SetWhereClause(wxGetApp().Contact->whereStr);
3ca6a5f0
BP
1677 }
1678 else
da1e87c4 1679 wxGetApp().Contact->SetWhereClause(wxEmptyString);
3ca6a5f0 1680
925e9792
WS
1681 // Perform the Query to get the result set.
1682 // NOTE: If there are no rows returned, that is a valid result, so Query() would return true.
6d841efd 1683 // Only if there is a database error will Query() come back as false
ea24eeb2 1684 if (!wxGetApp().Contact->Query())
3ca6a5f0
BP
1685 {
1686 wxString tStr;
f21b2fd8 1687 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 1688 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 1689 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
6d841efd 1690 return false;
3ca6a5f0
BP
1691 }
1692
1693 // Since Query succeeded, now get the row that was returned
ea24eeb2 1694 if (!wxGetApp().Contact->GetNext())
925e9792
WS
1695 // If the GetNext() failed at this point, then there are no rows to retrieve,
1696 // so clear the values in the members of "Contact" so that PutData() blanks the
3ca6a5f0 1697 // widgets on the dialog
ea24eeb2
GT
1698 wxGetApp().Contact->Initialize();
1699/*
1700 wxGetApp().Contact->GetDb()->RollbackTrans();
1701*/
3ca6a5f0
BP
1702 SetMode(mView);
1703 PutData();
1704
6d841efd 1705 Show(true);
3ca6a5f0 1706
6d841efd
WS
1707 initialized = true;
1708 return true;
3ca6a5f0
BP
1709} // CeditorDlg::Initialize()
1710
da1e87c4
GT
1711#ifdef wxODBC_BLOB_SUPPORT
1712
1713void CeditorDlg::OnSelectPict()
1714{
ff3e84ff 1715 wxFileDialog dlg(this, wxT("Choose an image file less than 60K"), wxEmptyString, wxEmptyString, wxT("JPEG files (*.jpg)|*.jpg|GIF files (*.gif)|*.gif|BMP files (*.bmp)|*.bmp|All Files (*.*)|*.*"), wxFD_OPEN);
da1e87c4
GT
1716
1717 if (dlg.ShowModal() == wxID_OK)
1718 {
1719 wxFile file(dlg.GetPath());
1720
1721 if (file.IsOpened())
1722 {
f0fb3b3b
WS
1723 // assume not huge file in sample
1724 long iSize = (long)file.Length();
da1e87c4
GT
1725
1726 if ((iSize > 0) && (iSize < MAX_PICTURE_SIZE))
1727 {
79911be1 1728 wxGetApp().Contact->BlobSize = (size_t)iSize;
da1e87c4
GT
1729
1730 memset(wxGetApp().Contact->Picture, 0, MAX_PICTURE_SIZE);
1731
79911be1 1732 wxFileOffset iReadSize = file.Read(wxGetApp().Contact->Picture, (size_t)iSize);
da1e87c4
GT
1733
1734 if (iReadSize < iSize)
1735 wxMessageBox(wxT("Something bad happened while reading..."), wxT("BLOB Loading Error"), wxOK | wxICON_EXCLAMATION);
1736
1737 wxString tStr;
f0fb3b3b 1738 tStr.Printf(wxT("%ld"),iSize);
da1e87c4
GT
1739 pPictSizeTxt->SetValue(tStr);
1740 }
1741 else
1742 wxMessageBox(wxT("Selected File is TOO BIG. 60k is the max image size"), wxT("BLOB Loading Error"), wxOK | wxICON_EXCLAMATION);
1743 }
1744 else
1745 wxMessageBox(wxT("Unable to open the requested image file"), wxT("File Access Error"), wxOK | wxICON_EXCLAMATION);
1746 }
1747}
1748
1749void CeditorDlg::OnShowImage()
1750{
1751 if (wxGetApp().Contact->BlobSize > 0)
1752 {
1753 CimageDlg dlg(this, wxGetApp().Contact->Picture, wxGetApp().Contact->BlobSize);
1754
1755 dlg.ShowModal();
1756 }
1757}
1758
1759#endif
3ca6a5f0 1760
108106cf
JS
1761void CeditorDlg::FieldsEditable()
1762{
3fe813a9
GT
1763 if (!widgetPtrsSet)
1764 return;
1765
e70e8f4c
GT
1766 pNameTxt->Enable((mode == mCreate) || (mode == mEdit));
1767 pAddress1Txt->Enable((mode == mCreate) || (mode == mEdit));
1768 pAddress2Txt->Enable((mode == mCreate) || (mode == mEdit));
1769 pCityTxt->Enable((mode == mCreate) || (mode == mEdit));
1770 pStateTxt->Enable((mode == mCreate) || (mode == mEdit));
1771 pPostalCodeTxt->Enable((mode == mCreate) || (mode == mEdit));
1772 pCountryTxt->Enable((mode == mCreate) || (mode == mEdit));
1773
1774 pJoinDateTxt->Enable((mode == mCreate) || (mode == mEdit));
1775 pContribTxt->Enable((mode == mCreate) || (mode == mEdit));
1776 pLinesTxt->Enable((mode == mCreate) || (mode == mEdit));
1777 pNativeLangChoice->Enable((mode == mCreate) || (mode == mEdit));
1778 pDeveloperRadio->Enable((mode == mCreate) || (mode == mEdit));
108106cf 1779
da1e87c4
GT
1780#ifdef wxODBC_BLOB_SUPPORT
1781 pPictSizeTxt->Enable(false);
1782 pChooseImageBtn->Enable((mode == mCreate) || (mode == mEdit));
1783 pShowImageBtn->Enable(wxGetApp().Contact && wxGetApp().Contact->BlobSize > 0); //((mode == mCreate) || (mode == mEdit));
1784#endif
1785
108106cf
JS
1786} // CeditorDlg::FieldsEditable()
1787
1788
1789void CeditorDlg::SetMode(enum DialogModes m)
1790{
6d841efd 1791 bool edit = false;
e70e8f4c
GT
1792
1793 mode = m;
1794 switch (mode)
1795 {
1796 case mCreate:
1797 case mEdit:
6d841efd 1798 edit = true;
e70e8f4c
GT
1799 break;
1800 case mView:
1801 case mSearch:
6d841efd 1802 edit = false;
e70e8f4c
GT
1803 break;
1804 default:
1805 break;
1806 };
1807
1808 if (widgetPtrsSet)
1809 {
1810 pCreateBtn->Enable( !edit );
da1e87c4
GT
1811 pEditBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name, wxEmptyString) != 0) );
1812 pDeleteBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name, wxEmptyString)!=0) );
1813 pCopyBtn->Enable( !edit && (wxStrcmp(wxGetApp().Contact->Name, wxEmptyString)!=0) );
e70e8f4c
GT
1814 pSaveBtn->Enable( edit );
1815 pCancelBtn->Enable( edit );
1816 pPrevBtn->Enable( !edit );
1817 pNextBtn->Enable( !edit );
1818 pQueryBtn->Enable( !edit );
51e298bb 1819 pResetBtn->Enable( !edit && !wxGetApp().Contact->qryWhereStr.empty() );
e70e8f4c
GT
1820 pNameListBtn->Enable( !edit );
1821 }
1822
1823 FieldsEditable();
108106cf
JS
1824} // CeditorDlg::SetMode()
1825
1826
1fc5dd6f 1827bool CeditorDlg::PutData()
108106cf 1828{
e70e8f4c 1829 wxString tStr;
108106cf 1830
ea24eeb2
GT
1831 pNameTxt->SetValue(wxGetApp().Contact->Name);
1832 pAddress1Txt->SetValue(wxGetApp().Contact->Addr1);
1833 pAddress2Txt->SetValue(wxGetApp().Contact->Addr2);
1834 pCityTxt->SetValue(wxGetApp().Contact->City);
1835 pStateTxt->SetValue(wxGetApp().Contact->State);
1836 pCountryTxt->SetValue(wxGetApp().Contact->Country);
1837 pPostalCodeTxt->SetValue(wxGetApp().Contact->PostalCode);
108106cf 1838
ea24eeb2 1839 tStr.Printf(wxT("%d/%d/%d"),wxGetApp().Contact->JoinDate.month,wxGetApp().Contact->JoinDate.day,wxGetApp().Contact->JoinDate.year);
e70e8f4c 1840 pJoinDateTxt->SetValue(tStr);
108106cf 1841
ea24eeb2 1842 tStr.Printf(wxT("%d"),wxGetApp().Contact->Contributions);
e70e8f4c 1843 pContribTxt->SetValue(tStr);
108106cf 1844
ea24eeb2 1845 tStr.Printf(wxT("%lu"),wxGetApp().Contact->LinesOfCode);
e70e8f4c 1846 pLinesTxt->SetValue(tStr);
108106cf 1847
ea24eeb2 1848 pNativeLangChoice->SetSelection(wxGetApp().Contact->NativeLanguage);
108106cf 1849
ea24eeb2 1850 pDeveloperRadio->SetSelection(wxGetApp().Contact->IsDeveloper);
108106cf 1851
da1e87c4
GT
1852#ifdef wxODBC_BLOB_SUPPORT
1853 tStr.Printf(wxT("%lu"),wxGetApp().Contact->BlobSize);
1854 pPictSizeTxt->SetValue(tStr);
1855 pShowImageBtn->Enable(wxGetApp().Contact->BlobSize > 0);
1856#endif
1857
6d841efd 1858 return true;
108106cf
JS
1859} // Ceditor::PutData()
1860
1861
1862/*
1863 * Reads the data out of all the widgets on the dialog. Some data evaluation is done
1864 * to ensure that there is a name entered and that the date field is valid.
1865 *
6d841efd 1866 * A return value of true means that valid data was retrieved from the dialog, otherwise
108106cf
JS
1867 * invalid data was found (and a message was displayed telling the user what to fix), and
1868 * the data was not placed into the appropraite fields of Ccontact
1869 */
1fc5dd6f 1870bool CeditorDlg::GetData()
108106cf 1871{
e70e8f4c
GT
1872 // Validate that the data currently entered into the widgets is valid data
1873
1874 wxString tStr;
1875 tStr = pNameTxt->GetValue();
da1e87c4 1876 if (!wxStrcmp((const wxChar*) tStr, wxEmptyString))
e70e8f4c 1877 {
da1e87c4 1878 wxMessageBox(wxT("A name is required for entry into the contact table"), wxT("Notice..."), wxOK | wxICON_INFORMATION);
6d841efd 1879 return false;
e70e8f4c
GT
1880 }
1881
6d841efd 1882 bool invalid = false;
f369dd4f 1883 int mm = 1,dd = 1,yyyy = 2001;
e70e8f4c
GT
1884 int first, second;
1885
1886 tStr = pJoinDateTxt->GetValue();
94613352 1887 if (tStr.Freq(wxT('/')) != 2)
6d841efd 1888 invalid = true;
e70e8f4c
GT
1889
1890 // Find the month, day, and year tokens
1891 if (!invalid)
1892 {
94613352
GT
1893 first = tStr.First(wxT('/'));
1894 second = tStr.Last(wxT('/'));
e70e8f4c 1895
74de91cc
JS
1896 mm = wxAtoi(tStr.SubString(0,first));
1897 dd = wxAtoi(tStr.SubString(first+1,second));
1898 yyyy = wxAtoi(tStr.SubString(second+1,tStr.Length()-1));
e70e8f4c
GT
1899
1900 invalid = !(mm && dd && yyyy);
1901 }
1902
1903 // Force Year 2000 compliance
1904 if (!invalid && (yyyy < 1000))
6d841efd 1905 invalid = true;
e70e8f4c
GT
1906
1907 // Check the token ranges for validity
1908 if (!invalid)
1909 {
1910 if (yyyy > 9999)
6d841efd 1911 invalid = true;
e70e8f4c 1912 else if ((mm < 1) || (mm > 12))
6d841efd 1913 invalid = true;
e70e8f4c
GT
1914 else
1915 {
1916 if (dd < 1)
6d841efd 1917 invalid = true;
e70e8f4c
GT
1918 else
1919 {
1920 int days[12] = {31,28,31,30,31,30,
1921 31,31,30,31,30,31};
1922 if (dd > days[mm-1])
1923 {
6d841efd 1924 invalid = true;
e70e8f4c
GT
1925 if ((dd == 29) && (mm == 2))
1926 {
1927 if (((yyyy % 4) == 0) && (((yyyy % 100) != 0) || ((yyyy % 400) == 0)))
6d841efd 1928 invalid = false;
e70e8f4c
GT
1929 }
1930 }
1931 }
1932 }
1933 }
1934
1935 if (!invalid)
1936 {
29787237
JS
1937 wxGetApp().Contact->JoinDate.month = (unsigned short) mm;
1938 wxGetApp().Contact->JoinDate.day = (unsigned short) dd;
1939 wxGetApp().Contact->JoinDate.year = (short) yyyy;
e70e8f4c
GT
1940 }
1941 else
1942 {
94613352 1943 wxMessageBox(wxT("Improper date format. Please check the date\nspecified and try again.\n\nNOTE: Dates are in american format (MM/DD/YYYY)"),wxT("Notice..."),wxOK | wxICON_INFORMATION);
6d841efd 1944 return false;
e70e8f4c
GT
1945 }
1946
1947 tStr = pNameTxt->GetValue();
ea24eeb2
GT
1948 wxStrcpy(wxGetApp().Contact->Name,(const wxChar*) tStr);
1949 wxStrcpy(wxGetApp().Contact->Addr1,pAddress1Txt->GetValue());
1950 wxStrcpy(wxGetApp().Contact->Addr2,pAddress2Txt->GetValue());
1951 wxStrcpy(wxGetApp().Contact->City,pCityTxt->GetValue());
1952 wxStrcpy(wxGetApp().Contact->State,pStateTxt->GetValue());
1953 wxStrcpy(wxGetApp().Contact->Country,pCountryTxt->GetValue());
1954 wxStrcpy(wxGetApp().Contact->PostalCode,pPostalCodeTxt->GetValue());
e70e8f4c 1955
925e9792 1956 wxGetApp().Contact->Contributions = (UCHAR)wxAtoi(pContribTxt->GetValue());
74de91cc 1957 wxGetApp().Contact->LinesOfCode = wxAtol(pLinesTxt->GetValue());
e70e8f4c 1958
ea24eeb2
GT
1959 wxGetApp().Contact->NativeLanguage = (enum Language) pNativeLangChoice->GetSelection();
1960 wxGetApp().Contact->IsDeveloper = pDeveloperRadio->GetSelection() > 0;
e70e8f4c 1961
6d841efd 1962 return true;
108106cf
JS
1963} // CeditorDlg::GetData()
1964
1965
1966/*
1967 * Retrieve data from the dialog, verify the validity of the data, and if it is valid,
1968 * try to insert/update the data to the table based on the current 'mode' the dialog
1969 * is set to.
1970 *
6d841efd
WS
1971 * A return value of true means the insert/update was completed successfully, a return
1972 * value of false means that Save() failed. If returning false, then this function
108106cf
JS
1973 * has displayed a detailed error message for the user.
1974 */
1fc5dd6f 1975bool CeditorDlg::Save()
108106cf 1976{
6d841efd 1977 bool failed = false;
e70e8f4c
GT
1978
1979 // Read the data in the widgets of the dialog to get the user's data
1980 if (!GetData())
6d841efd 1981 failed = true;
e70e8f4c
GT
1982
1983 // Perform any other required validations necessary before saving
1984 if (!failed)
1985 {
1986 wxBeginBusyCursor();
1987
1988 if (mode == mCreate)
1989 {
925e9792 1990 RETCODE result = (RETCODE)wxGetApp().Contact->Insert();
e70e8f4c
GT
1991
1992 failed = (result != DB_SUCCESS);
1993 if (failed)
1994 {
1995 // Some errors may be expected, like a duplicate key, so handle those instances with
1996 // specific error messages.
1997 if (result == DB_ERR_INTEGRITY_CONSTRAINT_VIOL)
1998 {
1999 wxString tStr;
f21b2fd8 2000 tStr = wxT("A duplicate key value already exists in the table.\nUnable to save record\n\n");
74de91cc 2001 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 2002 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
2003 }
2004 else
2005 {
5d59e67a 2006 // Some other unexpected error occurred
e70e8f4c 2007 wxString tStr;
f21b2fd8 2008 tStr = wxT("Database insert failed\n\n");
74de91cc 2009 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 2010 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
2011 }
2012 }
2013 }
2014 else // mode == mEdit
2015 {
5d59e67a 2016 wxGetApp().Contact->GetDb()->RollbackTrans();
74de91cc 2017 wxGetApp().Contact->whereStr.Printf(wxT("NAME = '%s'"),saveName.c_str());
ea24eeb2 2018 if (!wxGetApp().Contact->UpdateWhere(wxGetApp().Contact->whereStr))
e70e8f4c
GT
2019 {
2020 wxString tStr;
f21b2fd8 2021 tStr = wxT("Database update failed\n\n");
74de91cc 2022 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 2023 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
6d841efd 2024 failed = true;
e70e8f4c
GT
2025 }
2026 }
2027
2028 if (!failed)
2029 {
ea24eeb2 2030 wxGetApp().Contact->GetDb()->CommitTrans();
e70e8f4c
GT
2031 SetMode(mView); // Sets the dialog mode back to viewing after save is successful
2032 }
2033 else
ea24eeb2 2034 wxGetApp().Contact->GetDb()->RollbackTrans();
e70e8f4c
GT
2035
2036 wxEndBusyCursor();
2037 }
2038
2039 return !failed;
108106cf
JS
2040} // CeditorDlg::Save()
2041
2042
2043/*
2044 * Where this program is only showing a single row at a time in the dialog,
2045 * a special where clause must be built to find just the single row which,
2046 * in sequence, would follow the currently displayed row.
2047 */
1fc5dd6f 2048bool CeditorDlg::GetNextRec()
108106cf 2049{
e70e8f4c
GT
2050 wxString w;
2051
ea24eeb2
GT
2052 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
2053 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
e70e8f4c 2054 {
94613352 2055 w = wxT("NAME = (SELECT MIN(NAME) FROM ");
ea24eeb2 2056 w += wxGetApp().Contact->GetTableName();
94613352 2057 w += wxT(" WHERE NAME > '");
e70e8f4c
GT
2058 }
2059 else
94613352 2060 w = wxT("(NAME > '");
e70e8f4c 2061
ea24eeb2 2062 w += wxGetApp().Contact->Name;
94613352 2063 w += wxT("'");
e70e8f4c
GT
2064
2065 // If a query where string is currently set, append that criteria
51e298bb 2066 if (!wxGetApp().Contact->qryWhereStr.empty())
e70e8f4c 2067 {
94613352 2068 w += wxT(" AND (");
ea24eeb2 2069 w += wxGetApp().Contact->qryWhereStr;
94613352 2070 w += wxT(")");
e70e8f4c
GT
2071 }
2072
94613352 2073 w += wxT(")");
049977d0 2074 return(GetRec(w));
108106cf
JS
2075
2076} // CeditorDlg::GetNextRec()
2077
2078
2079/*
2080 * Where this program is only showing a single row at a time in the dialog,
2081 * a special where clause must be built to find just the single row which,
2082 * in sequence, would precede the currently displayed row.
2083 */
1fc5dd6f 2084bool CeditorDlg::GetPrevRec()
108106cf 2085{
e70e8f4c 2086 wxString w;
108106cf 2087
ea24eeb2
GT
2088 if (wxGetApp().Contact->GetDb()->Dbms() != dbmsPOSTGRES &&
2089 wxGetApp().Contact->GetDb()->Dbms() != dbmsMY_SQL)
e70e8f4c 2090 {
94613352 2091 w = wxT("NAME = (SELECT MAX(NAME) FROM ");
ea24eeb2 2092 w += wxGetApp().Contact->GetTableName();
94613352 2093 w += wxT(" WHERE NAME < '");
e70e8f4c
GT
2094 }
2095 else
94613352 2096 w = wxT("(NAME < '");
65d7ddc4 2097
ea24eeb2 2098 w += wxGetApp().Contact->Name;
94613352 2099 w += wxT("'");
108106cf 2100
e70e8f4c 2101 // If a query where string is currently set, append that criteria
51e298bb 2102 if (!wxGetApp().Contact->qryWhereStr.empty())
e70e8f4c 2103 {
94613352 2104 w += wxT(" AND (");
ea24eeb2 2105 w += wxGetApp().Contact->qryWhereStr;
94613352 2106 w += wxT(")");
e70e8f4c 2107 }
108106cf 2108
94613352 2109 w += wxT(")");
108106cf 2110
049977d0 2111 return(GetRec(w));
108106cf
JS
2112
2113} // CeditorDlg::GetPrevRec()
2114
2115
2116/*
2117 * This function is here to avoid duplicating this same code in both the
2118 * GetPrevRec() and GetNextRec() functions
2119 */
049977d0 2120bool CeditorDlg::GetRec(const wxString &whereStr)
108106cf 2121{
ea24eeb2
GT
2122 wxGetApp().Contact->SetWhereClause(whereStr);
2123 wxGetApp().Contact->SetOrderByClause(wxT("NAME"));
e70e8f4c 2124
ea24eeb2 2125 if (!wxGetApp().Contact->Query())
e70e8f4c
GT
2126 {
2127 wxString tStr;
f21b2fd8 2128 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 2129 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 2130 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c 2131
6d841efd 2132 return(false);
e70e8f4c
GT
2133 }
2134
ea24eeb2 2135 if (wxGetApp().Contact->GetNext())
e70e8f4c
GT
2136 {
2137 PutData();
6d841efd 2138 return(true);
e70e8f4c
GT
2139 }
2140 else
6d841efd 2141 return(false);
108106cf
JS
2142} // CeditorDlg::GetRec()
2143
2144
2145
2146/*
2147 * CparameterDlg constructor
2148 */
e3065973
JS
2149
2150BEGIN_EVENT_TABLE(CparameterDlg, wxDialog)
65d7ddc4
GT
2151 EVT_BUTTON(PARAMETER_DIALOG_SAVE, CparameterDlg::OnButton)
2152 EVT_BUTTON(PARAMETER_DIALOG_CANCEL, CparameterDlg::OnButton)
e3065973
JS
2153 EVT_CLOSE(CparameterDlg::OnCloseWindow)
2154END_EVENT_TABLE()
2155
6d841efd 2156CparameterDlg::CparameterDlg(wxWindow *parent) : wxDialog (parent, PARAMETER_DIALOG, wxT("ODBC parameter settings"), wxDefaultPosition, wxSize(400, 325))
108106cf 2157{
e70e8f4c
GT
2158 // Since the ::OnCommand() function is overridden, this prevents the widget
2159 // detection in ::OnCommand() until all widgets have been initialized to prevent
2160 // uninitialized pointers from crashing the program
6d841efd 2161 widgetPtrsSet = false;
e70e8f4c 2162
6d841efd 2163 pParamODBCSourceMsg = new wxStaticText(this, PARAMETER_DIALOG_SOURCE_MSG, wxT("ODBC data sources:"), wxPoint( 10, 10), wxDefaultSize, 0, wxT("ParamODBCSourceMsg"));
da1e87c4 2164 pParamODBCSourceList = new wxListBox(this, PARAMETER_DIALOG_SOURCE_LISTBOX, wxPoint( 10, 29), wxSize(285, 150), 0, 0, wxLB_SINGLE|wxLB_ALWAYS_SB, wxDefaultValidator, wxT("ParamODBCSourceList"));
6d841efd 2165 pParamUserNameMsg = new wxStaticText(this, PARAMETER_DIALOG_NAME_MSG, wxT("Database user name:"), wxPoint( 10, 193), wxDefaultSize, 0, wxT("ParamUserNameMsg"));
da1e87c4 2166 pParamUserNameTxt = new wxTextCtrl(this, PARAMETER_DIALOG_NAME_TEXT, wxEmptyString, wxPoint(10, 209), wxSize( 140, 25), 0, wxDefaultValidator, wxT("ParamUserNameTxt"));
6d841efd 2167 pParamPasswordMsg = new wxStaticText(this, PARAMETER_DIALOG_PASSWORD_MSG, wxT("Password:"), wxPoint(156, 193), wxDefaultSize, 0, wxT("ParamPasswordMsg"));
da1e87c4 2168 pParamPasswordTxt = new wxTextCtrl(this, PARAMETER_DIALOG_PASSWORD_TEXT, wxEmptyString, wxPoint(156, 209), wxSize( 140, 25), 0, wxDefaultValidator, wxT("ParamPasswordTxt"));
6d841efd 2169 pParamDirPathMsg = new wxStaticText(this, PARAMETER_DIALOG_DIRPATH_MSG, wxT("Directory:"), wxPoint( 10, 243), wxDefaultSize, 0, wxT("ParamDirPathMsg"));
da1e87c4 2170 pParamDirPathTxt = new wxTextCtrl(this, PARAMETER_DIALOG_DIRPATH_TEXT, wxEmptyString, wxPoint( 10, 259), wxSize(140, 25), 0, wxDefaultValidator, wxT("ParamDirPathTxt"));
94613352
GT
2171 pParamSaveBtn = new wxButton(this, PARAMETER_DIALOG_SAVE, wxT("&Save"), wxPoint(310, 21), wxSize( 70, 35), 0, wxDefaultValidator, wxT("ParamSaveBtn"));
2172 pParamCancelBtn = new wxButton(this, PARAMETER_DIALOG_CANCEL, wxT("C&ancel"), wxPoint(310, 66), wxSize( 70, 35), 0, wxDefaultValidator, wxT("ParamCancelBtn"));
e70e8f4c 2173
925e9792 2174 // Now that all the widgets on the panel are created, its safe to allow ::OnCommand() to
e70e8f4c 2175 // handle all widget processing
6d841efd 2176 widgetPtrsSet = true;
e70e8f4c 2177
6d841efd 2178 saved = false;
e70e8f4c
GT
2179 savedParamSettings = wxGetApp().params;
2180
2181 Centre(wxBOTH);
2182 PutData();
2183 ShowModal();
108106cf
JS
2184} // CparameterDlg constructor
2185
2186
e3065973 2187void CparameterDlg::OnCloseWindow(wxCloseEvent& event)
108106cf 2188{
e70e8f4c
GT
2189 // Put any additional checking necessary to make certain it is alright
2190 // to close the program here that is not done elsewhere
2191 if (!saved)
2192 {
94613352 2193 bool Ok = (wxMessageBox(wxT("No changes have been saved.\n\nAre you sure you wish exit the parameter screen?"),wxT("Confirm"),wxYES_NO|wxICON_QUESTION) == wxYES);
925e9792 2194
e70e8f4c 2195 if (!Ok)
e3065973
JS
2196 {
2197 event.Veto();
e70e8f4c 2198 return;
e3065973 2199 }
925e9792 2200
e70e8f4c
GT
2201 wxGetApp().params = savedParamSettings;
2202 }
108106cf 2203
e70e8f4c
GT
2204 if (GetParent() != NULL)
2205 GetParent()->SetFocus();
e3065973 2206
3ca6a5f0
BP
2207 while (wxIsBusy())
2208 wxEndBusyCursor();
2209
6d841efd 2210 Show(false);
3ca6a5f0
BP
2211 SetReturnCode(0); // added so BoundsChecker would not report use of uninitialized variable
2212
2213 this->Destroy();
2214} // CparameterDlg::OnCloseWindow()
108106cf
JS
2215
2216
65d7ddc4
GT
2217void CparameterDlg::OnButton( wxCommandEvent &event )
2218{
e70e8f4c
GT
2219 wxWindow *win = (wxWindow*) event.GetEventObject();
2220 OnCommand( *win, event );
65d7ddc4
GT
2221}
2222
3ca6a5f0 2223
74de91cc 2224void CparameterDlg::OnCommand(wxWindow& win, wxCommandEvent& WXUNUSED(event))
108106cf 2225{
e70e8f4c 2226 wxString widgetName;
925e9792 2227
e70e8f4c
GT
2228 widgetName = win.GetName();
2229
2230 if (!widgetPtrsSet)
2231 return;
2232
2233 if (widgetName == pParamSaveBtn->GetName())
2234 {
2235 if (Save())
2236 {
2237 wxString tStr;
94613352 2238 tStr = wxT("Database parameters have been saved.");
e70e8f4c 2239 if (GetParent() != NULL) // The parameter dialog was not called during startup due to a missing cfg file
94613352
GT
2240 tStr += wxT("\nNew parameters will take effect the next time the program is started.");
2241 wxMessageBox(tStr,wxT("Notice..."),wxOK | wxICON_INFORMATION);
6d841efd 2242 saved = true;
e70e8f4c
GT
2243 Close();
2244 }
2245 return;
2246 }
2247
2248 if (widgetName == pParamCancelBtn->GetName())
2249 {
2250 Close();
2251 return;
2252 }
108106cf
JS
2253} // CparameterDlg::OnCommand()
2254
2255
1fc5dd6f 2256bool CparameterDlg::PutData()
108106cf 2257{
e70e8f4c
GT
2258 // Fill the data source list box
2259 FillDataSourceList();
2260
2261 // Fill in the fields from the params object
2262 if (wxGetApp().params.ODBCSource && wxStrlen(wxGetApp().params.ODBCSource))
f369dd4f
GT
2263 {
2264 int index = pParamODBCSourceList->FindString(wxGetApp().params.ODBCSource);
6d841efd 2265 if (index != wxNOT_FOUND)
f369dd4f
GT
2266 pParamODBCSourceList->SetSelection(index);
2267 }
e70e8f4c
GT
2268 pParamUserNameTxt->SetValue(wxGetApp().params.UserName);
2269 pParamPasswordTxt->SetValue(wxGetApp().params.Password);
2270 pParamDirPathTxt->SetValue(wxGetApp().params.DirPath);
6d841efd 2271 return true;
108106cf
JS
2272} // CparameterDlg::PutData()
2273
2274
1fc5dd6f 2275bool CparameterDlg::GetData()
108106cf 2276{
e70e8f4c 2277 wxString tStr;
da1e87c4 2278 if (pParamODBCSourceList->GetStringSelection() != wxEmptyString)
e70e8f4c
GT
2279 {
2280 tStr = pParamODBCSourceList->GetStringSelection();
da1e87c4 2281 if (tStr.Length() > ((int)(sizeof(wxGetApp().params.ODBCSource) / sizeof(wxChar))-1))
e70e8f4c
GT
2282 {
2283 wxString errmsg;
da1e87c4
GT
2284 errmsg.Printf(wxT("ODBC Data source name is longer than the data structure to hold it.\n'Cparameter.ODBCSource' must have a larger character array\nto handle a data source with this long of a name\n\nThe data source currently selected is %d characters long."), tStr.Length());
2285 wxMessageBox(errmsg, wxT("Internal program error..."), wxOK | wxICON_EXCLAMATION);
6d841efd 2286 return false;
e70e8f4c 2287 }
f6bcfd97 2288 wxStrcpy(wxGetApp().params.ODBCSource, tStr);
e70e8f4c
GT
2289 }
2290 else
6d841efd 2291 return false;
925e9792 2292
e70e8f4c 2293 tStr = pParamUserNameTxt->GetValue();
da1e87c4 2294 if (tStr.Length() > ((int)(sizeof(wxGetApp().params.UserName) / sizeof(wxChar))-1))
e70e8f4c
GT
2295 {
2296 wxString errmsg;
da1e87c4
GT
2297 errmsg.Printf(wxT("User name is longer than the data structure to hold it.\n'Cparameter.UserName' must have a larger character array\nto handle a data source with this long of a name\n\nThe user name currently specified is %d characters long."), tStr.Length());
2298 wxMessageBox(errmsg, wxT("Internal program error..."), wxOK | wxICON_EXCLAMATION);
6d841efd 2299 return false;
e70e8f4c 2300 }
f6bcfd97 2301 wxStrcpy(wxGetApp().params.UserName, tStr);
e70e8f4c
GT
2302
2303 tStr = pParamPasswordTxt->GetValue();
da1e87c4 2304 if (tStr.Length() > ((int)(sizeof(wxGetApp().params.Password) / sizeof(wxChar))-1))
e70e8f4c
GT
2305 {
2306 wxString errmsg;
da1e87c4
GT
2307 errmsg.Printf(wxT("Password is longer than the data structure to hold it.\n'Cparameter.Password' must have a larger character array\nto handle a data source with this long of a name\n\nThe password currently specified is %d characters long."), tStr.Length());
2308 wxMessageBox(errmsg, wxT("Internal program error..."), wxOK | wxICON_EXCLAMATION);
6d841efd 2309 return false;
e70e8f4c 2310 }
f6bcfd97 2311 wxStrcpy(wxGetApp().params.Password,tStr);
e70e8f4c
GT
2312
2313 tStr = pParamDirPathTxt->GetValue();
94613352 2314 tStr.Replace(wxT("\\"),wxT("/"));
da1e87c4 2315 if (tStr.Length() > ((int)(sizeof(wxGetApp().params.DirPath) / sizeof(wxChar))-1))
e70e8f4c
GT
2316 {
2317 wxString errmsg;
da1e87c4
GT
2318 errmsg.Printf(wxT("DirPath is longer than the data structure to hold it.\n'Cparameter.DirPath' must have a larger character array\nto handle a data source with this long of a name\n\nThe password currently specified is %d characters long."), tStr.Length());
2319 wxMessageBox(errmsg, wxT("Internal program error..."), wxOK | wxICON_EXCLAMATION);
6d841efd 2320 return false;
e70e8f4c 2321 }
f6bcfd97 2322 wxStrcpy(wxGetApp().params.DirPath,tStr);
6d841efd 2323 return true;
108106cf
JS
2324} // CparameterDlg::GetData()
2325
2326
1fc5dd6f 2327bool CparameterDlg::Save()
108106cf 2328{
049977d0
GT
2329 // Copy the current params in case user cancels changing
2330 // the params, so that we can reset them.
e70e8f4c
GT
2331 if (!GetData())
2332 {
049977d0 2333 wxGetApp().params = savedParamSettings;
6d841efd 2334 return false;
e70e8f4c
GT
2335 }
2336
049977d0 2337 wxGetApp().WriteParamFile(wxGetApp().params);
e70e8f4c 2338
6d841efd 2339 return true;
108106cf
JS
2340} // CparameterDlg::Save()
2341
2342
2343void CparameterDlg::FillDataSourceList()
2344{
da1e87c4
GT
2345 wxChar Dsn[SQL_MAX_DSN_LENGTH+1];
2346 wxChar DsDesc[254+1];
44420d2e 2347 wxSortedArrayString strArr;
108106cf 2348
049977d0 2349 while (wxDbGetDataSource(wxGetApp().DbConnectInf->GetHenv(), Dsn,
da1e87c4 2350 SQL_MAX_DSN_LENGTH, DsDesc, 254))
44420d2e
WS
2351 {
2352 strArr.Add(Dsn);
2353 }
108106cf 2354
da1e87c4 2355 for (size_t i=0; i < strArr.GetCount(); i++)
6d841efd 2356 {
44420d2e 2357 pParamODBCSourceList->Append(strArr[i].c_str());
6d841efd 2358 }
3ca6a5f0 2359
3fe813a9 2360} // CparameterDlg::FillDataSourceList()
108106cf
JS
2361
2362
f6fcbb63 2363BEGIN_EVENT_TABLE(CqueryDlg, wxDialog)
6d841efd 2364 EVT_BUTTON(wxID_ANY, CqueryDlg::OnButton)
e3065973 2365 EVT_CLOSE(CqueryDlg::OnCloseWindow)
f6fcbb63 2366END_EVENT_TABLE()
3ca6a5f0 2367
925e9792 2368
108106cf 2369// CqueryDlg() constructor
925e9792 2370CqueryDlg::CqueryDlg(wxWindow *parent, wxDb *pDb, wxChar *tblName[],
d3358961 2371 const wxString &pWhereArg) :
6d841efd 2372 wxDialog (parent, QUERY_DIALOG, wxT("Query"), wxDefaultPosition, wxSize(480, 360))
108106cf 2373{
e70e8f4c
GT
2374 wxBeginBusyCursor();
2375
2376 colInf = 0;
2377 dbTable = 0;
2378 masterTableName = tblName[0];
6d841efd 2379 widgetPtrsSet = false;
e70e8f4c
GT
2380 pDB = pDb;
2381
2382 // Initialize the WHERE clause from the string passed in
d3358961
GT
2383 pWhere = pWhereArg; // Save a pointer to the output buffer
2384 if (pWhere.Length() > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN) // Check the length of the buffer passed in
e70e8f4c
GT
2385 {
2386 wxString s;
94613352
GT
2387 s.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN+1);
2388 wxMessageBox(s,wxT("Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
2389 Close();
2390 return;
2391 }
2392
da1e87c4
GT
2393 pQueryCol1Msg = new wxStaticText(this, QUERY_DIALOG_COL_MSG, wxT("Column 1:"), wxPoint( 10, 10), wxSize( 69, 16), 0, wxT("QueryCol1Msg"));
2394 pQueryCol1Choice = new wxChoice(this, QUERY_DIALOG_COL_CHOICE, wxPoint( 10, 27), wxSize(250, 27), 0, 0, 0, wxDefaultValidator, wxT("QueryCol1Choice"));
2395 pQueryNotMsg = new wxStaticText(this, QUERY_DIALOG_NOT_MSG, wxT("NOT"), wxPoint(268, 10), wxDefaultSize, 0, wxT("QueryNotMsg"));
2396 pQueryNotCheck = new wxCheckBox(this, QUERY_DIALOG_NOT_CHECKBOX, wxEmptyString, wxPoint(275, 37), wxSize( 20, 20), 0, wxDefaultValidator, wxT("QueryNotCheck"));
e70e8f4c
GT
2397
2398 wxString choice_strings[9];
94613352
GT
2399 choice_strings[0] = wxT("=");
2400 choice_strings[1] = wxT("<");
2401 choice_strings[2] = wxT(">");
2402 choice_strings[3] = wxT("<=");
2403 choice_strings[4] = wxT(">=");
2404 choice_strings[5] = wxT("Begins");
2405 choice_strings[6] = wxT("Contains");
2406 choice_strings[7] = wxT("Like");
2407 choice_strings[8] = wxT("Between");
2408
6d841efd 2409 pQueryOperatorMsg = new wxStaticText(this, QUERY_DIALOG_OP_MSG, wxT("Operator:"), wxPoint(305, 10), wxDefaultSize, 0, wxT("QueryOperatorMsg"));
94613352
GT
2410 pQueryOperatorChoice = new wxChoice(this, QUERY_DIALOG_OP_CHOICE, wxPoint(305, 27), wxSize( 80, 27), 9, choice_strings, 0, wxDefaultValidator, wxT("QueryOperatorChoice"));
2411 pQueryCol2Msg = new wxStaticText(this, QUERY_DIALOG_COL2_MSG, wxT("Column 2:"), wxPoint( 10, 65), wxSize( 69, 16), 0, wxT("QueryCol2Msg"));
2412 pQueryCol2Choice = new wxChoice(this, QUERY_DIALOG_COL2_CHOICE, wxPoint( 10, 82), wxSize(250, 27), 0, 0, 0, wxDefaultValidator, wxT("QueryCol2Choice"));
6d841efd 2413 pQuerySqlWhereMsg = new wxStaticText(this, QUERY_DIALOG_WHERE_MSG, wxT("SQL where clause:"), wxPoint( 10, 141), wxDefaultSize, 0, wxT("QuerySqlWhereMsg"));
da1e87c4 2414 pQuerySqlWhereMtxt = new wxTextCtrl(this, QUERY_DIALOG_WHERE_TEXT, wxEmptyString, wxPoint( 10, 159), wxSize(377, 134), wxTE_MULTILINE, wxDefaultValidator, wxT("QuerySqlWhereMtxt"));
94613352
GT
2415 pQueryAddBtn = new wxButton(this, QUERY_DIALOG_ADD, wxT("&Add"), wxPoint(406, 24), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryAddBtn"));
2416 pQueryAndBtn = new wxButton(this, QUERY_DIALOG_AND, wxT("A&nd"), wxPoint(406, 58), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryAndBtn"));
2417 pQueryOrBtn = new wxButton(this, QUERY_DIALOG_OR, wxT("&Or"), wxPoint(406, 92), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryOrBtn"));
2418 pQueryLParenBtn = new wxButton(this, QUERY_DIALOG_LPAREN, wxT("("), wxPoint(406, 126), wxSize( 26, 26), 0, wxDefaultValidator, wxT("QueryLParenBtn"));
2419 pQueryRParenBtn = new wxButton(this, QUERY_DIALOG_RPAREN, wxT(")"), wxPoint(436, 126), wxSize( 26, 26), 0, wxDefaultValidator, wxT("QueryRParenBtn"));
2420 pQueryDoneBtn = new wxButton(this, QUERY_DIALOG_DONE, wxT("&Done"), wxPoint(406, 185), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryDoneBtn"));
2421 pQueryClearBtn = new wxButton(this, QUERY_DIALOG_CLEAR, wxT("C&lear"), wxPoint(406, 218), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryClearBtn"));
2422 pQueryCountBtn = new wxButton(this, QUERY_DIALOG_COUNT, wxT("&Count"), wxPoint(406, 252), wxSize( 56, 26), 0, wxDefaultValidator, wxT("QueryCountBtn"));
6d841efd 2423 pQueryValue1Msg = new wxStaticText(this, QUERY_DIALOG_VALUE1_MSG, wxT("Value:"), wxPoint(277, 66), wxDefaultSize, 0, wxT("QueryValue1Msg"));
da1e87c4 2424 pQueryValue1Txt = new wxTextCtrl(this, QUERY_DIALOG_VALUE1_TEXT, wxEmptyString, wxPoint(277, 83), wxSize(108, 25), 0, wxDefaultValidator, wxT("QueryValue1Txt"));
6d841efd 2425 pQueryValue2Msg = new wxStaticText(this, QUERY_DIALOG_VALUE2_MSG, wxT("AND"), wxPoint(238, 126), wxDefaultSize, 0, wxT("QueryValue2Msg"));
da1e87c4
GT
2426 pQueryValue2Txt = new wxTextCtrl(this, QUERY_DIALOG_VALUE2_TEXT, wxEmptyString, wxPoint(277, 120), wxSize(108, 25), 0, wxDefaultValidator, wxT("QueryValue2Txt"));
2427 pQueryHintGrp = new wxStaticBox(this, QUERY_DIALOG_HINT_GROUP, wxEmptyString, wxPoint( 10, 291), wxSize(377, 40), 0, wxT("QueryHintGrp"));
2428 pQueryHintMsg = new wxStaticText(this, QUERY_DIALOG_HINT_MSG, wxEmptyString, wxPoint( 16, 306), wxDefaultSize, 0, wxT("QueryHintMsg"));
e70e8f4c 2429
6d841efd 2430 widgetPtrsSet = true;
e70e8f4c
GT
2431 // Initialize the dialog
2432 wxString qualName;
94613352 2433 pQueryCol2Choice->Append(wxT("VALUE -->"));
e70e8f4c
GT
2434 colInf = pDB->GetColumns(tblName);
2435
2436 if (!colInf)
2437 {
2438 wxEndBusyCursor();
2439 wxString tStr;
f21b2fd8 2440 tStr = wxT("ODBC error during GetColumns()\n\n");
74de91cc 2441 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 2442 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
2443 return;
2444 }
2445
2446 int i;
f6bcfd97 2447 for (i = 0; colInf[i].colName && wxStrlen(colInf[i].colName); i++)
e70e8f4c
GT
2448 {
2449 // If there is more than one table being queried, qualify
2450 // the column names with the table name prefix.
f6bcfd97 2451 if (tblName[1] && wxStrlen(tblName[1]))
e70e8f4c 2452 {
94613352 2453 qualName.Printf(wxT("%s.%s"), colInf[i].tableName, colInf[i].colName);
e70e8f4c
GT
2454 pQueryCol1Choice->Append(qualName);
2455 pQueryCol2Choice->Append(qualName);
2456 }
2457 else // Single table query, append just the column names
2458 {
2459 pQueryCol1Choice->Append(colInf[i].colName);
2460 pQueryCol2Choice->Append(colInf[i].colName);
2461 }
2462 }
2463
2464 pQueryCol1Choice->SetSelection(0);
2465 pQueryCol2Choice->SetSelection(0);
2466 pQueryOperatorChoice->SetSelection(0);
2467
6d841efd
WS
2468 pQueryValue2Msg->Show(false);
2469 pQueryValue2Txt->Show(false);
e70e8f4c
GT
2470
2471 pQueryHintMsg->SetLabel(langQRY_EQ);
2472
d3358961 2473 pQuerySqlWhereMtxt->SetValue(pWhere.c_str());
e70e8f4c
GT
2474
2475 wxEndBusyCursor();
2476
2477 // Display the dialog window
2478 Centre(wxBOTH);
2479 ShowModal();
108106cf
JS
2480} // CqueryDlg() constructor
2481
2482
da1e87c4
GT
2483CqueryDlg::~CqueryDlg()
2484{
2485} // CqueryDlg::~CqueryDlg() destructor
2486
2487
3ca6a5f0 2488void CqueryDlg::OnButton(wxCommandEvent &event)
f6fcbb63
RR
2489{
2490 wxWindow *win = (wxWindow*) event.GetEventObject();
2491 OnCommand( *win, event );
3ca6a5f0
BP
2492} // CqueryDlg::OnButton()
2493
f6fcbb63 2494
74de91cc 2495void CqueryDlg::OnCommand(wxWindow& win, wxCommandEvent& WXUNUSED(event))
108106cf 2496{
e70e8f4c
GT
2497 // Widget pointers won't be set when the dialog is constructed.
2498 // Control is passed through this function once for each widget on
2499 // a dialog as the dialog is constructed.
2500 if (!widgetPtrsSet)
2501 return;
2502
2503 wxString widgetName = win.GetName();
2504
2505 // Operator choice box
2506 if (widgetName == pQueryOperatorChoice->GetName())
2507 {
2508 // Set the help text
2509 switch((qryOp) pQueryOperatorChoice->GetSelection())
2510 {
3ca6a5f0
BP
2511 case qryOpEQ:
2512 pQueryHintMsg->SetLabel(langQRY_EQ);
2513 break;
2514 case qryOpLT:
2515 pQueryHintMsg->SetLabel(langQRY_LT);
2516 break;
2517 case qryOpGT:
2518 pQueryHintMsg->SetLabel(langQRY_GT);
2519 break;
2520 case qryOpLE:
2521 pQueryHintMsg->SetLabel(langQRY_LE);
2522 break;
2523 case qryOpGE:
2524 pQueryHintMsg->SetLabel(langQRY_GE);
2525 break;
2526 case qryOpBEGINS:
2527 pQueryHintMsg->SetLabel(langQRY_BEGINS);
2528 break;
2529 case qryOpCONTAINS:
2530 pQueryHintMsg->SetLabel(langQRY_CONTAINS);
2531 break;
2532 case qryOpLIKE:
2533 pQueryHintMsg->SetLabel(langQRY_LIKE);
2534 break;
2535 case qryOpBETWEEN:
2536 pQueryHintMsg->SetLabel(langQRY_BETWEEN);
2537 break;
e70e8f4c
GT
2538 }
2539
2540 // Hide the value2 widget
6d841efd
WS
2541 pQueryValue2Msg->Show(false); // BETWEEN will show this widget
2542 pQueryValue2Txt->Show(false); // BETWEEN will show this widget
e70e8f4c
GT
2543
2544 // Disable the NOT operator for <, <=, >, >=
2545 switch((qryOp) pQueryOperatorChoice->GetSelection())
2546 {
3ca6a5f0
BP
2547 case qryOpLT:
2548 case qryOpGT:
2549 case qryOpLE:
2550 case qryOpGE:
2551 pQueryNotCheck->SetValue(0);
6d841efd 2552 pQueryNotCheck->Enable(false);
3ca6a5f0
BP
2553 break;
2554 default:
6d841efd 2555 pQueryNotCheck->Enable(true);
3ca6a5f0 2556 break;
e70e8f4c
GT
2557 }
2558
2559 // Manipulate the dialog to handle the selected operator
2560 switch((qryOp) pQueryOperatorChoice->GetSelection())
2561 {
3ca6a5f0
BP
2562 case qryOpEQ:
2563 case qryOpLT:
2564 case qryOpGT:
2565 case qryOpLE:
2566 case qryOpGE:
6d841efd 2567 pQueryCol2Choice->Enable(true);
3ca6a5f0
BP
2568 if (pQueryCol2Choice->GetSelection()) // Column name is highlighted
2569 {
6d841efd
WS
2570 pQueryValue1Msg->Show(false);
2571 pQueryValue1Txt->Show(false);
3ca6a5f0
BP
2572 }
2573 else // "Value" is highlighted
2574 {
6d841efd
WS
2575 pQueryValue1Msg->Show(true);
2576 pQueryValue1Txt->Show(true);
3ca6a5f0
BP
2577 pQueryValue1Txt->SetFocus();
2578 }
2579 break;
2580 case qryOpBEGINS:
2581 case qryOpCONTAINS:
2582 case qryOpLIKE:
2583 pQueryCol2Choice->SetSelection(0);
6d841efd
WS
2584 pQueryCol2Choice->Enable(false);
2585 pQueryValue1Msg->Show(true);
2586 pQueryValue1Txt->Show(true);
e70e8f4c 2587 pQueryValue1Txt->SetFocus();
3ca6a5f0
BP
2588 break;
2589 case qryOpBETWEEN:
2590 pQueryCol2Choice->SetSelection(0);
6d841efd
WS
2591 pQueryCol2Choice->Enable(false);
2592 pQueryValue2Msg->Show(true);
2593 pQueryValue2Txt->Show(true);
2594 pQueryValue1Msg->Show(true);
2595 pQueryValue1Txt->Show(true);
3ca6a5f0
BP
2596 pQueryValue1Txt->SetFocus();
2597 break;
e70e8f4c
GT
2598 }
2599
2600 return;
2601
2602 } // Operator choice box
2603
2604 // Column 2 choice
2605 if (widgetName == pQueryCol2Choice->GetName())
2606 {
2607 if (pQueryCol2Choice->GetSelection()) // Column name is highlighted
2608 {
6d841efd
WS
2609 pQueryValue1Msg->Show(false);
2610 pQueryValue1Txt->Show(false);
e70e8f4c
GT
2611 }
2612 else // "Value" is highlighted
2613 {
6d841efd
WS
2614 pQueryValue1Msg->Show(true);
2615 pQueryValue1Txt->Show(true);
e70e8f4c
GT
2616 pQueryValue1Txt->SetFocus();
2617 }
2618 return;
e70e8f4c
GT
2619 } // Column 2 choice
2620
2621 // Add button
2622 if (widgetName == pQueryAddBtn->GetName())
2623 {
2624 ProcessAddBtn();
2625 return;
e70e8f4c
GT
2626 } // Add button
2627
2628 // And button
2629 if (widgetName == pQueryAndBtn->GetName())
2630 {
94613352 2631 AppendToWhere(wxT(" AND\n"));
e70e8f4c 2632 return;
e70e8f4c
GT
2633 } // And button
2634
2635 // Or button
2636 if (widgetName == pQueryOrBtn->GetName())
2637 {
94613352 2638 AppendToWhere(wxT(" OR\n"));
e70e8f4c 2639 return;
e70e8f4c
GT
2640 } // Or button
2641
2642 // Left Paren button
2643 if (widgetName == pQueryLParenBtn->GetName())
2644 {
94613352 2645 AppendToWhere(wxT("("));
e70e8f4c 2646 return;
e70e8f4c
GT
2647 } // Left Paren button
2648
2649 // Right paren button
2650 if (widgetName == pQueryRParenBtn->GetName())
2651 {
94613352 2652 AppendToWhere(wxT(")"));
e70e8f4c 2653 return;
e70e8f4c
GT
2654 } // Right Paren button
2655
2656 // Done button
2657 if (widgetName == pQueryDoneBtn->GetName())
2658 {
2659 // Be sure the where clause will not overflow the output buffer
3ca6a5f0 2660 if (wxStrlen(pQuerySqlWhereMtxt->GetValue()) > (unsigned int)DB_MAX_WHERE_CLAUSE_LEN)
e70e8f4c
GT
2661 {
2662 wxString s;
94613352
GT
2663 s.Printf(wxT("Maximum where clause length exceeded.\nLength must be less than %d"), DB_MAX_WHERE_CLAUSE_LEN+1);
2664 wxMessageBox(s,wxT("Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
2665 return;
2666 }
2667 // Validate the where clause for things such as matching parens
2668 if (!ValidateWhereClause())
2669 return;
2670 // Copy the where clause to the output buffer and exit
d3358961 2671 pWhere = pQuerySqlWhereMtxt->GetValue();
e70e8f4c
GT
2672 Close();
2673 return;
e70e8f4c
GT
2674 } // Done button
2675
2676 // Clear button
2677 if (widgetName == pQueryClearBtn->GetName())
2678 {
da1e87c4 2679 bool Ok = (wxMessageBox(wxT("Are you sure you wish to clear the Query?"), wxT("Confirm"), wxYES_NO|wxICON_QUESTION) == wxYES);
e70e8f4c
GT
2680
2681 if (Ok)
da1e87c4
GT
2682 pQuerySqlWhereMtxt->SetValue(wxEmptyString);
2683
e70e8f4c 2684 return;
e70e8f4c
GT
2685 } // Clear button
2686
2687 // Count button
2688 if (widgetName == pQueryCountBtn->GetName())
2689 {
2690 wxBeginBusyCursor();
2691 ProcessCountBtn();
2692 wxEndBusyCursor();
2693 return;
e70e8f4c 2694 } // Count button
108106cf
JS
2695
2696} // CqueryDlg::OnCommand
2697
2698
74de91cc 2699void CqueryDlg::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
108106cf 2700{
e70e8f4c 2701 // Clean up
ea24eeb2 2702 wxDELETEA(colInf);
e70e8f4c 2703
ea24eeb2 2704 wxDELETE(dbTable);
e70e8f4c
GT
2705
2706 GetParent()->SetFocus();
2707 while (wxIsBusy())
2708 wxEndBusyCursor();
108106cf 2709
6d841efd 2710 Show(false);
3ca6a5f0 2711 SetReturnCode(1); // added so BoundsChecker would not report use of uninitialized variable
e3065973 2712
3ca6a5f0 2713 this->Destroy();
e3065973 2714} // CqueryDlg::OnCloseWindow()
108106cf 2715
108106cf 2716
94613352 2717void CqueryDlg::AppendToWhere(wxChar *s)
108106cf 2718{
3ca6a5f0
BP
2719 wxString whereStr = pQuerySqlWhereMtxt->GetValue();
2720 whereStr += s;
2721 pQuerySqlWhereMtxt->SetValue(whereStr);
108106cf
JS
2722} // CqueryDlg::AppendToWhere()
2723
2724
2725void CqueryDlg::ProcessAddBtn()
2726{
e70e8f4c
GT
2727 qryOp oper = (qryOp) pQueryOperatorChoice->GetSelection();
2728
2729 // Verify that eveything is filled in correctly
2730 if (pQueryCol2Choice->GetSelection() == 0) // "Value" is selected
2731 {
2732 // Verify that value 1 is filled in
f6bcfd97 2733 if (wxStrlen(pQueryValue1Txt->GetValue()) == 0)
e70e8f4c
GT
2734 {
2735 wxBell();
2736 pQueryValue1Txt->SetFocus();
2737 return;
2738 }
2739 // For the BETWEEN operator, value 2 must be filled in as well
2740 if (oper == qryOpBETWEEN &&
f6bcfd97 2741 wxStrlen(pQueryValue2Txt->GetValue()) == 0)
e70e8f4c
GT
2742 {
2743 wxBell();
2744 pQueryValue2Txt->SetFocus();
2745 return;
2746 }
2747 }
2748
2749 // Build the expression and append it to the where clause window
2750 wxString s = pQueryCol1Choice->GetStringSelection();
925e9792 2751
e70e8f4c 2752 if (pQueryNotCheck->GetValue() && (oper != qryOpEQ))
94613352 2753 s += wxT(" NOT");
925e9792 2754
e70e8f4c
GT
2755 switch(oper)
2756 {
2757 case qryOpEQ:
2758 if (pQueryNotCheck->GetValue()) // NOT box is checked
94613352 2759 s += wxT(" <>");
e70e8f4c 2760 else
94613352 2761 s += wxT(" =");
e70e8f4c
GT
2762 break;
2763 case qryOpLT:
94613352 2764 s += wxT(" <");
e70e8f4c
GT
2765 break;
2766 case qryOpGT:
94613352 2767 s += wxT(" >");
e70e8f4c
GT
2768 break;
2769 case qryOpLE:
94613352 2770 s += wxT(" <=");
e70e8f4c
GT
2771 break;
2772 case qryOpGE:
94613352 2773 s += wxT(" >=");
e70e8f4c
GT
2774 break;
2775 case qryOpBEGINS:
2776 case qryOpCONTAINS:
2777 case qryOpLIKE:
94613352 2778 s += wxT(" LIKE");
e70e8f4c
GT
2779 break;
2780 case qryOpBETWEEN:
94613352 2781 s += wxT(" BETWEEN");
e70e8f4c
GT
2782 break;
2783 }
2784
94613352 2785 s += wxT(" ");
e70e8f4c
GT
2786
2787 int col1Idx = pQueryCol1Choice->GetSelection();
2788
6d841efd 2789 bool quote = false;
e70e8f4c
GT
2790 if (colInf[col1Idx].sqlDataType == SQL_VARCHAR ||
2791 oper == qryOpBEGINS ||
2792 oper == qryOpCONTAINS ||
2793 oper == qryOpLIKE)
6d841efd 2794 quote = true;
e70e8f4c
GT
2795
2796 if (pQueryCol2Choice->GetSelection()) // Column name
2797 s += pQueryCol2Choice->GetStringSelection();
2798 else // Column 2 is a "value"
2799 {
2800 if (quote)
94613352 2801 s += wxT("'");
e70e8f4c 2802 if (oper == qryOpCONTAINS)
94613352 2803 s += wxT("%");
e70e8f4c
GT
2804 s += pQueryValue1Txt->GetValue();
2805 if (oper == qryOpCONTAINS || oper == qryOpBEGINS)
94613352 2806 s += wxT("%");
e70e8f4c 2807 if (quote)
94613352 2808 s += wxT("'");
e70e8f4c
GT
2809 }
2810
2811 if (oper == qryOpBETWEEN)
2812 {
94613352 2813 s += wxT(" AND ");
e70e8f4c 2814 if (quote)
94613352 2815 s += wxT("'");
e70e8f4c
GT
2816 s += pQueryValue2Txt->GetValue();
2817 if (quote)
94613352 2818 s += wxT("'");
e70e8f4c
GT
2819 }
2820
94613352 2821 AppendToWhere((wxChar*) (const wxChar*) s);
108106cf
JS
2822
2823} // CqueryDlg::ProcessAddBtn()
2824
2825
2826void CqueryDlg::ProcessCountBtn()
2827{
e70e8f4c
GT
2828 if (!ValidateWhereClause())
2829 return;
2830
3fe813a9 2831 if (!dbTable) // wxDbTable object needs to be created and opened
e70e8f4c 2832 {
c3677ad3 2833 dbTable = new wxDbTable(pDB, masterTableName, 0, (const wxString &)wxEmptyString,
925e9792 2834 !wxDB_QUERY_ONLY,
3fe813a9
GT
2835 wxGetApp().DbConnectInf->GetDefaultDir());
2836 if (!dbTable)
e70e8f4c 2837 {
94613352 2838 wxMessageBox(wxT("Memory allocation failed creating a wxDbTable object."),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
2839 return;
2840 }
2841 if (!dbTable->Open())
2842 {
2843 wxString tStr;
f21b2fd8 2844 tStr = wxT("ODBC error during Open()\n\n");
74de91cc 2845 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 2846 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
e70e8f4c
GT
2847 return;
2848 }
2849 }
2850
2851 // Count() with WHERE clause
f6bcfd97 2852 wxString whereStr;
4c4a393f
GT
2853
2854 whereStr = pQuerySqlWhereMtxt->GetValue();
f6bcfd97 2855 dbTable->SetWhereClause(whereStr.c_str());
94613352 2856
e70e8f4c
GT
2857 ULONG whereCnt = dbTable->Count();
2858
2859 // Count() of all records in the table
da1e87c4 2860 dbTable->SetWhereClause(wxEmptyString);
e70e8f4c
GT
2861 ULONG totalCnt = dbTable->Count();
2862
2863 if (whereCnt > 0 || totalCnt == 0)
2864 {
2865 wxString tStr;
94613352
GT
2866 tStr.Printf(wxT("%lu of %lu records match the query criteria."),whereCnt,totalCnt);
2867 wxMessageBox(tStr,wxT("Notice..."),wxOK | wxICON_INFORMATION);
e70e8f4c
GT
2868 }
2869 else
2870 {
2871 wxString tStr;
94613352
GT
2872 tStr.Printf(wxT("%lu of %lu records match the query criteria.\n\nEither the criteria entered produced a result set\nwith no records, or there was a syntactical error\nin the clause you entered.\n\nPress the details button to see if any database errors were reported."),whereCnt,totalCnt);
2873 wxMessageBox(tStr,wxT("Notice..."),wxOK | wxICON_INFORMATION);
e70e8f4c
GT
2874 }
2875
2876 // After a wxMessageBox, the focus does not necessarily return to the
2877 // window which was the focus when the message box popped up, so return
2878 // focus to the Query dialog for certain
2879 SetFocus();
108106cf
JS
2880
2881} // CqueryDlg::ProcessCountBtn()
2882
2883
1fc5dd6f 2884bool CqueryDlg::ValidateWhereClause()
108106cf 2885{
e70e8f4c
GT
2886 wxString where = pQuerySqlWhereMtxt->GetValue();
2887
94613352 2888 if (where.Freq(wxT('(')) != where.Freq(wxT(')')))
e70e8f4c 2889 {
94613352 2890 wxMessageBox(wxT("There are mismatched parenthesis in the constructed where clause"),wxT("Error..."),wxOK | wxICON_EXCLAMATION);
6d841efd 2891 return(false);
e70e8f4c
GT
2892 }
2893 // After a wxMessageBox, the focus does not necessarily return to the
2894 // window which was the focus when the message box popped up, so return
2895 // focus to the Query dialog for certain
2896 SetFocus();
2897
6d841efd 2898 return(true);
108106cf
JS
2899
2900} // CqueryDlg::ValidateWhereClause()
3f755e2d 2901
da1e87c4
GT
2902#ifdef wxODBC_BLOB_SUPPORT
2903
2904BEGIN_EVENT_TABLE(CimageDlg, wxDialog)
2905 EVT_CLOSE(CimageDlg::OnCloseWindow)
2906END_EVENT_TABLE()
2907
2908CimageDlg::CimageDlg(wxWindow *parent, wxChar *pImageData, off_t iSize)
2909: wxDialog(parent, IMAGE_DIALOG, wxT("BLOB Image"), wxDefaultPosition, wxDefaultSize),
51e298bb 2910m_pDisplayBmp(NULL),
da1e87c4 2911m_pBmp(NULL),
51e298bb 2912m_pImage(NULL)
da1e87c4
GT
2913{
2914 wxMemoryInputStream inStream(pImageData, iSize);
2915
2916 if(inStream.IsOk())
2917 {
2918 m_pImage = new wxImage(inStream, wxBITMAP_TYPE_ANY);
2919
2920 if(m_pImage->Ok())
2921 {
eb3efe0d 2922 m_pBmp = new wxBitmap(*m_pImage);
da1e87c4
GT
2923 m_pDisplayBmp = new wxStaticBitmap(this, IMAGE_DIALOG_STATIC_BMP, *m_pBmp, wxPoint(5,5), wxDefaultSize);
2924
2925 SetSize(m_pBmp->GetWidth() + 10, m_pBmp->GetHeight() + 30);
2926 }
2927 }
2928}
2929
2930CimageDlg::~CimageDlg()
2931{
2932 if(m_pImage)
2933 delete m_pImage;
2934
2935 if(m_pBmp)
2936 delete m_pBmp;
3f755e2d 2937
da1e87c4
GT
2938 if(m_pDisplayBmp)
2939 delete m_pDisplayBmp;
2940}
2941
2942void CimageDlg::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
2943{
2944 GetParent()->SetFocus();
2945
2946 Show(false);
2947
2948 this->Destroy();
2949}
2950
2951#endif
3f755e2d 2952
3f030b48
GT
2953void DisplayDbDiagnostics(wxDb *pDb)
2954{
69a2b59d 2955 wxString s, t;
6d841efd 2956 bool comma;
69a2b59d 2957
9b12bd99
GT
2958 s = wxT("Diagnostics Output\n");
2959 s += langDBINF_DB_NAME;
69a2b59d 2960 s += pDb->dbInf.dbmsName;
74de91cc 2961 s += wxT("\n");
69a2b59d
GT
2962
2963 s += langDBINF_DB_VER;
2964 s += pDb->dbInf.dbmsVer;
74de91cc 2965 s += wxT("\n");
69a2b59d
GT
2966
2967 s += langDBINF_DRIVER_NAME;
2968 s += pDb->dbInf.driverName;
74de91cc 2969 s += wxT("\n");
69a2b59d
GT
2970
2971 s += langDBINF_DRIVER_ODBC_VER;
2972 s += pDb->dbInf.odbcVer;
74de91cc 2973 s += wxT("\n");
69a2b59d
GT
2974
2975 s += langDBINF_DRIVER_MGR_ODBC_VER;
2976 s += pDb->dbInf.drvMgrOdbcVer;
74de91cc 2977 s += wxT("\n");
69a2b59d
GT
2978
2979 s += langDBINF_DRIVER_VER;
2980 s += pDb->dbInf.driverVer;
74de91cc 2981 s += wxT("\n");
69a2b59d
GT
2982
2983 s += langDBINF_SERVER_NAME;
2984 s += pDb->dbInf.serverName;
74de91cc 2985 s += wxT("\n");
69a2b59d
GT
2986
2987 s += langDBINF_FILENAME;
2988 s += pDb->dbInf.databaseName;
74de91cc 2989 s += wxT("\n");
69a2b59d
GT
2990
2991 s += langDBINF_OUTER_JOINS;
2992 s += pDb->dbInf.outerJoins;
74de91cc 2993 s += wxT("\n");
69a2b59d
GT
2994
2995 s += langDBINF_STORED_PROC;
2996 s += pDb->dbInf.procedureSupport;
74de91cc 2997 s += wxT("\n");
69a2b59d
GT
2998
2999 if (pDb->dbInf.maxConnections)
74de91cc 3000 t.sprintf(wxT("%s%d\n"), langDBINF_MAX_HDBC, pDb->dbInf.maxConnections);
69a2b59d 3001 else
74de91cc 3002 t.sprintf(wxT("%s%s\n"), langDBINF_MAX_HDBC, langDBINF_UNLIMITED);
69a2b59d
GT
3003 s += t;
3004
3005 if (pDb->dbInf.maxStmts)
74de91cc 3006 t.sprintf(wxT("%s%d\n"), langDBINF_MAX_HSTMT, pDb->dbInf.maxStmts);
69a2b59d 3007 else
74de91cc 3008 t.sprintf(wxT("%s%s\n"), langDBINF_MAX_HSTMT, langDBINF_UNLIMITED);
69a2b59d
GT
3009 s += t;
3010
3011 s += langDBINF_API_LVL;
3012 switch(pDb->dbInf.apiConfLvl)
3013 {
3014 case SQL_OAC_NONE: s += langDBINF_NONE; break;
3015 case SQL_OAC_LEVEL1: s += langDBINF_LEVEL1; break;
3016 case SQL_OAC_LEVEL2: s += langDBINF_LEVEL2; break;
3017 }
74de91cc 3018 s += wxT("\n");
69a2b59d
GT
3019
3020 s += langDBINF_CLI_LVL;
3021 switch(pDb->dbInf.cliConfLvl)
3022 {
3023 case SQL_OSCC_NOT_COMPLIANT: s += langDBINF_NOT_COMPLIANT; break;
3024 case SQL_OSCC_COMPLIANT: s += langDBINF_COMPLIANT; break;
3025 }
74de91cc 3026 s += wxT("\n");
69a2b59d
GT
3027
3028 s += langDBINF_SQL_LVL;
3029 switch(pDb->dbInf.sqlConfLvl)
3030 {
3031 case SQL_OSC_MINIMUM: s += langDBINF_MIN_GRAMMAR; break;
3032 case SQL_OSC_CORE: s += langDBINF_CORE_GRAMMAR; break;
3033 case SQL_OSC_EXTENDED: s += langDBINF_EXT_GRAMMAR; break;
3034 }
74de91cc 3035 s += wxT("\n");
69a2b59d
GT
3036
3037 s += langDBINF_COMMIT_BEHAVIOR;
3038 switch(pDb->dbInf.cursorCommitBehavior)
3039 {
3040 case SQL_CB_DELETE: s += langDBINF_DELETE_CURSORS; break;
3041 case SQL_CB_CLOSE: s += langDBINF_CLOSE_CURSORS; break;
3042 case SQL_CB_PRESERVE: s += langDBINF_PRESERVE_CURSORS; break;
3043 }
74de91cc 3044 s += wxT("\n");
69a2b59d
GT
3045
3046 s += langDBINF_ROLLBACK_BEHAVIOR;
3047 switch(pDb->dbInf.cursorRollbackBehavior)
3048 {
3049 case SQL_CB_DELETE: s += langDBINF_DELETE_CURSORS; break;
3050 case SQL_CB_CLOSE: s += langDBINF_CLOSE_CURSORS; break;
3051 case SQL_CB_PRESERVE: s += langDBINF_PRESERVE_CURSORS; break;
3052 }
74de91cc 3053 s += wxT("\n");
69a2b59d
GT
3054
3055 s += langDBINF_SUPP_NOT_NULL;
3056 switch(pDb->dbInf.supportNotNullClause)
3057 {
3058 case SQL_NNC_NULL: s += langNO; break;
3059 case SQL_NNC_NON_NULL: s += langYES; break;
3060 }
74de91cc 3061 s += wxT("\n");
69a2b59d
GT
3062
3063 s += langDBINF_SUPP_IEF;
3064 s += pDb->dbInf.supportIEF;
74de91cc 3065 s += wxT("\n");
69a2b59d
GT
3066
3067 // DEFAULT setting for "Transaction Isolation Level"
3068 s += langDBINF_TXN_ISOLATION;
3069 switch(pDb->dbInf.txnIsolation)
3070 {
3071 case SQL_TXN_READ_UNCOMMITTED: s += langDBINF_READ_UNCOMMITTED; break;
3072 case SQL_TXN_READ_COMMITTED: s += langDBINF_READ_COMMITTED; break;
3073 case SQL_TXN_REPEATABLE_READ: s += langDBINF_REPEATABLE_READ; break;
3074 case SQL_TXN_SERIALIZABLE: s += langDBINF_SERIALIZABLE; break;
3f030b48 3075#ifdef ODBC_V20
69a2b59d
GT
3076 case SQL_TXN_VERSIONING: s += langDBINF_VERSIONING; break;
3077#endif
3078 }
74de91cc 3079 s += wxT("\n");
69a2b59d
GT
3080
3081 // CURRENT setting for "Transaction Isolation Level"
3082 long txnIsoLvl;
3083 s += langDBINF_TXN_ISOLATION_CURR;
3084 if (SQLGetConnectOption(pDb->GetHDBC(),SQL_TXN_ISOLATION,&txnIsoLvl) == SQL_SUCCESS)
3085 {
3086 switch(txnIsoLvl)
3087 {
3088 case SQL_TXN_READ_UNCOMMITTED: s += langDBINF_READ_UNCOMMITTED; break;
3089 case SQL_TXN_READ_COMMITTED: s += langDBINF_READ_COMMITTED; break;
3090 case SQL_TXN_REPEATABLE_READ: s += langDBINF_REPEATABLE_READ; break;
3091 case SQL_TXN_SERIALIZABLE: s += langDBINF_SERIALIZABLE; break;
3f030b48 3092#ifdef ODBC_V20
69a2b59d
GT
3093 case SQL_TXN_VERSIONING: s += langDBINF_VERSIONING; break;
3094#endif
3095 }
3096 }
74de91cc 3097 s += wxT("\n");
69a2b59d 3098
abfcca57
JJ
3099#ifdef __VMS__
3100#pragma message disable incboodep
3101#endif
6d841efd 3102 comma = false;
69a2b59d
GT
3103 s += langDBINF_TXN_ISOLATION_OPTS;
3104 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_READ_UNCOMMITTED)
3105 {s += langDBINF_READ_UNCOMMITTED; comma++;}
3106 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_READ_COMMITTED)
74de91cc 3107 {if (comma++) s += wxT(", "); s += langDBINF_READ_COMMITTED;}
69a2b59d 3108 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_REPEATABLE_READ)
74de91cc 3109 {if (comma++) s += wxT(", "); s += langDBINF_REPEATABLE_READ;}
69a2b59d 3110 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_SERIALIZABLE)
74de91cc 3111 {if (comma++) s += wxT(", "); s += langDBINF_SERIALIZABLE;}
3f030b48 3112#ifdef ODBC_V20
69a2b59d 3113 if (pDb->dbInf.txnIsolationOptions & SQL_TXN_VERSIONING)
74de91cc 3114 {if (comma++) s += wxT(", "); s += langDBINF_VERSIONING;}
69a2b59d 3115#endif
74de91cc 3116 s += wxT("\n");
69a2b59d 3117
6d841efd 3118 comma = false;
69a2b59d
GT
3119 s += langDBINF_FETCH_DIRS;
3120 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_NEXT)
3121 {s += langDBINF_NEXT; comma++;}
3122 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_PRIOR)
74de91cc 3123 {if (comma++) s += wxT(", "); s += langDBINF_PREV;}
69a2b59d 3124 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_FIRST)
74de91cc 3125 {if (comma++) s += wxT(", "); s += langDBINF_FIRST;}
69a2b59d 3126 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_LAST)
74de91cc 3127 {if (comma++) s += wxT(", "); s += langDBINF_LAST;}
69a2b59d 3128 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_ABSOLUTE)
74de91cc 3129 {if (comma++) s += wxT(", "); s += langDBINF_ABSOLUTE;}
69a2b59d 3130 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_RELATIVE)
74de91cc 3131 {if (comma++) s += wxT(", "); s += langDBINF_RELATIVE;}
3f030b48 3132#ifdef ODBC_V20
69a2b59d 3133 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_RESUME)
74de91cc 3134 {if (comma++) s += wxT(", "); s += langDBINF_RESUME;}
69a2b59d
GT
3135#endif
3136 if (pDb->dbInf.fetchDirections & SQL_FD_FETCH_BOOKMARK)
74de91cc
JS
3137 {if (comma++) s += wxT(", "); s += langDBINF_BOOKMARK;}
3138 s += wxT("\n");
69a2b59d 3139
6d841efd 3140 comma = false;
69a2b59d
GT
3141 s += langDBINF_LOCK_TYPES;
3142 if (pDb->dbInf.lockTypes & SQL_LCK_NO_CHANGE)
3143 {s += langDBINF_NO_CHANGE; comma++;}
3144 if (pDb->dbInf.lockTypes & SQL_LCK_EXCLUSIVE)
74de91cc 3145 {if (comma++) s += wxT(", "); s += langDBINF_EXCLUSIVE;}
69a2b59d 3146 if (pDb->dbInf.lockTypes & SQL_LCK_UNLOCK)
74de91cc
JS
3147 {if (comma++) s += wxT(", "); s += langDBINF_UNLOCK;}
3148 s += wxT("\n");
69a2b59d 3149
6d841efd 3150 comma = false;
69a2b59d
GT
3151 s += langDBINF_POS_OPERS;
3152 if (pDb->dbInf.posOperations & SQL_POS_POSITION)
3153 {s += langDBINF_POSITION; comma++;}
3154 if (pDb->dbInf.posOperations & SQL_POS_REFRESH)
74de91cc 3155 {if (comma++) s += wxT(", "); s += langDBINF_REFRESH;}
69a2b59d 3156 if (pDb->dbInf.posOperations & SQL_POS_UPDATE)
74de91cc 3157 {if (comma++) s += wxT(", "); s += langDBINF_UPD;}
69a2b59d 3158 if (pDb->dbInf.posOperations & SQL_POS_DELETE)
74de91cc 3159 {if (comma++) s += wxT(", "); s += langDBINF_DEL;}
69a2b59d 3160 if (pDb->dbInf.posOperations & SQL_POS_ADD)
74de91cc
JS
3161 {if (comma++) s += wxT(", "); s += langDBINF_ADD;}
3162 s += wxT("\n");
69a2b59d 3163
6d841efd 3164 comma = false;
69a2b59d
GT
3165 s += langDBINF_POS_STMTS;
3166 if (pDb->dbInf.posStmts & SQL_PS_POSITIONED_DELETE)
3167 {s += langDBINF_POS_DEL; comma++;}
3168 if (pDb->dbInf.posStmts & SQL_PS_POSITIONED_UPDATE)
74de91cc 3169 {if (comma++) s += wxT(", "); s += langDBINF_POS_UPD;}
69a2b59d 3170 if (pDb->dbInf.posStmts & SQL_PS_SELECT_FOR_UPDATE)
74de91cc
JS
3171 {if (comma++) s += wxT(", "); s += langDBINF_SELECT_FOR_UPD;}
3172 s += wxT("\n");
69a2b59d 3173
6d841efd 3174 comma = false;
69a2b59d
GT
3175 s += langDBINF_SCROLL_CONCURR;
3176 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_READ_ONLY)
3177 {s += langDBINF_READ_ONLY; comma++;}
3178 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_LOCK)
74de91cc 3179 {if (comma++) s += wxT(", "); s += langDBINF_LOCK;}
69a2b59d 3180 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_OPT_ROWVER)
74de91cc 3181 {if (comma++) s += wxT(", "); s += langDBINF_OPT_ROWVER;}
69a2b59d 3182 if (pDb->dbInf.scrollConcurrency & SQL_SCCO_OPT_VALUES)
74de91cc
JS
3183 {if (comma++) s += wxT(", "); s += langDBINF_OPT_VALUES;}
3184 s += wxT("\n");
69a2b59d 3185
6d841efd 3186 comma = false;
69a2b59d
GT
3187 s += langDBINF_SCROLL_OPTS;
3188 if (pDb->dbInf.scrollOptions & SQL_SO_FORWARD_ONLY)
3189 {s += langDBINF_FWD_ONLY; comma++;}
3190 if (pDb->dbInf.scrollOptions & SQL_SO_STATIC)
74de91cc 3191 {if (comma++) s += wxT(", "); s += langDBINF_STATIC;}
69a2b59d 3192 if (pDb->dbInf.scrollOptions & SQL_SO_KEYSET_DRIVEN)
74de91cc 3193 {if (comma++) s += wxT(", "); s += langDBINF_KEYSET_DRIVEN;}
69a2b59d 3194 if (pDb->dbInf.scrollOptions & SQL_SO_DYNAMIC)
74de91cc 3195 {if (comma++) s += wxT(", "); s += langDBINF_DYNAMIC;}
69a2b59d 3196 if (pDb->dbInf.scrollOptions & SQL_SO_MIXED)
74de91cc
JS
3197 {if (comma++) s += wxT(", "); s += langDBINF_MIXED;}
3198 s += wxT("\n");
69a2b59d 3199
6d841efd 3200 comma = false;
69a2b59d
GT
3201 s += langDBINF_STATIC_SENS;
3202 if (pDb->dbInf.staticSensitivity & SQL_SS_ADDITIONS)
3203 {s += langDBINF_ADDITIONS; comma++;}
3204 if (pDb->dbInf.staticSensitivity & SQL_SS_DELETIONS)
74de91cc 3205 {if (comma++) s += wxT(", "); s += langDBINF_DELETIONS;}
69a2b59d 3206 if (pDb->dbInf.staticSensitivity & SQL_SS_UPDATES)
74de91cc
JS
3207 {if (comma++) s += wxT(", "); s += langDBINF_UPDATES;}
3208 s += wxT("\n");
abfcca57
JJ
3209#ifdef __VMS__
3210#pragma message enable incboodep
3211#endif
69a2b59d
GT
3212
3213
3214 s += langDBINF_TXN_CAPABLE;
3215 switch(pDb->dbInf.txnCapable)
3216 {
3217 case SQL_TC_NONE: s += langNO; break;
3218 case SQL_TC_DML: s += langDBINF_DML_ONLY; break;
da1e87c4
GT
3219 case SQL_TC_DDL_COMMIT: s += langDBINF_DDL_COMMIT; break;
3220 case SQL_TC_DDL_IGNORE: s += langDBINF_DDL_IGNORE; break;
69a2b59d
GT
3221 case SQL_TC_ALL: s += langDBINF_DDL_AND_DML; break;
3222 }
74de91cc 3223 s += wxT("\n");
69a2b59d 3224
74de91cc 3225 t.sprintf(wxT("%s%lu\n"), langDBINF_LOGIN_TIMEOUT, pDb->dbInf.loginTimeout);
69a2b59d
GT
3226 s += t;
3227
3228 // Oracle specific information
3229 if (pDb->Dbms() == dbmsORACLE)
3230 {
74de91cc 3231 s += wxT("\n");
69a2b59d 3232 s += langDBINF_ORACLE_BANNER;
74de91cc 3233 s += wxT("\n");
69a2b59d
GT
3234
3235 // Oracle cache hit ratio
3236 SDWORD cb;
3237 ULONG dbBlockGets;
74de91cc 3238 pDb->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'db block gets'"));
69a2b59d
GT
3239 pDb->GetNext();
3240 if (pDb->GetData(1, SQL_C_ULONG, &dbBlockGets, 0, &cb))
3241 {
74de91cc 3242 t.sprintf(wxT("%s: %lu\n"), langDBINF_DB_BLOCK_GETS, dbBlockGets);
69a2b59d
GT
3243 s += t;
3244 }
3245
3246 ULONG consistentGets;
74de91cc 3247 pDb->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'consistent gets'"));
69a2b59d
GT
3248 pDb->GetNext();
3249 if (pDb->GetData(1, SQL_C_ULONG, &consistentGets, 0, &cb))
3250 {
74de91cc 3251 t.sprintf(wxT("%s: %lu\n"), langDBINF_CONSISTENT_GETS, consistentGets);
69a2b59d
GT
3252 s += t;
3253 }
3254
3255 ULONG physReads;
74de91cc 3256 pDb->ExecSql(wxT("SELECT VALUE FROM V$SYSSTAT WHERE NAME = 'physical reads'"));
69a2b59d
GT
3257 pDb->GetNext();
3258 if (pDb->GetData(1, SQL_C_ULONG, &physReads, 0, &cb))
3259 {
74de91cc 3260 t.sprintf(wxT("%s: %lu\n"), langDBINF_PHYSICAL_READS, physReads);
69a2b59d
GT
3261 s += t;
3262 }
3263
3264 ULONG hitRatio = (ULONG)((1.00 - ((float)physReads / (float)(dbBlockGets + consistentGets))) * 100.00);
74de91cc 3265 t.sprintf(wxT("*** %s: %lu%%\n"), langDBINF_CACHE_HIT_RATIO, hitRatio);
69a2b59d
GT
3266 s += t;
3267
3268 // Tablespace information
74de91cc 3269 s += wxT("\n");
69a2b59d 3270 s += langDBINF_TABLESPACE_IO;
74de91cc 3271 s += wxT("\n");
69a2b59d 3272 ULONG physWrites;
da1e87c4 3273 char tablespaceName[256+1];
74de91cc 3274 pDb->ExecSql(wxT("SELECT NAME,PHYRDS,PHYWRTS FROM V$DATAFILE, V$FILESTAT WHERE V$DATAFILE.FILE# = V$FILESTAT.FILE#"));
69a2b59d
GT
3275 while (pDb->GetNext())
3276 {
da1e87c4
GT
3277 pDb->GetData(1, SQL_C_WXCHAR, tablespaceName, 256, &cb);
3278 pDb->GetData(2, SQL_C_ULONG, &physReads, 0, &cb);
3279 pDb->GetData(3, SQL_C_ULONG, &physWrites, 0, &cb);
74de91cc 3280 t.sprintf(wxT("%s\n\t%s: %lu\t%s: %lu\n"), tablespaceName,
69a2b59d
GT
3281 langDBINF_PHYSICAL_READS, physReads, langDBINF_PHYSICAL_WRITES, physWrites);
3282 s += t;
3283 }
3284
74de91cc 3285 s += wxT("\n");
69a2b59d 3286 }
3f030b48 3287
9b12bd99 3288 s += wxT("End of Diagnostics\n");
3f030b48
GT
3289 wxLogMessage(s);
3290
3291} // DisplayDbDiagnostics()
3292
9b12bd99 3293#if wxUSE_GRID
f21b2fd8
GT
3294
3295BEGIN_EVENT_TABLE(DbGridFrame, wxFrame)
3296 // EVT_CLOSE(DbGridFrame::OnCloseWindow)
3297END_EVENT_TABLE()
3298
3299
3300DbGridFrame::DbGridFrame(wxWindow *parent)
6d841efd 3301 : wxFrame (parent, wxID_ANY, wxT("Database Table"),
2f6c54eb 3302 wxDefaultPosition, wxSize(400, 325))
f21b2fd8 3303{
6d841efd 3304 initialized = false;
f21b2fd8
GT
3305}
3306
3307
9b12bd99 3308void DbGridFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
f21b2fd8
GT
3309{
3310 this->Destroy();
3311}
3312
3313
3314bool DbGridFrame::Initialize()
3315{
6d841efd 3316 wxGrid *grid = new wxGrid(this, wxID_ANY, wxDefaultPosition);
f21b2fd8
GT
3317
3318 grid->RegisterDataType(wxGRID_VALUE_DATETIME,
74de91cc 3319 new wxGridCellDateTimeRenderer(wxT("%d %b %Y")),
f21b2fd8
GT
3320 new wxGridCellTextEditor);
3321#ifdef CHOICEINT
3322 grid->RegisterDataType(wxGRID_VALUE_CHOICEINT,
3323 new wxGridCellEnumRenderer,
3324 new wxGridCellEnumEditor);
925e9792
WS
3325
3326 wxString NativeLangChoice( wxString::Format(wxT("%s:%s,%s,%s,%s,%s"),wxGRID_VALUE_CHOICEINT,
f21b2fd8
GT
3327 wxT("English"),
3328 wxT("French"),
3329 wxT("German"),
3330 wxT("Spanish"),
925e9792 3331 wxT("Other") ));
f21b2fd8
GT
3332#endif
3333
3334 // Columns must match the sequence specified in SetColDef() calls
3335 wxDbGridColInfo* cols =
3336 new wxDbGridColInfo( 0,wxGRID_VALUE_STRING,wxT("Name"),
3337 new wxDbGridColInfo( 1,wxGRID_VALUE_STRING,wxT("Address 1"),
3338 new wxDbGridColInfo( 2,wxGRID_VALUE_STRING,wxT("Address 2"),
3339 new wxDbGridColInfo( 3,wxGRID_VALUE_STRING,wxT("City"),
3340 new wxDbGridColInfo( 4,wxGRID_VALUE_STRING,wxT("State"),
3341 new wxDbGridColInfo( 5,wxGRID_VALUE_STRING,wxT("PostCode"),
3342 new wxDbGridColInfo( 6,wxGRID_VALUE_STRING,wxT("Country"),
3343 new wxDbGridColInfo( 7,wxGRID_VALUE_DBAUTO,wxT("Join Date"),
3344 new wxDbGridColInfo( 8,wxGRID_VALUE_BOOL, wxT("Developer"),
3345 new wxDbGridColInfo( 9,wxGRID_VALUE_NUMBER,wxT("Contributions"),
3346 new wxDbGridColInfo(10,wxGRID_VALUE_NUMBER,wxT("Lines Of Code"),
3347#ifdef CHOICEINT
3348 new wxDbGridColInfo(11,NativeLangChoice, wxT("Native Language"),NULL))))))))))));
925e9792 3349#else
f21b2fd8
GT
3350 new wxDbGridColInfo(11,wxGRID_VALUE_NUMBER,wxT("Native Language"),NULL))))))))))));
3351#endif
3352
3353 Ccontact *Contact = new Ccontact();
3354 //wxGetApp().Contact
3355
3356 if (!Contact)
3357 {
3358 wxMessageBox(wxT("Unable to instantiate an instance of Ccontact"), wxT("Error..."), wxOK | wxICON_EXCLAMATION);
6d841efd 3359 return false;
f21b2fd8
GT
3360 }
3361
3362 if (!Contact->Open())
3363 {
3364 if (Contact->GetDb()->TableExists(CONTACT_TABLE_NAME, Contact->GetDb()->GetUsername(),
3365 wxGetApp().DbConnectInf->GetDefaultDir()))
3366 {
3367 wxString tStr;
51e298bb 3368 tStr.Printf(wxT("Unable to open the table '%s'.\n\n"),CONTACT_TABLE_NAME.c_str());
74de91cc 3369 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8
GT
3370 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
3371 }
3372
6d841efd 3373 return false;
f21b2fd8
GT
3374 }
3375
3376 // Execute the following query using the cursor designated
3377 // for full table query
3378 Contact->SetRowMode(wxDbTable::WX_ROW_MODE_QUERY);
3379
3380 if (!Contact->Query())
3381 {
3382 wxString tStr;
3383 tStr = wxT("ODBC error during Query()\n\n");
74de91cc 3384 wxMessageBox(wxDbLogExtendedErrorMsg(tStr.c_str(),wxGetApp().Contact->GetDb(),__TFILE__,__LINE__),
f21b2fd8 3385 wxT("ODBC Error..."),wxOK | wxICON_EXCLAMATION);
6d841efd 3386 return false;
f21b2fd8
GT
3387 }
3388
3389 // No data has been read in from the database yet, so
3390 // we need to initialize the data members to valid values
3391 // so Fit() can correctly size the grid
3392 Contact->Initialize();
3393
6d841efd 3394 wxDbGridTableBase* db = new wxDbGridTableBase(Contact, cols, wxUSE_QUERY, true);
f21b2fd8
GT
3395
3396 delete cols;
3397
6d841efd 3398 grid->SetTable(db,true);
f21b2fd8 3399 grid->SetMargins(0, 0);
3f030b48 3400
f21b2fd8
GT
3401 grid->Fit();
3402 wxSize size = grid->GetSize();
3403 size.x += 10;
3404 size.y += 10;
3405 SetClientSize(size);
6d841efd
WS
3406 initialized = true;
3407 return true;
f21b2fd8 3408} // DbGridFrame::Initialize()
3f030b48 3409
9b12bd99 3410#endif // #if wxUSE_GRID
3f755e2d
GT
3411
3412/*
3413 TEST CODE FOR TESTING THE wxDbCreateDataSource() FUNCTION
3414
3415 int result = 0;
da1e87c4 3416 result = wxDbCreateDataSource(wxT("Microsoft Access Driver (*.mdb)"), wxT("GLT-TEST2"), wxT("GLT-Descrip"), false, wxEmptyString, this);
3f755e2d
GT
3417 if (!result)
3418 {
3419 // check for errors caused by ConfigDSN based functions
3420 DWORD retcode = 0;
3421 WORD cb;
3422 wxChar errMsg[500+1];
94613352 3423 errMsg[0] = wxT('\0');
3f755e2d 3424
da1e87c4 3425 SQLInstallerError(1, &retcode, errMsg, 500, &cb);
3f755e2d 3426
da1e87c4 3427 wxMessageBox(wxT("FAILED creating data source"), wxT("FAILED"));
3f755e2d
GT
3428 }
3429 else
da1e87c4 3430 wxMessageBox(wxT("SUCCEEDED creating data source"), wxT("SUCCESS"));
3f755e2d
GT
3431*/
3432
3433