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