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