1 /*
2 / BlobExplorer.cpp
3 / a dialog to explore a BLOB value
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/mstream.h"
29 #include "wx/clipbrd.h"
30 #include "wx/tokenzr.h"
31 #include "wx/spinctrl.h"
32 
33 #include "gaiagraphics.h"
34 
BlobExplorerDialog(MyFrame * parent,int blob_size,unsigned char * blob)35 BlobExplorerDialog::BlobExplorerDialog(MyFrame * parent, int blob_size,
36                                        unsigned char *blob)
37 {
38 //
39 // constructor; just calls Create()
40 //
41   Create(parent, blob_size, blob);
42 }
43 
Create(MyFrame * parent,int blob_size,unsigned char * blob)44 bool BlobExplorerDialog::Create(MyFrame * parent, int blob_size,
45                                 unsigned char *blob)
46 {
47 //
48 // creating the dialog
49 //
50   MainFrame = parent;
51   BlobSize = blob_size;
52   Blob = blob;
53   BlobType = gaiaGuessBlobType(Blob, BlobSize);
54   Geometry = NULL;
55   IsSVG = false;
56   XMLDocument = wxT("");
57   XMLIndented = wxT("");
58   Image = NULL;
59   SVGrelative = true;
60   SVGprecision = -1;
61   KMLprecision = -1;
62   GMLv2v3 = true;
63   GMLprecision = -1;
64   GeoJSONoptions = 0;
65   GeoJSONprecision = -1;
66   const void *img = NULL;
67   unsigned char *rgbaArray = NULL;
68   int width;
69   int height;
70   bool isRasterLiteRaw = false;
71 
72   if (BlobType == GAIA_GEOMETRY_BLOB)
73     Geometry = gaiaFromSpatiaLiteBlobWkb(Blob, BlobSize);
74   else if (BlobType == GAIA_XML_BLOB)
75     {
76 #ifdef ENABLE_LIBXML2           /* only if LIBXML2 is enabled */
77 
78       char *xml = gaiaXmlTextFromBlob(Blob, BlobSize, -1);
79       if (xml != NULL)
80         {
81           XMLDocument = wxString::FromUTF8(xml);
82           free(xml);
83         }
84       xml = gaiaXmlTextFromBlob(Blob, BlobSize, 4);
85       if (xml != NULL)
86         {
87           XMLIndented = wxString::FromUTF8(xml);
88           free(xml);
89         }
90       if (gaiaIsSvgXmlBlob(Blob, BlobSize))
91         {
92           /* handling the SVG preview */
93           char *svg = gaiaXmlTextFromBlob(Blob, BlobSize, 0);
94           int svg_sz = strlen(svg);
95           IsSVG = true;
96           SvgSize = svg_sz;
97           void *svg_handle;
98           img = NULL;
99           if (gGraphCreateSVG((const unsigned char *) svg, svg_sz, &svg_handle)
100               == GGRAPH_OK)
101 
102             {
103               gGraphGetSVGDims(svg_handle, &SvgWidth, &SvgHeight);
104               double w = SvgWidth;
105               double h = SvgHeight;
106               while (w > 560.0 || h > 300.0)
107                 {
108                   /* rescaling */
109                   w *= 0.9;
110                   h *= 0.9;
111                 }
112               double sz = w;
113               if (h > sz)
114                 sz = h;
115               if (gGraphImageFromSVG(svg_handle, sz, &img) != GGRAPH_OK)
116                 img = NULL;
117               gGraphFreeSVG(svg_handle);
118             }
119           free(svg);
120         }
121 #endif /* end LIBXML2 conditionals */
122   } else
123     {
124       switch (BlobType)
125         {
126           case GAIA_JPEG_BLOB:
127           case GAIA_EXIF_BLOB:
128           case GAIA_EXIF_GPS_BLOB:
129             if (gGraphImageFromMemBuf
130                 (Blob, BlobSize, GGRAPH_IMAGE_JPEG, &img, 1) != GGRAPH_OK)
131               img = NULL;
132             break;
133           case GAIA_PNG_BLOB:
134             if (gGraphImageFromMemBuf(Blob, BlobSize, GGRAPH_IMAGE_PNG, &img, 1)
135                 != GGRAPH_OK)
136               img = NULL;
137             break;
138           case GAIA_GIF_BLOB:
139             if (gGraphImageFromMemBuf(Blob, BlobSize, GGRAPH_IMAGE_GIF, &img, 1)
140                 != GGRAPH_OK)
141               img = NULL;
142             break;
143           case GAIA_TIFF_BLOB:
144             if (gGraphImageFromMemBuf
145                 (Blob, BlobSize, GGRAPH_IMAGE_TIFF, &img, 1) != GGRAPH_OK)
146               img = NULL;
147             break;
148           default:
149             if (gGraphIsRawImage(Blob, BlobSize) == GGRAPH_OK)
150               {
151                 /* this one is a RasterLite RAW image */
152                 if (gGraphImageFromRawMemBuf(Blob, BlobSize, &img) != GGRAPH_OK)
153                   img = NULL;
154                 else
155                   isRasterLiteRaw = true;
156               }
157             break;
158         };
159     }
160   if (img)
161     {
162       if (gGraphGetImageDims(img, &width, &height) == GGRAPH_OK)
163         {
164           if (gGraphImageBufferReferenceRGBA(img, &rgbaArray) != GGRAPH_OK)
165             rgbaArray = NULL;
166         }
167     }
168   if (rgbaArray)
169     {
170       // creating the Image from RGB array
171       int x;
172       int y;
173       Image = new wxImage(width, height);
174       unsigned char *p = rgbaArray;
175       Image->SetAlpha();
176       for (y = 0; y < height; y++)
177         {
178           for (x = 0; x < width; x++)
179             {
180               unsigned char r = *p++;
181               unsigned char g = *p++;
182               unsigned char b = *p++;
183               unsigned char alpha = *p++;
184               Image->SetRGB(x, y, r, g, b);
185               Image->SetAlpha(x, y, alpha);
186             }
187         }
188       free(rgbaArray);
189   } else
190     {
191       // creating a default BLACK Image
192       int x;
193       int y;
194       Image = new wxImage(128, 128);
195       for (y = 0; y < 128; y++)
196         {
197           for (x = 0; x < 128; x++)
198             Image->SetRGB(x, y, 0, 0, 0);
199         }
200     }
201   if (img)
202     gGraphDestroyImage(img);
203 
204   if (wxPropertySheetDialog::Create(parent, wxID_ANY, wxT("BLOB explorer")) ==
205       false)
206     return false;
207   wxBookCtrlBase *book = GetBookCtrl();
208 // creates individual panels
209   wxPanel *hexadecimal = CreateHexadecimalPage(book);
210   book->AddPage(hexadecimal, wxT("Hexadecimal dump"), true);
211   if (BlobType == GAIA_GEOMETRY_BLOB)
212     {
213       wxPanel *geometry = CreateGeometryPage(book);
214       book->AddPage(geometry, wxT("Geometry explorer"), false);
215       wxPanel *wkt = CreateWKTPage(book);
216       book->AddPage(wkt, wxT("WKT"), false);
217       wxPanel *ewkt = CreateEWKTPage(book);
218       book->AddPage(ewkt, wxT("EWKT"), false);
219       wxPanel *svg = CreateSVGPage(book);
220       book->AddPage(svg, wxT("SVG"), false);
221       wxPanel *kml = CreateKMLPage(book);
222       book->AddPage(kml, wxT("KML"), false);
223       wxPanel *gml = CreateGMLPage(book);
224       book->AddPage(gml, wxT("GML"), false);
225       wxPanel *geoJson = CreateGeoJSONPage(book);
226       book->AddPage(geoJson, wxT("GeoJSON"), false);
227     }
228 
229   if (BlobType == GAIA_XML_BLOB)
230     {
231       wxPanel *xml_document = CreateXmlDocumentPage(book);
232       book->AddPage(xml_document, wxT("XML Document"), false);
233       wxPanel *xml_indented = CreateXmlIndentedPage(book);
234       book->AddPage(xml_indented, wxT("XML (indented)"), false);
235     }
236 
237   if (BlobType == GAIA_JPEG_BLOB || BlobType == GAIA_EXIF_BLOB
238       || BlobType == GAIA_EXIF_GPS_BLOB || BlobType == GAIA_PNG_BLOB
239       || BlobType == GAIA_GIF_BLOB || BlobType == GAIA_TIFF_BLOB
240       || isRasterLiteRaw == true || IsSVG == true)
241     {
242       wxPanel *image = CreateImagePage(book);
243       book->AddPage(image, wxT("Image"), false);
244     }
245   CreateButtons(wxOK);
246   LayoutDialog();
247 // appends event handler for TAB/PAGE changing
248   Connect(wxID_ANY, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
249           (wxObjectEventFunction) & BlobExplorerDialog::OnPageChanged);
250 // appends event handler for OK button
251   Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,
252           (wxObjectEventFunction) & BlobExplorerDialog::OnOk);
253 // centers the dialog window
254   Centre();
255   UpdateHexadecimalPage();
256   return true;
257 }
258 
CreateHexadecimalPage(wxWindow * parent)259 wxPanel *BlobExplorerDialog::CreateHexadecimalPage(wxWindow * parent)
260 {
261 //
262 // creating the HEXADECIMAL page
263 //
264   wxPanel *panel = new wxPanel(parent, ID_PANE_HEXADECIMAL);
265   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
266   panel->SetSizer(topSizer);
267   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
268   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
269 // creating a control to show the hexadecimal dump
270   wxBoxSizer *hexSizer = new wxBoxSizer(wxHORIZONTAL);
271   boxSizer->Add(hexSizer, 0, wxALIGN_LEFT | wxALL, 0);
272   MyHexList *hexCtrl = new MyHexList(this, Blob, BlobSize, panel,
273                                      ID_HEX, wxDefaultPosition,
274                                      wxSize(620, 320),
275                                      wxLC_REPORT | wxLC_VIRTUAL);
276   wxFont font(9, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
277   hexCtrl->SetFont(font);
278   wxListItem column0;
279   hexCtrl->InsertColumn(0, wxT("Address"));
280   hexCtrl->SetColumnWidth(0, 90);
281   hexCtrl->InsertColumn(1, wxT("Hexadecimal"));
282   hexCtrl->SetColumnWidth(1, 370);
283   hexCtrl->InsertColumn(2, wxT("ASCII"));
284   hexCtrl->SetColumnWidth(2, 130);
285   hexSizer->Add(hexCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
286   panel->SetSizer(topSizer);
287   topSizer->Fit(panel);
288   return panel;
289 }
290 
CreateGeometryPage(wxWindow * parent)291 wxPanel *BlobExplorerDialog::CreateGeometryPage(wxWindow * parent)
292 {
293 //
294 // creating the GEOMETRY page
295 //
296   wxPanel *panel = new wxPanel(parent, ID_PANE_HEXADECIMAL);
297   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
298   panel->SetSizer(topSizer);
299   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
300   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
301 // creating a control to show the geometry as a text table
302   wxBoxSizer *geomSizer = new wxBoxSizer(wxHORIZONTAL);
303   boxSizer->Add(geomSizer, 0, wxALIGN_LEFT | wxALL, 0);
304   wxTextCtrl *geomCtrl = new wxTextCtrl(panel, ID_GEOM_TABLE, wxT(""),
305                                         wxDefaultPosition, wxSize(270,
306                                                                   320),
307                                         wxTE_MULTILINE | wxTE_RICH |
308                                         wxTE_READONLY | wxHSCROLL);
309   geomSizer->Add(geomCtrl, 0, wxALIGN_LEFT | wxALL, 5);
310 // creating a control to show the geometry in a graphical fashion
311   wxStaticBox *exBox = new wxStaticBox(panel, wxID_STATIC,
312                                        wxT("Geometry preview"),
313                                        wxDefaultPosition, wxDefaultSize);
314   wxBoxSizer *exampleSizer = new wxStaticBoxSizer(exBox, wxHORIZONTAL);
315   geomSizer->Add(exampleSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
316   DrawGeometry(300, 300);
317   GraphicsGeometry *geomGraph = new GraphicsGeometry(this, panel, ID_GEOM_GRAPH,
318                                                      GeomPreview, wxSize(300,
319                                                                          300));
320   exampleSizer->Add(geomGraph, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
321   panel->SetSizer(topSizer);
322   topSizer->Fit(panel);
323   return panel;
324 }
325 
CreateWKTPage(wxWindow * parent)326 wxPanel *BlobExplorerDialog::CreateWKTPage(wxWindow * parent)
327 {
328 //
329 // creating the WKT page
330 //
331   wxPanel *panel = new wxPanel(parent, ID_PANE_WKT);
332   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
333   panel->SetSizer(topSizer);
334   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
335   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
336 // creating a control to show the WKT notation
337   wxBoxSizer *wktSizer = new wxBoxSizer(wxHORIZONTAL);
338   boxSizer->Add(wktSizer, 0, wxALIGN_LEFT | wxALL, 0);
339   wxTextCtrl *wktCtrl = new wxTextCtrl(panel, ID_WKT_TABLE, wxT(""),
340                                        wxDefaultPosition, wxSize(600,
341                                                                  300),
342                                        wxTE_MULTILINE | wxTE_READONLY |
343                                        wxTE_RICH | wxVSCROLL);
344   wxFont font =
345     wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
346   wktCtrl->SetFont(font);
347   wktSizer->Add(wktCtrl, 0, wxALIGN_LEFT | wxALL, 5);
348   wxBoxSizer *btnSizer = new wxBoxSizer(wxHORIZONTAL);
349   boxSizer->Add(btnSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
350   wxButton *btnCopy = new wxButton(panel, ID_WKT_COPY, wxT("&Copy"));
351   btnSizer->Add(btnCopy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
352   panel->SetSizer(topSizer);
353   topSizer->Fit(panel);
354 // appends event handlers
355   Connect(ID_WKT_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
356           (wxObjectEventFunction) & BlobExplorerDialog::OnCopyWKT);
357   return panel;
358 }
359 
OnCopyWKT(wxCommandEvent & WXUNUSED (event))360 void BlobExplorerDialog::OnCopyWKT(wxCommandEvent & WXUNUSED(event))
361 {
362 //
363 // Copying WKT to the Clipboard
364 //
365   if (wxTheClipboard->Open())
366     {
367       wxTheClipboard->SetData(new wxTextDataObject(WKTstring));
368       wxTheClipboard->Close();
369     }
370 }
371 
CreateEWKTPage(wxWindow * parent)372 wxPanel *BlobExplorerDialog::CreateEWKTPage(wxWindow * parent)
373 {
374 //
375 // creating the EWKT page
376 //
377   wxPanel *panel = new wxPanel(parent, ID_PANE_EWKT);
378   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
379   panel->SetSizer(topSizer);
380   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
381   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
382 // creating a control to show the EWKT notation
383   wxBoxSizer *ewktSizer = new wxBoxSizer(wxHORIZONTAL);
384   boxSizer->Add(ewktSizer, 0, wxALIGN_LEFT | wxALL, 0);
385   wxTextCtrl *ewktCtrl = new wxTextCtrl(panel, ID_EWKT_TABLE, wxT(""),
386                                         wxDefaultPosition, wxSize(600,
387                                                                   300),
388                                         wxTE_MULTILINE | wxTE_READONLY |
389                                         wxTE_RICH | wxVSCROLL);
390   wxFont font =
391     wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
392   ewktCtrl->SetFont(font);
393   ewktSizer->Add(ewktCtrl, 0, wxALIGN_LEFT | wxALL, 5);
394   wxBoxSizer *btnSizer = new wxBoxSizer(wxHORIZONTAL);
395   boxSizer->Add(btnSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
396   wxButton *btnCopy = new wxButton(panel, ID_EWKT_COPY, wxT("&Copy"));
397   btnSizer->Add(btnCopy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
398   panel->SetSizer(topSizer);
399   topSizer->Fit(panel);
400 // appends event handlers
401   Connect(ID_EWKT_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
402           (wxObjectEventFunction) & BlobExplorerDialog::OnCopyEWKT);
403   return panel;
404 }
405 
OnCopyEWKT(wxCommandEvent & WXUNUSED (event))406 void BlobExplorerDialog::OnCopyEWKT(wxCommandEvent & WXUNUSED(event))
407 {
408 //
409 // Copying EWKT to the Clipboard
410 //
411 
412   if (wxTheClipboard->Open())
413     {
414       wxTheClipboard->SetData(new wxTextDataObject(EWKTstring));
415       wxTheClipboard->Close();
416     }
417 }
418 
CreateSVGPage(wxWindow * parent)419 wxPanel *BlobExplorerDialog::CreateSVGPage(wxWindow * parent)
420 {
421 //
422 // creating the SVG page
423 //
424   wxPanel *panel = new wxPanel(parent, ID_PANE_SVG);
425   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
426   panel->SetSizer(topSizer);
427   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
428   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
429 // creating a control to show the SVG notation
430   wxBoxSizer *svgSizer = new wxBoxSizer(wxHORIZONTAL);
431   boxSizer->Add(svgSizer, 0, wxALIGN_LEFT | wxALL, 0);
432   wxTextCtrl *svgCtrl = new wxTextCtrl(panel, ID_SVG_TABLE, wxT(""),
433                                        wxDefaultPosition, wxSize(600,
434                                                                  270),
435                                        wxTE_MULTILINE | wxTE_READONLY |
436                                        wxTE_RICH | wxVSCROLL);
437   wxFont font =
438     wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
439   svgCtrl->SetFont(font);
440   svgSizer->Add(svgCtrl, 0, wxALIGN_LEFT | wxALL, 5);
441   wxBoxSizer *btnSizer = new wxBoxSizer(wxHORIZONTAL);
442   boxSizer->Add(btnSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
443   wxStaticBox *optBox = new wxStaticBox(panel, wxID_STATIC,
444                                         wxT("SVG options"),
445                                         wxDefaultPosition, wxDefaultSize);
446   wxBoxSizer *optSizer = new wxStaticBoxSizer(optBox, wxHORIZONTAL);
447   btnSizer->Add(optSizer, 0, wxALIGN_LEFT | wxALL, 0);
448   wxBoxSizer *absRelSizer = new wxBoxSizer(wxHORIZONTAL);
449   optSizer->Add(absRelSizer, 0, wxALIGN_LEFT | wxALL, 0);
450   wxString absrel[2];
451   absrel[0] = wxT("&Relative");
452   absrel[1] = wxT("&Absolute");
453   wxRadioBox *absRelBox = new wxRadioBox(panel, ID_SVG_RELATIVE,
454                                          wxT("&Coord Mode"),
455                                          wxDefaultPosition,
456                                          wxDefaultSize, 2,
457                                          absrel, 2,
458                                          wxRA_SPECIFY_COLS);
459   absRelSizer->Add(absRelBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
460   wxStaticText *precisionLabel =
461     new wxStaticText(panel, wxID_STATIC, wxT("&Precision:"));
462   optSizer->Add(precisionLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
463   wxSpinCtrl *precisionCtrl =
464     new wxSpinCtrl(panel, ID_SVG_PRECISION, wxEmptyString,
465                    wxDefaultPosition, wxSize(50, 20),
466                    wxSP_ARROW_KEYS,
467                    -1, 15, -1);
468   optSizer->Add(precisionCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
469   wxButton *btnCopy = new wxButton(panel, ID_SVG_COPY, wxT("&Copy"));
470   btnSizer->Add(btnCopy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
471   panel->SetSizer(topSizer);
472   topSizer->Fit(panel);
473 // appends event handlers
474   Connect(ID_SVG_RELATIVE, wxEVT_COMMAND_RADIOBOX_SELECTED,
475           (wxObjectEventFunction) & BlobExplorerDialog::OnSVGRelative);
476   Connect(ID_SVG_PRECISION, wxEVT_COMMAND_SPINCTRL_UPDATED,
477           (wxObjectEventFunction) & BlobExplorerDialog::OnSVGPrecision);
478   Connect(ID_SVG_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
479           (wxObjectEventFunction) & BlobExplorerDialog::OnCopySVG);
480   return panel;
481 }
482 
OnSVGRelative(wxCommandEvent & WXUNUSED (event))483 void BlobExplorerDialog::OnSVGRelative(wxCommandEvent & WXUNUSED(event))
484 {
485 //
486 // SVG Relative/Absolute selection changed
487 //
488   wxRadioBox *absRelCtrl = (wxRadioBox *) FindWindow(ID_SVG_RELATIVE);
489   switch (absRelCtrl->GetSelection())
490     {
491       case 0:
492         SVGrelative = true;
493         break;
494       case 1:
495         SVGrelative = false;
496         break;
497     };
498   SVGstring = wxT("");
499   wxTextCtrl *svgCtrl = (wxTextCtrl *) FindWindow(ID_SVG_TABLE);
500   svgCtrl->SetValue(wxT(""));
501   UpdateSVGPage();
502 }
503 
OnSVGPrecision(wxCommandEvent & WXUNUSED (event))504 void BlobExplorerDialog::OnSVGPrecision(wxCommandEvent & WXUNUSED(event))
505 {
506 //
507 // SVG Precision selection changed
508 //
509   wxSpinCtrl *precisionCtrl = (wxSpinCtrl *) FindWindow(ID_SVG_PRECISION);
510   SVGprecision = precisionCtrl->GetValue();
511   SVGstring = wxT("");
512   wxTextCtrl *svgCtrl = (wxTextCtrl *) FindWindow(ID_SVG_TABLE);
513   svgCtrl->SetValue(wxT(""));
514   UpdateSVGPage();
515 }
516 
OnCopySVG(wxCommandEvent & WXUNUSED (event))517 void BlobExplorerDialog::OnCopySVG(wxCommandEvent & WXUNUSED(event))
518 {
519 //
520 // Copying SVG to the Clipboard
521 //
522 
523   if (wxTheClipboard->Open())
524     {
525       wxTheClipboard->SetData(new wxTextDataObject(SVGstring));
526       wxTheClipboard->Close();
527     }
528 }
529 
CreateKMLPage(wxWindow * parent)530 wxPanel *BlobExplorerDialog::CreateKMLPage(wxWindow * parent)
531 {
532 //
533 // creating the KML page
534 //
535   wxPanel *panel = new wxPanel(parent, ID_PANE_KML);
536   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
537   panel->SetSizer(topSizer);
538   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
539   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
540 // creating a control to show the KML notation
541   wxBoxSizer *kmlSizer = new wxBoxSizer(wxHORIZONTAL);
542   boxSizer->Add(kmlSizer, 0, wxALIGN_LEFT | wxALL, 0);
543   wxTextCtrl *kmlCtrl = new wxTextCtrl(panel, ID_KML_TABLE, wxT(""),
544                                        wxDefaultPosition, wxSize(600,
545                                                                  280),
546                                        wxTE_MULTILINE | wxTE_READONLY |
547                                        wxTE_RICH | wxVSCROLL);
548   wxFont font =
549     wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
550   kmlCtrl->SetFont(font);
551   kmlSizer->Add(kmlCtrl, 0, wxALIGN_LEFT | wxALL, 5);
552   wxBoxSizer *btnSizer = new wxBoxSizer(wxHORIZONTAL);
553   boxSizer->Add(btnSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
554   wxStaticBox *optBox = new wxStaticBox(panel, wxID_STATIC,
555                                         wxT("KML options"),
556                                         wxDefaultPosition, wxDefaultSize);
557   wxBoxSizer *optSizer = new wxStaticBoxSizer(optBox, wxHORIZONTAL);
558   btnSizer->Add(optSizer, 0, wxALIGN_LEFT | wxALL, 0);
559   wxStaticText *precisionLabel =
560     new wxStaticText(panel, wxID_STATIC, wxT("&Precision:"));
561   optSizer->Add(precisionLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
562   wxSpinCtrl *precisionCtrl =
563     new wxSpinCtrl(panel, ID_KML_PRECISION, wxEmptyString,
564                    wxDefaultPosition, wxSize(50, 20),
565                    wxSP_ARROW_KEYS,
566                    -1, 18, -1);
567   optSizer->Add(precisionCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
568   wxButton *btnCopy = new wxButton(panel, ID_KML_COPY, wxT("&Copy"));
569   btnSizer->Add(btnCopy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
570   panel->SetSizer(topSizer);
571   topSizer->Fit(panel);
572 // appends event handlers
573   Connect(ID_KML_PRECISION, wxEVT_COMMAND_SPINCTRL_UPDATED,
574           (wxObjectEventFunction) & BlobExplorerDialog::OnKMLPrecision);
575   Connect(ID_KML_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
576           (wxObjectEventFunction) & BlobExplorerDialog::OnCopyKML);
577   return panel;
578 }
579 
OnKMLPrecision(wxCommandEvent & WXUNUSED (event))580 void BlobExplorerDialog::OnKMLPrecision(wxCommandEvent & WXUNUSED(event))
581 {
582 //
583 // KML Precision selection changed
584 //
585   wxSpinCtrl *precisionCtrl = (wxSpinCtrl *) FindWindow(ID_KML_PRECISION);
586   KMLprecision = precisionCtrl->GetValue();
587   KMLstring = wxT("");
588   wxTextCtrl *kmlCtrl = (wxTextCtrl *) FindWindow(ID_KML_TABLE);
589   kmlCtrl->SetValue(wxT(""));
590   UpdateKMLPage();
591 }
592 
OnCopyKML(wxCommandEvent & WXUNUSED (event))593 void BlobExplorerDialog::OnCopyKML(wxCommandEvent & WXUNUSED(event))
594 {
595 //
596 // Copying KML to the Clipboard
597 //
598 
599   if (wxTheClipboard->Open())
600     {
601       wxTheClipboard->SetData(new wxTextDataObject(KMLstring));
602       wxTheClipboard->Close();
603     }
604 }
605 
CreateGMLPage(wxWindow * parent)606 wxPanel *BlobExplorerDialog::CreateGMLPage(wxWindow * parent)
607 {
608 //
609 // creating the GML page
610 //
611   wxPanel *panel = new wxPanel(parent, ID_PANE_GML);
612   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
613   panel->SetSizer(topSizer);
614   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
615   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
616 // creating a control to show the GML notation
617   wxBoxSizer *gmlSizer = new wxBoxSizer(wxHORIZONTAL);
618   boxSizer->Add(gmlSizer, 0, wxALIGN_LEFT | wxALL, 0);
619   wxTextCtrl *gmlCtrl = new wxTextCtrl(panel, ID_GML_TABLE, wxT(""),
620                                        wxDefaultPosition, wxSize(600,
621                                                                  270),
622                                        wxTE_MULTILINE | wxTE_READONLY |
623                                        wxTE_RICH | wxVSCROLL);
624   wxFont font =
625     wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
626   gmlCtrl->SetFont(font);
627   gmlSizer->Add(gmlCtrl, 0, wxALIGN_LEFT | wxALL, 5);
628   wxBoxSizer *btnSizer = new wxBoxSizer(wxHORIZONTAL);
629   boxSizer->Add(btnSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
630   wxStaticBox *optBox = new wxStaticBox(panel, wxID_STATIC,
631                                         wxT("GML options"),
632                                         wxDefaultPosition, wxDefaultSize);
633   wxBoxSizer *optSizer = new wxStaticBoxSizer(optBox, wxHORIZONTAL);
634   btnSizer->Add(optSizer, 0, wxALIGN_LEFT | wxALL, 0);
635   wxBoxSizer *versionSizer = new wxBoxSizer(wxHORIZONTAL);
636   optSizer->Add(versionSizer, 0, wxALIGN_LEFT | wxALL, 0);
637   wxString version[2];
638   version[0] = wxT("&GML v2");
639   version[1] = wxT("&GML v3");
640   wxRadioBox *versionBox = new wxRadioBox(panel, ID_GML_V2_V3,
641                                           wxT("&GML version"),
642                                           wxDefaultPosition,
643                                           wxDefaultSize, 2,
644                                           version, 2,
645                                           wxRA_SPECIFY_COLS);
646   versionSizer->Add(versionBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
647   wxStaticText *precisionLabel =
648     new wxStaticText(panel, wxID_STATIC, wxT("&Precision:"));
649   optSizer->Add(precisionLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
650   wxSpinCtrl *precisionCtrl =
651     new wxSpinCtrl(panel, ID_GML_PRECISION, wxEmptyString,
652                    wxDefaultPosition, wxSize(50, 20),
653                    wxSP_ARROW_KEYS,
654                    -1, 18, -1);
655   optSizer->Add(precisionCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
656   wxButton *btnCopy = new wxButton(panel, ID_GML_COPY, wxT("&Copy"));
657   btnSizer->Add(btnCopy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
658   panel->SetSizer(topSizer);
659   topSizer->Fit(panel);
660 // appends event handlers
661   Connect(ID_GML_V2_V3, wxEVT_COMMAND_RADIOBOX_SELECTED,
662           (wxObjectEventFunction) & BlobExplorerDialog::OnGMLv2v3);
663   Connect(ID_GML_PRECISION, wxEVT_COMMAND_SPINCTRL_UPDATED,
664           (wxObjectEventFunction) & BlobExplorerDialog::OnGMLPrecision);
665   Connect(ID_GML_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
666           (wxObjectEventFunction) & BlobExplorerDialog::OnCopyGML);
667   return panel;
668 }
669 
OnGMLv2v3(wxCommandEvent & WXUNUSED (event))670 void BlobExplorerDialog::OnGMLv2v3(wxCommandEvent & WXUNUSED(event))
671 {
672 //
673 // GML Version selection changed
674 //
675   wxRadioBox *versionCtrl = (wxRadioBox *) FindWindow(ID_GML_V2_V3);
676   switch (versionCtrl->GetSelection())
677     {
678       case 0:
679         GMLv2v3 = true;
680         break;
681       case 1:
682         GMLv2v3 = false;
683         break;
684     };
685   GMLstring = wxT("");
686   wxTextCtrl *gmlCtrl = (wxTextCtrl *) FindWindow(ID_GML_TABLE);
687   gmlCtrl->SetValue(wxT(""));
688   UpdateGMLPage();
689 }
690 
OnGMLPrecision(wxCommandEvent & WXUNUSED (event))691 void BlobExplorerDialog::OnGMLPrecision(wxCommandEvent & WXUNUSED(event))
692 {
693 //
694 // GML Precision selection changed
695 //
696   wxSpinCtrl *precisionCtrl = (wxSpinCtrl *) FindWindow(ID_GML_PRECISION);
697   GMLprecision = precisionCtrl->GetValue();
698   GMLstring = wxT("");
699   wxTextCtrl *gmlCtrl = (wxTextCtrl *) FindWindow(ID_GML_TABLE);
700   gmlCtrl->SetValue(wxT(""));
701   UpdateGMLPage();
702 }
703 
OnCopyGML(wxCommandEvent & WXUNUSED (event))704 void BlobExplorerDialog::OnCopyGML(wxCommandEvent & WXUNUSED(event))
705 {
706 //
707 // Copying GML to the Clipboard
708 //
709 
710   if (wxTheClipboard->Open())
711     {
712       wxTheClipboard->SetData(new wxTextDataObject(GMLstring));
713       wxTheClipboard->Close();
714     }
715 }
716 
CreateGeoJSONPage(wxWindow * parent)717 wxPanel *BlobExplorerDialog::CreateGeoJSONPage(wxWindow * parent)
718 {
719 //
720 // creating the GeoJSON page
721 //
722   wxPanel *panel = new wxPanel(parent, ID_PANE_SVG);
723   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
724   panel->SetSizer(topSizer);
725   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
726   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
727 // creating a control to show the GeoJSON notation
728   wxBoxSizer *geoJsonSizer = new wxBoxSizer(wxHORIZONTAL);
729   boxSizer->Add(geoJsonSizer, 0, wxALIGN_LEFT | wxALL, 0);
730   wxTextCtrl *geoJsonCtrl = new wxTextCtrl(panel, ID_GEOJSON_TABLE, wxT(""),
731                                            wxDefaultPosition, wxSize(600,
732                                                                      270),
733                                            wxTE_MULTILINE | wxTE_READONLY |
734                                            wxTE_RICH | wxVSCROLL);
735   wxFont font =
736     wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
737   geoJsonCtrl->SetFont(font);
738   geoJsonSizer->Add(geoJsonCtrl, 0, wxALIGN_LEFT | wxALL, 5);
739   wxBoxSizer *btnSizer = new wxBoxSizer(wxHORIZONTAL);
740   boxSizer->Add(btnSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
741   wxStaticBox *optBox = new wxStaticBox(panel, wxID_STATIC,
742                                         wxT("GeoJSON options"),
743                                         wxDefaultPosition, wxDefaultSize);
744   wxBoxSizer *optSizer = new wxStaticBoxSizer(optBox, wxHORIZONTAL);
745   btnSizer->Add(optSizer, 0, wxALIGN_LEFT | wxALL, 0);
746   wxBoxSizer *optionsSizer = new wxBoxSizer(wxHORIZONTAL);
747   optSizer->Add(optionsSizer, 0, wxALIGN_LEFT | wxALL, 0);
748   wxString options[6];
749   options[0] = wxT("&none");
750   options[1] = wxT("&BBOX");
751   options[2] = wxT("&shortCRS");
752   options[3] = wxT("&shortCRS + BBOX");
753   options[4] = wxT("&longCRS");
754   options[5] = wxT("&longCRS + BBOX");
755   wxRadioBox *optionsBox = new wxRadioBox(panel, ID_GEOJSON_OPTIONS,
756                                           wxT("&BBOX - CRS options"),
757                                           wxDefaultPosition,
758                                           wxDefaultSize, 6,
759                                           options, 2,
760                                           wxRA_SPECIFY_ROWS);
761   optionsSizer->Add(optionsBox, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
762   wxStaticText *precisionLabel =
763     new wxStaticText(panel, wxID_STATIC, wxT("&Precision:"));
764   optSizer->Add(precisionLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
765   wxSpinCtrl *precisionCtrl =
766     new wxSpinCtrl(panel, ID_GEOJSON_PRECISION, wxEmptyString,
767                    wxDefaultPosition, wxSize(50, 20),
768                    wxSP_ARROW_KEYS,
769                    -1, 18, -1);
770   optSizer->Add(precisionCtrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
771   wxButton *btnCopy = new wxButton(panel, ID_GEOJSON_COPY, wxT("&Copy"));
772   btnSizer->Add(btnCopy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
773   panel->SetSizer(topSizer);
774   topSizer->Fit(panel);
775 // appends event handlers
776   Connect(ID_GEOJSON_OPTIONS, wxEVT_COMMAND_RADIOBOX_SELECTED,
777           (wxObjectEventFunction) & BlobExplorerDialog::OnGeoJSONOptions);
778   Connect(ID_GEOJSON_PRECISION, wxEVT_COMMAND_SPINCTRL_UPDATED,
779           (wxObjectEventFunction) & BlobExplorerDialog::OnGeoJSONPrecision);
780   Connect(ID_GEOJSON_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
781           (wxObjectEventFunction) & BlobExplorerDialog::OnCopyGeoJSON);
782   return panel;
783 }
784 
OnGeoJSONOptions(wxCommandEvent & WXUNUSED (event))785 void BlobExplorerDialog::OnGeoJSONOptions(wxCommandEvent & WXUNUSED(event))
786 {
787 //
788 // GeoJSON Options selection changed
789 //
790   wxRadioBox *optionsCtrl = (wxRadioBox *) FindWindow(ID_GEOJSON_OPTIONS);
791   GeoJSONoptions = optionsCtrl->GetSelection();
792   GMLstring = wxT("");
793   wxTextCtrl *gmlCtrl = (wxTextCtrl *) FindWindow(ID_GEOJSON_TABLE);
794   gmlCtrl->SetValue(wxT(""));
795   UpdateGeoJSONPage();
796 }
797 
OnGeoJSONPrecision(wxCommandEvent & WXUNUSED (event))798 void BlobExplorerDialog::OnGeoJSONPrecision(wxCommandEvent & WXUNUSED(event))
799 {
800 //
801 // GeoJSON Precision selection changed
802 //
803   wxSpinCtrl *precisionCtrl = (wxSpinCtrl *) FindWindow(ID_GEOJSON_PRECISION);
804   GeoJSONprecision = precisionCtrl->GetValue();
805   GeoJSONstring = wxT("");
806   wxTextCtrl *geoJsonCtrl = (wxTextCtrl *) FindWindow(ID_GEOJSON_TABLE);
807   geoJsonCtrl->SetValue(wxT(""));
808   UpdateGeoJSONPage();
809 }
810 
OnCopyGeoJSON(wxCommandEvent & WXUNUSED (event))811 void BlobExplorerDialog::OnCopyGeoJSON(wxCommandEvent & WXUNUSED(event))
812 {
813 //
814 // Copying GeoJSON to the Clipboard
815 //
816 
817   if (wxTheClipboard->Open())
818     {
819       wxTheClipboard->SetData(new wxTextDataObject(GeoJSONstring));
820       wxTheClipboard->Close();
821     }
822 }
823 
CreateXmlDocumentPage(wxWindow * parent)824 wxPanel *BlobExplorerDialog::CreateXmlDocumentPage(wxWindow * parent)
825 {
826 //
827 // creating the XMLDocument page
828 //
829   wxPanel *panel = new wxPanel(parent, ID_PANE_WKT);
830   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
831   panel->SetSizer(topSizer);
832   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
833   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
834 // creating a control to show the WKT notation
835   wxBoxSizer *wktSizer = new wxBoxSizer(wxHORIZONTAL);
836   boxSizer->Add(wktSizer, 0, wxALIGN_LEFT | wxALL, 0);
837   wxTextCtrl *wktCtrl = new wxTextCtrl(panel, ID_XML_DOCUMENT_TABLE, wxT(""),
838                                        wxDefaultPosition, wxSize(600,
839                                                                  300),
840                                        wxTE_MULTILINE | wxTE_READONLY |
841                                        wxTE_RICH | wxVSCROLL);
842   wxFont font =
843     wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
844   wktCtrl->SetFont(font);
845   wktSizer->Add(wktCtrl, 0, wxALIGN_LEFT | wxALL, 5);
846   wxBoxSizer *btnSizer = new wxBoxSizer(wxHORIZONTAL);
847   boxSizer->Add(btnSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
848   wxButton *btnCopy = new wxButton(panel, ID_XML_DOCUMENT_COPY, wxT("&Copy"));
849   btnSizer->Add(btnCopy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
850   panel->SetSizer(topSizer);
851   topSizer->Fit(panel);
852 // appends event handlers
853   Connect(ID_XML_DOCUMENT_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
854           (wxObjectEventFunction) & BlobExplorerDialog::OnCopyXmlDocument);
855   return panel;
856 }
857 
OnCopyXmlDocument(wxCommandEvent & WXUNUSED (event))858 void BlobExplorerDialog::OnCopyXmlDocument(wxCommandEvent & WXUNUSED(event))
859 {
860 //
861 // Copying XMLDocument to the Clipboard
862 //
863 
864   if (wxTheClipboard->Open())
865     {
866       wxTheClipboard->SetData(new wxTextDataObject(XMLDocument));
867       wxTheClipboard->Close();
868     }
869 }
870 
CreateXmlIndentedPage(wxWindow * parent)871 wxPanel *BlobExplorerDialog::CreateXmlIndentedPage(wxWindow * parent)
872 {
873 //
874 // creating the XMLIndented page
875 //
876   wxPanel *panel = new wxPanel(parent, ID_PANE_WKT);
877   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
878   panel->SetSizer(topSizer);
879   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
880   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
881 // creating a control to show the WKT notation
882   wxBoxSizer *wktSizer = new wxBoxSizer(wxHORIZONTAL);
883   boxSizer->Add(wktSizer, 0, wxALIGN_LEFT | wxALL, 0);
884   wxTextCtrl *wktCtrl = new wxTextCtrl(panel, ID_XML_INDENTED_TABLE, wxT(""),
885                                        wxDefaultPosition, wxSize(600,
886                                                                  300),
887                                        wxTE_MULTILINE | wxTE_READONLY |
888                                        wxTE_RICH | wxVSCROLL);
889   wxFont font =
890     wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
891   wktCtrl->SetFont(font);
892   wktSizer->Add(wktCtrl, 0, wxALIGN_LEFT | wxALL, 5);
893   wxBoxSizer *btnSizer = new wxBoxSizer(wxHORIZONTAL);
894   boxSizer->Add(btnSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 0);
895   wxButton *btnCopy = new wxButton(panel, ID_XML_INDENTED_COPY, wxT("&Copy"));
896   btnSizer->Add(btnCopy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
897   panel->SetSizer(topSizer);
898   topSizer->Fit(panel);
899 // appends event handlers
900   Connect(ID_XML_INDENTED_COPY, wxEVT_COMMAND_BUTTON_CLICKED,
901           (wxObjectEventFunction) & BlobExplorerDialog::OnCopyXmlIndented);
902   return panel;
903 }
904 
OnCopyXmlIndented(wxCommandEvent & WXUNUSED (event))905 void BlobExplorerDialog::OnCopyXmlIndented(wxCommandEvent & WXUNUSED(event))
906 {
907 //
908 // Copying XMLDocument to the Clipboard
909 //
910 
911   if (wxTheClipboard->Open())
912     {
913       wxTheClipboard->SetData(new wxTextDataObject(XMLIndented));
914       wxTheClipboard->Close();
915     }
916 }
917 
CreateImagePage(wxWindow * parent)918 wxPanel *BlobExplorerDialog::CreateImagePage(wxWindow * parent)
919 {
920 //
921 // creating the IMAGE page
922 //
923   wxPanel *panel = new wxPanel(parent, ID_PANE_IMAGE);
924   wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
925   panel->SetSizer(topSizer);
926   wxBoxSizer *boxSizer = new wxBoxSizer(wxVERTICAL);
927   topSizer->Add(boxSizer, 0, wxALIGN_CENTER | wxALL, 5);
928 // creating a control to show the image title
929   wxBoxSizer *imgSizer = new wxBoxSizer(wxVERTICAL);
930   boxSizer->Add(imgSizer, 0, wxALIGN_TOP | wxALL, 0);
931   wxStaticText *imageTitle = new wxStaticText(panel, ID_IMAGE_TITLE,
932                                               wxT("Image"),
933                                               wxDefaultPosition,
934                                               wxSize(560,
935                                                      10));
936   imgSizer->Add(imageTitle, 0, wxALIGN_LEFT | wxALL, 5);
937 // creating a control to show the image
938   wxStaticBox *exBox = new wxStaticBox(panel, ID_IMG_BOX,
939                                        wxT("Image preview"),
940                                        wxDefaultPosition, wxDefaultSize);
941   wxBoxSizer *exampleSizer = new wxStaticBoxSizer(exBox, wxHORIZONTAL);
942   imgSizer->Add(exampleSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
943   ImageShow *imgShow = new ImageShow(this, panel, ID_IMAGE,
944                                      wxBitmap(), wxSize(560, 300));
945   exampleSizer->Add(imgShow, 0, wxALIGN_CENTER_VERTICAL | wxALL, 0);
946   panel->SetSizer(topSizer);
947   topSizer->Fit(panel);
948   return panel;
949 }
950 
OnPageChanged(wxNotebookEvent & event)951 void BlobExplorerDialog::OnPageChanged(wxNotebookEvent & event)
952 {
953 //
954 // TAB/PAGE selection changed
955 //
956   switch (event.GetSelection())
957     {
958       case 0:
959         UpdateHexadecimalPage();
960         break;
961       case 1:
962         if (BlobType == GAIA_GEOMETRY_BLOB)
963           UpdateGeometryPage();
964         else if (BlobType == GAIA_XML_BLOB)
965           UpdateXmlDocumentPage();
966         else
967           UpdateImagePage();
968         break;
969       case 2:
970         if (BlobType == GAIA_XML_BLOB)
971           UpdateXmlIndentedPage();
972         else
973           UpdateWKTPage();
974         break;
975       case 3:
976         if (IsSVG == true)
977           UpdateImagePage();
978         else
979           UpdateEWKTPage();
980         break;
981       case 4:
982         UpdateSVGPage();
983         break;
984       case 5:
985         UpdateKMLPage();
986         break;
987       case 6:
988         UpdateGMLPage();
989         break;
990       case 7:
991         UpdateGeoJSONPage();
992         break;
993     };
994 }
995 
UpdateHexadecimalPage()996 void BlobExplorerDialog::UpdateHexadecimalPage()
997 {
998 //
999 // updating the HEXADECIMAL page
1000 //
1001   MyHexList *hexCtrl = (MyHexList *) FindWindow(ID_HEX);
1002   hexCtrl->EnsureVisible(0);
1003 }
1004 
UpdateGeometryPage()1005 void BlobExplorerDialog::UpdateGeometryPage()
1006 {
1007 //
1008 // updating the GEOMETRY page
1009 //
1010   gaiaPointPtr pt;
1011   gaiaLinestringPtr ln;
1012   gaiaPolygonPtr pg;
1013   gaiaRingPtr rng;
1014   int points = 0;
1015   int linestrings = 0;
1016   int polygons = 0;
1017   int ib;
1018   wxString strValue;
1019   char dummy[1024];
1020   wxTextAttr attrBold(wxColour(0, 0, 0), wxColour(255, 255, 255),
1021                       wxFont(9, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL,
1022                              wxFONTWEIGHT_BOLD));
1023   wxTextAttr attrNorm(wxColour(0, 0, 0), wxColour(255, 255, 255),
1024                       wxFont(9, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL,
1025                              wxFONTWEIGHT_NORMAL));
1026   wxTextCtrl *geomCtrl = (wxTextCtrl *) FindWindow(ID_GEOM_TABLE);
1027   if (geomCtrl->GetValue().Len() < 1)
1028     {
1029       ::wxBeginBusyCursor();
1030       pt = Geometry->FirstPoint;
1031       while (pt)
1032         {
1033           // counting how many points are into this Geometry
1034           points++;
1035           pt = pt->Next;
1036         }
1037       ln = Geometry->FirstLinestring;
1038       while (ln)
1039         {
1040           // counting how many linestrings are into this Geometry
1041           linestrings++;
1042           ln = ln->Next;
1043         }
1044       pg = Geometry->FirstPolygon;
1045       while (pg)
1046         {
1047           // counting how many polygons are into this Geometry
1048           polygons++;
1049           pg = pg->Next;
1050         }
1051       // determining the Geometry type
1052       geomCtrl->SetDefaultStyle(attrNorm);
1053       geomCtrl->AppendText(wxT("SRID: "));
1054       geomCtrl->SetDefaultStyle(attrBold);
1055       sprintf(dummy, "%d", Geometry->Srid);
1056       strValue = wxString::FromUTF8(dummy);
1057       geomCtrl->AppendText(strValue);
1058       geomCtrl->SetDefaultStyle(attrNorm);
1059       geomCtrl->AppendText(wxT("\n\n"));
1060       strValue = wxT("UNKNOWN GEOMETRY TYPE");
1061       if (points == 1 && linestrings == 0 && polygons == 0)
1062         {
1063           if (Geometry->DeclaredType == GAIA_MULTIPOINT)
1064             strValue = wxT("MULTIPOINT");
1065           else if (Geometry->DeclaredType == GAIA_GEOMETRYCOLLECTION)
1066             strValue = wxT("GEOMETRYCOLLECTION");
1067           else
1068             strValue = wxT("POINT");
1069       } else if (points == 0 && linestrings == 1 && polygons == 0)
1070         {
1071           if (Geometry->DeclaredType == GAIA_MULTILINESTRING)
1072             strValue = wxT("MULTILINESTRING");
1073           else if (Geometry->DeclaredType == GAIA_GEOMETRYCOLLECTION)
1074             strValue = wxT("GEOMETRYCOLLECTION");
1075           else
1076             strValue = wxT("LINESTRING");
1077       } else if (points == 0 && linestrings == 0 && polygons == 1)
1078         {
1079           if (Geometry->DeclaredType == GAIA_MULTIPOLYGON)
1080             strValue = wxT("MULTIPOLYGON");
1081           else if (Geometry->DeclaredType == GAIA_GEOMETRYCOLLECTION)
1082             strValue = wxT("GEOMETRYCOLLECTION");
1083           else
1084             strValue = wxT("POLYGON");
1085       } else if (points > 1 && linestrings == 0 && polygons == 0)
1086         {
1087           if (Geometry->DeclaredType == GAIA_GEOMETRYCOLLECTION)
1088             strValue = wxT("GEOMETRYCOLLECTION");
1089           else
1090             strValue = wxT("MULTIPOINT");
1091       } else if (points == 0 && linestrings > 1 && polygons == 0)
1092         {
1093           if (Geometry->DeclaredType == GAIA_GEOMETRYCOLLECTION)
1094             strValue = wxT("GEOMETRYCOLLECTION");
1095           else
1096             strValue = wxT("MULTILINESTRING");
1097       } else if (points == 0 && linestrings == 0 && polygons > 1)
1098         {
1099           if (Geometry->DeclaredType == GAIA_GEOMETRYCOLLECTION)
1100             strValue = wxT("GEOMETRYCOLLECTION");
1101           else
1102             strValue = wxT("MULTIPOLYGON");
1103       } else
1104         strValue = wxT("GEOMETRYCOLLECTION");
1105       geomCtrl->SetDefaultStyle(attrNorm);
1106       geomCtrl->AppendText(wxT("Geometry type: "));
1107       geomCtrl->SetDefaultStyle(attrBold);
1108       geomCtrl->AppendText(strValue);
1109       geomCtrl->SetDefaultStyle(attrNorm);
1110       geomCtrl->AppendText(wxT("\n\n"));
1111       if (points)
1112         {
1113           // printing the Points list
1114           sprintf(dummy, "#%d POINT", points);
1115           strValue = wxString::FromUTF8(dummy);
1116           if (points > 1)
1117             strValue += wxT("s:");
1118           else
1119             strValue += wxT(":");
1120           geomCtrl->SetDefaultStyle(attrBold);
1121           geomCtrl->AppendText(strValue);
1122           geomCtrl->SetDefaultStyle(attrNorm);
1123           pt = Geometry->FirstPoint;
1124           points = 0;
1125           while (pt)
1126             {
1127               // printing each Point
1128               points++;
1129               sprintf(dummy, "\n  %d) ", points);
1130               strValue = wxString::FromUTF8(dummy);
1131               geomCtrl->SetDefaultStyle(attrBold);
1132               geomCtrl->AppendText(strValue);
1133               geomCtrl->SetDefaultStyle(attrNorm);
1134               sprintf(dummy, "%1.4f  %1.4f", pt->X, pt->Y);
1135               strValue = wxString::FromUTF8(dummy);
1136               geomCtrl->AppendText(strValue);
1137               pt = pt->Next;
1138             }
1139           geomCtrl->AppendText(wxT("\n\n\n"));
1140         }
1141       if (linestrings)
1142         {
1143           // printing the Linestrings list
1144           sprintf(dummy, "#%d LINESTRING", linestrings);
1145           strValue = wxString::FromUTF8(dummy);
1146           if (linestrings > 1)
1147             strValue += wxT("s:");
1148           else
1149             strValue += wxT(":");
1150           geomCtrl->SetDefaultStyle(attrBold);
1151           geomCtrl->AppendText(strValue);
1152           geomCtrl->SetDefaultStyle(attrNorm);
1153           ln = Geometry->FirstLinestring;
1154           linestrings = 0;
1155           while (ln)
1156             {
1157               // printing each Linestring
1158               linestrings++;
1159               sprintf(dummy, "\n  %d) ", linestrings);
1160               strValue = wxString::FromUTF8(dummy);
1161               geomCtrl->SetDefaultStyle(attrBold);
1162               geomCtrl->AppendText(strValue);
1163               geomCtrl->SetDefaultStyle(attrNorm);
1164               sprintf(dummy, "%d vertices", ln->Points);
1165               strValue = wxString::FromUTF8(dummy);
1166               geomCtrl->AppendText(strValue);
1167               ln = ln->Next;
1168             }
1169           geomCtrl->AppendText(wxT("\n\n\n"));
1170         }
1171       if (polygons)
1172         {
1173           // printing the Polygons list
1174           sprintf(dummy, "#%d POLYGON", polygons);
1175           strValue = wxString::FromUTF8(dummy);
1176           if (polygons > 1)
1177             strValue += wxT("s:");
1178           else
1179             strValue += wxT(":");
1180           geomCtrl->SetDefaultStyle(attrBold);
1181           geomCtrl->AppendText(strValue);
1182           geomCtrl->SetDefaultStyle(attrNorm);
1183           pg = Geometry->FirstPolygon;
1184           polygons = 0;
1185           while (pg)
1186             {
1187               // printing each Polygon
1188               polygons++;
1189               sprintf(dummy, "\n  %d)    exterior ring", polygons);
1190               strValue = wxString::FromUTF8(dummy);
1191               geomCtrl->SetDefaultStyle(attrBold);
1192               geomCtrl->AppendText(strValue);
1193               geomCtrl->SetDefaultStyle(attrNorm);
1194               rng = pg->Exterior;
1195               sprintf(dummy, ": %d vertices", rng->Points);
1196               strValue = wxString::FromUTF8(dummy);
1197               geomCtrl->AppendText(strValue);
1198               for (ib = 0; ib < pg->NumInteriors; ib++)
1199                 {
1200                   // printing each interior ring
1201                   sprintf(dummy, "\n  %d.%d) ", polygons, ib + 1);
1202                   strValue = wxString::FromUTF8(dummy);
1203                   geomCtrl->SetDefaultStyle(attrBold);
1204                   geomCtrl->AppendText(strValue);
1205                   geomCtrl->SetDefaultStyle(attrNorm);
1206                   rng = pg->Interiors + ib;
1207                   sprintf(dummy, " interior ring: %d vertices", rng->Points);
1208                   strValue = wxString::FromUTF8(dummy);
1209                   geomCtrl->AppendText(strValue);
1210                 }
1211               pg = pg->Next;
1212             }
1213           geomCtrl->AppendText(wxT("\n\n\n"));
1214         }
1215       ::wxEndBusyCursor();
1216     }
1217   GraphicsGeometry *geomGraph = (GraphicsGeometry *) FindWindow(ID_GEOM_GRAPH);
1218   geomGraph->SetBitmap(GeomPreview);
1219 }
1220 
UpdateImagePage()1221 void BlobExplorerDialog::UpdateImagePage()
1222 {
1223 //
1224 // updating the IMAGE page
1225 //
1226   double horz;
1227   double vert;
1228   wxImage scaledImg;
1229   wxSize sz;
1230   wxSize box;
1231   int boxX;
1232   int boxY;
1233   int posX;
1234   int posY;
1235   char latlong[1024];
1236   char dummy[1024];
1237   wxString ll;
1238   wxString title = wxT("Invalid Image");
1239   wxStaticBox *imgBox = (wxStaticBox *) FindWindow(ID_IMG_BOX);
1240   ImageShow *imgShow = (ImageShow *) FindWindow(ID_IMAGE);
1241   wxStaticText *imageTitle = (wxStaticText *) FindWindow(ID_IMAGE_TITLE);
1242   if (Image)
1243     {
1244       ::wxBeginBusyCursor();
1245       if (Image->IsOk() == true)
1246         {
1247           horz = Image->GetWidth();
1248           vert = Image->GetHeight();
1249           sz = imgShow->GetSize();
1250           box = imgBox->GetSize();
1251           while (horz > sz.GetWidth() || vert > sz.GetHeight())
1252             {
1253               horz *= 0.9;
1254               vert *= 0.9;
1255             }
1256           if (horz == Image->GetWidth() && vert == Image->GetHeight())
1257             scaledImg = Image->Copy();
1258           else
1259             scaledImg =
1260               Image->Scale((int) horz, (int) vert, wxIMAGE_QUALITY_HIGH);
1261           wxBitmap bmp(scaledImg);
1262           imgBox->GetPosition(&boxX, &boxY);
1263           posX = (box.GetWidth() - (int) horz) / 2;
1264           posY = (box.GetHeight() - (int) vert) / 2;
1265           imgShow->SetSize(boxX + posX, boxY + posY, (int) horz, (int) vert);
1266           imgShow->SetBitmap(bmp);
1267           imgShow->Show(true);
1268           switch (BlobType)
1269             {
1270               case GAIA_JPEG_BLOB:
1271                 sprintf(dummy,
1272                         "JPEG image     resolution: %d x %d          %d bytes",
1273                         Image->GetWidth(), Image->GetHeight(), BlobSize);
1274                 title = wxString::FromUTF8(dummy);
1275                 break;
1276               case GAIA_EXIF_BLOB:
1277                 sprintf(dummy,
1278                         "EXIF image     resolution: %d x %d          %d bytes",
1279                         Image->GetWidth(), Image->GetHeight(), BlobSize);
1280                 title = wxString::FromUTF8(dummy);
1281                 break;
1282               case GAIA_EXIF_GPS_BLOB:
1283                 if (gaiaGetGpsLatLong(Blob, BlobSize, latlong, 1024))
1284                   ll = wxString::FromUTF8(latlong);
1285                 else
1286                   ll = wxT("NOT AVAILABLE");
1287                 sprintf(dummy,
1288                         "EXIF-GPS image     resolution: %d x %d          %d bytes    GPS: ",
1289                         Image->GetWidth(), Image->GetHeight(), BlobSize);
1290                 title = wxString::FromUTF8(dummy);
1291                 title += ll;
1292                 break;
1293               case GAIA_PNG_BLOB:
1294                 sprintf(dummy,
1295                         "PNG image     resolution: %d x %d          %d bytes",
1296                         Image->GetWidth(), Image->GetHeight(), BlobSize);
1297                 title = wxString::FromUTF8(dummy);
1298                 break;
1299               case GAIA_GIF_BLOB:
1300                 sprintf(dummy,
1301                         "GIF image     resolution: %d x %d          %d bytes",
1302                         Image->GetWidth(), Image->GetHeight(), BlobSize);
1303                 title = wxString::FromUTF8(dummy);
1304                 break;
1305               case GAIA_TIFF_BLOB:
1306                 sprintf(dummy,
1307                         "TIFF image     resolution: %d x %d          %d bytes",
1308                         Image->GetWidth(), Image->GetHeight(), BlobSize);
1309                 title = wxString::FromUTF8(dummy);
1310                 break;
1311               default:
1312                 if (gGraphIsRawImage(Blob, BlobSize) == GGRAPH_OK)
1313                   {
1314                     sprintf(dummy,
1315                             "RasterLite RAW image     resolution: %d x %d          %d bytes",
1316                             Image->GetWidth(), Image->GetHeight(), BlobSize);
1317                     title = wxString::FromUTF8(dummy);
1318                 } else if (IsSVG == true)
1319                   {
1320                     sprintf(dummy,
1321                             "SVG image     resolution: %1.2f x %1.2f          %d bytes",
1322                             SvgWidth, SvgHeight, SvgSize);
1323                     title = wxString::FromUTF8(dummy);
1324                   }
1325                 break;
1326             }
1327         }
1328       ::wxEndBusyCursor();
1329     }
1330   imageTitle->SetLabel(title);
1331 }
1332 
FormatWKT(wxTextCtrl * txtCtrl,wxString & in,wxString & out)1333 void BlobExplorerDialog::FormatWKT(wxTextCtrl * txtCtrl, wxString & in,
1334                                    wxString & out)
1335 {
1336 //
1337 // splitting WKT into rows
1338 //
1339   int page_width;
1340   int h;
1341   wxClientDC *dc = new wxClientDC(txtCtrl);
1342   int row_sz = 0;
1343   wxSize spSz = dc->GetTextExtent(wxT(","));
1344   int sp_sz = spSz.GetWidth();
1345 
1346   out = wxT("");
1347   txtCtrl->GetSize(&page_width, &h);
1348   page_width -= page_width / 4;
1349   wxStringTokenizer tkz(in, wxT(","));
1350   while (tkz.HasMoreTokens())
1351     {
1352       wxString token = tkz.GetNextToken();
1353       wxSize sz = dc->GetTextExtent(token);
1354       if (row_sz == 0)
1355         {
1356           out += token;
1357           row_sz = sz.GetWidth();
1358       } else
1359         {
1360           if (row_sz + sp_sz + sz.GetWidth() < page_width)
1361             {
1362               out += wxT(",") + token;
1363               row_sz += sp_sz + sz.GetWidth();
1364           } else
1365             {
1366               out += wxT(",\n") + token;
1367               row_sz = sz.GetWidth();
1368             }
1369         }
1370     }
1371   delete dc;
1372 }
1373 
UpdateWKTPage()1374 void BlobExplorerDialog::UpdateWKTPage()
1375 {
1376 //
1377 // updating the WKT page
1378 //
1379   wxTextCtrl *wktCtrl = (wxTextCtrl *) FindWindow(ID_WKT_TABLE);
1380   if (wktCtrl->GetValue().Len() < 1)
1381     {
1382       sqlite3_stmt *stmt = NULL;
1383       char err_msg[2048];
1384       const char *sql = "SELECT ST_AsText(?)";
1385       ::wxBeginBusyCursor();
1386       int ret =
1387         sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt,
1388                            NULL);
1389       if (ret != SQLITE_OK)
1390         {
1391           sprintf(err_msg, "SQL error: %s",
1392                   sqlite3_errmsg(MainFrame->GetSqlite()));
1393           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
1394                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1395           ::wxEndBusyCursor();
1396           return;
1397         }
1398       sqlite3_reset(stmt);
1399       sqlite3_clear_bindings(stmt);
1400       sqlite3_bind_blob(stmt, 1, Blob, BlobSize, SQLITE_STATIC);
1401       while (1)
1402         {
1403           //
1404           // fetching the result set row
1405           //
1406           ret = sqlite3_step(stmt);
1407           if (ret == SQLITE_DONE)
1408             break;              // end of result set
1409           if (ret == SQLITE_ROW)
1410             {
1411               //
1412               // fetching a row
1413               //
1414               if (sqlite3_column_type(stmt, 0) == SQLITE_TEXT)
1415                 WKTstring =
1416                   wxString::FromUTF8((const char *)
1417                                      sqlite3_column_text(stmt, 0));
1418           } else
1419             {
1420               sqlite3_finalize(stmt);
1421               sprintf(err_msg, "SQL error: %s",
1422                       sqlite3_errmsg(MainFrame->GetSqlite()));
1423               wxMessageBox(wxT("SQLite SQL error: ") +
1424                            wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
1425                            wxOK | wxICON_ERROR, this);
1426               ::wxEndBusyCursor();
1427               return;
1428             }
1429         }
1430       sqlite3_finalize(stmt);
1431       wxString wkt;
1432       FormatWKT(wktCtrl, WKTstring, wkt);
1433       wktCtrl->WriteText(wkt);
1434       ::wxEndBusyCursor();
1435     }
1436 }
1437 
UpdateEWKTPage()1438 void BlobExplorerDialog::UpdateEWKTPage()
1439 {
1440 //
1441 // updating the EWKT page
1442 //
1443   wxTextCtrl *ewktCtrl = (wxTextCtrl *) FindWindow(ID_EWKT_TABLE);
1444   if (ewktCtrl->GetValue().Len() < 1)
1445     {
1446       sqlite3_stmt *stmt = NULL;
1447       char err_msg[2048];
1448       const char *sql = "SELECT AsEWKT(?)";
1449       ::wxBeginBusyCursor();
1450       int ret =
1451         sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt,
1452                            NULL);
1453       if (ret != SQLITE_OK)
1454         {
1455           sprintf(err_msg, "SQL error: %s",
1456                   sqlite3_errmsg(MainFrame->GetSqlite()));
1457           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
1458                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1459           ::wxEndBusyCursor();
1460           return;
1461         }
1462       sqlite3_reset(stmt);
1463       sqlite3_clear_bindings(stmt);
1464       sqlite3_bind_blob(stmt, 1, Blob, BlobSize, SQLITE_STATIC);
1465       while (1)
1466         {
1467           //
1468           // fetching the result set row
1469           //
1470           ret = sqlite3_step(stmt);
1471           if (ret == SQLITE_DONE)
1472             break;              // end of result set
1473           if (ret == SQLITE_ROW)
1474             {
1475               //
1476               // fetching a row
1477               //
1478               if (sqlite3_column_type(stmt, 0) == SQLITE_TEXT)
1479                 EWKTstring =
1480                   wxString::FromUTF8((const char *)
1481                                      sqlite3_column_text(stmt, 0));
1482           } else
1483             {
1484               sqlite3_finalize(stmt);
1485               sprintf(err_msg, "SQL error: %s",
1486                       sqlite3_errmsg(MainFrame->GetSqlite()));
1487               wxMessageBox(wxT("SQLite SQL error: ") +
1488                            wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
1489                            wxOK | wxICON_ERROR, this);
1490               ::wxEndBusyCursor();
1491               return;
1492             }
1493         }
1494       sqlite3_finalize(stmt);
1495       wxString ewkt;
1496       FormatWKT(ewktCtrl, EWKTstring, ewkt);
1497       ewktCtrl->WriteText(ewkt);
1498       ::wxEndBusyCursor();
1499     }
1500 }
1501 
FormatSVG(wxTextCtrl * txtCtrl,wxString & in,wxString & out)1502 void BlobExplorerDialog::FormatSVG(wxTextCtrl * txtCtrl, wxString & in,
1503                                    wxString & out)
1504 {
1505 //
1506 // splitting SVG into rows
1507 //
1508   int page_width;
1509   int h;
1510   wxClientDC *dc = new wxClientDC(txtCtrl);
1511   int row_sz = 0;
1512   wxSize spSz = dc->GetTextExtent(wxT(" "));
1513   int sp_sz = spSz.GetWidth();
1514 
1515   out = wxT("");
1516   txtCtrl->GetSize(&page_width, &h);
1517   page_width -= page_width / 4;
1518   wxStringTokenizer tkz(in, wxT(" "));
1519   while (tkz.HasMoreTokens())
1520     {
1521       wxString token = tkz.GetNextToken();
1522       wxSize sz = dc->GetTextExtent(token);
1523       if (row_sz == 0)
1524         {
1525           out += token;
1526           row_sz = sz.GetWidth();
1527       } else
1528         {
1529           if (row_sz + sp_sz + sz.GetWidth() < page_width)
1530             {
1531               out += wxT(" ") + token;
1532               row_sz += sp_sz + sz.GetWidth();
1533           } else
1534             {
1535               out += wxT("\n") + token;
1536               row_sz = sz.GetWidth();
1537             }
1538         }
1539     }
1540   delete dc;
1541 }
1542 
UpdateSVGPage()1543 void BlobExplorerDialog::UpdateSVGPage()
1544 {
1545 //
1546 // updating the SVG page
1547 //
1548   wxTextCtrl *svgCtrl = (wxTextCtrl *) FindWindow(ID_SVG_TABLE);
1549   if (svgCtrl->GetValue().Len() < 1)
1550     {
1551       sqlite3_stmt *stmt = NULL;
1552       char err_msg[2048];
1553       const char *sql = "SELECT AsSVG(?, ?)";
1554       ::wxBeginBusyCursor();
1555       if (SVGprecision >= 0)
1556         sql = "SELECT AsSVG(?, ?, ?)";
1557       int ret =
1558         sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt,
1559                            NULL);
1560       if (ret != SQLITE_OK)
1561         {
1562           sprintf(err_msg, "SQL error: %s",
1563                   sqlite3_errmsg(MainFrame->GetSqlite()));
1564           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
1565                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1566           ::wxEndBusyCursor();
1567           return;
1568         }
1569       sqlite3_reset(stmt);
1570       sqlite3_clear_bindings(stmt);
1571       sqlite3_bind_blob(stmt, 1, Blob, BlobSize, SQLITE_STATIC);
1572       if (SVGrelative == true)
1573         sqlite3_bind_int(stmt, 2, 1);
1574       else
1575         sqlite3_bind_int(stmt, 2, 0);
1576       if (SVGprecision >= 0)
1577         sqlite3_bind_int(stmt, 3, SVGprecision);
1578       while (1)
1579         {
1580           //
1581           // fetching the result set row
1582           //
1583           ret = sqlite3_step(stmt);
1584           if (ret == SQLITE_DONE)
1585             break;              // end of result set
1586           if (ret == SQLITE_ROW)
1587             {
1588               //
1589               // fetching a row
1590               //
1591               if (sqlite3_column_type(stmt, 0) == SQLITE_TEXT)
1592                 SVGstring =
1593                   wxString::FromUTF8((const char *)
1594                                      sqlite3_column_text(stmt, 0));
1595           } else
1596             {
1597               sqlite3_finalize(stmt);
1598               sprintf(err_msg, "SQL error: %s",
1599                       sqlite3_errmsg(MainFrame->GetSqlite()));
1600               wxMessageBox(wxT("SQLite SQL error: ") +
1601                            wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
1602                            wxOK | wxICON_ERROR, this);
1603               ::wxEndBusyCursor();
1604               return;
1605             }
1606         }
1607       sqlite3_finalize(stmt);
1608       wxString svg;
1609       FormatSVG(svgCtrl, SVGstring, svg);
1610       svgCtrl->WriteText(svg);
1611       ::wxEndBusyCursor();
1612     }
1613 }
1614 
UpdateKMLPage()1615 void BlobExplorerDialog::UpdateKMLPage()
1616 {
1617 //
1618 // updating the KML page
1619 //
1620   wxTextCtrl *kmlCtrl = (wxTextCtrl *) FindWindow(ID_KML_TABLE);
1621   if (kmlCtrl->GetValue().Len() < 1)
1622     {
1623       sqlite3_stmt *stmt = NULL;
1624       char err_msg[2048];
1625       const char *sql = "SELECT AsKML(?)";
1626       if (KMLprecision >= 0)
1627         sql = "SELECT AsKML(?, ?)";
1628       ::wxBeginBusyCursor();
1629       int ret =
1630         sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt,
1631                            NULL);
1632       if (ret != SQLITE_OK)
1633         {
1634           sprintf(err_msg, "SQL error: %s",
1635                   sqlite3_errmsg(MainFrame->GetSqlite()));
1636           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
1637                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1638           ::wxEndBusyCursor();
1639           return;
1640         }
1641       sqlite3_reset(stmt);
1642       sqlite3_clear_bindings(stmt);
1643       sqlite3_bind_blob(stmt, 1, Blob, BlobSize, SQLITE_STATIC);
1644       if (KMLprecision >= 0)
1645         sqlite3_bind_int(stmt, 2, KMLprecision);
1646       while (1)
1647         {
1648           //
1649           // fetching the result set row
1650           //
1651           ret = sqlite3_step(stmt);
1652           if (ret == SQLITE_DONE)
1653             break;              // end of result set
1654           if (ret == SQLITE_ROW)
1655             {
1656               //
1657               // fetching a row
1658               //
1659               if (sqlite3_column_type(stmt, 0) == SQLITE_TEXT)
1660                 KMLstring =
1661                   wxString::FromUTF8((const char *)
1662                                      sqlite3_column_text(stmt, 0));
1663           } else
1664             {
1665               sqlite3_finalize(stmt);
1666               sprintf(err_msg, "SQL error: %s",
1667                       sqlite3_errmsg(MainFrame->GetSqlite()));
1668               wxMessageBox(wxT("SQLite SQL error: ") +
1669                            wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
1670                            wxOK | wxICON_ERROR, this);
1671               ::wxEndBusyCursor();
1672               return;
1673             }
1674         }
1675       sqlite3_finalize(stmt);
1676       wxString kml;
1677       FormatSVG(kmlCtrl, KMLstring, kml);
1678       kmlCtrl->WriteText(kml);
1679       ::wxEndBusyCursor();
1680     }
1681 }
1682 
UpdateGMLPage()1683 void BlobExplorerDialog::UpdateGMLPage()
1684 {
1685 //
1686 // updating the GML page
1687 //
1688   wxTextCtrl *gmlCtrl = (wxTextCtrl *) FindWindow(ID_GML_TABLE);
1689   if (gmlCtrl->GetValue().Len() < 1)
1690     {
1691       sqlite3_stmt *stmt = NULL;
1692       char err_msg[2048];
1693       const char *sql = "SELECT AsGML(?, ?)";
1694       if (GMLprecision >= 0)
1695         sql = "SELECT AsGML(?, ?, ?)";
1696       ::wxBeginBusyCursor();
1697       int ret =
1698         sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt,
1699                            NULL);
1700       if (ret != SQLITE_OK)
1701         {
1702           sprintf(err_msg, "SQL error: %s",
1703                   sqlite3_errmsg(MainFrame->GetSqlite()));
1704           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
1705                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1706           ::wxEndBusyCursor();
1707           return;
1708         }
1709       sqlite3_reset(stmt);
1710       sqlite3_clear_bindings(stmt);
1711       if (GMLv2v3 == true)
1712         sqlite3_bind_int(stmt, 1, 2);
1713       else
1714         sqlite3_bind_int(stmt, 1, 3);
1715       sqlite3_bind_blob(stmt, 2, Blob, BlobSize, SQLITE_STATIC);
1716       if (GMLprecision >= 0)
1717         sqlite3_bind_int(stmt, 3, GMLprecision);
1718       while (1)
1719         {
1720           //
1721           // fetching the result set row
1722           //
1723           ret = sqlite3_step(stmt);
1724           if (ret == SQLITE_DONE)
1725             break;              // end of result set
1726           if (ret == SQLITE_ROW)
1727             {
1728               //
1729               // fetching a row
1730               //
1731               if (sqlite3_column_type(stmt, 0) == SQLITE_TEXT)
1732                 GMLstring =
1733                   wxString::FromUTF8((const char *)
1734                                      sqlite3_column_text(stmt, 0));
1735           } else
1736             {
1737               sqlite3_finalize(stmt);
1738               sprintf(err_msg, "SQL error: %s",
1739                       sqlite3_errmsg(MainFrame->GetSqlite()));
1740               wxMessageBox(wxT("SQLite SQL error: ") +
1741                            wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
1742                            wxOK | wxICON_ERROR, this);
1743               ::wxEndBusyCursor();
1744               return;
1745             }
1746         }
1747       sqlite3_finalize(stmt);
1748       wxString gml;
1749       FormatSVG(gmlCtrl, GMLstring, gml);
1750       gmlCtrl->WriteText(gml);
1751       ::wxEndBusyCursor();
1752     }
1753 }
1754 
UpdateGeoJSONPage()1755 void BlobExplorerDialog::UpdateGeoJSONPage()
1756 {
1757 //
1758 // updating the GeoJSON page
1759 //
1760   wxTextCtrl *geoJsonCtrl = (wxTextCtrl *) FindWindow(ID_GEOJSON_TABLE);
1761   if (geoJsonCtrl->GetValue().Len() < 1)
1762     {
1763       sqlite3_stmt *stmt = NULL;
1764       char err_msg[2048];
1765       const char *sql = "SELECT AsGeoJSON(?)";
1766       if (GeoJSONprecision >= 0)
1767         sql = "SELECT AsGeoJSON(?, ?)";
1768       if (GeoJSONoptions > 0)
1769         sql = "SELECT AsGeoJSON(?, ?, ?)";
1770       ::wxBeginBusyCursor();
1771       int ret =
1772         sqlite3_prepare_v2(MainFrame->GetSqlite(), sql, strlen(sql), &stmt,
1773                            NULL);
1774       if (ret != SQLITE_OK)
1775         {
1776           sprintf(err_msg, "SQL error: %s",
1777                   sqlite3_errmsg(MainFrame->GetSqlite()));
1778           wxMessageBox(wxT("SQLite SQL error: ") + wxString::FromUTF8(err_msg),
1779                        wxT("spatialite_gui"), wxOK | wxICON_ERROR, this);
1780           ::wxEndBusyCursor();
1781           return;
1782         }
1783       sqlite3_reset(stmt);
1784       sqlite3_clear_bindings(stmt);
1785       sqlite3_bind_blob(stmt, 1, Blob, BlobSize, SQLITE_STATIC);
1786       if (GeoJSONoptions > 0)
1787         {
1788           if (GeoJSONprecision >= 0)
1789             sqlite3_bind_int(stmt, 2, GeoJSONprecision);
1790           else
1791             sqlite3_bind_int(stmt, 2, 15);
1792           sqlite3_bind_int(stmt, 3, GeoJSONoptions);
1793       } else if (GeoJSONprecision >= 0)
1794         sqlite3_bind_int(stmt, 2, GeoJSONprecision);
1795       while (1)
1796         {
1797           //
1798           // fetching the result set row
1799           //
1800           ret = sqlite3_step(stmt);
1801           if (ret == SQLITE_DONE)
1802             break;              // end of result set
1803           if (ret == SQLITE_ROW)
1804             {
1805               //
1806               // fetching a row
1807               //
1808               if (sqlite3_column_type(stmt, 0) == SQLITE_TEXT)
1809                 GeoJSONstring =
1810                   wxString::FromUTF8((const char *)
1811                                      sqlite3_column_text(stmt, 0));
1812           } else
1813             {
1814               sqlite3_finalize(stmt);
1815               sprintf(err_msg, "SQL error: %s",
1816                       sqlite3_errmsg(MainFrame->GetSqlite()));
1817               wxMessageBox(wxT("SQLite SQL error: ") +
1818                            wxString::FromUTF8(err_msg), wxT("spatialite_gui"),
1819                            wxOK | wxICON_ERROR, this);
1820               ::wxEndBusyCursor();
1821               return;
1822             }
1823         }
1824       sqlite3_finalize(stmt);
1825       wxString geoJson;
1826       FormatWKT(geoJsonCtrl, GeoJSONstring, geoJson);
1827       geoJsonCtrl->WriteText(geoJson);
1828       ::wxEndBusyCursor();
1829     }
1830 }
1831 
UpdateXmlDocumentPage()1832 void BlobExplorerDialog::UpdateXmlDocumentPage()
1833 {
1834 //
1835 // updating the XmlDocument page
1836 //
1837   wxTextCtrl *xmlCtrl = (wxTextCtrl *) FindWindow(ID_XML_DOCUMENT_TABLE);
1838   xmlCtrl->WriteText(XMLDocument);
1839 }
1840 
UpdateXmlIndentedPage()1841 void BlobExplorerDialog::UpdateXmlIndentedPage()
1842 {
1843 //
1844 // updating the XmlIndented page
1845 //
1846   wxTextCtrl *xmlCtrl = (wxTextCtrl *) FindWindow(ID_XML_INDENTED_TABLE);
1847   xmlCtrl->WriteText(XMLIndented);
1848 }
1849 
OnOk(wxCommandEvent & WXUNUSED (event))1850 void BlobExplorerDialog::OnOk(wxCommandEvent & WXUNUSED(event))
1851 {
1852 //
1853 // all done: exiting
1854 //
1855   wxDialog::EndModal(wxID_OK);
1856 }
1857 
DrawGeometry(int horz,int vert)1858 void BlobExplorerDialog::DrawGeometry(int horz, int vert)
1859 {
1860 //
1861 // drawing graphic representation for current Geometry
1862 //
1863   gaiaPointPtr pt;
1864   gaiaLinestringPtr ln;
1865   gaiaPolygonPtr pg;
1866   gaiaRingPtr rng;
1867   double minx;
1868   double miny;
1869   double maxx;
1870   double maxy;
1871   double ext_x;
1872   double ext_y;
1873   double cx;
1874   double cy;
1875   double pixelRatioX;
1876   double pixelRatioY;
1877   double pixelRatio;
1878   double span_x;
1879   double span_y;
1880   double baseX;
1881   double baseY;
1882   double x;
1883   double y;
1884   double z;
1885   double m;
1886   double xx;
1887   double yy;
1888   int iv;
1889   int ib;
1890   int pts;
1891   int *borders;
1892   wxPoint *points;
1893   GeomPreview.Create(horz, vert);
1894   wxMemoryDC dc(GeomPreview);
1895 //
1896 // background filling
1897 //
1898   dc.SetBrush(wxBrush(wxColour(255, 255, 255)));
1899   dc.DrawRectangle(0, 0, horz, vert);
1900 //
1901 // prepearing the drawing pen and brush
1902 //
1903   dc.SetBrush(wxBrush(wxColour(240, 240, 192)));
1904   dc.SetPen(wxPen(wxColour(64, 64, 192), 1));
1905 //
1906 // computing the pixel ratio, center position and so on
1907 //
1908   minx = Geometry->MinX;
1909   miny = Geometry->MinY;
1910   maxx = Geometry->MaxX;
1911   maxy = Geometry->MaxY;
1912   ext_x = maxx - minx;
1913   ext_y = maxy - miny;
1914   minx = Geometry->MinX - (ext_x / 20.0);
1915   miny = Geometry->MinY - (ext_y / 20.0);
1916   maxx = Geometry->MaxX + (ext_x / 20.0);
1917   maxy = Geometry->MaxY + (ext_y / 20.0);
1918   ext_x = maxx - minx;
1919   ext_y = maxy - miny;
1920   cx = minx + (ext_x / 2.0);
1921   cy = miny + (ext_y / 2.0);
1922   pixelRatioX = ext_x / horz;
1923   pixelRatioY = ext_y / vert;
1924   if (pixelRatioX > pixelRatioY)
1925     pixelRatio = pixelRatioX;
1926   else
1927     pixelRatio = pixelRatioY;
1928 //
1929 // centering the Y axis
1930 //
1931   span_y = vert * pixelRatio;
1932   baseY = cy - (span_y / 2.0);
1933 //
1934 // centering the X axis
1935 //
1936   span_x = horz * pixelRatio;
1937   baseX = cx - (span_x / 2.0);
1938   pg = Geometry->FirstPolygon;
1939   while (pg)
1940     {
1941       //
1942       // drawing polygons
1943       //
1944       pts = pg->Exterior->Points;
1945       for (ib = 0; ib < pg->NumInteriors; ib++)
1946         {
1947           rng = pg->Interiors + ib;
1948           pts += rng->Points;
1949         }
1950       borders = new int[pg->NumInteriors + 1];
1951       points = new wxPoint[pts];
1952       pts = 0;
1953       rng = pg->Exterior;
1954       borders[0] = rng->Points;
1955       for (iv = 0; iv < rng->Points; iv++)
1956         {
1957           if (rng->DimensionModel == GAIA_XY_Z)
1958             {
1959               gaiaGetPointXYZ(rng->Coords, iv, &x, &y, &z);
1960           } else if (rng->DimensionModel == GAIA_XY_M)
1961             {
1962               gaiaGetPointXYM(rng->Coords, iv, &x, &y, &m);
1963           } else if (rng->DimensionModel == GAIA_XY_Z_M)
1964             {
1965               gaiaGetPointXYZM(rng->Coords, iv, &x, &y, &z, &m);
1966           } else
1967             {
1968               gaiaGetPoint(rng->Coords, iv, &x, &y);
1969             }
1970           xx = (x - baseX) / pixelRatio;
1971           yy = (y - baseY) / pixelRatio;
1972           yy = vert - yy;
1973           points[pts].x = (int) xx;
1974           points[pts].y = (int) yy;
1975           pts++;
1976         }
1977       for (ib = 0; ib < pg->NumInteriors; ib++)
1978         {
1979           rng = pg->Interiors + ib;
1980           borders[1 + ib] = rng->Points;
1981           for (iv = 0; iv < rng->Points; iv++)
1982             {
1983               if (rng->DimensionModel == GAIA_XY_Z)
1984                 {
1985                   gaiaGetPointXYZ(rng->Coords, iv, &x, &y, &z);
1986               } else if (rng->DimensionModel == GAIA_XY_M)
1987                 {
1988                   gaiaGetPointXYM(rng->Coords, iv, &x, &y, &m);
1989               } else if (rng->DimensionModel == GAIA_XY_Z_M)
1990                 {
1991                   gaiaGetPointXYZM(rng->Coords, iv, &x, &y, &z, &m);
1992               } else
1993                 {
1994                   gaiaGetPoint(rng->Coords, iv, &x, &y);
1995                 }
1996               xx = (x - baseX) / pixelRatio;
1997               yy = (y - baseY) / pixelRatio;
1998               yy = vert - yy;
1999               points[pts].x = (int) xx;
2000               points[pts].y = (int) yy;
2001               pts++;
2002             }
2003         }
2004       dc.DrawPolyPolygon(pg->NumInteriors + 1, borders, points);
2005       delete[]points;
2006       delete[]borders;
2007       pg = pg->Next;
2008     }
2009   ln = Geometry->FirstLinestring;
2010   while (ln)
2011     {
2012       //
2013       // drawing linestrings
2014       //
2015       points = new wxPoint[ln->Points];
2016       for (iv = 0; iv < ln->Points; iv++)
2017         {
2018           if (ln->DimensionModel == GAIA_XY_Z)
2019             {
2020               gaiaGetPointXYZ(ln->Coords, iv, &x, &y, &z);
2021           } else if (ln->DimensionModel == GAIA_XY_M)
2022             {
2023               gaiaGetPointXYM(ln->Coords, iv, &x, &y, &m);
2024           } else if (ln->DimensionModel == GAIA_XY_Z_M)
2025             {
2026               gaiaGetPointXYZM(ln->Coords, iv, &x, &y, &z, &m);
2027           } else
2028             {
2029               gaiaGetPoint(ln->Coords, iv, &x, &y);
2030             }
2031           xx = (x - baseX) / pixelRatio;
2032           yy = (y - baseY) / pixelRatio;
2033           yy = vert - yy;
2034           points[iv].x = (int) xx;
2035           points[iv].y = (int) yy;
2036         }
2037       dc.DrawLines(ln->Points, points);
2038       delete[]points;
2039       ln = ln->Next;
2040     }
2041   pt = Geometry->FirstPoint;
2042   while (pt)
2043     {
2044       //
2045       // drawing points
2046       //
2047       xx = (pt->X - baseX) / pixelRatio;
2048       yy = (pt->Y - baseY) / pixelRatio;
2049       yy = vert - yy;
2050       dc.DrawCircle((int) xx, (int) yy, 2);
2051       pt = pt->Next;
2052     }
2053 }
2054 
GraphicsGeometry(BlobExplorerDialog * parent,wxWindow * panel,wxWindowID id,const wxBitmap & bmp,const wxSize & size)2055 GraphicsGeometry::GraphicsGeometry(BlobExplorerDialog * parent,
2056                                    wxWindow * panel, wxWindowID id,
2057                                    const wxBitmap & bmp,
2058                                    const wxSize & size):wxStaticBitmap(panel,
2059                                                                        id, bmp,
2060                                                                        wxDefaultPosition,
2061                                                                        size)
2062 {
2063   Parent = parent;
2064 }
2065 
ImageShow(BlobExplorerDialog * parent,wxWindow * panel,wxWindowID id,const wxBitmap & bmp,const wxSize & size)2066 ImageShow::ImageShow(BlobExplorerDialog * parent, wxWindow * panel,
2067                      wxWindowID id, const wxBitmap & bmp,
2068                      const wxSize & size):wxStaticBitmap(panel, id, bmp,
2069                                                          wxDefaultPosition,
2070                                                          size, wxBORDER_SIMPLE)
2071 {
2072   Parent = parent;
2073 // appends event handler
2074   Connect(ID_IMAGE, wxEVT_RIGHT_DOWN,
2075           (wxObjectEventFunction) & ImageShow::OnRightClick);
2076   Connect(Image_Copy, wxEVT_COMMAND_MENU_SELECTED,
2077           (wxObjectEventFunction) & ImageShow::OnCmdCopy);
2078 }
2079 
OnRightClick(wxMouseEvent & event)2080 void ImageShow::OnRightClick(wxMouseEvent & event)
2081 {
2082 //
2083 // right click on the Image
2084 //
2085   wxMenu *menu = new wxMenu();
2086   wxMenuItem *menuItem;
2087   wxImage *Image = Parent->GetImage();
2088   if (Image)
2089     {
2090       if (Image->IsOk() == true)
2091         {
2092           wxPoint pt = event.GetPosition();
2093           menuItem = new wxMenuItem(menu, Image_Copy, wxT("&Copy"));
2094           menu->Append(menuItem);
2095           PopupMenu(menu, pt);
2096         }
2097     }
2098 }
2099 
OnCmdCopy(wxCommandEvent & WXUNUSED (event))2100 void ImageShow::OnCmdCopy(wxCommandEvent & WXUNUSED(event))
2101 {
2102 //
2103 // copying the Image into the clipboard
2104 //
2105   wxImage *Image = Parent->GetImage();
2106   if (wxTheClipboard->Open())
2107     {
2108       wxTheClipboard->SetData(new wxBitmapDataObject(*Image));
2109       wxTheClipboard->Close();
2110     }
2111 }
2112 
MyHexList(BlobExplorerDialog * parent,unsigned char * blob,int blob_size,wxWindow * panel,wxWindowID id,const wxPoint & pos,const wxSize & size,long style)2113 MyHexList::MyHexList(BlobExplorerDialog * parent, unsigned char *blob,
2114                      int blob_size, wxWindow * panel, wxWindowID id,
2115                      const wxPoint & pos, const wxSize & size,
2116                      long style):wxListCtrl(panel, id, pos, size, style)
2117 {
2118 // constructor - the blob hexadecimal dump
2119   int i = 0;
2120   int rows = 0;
2121   Parent = parent;
2122   Blob = blob;
2123   BlobSize = blob_size;
2124   while (i < BlobSize)
2125     {
2126       // counting how many rows are there
2127       rows++;
2128       i += 16;
2129     }
2130   SetItemCount(rows);
2131 }
2132 
~MyHexList()2133 MyHexList::~MyHexList()
2134 {
2135 // does nothing
2136 }
2137 
OnGetItemText(long item,long column) const2138 wxString MyHexList::OnGetItemText(long item, long column) const
2139 {
2140 // return a column value
2141   int i;
2142   int c;
2143   int base = item * 16;
2144   wxString value;
2145   char dummy[64];
2146   wxString hex;
2147   if (column == 0)
2148     {
2149       sprintf(dummy, "%08xd", base);
2150       value = wxString::FromUTF8(dummy);
2151   } else if (column == 1)
2152     {
2153       // prepearing the hex-dump
2154       c = 0;
2155       for (i = base; i < BlobSize; i++)
2156         {
2157           if (c >= 16)
2158             break;
2159           sprintf(dummy, "%02x", *(Blob + i));
2160           hex = wxString::FromUTF8(dummy);
2161           if (c == 8)
2162             value += wxT("   ");
2163           else
2164             value += wxT(" ");
2165           value += hex;
2166           c++;
2167         }
2168   } else
2169     {
2170       // prepearing the ascii dump
2171       c = 0;
2172       for (i = base; i < BlobSize; i++)
2173         {
2174           if (c >= 16)
2175             break;
2176           if (isprint(*(Blob + i)))
2177             {
2178               sprintf(dummy, "%c", *(Blob + i));
2179               hex = wxString::FromUTF8(dummy);
2180           } else
2181             hex = wxT(".");
2182           value += hex;
2183           c++;
2184         }
2185     }
2186   return value;
2187 }
2188