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