00001
00002
00003
00004
00005
00006
00007 #include "AddressGridTable.h"
00008
00009 #include "wx/arrimpl.cpp"
00010 WX_DEFINE_OBJARRAY(StringArray);
00011 WX_DEFINE_OBJARRAY(StringGrid);
00012
00013
00014 void wxGridTableBaseWithNotifyMethods::RequestViewGetValues()
00015 {
00016 wxGrid* pView = GetView();
00017 if (pView) {
00018 wxGridTableMessage msg(this, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES);
00019 pView->ProcessTableMessage(msg);
00020 }
00021 }
00022
00023 void wxGridTableBaseWithNotifyMethods::RequestViewSendValues()
00024 {
00025 wxGrid* pView = GetView();
00026 if (pView) {
00027 wxGridTableMessage msg(this, wxGRIDTABLE_REQUEST_VIEW_SEND_VALUES);
00028 pView->ProcessTableMessage(msg);
00029 }
00030 }
00031
00032 void wxGridTableBaseWithNotifyMethods::NotifyRowsInserted(int pos, int numRows)
00033 {
00034 wxGrid* pView = GetView();
00035 if (pView) {
00036 wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, pos, numRows);
00037 pView->ProcessTableMessage(msg);
00038 }
00039 }
00040
00041 void wxGridTableBaseWithNotifyMethods::NotifyRowsAppended(int numRows)
00042 {
00043 wxGrid* pView = GetView();
00044 if (pView) {
00045 wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, numRows);
00046 pView->ProcessTableMessage(msg);
00047 }
00048 }
00049
00050 void wxGridTableBaseWithNotifyMethods::NotifyRowsDeleted(int pos, int numRows)
00051 {
00052 wxGrid* pView = GetView();
00053 if (pView) {
00054 wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, pos, numRows);
00055 pView->ProcessTableMessage(msg);
00056 }
00057 }
00058
00059 void wxGridTableBaseWithNotifyMethods::NotifyColsInserted(int pos, int numCols)
00060 {
00061 wxGrid* pView = GetView();
00062 if (pView) {
00063 wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_COLS_INSERTED, pos, numCols);
00064 pView->ProcessTableMessage(msg);
00065 }
00066 }
00067
00068 void wxGridTableBaseWithNotifyMethods::NotifyColsAppended(int numCols)
00069 {
00070 wxGrid* pView = GetView();
00071 if (pView) {
00072 wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_COLS_APPENDED, numCols);
00073 pView->ProcessTableMessage(msg);
00074 }
00075 }
00076
00077 void wxGridTableBaseWithNotifyMethods::NotifyColsDeleted(int pos, int numCols)
00078 {
00079 wxGrid* pView = GetView();
00080 if (pView) {
00081 wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_COLS_DELETED, pos, numCols);
00082 pView->ProcessTableMessage(msg);
00083 }
00084 }
00085
00086
00088
00089
00090
00091
00092
00093
00094
00095 bool isEmpty(StringArray& row, size_t cols)
00096 {
00097 for (size_t j = 0; j < cols; j++) if (row[j].Length()) return false;
00098 return true;
00099 }
00100
00101 void AddressGridTable::serialize(wxDataOutputStream& out)
00102 {
00103
00104 size_t cols = GetNumberCols();
00105 size_t rows = GetNumberRows();
00106
00107
00108 size_t textRows = 0;
00109 size_t i;
00110 for (i = 0; i < rows; i++) {
00111 if (!isEmpty(m_data[i], cols)) textRows++;
00112 }
00113
00114
00115 out.Write32(cols);
00116 out.Write32(textRows);
00117
00118
00119 wxGrid* pView = GetView();
00120 for (i = 0; i < cols; i++) {
00121 out.WriteString(GetColLabelValue(i));
00122 out.Write32(pView->GetColumnWidth(i));
00123 }
00124
00125
00126 for (i = 0; i < rows; i++) {
00127 if (!isEmpty(m_data[i], cols)) {
00128 for (size_t j = 0; j < cols; j++) out.WriteString(m_data[i][j]);
00129 }
00130 }
00131 }
00132
00133 int AddressGridTable::GetNumberRows()
00134 {
00135 return m_data.GetCount();
00136 }
00137
00138 int AddressGridTable::GetNumberCols()
00139 {
00140 return m_colLabels.GetCount();
00141 }
00142
00143 wxString AddressGridTable::GetValue( int row, int col )
00144 {
00145 wxASSERT_MSG( (row < GetNumberRows()) && (col < GetNumberCols()),
00146 _T("invalid row or column index in AddressGridTable") );
00147
00148 return m_data[row][col];
00149 }
00150
00151 void AddressGridTable::SetValue( int row, int col, const wxString& value )
00152 {
00153 wxASSERT_MSG( (row < GetNumberRows()) && (col < GetNumberCols()),
00154 _T("invalid row or column index in AddressGridTable") );
00155
00156 m_data[row][col] = value;
00157 }
00158
00159 bool AddressGridTable::IsEmptyCell( int row, int col )
00160 {
00161 wxASSERT_MSG( (row < GetNumberRows()) && (col < GetNumberCols()),
00162 _T("invalid row or column index in AddressGridTable") );
00163
00164 return (m_data[row][col] == wxEmptyString);
00165 }
00166
00167 void AddressGridTable::Clear()
00168 {
00169 int row, col;
00170 int numRows, numCols;
00171
00172 numRows = m_data.GetCount();
00173 if ( numRows > 0 )
00174 {
00175 numCols = m_data[0].GetCount();
00176
00177 for ( row = 0; row < numRows; row++ )
00178 {
00179 for ( col = 0; col < numCols; col++ )
00180 {
00181 m_data[row][col] = wxEmptyString;
00182 }
00183 }
00184 }
00185 }
00186
00187
00188 bool AddressGridTable::InsertRows( size_t pos, size_t numRows )
00189 {
00190 size_t row, col;
00191
00192 size_t curNumRows = m_data.GetCount();
00193 size_t curNumCols = ( curNumRows > 0 ? m_data[0].GetCount() :
00194 ( GetView() ? GetView()->GetNumberCols() : 0 ) );
00195
00196 if ( pos >= curNumRows )
00197 {
00198 return AppendRows( numRows );
00199 }
00200
00201 StringArray sa;
00202 sa.Alloc( curNumCols );
00203 for ( col = 0; col < curNumCols; col++ )
00204 {
00205 sa.Add( wxEmptyString );
00206 }
00207
00208 for ( row = pos; row < pos + numRows; row++ )
00209 {
00210 m_data.Insert( sa, row );
00211 }
00212 NotifyRowsInserted(pos, numRows);
00213
00214 return TRUE;
00215 }
00216
00217 bool AddressGridTable::AppendRows( size_t numRows )
00218 {
00219 size_t row, col;
00220
00221 size_t curNumRows = m_data.GetCount();
00222 size_t curNumCols = ( curNumRows > 0 ? m_data[0].GetCount() :
00223 ( GetView() ? GetView()->GetNumberCols() : 0 ) );
00224
00225 StringArray sa;
00226 if ( curNumCols > 0 )
00227 {
00228 sa.Alloc( curNumCols );
00229 for ( col = 0; col < curNumCols; col++ )
00230 {
00231 sa.Add( wxEmptyString );
00232 }
00233 }
00234
00235 for ( row = 0; row < numRows; row++ )
00236 {
00237 m_data.Add( sa );
00238 }
00239 NotifyRowsAppended(numRows);
00240
00241 return TRUE;
00242 }
00243
00244 bool AddressGridTable::DeleteRows( size_t pos, size_t numRows )
00245 {
00246 size_t n;
00247
00248 size_t curNumRows = m_data.GetCount();
00249
00250 if ( pos >= curNumRows )
00251 {
00252 wxString errmsg;
00253 errmsg.Printf(wxT("Called AddressGridTable::DeleteRows(pos=%d, N=%d)\nPos value is invalid for present table with %d rows"),
00254 pos, numRows, curNumRows );
00255 wxFAIL_MSG( errmsg );
00256 return FALSE;
00257 }
00258
00259 if ( numRows > curNumRows - pos )
00260 {
00261 numRows = curNumRows - pos;
00262 }
00263
00264 if ( numRows >= curNumRows )
00265 {
00266 m_data.Empty();
00267 }
00268 else
00269 {
00270 for ( n = 0; n < numRows; n++ )
00271 {
00272 m_data.RemoveAt( pos );
00273 }
00274 }
00275 NotifyRowsDeleted(pos, numRows);
00276
00277 return TRUE;
00278 }
00279
00280 bool AddressGridTable::InsertCols( size_t pos, size_t numCols )
00281 {
00282 size_t row, col;
00283
00284 size_t curNumRows = m_data.GetCount();
00285 size_t curNumCols = ( curNumRows > 0 ? m_data[0].GetCount() :
00286 ( GetView() ? GetView()->GetNumberCols() : 0 ) );
00287
00288 if ( pos >= curNumCols )
00289 {
00290 return AppendCols( numCols );
00291 }
00292
00293 for ( row = 0; row < curNumRows; row++ )
00294 {
00295 for ( col = pos; col < pos + numCols; col++ )
00296 {
00297 m_data[row].Insert( wxEmptyString, col );
00298 }
00299 }
00300 NotifyColsInserted(pos, numCols);
00301
00302 return TRUE;
00303 }
00304
00305 bool AddressGridTable::AppendCols( size_t numCols )
00306 {
00307 size_t row, n;
00308
00309 size_t curNumRows = m_data.GetCount();
00310
00311 for ( row = 0; row < curNumRows; row++ )
00312 {
00313 for ( n = 0; n < numCols; n++ )
00314 {
00315 m_data[row].Add( wxEmptyString );
00316 }
00317 }
00318 NotifyColsAppended(numCols);
00319
00320 return TRUE;
00321 }
00322
00323 bool AddressGridTable::DeleteCols( size_t pos, size_t numCols )
00324 {
00325 size_t row, n;
00326
00327 size_t curNumRows = m_data.GetCount();
00328 size_t curNumCols = ( curNumRows > 0 ? m_data[0].GetCount() :
00329 ( GetView() ? GetView()->GetNumberCols() : 0 ) );
00330
00331 if ( pos >= curNumCols )
00332 {
00333 wxString errmsg;
00334 errmsg.Printf( wxT("Called AddressGridTable::DeleteCols(pos=%d, N=%d)...\nPos value is invalid for present table with %d cols"),
00335 pos, numCols, curNumCols );
00336 wxFAIL_MSG( errmsg );
00337 return FALSE;
00338 }
00339
00340 if ( numCols > curNumCols - pos )
00341 {
00342 numCols = curNumCols - pos;
00343 }
00344
00345 for ( row = 0; row < curNumRows; row++ )
00346 {
00347 if ( numCols >= curNumCols )
00348 {
00349 m_data[row].Clear();
00350 }
00351 else
00352 {
00353 for ( n = 0; n < numCols; n++ )
00354 {
00355 m_data[row].RemoveAt( pos );
00356 }
00357 }
00358 }
00359 NotifyColsDeleted(pos, numCols);
00360
00361 return TRUE;
00362 }
00363
00364 wxString AddressGridTable::GetColLabelValue( int col )
00365 {
00366 if ( col > (int)(m_colLabels.GetCount()) - 1 )
00367 {
00368
00369
00370 return wxGridTableBase::GetColLabelValue( col );
00371 }
00372 else
00373 {
00374 return m_colLabels[ col ];
00375 }
00376 }
00377
00378 void AddressGridTable::SetColLabelValue( int col, const wxString& value )
00379 {
00380 if ( col > (int)(m_colLabels.GetCount()) - 1 )
00381 {
00382 int n = m_colLabels.GetCount();
00383 int i;
00384 for ( i = n; i <= col; i++ )
00385 {
00386 m_colLabels.Add( wxGridTableBase::GetColLabelValue(i) );
00387 }
00388 }
00389
00390 m_colLabels[col] = value;
00391 }
00392
00393 void AddressGridTable::ClearAll()
00394 {
00395 int rows = m_data.GetCount();
00396 m_data = StringGrid();
00397 NotifyRowsDeleted(0, rows);
00398
00399 int cols = m_colLabels.GetCount();
00400 m_colLabels = StringArray();
00401 NotifyColsDeleted(0, cols);
00402 }
00403
00404 void AddressGridTable::Initialize()
00405 {
00406 ClearAll();
00407 m_colLabels.Add("eMail");
00408 m_colLabels.Add("Handy");
00409 m_colLabels.Add("SMS-Export");
00410 m_colLabels.Add("Fax");
00411 StringArray empty;
00412 empty.Add(wxEmptyString);
00413 empty.Add(wxEmptyString);
00414 empty.Add(wxEmptyString);
00415 empty.Add(wxEmptyString);
00416 m_data.Add(empty);
00417 NotifyColsAppended(4);
00418 NotifyRowsAppended(1);
00419 }
00420
00421
00422 void AddressGridTable::Initialize(wxDataInputStream& in)
00423 {
00424 ClearAll();
00425
00426
00427 size_t cols = in.Read32();
00428 size_t rows = in.Read32();
00429
00430
00431 NotifyColsAppended(cols);
00432
00433
00434 size_t i;
00435 wxGrid* pView = GetView();
00436 for (i = 0; i < cols; i++) {
00437 m_colLabels.Add(in.ReadString());
00438 pView->SetColumnWidth(i, in.Read32());
00439 }
00440
00441
00442 m_data.Alloc(rows + 1);
00443 for (i = 0; i < rows; i++) {
00444 StringArray row;
00445 row.Alloc(cols);
00446 for (size_t j = 0; j < cols; j++) {
00447 row.Add(in.ReadString());
00448 }
00449 m_data.Add(row);
00450 }
00451
00452
00453 StringArray empty;
00454 empty.Alloc(cols);
00455 for (i = 0; i < cols; i++) empty.Add(wxEmptyString);
00456 m_data.Add(empty);
00457
00458
00459 NotifyRowsAppended(rows + 1);
00460 }
00461
00462
00463 int gSortCol1;
00464 int gSortCol2;
00465 int gSortCol3;
00466 StringGrid* gSortGrid;
00467 wxUint32* gSortArray;
00468
00469 int compare(const void *arg1, const void *arg2)
00470 {
00471 wxUint32 index1 = *((wxUint32*)arg1);
00472 wxUint32 index2 = *((wxUint32*)arg2);
00473 wxString& value1 = (*gSortGrid)[index1][gSortCol1];
00474 wxString& value2 = (*gSortGrid)[index2][gSortCol1];
00475 if (value1.Length() == 0) return 1;
00476 if (value2.Length() == 0) return -1;
00477 int cmp = value1.CmpNoCase(value2);
00478 if (cmp != 0) return cmp;
00479 if (gSortCol2 < 0) return cmp;
00480 wxString& value3 = (*gSortGrid)[index1][gSortCol2];
00481 wxString& value4 = (*gSortGrid)[index2][gSortCol2];
00482 if (value3.Length() == 0) return 1;
00483 if (value4.Length() == 0) return -1;
00484 cmp = value3.CmpNoCase(value4);
00485 if (cmp != 0) return cmp;
00486 if (gSortCol3 < 0) return cmp;
00487 wxString& value5 = (*gSortGrid)[index1][gSortCol3];
00488 wxString& value6 = (*gSortGrid)[index2][gSortCol3];
00489 if (value5.Length() == 0) return 1;
00490 if (value6.Length() == 0) return -1;
00491 return value5.CmpNoCase(value6);
00492 }
00493
00494 void AddressGridTable::Sort(int col1, int col2, int col3)
00495 {
00496 gSortCol1 = col1;
00497 gSortCol2 = col2;
00498 gSortCol3 = col3;
00499
00500
00501 unsigned rowCount = GetNumberRows();
00502 gSortArray = new wxUint32[rowCount];
00503 size_t i;
00504 for (i = 0; i < rowCount; i++) gSortArray[i] = i;
00505
00506
00507 gSortGrid = &m_data;
00508 qsort((void *)gSortArray, rowCount, sizeof(wxUint32), compare);
00509
00510
00511 unsigned colCount = GetNumberCols();
00512 unsigned newCount = 0;
00513 StringGrid newGrid = StringGrid();
00514 newGrid.Alloc(rowCount);
00515 for (i = 0; i < rowCount; i++)
00516 {
00517 unsigned len = 0;
00518 for (unsigned j = 0; j < colCount; j++) {
00519 wxString& value = m_data[gSortArray[i]][j];
00520 len += value.Length();
00521 }
00522 if (len > 0) {
00523 newGrid.Add(m_data[gSortArray[i]]);
00524 newCount++;
00525 }
00526 }
00527 delete [] gSortArray;
00528
00529
00530 m_data = newGrid;
00531
00532
00533 NotifyRowsDeleted(0, rowCount);
00534 NotifyRowsAppended(newCount);
00535 }
00536
00537
00538 void AddressGridTable::ChangeColumns(ColumnFieldArray& columns)
00539 {
00540
00541 size_t cols = columns.GetCount();
00542 size_t rows = GetNumberRows();
00543
00544
00545 StringGrid newGrid = StringGrid();
00546 StringArray newColLabels;
00547 newGrid.Alloc(rows);
00548 StringArray empty;
00549 empty.Alloc(cols);
00550 size_t i;
00551 for (i = 0; i < cols; i++) empty.Add(wxEmptyString);
00552 for (i = 0; i < rows; i++) newGrid.Add(empty);
00553
00554
00555 for (i = 0; i < cols; i++)
00556 {
00557
00558 int oldIndex = columns[i].getOldIndex();
00559 newColLabels.Add(columns[i].getName());
00560
00561
00562 if (!columns[i].isNew()) {
00563 for (size_t j = 0; j < rows; j++) {
00564 newGrid[j][i] = m_data[j][oldIndex];
00565 }
00566 }
00567 }
00568
00569
00570 ClearAll();
00571 m_data = newGrid;
00572 m_colLabels = newColLabels;
00573
00574
00575 NotifyColsAppended(cols);
00576 NotifyRowsAppended(rows);
00577
00578
00579 wxGrid* pView = GetView();
00580 for (i = 0; i < cols; i++)
00581 {
00582 if (!columns[i].isNew()) {
00583 pView->SetColumnWidth(i, columns[i].getOldWidth());
00584 }
00585 }
00586 }
00587