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