1 /*
2 / ResultSetView.cpp
3 / a panel to show SQL query results
4 /
5 / version 1.7, 2013 May 8
6 /
7 / Author: Sandro Furieri a-furieri@lqt.it
8 /
9 / Copyright (C) 2008-2013 Alessandro Furieri
10 /
11 / This program is free software: you can redistribute it and/or modify
12 / it under the terms of the GNU General Public License as published by
13 / the Free Software Foundation, either version 3 of the License, or
14 / (at your option) any later version.
15 /
16 / This program is distributed in the hope that it will be useful,
17 / but WITHOUT ANY WARRANTY; without even the implied warranty of
18 / MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 / GNU General Public License for more details.
20 /
21 / You should have received a copy of the GNU General Public License
22 / along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /
24 */
25
26 #include "Classdef.h"
27
28 #include "wx/clipbrd.h"
29 #include "wx/filename.h"
30
31 #include "gaiagraphics.h"
32
33 #ifdef _WIN32
34 #include <windows.h>
35 #include <process.h>
36 #include <io.h>
37 #else
38 #include <pthread.h>
39 #include <unistd.h>
40 #endif
41
42 //
43 // ICONs in XPM format [universally portable]
44 //
45 #include "icons/rs_first.xpm"
46 #include "icons/rs_last.xpm"
47 #include "icons/rs_next.xpm"
48 #include "icons/rs_previous.xpm"
49 #include "icons/refresh.xpm"
50
51 #if defined(_WIN32) || defined (__MINGW32__)
52 #define FORMAT_64 "%I64d"
53 #else
54 #define FORMAT_64 "%lld"
55 #endif
56
MyResultSetView(MyFrame * parent,wxWindowID id)57 MyResultSetView::MyResultSetView(MyFrame * parent, wxWindowID id):
58 wxPanel(parent, id, wxDefaultPosition, wxSize(440, 480), wxBORDER_SUNKEN)
59 {
60 //
61 // constructor: a frame for SQL Result Sets
62 //
63 RsBlock = 500; // the ResultSet block size
64 RowIds = new sqlite3_int64[RsBlock];
65 ReadOnly = true;
66 InsertRow = NULL;
67 MainFrame = parent;
68 BtnRsFirst =
69 new wxBitmapButton(this, ID_RS_FIRST, wxBitmap(rs_first_xpm),
70 wxPoint(5, 400), wxSize(32, 32));
71 BtnRsFirst->SetToolTip(wxT("ResultSet: go to first row"));
72 BtnRsPrevious =
73 new wxBitmapButton(this, ID_RS_PREVIOUS, wxBitmap(rs_previous_xpm),
74 wxPoint(55, 400), wxSize(32, 32));
75 BtnRsPrevious->SetToolTip(wxT("ResultSet: go to previous block"));
76 BtnRefresh =
77 new wxBitmapButton(this, ID_REFRESH, wxBitmap(refresh_xpm),
78 wxPoint(55, 400), wxSize(32, 32));
79 BtnRefresh->SetToolTip(wxT("ResultSet: refresh"));
80 BtnRsNext =
81 new wxBitmapButton(this, ID_RS_NEXT, wxBitmap(rs_next_xpm),
82 wxPoint(105, 400), wxSize(32, 32));
83 BtnRsNext->SetToolTip(wxT("ResultSet: go to next block"));
84 BtnRsLast =
85 new wxBitmapButton(this, ID_RS_LAST, wxBitmap(rs_last_xpm),
86 wxPoint(155, 400), wxSize(32, 32));
87 BtnRsLast->SetToolTip(wxT("ResultSet: go to last row"));
88 RsCurrentBlock =
89 new wxStaticText(this, ID_RS_BLOCK, wxT(""), wxPoint(210, 400),
90 wxSize(200, 18));
91 TableView = NULL;
92 TableBlobs = NULL;
93 TableValues = NULL;
94 CurrentBlob = NULL;
95 // setting up event handlers
96 Connect(ID_RS_FIRST, wxEVT_COMMAND_BUTTON_CLICKED,
97 (wxObjectEventFunction) & MyResultSetView::OnRsFirst);
98 Connect(ID_RS_PREVIOUS, wxEVT_COMMAND_BUTTON_CLICKED,
99 (wxObjectEventFunction) & MyResultSetView::OnRsPrevious);
100 Connect(ID_RS_NEXT, wxEVT_COMMAND_BUTTON_CLICKED,
101 (wxObjectEventFunction) & MyResultSetView::OnRsNext);
102 Connect(ID_RS_LAST, wxEVT_COMMAND_BUTTON_CLICKED,
103 (wxObjectEventFunction) & MyResultSetView::OnRsLast);
104 Connect(ID_REFRESH, wxEVT_COMMAND_BUTTON_CLICKED,
105 (wxObjectEventFunction) & MyResultSetView::OnRefresh);
106 Connect(ID_RS_THREAD_FINISHED, wxEVT_COMMAND_BUTTON_CLICKED,
107 (wxObjectEventFunction) & MyResultSetView::OnThreadFinished);
108 Connect(ID_RS_STATS_UPDATE, wxEVT_COMMAND_BUTTON_CLICKED,
109 (wxObjectEventFunction) & MyResultSetView::OnStatsUpdate);
110 Connect(wxID_ANY, wxEVT_SIZE,
111 (wxObjectEventFunction) & MyResultSetView::OnSize);
112 Connect(wxID_ANY, wxEVT_GRID_SELECT_CELL,
113 (wxObjectEventFunction) & MyResultSetView::OnCellSelected);
114 Connect(wxID_ANY, wxEVT_GRID_CELL_RIGHT_CLICK,
115 (wxObjectEventFunction) & MyResultSetView::OnRightClick);
116 Connect(wxID_ANY, wxEVT_GRID_CELL_CHANGE,
117 (wxObjectEventFunction) & MyResultSetView::OnCellChanged);
118 Connect(Grid_Delete, wxEVT_COMMAND_MENU_SELECTED,
119 (wxObjectEventFunction) & MyResultSetView::OnCmdDelete);
120 Connect(Grid_Insert, wxEVT_COMMAND_MENU_SELECTED,
121 (wxObjectEventFunction) & MyResultSetView::OnCmdInsert);
122 Connect(Grid_Abort, wxEVT_COMMAND_MENU_SELECTED,
123 (wxObjectEventFunction) & MyResultSetView::OnCmdAbort);
124 Connect(Grid_Clear, wxEVT_COMMAND_MENU_SELECTED,
125 (wxObjectEventFunction) & MyResultSetView::OnCmdClearSelection);
126 Connect(Grid_All, wxEVT_COMMAND_MENU_SELECTED,
127 (wxObjectEventFunction) & MyResultSetView::OnCmdSelectAll);
128 Connect(Grid_Row, wxEVT_COMMAND_MENU_SELECTED,
129 (wxObjectEventFunction) & MyResultSetView::OnCmdSelectRow);
130 Connect(Grid_Column, wxEVT_COMMAND_MENU_SELECTED,
131 (wxObjectEventFunction) & MyResultSetView::OnCmdSelectColumn);
132 Connect(Grid_Copy, wxEVT_COMMAND_MENU_SELECTED,
133 (wxObjectEventFunction) & MyResultSetView::OnCmdCopy);
134 Connect(Grid_Blob, wxEVT_COMMAND_MENU_SELECTED,
135 (wxObjectEventFunction) & MyResultSetView::OnCmdBlob);
136 Connect(Grid_BlobIn, wxEVT_COMMAND_MENU_SELECTED,
137 (wxObjectEventFunction) & MyResultSetView::OnCmdBlobIn);
138 Connect(Grid_BlobOut, wxEVT_COMMAND_MENU_SELECTED,
139 (wxObjectEventFunction) & MyResultSetView::OnCmdBlobOut);
140 Connect(Grid_BlobNull, wxEVT_COMMAND_MENU_SELECTED,
141 (wxObjectEventFunction) & MyResultSetView::OnCmdBlobNull);
142 Connect(Grid_XmlBlobIn, wxEVT_COMMAND_MENU_SELECTED,
143 (wxObjectEventFunction) & MyResultSetView::OnCmdXmlBlobIn);
144 Connect(Grid_XmlBlobOut, wxEVT_COMMAND_MENU_SELECTED,
145 (wxObjectEventFunction) & MyResultSetView::OnCmdXmlBlobOut);
146 Connect(Grid_XmlBlobOutIndented, wxEVT_COMMAND_MENU_SELECTED,
147 (wxObjectEventFunction) & MyResultSetView::OnCmdXmlBlobOutIndented);
148 Connect(Grid_ExpTxtTab, wxEVT_COMMAND_MENU_SELECTED,
149 (wxObjectEventFunction) & MyResultSetView::OnCmdExpTxtTab);
150 Connect(Grid_ExpCsv, wxEVT_COMMAND_MENU_SELECTED,
151 (wxObjectEventFunction) & MyResultSetView::OnCmdExpCsv);
152 Connect(Grid_ExpHtml, wxEVT_COMMAND_MENU_SELECTED,
153 (wxObjectEventFunction) & MyResultSetView::OnCmdExpHtml);
154 Connect(Grid_ExpShp, wxEVT_COMMAND_MENU_SELECTED,
155 (wxObjectEventFunction) & MyResultSetView::OnCmdExpShp);
156 Connect(Grid_ExpDif, wxEVT_COMMAND_MENU_SELECTED,
157 (wxObjectEventFunction) & MyResultSetView::OnCmdExpDif);
158 Connect(Grid_ExpSylk, wxEVT_COMMAND_MENU_SELECTED,
159 (wxObjectEventFunction) & MyResultSetView::OnCmdExpSylk);
160 Connect(Grid_ExpDbf, wxEVT_COMMAND_MENU_SELECTED,
161 (wxObjectEventFunction) & MyResultSetView::OnCmdExpDbf);
162 }
163
~MyResultSetView()164 MyResultSetView::~MyResultSetView()
165 {
166 // destructor
167 if (RowIds)
168 delete[]RowIds;
169 if (InsertRow)
170 delete InsertRow;
171 if (TableBlobs)
172 delete TableBlobs;
173 if (TableValues)
174 delete TableValues;
175 }
176
ShowControls()177 void MyResultSetView::ShowControls()
178 {
179 //
180 // making all ResultSet controls to be visible
181 //
182 BtnRsFirst->Show(true);
183 BtnRsPrevious->Show(true);
184 BtnRsNext->Show(true);
185 BtnRsLast->Show(true);
186 BtnRefresh->Show(true);
187 }
188
HideControls()189 void MyResultSetView::HideControls()
190 {
191 //
192 // making all controls to be invisible
193 //
194 BtnRsFirst->Show(false);
195 BtnRsPrevious->Show(false);
196 BtnRsNext->Show(false);
197 BtnRsLast->Show(false);
198 BtnRefresh->Show(false);
199 }
200
EditTable(wxString & sql,int * primaryKeys,int * blobCols,wxString & table)201 void MyResultSetView::EditTable(wxString & sql, int *primaryKeys, int *blobCols,
202 wxString & table)
203 {
204 //
205 // starting the edit table sequence
206 //
207 int i;
208 for (i = 0; i < 1024; i++)
209 {
210 PrimaryKeys[i] = *(primaryKeys + i);
211 BlobColumns[i] = *(blobCols + i);
212 }
213 ReadOnly = false;
214 TableName = table;
215 MainFrame->GetQueryView()->GetSqlCtrl()->SetValue(sql);
216 if (ExecuteSqlPre(sql, 0, ReadOnly) == false)
217 wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
218 MainFrame);
219 }
220
FormatElapsedTime(double seconds,char * elapsed,bool simple)221 void MyResultSetView::FormatElapsedTime(double seconds, char *elapsed,
222 bool simple)
223 {
224 /* well formatting elapsed time */
225 int int_time = (int) seconds;
226 int millis = (int) ((seconds - (double) int_time) * 1000.0);
227 int secs = int_time % 60;
228 int_time /= 60;
229 int mins = int_time % 60;
230 int_time /= 60;
231 int hh = int_time;
232 if (simple == true)
233 {
234 if (hh == 0 && mins == 0)
235 sprintf(elapsed, "%d.%03d", secs, millis);
236 else if (hh == 0)
237 sprintf(elapsed, "%d:%02d.%03d", mins, secs, millis);
238 else
239 sprintf(elapsed, "%d:%02d:%02d.%03d", hh, mins, secs, millis);
240 } else
241 sprintf(elapsed, "%02d:%02d:%02d.%03d", hh, mins, secs, millis);
242 }
243
Reset(void)244 void SqlThreadParams::Reset(void)
245 {
246 //
247 // thread params: resetting to empty state
248 //
249 Mother = NULL;
250 Sql = wxT("");
251 Stmt = NULL;
252 FromRow = 0;
253 EndRow = 0;
254 MaxRow = 0;
255 List.Reset();
256 Sqlite = NULL;
257 Start = 0;
258 LastGuiUpdate = 0;
259 Error = false;
260 FetchedRows = 0;
261 StatFullscanStep = 0;
262 StatSort = 0;
263 StatAutoindex = 0;
264 ElapsedTime = 0.0;
265 AbortRequested = false;
266 Valid = false;
267 }
268
Initialize(MyResultSetView * mother,wxString & sql,sqlite3_stmt * stmt,int from,sqlite3 * sqlite,clock_t start)269 void SqlThreadParams::Initialize(MyResultSetView * mother, wxString & sql,
270 sqlite3_stmt * stmt, int from,
271 sqlite3 * sqlite, clock_t start)
272 {
273 //
274 // thread params: initializing
275 //
276 Reset();
277 Mother = mother;
278 Sql = sql;
279 Stmt = stmt;
280 FromRow = from;
281 EndRow = 0;
282 MaxRow = 0;
283 Sqlite = sqlite;
284 Start = start;
285 LastGuiUpdate = start;
286 Error = false;
287 FetchedRows = 0;
288 StatFullscanStep = 0;
289 StatSort = 0;
290 StatAutoindex = 0;
291 ElapsedTime = 0.0;
292 AbortRequested = false;
293 Valid = true;
294 }
295
UpdateStats(int fullscan,int sort,int autoindex,clock_t now)296 void SqlThreadParams::UpdateStats(int fullscan, int sort, int autoindex,
297 clock_t now)
298 {
299 //
300 // updading Stats (SQL query progress handler callback)
301 //
302 StatFullscanStep = fullscan;
303 StatSort = sort;
304 StatAutoindex = autoindex;
305 ElapsedTime = (double) (now - Start) / (double) CLOCKS_PER_SEC;
306 }
307
GuiHasToBeUpdated(clock_t now,int millisecs)308 bool SqlThreadParams::GuiHasToBeUpdated(clock_t now, int millisecs)
309 {
310 //
311 // checking if a GUI update is required (Stats)
312 //
313 double interval = (double) (now - LastGuiUpdate) / (double) CLOCKS_PER_SEC;
314 if (interval >= ((double) millisecs / 1000.0))
315 return true;
316 return false;
317 }
318
SqlProgressCallback(void * arg)319 int SqlProgressCallback(void *arg)
320 {
321 //
322 // SQL query progress handler callback function
323 //
324 int fullscan;
325 int sort;
326 int autoindex;
327 clock_t clock_end;
328 wxString currentBlock;
329 SqlThreadParams *params = (SqlThreadParams *) arg;
330
331 if (params->IsValid() == false)
332 return 0;
333
334 if (params->IsAbortRequested() == true)
335 {
336 // aborting the SQL query
337 sqlite3_interrupt(params->GetSqlite());
338 return 0;
339 }
340 // updating query stats
341 fullscan =
342 sqlite3_stmt_status(params->GetStmt(), SQLITE_STMTSTATUS_FULLSCAN_STEP, 0);
343 sort = sqlite3_stmt_status(params->GetStmt(), SQLITE_STMTSTATUS_SORT, 0);
344 #ifdef OMIT_SQLITE_STMTSTATUS_AUTOINXED
345 autoindex = -1;
346 #else
347 autoindex =
348 sqlite3_stmt_status(params->GetStmt(), SQLITE_STMTSTATUS_AUTOINDEX, 0);
349 #endif
350 clock_end = clock();
351 params->UpdateStats(fullscan, sort, autoindex, clock_end);
352 if (params->GuiHasToBeUpdated(clock_end, 500) == true)
353 {
354 // requesting a GUI update
355 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, ID_RS_STATS_UPDATE);
356 params->GetMother()->GetEventHandler()->AddPendingEvent(event);
357 params->SetLastGuiUpdate(clock_end);
358 }
359 return 0;
360 }
361
362 #ifdef _WIN32
DoExecuteSqlThread(void * arg)363 DWORD WINAPI DoExecuteSqlThread(void *arg)
364 #else
365 void *DoExecuteSqlThread(void *arg)
366 #endif
367 {
368 //
369 // threaded function: processing an SQL query
370 //
371 int ret;
372 int i_col;
373 int i_row = 0;
374 int end_row = 0;
375 int columns;
376 char err_msg[2048];
377
378 // setting up the sqlite's progress handler callback
379 SqlThreadParams *params = (SqlThreadParams *) arg;
380 sqlite3_progress_handler(params->GetSqlite(), 1000, SqlProgressCallback, arg);
381
382 while (1)
383 {
384 //
385 // fetching the result set rows
386 //
387 if (params->IsValid() == false)
388 goto error;
389 ret = sqlite3_step(params->GetStmt());
390 if (ret == SQLITE_DONE)
391 break; // end of result set
392 if (ret == SQLITE_ROW)
393 {
394 //
395 // fetching a row
396 //
397 if (params->IsAbortRequested() == true)
398 {
399 // aborting the SQL query
400 sqlite3_interrupt(params->GetSqlite());
401 continue;
402 }
403
404 params->FetchedRow();
405 if ((params->GetFetchedRows() % 1000) == 0)
406 SqlProgressCallback(params);
407 if (i_row < params->GetFromRow())
408 {
409 i_row++;
410 continue;
411 }
412 if ((i_row - params->GetFromRow()) >=
413 params->GetMother()->GetRsBlock())
414 {
415 i_row++;
416 continue;
417 }
418 end_row = i_row;
419 columns = sqlite3_column_count(params->GetStmt());
420 MyRowVariant *rowVariant = params->GetList()->Add(columns);
421 for (i_col = 0; i_col < columns; i_col++)
422 {
423 sqlite3_int64 int_value;
424 double dbl_value;
425 const unsigned char *txt_value;
426 const void *blob_value;
427 int blobSize;
428 params->GetList()->SetColumnName(i_col,
429 sqlite3_column_name
430 (params->GetStmt(), i_col));
431 switch (sqlite3_column_type(params->GetStmt(), i_col))
432 {
433 case SQLITE_INTEGER:
434 int_value = sqlite3_column_int64(params->GetStmt(), i_col);
435 rowVariant->Set(i_col, int_value);
436 break;
437 case SQLITE_FLOAT:
438 dbl_value = sqlite3_column_double(params->GetStmt(), i_col);
439 rowVariant->Set(i_col, dbl_value);
440 break;
441 case SQLITE_TEXT:
442 txt_value = sqlite3_column_text(params->GetStmt(), i_col);
443 rowVariant->Set(i_col, txt_value);
444 break;
445 case SQLITE_BLOB:
446 blob_value = sqlite3_column_blob(params->GetStmt(), i_col);
447 blobSize = sqlite3_column_bytes(params->GetStmt(), i_col);
448 rowVariant->Set(i_col, blob_value, blobSize);
449 break;
450 case SQLITE_NULL:
451 default:
452 break;
453 };
454 }
455 i_row++;
456 } else
457 {
458 sprintf(err_msg, "SQL error: %s",
459 sqlite3_errmsg(params->GetSqlite()));
460 sqlite3_finalize(params->GetStmt());
461 wxString msg = wxString::FromUTF8(err_msg);
462 params->GetMother()->SetSqlErrorMsg(msg);
463 goto error;
464 }
465 }
466 sqlite3_finalize(params->GetStmt());
467 params->SetEndRow(end_row);
468 params->SetMaxRow(i_row);
469 goto ok;
470 error:
471 params->SetError();
472 ok:
473 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, ID_RS_THREAD_FINISHED);
474 params->GetMother()->GetEventHandler()->AddPendingEvent(event);
475 #ifdef _WIN32
476 return 0;
477 #else
478 pthread_exit(NULL);
479 #endif
480 }
481
AbortRequested()482 void MyResultSetView::AbortRequested()
483 {
484 //
485 // attempting to abort the current SQL query
486 //
487 if (ThreadParams.IsValid() == true)
488 ThreadParams.Abort();
489 }
490
ExecuteSqlPre(wxString & sql,int from,bool read_only)491 bool MyResultSetView::ExecuteSqlPre(wxString & sql, int from, bool read_only)
492 {
493 //
494 // executing some SQL statement
495 //
496 ReadOnly = read_only;
497 char *xSql = NULL;
498 char err_msg[2048];
499 int i_row;
500 clock_t clock_start;
501 sqlite3_stmt *stmt;
502 sqlite3 *sqlite = MainFrame->GetSqlite();
503 SqlErrorMsg = wxT("");
504 if (TableView)
505 TableView->Destroy();
506 TableView = NULL;
507 if (TableBlobs)
508 delete TableBlobs;
509 if (TableValues)
510 delete TableValues;
511 TableBlobs = NULL;
512 TableValues = NULL;
513 CurrentBlob = NULL;
514 HideControls();
515 RsBeginRow = 0;
516 RsEndRow = 0;
517 RsMaxRow = 0;
518 #ifdef _WIN32
519 HANDLE thread_handle;
520 DWORD dwThreadId;
521 #else
522 pthread_t thread_id;
523 #endif
524 for (i_row = 0; i_row < RsBlock; i_row++)
525 RowIds[i_row] = -1;
526 i_row = 0;
527 xSql = new char[65536];
528 strcpy(xSql, sql.ToUTF8());
529
530 clock_start = clock();
531 int ret = sqlite3_prepare_v2(sqlite, xSql, strlen(xSql), &stmt, NULL);
532 delete[]xSql;
533 if (ret != SQLITE_OK)
534 {
535 sprintf(err_msg, "SQL error: %s", sqlite3_errmsg(sqlite));
536 SqlErrorMsg = wxString::FromUTF8(err_msg);
537 ::wxEndBusyCursor();
538 return false;
539 }
540 CreateStatsGrid();
541 ::wxBeginBusyCursor();
542
543 ThreadParams.Initialize(this, sql, stmt, from, sqlite, clock_start);
544 #ifdef _WIN32
545 thread_handle =
546 CreateThread(NULL, 0, DoExecuteSqlThread, &ThreadParams, 0, &dwThreadId);
547 SetThreadPriority(thread_handle, THREAD_PRIORITY_IDLE);
548 #else
549 int ok_prior = 0;
550 int policy;
551 int min_prio;
552 pthread_attr_t attr;
553 struct sched_param sp;
554 pthread_attr_init(&attr);
555 if (pthread_attr_setschedpolicy(&attr, SCHED_RR) == 0)
556 {
557 // attempting to set the lowest priority
558 if (pthread_attr_getschedpolicy(&attr, &policy) == 0)
559 {
560 min_prio = sched_get_priority_min(policy);
561 sp.sched_priority = min_prio;
562 if (pthread_attr_setschedparam(&attr, &sp) == 0)
563 {
564 // ok, setting the lowest priority
565 ok_prior = 1;
566 pthread_create(&thread_id, &attr, DoExecuteSqlThread,
567 &ThreadParams);
568 }
569 }
570 }
571 if (!ok_prior)
572 {
573 // failure: using standard priority
574 pthread_create(&thread_id, NULL, DoExecuteSqlThread, &ThreadParams);
575 }
576 #endif
577 MainFrame->GetQueryView()->EnableAbortButton();
578 return true;
579 }
580
ExecuteSqlPost()581 bool MyResultSetView::ExecuteSqlPost()
582 {
583 char dummy[1024];
584 int i_col;
585 int i_row;
586 double seconds;
587 clock_t clock_end;
588 char elapsed[64];
589 MyRowVariant *row;
590 MyVariant *value;
591 wxString blobType;
592 int type;
593 wxString cellValue;
594 wxString currentBlock;
595 MyVariantList *list;
596
597 MainFrame->GetQueryView()->DisableAbortButton();
598 if (TableView)
599 TableView->Destroy();
600 TableView = NULL;
601 if (TableBlobs)
602 delete TableBlobs;
603 if (TableValues)
604 delete TableValues;
605 TableBlobs = NULL;
606 TableValues = NULL;
607 CurrentBlob = NULL;
608
609 if (ThreadParams.IsValid() == false)
610 {
611 if (SqlErrorMsg.Len() > 0)
612 {
613 wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
614 MainFrame);
615 ::wxEndBusyCursor();
616 ThreadParams.Reset();
617 return true;
618 }
619 goto error;
620 }
621 if (ThreadParams.IsError() == true)
622 {
623 if (SqlErrorMsg.Len() > 0)
624 {
625 wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
626 MainFrame);
627 ::wxEndBusyCursor();
628 ThreadParams.Reset();
629 return true;
630 }
631 goto error;
632 }
633
634 list = ThreadParams.GetList();
635 clock_end = clock();
636 seconds =
637 (double) (clock_end - ThreadParams.GetStart()) / (double) CLOCKS_PER_SEC;
638 RsBeginRow = ThreadParams.GetFromRow();
639 RsEndRow = ThreadParams.GetEndRow();
640 RsMaxRow = ThreadParams.GetMaxRow();
641 if (list->GetRows() == 0)
642 {
643 //
644 // this one is an EMPTY Result Set
645 //
646 if (ReadOnly == false)
647 {
648 // preparing the insert row
649 int numCols = 0;
650 wxString *colNames = MainFrame->GetColumnNames(TableName, &numCols);
651 CreateGrid(0, numCols + 1);
652 TableView->SetColLabelValue(0, wxT("ROWID"));
653 for (i_col = 0; i_col < numCols; i_col++)
654 TableView->SetColLabelValue(i_col + 1, *(colNames + i_col));
655 TableView->EnableEditing(true);
656 delete[]colNames;
657 } else
658 {
659 // simply showing a warning message
660 CreateGrid(1, 1);
661 TableView->SetColLabelValue(0, wxT("Message"));
662 TableView->SetRowLabelValue(0, wxT("Message"));
663 TableView->SetCellValue(0, 0,
664 wxT
665 ("SQL query returned an empty ResultSet\n\nThis is not an error"));
666 }
667 } else
668 {
669 //
670 // preparing the Grid to show the result set
671 //
672 CreateGrid(list->GetRows(), list->GetColumns());
673 if (ReadOnly == true)
674 TableView->EnableEditing(false);
675 else
676 TableView->EnableEditing(true);
677 for (i_col = 0; i_col < list->GetColumns(); i_col++)
678 TableView->SetColLabelValue(i_col, list->GetColumnName(i_col));
679 if (ReadOnly == false)
680 TableView->SetColLabelValue(0, wxT("ROWID"));
681 i_row = 0;
682 row = list->GetFirst();
683 while (row)
684 {
685 sprintf(dummy, "%d", i_row + RsBeginRow + 1);
686 cellValue = wxString::FromUTF8(dummy);
687 TableView->SetRowLabelValue(i_row, cellValue);
688 if (ReadOnly == false)
689 {
690 // storing the ROWID value into the RowIds array
691 value = row->GetColumn(0);
692 if (value->GetType() == MY_INT_VARIANT)
693 RowIds[i_row] = value->GetIntValue();
694 }
695 for (i_col = 0; i_col < row->GetNumCols(); i_col++)
696 {
697 value = row->GetColumn(i_col);
698 if (value)
699 {
700 switch (value->GetType())
701 {
702 case MY_INT_VARIANT:
703 sprintf(dummy, FORMAT_64, value->GetIntValue());
704 cellValue = wxString::FromUTF8(dummy);
705 TableView->SetCellValue(i_row, i_col, cellValue);
706 if (ReadOnly == false)
707 TableValues->SetValue(i_row, i_col,
708 value->GetIntValue());
709 TableView->SetCellAlignment(i_row, i_col, wxALIGN_RIGHT,
710 wxALIGN_TOP);
711 break;
712 case MY_DBL_VARIANT:
713 sprintf(dummy, "%1.6f", value->GetDblValue());
714 cellValue = wxString::FromUTF8(dummy);
715 TableView->SetCellValue(i_row, i_col, cellValue);
716 if (ReadOnly == false)
717 TableValues->SetValue(i_row, i_col,
718 value->GetDblValue());
719 TableView->SetCellAlignment(i_row, i_col, wxALIGN_RIGHT,
720 wxALIGN_TOP);
721 break;
722 case MY_TXT_VARIANT:
723 TableView->SetCellValue(i_row, i_col,
724 value->GetTxtValue());
725 if (ReadOnly == false)
726 TableValues->SetValue(i_row, i_col,
727 value->GetTxtValue());
728 break;
729 case MY_BLOB_VARIANT:
730 blobType = wxT("UNKNOWN type");
731 type =
732 gaiaGuessBlobType(value->GetBlob(),
733 value->GetBlobSize());
734 switch (type)
735 {
736 case GAIA_GEOMETRY_BLOB:
737 blobType = wxT("GEOMETRY");
738 break;
739 case GAIA_XML_BLOB:
740 blobType = wxT("XmlBLOB");
741 break;
742 case GAIA_JPEG_BLOB:
743 blobType = wxT("JPEG image");
744 break;
745 case GAIA_EXIF_BLOB:
746 blobType = wxT("JPEG-EXIF image");
747 break;
748 case GAIA_EXIF_GPS_BLOB:
749 blobType = wxT("JPEG-EXIF-GPS image");
750 break;
751 case GAIA_PNG_BLOB:
752 blobType = wxT("PNG image");
753 break;
754 case GAIA_GIF_BLOB:
755 blobType = wxT("GIF image");
756 break;
757 case GAIA_TIFF_BLOB:
758 blobType = wxT("TIFF image");
759 break;
760 case GAIA_PDF_BLOB:
761 blobType = wxT("PDF document");
762 break;
763 case GAIA_ZIP_BLOB:
764 blobType = wxT("ZIP archive");
765 break;
766 default:
767 if (gGraphIsRawImage
768 (value->GetBlob(),
769 value->GetBlobSize()) == GGRAPH_OK)
770 blobType = wxT("RasterLite RAW image");
771 break;
772 };
773 if (type == GAIA_XML_BLOB)
774 {
775 #ifdef ENABLE_LIBXML2 /* only if LIBXML2 is enabled */
776
777 int doc_size =
778 gaiaXmlBlobGetDocumentSize(value->GetBlob(),
779 value->GetBlobSize());
780 if (gaiaIsSvgXmlBlob
781 (value->GetBlob(), value->GetBlobSize()))
782 sprintf(dummy, "XmlBLOB-SVG sz=%d (XMLsz=%d) ",
783 value->GetBlobSize(), doc_size);
784 else if (gaiaIsIsoMetadataXmlBlob
785 (value->GetBlob(), value->GetBlobSize()))
786 sprintf(dummy,
787 "XmlBLOB-ISOmetadata sz=%d (XMLsz=%d) ",
788 value->GetBlobSize(), doc_size);
789 else
790 if (gaiaIsSldSeVectorStyleXmlBlob
791 (value->GetBlob(), value->GetBlobSize()))
792 sprintf(dummy,
793 "XmlBLOB-VectorStyle sz=%d (XMLsz=%d) ",
794 value->GetBlobSize(), doc_size);
795 else
796 if (gaiaIsSldSeRasterStyleXmlBlob
797 (value->GetBlob(), value->GetBlobSize()))
798 sprintf(dummy,
799 "XmlBLOB-RasterStyle sz=%d (XMLsz=%d) ",
800 value->GetBlobSize(), doc_size);
801 else
802 sprintf(dummy, "XmlBLOB sz=%d (XMLsz=%d) ",
803 value->GetBlobSize(), doc_size);
804 cellValue = wxString::FromUTF8(dummy);
805 if (gaiaIsSchemaValidatedXmlBlob
806 (value->GetBlob(), value->GetBlobSize()))
807 cellValue += wxT(" SchemaValidated");
808
809 #endif /* end LIBXML2 conditionals */
810 } else
811 {
812 sprintf(dummy, "BLOB sz=%d ", value->GetBlobSize());
813 cellValue = wxString::FromUTF8(dummy);
814 cellValue += blobType;
815 }
816 TableView->SetCellValue(i_row, i_col, cellValue);
817 TableView->SetReadOnly(i_row, i_col);
818 TableBlobs->SetBlob(i_row, i_col, value);
819 break;
820 case MY_NULL_VARIANT:
821 default:
822 TableView->SetCellValue(i_row, i_col, wxT("NULL"));
823 break;
824 };
825 } else
826 TableView->SetCellValue(i_row, i_col, wxT("NULL"));
827 if (ReadOnly == false)
828 {
829 if (IsPrimaryKey(i_col) == true)
830 TableView->SetReadOnly(i_row, i_col);
831 if (IsBlobColumn(i_col) == true)
832 TableView->SetReadOnly(i_row, i_col);
833 }
834 }
835 i_row++;
836 row = row->GetNext();
837 }
838 }
839 if (ReadOnly == false)
840 {
841 // prepearing the insert row
842 TableView->SetRowLabelValue(TableView->GetNumberRows() - 1,
843 wxT("Insert row"));
844 InsertPending = false;
845 for (i_col = 0; i_col < TableView->GetNumberCols(); i_col++)
846 {
847 TableView->SetCellValue(TableView->GetNumberRows() - 1, i_col,
848 wxT(""));
849 TableView->SetCellBackgroundColour(TableView->GetNumberRows() - 1,
850 i_col, wxColour(0, 0, 0));
851 TableView->SetReadOnly(TableView->GetNumberRows() - 1, i_col);
852 }
853 }
854 TableView->SetRowLabelSize(wxGRID_AUTOSIZE);
855 TableView->AutoSize();
856 ResizeView();
857 FormatElapsedTime(seconds, elapsed);
858 sprintf(dummy, "current block: %d / %d [%d rows] [fetched in %s]",
859 RsBeginRow + 1, RsEndRow + 1, RsMaxRow, elapsed);
860 currentBlock = wxString::FromUTF8(dummy);
861 RsCurrentBlock->SetLabel(currentBlock);
862 ShowControls();
863 MainFrame->GetQueryView()->AddToHistory(ThreadParams.GetSql());
864 ThreadParams.Reset();
865 ::wxEndBusyCursor();
866 return true;
867 error:
868 ::wxEndBusyCursor();
869 ThreadParams.Reset();
870 return false;
871 }
872
IsPrimaryKey(int column)873 bool MyResultSetView::IsPrimaryKey(int column)
874 {
875 //
876 // checks if this column is a Primary Key one
877 //
878 int i;
879 for (i = 0; i < 1024; i++)
880 {
881 if (PrimaryKeys[i] == column)
882 return true;
883 }
884 return false;
885 }
886
IsBlobColumn(int column)887 bool MyResultSetView::IsBlobColumn(int column)
888 {
889 //
890 // checks if this column is a BLOB-type column
891 //
892 int i;
893 for (i = 0; i < 1024; i++)
894 {
895 if (BlobColumns[i] == column)
896 return true;
897 }
898 return false;
899 }
900
CreateGrid(int rows,int cols)901 void MyResultSetView::CreateGrid(int rows, int cols)
902 {
903 //
904 // creating a new Grid to show the result set
905 //
906 int extra = 0;
907 if (ReadOnly == false)
908 extra = 1;
909 TableView = new wxGrid(this, wxID_ANY, wxPoint(5, 5), wxSize(200, 200));
910 TableView->Show(false);
911 TableView->CreateGrid(rows + extra, cols);
912 TableBlobs = new MyBlobs(rows, cols);
913 if (ReadOnly == false)
914 TableValues = new MyValues(rows, cols);
915 }
916
CreateStatsGrid()917 void MyResultSetView::CreateStatsGrid()
918 {
919 //
920 // creating a new Grid to show the SQL query stats (progress handler)
921 //
922 wxSize sz = GetClientSize();
923 TableView = new wxGrid(this, wxID_ANY, wxPoint(5, 5), wxSize(200, 200));
924 TableView->Show(false);
925 TableView->CreateGrid(5, 2);
926 TableView->EnableEditing(false);
927 TableView->SetColLabelValue(0, wxT("Progress Counter"));
928 TableView->SetColLabelValue(1, wxT("Current Value"));
929 TableView->SetCellValue(0, 0, wxT("FullscanStep"));
930 TableView->SetCellValue(1, 0, wxT("Sort"));
931 TableView->SetCellValue(2, 0, wxT("Autoindex"));
932 TableView->SetCellValue(3, 0, wxT("FetchedRows"));
933 TableView->SetCellValue(4, 0, wxT("ElapsedTime"));
934 TableView->SetCellBackgroundColour(4, 0, wxColour(128, 255, 128));
935 TableView->SetCellValue(0, 1, wxT("0"));
936 TableView->SetCellAlignment(0, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
937 TableView->SetCellValue(1, 1, wxT("0"));
938 TableView->SetCellAlignment(1, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
939 TableView->SetCellValue(2, 1, wxT("0"));
940 TableView->SetCellAlignment(2, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
941 TableView->SetCellValue(3, 1, wxT("0"));
942 TableView->SetCellAlignment(3, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
943 TableView->SetCellValue(4, 1, wxT("0"));
944 TableView->SetCellAlignment(4, 1, wxALIGN_RIGHT, wxALIGN_CENTRE);
945 TableView->SetRowLabelSize(wxGRID_AUTOSIZE);
946 TableView->AutoSize();
947 TableView->SetSize(sz.GetWidth() - 10, sz.GetHeight() - 45);
948 TableView->Show(true);
949 TableView->Disable();
950 wxString msg = wxT("... wait please: SQL query in progress ...");
951 RsCurrentBlock->SetLabel(msg);
952 }
953
ResizeView()954 void MyResultSetView::ResizeView()
955 {
956 //
957 // resizing the Grid to show the result set
958 //
959 wxSize sz = GetClientSize();
960 if (TableView)
961 {
962 TableView->SetSize(sz.GetWidth() - 10, sz.GetHeight() - 45);
963 TableView->Show(true);
964 }
965 }
966
OnSize(wxSizeEvent & WXUNUSED (event))967 void MyResultSetView::OnSize(wxSizeEvent & WXUNUSED(event))
968 {
969 //
970 // this window has changed its size
971 //
972 wxSize sz = GetClientSize();
973 if (TableView)
974 TableView->SetSize(sz.GetWidth() - 10, sz.GetHeight() - 45);
975 BtnRsFirst->Move(5, sz.GetHeight() - 35);
976 BtnRsPrevious->Move(40, sz.GetHeight() - 35);
977 BtnRefresh->Move(75, sz.GetHeight() - 35);
978 BtnRsNext->Move(110, sz.GetHeight() - 35);
979 BtnRsLast->Move(145, sz.GetHeight() - 35);
980 RsCurrentBlock->Move(180, sz.GetHeight() - 25);
981 }
982
OnRsFirst(wxCommandEvent & WXUNUSED (event))983 void MyResultSetView::OnRsFirst(wxCommandEvent & WXUNUSED(event))
984 {
985 //
986 // scrolling to the result set beginning
987 //
988 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
989 if (ExecuteSqlPre(sql, 0, ReadOnly) == false)
990 wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
991 MainFrame);
992 }
993
OnRsPrevious(wxCommandEvent & WXUNUSED (event))994 void MyResultSetView::OnRsPrevious(wxCommandEvent & WXUNUSED(event))
995 {
996 //
997 // scrolling to the result set previous block
998 //
999 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
1000 int start = RsBeginRow - RsBlock;
1001 if (start < 0)
1002 start = 0;
1003 if (ExecuteSqlPre(sql, start, ReadOnly) == false)
1004 wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
1005 MainFrame);
1006 }
1007
OnRsNext(wxCommandEvent & WXUNUSED (event))1008 void MyResultSetView::OnRsNext(wxCommandEvent & WXUNUSED(event))
1009 {
1010 //
1011 // scrolling to the result set next block
1012 //
1013 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
1014 int start = RsEndRow + 1;
1015 if (ExecuteSqlPre(sql, start, ReadOnly) == false)
1016 wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
1017 MainFrame);
1018 }
1019
OnRsLast(wxCommandEvent & WXUNUSED (event))1020 void MyResultSetView::OnRsLast(wxCommandEvent & WXUNUSED(event))
1021 {
1022 //
1023 // scrolling to the result set ending
1024 //
1025 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
1026 int start = RsMaxRow - RsBlock;
1027 if (start < 0)
1028 start = 0;
1029 if (ExecuteSqlPre(sql, start, ReadOnly) == false)
1030 wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
1031 MainFrame);
1032 }
1033
OnRefresh(wxCommandEvent & WXUNUSED (event))1034 void MyResultSetView::OnRefresh(wxCommandEvent & WXUNUSED(event))
1035 {
1036 //
1037 // refreshing the result set
1038 //
1039 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
1040 int start = RsBeginRow;
1041 if (ExecuteSqlPre(sql, start, ReadOnly) == false)
1042 wxMessageBox(SqlErrorMsg, wxT("spatialite_gui"), wxOK | wxICON_ERROR,
1043 MainFrame);
1044 }
1045
OnThreadFinished(wxCommandEvent & WXUNUSED (event))1046 void MyResultSetView::OnThreadFinished(wxCommandEvent & WXUNUSED(event))
1047 {
1048 //
1049 // the SQL thread signals termination
1050 //
1051 if (ExecuteSqlPost() == false)
1052 wxMessageBox(wxT("An error occurred while showing the ResultSet"),
1053 wxT("spatialite_gui"), wxOK | wxICON_ERROR, MainFrame);
1054 }
1055
OnStatsUpdate(wxCommandEvent & WXUNUSED (event))1056 void MyResultSetView::OnStatsUpdate(wxCommandEvent & WXUNUSED(event))
1057 {
1058 //
1059 // updating SQL stats (progress handler)
1060 //
1061 char elapsed[64];
1062 char dummy[1024];
1063 wxString cellValue;
1064 if (ThreadParams.IsValid() == false)
1065 return;
1066 FormatElapsedTime(ThreadParams.GetElapsedTime(), elapsed, true);
1067 sprintf(dummy, "%d", ThreadParams.GetStatFullscanStep());
1068 cellValue = wxString::FromUTF8(dummy);
1069 TableView->SetCellValue(0, 1, cellValue);
1070 sprintf(dummy, "%d", ThreadParams.GetStatSort());
1071 cellValue = wxString::FromUTF8(dummy);
1072 TableView->SetCellValue(1, 1, cellValue);
1073 sprintf(dummy, "%d", ThreadParams.GetStatAutoindex());
1074 cellValue = wxString::FromUTF8(dummy);
1075 TableView->SetCellValue(2, 1, cellValue);
1076 sprintf(dummy, "%d", ThreadParams.GetFetchedRows());
1077 cellValue = wxString::FromUTF8(dummy);
1078 TableView->SetCellValue(3, 1, cellValue);
1079 sprintf(dummy, "%s", elapsed);
1080 cellValue = wxString::FromUTF8(dummy);
1081 TableView->SetCellValue(4, 1, cellValue);
1082 TableView->ForceRefresh();
1083 }
1084
OnRightClick(wxGridEvent & event)1085 void MyResultSetView::OnRightClick(wxGridEvent & event)
1086 {
1087 //
1088 // right click on some cell [mouse action]
1089 //
1090 int blob_type;
1091 MyVariant *blobVar;
1092 wxMenu *menu = new wxMenu();
1093 wxMenuItem *menuItem;
1094 wxPoint pt = event.GetPosition();
1095 if (ReadOnly == false && event.GetRow() == TableView->GetNumberRows() - 1)
1096 {
1097 // this is the INSERT ROW
1098 if (InsertPending == true)
1099 {
1100 menuItem =
1101 new wxMenuItem(menu, Grid_Insert, wxT("&Confirm insertion"));
1102 menu->Append(menuItem);
1103 menuItem = new wxMenuItem(menu, Grid_Abort, wxT("&Abort insertion"));
1104 menu->Append(menuItem);
1105 } else
1106 {
1107 menuItem = new wxMenuItem(menu, Grid_Insert, wxT("&Insert new row"));
1108 menu->Append(menuItem);
1109 }
1110 TableView->PopupMenu(menu, pt);
1111 return;
1112 }
1113 CurrentEvtRow = event.GetRow();
1114 CurrentEvtColumn = event.GetCol();
1115 blobVar = TableBlobs->GetBlob(CurrentEvtRow, CurrentEvtColumn);
1116 if (blobVar)
1117 {
1118 // this one is a BLOB cell
1119 if (ReadOnly == false)
1120 {
1121 MyRowVariant *varRow = TableValues->GetRow(CurrentEvtRow);
1122 if (varRow->IsDeleted() == false)
1123 {
1124 menuItem = new wxMenuItem(menu, Grid_Delete, wxT("&Delete row"));
1125 menu->Append(menuItem);
1126 menuItem =
1127 new wxMenuItem(menu, Grid_Insert, wxT("&Insert new row"));
1128 menu->Append(menuItem);
1129 menu->AppendSeparator();
1130 }
1131 }
1132 menuItem = new wxMenuItem(menu, Grid_Blob, wxT("BLOB &explore"));
1133 menu->Append(menuItem);
1134 blob_type = gaiaGuessBlobType(blobVar->GetBlob(), blobVar->GetBlobSize());
1135 if (blob_type == GAIA_GEOMETRY_BLOB)
1136 ;
1137 else if (blob_type == GAIA_XML_BLOB)
1138 {
1139 menu->AppendSeparator();
1140 menuItem =
1141 new wxMenuItem(menu, Grid_XmlBlobIn, wxT("XmlBLOB &import"));
1142 menu->Append(menuItem);
1143 menuItem =
1144 new wxMenuItem(menu, Grid_XmlBlobOut,
1145 wxT("XmlBLOB &export (not indented)"));
1146 menu->Append(menuItem);
1147 menuItem =
1148 new wxMenuItem(menu, Grid_XmlBlobOutIndented,
1149 wxT("XmlBLOB export (i&ndented)"));
1150 menu->Append(menuItem);
1151 menuItem =
1152 new wxMenuItem(menu, Grid_BlobNull, wxT("Set BLOB as &NULL"));
1153 menu->Append(menuItem);
1154 } else
1155 {
1156 menu->AppendSeparator();
1157 menuItem = new wxMenuItem(menu, Grid_BlobIn, wxT("BLOB &import"));
1158 menu->Append(menuItem);
1159 menuItem = new wxMenuItem(menu, Grid_BlobOut, wxT("BLOB &export"));
1160 menu->Append(menuItem);
1161 menuItem =
1162 new wxMenuItem(menu, Grid_BlobNull, wxT("Set BLOB as &NULL"));
1163 menu->Append(menuItem);
1164 }
1165 CurrentBlob = blobVar;
1166 } else
1167 {
1168 // this one is an ordinary cell
1169 CurrentBlob = NULL;
1170 if (ReadOnly == false)
1171 {
1172 MyRowVariant *varRow = TableValues->GetRow(CurrentEvtRow);
1173 if (varRow->IsDeleted() == false)
1174 {
1175 menuItem = new wxMenuItem(menu, Grid_Delete, wxT("&Delete row"));
1176 menu->Append(menuItem);
1177 menuItem =
1178 new wxMenuItem(menu, Grid_Insert, wxT("&Insert new row"));
1179 menu->Append(menuItem);
1180 if (IsBlobColumn(CurrentEvtColumn) == true)
1181 {
1182 menu->AppendSeparator();
1183 menuItem =
1184 new wxMenuItem(menu, Grid_BlobIn, wxT("BLOB &import"));
1185 menu->Append(menuItem);
1186 }
1187 menu->AppendSeparator();
1188 }
1189 }
1190 menuItem = new wxMenuItem(menu, Grid_Clear, wxT("&Clear selection"));
1191 menu->Append(menuItem);
1192 menuItem = new wxMenuItem(menu, Grid_All, wxT("Select &all"));
1193 menu->Append(menuItem);
1194 menuItem = new wxMenuItem(menu, Grid_Row, wxT("Select &row"));
1195 menu->Append(menuItem);
1196 menuItem = new wxMenuItem(menu, Grid_Column, wxT("&Select column"));
1197 menu->Append(menuItem);
1198 menu->AppendSeparator();
1199 menuItem = new wxMenuItem(menu, Grid_Copy, wxT("&Copy"));
1200 menu->Append(menuItem);
1201 if (TableView->IsSelection() == false)
1202 menuItem->Enable(false);
1203 }
1204 menu->AppendSeparator();
1205 wxMenu *exportMenu = new wxMenu();
1206 menuItem = new wxMenuItem(exportMenu, Grid_ExpTxtTab, wxT("as &Txt/Tab"));
1207 exportMenu->Append(menuItem);
1208 menuItem = new wxMenuItem(exportMenu, Grid_ExpCsv, wxT("as &CSV"));
1209 exportMenu->Append(menuItem);
1210 menuItem = new wxMenuItem(exportMenu, Grid_ExpHtml, wxT("as &HTML"));
1211 exportMenu->Append(menuItem);
1212 menuItem = new wxMenuItem(exportMenu, Grid_ExpShp, wxT("as &Shapefile"));
1213 exportMenu->Append(menuItem);
1214 menuItem =
1215 new wxMenuItem(exportMenu, Grid_ExpDif, wxT("as &DIF spreadsheet"));
1216 exportMenu->Append(menuItem);
1217 menuItem =
1218 new wxMenuItem(exportMenu, Grid_ExpSylk, wxT("as &SYLK spreadsheet"));
1219 exportMenu->Append(menuItem);
1220 menuItem = new wxMenuItem(exportMenu, Grid_ExpDbf, wxT("as &DBF archive"));
1221 exportMenu->Append(menuItem);
1222 menu->AppendSubMenu(exportMenu, wxT("&Export ResultSet"));
1223 TableView->PopupMenu(menu, pt);
1224 }
1225
OnCellSelected(wxGridEvent & event)1226 void MyResultSetView::OnCellSelected(wxGridEvent & event)
1227 {
1228 //
1229 // cell selection changed
1230 //
1231 if (InsertPending == true)
1232 {
1233 // an INSERT row is still pending
1234 if (event.GetRow() != TableView->GetNumberRows() - 1)
1235 DoInsert(false);
1236 }
1237 event.Skip();
1238 }
1239
OnCellChanged(wxGridEvent & event)1240 void MyResultSetView::OnCellChanged(wxGridEvent & event)
1241 {
1242 //
1243 // user changed value in some cell
1244 //
1245 MyVariant *oldValue;
1246 MyVariant *insValue;
1247 wxString value;
1248 wxString numValue;
1249 wxString newValue = wxT("NULL");
1250 wxString sql;
1251 wxString rowid;
1252 char *errMsg = NULL;
1253 bool error = false;
1254 sqlite3_int64 int64_value;
1255 long long_value;
1256 bool okIntValue = false;
1257 double dbl_value;
1258 bool okDblValue = false;
1259 int ret;
1260 char dummy[256];
1261 int row = event.GetRow();
1262 int column = event.GetCol();
1263 char xname[1024];
1264 value = TableView->GetCellValue(row, column);
1265 if (InsertPending == true)
1266 {
1267 // an INSERT row is still pending
1268 insValue = InsertRow->GetColumn(column);
1269 numValue = value;
1270 numValue.Replace(wxT(","), wxT("."));
1271 okIntValue = numValue.ToLong(&long_value);
1272 okDblValue = numValue.ToDouble(&dbl_value);
1273 if (okIntValue == true)
1274 {
1275 int64_value = long_value;
1276 insValue->Set(int64_value);
1277 } else if (okDblValue == true)
1278 insValue->Set(dbl_value);
1279 else
1280 insValue->Set(value);
1281 if (row != TableView->GetNumberRows() - 1)
1282 DoInsert(false);
1283 return;
1284 }
1285 if (value.Len() > 0)
1286 {
1287 numValue = value;
1288 numValue.Replace(wxT(","), wxT("."));
1289 okIntValue = numValue.ToLong(&long_value);
1290 okDblValue = numValue.ToDouble(&dbl_value);
1291 if (okIntValue == true)
1292 {
1293 int64_value = long_value;
1294 sprintf(dummy, FORMAT_64, int64_value);
1295 newValue = wxString::FromUTF8(dummy);
1296 } else if (okDblValue == true)
1297 {
1298 sprintf(dummy, "%1.6f", dbl_value);
1299 newValue = wxString::FromUTF8(dummy);
1300 } else
1301 {
1302 value.Replace(wxT("'"), wxT("''"));
1303 newValue = wxT("'") + value + wxT("'");
1304 }
1305 }
1306 oldValue = TableValues->GetValue(row, 0);
1307 sprintf(dummy, FORMAT_64, oldValue->GetIntValue());
1308 rowid = wxString::FromUTF8(dummy);
1309 sql = wxT("UPDATE ");
1310 strcpy(xname, TableName.ToUTF8());
1311 MainFrame->DoubleQuotedSql(xname);
1312 sql += wxString::FromUTF8(xname);
1313 sql += wxT(" SET ");
1314 strcpy(xname, TableView->GetColLabelValue(column).ToUTF8());
1315 MainFrame->DoubleQuotedSql(xname);
1316 sql += wxString::FromUTF8(xname);
1317 sql += wxT(" = ") + newValue + wxT(" WHERE ROWID = ") + rowid;
1318 ret = sqlite3_exec(MainFrame->GetSqlite(), sql.ToUTF8(), NULL, NULL, &errMsg);
1319 if (ret != SQLITE_OK)
1320 {
1321 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
1322 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1323 sqlite3_free(errMsg);
1324 error = true;
1325 }
1326 oldValue = TableValues->GetValue(row, column);
1327 if (error == true)
1328 {
1329 // update failed; restorig old cell value
1330 value = wxT("NULL");
1331 if (oldValue)
1332 {
1333 if (oldValue->GetType() == MY_INT_VARIANT)
1334 {
1335 sprintf(dummy, FORMAT_64, oldValue->GetIntValue());
1336 value = wxString::FromUTF8(dummy);
1337 }
1338 if (oldValue->GetType() == MY_DBL_VARIANT)
1339 {
1340 sprintf(dummy, "%1.6f", oldValue->GetDblValue());
1341 value = wxString::FromUTF8(dummy);
1342 }
1343 if (oldValue->GetType() == MY_TXT_VARIANT)
1344 value = oldValue->GetTxtValue();
1345 }
1346 TableView->SetCellValue(row, column, value);
1347 TableView->ForceRefresh();
1348 } else
1349 {
1350 // marking cell as modified
1351 TableView->SetCellTextColour(row, column, wxColour(0, 0, 192));
1352 TableView->SetCellBackgroundColour(row, column, wxColour(255, 255, 204));
1353 TableView->ForceRefresh();
1354 }
1355 }
1356
DoInsert(bool confirmed)1357 void MyResultSetView::DoInsert(bool confirmed)
1358 {
1359 //
1360 // performing actual row INSERT
1361 //
1362 int i;
1363 int ret;
1364 MyVariant *var;
1365 wxString value;
1366 wxString strValue;
1367 wxString sql;
1368 char dummy[256];
1369 char *errMsg = NULL;
1370 char xname[1024];
1371 if (confirmed == false)
1372 {
1373 ret =
1374 wxMessageBox(wxT("A new row is ready for insertion\n\nConfirm ?"),
1375 wxT("spatialite_gui"), wxYES_NO | wxICON_QUESTION, this);
1376 if (ret != wxYES)
1377 goto close_insert;
1378 }
1379 sql = wxT("INSERT INTO ");
1380 strcpy(xname, TableName.ToUTF8());
1381 MainFrame->DoubleQuotedSql(xname);
1382 sql += wxString::FromUTF8(xname);
1383 sql += wxT(" (");
1384 for (i = 1; i < TableView->GetNumberCols(); i++)
1385 {
1386 if (i > 1)
1387 sql += wxT(", ");
1388 strcpy(xname, TableView->GetColLabelValue(i).ToUTF8());
1389 MainFrame->DoubleQuotedSql(xname);
1390 sql += wxString::FromUTF8(xname);
1391 }
1392 sql += wxT(") VALUES (");
1393 for (i = 1; i < InsertRow->GetNumCols(); i++)
1394 {
1395 if (i > 1)
1396 sql += wxT(", ");
1397 var = InsertRow->GetColumn(i);
1398 value = wxT("NULL");
1399 if (var->GetType() == MY_INT_VARIANT)
1400 {
1401 sprintf(dummy, FORMAT_64, var->GetIntValue());
1402 value = wxString::FromUTF8(dummy);
1403 }
1404 if (var->GetType() == MY_DBL_VARIANT)
1405 {
1406 sprintf(dummy, "%1.6f", var->GetDblValue());
1407 value = wxString::FromUTF8(dummy);
1408 }
1409 if (var->GetType() == MY_TXT_VARIANT)
1410 {
1411 strValue = var->GetTxtValue();
1412 strValue.Replace(wxT("'"), wxT("''"));
1413 value = wxT("'") + strValue + wxT("'");
1414 }
1415 sql += value;
1416 }
1417 sql += wxT(")");
1418 ret = sqlite3_exec(MainFrame->GetSqlite(), sql.ToUTF8(), NULL, NULL, &errMsg);
1419 if (ret != SQLITE_OK)
1420 {
1421 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
1422 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1423 sqlite3_free(errMsg);
1424 }
1425 close_insert:
1426 //
1427 // closing insert row
1428 //
1429 InsertPending = false;
1430 delete InsertRow;
1431 InsertRow = NULL;
1432 for (i = 0; i < TableView->GetNumberCols(); i++)
1433 {
1434 TableView->SetCellValue(TableView->GetNumberRows() - 1, i, wxT(""));
1435 TableView->SetCellBackgroundColour(TableView->GetNumberRows() - 1, i,
1436 wxColour(0, 0, 0));
1437 TableView->SetReadOnly(TableView->GetNumberRows() - 1, i);
1438 }
1439 }
1440
OnCmdDelete(wxCommandEvent & WXUNUSED (event))1441 void MyResultSetView::OnCmdDelete(wxCommandEvent & WXUNUSED(event))
1442 {
1443 //
1444 // user required row deletion
1445 //
1446 char *errMsg = NULL;
1447 bool error = false;
1448 int ret;
1449 int i;
1450 wxString sql;
1451 wxString rowid;
1452 MyVariant *value;
1453 char dummy[256];
1454 char xname[1024];
1455 MyRowVariant *varRow = TableValues->GetRow(CurrentEvtRow);
1456 if (varRow->IsDeleted() == true)
1457 return;
1458 value = TableValues->GetValue(CurrentEvtRow, 0);
1459 sprintf(dummy, FORMAT_64, value->GetIntValue());
1460 rowid = wxString::FromUTF8(dummy);
1461 ret =
1462 wxMessageBox(wxT("Requested deletion for row identified by RowId = ")
1463 + rowid + wxT("\n\nConfirm ?"), wxT("spatialite_gui"),
1464 wxYES_NO | wxICON_QUESTION, this);
1465 if (ret != wxYES)
1466 return;
1467 strcpy(xname, TableName.ToUTF8());
1468 MainFrame->DoubleQuotedSql(xname);
1469 sql =
1470 wxT("DELETE FROM ") + wxString::FromUTF8(xname) + wxT(" WHERE ROWID = ") +
1471 rowid;
1472 ret = sqlite3_exec(MainFrame->GetSqlite(), sql.ToUTF8(), NULL, NULL, &errMsg);
1473 if (ret != SQLITE_OK)
1474 {
1475 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
1476 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1477 sqlite3_free(errMsg);
1478 error = true;
1479 }
1480 if (error == false)
1481 {
1482 // marking row as deleted
1483 varRow->SetDeleted();
1484 for (i = 0; i < TableView->GetNumberCols(); i++)
1485 {
1486 TableView->SetCellTextColour(CurrentEvtRow, i, wxColour(0, 0, 0));
1487 TableView->SetCellBackgroundColour(CurrentEvtRow, i,
1488 wxColour(128, 128, 128));
1489 TableView->SetReadOnly(CurrentEvtRow, i);
1490 }
1491 TableView->ForceRefresh();
1492 }
1493 }
1494
OnCmdInsert(wxCommandEvent & WXUNUSED (event))1495 void MyResultSetView::OnCmdInsert(wxCommandEvent & WXUNUSED(event))
1496 {
1497 //
1498 // user required row insertion
1499 //
1500 int i;
1501 if (ReadOnly == true)
1502 return;
1503 if (InsertPending == true)
1504 {
1505 // an INSERT is still pending, and the user required actual insertion
1506 DoInsert(true);
1507 return;
1508 }
1509 InsertRow = new MyRowVariant(TableView->GetNumberCols());
1510 TableView->MakeCellVisible(TableView->GetNumberRows() - 1, 1);
1511 InsertPending = true;
1512 for (i = 1; i < TableView->GetNumberCols(); i++)
1513 {
1514 TableView->SetCellValue(TableView->GetNumberRows() - 1, i, wxT(""));
1515 TableView->SetCellBackgroundColour(TableView->GetNumberRows() - 1, i,
1516 wxColour(255, 255, 255));
1517 TableView->SetReadOnly(TableView->GetNumberRows() - 1, i, false);
1518 }
1519 }
1520
OnCmdAbort(wxCommandEvent & WXUNUSED (event))1521 void MyResultSetView::OnCmdAbort(wxCommandEvent & WXUNUSED(event))
1522 {
1523 //
1524 // user cancelled current row insertion
1525 //
1526 int i;
1527 if (InsertPending)
1528 {
1529 InsertPending = false;
1530 delete InsertRow;
1531 InsertRow = NULL;
1532 for (i = 0; i < TableView->GetNumberCols(); i++)
1533 {
1534 TableView->SetCellValue(TableView->GetNumberRows() - 1, i, wxT(""));
1535 TableView->SetCellBackgroundColour(TableView->GetNumberRows() - 1, i,
1536 wxColour(0, 0, 0));
1537 TableView->SetReadOnly(TableView->GetNumberRows() - 1, i);
1538 }
1539 }
1540 }
1541
OnCmdClearSelection(wxCommandEvent & WXUNUSED (event))1542 void MyResultSetView::OnCmdClearSelection(wxCommandEvent & WXUNUSED(event))
1543 {
1544 //
1545 // clearing current selection
1546 //
1547 TableView->ClearSelection();
1548 }
1549
OnCmdSelectAll(wxCommandEvent & WXUNUSED (event))1550 void MyResultSetView::OnCmdSelectAll(wxCommandEvent & WXUNUSED(event))
1551 {
1552 //
1553 // selecting all
1554 //
1555 TableView->SelectAll();
1556 }
1557
OnCmdSelectRow(wxCommandEvent & WXUNUSED (event))1558 void MyResultSetView::OnCmdSelectRow(wxCommandEvent & WXUNUSED(event))
1559 {
1560 //
1561 // selecting the current row
1562 //
1563 TableView->SelectRow(CurrentEvtRow);
1564 }
1565
OnCmdSelectColumn(wxCommandEvent & WXUNUSED (event))1566 void MyResultSetView::OnCmdSelectColumn(wxCommandEvent & WXUNUSED(event))
1567 {
1568 //
1569 // selecting column
1570 //
1571 TableView->SelectCol(CurrentEvtColumn);
1572 }
1573
OnCmdCopy(wxCommandEvent & WXUNUSED (event))1574 void MyResultSetView::OnCmdCopy(wxCommandEvent & WXUNUSED(event))
1575 {
1576 //
1577 // copying the selection into the clipboard
1578 //
1579 wxString copyData;
1580 int row;
1581 int col;
1582 bool newRow;
1583 bool firstRow = true;
1584 for (row = 0; row < TableView->GetNumberRows(); row++)
1585 {
1586 newRow = true;
1587 for (col = 0; col < TableView->GetNumberCols(); col++)
1588 {
1589 if (TableView->IsInSelection(row, col) == true)
1590 {
1591 // ok, this cell is included into the selection to copy
1592 if (firstRow == true)
1593 {
1594 newRow = false;
1595 firstRow = false;
1596 } else if (newRow == true)
1597 {
1598 newRow = false;
1599 copyData += wxT("\n");
1600 } else
1601 copyData += wxT("\t");
1602 copyData += TableView->GetCellValue(row, col);
1603 }
1604 }
1605 }
1606 if (wxTheClipboard->Open())
1607 {
1608 wxTheClipboard->SetData(new wxTextDataObject(copyData));
1609 wxTheClipboard->Close();
1610 }
1611 }
1612
OnCmdBlob(wxCommandEvent & WXUNUSED (event))1613 void MyResultSetView::OnCmdBlob(wxCommandEvent & WXUNUSED(event))
1614 {
1615 //
1616 // exploring some BLOB value
1617 //
1618 if (!CurrentBlob)
1619 return;
1620 BlobExplorerDialog dlg;
1621 dlg.Create(MainFrame, CurrentBlob->GetBlobSize(), CurrentBlob->GetBlob());
1622 dlg.ShowModal();
1623 }
1624
OnCmdBlobIn(wxCommandEvent & WXUNUSED (event))1625 void MyResultSetView::OnCmdBlobIn(wxCommandEvent & WXUNUSED(event))
1626 {
1627 // importing an external file into a BLOB-value
1628 FILE *in = NULL;
1629 char path[2048];
1630 int rd;
1631 int maxSize = 1024 * 1024; // limit BLOB size to 1MB
1632 wxString fileList;
1633 wxString rowid;
1634 wxString sql;
1635 wxString blobValue;
1636 wxString hex;
1637 MyVariant *value;
1638 char dummy[1024];
1639 bool error = false;
1640 unsigned char *buffer = NULL;
1641 int ret;
1642 char *errMsg = NULL;
1643 wxString lastDir;
1644 char xname[1024];
1645 fileList =
1646 wxT
1647 ("BLOB Document (*.jpg;*.jpeg;*.png;*.gif;*.tif;*.pdf;*.zip)|*.jpg;*.jpeg;*.png;*.gif;*.tif;*.pdf;*.zip|");
1648 fileList +=
1649 wxT
1650 ("Image (*.jpg;*.jpeg;*.png;*.gif;*.tif)|*.jpg;*.jpeg;*.png;*.gif;*.tif|");
1651 fileList +=
1652 wxT
1653 ("JPEG Image (*.jpg;*.jpeg)|*.jpg;*.jpeg|PNG Image (*.png)|*.png|GIF Image (*.gif)|*.gif|TIFF Image (*.tif)|*.tif|");
1654 fileList +=
1655 wxT("PDF Document (*.pdf)|*.pdf|ZIP Archive|(*.zip)|All files (*.*)|*.*");
1656 wxFileDialog fileDialog(this, wxT("loading a BLOB value"),
1657 wxT(""), wxT(""), fileList,
1658 wxFD_OPEN | wxFD_FILE_MUST_EXIST,
1659 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
1660 lastDir = MainFrame->GetLastDirectory();
1661 if (lastDir.Len() >= 1)
1662 fileDialog.SetDirectory(lastDir);
1663 ret = fileDialog.ShowModal();
1664 if (ret == wxID_OK)
1665 {
1666 strcpy(path, fileDialog.GetPath().ToUTF8());
1667 in = fopen(path, "rb");
1668 if (!in)
1669 {
1670 wxMessageBox(wxT("Cannot open '") + fileDialog.GetPath() +
1671 wxT("' for reading"), wxT("spatialite_gui"),
1672 wxOK | wxICON_ERROR, this);
1673 return;
1674 }
1675 wxFileName file(fileDialog.GetPath());
1676 lastDir = file.GetPath();
1677 MainFrame->SetLastDirectory(lastDir);
1678 ::wxBeginBusyCursor();
1679 buffer = new unsigned char[maxSize];
1680 rd = fread(buffer, 1, maxSize, in);
1681 if (rd == maxSize && !(feof(in)))
1682 {
1683 // exceding 1MB; it's too big for a BLOB
1684 wxMessageBox(wxT
1685 ("Selected file excedes 1MB; cowardly refusing to load it as a BLOB value ..."),
1686 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1687 goto end;
1688 }
1689 if (ferror(in))
1690 {
1691 // I/O error
1692 wxMessageBox(wxT("an I/O error occurred"), wxT("spatialite_gui"),
1693 wxOK | wxICON_ERROR, this);
1694 goto end;
1695 }
1696 //
1697 // preparing the SQL UPDATE statement
1698 //
1699 value = TableValues->GetValue(CurrentEvtRow, 0);
1700 sprintf(dummy, FORMAT_64, value->GetIntValue());
1701 rowid = wxString::FromUTF8(dummy);
1702 HexBlobValue(buffer, rd, hex);
1703 sql = wxT("UPDATE ");
1704 strcpy(xname, TableName.ToUTF8());
1705 MainFrame->DoubleQuotedSql(xname);
1706 sql += wxString::FromUTF8(xname);
1707 sql += wxT(" SET ");
1708 strcpy(xname, TableView->GetColLabelValue(CurrentEvtColumn).ToUTF8());
1709 MainFrame->DoubleQuotedSql(xname);
1710 sql += wxString::FromUTF8(xname);
1711 sql += wxT(" = ") + hex + wxT(" WHERE ROWID = ") + rowid;
1712 ret =
1713 sqlite3_exec(MainFrame->GetSqlite(), sql.ToUTF8(), NULL, NULL, &errMsg);
1714 if (ret != SQLITE_OK)
1715 {
1716 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
1717 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1718 sqlite3_free(errMsg);
1719 error = true;
1720 }
1721 value = TableValues->GetValue(CurrentEvtRow, CurrentEvtColumn);
1722 if (error == false)
1723 {
1724 // updating the Grid cell
1725 sprintf(dummy, "BLOB sz=%d ", rd);
1726 blobValue = wxString::FromUTF8(dummy);
1727 switch (gaiaGuessBlobType(buffer, rd))
1728 {
1729 case GAIA_JPEG_BLOB:
1730 blobValue += wxT("JPEG image");
1731 break;
1732 case GAIA_EXIF_BLOB:
1733 blobValue += wxT("JPEG-EXIF image");
1734 break;
1735 case GAIA_EXIF_GPS_BLOB:
1736 blobValue += wxT("JPEG-EXIF-GPS image");
1737 break;
1738 case GAIA_PNG_BLOB:
1739 blobValue += wxT("PNG image");
1740 break;
1741 case GAIA_GIF_BLOB:
1742 blobValue += wxT("GIF image");
1743 break;
1744 case GAIA_TIFF_BLOB:
1745 blobValue += wxT("TIFF image");
1746 break;
1747 case GAIA_PDF_BLOB:
1748 blobValue += wxT("PDF document");
1749 break;
1750 case GAIA_ZIP_BLOB:
1751 blobValue += wxT("ZIP archive");
1752 break;
1753 default:
1754 blobValue += wxT("UNKNOWN type");
1755 break;
1756 };
1757 TableView->SetCellValue(CurrentEvtRow, CurrentEvtColumn, blobValue);
1758 TableView->SetCellTextColour(CurrentEvtRow, CurrentEvtColumn,
1759 wxColour(0, 0, 192));
1760 TableView->SetCellBackgroundColour(CurrentEvtRow, CurrentEvtColumn,
1761 wxColour(255, 255, 204));
1762 TableView->ForceRefresh();
1763 }
1764 }
1765 end:
1766 // clean-up
1767 ::wxEndBusyCursor();
1768 if (in)
1769 fclose(in);
1770 if (buffer)
1771 delete[]buffer;
1772 }
1773
HexBlobValue(unsigned char * blob,int size,wxString & hex)1774 void MyResultSetView::HexBlobValue(unsigned char *blob, int size,
1775 wxString & hex)
1776 {
1777 //
1778 // builds the HEX BLOB as X'01234567890abcdef'
1779 //
1780 int i;
1781 char digit[16];
1782 hex = wxT("X'");
1783 for (i = 0; i < size; i++)
1784 {
1785 sprintf(digit, "%02x", *(blob + i));
1786 hex += wxString::FromUTF8(digit);
1787 }
1788 hex += wxT("'");
1789 }
1790
OnCmdBlobOut(wxCommandEvent & WXUNUSED (event))1791 void MyResultSetView::OnCmdBlobOut(wxCommandEvent & WXUNUSED(event))
1792 {
1793 // exporting to external file a BLOB-value
1794 int blobType;
1795 wxString fileName;
1796 wxString fileType;
1797 int ret;
1798 wxString path;
1799 FILE *out = NULL;
1800 char xpath[2048];
1801 int wr;
1802 wxString lastDir;
1803 if (!CurrentBlob)
1804 return;
1805 blobType =
1806 gaiaGuessBlobType(CurrentBlob->GetBlob(), CurrentBlob->GetBlobSize());
1807 switch (blobType)
1808 {
1809 case GAIA_JPEG_BLOB:
1810 case GAIA_EXIF_BLOB:
1811 case GAIA_EXIF_GPS_BLOB:
1812 fileName = wxT("image.jpg");
1813 fileType = wxT("File JPEG (*.jpg;*.jpeg)|*.jpg");
1814 break;
1815 case GAIA_PNG_BLOB:
1816 fileName = wxT("image.png");
1817 fileType = wxT("File PNG (*.png)|*.png");
1818 break;
1819 case GAIA_GIF_BLOB:
1820 fileName = wxT("image.gif");
1821 fileType = wxT("File GIF (*.gif)|*.gif");
1822 break;
1823 case GAIA_TIFF_BLOB:
1824 fileName = wxT("image.tiff");
1825 fileType = wxT("File TIFF (*.tif)|*.tif");
1826 break;
1827 case GAIA_PDF_BLOB:
1828 fileName = wxT("document.pdf");
1829 fileType = wxT("PDF document (*.pdf)|*.pdf");
1830 break;
1831 case GAIA_ZIP_BLOB:
1832 fileName = wxT("archive.zip");
1833 fileType = wxT("ZIP Archive (*.zip)|*.zip");
1834 break;
1835 default:
1836 fileName = wxT("file");
1837 };
1838 fileType += wxT("|All files (*.*)|*.*");
1839 wxFileDialog fileDialog(this, wxT("exporting a BLOB value to file"),
1840 wxT(""), fileName, fileType,
1841 wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
1842 wxDefaultSize, wxT("filedlg"));
1843 lastDir = MainFrame->GetLastDirectory();
1844 if (lastDir.Len() >= 1)
1845 fileDialog.SetDirectory(lastDir);
1846 ret = fileDialog.ShowModal();
1847 if (ret == wxID_OK)
1848 {
1849 wxFileName file(fileDialog.GetPath());
1850 path = file.GetPath();
1851 path += file.GetPathSeparator();
1852 path += file.GetName();
1853 switch (blobType)
1854 {
1855 case GAIA_JPEG_BLOB:
1856 case GAIA_EXIF_BLOB:
1857 case GAIA_EXIF_GPS_BLOB:
1858 path += wxT(".jpg");
1859 break;
1860 case GAIA_PNG_BLOB:
1861 path += wxT(".png");
1862 break;
1863 case GAIA_GIF_BLOB:
1864 path += wxT(".gif");
1865 break;
1866 case GAIA_TIFF_BLOB:
1867 path += wxT(".tif");
1868 break;
1869 case GAIA_PDF_BLOB:
1870 path += wxT(".pdf");
1871 break;
1872 case GAIA_ZIP_BLOB:
1873 path += wxT(".zip");
1874 break;
1875 default:
1876 path += file.GetExt();
1877 };
1878 strcpy(xpath, path.ToUTF8());
1879 out = fopen(xpath, "wb");
1880 if (!out)
1881 {
1882 wxMessageBox(wxT("Cannot open '") + path + wxT("' for writing"),
1883 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1884 return;
1885 }
1886 lastDir = file.GetPath();
1887 MainFrame->SetLastDirectory(lastDir);
1888 ::wxBeginBusyCursor();
1889 wr = fwrite(CurrentBlob->GetBlob(), 1, CurrentBlob->GetBlobSize(), out);
1890 if (wr != CurrentBlob->GetBlobSize())
1891 {
1892 wxMessageBox(wxT("an I/O error occurred"), wxT("spatialite_gui"),
1893 wxOK | wxICON_ERROR, this);
1894 }
1895 fclose(out);
1896 ::wxEndBusyCursor();
1897 }
1898 }
1899
OnCmdXmlBlobIn(wxCommandEvent & WXUNUSED (event))1900 void MyResultSetView::OnCmdXmlBlobIn(wxCommandEvent & WXUNUSED(event))
1901 {
1902 // importing an external XMLDocument into an XmlBLOB-value
1903 #ifdef ENABLE_LIBXML2 /* only if LIBXML2 is enabled */
1904 FILE *in = NULL;
1905 char path[2048];
1906 int rd;
1907 int maxSize = 1024 * 1024; // limit XmlBLOB size to 1MB
1908 wxString fileList;
1909 wxString rowid;
1910 wxString sql;
1911 wxString blobValue;
1912 wxString hex;
1913 MyVariant *value;
1914 char dummy[1024];
1915 bool error = false;
1916 unsigned char *buffer = NULL;
1917 int ret;
1918 char *errMsg = NULL;
1919 wxString lastDir;
1920 char xname[1024];
1921 unsigned char *xml = NULL;
1922 int xml_size;
1923 int compressed;
1924 char *schemaURI;
1925 char xschema[8192];
1926 fileList = wxT("XML Document (*.xml)|*.xml|All files (*.*)|*.*");
1927 wxFileDialog fileDialog(this, wxT("loading an XmlBLOB value"),
1928 wxT(""), wxT(""), fileList,
1929 wxFD_OPEN | wxFD_FILE_MUST_EXIST,
1930 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
1931 lastDir = MainFrame->GetLastDirectory();
1932 if (lastDir.Len() >= 1)
1933 fileDialog.SetDirectory(lastDir);
1934 ret = fileDialog.ShowModal();
1935 if (ret == wxID_OK)
1936 {
1937 strcpy(path, fileDialog.GetPath().ToUTF8());
1938 in = fopen(path, "rb");
1939 if (!in)
1940 {
1941 wxMessageBox(wxT("Cannot open '") + fileDialog.GetPath() +
1942 wxT("' for reading"), wxT("spatialite_gui"),
1943 wxOK | wxICON_ERROR, this);
1944 return;
1945 }
1946 wxFileName file(fileDialog.GetPath());
1947 lastDir = file.GetPath();
1948 MainFrame->SetLastDirectory(lastDir);
1949 ::wxBeginBusyCursor();
1950 buffer = new unsigned char[maxSize];
1951 rd = fread(buffer, 1, maxSize, in);
1952 if (rd == maxSize && !(feof(in)))
1953 {
1954 // exceding 1MB; it's too big for a BLOB
1955 wxMessageBox(wxT
1956 ("Selected file excedes 1MB; cowardly refusing to load it as an XmlBLOB value ..."),
1957 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1958 goto end;
1959 }
1960 if (ferror(in))
1961 {
1962 // I/O error
1963 wxMessageBox(wxT("an I/O error occurred"), wxT("spatialite_gui"),
1964 wxOK | wxICON_ERROR, this);
1965 goto end;
1966 }
1967
1968 LoadXmlDialog dlg;
1969 wxString inPath = fileDialog.GetPath();
1970 dlg.Create(MainFrame, inPath);
1971 ret = dlg.ShowModal();
1972 if (ret == wxID_OK)
1973 {
1974 if (dlg.IsCompressed() == true)
1975 compressed = 1;
1976 else
1977 compressed = 0;
1978 wxString schema = dlg.GetSchemaURI();
1979 if (schema.Len() == 0)
1980 schemaURI = NULL;
1981 else
1982 {
1983 strcpy(xschema, schema.ToUTF8());
1984 schemaURI = xschema;
1985 }
1986 } else
1987 goto end;
1988
1989 // attempting to parse (and possibly validate) the XML
1990 gaiaXmlToBlob(MainFrame->GetInternalCache(), buffer, rd, compressed,
1991 schemaURI, &xml, &xml_size, NULL, NULL);
1992 if (xml == NULL)
1993 {
1994 wxMessageBox(wxT("Invalid XML ... unable to parse or validate"),
1995 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1996 goto end;
1997 }
1998 //
1999 // preparing the SQL UPDATE statement
2000 //
2001 value = TableValues->GetValue(CurrentEvtRow, 0);
2002 sprintf(dummy, FORMAT_64, value->GetIntValue());
2003 rowid = wxString::FromUTF8(dummy);
2004 HexBlobValue(xml, xml_size, hex);
2005 sql = wxT("UPDATE ");
2006 strcpy(xname, TableName.ToUTF8());
2007 MainFrame->DoubleQuotedSql(xname);
2008 sql += wxString::FromUTF8(xname);
2009 sql += wxT(" SET ");
2010 strcpy(xname, TableView->GetColLabelValue(CurrentEvtColumn).ToUTF8());
2011 MainFrame->DoubleQuotedSql(xname);
2012 sql += wxString::FromUTF8(xname);
2013 sql += wxT(" = ") + hex + wxT(" WHERE ROWID = ") + rowid;
2014 ret =
2015 sqlite3_exec(MainFrame->GetSqlite(), sql.ToUTF8(), NULL, NULL, &errMsg);
2016 if (ret != SQLITE_OK)
2017 {
2018 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2019 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2020 sqlite3_free(errMsg);
2021 error = true;
2022 }
2023 value = TableValues->GetValue(CurrentEvtRow, CurrentEvtColumn);
2024 if (error == false)
2025 {
2026 // updating the Grid cell
2027 int doc_size = gaiaXmlBlobGetDocumentSize(xml, xml_size);
2028 sprintf(dummy, "XmlBLOB sz=%d (XMLsz=%d) ", xml_size, doc_size);
2029 blobValue = wxString::FromUTF8(dummy);
2030 if (gaiaIsSchemaValidatedXmlBlob(xml, xml_size))
2031 blobValue += wxT(" SchemaValidated");
2032 TableView->SetCellValue(CurrentEvtRow, CurrentEvtColumn, blobValue);
2033 TableView->SetCellTextColour(CurrentEvtRow, CurrentEvtColumn,
2034 wxColour(0, 0, 192));
2035 TableView->SetCellBackgroundColour(CurrentEvtRow, CurrentEvtColumn,
2036 wxColour(255, 255, 204));
2037 TableView->ForceRefresh();
2038 }
2039 }
2040 end:
2041 // clean-up
2042 ::wxEndBusyCursor();
2043 if (in)
2044 fclose(in);
2045 if (buffer)
2046 delete[]buffer;
2047 if (xml)
2048 free(xml);
2049
2050 #else
2051
2052 wxMessageBox(wxT
2053 ("Sorry, spatialite_gui was built disabling LIBXML2\n\nUnsupported operation"),
2054 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2055
2056 #endif /* end LIBXML2 conditionals */
2057 }
2058
XmlBlobOut(bool indented)2059 void MyResultSetView::XmlBlobOut(bool indented)
2060 {
2061 // exporting to external file an XmlBLOB-value
2062 #ifdef ENABLE_LIBXML2 /* only if LIBXML2 is enabled */
2063 wxString fileName;
2064 wxString fileType;
2065 int ret;
2066 wxString path;
2067 FILE *out = NULL;
2068 char xpath[2048];
2069 int wr;
2070 wxString lastDir;
2071 unsigned char *xml;
2072 int xml_size;
2073 wxString title = wxT("exporting an XmlBLOB value to file ");
2074 if (!CurrentBlob)
2075 return;
2076 if (indented)
2077 {
2078 title += wxT("(not indented)");
2079 gaiaXmlFromBlob(CurrentBlob->GetBlob(), CurrentBlob->GetBlobSize(), 0,
2080 &xml, &xml_size);
2081 } else
2082 {
2083 title += wxT("(indented)");
2084 gaiaXmlFromBlob(CurrentBlob->GetBlob(), CurrentBlob->GetBlobSize(), 1,
2085 &xml, &xml_size);
2086 }
2087 if (xml == NULL)
2088 return;
2089 fileName = wxT("document.xml");
2090 fileType = wxT("XML Document (*.xml)|*.xml");
2091 fileType += wxT("|All files (*.*)|*.*");
2092 wxFileDialog fileDialog(this, title,
2093 wxT(""), fileName, fileType,
2094 wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
2095 wxDefaultSize, wxT("filedlg"));
2096 lastDir = MainFrame->GetLastDirectory();
2097 if (lastDir.Len() >= 1)
2098 fileDialog.SetDirectory(lastDir);
2099 ret = fileDialog.ShowModal();
2100 if (ret == wxID_OK)
2101 {
2102 wxFileName file(fileDialog.GetPath());
2103 path = file.GetPath();
2104 path += file.GetPathSeparator();
2105 path += file.GetName();
2106 path += wxT(".xml");
2107 strcpy(xpath, path.ToUTF8());
2108 out = fopen(xpath, "wb");
2109 if (!out)
2110 {
2111 wxMessageBox(wxT("Cannot open '") + path + wxT("' for writing"),
2112 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2113 free(xml);
2114 return;
2115 }
2116 lastDir = file.GetPath();
2117 MainFrame->SetLastDirectory(lastDir);
2118 ::wxBeginBusyCursor();
2119 wr = fwrite(xml, 1, xml_size, out);
2120 if (wr != xml_size)
2121 {
2122 wxMessageBox(wxT("an I/O error occurred"), wxT("spatialite_gui"),
2123 wxOK | wxICON_ERROR, this);
2124 }
2125 fclose(out);
2126 ::wxEndBusyCursor();
2127 }
2128 free(xml);
2129
2130 #else
2131
2132 wxMessageBox(wxT
2133 ("Sorry, spatialite_gui was built disabling LIBXML2\n\nUnsupported operation"),
2134 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2135
2136 #endif /* end LIBXML2 conditionals */
2137 }
2138
OnCmdXmlBlobOut(wxCommandEvent & WXUNUSED (event))2139 void MyResultSetView::OnCmdXmlBlobOut(wxCommandEvent & WXUNUSED(event))
2140 {
2141 // exporting to external file an XmlBLOB-value (not indented)
2142 XmlBlobOut(false);
2143 }
2144
OnCmdXmlBlobOutIndented(wxCommandEvent & WXUNUSED (event))2145 void MyResultSetView::OnCmdXmlBlobOutIndented(wxCommandEvent & WXUNUSED(event))
2146 {
2147 // exporting to external file an XmlBLOB-value (indented)
2148 XmlBlobOut(true);
2149 }
2150
OnCmdBlobNull(wxCommandEvent & WXUNUSED (event))2151 void MyResultSetView::OnCmdBlobNull(wxCommandEvent & WXUNUSED(event))
2152 {
2153 // setting to NULL a BLOB-value
2154 wxString rowid;
2155 wxString sql;
2156 int ret;
2157 char *errMsg = NULL;
2158 bool error = false;
2159 MyVariant *value;
2160 char dummy[256];
2161 char xname[1024];
2162 value = TableValues->GetValue(CurrentEvtRow, 0);
2163 sprintf(dummy, FORMAT_64, value->GetIntValue());
2164 rowid = wxString::FromUTF8(dummy);
2165 sql = wxT("UPDATE ");
2166 strcpy(xname, TableName.ToUTF8());
2167 MainFrame->DoubleQuotedSql(xname);
2168 sql += wxString::FromUTF8(xname);
2169 sql += wxT(" SET ");
2170 strcpy(xname, TableView->GetColLabelValue(CurrentEvtColumn).ToUTF8());
2171 MainFrame->DoubleQuotedSql(xname);
2172 sql += wxString::FromUTF8(xname);
2173 sql += wxT(" = NULL WHERE ROWID = ") + rowid;
2174 ret = sqlite3_exec(MainFrame->GetSqlite(), sql.ToUTF8(), NULL, NULL, &errMsg);
2175 if (ret != SQLITE_OK)
2176 {
2177 wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(errMsg),
2178 wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
2179 sqlite3_free(errMsg);
2180 error = true;
2181 }
2182 if (error == false)
2183 {
2184 // updating the Grid cell
2185 TableView->SetCellValue(CurrentEvtRow, CurrentEvtColumn, wxT("NULL"));
2186 TableView->SetCellTextColour(CurrentEvtRow, CurrentEvtColumn,
2187 wxColour(0, 0, 192));
2188 TableView->SetCellBackgroundColour(CurrentEvtRow, CurrentEvtColumn,
2189 wxColour(255, 255, 204));
2190 TableView->ForceRefresh();
2191 }
2192 }
2193
OnCmdExpTxtTab(wxCommandEvent & WXUNUSED (event))2194 void MyResultSetView::OnCmdExpTxtTab(wxCommandEvent & WXUNUSED(event))
2195 {
2196 //
2197 // exporting the ResultSet as TXT-TAB
2198 //
2199 int ret;
2200 wxString path;
2201 wxString lastDir;
2202 wxString target;
2203 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
2204 wxFileDialog fileDialog(this, wxT("Exporting the ResultSet as Txt/Tab file"),
2205 wxT(""), wxT("result_set.txt"),
2206 wxT("Txt/Tab file (*.txt)|*.txt|All files (*.*)|*.*"),
2207 wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
2208 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
2209 lastDir = MainFrame->GetLastDirectory();
2210 if (lastDir.Len() >= 1)
2211 fileDialog.SetDirectory(lastDir);
2212 ret = fileDialog.ShowModal();
2213 if (ret == wxID_OK)
2214 {
2215 wxFileName file(fileDialog.GetPath());
2216 path = file.GetPath();
2217 path += file.GetPathSeparator();
2218 path += file.GetName();
2219 path += wxT(".txt");
2220 lastDir = file.GetPath();
2221 if (MainFrame->IsSetAskCharset() == false)
2222 {
2223 // using the default output charset
2224 MainFrame->SetLastDirectory(lastDir);
2225 ::wxBeginBusyCursor();
2226 MainFrame->ExportResultSetAsTxtTab(path, sql,
2227 MainFrame->GetDefaultCharset());
2228 ::wxEndBusyCursor();
2229 } else
2230 {
2231 // asking the charset to be used
2232 DumpTxtDialog dlg;
2233 target = wxT("TXT / TAB");
2234 dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
2235 ret = dlg.ShowModal();
2236 if (ret == wxID_OK)
2237 {
2238 MainFrame->SetLastDirectory(lastDir);
2239 ::wxBeginBusyCursor();
2240 MainFrame->ExportResultSetAsTxtTab(path, sql, dlg.GetCharset());
2241 ::wxEndBusyCursor();
2242 }
2243 }
2244 }
2245 }
2246
OnCmdExpCsv(wxCommandEvent & WXUNUSED (event))2247 void MyResultSetView::OnCmdExpCsv(wxCommandEvent & WXUNUSED(event))
2248 {
2249 //
2250 // exporting the ResultSet as CSV
2251 //
2252 int ret;
2253 wxString path;
2254 wxString lastDir;
2255 wxString target;
2256 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
2257 wxFileDialog fileDialog(this, wxT("Exporting the ResultSet as CSV"),
2258 wxT(""), wxT("result_set.csv"),
2259 wxT("CSV file (*.csv)|*.csv|All files (*.*)|*.*"),
2260 wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
2261 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
2262 lastDir = MainFrame->GetLastDirectory();
2263 if (lastDir.Len() >= 1)
2264 fileDialog.SetDirectory(lastDir);
2265 ret = fileDialog.ShowModal();
2266 if (ret == wxID_OK)
2267 {
2268 wxFileName file(fileDialog.GetPath());
2269 path = file.GetPath();
2270 path += file.GetPathSeparator();
2271 path += file.GetName();
2272 path += wxT(".csv");
2273 lastDir = file.GetPath();
2274 if (MainFrame->IsSetAskCharset() == false)
2275 {
2276 // using the default output charset
2277 MainFrame->SetLastDirectory(lastDir);
2278 ::wxBeginBusyCursor();
2279 MainFrame->ExportResultSetAsCsv(path, sql,
2280 MainFrame->GetDefaultCharset());
2281 ::wxEndBusyCursor();
2282 } else
2283 {
2284 // asking the charset to be used
2285 DumpTxtDialog dlg;
2286 target = wxT("CSV");
2287 dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
2288 ret = dlg.ShowModal();
2289 if (ret == wxID_OK)
2290 {
2291 MainFrame->SetLastDirectory(lastDir);
2292 ::wxBeginBusyCursor();
2293 MainFrame->ExportResultSetAsCsv(path, sql, dlg.GetCharset());
2294 ::wxEndBusyCursor();
2295 }
2296 }
2297 }
2298 }
2299
OnCmdExpHtml(wxCommandEvent & WXUNUSED (event))2300 void MyResultSetView::OnCmdExpHtml(wxCommandEvent & WXUNUSED(event))
2301 {
2302 //
2303 // exporting the ResultSet as HTML
2304 //
2305 int ret;
2306 wxString path;
2307 wxString lastDir;
2308 wxString target;
2309 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
2310 wxFileDialog fileDialog(this, wxT("Exporting the ResultSet as HTML"),
2311 wxT(""), wxT("result_set.html"),
2312 wxT
2313 ("HTML web page (*.html)|*.html|All files (*.*)|*.*"),
2314 wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
2315 wxDefaultSize, wxT("filedlg"));
2316 lastDir = MainFrame->GetLastDirectory();
2317 if (lastDir.Len() >= 1)
2318 fileDialog.SetDirectory(lastDir);
2319 ret = fileDialog.ShowModal();
2320 if (ret == wxID_OK)
2321 {
2322 wxFileName file(fileDialog.GetPath());
2323 path = file.GetPath();
2324 path += file.GetPathSeparator();
2325 path += file.GetName();
2326 path += wxT(".html");
2327 lastDir = file.GetPath();
2328 if (MainFrame->IsSetAskCharset() == false)
2329 {
2330 // using the default output charset
2331 MainFrame->SetLastDirectory(lastDir);
2332 ::wxBeginBusyCursor();
2333 MainFrame->ExportResultSetAsHtml(path, sql,
2334 MainFrame->GetSqlitePath(),
2335 MainFrame->GetDefaultCharset());
2336 ::wxEndBusyCursor();
2337 } else
2338 {
2339 // asking the charset to be used
2340 DumpTxtDialog dlg;
2341 target = wxT("HTML");
2342 dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
2343 ret = dlg.ShowModal();
2344 if (ret == wxID_OK)
2345 {
2346 MainFrame->SetLastDirectory(lastDir);
2347 ::wxBeginBusyCursor();
2348 MainFrame->ExportResultSetAsHtml(path, sql,
2349 MainFrame->GetSqlitePath(),
2350 dlg.GetCharset());
2351 ::wxEndBusyCursor();
2352 }
2353 }
2354 }
2355 }
2356
OnCmdExpShp(wxCommandEvent & WXUNUSED (event))2357 void MyResultSetView::OnCmdExpShp(wxCommandEvent & WXUNUSED(event))
2358 {
2359 //
2360 // exporting the ResultSet as Shapefile
2361 //
2362 int ret;
2363 wxString path;
2364 wxString lastDir;
2365 wxString target;
2366 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
2367 wxFileDialog fileDialog(this, wxT("Exporting the ResultSet as Shapefile"),
2368 wxT(""), wxT("shapefile.shp"),
2369 wxT
2370 ("Shapefile (*.shp)|*.shp|All files (*.*)|*.*"),
2371 wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
2372 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
2373 lastDir = MainFrame->GetLastDirectory();
2374 if (lastDir.Len() >= 1)
2375 fileDialog.SetDirectory(lastDir);
2376 ret = fileDialog.ShowModal();
2377 if (ret == wxID_OK)
2378 {
2379
2380 wxFileName file(fileDialog.GetPath());
2381 path = file.GetPath();
2382 path += file.GetPathSeparator();
2383 path += file.GetName();
2384 lastDir = file.GetPath();
2385 if (MainFrame->IsSetAskCharset() == false)
2386 {
2387 // using the default output charset
2388 MainFrame->SetLastDirectory(lastDir);
2389 ::wxBeginBusyCursor();
2390 MainFrame->ExportResultSetAsShp(path, sql,
2391 MainFrame->GetDefaultCharset());
2392 ::wxEndBusyCursor();
2393 } else
2394 {
2395 // asking the charset to be used
2396 DumpTxtDialog dlg;
2397 target = wxT("Shapefile");
2398 dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
2399 ret = dlg.ShowModal();
2400 if (ret == wxID_OK)
2401 {
2402 MainFrame->SetLastDirectory(lastDir);
2403 ::wxBeginBusyCursor();
2404 MainFrame->ExportResultSetAsShp(path, sql, dlg.GetCharset());
2405 ::wxEndBusyCursor();
2406 }
2407 }
2408 }
2409 }
2410
OnCmdExpDif(wxCommandEvent & WXUNUSED (event))2411 void MyResultSetView::OnCmdExpDif(wxCommandEvent & WXUNUSED(event))
2412 {
2413 //
2414 // exporting the ResultSet as DIF spreadsheet
2415 //
2416 int ret;
2417 wxString path;
2418 wxString lastDir;
2419 wxString target;
2420 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
2421 // asking Decimal Point / Date-Times params
2422 DumpSpreadsheetDialog sheet_dlg;
2423 char decimal_point;
2424 bool date_times;
2425 sheet_dlg.Create(MainFrame);
2426 ret = sheet_dlg.ShowModal();
2427 if (ret == wxID_OK)
2428 {
2429 decimal_point = sheet_dlg.GetDecimalPoint();
2430 date_times = sheet_dlg.IsDateTimes();
2431 } else
2432 return;
2433 wxFileDialog fileDialog(this,
2434 wxT("Exporting the ResultSet as DIF spreadsheet"),
2435 wxT(""), wxT("spreadsheet.dif"),
2436 wxT
2437 ("DIF spreadsheet document (*.dif)|*.dif|All files (*.*)|*.*"),
2438 wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
2439 wxDefaultSize, wxT("filedlg"));
2440 lastDir = MainFrame->GetLastDirectory();
2441 if (lastDir.Len() >= 1)
2442 fileDialog.SetDirectory(lastDir);
2443 ret = fileDialog.ShowModal();
2444 if (ret == wxID_OK)
2445 {
2446
2447 wxFileName file(fileDialog.GetPath());
2448 path = file.GetPath();
2449 path += file.GetPathSeparator();
2450 path += file.GetName();
2451 path += wxT(".dif");
2452 lastDir = file.GetPath();
2453 if (MainFrame->IsSetAskCharset() == false)
2454 {
2455 // using the default output charset
2456 MainFrame->SetLastDirectory(lastDir);
2457 ::wxBeginBusyCursor();
2458 MainFrame->ExportResultSetAsDif(path, sql,
2459 MainFrame->GetDefaultCharset(),
2460 decimal_point, date_times);
2461 ::wxEndBusyCursor();
2462 } else
2463 {
2464 // asking the charset to be used
2465 DumpTxtDialog dlg;
2466 target = wxT("DIF spreadsheet");
2467 dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
2468 ret = dlg.ShowModal();
2469 if (ret == wxID_OK)
2470 {
2471 MainFrame->SetLastDirectory(lastDir);
2472 ::wxBeginBusyCursor();
2473 MainFrame->ExportResultSetAsDif(path, sql, dlg.GetCharset(),
2474 decimal_point, date_times);
2475 ::wxEndBusyCursor();
2476 }
2477 }
2478 }
2479 }
2480
OnCmdExpSylk(wxCommandEvent & WXUNUSED (event))2481 void MyResultSetView::OnCmdExpSylk(wxCommandEvent & WXUNUSED(event))
2482 {
2483 //
2484 // exporting the ResultSet as SYLK spreadsheet
2485 //
2486 int ret;
2487 wxString path;
2488 wxString lastDir;
2489 wxString target;
2490 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
2491 // asking Decimal Point / Date-Times params
2492 DumpSpreadsheetDialog sheet_dlg;
2493 bool date_times;
2494 sheet_dlg.Create(MainFrame);
2495 ret = sheet_dlg.ShowModal();
2496 if (ret == wxID_OK)
2497 date_times = sheet_dlg.IsDateTimes();
2498 else
2499 return;
2500 wxFileDialog fileDialog(this,
2501 wxT("Exporting the ResultSet as SYLK spreadsheet"),
2502 wxT(""), wxT("spreadsheet.slk"),
2503 wxT
2504 ("SYLK spreadsheet document (*.slk)|*.slk|All files (*.*)|*.*"),
2505 wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition,
2506 wxDefaultSize, wxT("filedlg"));
2507 lastDir = MainFrame->GetLastDirectory();
2508 if (lastDir.Len() >= 1)
2509 fileDialog.SetDirectory(lastDir);
2510 ret = fileDialog.ShowModal();
2511 if (ret == wxID_OK)
2512 {
2513
2514 wxFileName file(fileDialog.GetPath());
2515 path = file.GetPath();
2516 path += file.GetPathSeparator();
2517 path += file.GetName();
2518 path += wxT(".slk");
2519 lastDir = file.GetPath();
2520 if (MainFrame->IsSetAskCharset() == false)
2521 {
2522 // using the default output charset
2523 MainFrame->SetLastDirectory(lastDir);
2524 ::wxBeginBusyCursor();
2525 MainFrame->ExportResultSetAsSylk(path, sql,
2526 MainFrame->GetDefaultCharset(),
2527 date_times);
2528 ::wxEndBusyCursor();
2529 } else
2530 {
2531 // asking the charset to be used
2532 DumpTxtDialog dlg;
2533 target = wxT("SYLK spreadsheet");
2534 dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
2535 ret = dlg.ShowModal();
2536 if (ret == wxID_OK)
2537 {
2538 MainFrame->SetLastDirectory(lastDir);
2539 ::wxBeginBusyCursor();
2540 MainFrame->ExportResultSetAsSylk(path, sql, dlg.GetCharset(),
2541 date_times);
2542 ::wxEndBusyCursor();
2543 }
2544 }
2545 }
2546 }
2547
OnCmdExpDbf(wxCommandEvent & WXUNUSED (event))2548 void MyResultSetView::OnCmdExpDbf(wxCommandEvent & WXUNUSED(event))
2549 {
2550 //
2551 // exporting the ResultSet as DBF archive
2552 //
2553 int ret;
2554 wxString path;
2555 wxString lastDir;
2556 wxString target;
2557 wxString sql = MainFrame->GetQueryView()->GetSqlCtrl()->GetValue();
2558 wxFileDialog fileDialog(this, wxT("Exporting the ResultSet as DBF archive"),
2559 wxT(""), wxT("archive.dbf"),
2560 wxT
2561 ("DBF archive (*.dbf)|*.dbf|All files (*.*)|*.*"),
2562 wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
2563 wxDefaultPosition, wxDefaultSize, wxT("filedlg"));
2564 lastDir = MainFrame->GetLastDirectory();
2565 if (lastDir.Len() >= 1)
2566 fileDialog.SetDirectory(lastDir);
2567 ret = fileDialog.ShowModal();
2568 if (ret == wxID_OK)
2569 {
2570
2571 wxFileName file(fileDialog.GetPath());
2572 path = file.GetPath();
2573 path += file.GetPathSeparator();
2574 path += file.GetName();
2575 path += wxT(".dbf");
2576 lastDir = file.GetPath();
2577 if (MainFrame->IsSetAskCharset() == false)
2578 {
2579 // using the default output charset
2580 MainFrame->SetLastDirectory(lastDir);
2581 ::wxBeginBusyCursor();
2582 MainFrame->ExportResultSetAsDbf(path, sql,
2583 MainFrame->GetDefaultCharset());
2584 ::wxEndBusyCursor();
2585 } else
2586 {
2587 // asking the charset to be used
2588 DumpTxtDialog dlg;
2589 target = wxT("DBF archive");
2590 dlg.Create(MainFrame, path, target, MainFrame->GetDefaultCharset());
2591 ret = dlg.ShowModal();
2592 if (ret == wxID_OK)
2593 {
2594 MainFrame->SetLastDirectory(lastDir);
2595 ::wxBeginBusyCursor();
2596 MainFrame->ExportResultSetAsDbf(path, sql, dlg.GetCharset());
2597 ::wxEndBusyCursor();
2598 }
2599 }
2600 }
2601 }
2602