]> git.saurik.com Git - wxWidgets.git/blame - src/common/dbgrid.cpp
1. make debugging macros compatible with ANSI build even in Unicode build (i.e.,...
[wxWidgets.git] / src / common / dbgrid.cpp
CommitLineData
32a2907b 1///////////////////////////////////////////////////////////////////////////////
670f9935 2// Name: src/common/dbgrid.cpp
32a2907b
GT
3// Purpose: Displays a wxDbTable in a wxGrid.
4// Author: Roger Gammans, Paul Gammans
eae630f1
DW
5// Modified by:
6// Created:
32a2907b
GT
7// RCS-ID: $Id$
8// Copyright: (c) 1999 The Computer Surgery (roger@computer-surgery.co.uk)
65571936 9// Licence: wxWindows licence
32a2907b
GT
10///////////////////////////////////////////////////////////////////////////////
11// Branched From : dbgrid.cpp,v 1.18 2000/12/19 13:00:58
12///////////////////////////////////////////////////////////////////////////////
13
32a2907b
GT
14#include "wx/wxprec.h"
15
16#ifdef __BORLANDC__
17 #pragma hdrstop
18#endif
19
670f9935 20#if wxUSE_ODBC && wxUSE_GRID
32a2907b
GT
21
22#ifndef WX_PRECOMP
23 #include "wx/textctrl.h"
24 #include "wx/dc.h"
670f9935 25 #include "wx/app.h"
32a2907b
GT
26#endif // WX_PRECOMP
27
28#include "wx/generic/gridctrl.h"
29#include "wx/dbgrid.h"
30
34fdf762 31// DLL options compatibility check:
34fdf762
VS
32WX_CHECK_BUILD_OPTIONS("wxDbGrid")
33
32a2907b
GT
34
35wxDbGridCellAttrProvider::wxDbGridCellAttrProvider()
36{
37 m_data=NULL;
38 m_ColInfo=NULL;
39}
40
41wxDbGridCellAttrProvider::wxDbGridCellAttrProvider(wxDbTable *tab, wxDbGridColInfoBase* ColInfo)
42{
43 m_data=tab;
44 m_ColInfo=ColInfo;
45}
46
47wxDbGridCellAttrProvider::~wxDbGridCellAttrProvider()
48{
49}
50
51wxGridCellAttr *wxDbGridCellAttrProvider::GetAttr(int row, int col,
52 wxGridCellAttr::wxAttrKind kind) const
53{
54 wxGridCellAttr *attr = wxGridCellAttrProvider::GetAttr(row,col,kind);
55
56 if (m_data && m_ColInfo && (m_data->GetNumberOfColumns() > m_ColInfo[col].DbCol))
57 {
58 //FIXME: this test could.
59 // ??::InsertPending == m_data->get_ModifiedStatus()
60 // and if InsertPending use colDef[].InsertAllowed
61 if (!(m_data->GetColDefs()[(m_ColInfo[col].DbCol)].Updateable))
62 {
63 switch(kind)
64 {
65 case (wxGridCellAttr::Any):
66 if (!attr)
67 {
68 attr = new wxGridCellAttr;
69 // Store so we don't keep creating / deleting this...
70 wxDbGridCellAttrProvider * self = wxConstCast(this, wxDbGridCellAttrProvider) ;
71 attr->IncRef();
72 self->SetColAttr(attr, col);
73 attr->SetReadOnly();
74 }
75 else
76 {
77 //We now must check what we were returned. and do the right thing (tm)
78 wxGridCellAttr::wxAttrKind attrkind = attr->GetKind();
79 if ((attrkind == (wxGridCellAttr::Default)) || (attrkind == (wxGridCellAttr::Cell)) ||
80 (attrkind == (wxGridCellAttr::Col)))
81 {
82 wxGridCellAttr *attrtomerge = attr;
83 attr = new wxGridCellAttr;
84 attr->SetKind(wxGridCellAttr::Merged);
85 attr->MergeWith(attrtomerge);
86 attr->SetReadOnly();
87 attrtomerge->DecRef();
88 }
89 attr->SetReadOnly();
90 }
91 break;
92 case (wxGridCellAttr::Col):
93 //As we must have a Coll, and were setting Coll attributes
94 // we can based on wxdbTable's so just set RO if attr valid
95 if (!attr)
96 {
97 attr = new wxGridCellAttr;
98 wxDbGridCellAttrProvider * self = wxConstCast(this, wxDbGridCellAttrProvider) ;
99 attr->IncRef();
100 self->SetColAttr(attr, col);
101 }
102 attr->SetReadOnly();
103 break;
104 default:
105 //Dont add RO for...
106 // wxGridCellAttr::Cell - Not required, will inherit on merge from row.
107 // wxGridCellAttr::Row - If wxDbtable ever supports row locking could add
108 // support to make RO on a row basis also.
109 // wxGridCellAttr::Default - Don't edit this ! or all cell with a attr will become readonly
110 // wxGridCellAttr::Merged - This should never be asked for.
111 break;
112 }
113 }
eae630f1 114
32a2907b
GT
115 }
116 return attr;
117}
118
119void wxDbGridCellAttrProvider::AssignDbTable(wxDbTable *tab)
120{
121 m_data = tab;
122}
123
124wxDbGridTableBase::wxDbGridTableBase(wxDbTable *tab, wxDbGridColInfo* ColInfo,
125 int count, bool takeOwnership) :
eae630f1 126 m_keys(),
32a2907b
GT
127 m_data(tab),
128 m_dbowner(takeOwnership),
68379eaf 129 m_rowmodified(false)
32a2907b
GT
130{
131
132 if (count == wxUSE_QUERY)
133 {
134 m_rowtotal = m_data ? m_data->Count() : 0;
135 }
136 else
137 {
138 m_rowtotal = count;
139 }
140// m_keys.Size(m_rowtotal);
141 m_row = -1;
142 if (ColInfo)
143 {
144 m_nocols = ColInfo->Length();
145 m_ColInfo = new wxDbGridColInfoBase[m_nocols];
146 //Do Copy.
147 wxDbGridColInfo *ptr = ColInfo;
148 int i =0;
149 while (ptr && i < m_nocols)
150 {
151 m_ColInfo[i] = ptr->m_data;
152 ptr = ptr->m_next;
153 i++;
154 }
155#ifdef __WXDEBUG__
156 if (ptr)
157 {
158 wxLogDebug(wxT("NoCols over length after traversing %i items"),i);
159 }
160 if (i < m_nocols)
161 {
162 wxLogDebug(wxT("NoCols under length after traversing %i items"),i);
eae630f1 163 }
32a2907b
GT
164#endif
165 }
166}
167
168wxDbGridTableBase::~wxDbGridTableBase()
169{
170 wxDbGridCellAttrProvider *provider;
171
eae630f1 172 //Can't check for update here as
32a2907b
GT
173
174 //FIXME: should i remove m_ColInfo and m_data from m_attrProvider if a wxDbGridAttrProvider
175// if ((provider = dynamic_cast<wxDbGridCellAttrProvider *>(GetAttrProvider())))
77ffb593 176 // Using C casting for now until we can support dynamic_cast with wxWidgets
eae630f1
DW
177 provider = (wxDbGridCellAttrProvider *)(GetAttrProvider());
178 if (provider)
32a2907b
GT
179 {
180 provider->AssignDbTable(NULL);
181 }
182 delete [] m_ColInfo;
eae630f1 183
32a2907b
GT
184 Writeback();
185 if (m_dbowner)
186 {
187 delete m_data;
188 }
189}
190
191bool wxDbGridTableBase::CanHaveAttributes()
192{
193 if (!GetAttrProvider())
194 {
195 // use the default attr provider by default
196 SetAttrProvider(new wxDbGridCellAttrProvider(m_data, m_ColInfo));
197 }
68379eaf 198 return true;
32a2907b
GT
199}
200
201
202bool wxDbGridTableBase::AssignDbTable(wxDbTable *tab, int count, bool takeOwnership)
203{
204 wxDbGridCellAttrProvider *provider;
205
b62f94ff
VZ
206 wxGridUpdateLocker locker(GetView());
207
32a2907b
GT
208 //Remove Information from grid about old data
209 if (GetView())
210 {
211 wxGrid *grid = GetView();
32a2907b
GT
212 grid->ClearSelection();
213 if (grid->IsCellEditControlEnabled())
214 {
215 grid->DisableCellEditControl();
216 }
217 wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_DELETED,0,m_rowtotal);
218 grid->ProcessTableMessage(msg);
219 }
220
221 //reset our internals...
222 Writeback();
223 if (m_dbowner)
224 {
225 delete m_data;
226 }
227 m_keys.Empty();
228 m_data = tab;
eae630f1 229 //FIXME: Remove dynamic_cast before sumision to wxwin
32a2907b 230// if ((provider = dynamic_cast<wxDbGridCellAttrProvider *> (GetAttrProvider())))
77ffb593 231 // Using C casting for now until we can support dynamic_cast with wxWidgets
eae630f1
DW
232 provider = (wxDbGridCellAttrProvider *)(GetAttrProvider());
233 if (provider)
32a2907b
GT
234 {
235 provider->AssignDbTable(m_data);
236 }
eae630f1 237
32a2907b
GT
238 if (count == wxUSE_QUERY)
239 {
240 m_rowtotal = m_data ? m_data->Count() : 0;
241 }
242 else
243 {
244 m_rowtotal = count;
245 }
246 m_row = -1;
247
248 //Add Information to grid about new data
249 if (GetView())
250 {
251 wxGrid * grid = GetView();
252 wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_rowtotal);
253 grid->ProcessTableMessage(msg);
32a2907b
GT
254 }
255 m_dbowner = takeOwnership;
68379eaf
WS
256 m_rowmodified = false;
257 return true;
32a2907b
GT
258}
259
8a39593e 260wxString wxDbGridTableBase::GetTypeName(int WXUNUSED(row), int col)
32a2907b 261{
32a2907b
GT
262 if (GetNumberCols() > col)
263 {
264 if (m_ColInfo[col].wxtypename == wxGRID_VALUE_DBAUTO)
265 {
266 if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
267 {
268 wxFAIL_MSG (_T("You can not use wxGRID_VALUE_DBAUTO for virtual columns"));
269 }
270 switch(m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype)
271 {
272 case SQL_C_CHAR:
92850d6b 273#ifdef SQL_C_WCHAR
5a349c39 274 case SQL_C_WCHAR:
670f9935 275#endif
32a2907b 276 return wxGRID_VALUE_STRING;
5a349c39 277 case SQL_C_SHORT:
32a2907b
GT
278 case SQL_C_SSHORT:
279 return wxGRID_VALUE_NUMBER;
32a2907b
GT
280 case SQL_C_USHORT:
281 return wxGRID_VALUE_NUMBER;
5a349c39 282 case SQL_C_LONG:
32a2907b
GT
283 case SQL_C_SLONG:
284 return wxGRID_VALUE_NUMBER;
32a2907b
GT
285 case SQL_C_ULONG:
286 return wxGRID_VALUE_NUMBER;
32a2907b
GT
287 case SQL_C_FLOAT:
288 return wxGRID_VALUE_FLOAT;
32a2907b
GT
289 case SQL_C_DOUBLE:
290 return wxGRID_VALUE_FLOAT;
32a2907b
GT
291 case SQL_C_DATE:
292 return wxGRID_VALUE_DATETIME;
32a2907b
GT
293 case SQL_C_TIME:
294 return wxGRID_VALUE_DATETIME;
32a2907b
GT
295 case SQL_C_TIMESTAMP:
296 return wxGRID_VALUE_DATETIME;
32a2907b
GT
297 default:
298 return wxGRID_VALUE_STRING;
32a2907b
GT
299 }
300 }
301 else
302 {
303 return m_ColInfo[col].wxtypename;
304 }
305 }
306 wxFAIL_MSG (_T("unknown column"));
307 return wxString();
308}
309
310bool wxDbGridTableBase::CanGetValueAs(int row, int col, const wxString& typeName)
311{
312 wxLogDebug(wxT("CanGetValueAs() on %i,%i"),row,col);
313 //Is this needed? As it will be validated on GetValueAsXXXX
314 ValidateRow(row);
315
316 if (typeName == wxGRID_VALUE_STRING)
317 {
318 //FIXME ummm What about blob field etc.
68379eaf 319 return true;
32a2907b
GT
320 }
321
254a2129 322 if (m_data->IsColNull((UWORD)m_ColInfo[col].DbCol))
32a2907b 323 {
68379eaf 324 return false;
32a2907b
GT
325 }
326
327 if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
328 {
eae630f1 329 //If a virtual column then we can't find it's type. we have to
68379eaf
WS
330 // return false to get using wxVariant.
331 return false;
32a2907b
GT
332 }
333 int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
eae630f1 334
32a2907b
GT
335 if (typeName == wxGRID_VALUE_DATETIME)
336 {
337 if ((sqltype == SQL_C_DATE) ||
eae630f1 338 (sqltype == SQL_C_TIME) ||
32a2907b
GT
339 (sqltype == SQL_C_TIMESTAMP))
340 {
68379eaf 341 return true;
32a2907b 342 }
68379eaf 343 return false;
32a2907b
GT
344 }
345 if (typeName == wxGRID_VALUE_NUMBER)
346 {
347 if ((sqltype == SQL_C_SSHORT) ||
eae630f1 348 (sqltype == SQL_C_USHORT) ||
32a2907b
GT
349 (sqltype == SQL_C_SLONG) ||
350 (sqltype == SQL_C_ULONG))
351 {
68379eaf 352 return true;
32a2907b 353 }
68379eaf 354 return false;
32a2907b
GT
355 }
356 if (typeName == wxGRID_VALUE_FLOAT)
357 {
358 if ((sqltype == SQL_C_SSHORT) ||
eae630f1 359 (sqltype == SQL_C_USHORT) ||
32a2907b
GT
360 (sqltype == SQL_C_SLONG) ||
361 (sqltype == SQL_C_ULONG) ||
362 (sqltype == SQL_C_FLOAT) ||
363 (sqltype == SQL_C_DOUBLE))
364 {
68379eaf 365 return true;
32a2907b 366 }
68379eaf 367 return false;
32a2907b 368 }
68379eaf 369 return false;
32a2907b
GT
370}
371
8a39593e 372bool wxDbGridTableBase::CanSetValueAs(int WXUNUSED(row), int col, const wxString& typeName)
32a2907b 373{
32a2907b
GT
374 if (typeName == wxGRID_VALUE_STRING)
375 {
376 //FIXME ummm What about blob field etc.
68379eaf 377 return true;
32a2907b
GT
378 }
379
380 if (!(m_data->GetColDefs()[(m_ColInfo[col].DbCol)].Updateable))
381 {
68379eaf 382 return false;
32a2907b
GT
383 }
384
385 if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
386 {
eae630f1 387 //If a virtual column then we can't find it's type. we have to faulse to
32a2907b 388 //get using wxVairent.
68379eaf 389 return false;
32a2907b
GT
390 }
391
392 int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
393 if (typeName == wxGRID_VALUE_DATETIME)
394 {
395 if ((sqltype == SQL_C_DATE) ||
eae630f1 396 (sqltype == SQL_C_TIME) ||
32a2907b
GT
397 (sqltype == SQL_C_TIMESTAMP))
398 {
68379eaf 399 return true;
32a2907b 400 }
68379eaf 401 return false;
32a2907b
GT
402 }
403 if (typeName == wxGRID_VALUE_NUMBER)
404 {
405 if ((sqltype == SQL_C_SSHORT) ||
eae630f1 406 (sqltype == SQL_C_USHORT) ||
32a2907b
GT
407 (sqltype == SQL_C_SLONG) ||
408 (sqltype == SQL_C_ULONG))
409 {
68379eaf 410 return true;
32a2907b 411 }
68379eaf 412 return false;
32a2907b
GT
413 }
414 if (typeName == wxGRID_VALUE_FLOAT)
415 {
416 if ((sqltype == SQL_C_SSHORT) ||
eae630f1 417 (sqltype == SQL_C_USHORT) ||
32a2907b
GT
418 (sqltype == SQL_C_SLONG) ||
419 (sqltype == SQL_C_ULONG) ||
420 (sqltype == SQL_C_FLOAT) ||
421 (sqltype == SQL_C_DOUBLE))
422 {
68379eaf 423 return true;
32a2907b 424 }
68379eaf 425 return false;
32a2907b 426 }
68379eaf 427 return false;
32a2907b
GT
428}
429
430long wxDbGridTableBase::GetValueAsLong(int row, int col)
431{
432 ValidateRow(row);
433
434 if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
435 {
436 wxFAIL_MSG (_T("You can not use GetValueAsLong for virtual columns"));
437 return 0;
438 }
439 int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
440 if ((sqltype == SQL_C_SSHORT) ||
eae630f1 441 (sqltype == SQL_C_USHORT) ||
32a2907b
GT
442 (sqltype == SQL_C_SLONG) ||
443 (sqltype == SQL_C_ULONG))
444 {
b8032740 445 wxVariant val = m_data->GetColumn(m_ColInfo[col].DbCol);
32a2907b
GT
446 return val.GetLong();
447 }
448 wxFAIL_MSG (_T("unknown column, "));
449 return 0;
450}
451
452double wxDbGridTableBase::GetValueAsDouble(int row, int col)
453{
454 wxLogDebug(wxT("GetValueAsDouble() on %i,%i"),row,col);
455 ValidateRow(row);
456
457 if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
458 {
459 wxFAIL_MSG (_T("You can not use GetValueAsDouble for virtual columns"));
460 return 0.0;
461 }
462 int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
463 if ((sqltype == SQL_C_SSHORT) ||
eae630f1 464 (sqltype == SQL_C_USHORT) ||
32a2907b
GT
465 (sqltype == SQL_C_SLONG) ||
466 (sqltype == SQL_C_ULONG) ||
467 (sqltype == SQL_C_FLOAT) ||
468 (sqltype == SQL_C_DOUBLE))
469 {
b8032740 470 wxVariant val = m_data->GetColumn(m_ColInfo[col].DbCol);
32a2907b
GT
471 return val.GetDouble();
472 }
473 wxFAIL_MSG (_T("unknown column"));
474 return 0.0;
475}
476
477bool wxDbGridTableBase::GetValueAsBool(int row, int col)
478{
479 wxLogDebug(wxT("GetValueAsBool() on %i,%i"),row,col);
480 ValidateRow(row);
481
482 if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
483 {
484 wxFAIL_MSG (_T("You can not use GetValueAsBool for virtual columns"));
485 return 0;
486 }
487 int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
488 if ((sqltype == SQL_C_SSHORT) ||
eae630f1 489 (sqltype == SQL_C_USHORT) ||
32a2907b
GT
490 (sqltype == SQL_C_SLONG) ||
491 (sqltype == SQL_C_ULONG))
492 {
b8032740 493 wxVariant val = m_data->GetColumn(m_ColInfo[col].DbCol);
32a2907b
GT
494 return val.GetBool();
495 }
496 wxFAIL_MSG (_T("unknown column, "));
497 return 0;
498}
499
500void* wxDbGridTableBase::GetValueAsCustom(int row, int col, const wxString& typeName)
501{
502 wxLogDebug(wxT("GetValueAsCustom() on %i,%i"),row,col);
503 ValidateRow(row);
eae630f1 504
32a2907b
GT
505 if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
506 {
507 wxFAIL_MSG (_T("You can not use GetValueAsCustom for virtual columns"));
508 return NULL;
509 }
254a2129 510 if (m_data->IsColNull((UWORD)m_ColInfo[col].DbCol))
32a2907b
GT
511 return NULL;
512
513 if (typeName == wxGRID_VALUE_DATETIME)
514 {
515 wxDbColDef *pColDefs = m_data->GetColDefs();
516 int sqltype = pColDefs[(m_ColInfo[col].DbCol)].SqlCtype;
517
518 if ((sqltype == SQL_C_DATE) ||
519 (sqltype == SQL_C_TIME) ||
520 (sqltype == SQL_C_TIMESTAMP))
521 {
b8032740 522 wxVariant val = m_data->GetColumn(m_ColInfo[col].DbCol);
32a2907b
GT
523 return new wxDateTime(val.GetDateTime());
524 }
525 }
526 wxFAIL_MSG (_T("unknown column data type "));
527 return NULL;
528}
529
530
531void wxDbGridTableBase::SetValueAsCustom(int row, int col, const wxString& typeName, void* value)
532{
533 wxLogDebug(wxT("SetValueAsCustom() on %i,%i"),row,col);
534 ValidateRow(row);
535
536 if (m_data->GetNumberOfColumns() <= m_ColInfo[col].DbCol)
537 {
538 wxFAIL_MSG (_T("You can not use SetValueAsCustom for virtual columns"));
539 return;
540 }
541
542 if (typeName == wxGRID_VALUE_DATETIME)
543 {
544 int sqltype = m_data->GetColDefs()[(m_ColInfo[col].DbCol)].SqlCtype;
545 if ((sqltype == SQL_C_DATE) ||
546 (sqltype == SQL_C_TIME) ||
547 (sqltype == SQL_C_TIMESTAMP))
548 {
549 //FIXME: you can't dynamic_cast from (void *)
550 //wxDateTime *date = wxDynamicCast(value, wxDateTime);
551 wxDateTime *date = (wxDateTime *)value;
552 if (!date)
553 {
554 wxFAIL_MSG (_T("Failed to convert data"));
555 return;
556 }
557 wxVariant val(date);
68379eaf 558 m_rowmodified = true;
b8032740 559 m_data->SetColumn(m_ColInfo[col].DbCol,val);
32a2907b
GT
560 }
561 }
562 wxFAIL_MSG (_T("unknown column data type"));
563 return ;
564}
565
566
567wxString wxDbGridTableBase::GetColLabelValue(int col)
568{
569 if (GetNumberCols() > col)
570 {
571 return m_ColInfo[col].Title;
572 }
573 wxFAIL_MSG (_T("unknown column"));
574 return wxString();
575}
576
577bool wxDbGridTableBase::IsEmptyCell(int row, int col)
578{
579 wxLogDebug(wxT("IsEmtpyCell on %i,%i"),row,col);
580
581 ValidateRow(row);
254a2129 582 return m_data->IsColNull((UWORD)m_ColInfo[col].DbCol);
32a2907b
GT
583}
584
585
586wxString wxDbGridTableBase::GetValue(int row, int col)
587{
588 wxLogDebug(wxT("GetValue() on %i,%i"),row,col);
eae630f1 589
32a2907b 590 ValidateRow(row);
b8032740 591 wxVariant val = m_data->GetColumn(m_ColInfo[col].DbCol);
32a2907b 592 wxLogDebug(wxT("\tReturning \"%s\"\n"),val.GetString().c_str());
eae630f1
DW
593
594 return val.GetString();
32a2907b
GT
595}
596
597
598void wxDbGridTableBase::SetValue(int row, int col,const wxString& value)
599{
600 wxLogDebug(wxT("SetValue() on %i,%i"),row,col);
601
602 ValidateRow(row);
603 wxVariant val(value);
604
68379eaf 605 m_rowmodified = true;
b8032740 606 m_data->SetColumn(m_ColInfo[col].DbCol,val);
32a2907b
GT
607}
608
609
610void wxDbGridTableBase::SetValueAsLong(int row, int col, long value)
611{
612 wxLogDebug(wxT("SetValueAsLong() on %i,%i"),row,col);
613
614 ValidateRow(row);
615 wxVariant val(value);
616
68379eaf 617 m_rowmodified = true;
b8032740 618 m_data->SetColumn(m_ColInfo[col].DbCol,val);
32a2907b
GT
619}
620
621
622void wxDbGridTableBase::SetValueAsDouble(int row, int col, double value)
623{
624 wxLogDebug(wxT("SetValueAsDouble() on %i,%i"),row,col);
625
626 ValidateRow(row);
627 wxVariant val(value);
628
68379eaf 629 m_rowmodified = true;
b8032740 630 m_data->SetColumn(m_ColInfo[col].DbCol,val);
32a2907b
GT
631
632}
633
634
635void wxDbGridTableBase::SetValueAsBool(int row, int col, bool value)
636{
637 wxLogDebug(wxT("SetValueAsBool() on %i,%i"),row,col);
638
639 ValidateRow(row);
640 wxVariant val(value);
641
68379eaf 642 m_rowmodified = true;
b8032740 643 m_data->SetColumn(m_ColInfo[col].DbCol,val);
32a2907b
GT
644}
645
646
647void wxDbGridTableBase::ValidateRow(int row)
648{
a855f8cc
VZ
649 wxLogDebug(wxT("ValidateRow(%i) currently on row (%i). Array count = %lu"),
650 row, m_row, (unsigned long)m_keys.GetCount());
32a2907b
GT
651
652 if (row == m_row)
653 return;
654 Writeback();
655
656 //We add to row as Count is unsigned!
657 if ((unsigned)(row+1) > m_keys.GetCount())
658 {
659 wxLogDebug(wxT("\trow key unknown"));
660 // Extend Array, iterate through data filling with keys
661 m_data->SetRowMode(wxDbTable::WX_ROW_MODE_QUERY);
662 int trow;
663 for (trow = m_keys.GetCount(); trow <= row; trow++)
664 {
665 wxLogDebug(wxT("Fetching row %i.."), trow);
666 bool ret = m_data->GetNext();
667
668 wxLogDebug(wxT(" ...success=(%i)"),ret);
669 GenericKey k = m_data->GetKey();
670 m_keys.Add(k);
671 }
672 m_row = row;
673 }
674 else
675 {
676 wxLogDebug(wxT("\trow key known centering data"));
677 GenericKey k = m_keys.Item(row);
678 m_data->SetRowMode(wxDbTable::WX_ROW_MODE_INDIVIDUAL);
679 m_data->ClearMemberVars();
680 m_data->SetKey(k);
681 if (!m_data->QueryOnKeyFields())
682 {
8a39593e 683 wxDbLogExtendedErrorMsg(_T("ODBC error during Query()\n\n"), m_data->GetDb(),__TFILE__,__LINE__);
32a2907b
GT
684 }
685
686 m_data->GetNext();
687
688 m_row = row;
689 }
68379eaf 690 m_rowmodified = false;
32a2907b
GT
691}
692
693bool wxDbGridTableBase::Writeback() const
694{
695 if (!m_rowmodified)
696 {
68379eaf 697 return true;
32a2907b
GT
698 }
699
68379eaf 700 bool result=true;
32a2907b
GT
701 wxLogDebug(wxT("\trow key unknown"));
702
eae630f1 703// FIXME: this code requires dbtable support for record status
32a2907b
GT
704#if 0
705 switch (m_data->get_ModifiedStatus())
706 {
707 case wxDbTable::UpdatePending:
708 result = m_data->Update();
709 break;
710 case wxDbTable::InsertPending:
711 result = (m_data->Insert() == SQL_SUCCESS);
712 break;
713 default:
714 //Nothing
715 break;
716 }
717#else
718 wxLogDebug(wxT("WARNING : Row writeback not implemented "));
719#endif
720 return result;
721}
722
4498031c 723#include "wx/arrimpl.cpp"
32a2907b 724
ae199d6e 725WX_DEFINE_EXPORTED_OBJARRAY(keyarray)
32a2907b 726
670f9935 727#endif // wxUSE_GRID && wxUSE_ODBC