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