ogr_converter-plugin-mloskot.patch

Patch with source code of OGR Layer Converter plugin (cmake configuration included) - Mateusz Loskot -, 2008-08-26 04:28 PM

Download (56.4 KB)

View differences:

qgis/src/plugins/CMakeLists.txt (working copy)
22 22

  
23 23

  
24 24
SUBDIRS (coordinate_capture dxf2shp_converter) 
25

  
26
SUBDIRS (ogr_converter)
qgis/src/plugins/ogr_converter/plugin.cpp (revision 0)
1
// $Id$
2
//////////////////////////////////////////////////////////////////////////////
3
//
4
// begin                : Aug 24, 2008
5
// copyright            : (C) 2008 by Mateusz Loskot
6
// email                : [email protected]
7
//
8
//////////////////////////////////////////////////////////////////////////////
9
//
10
// This program is free software; you can redistribute it and/or modify
11
// it under the terms of the GNU General Public License as published by
12
// the Free Software Foundation; either version 2 of the License,
13
// or (at your option) any later version.
14
//
15
//////////////////////////////////////////////////////////////////////////////
16

  
17
// qgis::plugin::ogrconv
18
#include "plugin.h"
19
#include "dialog.h"
20
// QGIS
21
#include <qgisinterface.h>
22
#include <qgisgui.h>
23
#include <qgslogger.h>
24
// Qt
25
#include <QAction>
26
#include <QToolBar>
27
// std
28
#include <cassert>
29

  
30
namespace qgis { namespace plugin { namespace ogrconv {
31

  
32
// GDAL/OGR loaded into private namesapce
33
#include <ogr_api.h>
34

  
35
static const char * const sIdent = "$Id$";
36
static const QString sName = QObject::tr("OGR Layer Converter");
37
static const QString sDescription = QObject::tr("Translates vector layers between formats supported by OGR library");
38
static const QString sPluginVersion = QObject::tr("Version 0.1");
39
static const QgisPlugin::PLUGINTYPE sPluginType = QgisPlugin::UI;
40

  
41
//////////////////////////////////////////////////////////////////////////////
42
// THE FOLLOWING METHODS ARE MANDATORY FOR ALL PLUGINS
43
//////////////////////////////////////////////////////////////////////////////
44

  
45
OgrPlugin::OgrPlugin(QgisInterface * theQgisInterface) :
46
    QgisPlugin(sName, sDescription, sPluginVersion, sPluginType),
47
    mQGisIface(theQgisInterface),
48
    mQActionPointer(0)
49
{
50
    assert(0 != mQGisIface);
51
}
52

  
53
OgrPlugin::~OgrPlugin()
54
{
55
}
56

  
57
void OgrPlugin::initGui()
58
{
59
    // Create the action for tool
60
    mQActionPointer = new QAction(QIcon(":/ogrconverter/ogrconverter.png"), tr("Run OGR Layer Converter"), this);
61

  
62
    // Set the what's this text
63
    mQActionPointer->setWhatsThis(tr("Replace this with a short description of the what the plugin does"));
64

  
65
    // Connect the action to the run
66
    connect(mQActionPointer, SIGNAL(triggered()), this, SLOT(run()));
67

  
68
    // Add the icon to the toolbar
69
    mQGisIface->addToolBarIcon(mQActionPointer);
70
    mQGisIface->addPluginMenu(tr("OG&R Converter"), mQActionPointer);
71
}
72

  
73
//method defined in interface
74
void OgrPlugin::help()
75
{
76
    //implement me!
77
}
78

  
79
void OgrPlugin::run()
80
{
81
    assert(0 != mQGisIface);
82

  
83
    Dialog* ogrDialog = new Dialog(mQGisIface->getMainWindow(), QgisGui::ModalDialogFlags);
84
    ogrDialog->setAttribute(Qt::WA_DeleteOnClose);
85
    ogrDialog->show();
86
}
87

  
88
void OgrPlugin::unload()
89
{
90
    assert(0 != mQGisIface);
91

  
92
    // TODO: Who is responsible for OGR cleanup?
93
    //OGRCleanupAll();
94

  
95
    // remove the GUI
96
    mQGisIface->removePluginMenu("&OGR Layer Converter", mQActionPointer);
97
    mQGisIface->removeToolBarIcon(mQActionPointer);
98
    delete mQActionPointer;
99
}
100

  
101
/////////////////////////////////////////////////////////////////////////////
102
//  THE FOLLOWING CODE IS AUTOGENERATED BY THE PLUGIN BUILDER SCRIPT
103
//    YOU WOULD NORMALLY NOT NEED TO MODIFY THIS, AND YOUR PLUGIN
104
//      MAY NOT WORK PROPERLY IF YOU MODIFY THIS INCORRECTLY
105
/////////////////////////////////////////////////////////////////////////////
106

  
107
// Required extern functions needed  for every plugin
108
// These functions can be called prior to creating an instance 
109
// of the plugin class.
110

  
111
// Class factory to return a new instance of the plugin class
112
QGISEXTERN QgisPlugin * classFactory(QgisInterface * theQgisInterfacePointer)
113
{
114
  return new OgrPlugin(theQgisInterfacePointer);
115
}
116

  
117
// Return the name of the plugin - note that we do not user class members as
118
// the class may not yet be insantiated when this method is called.
119
QGISEXTERN QString name()
120
{
121
  return sName;
122
}
123

  
124
// Return the description
125
QGISEXTERN QString description()
126
{
127
  return sDescription;
128
}
129

  
130
// Return the type (either UI or MapLayer plugin)
131
QGISEXTERN int type()
132
{
133
  return sPluginType;
134
}
135

  
136
// Return the version number for the plugin
137
QGISEXTERN QString version()
138
{
139
  return sPluginVersion;
140
}
141

  
142
// Delete ourself
143
QGISEXTERN void unload(QgisPlugin * thePluginPointer)
144
{
145
  delete thePluginPointer;
146
}
147

  
148
}}} // namespace qgis::plugin::ogrconv
149

  
qgis/src/plugins/ogr_converter/translator.h (revision 0)
1
// $Id$
2
//////////////////////////////////////////////////////////////////////////////
3
//
4
// Copyright (C) 2008 by Mateusz Loskot <[email protected]>
5
//
6
// This program is free software; you can redistribute it and/or modify
7
// it under the terms of the GNU General Public License as published by
8
// the Free Software Foundation; either version 2 of the License,
9
// or (at your option) any later version.
10
//
11
//////////////////////////////////////////////////////////////////////////////
12
#ifndef QGIS_PLUGIN_OGRCONV_TRANSLATOR_H_INCLUDED
13
#define QGIS_PLUGIN_OGRCONV_TRANSLATOR_H_INCLUDED 
14

  
15
// Qt4
16
#include <QString>
17

  
18
namespace qgis { namespace plugin { namespace ogrconv {
19

  
20
// GDAL/OGR loaded into private namespace
21
#include <ogr_api.h>
22

  
23
class Translator
24
{
25
public:
26

  
27
    Translator();
28
    Translator(QString const& src, QString const& dst, QString const& format);
29

  
30
    QString const& targetFormat() const;
31
    void setTargetFormat(QString const& format);
32

  
33
    QString const& targetLayer() const;
34
    void setTargetLayer(QString const& layer);
35

  
36
    QString const& sourceLayer() const;
37
    void setSourceLayer(QString const& layer);
38

  
39
    QString const& targetReferenceSystem() const;
40
    void setTargetReferenceSystem(QString const& srs);
41

  
42
    QString const& sourceReferenceSystem() const;
43
    void setSourceReferenceSystem(QString const& srs);
44

  
45
    bool isTargetUpdate() const;
46
    void setUpdateTarget(bool update);
47

  
48
    bool isTargetLayerOverwrite() const;
49
    // TODO: Implement, currently always overwrite
50
    // void setTargetLayerOverwrite(bool overwrite);
51

  
52
    bool translate();
53

  
54
private:
55

  
56
    QString mSrcUrl;
57
    QString mDstUrl;
58
    QString mDstFormat;
59
    QString mSrcLayer;
60
    QString mDstLayer;
61
    QString mSrcSrs;
62
    QString mDstSrs;
63
    bool mDstUpdate;
64
    bool mDstLayerOverwrite;
65
    // TODO: Append option not supported
66
    // bool mDstLayerAppend;
67

  
68
    bool translateLayer(OGRDataSourceH srcDs, OGRLayerH srcLayer, OGRDataSourceH dstDs);
69
    bool copyFields(OGRFeatureDefnH layerDefn, OGRLayerH layer);
70
    bool copyFeatures(OGRLayerH srcLayer, OGRLayerH dstLayer);
71

  
72
    OGRSFDriverH findDriver(QString const& name);
73
    OGRLayerH findLayer(OGRDataSourceH ds, QString const& name, int& index);
74
    OGRDataSourceH openDataSource(QString const& url, bool readOnly);
75
    OGRDataSourceH openDataTarget(QString const& url, bool update);
76

  
77
};
78

  
79
}}} // namespace qgis::plugin::ogrconv
80

  
81
#endif // QGIS_PLUGIN_OGRCONV_TRANSLATOR_H_INCLUDED
qgis/src/plugins/ogr_converter/dialog.cpp (revision 0)
1
// $Id$
2
//////////////////////////////////////////////////////////////////////////////
3
//
4
// Copyright (C) 2008 by Mateusz Loskot <[email protected]>
5
//
6
// This program is free software; you can redistribute it and/or modify
7
// it under the terms of the GNU General Public License as published by
8
// the Free Software Foundation; either version 2 of the License,
9
// or (at your option) any later version.
10
//
11
//////////////////////////////////////////////////////////////////////////////
12

  
13
// qgis::plugin::ogrconv
14
#include "dialog.h"
15
#include "format.h"
16
#include "translator.h"
17
// QGIS includes
18
#include <qgslogger.h>
19
#include <qgscontexthelp.h>
20
// TODO: Add support of QGIS projection selector 
21
//#include <qgsprojectionselector.h>
22
// Qt4
23
#include <QtAlgorithms>
24
#include <QtDebug>
25
#include <QFileDialog>
26
#include <QMessageBox>
27
#include <QSettings>
28
#include <QString>
29
#include <QStringList>
30
#include <QVariant>
31

  
32
namespace qgis { namespace plugin { namespace ogrconv {
33

  
34
// GDAL/OGR loaded into private namespace
35
#include <ogr_api.h>
36
#include <ogrsf_frmts.h>
37

  
38
Dialog::Dialog(QWidget* parent, Qt::WFlags fl)
39
    : QDialog(parent, fl)
40
{
41
    setupUi(this);
42
    populateFormats();
43
    resetSrcUi();
44
    resetDstUi();
45
}
46

  
47
Dialog::~Dialog()
48
{
49
}
50

  
51
void Dialog::resetSrcUi()
52
{
53
    // Clear all settings and states
54
    inputSrcDataset->clear();
55
    // TODO: Transformation support
56
    //inputSrcSrs->clear();
57
    comboSrcLayer->clear();
58
    radioSrcFile->setDisabled(true);
59
    radioSrcFile->setChecked(false);
60
    radioSrcDirectory->setDisabled(true);
61
    radioSrcDirectory->setChecked(false);
62
    radioSrcProtocol->setDisabled(true);
63
    radioSrcProtocol->setChecked(false);
64

  
65
    // Configure types of input sources
66
    unsigned char const& type = mSrcFormat.type();
67

  
68
    if (isFormatType(type, Format::eFile))
69
    {
70
        radioSrcFile->setDisabled(false);
71
        radioSrcFile->setChecked(true);
72
    }
73

  
74
    if (isFormatType(type, Format::eDirectory))
75
    {
76
        radioSrcDirectory->setDisabled(false);
77
        if (!radioSrcFile->isEnabled())
78
            radioSrcDirectory->setChecked(true);
79
    }
80

  
81
    if (isFormatType(type, Format::eProtocol))
82
    {
83
        radioSrcProtocol->setDisabled(false);
84

  
85
        if (!radioSrcFile->isEnabled() && !radioSrcDirectory->isEnabled())
86
        {
87
            radioSrcProtocol->setChecked(true);
88
            inputSrcDataset->setText(mSrcFormat.protocol());
89
        }
90
    }
91

  
92
    setButtonState(buttonSelectSrc, isFormatType(type, Format::eProtocol));
93
}
94

  
95
void Dialog::resetDstUi()
96
{
97
    inputDstDataset->clear();
98
    // TODO: Transformation support
99
    //inputDstSrs->clear();
100
    
101
    unsigned char const& type = mDstFormat.type();
102
    bool isProtocol = isFormatType(type, Format::eProtocol);
103

  
104
    if (isProtocol)
105
    {
106
        inputDstDataset->setText(mDstFormat.protocol());
107
    }
108
    
109
    setButtonState(buttonSelectDst, isProtocol);
110
}
111

  
112
void Dialog::setButtonState(QPushButton* btn, bool isProtocol)
113
{
114
    Q_CHECK_PTR(btn);
115

  
116
    if (isProtocol)
117
    {
118
        btn->setText(tr("Connect"));
119
    }
120
    else
121
    {
122
        btn->setText(tr("Browse"));
123
    }
124
}
125

  
126
void Dialog::populateFormats()
127
{
128
    comboSrcFormats->clear();
129
    comboDstFormats->clear();
130
    
131
    QStringList drvSrcList;
132
    QStringList drvDstList;
133
    QString drvName;
134

  
135
    if (0 >= OGRGetDriverCount())
136
    {
137
        OGRRegisterAll(); 
138
    }
139
    int const drvCount = OGRGetDriverCount();
140

  
141
    for (int i = 0; i < drvCount; ++i)
142
    {
143
        OGRSFDriverH drv = OGRGetDriver(i);
144
        Q_CHECK_PTR(drv);
145
        if (0 != drv)
146
        {
147
            drvName = OGR_Dr_GetName(drv);
148
            drvSrcList.append(drvName);
149

  
150
            if (0 != OGR_Dr_TestCapability(drv, ODrCCreateDataSource))
151
            {
152
                drvDstList.append(drvName);
153
            }
154
        }
155
    }
156

  
157
    qSort(drvSrcList.begin(), drvSrcList.end());
158
    qSort(drvDstList.begin(), drvDstList.end());
159
    comboSrcFormats->addItems(drvSrcList);
160
    comboDstFormats->addItems(drvDstList);
161
}
162

  
163
void Dialog::populateLayers(QString const& url)
164
{
165
    comboSrcLayer->clear();
166

  
167
    OGRDataSourceH ds = OGROpen(url.toAscii().constData(), 0, 0);
168
    if (0 != ds)
169
    {
170
        QString lyrName;
171
        QString lyrType;
172

  
173
        int const size = OGR_DS_GetLayerCount(ds);
174
        for (int i = 0; i < size; ++i)
175
        {
176
            OGRLayerH lyr = OGR_DS_GetLayer(ds, i);
177
            if (0 != lyr)
178
            {
179
                OGRFeatureDefnH lyrDef = OGR_L_GetLayerDefn(lyr);
180
                assert(0 != lyrDef);
181
                
182
                lyrName = OGR_FD_GetName(lyrDef);
183
                
184
                OGRwkbGeometryType const geomType = OGR_FD_GetGeomType(lyrDef);
185
                lyrType = OGRGeometryTypeToName(geomType);
186

  
187
                // FIXME: Appending type to layer name prevents from layer finding
188
                //comboSrcLayer->addItem(lyrName + " (" + lyrType.toUpper() + ")");
189
                comboSrcLayer->addItem(lyrName);
190
            }
191
        }
192

  
193
        OGR_DS_Destroy(ds);
194
    }
195
    else
196
    {
197
        QMessageBox::warning(this,
198
                tr("OGR Converter"),
199
                tr("Could not establish connection to: '") + url + "'",
200
                QMessageBox::Close);
201
    }
202
}
203

  
204
bool Dialog::testConnection(QString const& url)
205
{
206
    bool success = false;
207

  
208
    OGRDataSourceH ds = OGROpen(url.toAscii().constData(), 0, 0);
209
    if (0 != ds)
210
    {
211
        success = true;
212
        OGR_DS_Destroy(ds);
213
    }
214

  
215
    return success;
216
}
217

  
218
QString Dialog::openFile()
219
{
220
    QSettings sets;
221
    QString path = QFileDialog::getOpenFileName(this,
222
            tr("Open OGR file"),
223
            sets.value("/Plugin-OGR/ogr-file", "./").toString(),
224
            tr("OGR File Data Source (*.*)"));
225

  
226
    return path;
227
}
228

  
229
QString Dialog::openDirectory()
230
{
231
    QString path = QFileDialog::getExistingDirectory(this,
232
            tr("Open Directory"), "",
233
            QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
234
    
235
    return path;
236
}
237

  
238
void Dialog::on_buttonBox_accepted()
239
{
240
    // Validate input settings
241
    QString srcUrl(inputSrcDataset->text());
242
    QString srcLayer(comboSrcLayer->currentText());
243

  
244
    if (srcUrl.isEmpty())
245
    {
246
        QMessageBox::warning(this, "OGR Layer Converter",
247
                tr("Input OGR dataset is missing!"));
248
        return;
249
    }
250
   
251
    if (srcLayer.isEmpty())
252
    {
253
        QMessageBox::warning(this, "OGR Layer Converter",
254
                tr("Input OGR layer name is missing!"));
255
        return;
256
    }
257

  
258
    // Validate output settings
259
    QString dstFormat(comboDstFormats->currentText());
260
    QString dstUrl(inputDstDataset->text());
261
    QString dstLayer(inputDstLayer->text());
262
    if (dstLayer.isEmpty())
263
        dstLayer = srcLayer;
264
    
265
    if (dstFormat.isEmpty())
266
    {
267
        QMessageBox::warning(this, "OGR Layer Converter",
268
                tr("Target OGR format not selected!"));
269
        return;
270
    }
271
 
272
    if (dstUrl.isEmpty())
273
    {
274
        QMessageBox::warning(this, "OGR Layer Converter",
275
                tr("Output OGR dataset is missing!"));
276
        return;
277
    }
278

  
279
    if (dstLayer.isEmpty())
280
    {
281
        QMessageBox::warning(this, "OGR Layer Converter",
282
                tr("Output OGR layer name is missing!"));
283
        return;
284
    }
285

  
286
    // TODO: SRS transformation support
287
    //QString srcSrs("EPSG:");
288
    //QString dstSrs("EPSG:");
289
    //srcSrs += inputSrcSrs->text();
290
    //dstSrs += inputDstSrs->text();
291

  
292
    // Execute layer translation
293
    bool success = false;
294
    
295
    // TODO: Use try-catch to display more meaningful error messages from Translator
296
    Translator worker(srcUrl, dstUrl, dstFormat);
297
    worker.setSourceLayer(srcLayer);
298
    worker.setTargetLayer(dstLayer);
299
    success = worker.translate();
300

  
301
    if (success)
302
    {
303
        QMessageBox::information(this, "OGR Layer Converter",
304
                tr("Successfully translated layer '") + srcLayer + "'");
305
    }
306
    else
307
    {
308
        QMessageBox::information(this, "OGR Layer Converter",
309
                tr("Failed to translate layer '") + srcLayer + "'");
310
    }
311

  
312
    // Close dialog box
313
    accept();
314
}
315

  
316
void Dialog::on_buttonBox_rejected()
317
{
318
    reject();
319
}
320

  
321
void Dialog::on_buttonBox_helpRequested()
322
{
323
    QgsContextHelp::run(context_id);
324
}
325

  
326
void Dialog::on_radioSrcFile_toggled(bool checked)
327
{
328
    if (checked)
329
    {
330
        unsigned char const& type = mSrcFormat.type();
331
        Q_ASSERT(isFormatType(type, Format::eFile));
332

  
333
        inputSrcDataset->clear();
334
        setButtonState(buttonSelectSrc, isFormatType(type, Format::eProtocol));
335
    }
336
}
337

  
338
void Dialog::on_radioSrcDirectory_toggled(bool checked)
339
{
340
    if (checked)
341
    {
342
        unsigned char const& type = mSrcFormat.type();
343
        Q_ASSERT(isFormatType(type, Format::eDirectory));
344

  
345
        inputSrcDataset->clear();
346
        setButtonState(buttonSelectSrc, isFormatType(type, Format::eProtocol));
347
    }
348
}
349

  
350
void Dialog::on_radioSrcProtocol_toggled(bool checked)
351
{
352
    if (checked)
353
    {
354
        unsigned char const& type = mSrcFormat.type();
355
        Q_ASSERT(isFormatType(type, Format::eProtocol));
356

  
357
        inputSrcDataset->setText(mSrcFormat.protocol());
358
        setButtonState(buttonSelectSrc, isFormatType(type, Format::eProtocol));
359
    }
360
}
361

  
362
void Dialog::on_comboSrcFormats_currentIndexChanged(int index)
363
{
364
    // Select source data format
365
    QString frmtCode = comboSrcFormats->currentText(); 
366
    mSrcFormat = mFrmts.find(frmtCode);
367
    
368
    resetSrcUi();
369
}
370

  
371
void Dialog::on_comboDstFormats_currentIndexChanged(int index)
372
{
373
    // Select destination data format
374
    QString frmtCode = comboDstFormats->currentText(); 
375
    mDstFormat = mFrmts.find(frmtCode);
376

  
377
    resetDstUi();
378
}
379

  
380
void Dialog::on_buttonSelectSrc_clicked()
381
{
382
    QSettings settings;
383
    QString src;
384
    
385
    if (radioSrcFile->isChecked())
386
    {
387
        src = openFile();
388
    }
389
    else if (radioSrcDirectory->isChecked())
390
    {
391
        src = openDirectory();
392
    }
393
    else if (radioSrcProtocol->isChecked())
394
    {
395
        src = inputSrcDataset->text();
396
    }
397
    else
398
    {
399
        Q_ASSERT(!"SHOULD NEVER GET HERE");
400
    }
401

  
402
    inputSrcDataset->setText(src);
403

  
404
    if (!src.isEmpty())
405
    {
406
        populateLayers(src);
407
    }
408
}
409

  
410
void Dialog::on_buttonSelectDst_clicked()
411
{
412
    QSettings settings;
413
    QString dst;
414
    QString msg;
415

  
416
    unsigned char const& type = mDstFormat.type();
417
    if (isFormatType(type, Format::eProtocol))
418
    {
419
        dst = inputDstDataset->text();
420

  
421
        if (testConnection(dst))
422
        {
423
            msg = tr("Successfully connected to: '") + dst + "'";
424
        }
425
        else
426
        {
427
            msg = tr("Could not establish connection to: '") + dst + "'";
428
        }
429
        
430
        QMessageBox::information(this, tr("OGR Converter"),
431
                msg, QMessageBox::Close);
432
    }
433
    else if (isFormatType(type, Format::eDirectory))
434
    {
435
        dst = openDirectory();
436
    }
437
    else if (isFormatType(type, Format::eFile))
438
    {
439
        dst = QFileDialog::getSaveFileName(this,
440
                tr("Choose a file name to save to"),
441
                "output", tr("OGR File Data Source (*.*)"));
442
    }
443
    else
444
    {
445
        Q_ASSERT(!"SHOULD NEVER GET HERE");
446
    }
447

  
448
    inputDstDataset->setText(dst);
449
}
450

  
451

  
452
}}} // namespace qgis::plugin::ogrconv
453

  
qgis/src/plugins/ogr_converter/ogrconverter.qrc (revision 0)
1
<RCC>
2
    <qresource prefix="/ogrconverter/" >
3
        <file>ogrconverter.png</file>
4
    </qresource>
5
</RCC>
qgis/src/plugins/ogr_converter/plugin.h (revision 0)
1
// $Id$
2
//////////////////////////////////////////////////////////////////////////////
3
//
4
// begin                : Aug 24, 2008
5
// copyright            : (C) 2008 by Mateusz Loskot
6
// email                : [email protected]
7
//
8
//////////////////////////////////////////////////////////////////////////////
9
//
10
// This program is free software; you can redistribute it and/or modify
11
// it under the terms of the GNU General Public License as published by
12
// the Free Software Foundation; either version 2 of the License,
13
// or (at your option) any later version.
14
//
15
//////////////////////////////////////////////////////////////////////////////
16
#ifndef QGIS_PLUGIN_OGRCONV_PLUGIN_H_INCLUDED
17
#define QGIS_PLUGIN_OGRCONV_PLUGIN_H_INCLUDED
18

  
19
// QGIS
20
#include "../qgisplugin.h"
21
// Qt4
22
#include <QObject>
23

  
24
// Forward declarations
25
class QAction;
26
class QToolBar;
27
class QgisInterface;
28

  
29
namespace qgis { namespace plugin { namespace ogrconv {
30

  
31
/**
32
* \class OgrPlugin
33
* \brief Translates vector layers between formats supported by OGR library.
34
*/
35
class OgrPlugin : public QObject, public QgisPlugin
36
{
37
    Q_OBJECT
38

  
39
public:
40

  
41
    //////////////////////////////////////////////////////////////////////////
42
    //                MANDATORY PLUGIN METHODS FOLLOW
43
    //////////////////////////////////////////////////////////////////////////
44

  
45
    /**
46
    * Constructor for a plugin. The QgisInterface pointer is passed by
47
    * QGIS when it attempts to instantiate the plugin.
48
    * @param theInterface Pointer to the QgisInterface object.
49
    */
50
    OgrPlugin(QgisInterface * theInterface);
51

  
52
    //! Destructor
53
    virtual ~OgrPlugin();
54

  
55
public slots:
56

  
57
   /**
58
    * Initialize the GUI interface for the plugin.
59
    * This is only called once when the plugin is added to the plugin
60
    * registry in the QGIS application.
61
    */
62
    virtual void initGui();
63

  
64
    /**
65
     * Slot called when the menu item is triggered.
66
     * If you created more menu items / toolbar buttons in initiGui,
67
     * you should create a separate handler for each action - this
68
     * single run() method will not be enough.
69
     */
70
    void run();
71

  
72
    /**
73
     * Unload the plugin by cleaning up the GUI.
74
     */
75
    void unload();
76

  
77
    //! show the help document
78
    void help();
79

  
80
private:
81

  
82
    //////////////////////////////////////////////////////////////////////////
83
    // MANDATORY PLUGIN PROPERTY DECLARATIONS
84
    //////////////////////////////////////////////////////////////////////////
85

  
86
    // FIXME: Is it used at all?
87
    int mPluginType;
88

  
89
    //! Pointer to the QGIS interface object
90
    QgisInterface *mQGisIface;
91

  
92
    //!pointer to the qaction for this plugin
93
    QAction * mQActionPointer;
94
    
95
    //////////////////////////////////////////////////////////////////////////
96
    // ADD YOUR OWN PROPERTY DECLARATIONS AFTER THIS POINT.....
97
    //////////////////////////////////////////////////////////////////////////
98

  
99
}; // OgrPlugin
100

  
101
}}} // namespace qgis::plugin::ogrconv
102

  
103
#endif // QGIS_PLUGIN_OGRCONV_PLUGIN_H_INCLUDED
qgis/src/plugins/ogr_converter/dialog.h (revision 0)
1
// $Id$
2
//////////////////////////////////////////////////////////////////////////////
3
//
4
// Copyright (C) 2008 by Mateusz Loskot <[email protected]>
5
//
6
// This program is free software; you can redistribute it and/or modify
7
// it under the terms of the GNU General Public License as published by
8
// the Free Software Foundation; either version 2 of the License,
9
// or (at your option) any later version.
10
//
11
//////////////////////////////////////////////////////////////////////////////
12
#ifndef QGIS_PLUGIN_OGRCONV_DIALOG_H_INCLUDED
13
#define QGIS_PLUGIN_OGRCONV_DIALOG_H_INCLUDED
14

  
15
// qgis::plugin::ogrconv
16
#include "format.h"
17
#include <ui_ogrconverterguibase.h>
18
// Qt4
19
#include <QDialog>
20

  
21
namespace qgis { namespace plugin { namespace ogrconv {
22

  
23
/**
24
@author Mateusz Loskot
25
*/
26
class Dialog : public QDialog, private Ui::OgrConverterGuiBase
27
{
28
    Q_OBJECT
29

  
30
public:
31

  
32
    Dialog(QWidget* parent = 0, Qt::WFlags fl = 0);
33
    ~Dialog();
34

  
35
private:
36

  
37
    static const int context_id = 0;
38

  
39
    FormatsRegistry mFrmts;
40
    Format mSrcFormat;
41
    Format mDstFormat;
42

  
43
    void resetSrcUi();
44
    void resetDstUi();
45
    void setButtonState(QPushButton* btn, bool isProtocol);
46

  
47
    void populateFormats();
48
    void populateLayers(QString const& url);
49
    bool testConnection(QString const& url);
50
    QString openFile();
51
    QString openDirectory();
52

  
53
private slots:
54

  
55
    void on_buttonBox_accepted();
56
    void on_buttonBox_rejected();
57
    void on_buttonBox_helpRequested();
58
    void on_radioSrcFile_toggled(bool checked);
59
    void on_radioSrcDirectory_toggled(bool checked);
60
    void on_radioSrcProtocol_toggled(bool checked);
61
    void on_buttonSelectSrc_clicked();
62
    void on_buttonSelectDst_clicked();
63
    void on_comboSrcFormats_currentIndexChanged(int index);
64
    void on_comboDstFormats_currentIndexChanged(int index);
65
};
66

  
67
}}} // namespace qgis::plugin::ogrconv
68

  
69
#endif // QGIS_PLUGIN_OGRCONV_DIALOG_H_INCLUDED
qgis/src/plugins/ogr_converter/format.cpp (revision 0)
1
// $Id$
2
//////////////////////////////////////////////////////////////////////////////
3
//
4
// Copyright (C) 2008 by Mateusz Loskot <[email protected]>
5
//
6
// This program is free software; you can redistribute it and/or modify
7
// it under the terms of the GNU General Public License as published by
8
// the Free Software Foundation; either version 2 of the License,
9
// or (at your option) any later version.
10
//
11
//////////////////////////////////////////////////////////////////////////////
12

  
13
// qgis::plugin::ogrconv
14
#include "format.h"
15
// Qt4
16
#include <QString>
17

  
18
namespace qgis { namespace plugin { namespace ogrconv {
19

  
20
Format::Format()
21
{
22
}
23

  
24
Format::Format(QString const& c, QString const& n)
25
    : mCode(c), mName(n), mTypeFlags(0)
26
{
27
}
28

  
29
Format::Format(QString const& c, QString const& n, unsigned char const& t)
30
    : mCode(c), mName(n), mTypeFlags(t)
31
{
32
}
33

  
34
Format::Format(QString const& c, QString const& n, QString const& p, unsigned char const& t)
35
    : mCode(c), mName(n), mProtocol(p), mTypeFlags(t)
36
{
37
}
38

  
39
QString const& Format::code() const
40
{
41
    return mCode;
42
}
43

  
44
QString const& Format::name() const
45
{
46
    return mName;
47
}
48

  
49
QString const& Format::protocol() const
50
{
51
    return mProtocol;
52
}
53

  
54
unsigned char const& Format::type() const
55
{
56
    return mTypeFlags;
57
}
58

  
59

  
60
FormatsRegistry::FormatsRegistry()
61
{
62
    init();
63
}
64

  
65
void FormatsRegistry::add(Format const& frmt)
66
{
67
    QString code = frmt.code();
68
    mFrmts[code] = frmt;
69
}
70

  
71
Format const& FormatsRegistry::find(QString const& code)
72
{
73
    mCache = mFrmts.value(code);
74
    return mCache;
75
}
76

  
77
void FormatsRegistry::init()
78
{
79
    add(Format("AVCBin", "Arc/Info Binary Coverage", Format::eFile));
80
    add(Format("AVCE00", "Arc/Info .E00 (ASCII) Coverage", Format::eFile));
81
    add(Format("BNA", "Atlas BNA", Format::eFile));
82
    add(Format("CSV", "Comma Separated Value", Format::eFile | Format::eDirectory));
83
    add(Format("DODS", "DODS/OPeNDAP", Format::eFile));
84
    add(Format("DGN", "Microstation DGN", Format::eFile));
85
    add(Format("ESRI Shapefile", "ESRI Shapefile", Format::eFile | Format::eDirectory));
86
    add(Format("FMEObjects Gateway", "FMEObjects Gateway", Format::eFile));
87
    add(Format("Geoconcept Text Export", "Geoconcept", Format::eFile));
88
    add(Format("GML", "Geography Markup Language", Format::eFile));
89
    add(Format("GMT", "GMT ASCII Vectors", Format::eFile));
90
    add(Format("GPX", "GPS Exchange Format", Format::eFile));
91
    add(Format("GeoJSON", "GeoJSON", Format::eFile)); // FIXME: Format::eProtocol));
92
    add(Format("GRASS", "GRASS", Format::eDirectory));
93
    add(Format("Informix DataBlade", "IDB", "IDB:", Format::eProtocol));
94
    add(Format("Interlis 1", "INTERLIS", Format::eFile));
95
    add(Format("Interlis 2", "INTERLIS", Format::eFile));
96
    add(Format("Ingres Database", "INGRES", "@driver=ingres,", Format::eProtocol));
97
    add(Format("KML", "KML", Format::eFile));
98
    add(Format("MapInfo", "MapInfo File", Format::eFile));
99
    add(Format("Memory", "Memory", Format::eFile));
100
    add(Format("MySQL", "MySQL", "MySQL:", Format::eProtocol));
101
    add(Format("ODBC", "Open DataBase Connectivity", "ODBC:", Format::eProtocol));
102
    add(Format("OGDI", "Open Geographic Datastore Interface Vectors", "gltp:", Format::eProtocol));
103
    add(Format("OCI", "Oracle Spatial", "OCI:", Format::eProtocol));
104
    add(Format("PGeo", "ESRI Personal GeoDatabase", "PGeo:", Format::eFile | Format::eProtocol));
105
    add(Format("PostgreSQL", "PostgreSQL", "PG:", Format::eProtocol));
106
    add(Format("S57", "IHO S-57", Format::eFile));
107
    add(Format("SDE", "ESRI ArcSDE", "SDE:", Format::eProtocol));
108
    add(Format("SDTS", "SDTS Topological Vector Profile", Format::eFile));
109
    add(Format("SQLite", "SQLite Database File", Format::eFile));
110
    add(Format("UK.NTF", "UK National Transfer Format", Format::eFile));
111
    add(Format("TIGER", "U.S. Census TIGER/Line", Format::eFile));
112
    add(Format("VRT", "Virtual Datasource", Format::eFile));
113
    add(Format("XPLANE", "X-Plane/Flighgear Aeronautical Data", Format::eFile));
114
}
115

  
116
}}} // namespace qgis::plugin::ogrconv
117

  
qgis/src/plugins/ogr_converter/translator.cpp (revision 0)
1
// $Id$
2
//////////////////////////////////////////////////////////////////////////////
3
//
4
// Copyright (C) 2008 by Mateusz Loskot <[email protected]>
5
//
6
// This program is free software; you can redistribute it and/or modify
7
// it under the terms of the GNU General Public License as published by
8
// the Free Software Foundation; either version 2 of the License,
9
// or (at your option) any later version.
10
//
11
//////////////////////////////////////////////////////////////////////////////
12

  
13
// qgis::plugin::ogrconv
14
#include "translator.h"
15
// QGIS
16
#include <qgslogger.h>
17
// Qt4
18
#include <QString>
19

  
20
namespace qgis { namespace plugin { namespace ogrconv {
21

  
22
// GDAL/OGR loaded into private namespace
23
#include <ogr_api.h>
24

  
25
Translator::Translator()
26
    : mDstUpdate(false), mDstLayerOverwrite(true)
27
{
28
}
29

  
30
Translator::Translator(QString const& src, QString const& dst, QString const& format)
31
    : mSrcUrl(src), mDstUrl(dst), mDstFormat(format),
32
        mDstUpdate(false), mDstLayerOverwrite(true)
33
{
34
}
35

  
36
QString const& Translator::targetFormat() const
37
{
38
    return mDstFormat;
39
}
40

  
41
void Translator::setTargetFormat(QString const& format)
42
{
43
    mDstFormat = format;
44
}
45

  
46
QString const& Translator::targetLayer() const
47
{
48
    return mDstLayer;
49
}
50

  
51
void Translator::setTargetLayer(QString const& layer)
52
{
53
    mDstLayer = layer;
54
}
55

  
56
QString const& Translator::sourceLayer() const
57
{
58
    return mSrcLayer;
59
}
60

  
61
void Translator::setSourceLayer(QString const& layer)
62
{
63
    mSrcLayer = layer;
64
}
65

  
66
QString const& Translator::targetReferenceSystem() const
67
{
68
    return mDstSrs;
69
}
70

  
71
void Translator::setTargetReferenceSystem(QString const& srs)
72
{
73
    mDstSrs = srs;
74
}
75

  
76
QString const& Translator::sourceReferenceSystem() const
77
{
78
    return mSrcSrs;
79
}
80

  
81
void Translator::setSourceReferenceSystem(QString const& srs)
82
{
83
    mSrcSrs = srs;
84
}
85

  
86
bool Translator::isTargetUpdate() const
87
{
88
    return mDstUpdate;
89
}
90

  
91
void Translator::setUpdateTarget(bool update)
92
{
93
    mDstUpdate = update;
94
}
95

  
96
bool Translator::isTargetLayerOverwrite() const
97
{
98
    return mDstLayerOverwrite;
99
}
100

  
101
bool Translator::translate()
102
{
103
    bool success = false;
104

  
105
    // TODO: RAII for OGR handlers!!!
106

  
107
    // Open input data source
108
    OGRDataSourceH srcDs = openDataSource(mSrcUrl, true);
109
    if (0 == srcDs)
110
    {
111
        QgsDebugMsg("Open source failed: " + mSrcUrl);
112
        return false;
113
    }
114

  
115
    // Open output data source
116
    OGRDataSourceH dstDs = openDataTarget(mDstUrl, mDstUpdate);
117
    if (0 == dstDs)
118
    {
119
        QgsDebugMsg("Open target failed: " + mDstUrl);
120
        OGR_DS_Destroy(srcDs);
121
        return false;
122
    }
123

  
124
    // TODO: Support translation of all layers from input data source
125
    //for (int i = 0; i < OGR_DS_GetLayerCount(); ++i)
126

  
127
    OGRLayerH srcLayer = OGR_DS_GetLayerByName(srcDs, mSrcLayer.toAscii().constData());
128
    if (0 == srcLayer)
129
    {
130
        QgsDebugMsg("Can not find layer: " + mSrcLayer);
131
        OGR_DS_Destroy(srcDs);
132
        OGR_DS_Destroy(dstDs);
133
        return false;
134
    }
135

  
136
    if (mDstLayer.isEmpty())
137
    {
138
        QgsDebugMsg("Using source layer name: " + mDstLayer);
139
        mDstLayer = mSrcLayer;
140
    }
141

  
142
    QgsDebugMsg("START LAYER TRANSLATION ------");
143

  
144
    success = translateLayer(srcDs, srcLayer, dstDs);
145

  
146
    QgsDebugMsg("END LAYER TRANSLATION ------");
147

  
148
    OGR_DS_Destroy(dstDs);
149
    OGR_DS_Destroy(srcDs);
150

  
151
    return success;
152
}
153

  
154
bool Translator::translateLayer(OGRDataSourceH srcDs, OGRLayerH srcLayer, OGRDataSourceH dstDs)
155
{
156
    // Implementation based on TranslateLayer function from ogr2ogr.cpp, from GDAL/OGR.
157
    Q_ASSERT(0 != srcDs);
158
    Q_ASSERT(0 != srcLayer);
159
    Q_ASSERT(0 != dstDs);
160

  
161
    bool success = false;
162

  
163
    // Get source layer schema
164
    OGRFeatureDefnH srcLayerDefn = OGR_L_GetLayerDefn(srcLayer);
165
    Q_ASSERT(0 != srcLayerDefn);
166

  
167
    // Find if layer exists in target data source 
168
    int dstLayerIndex = 0;
169
    OGRLayerH dstLayer = findLayer(dstDs, mDstLayer, dstLayerIndex);
170

  
171
    // If the user requested overwrite, and we have the layer in question
172
    // we need to delete it now so it will get recreated overwritten
173
    if (0 != dstLayer && mDstLayerOverwrite
174
        && 0 != OGR_DS_TestCapability(dstDs, ODsCDeleteLayer))
175
    {
176
        if (OGRERR_NONE != OGR_DS_DeleteLayer(dstDs, dstLayerIndex))
177
        {
178
            QgsDebugMsg("Delete layer failed when overwrite requested");
179
            return false;
180
        }
181
    }
182

  
183
    if (0 == dstLayer)
184
    {
185
        QgsDebugMsg("Destination layer not found, will attempt to create");
186

  
187
        // If the layer does not exist, then create it
188
        if (0 == OGR_DS_TestCapability(dstDs, ODsCCreateLayer))
189
        {
190
            QgsDebugMsg("Layer " + mDstLayer + " not found, and CreateLayer not supported by driver");
191
            return false;
192
        }
193

  
194
        // FIXME: Do we need it here?
195
        //CPLErrorReset();
196

  
197
        // TODO: -nlt option support
198
        OGRwkbGeometryType geomType = OGR_FD_GetGeomType(srcLayerDefn);
199
        
200
        // TODO: Implement SRS transformation 
201
        OGRSpatialReferenceH dstLayerSrs = OGR_L_GetSpatialRef(srcLayer);
202

  
203
        dstLayer = OGR_DS_CreateLayer(dstDs, mDstLayer.toAscii().constData(),
204
                                      dstLayerSrs, geomType, 0); 
205
    }
206
    // TODO: Append and createion options not implemented
207
    // else if (!mDstLayerAppend)
208
    
209
    Q_ASSERT(0 != dstLayer);
210

  
211
    // Transfer attributes schema
212
    if (!copyFields(dstLayer, srcLayerDefn))
213
    {
214
        QgsDebugMsg("Faild to copy fields from layer " + mSrcLayer);
215
        return false;
216
    }
217

  
218
    // Transfer features
219
    success = copyFeatures(srcLayer, dstLayer);
220

  
221
    return success;
222
}
223

  
224
bool Translator::copyFields(OGRFeatureDefnH layerDefn, OGRLayerH layer)
225
{
226
    Q_ASSERT(0 != layerDefn);
227
    Q_ASSERT(0 != layer);
228

  
229
    int const count = OGR_FD_GetFieldCount(layerDefn);
230
    for (int i = 0; i < count; ++i)
231
    {
232
        OGRFieldDefnH fieldDefn = OGR_FD_GetFieldDefn(layerDefn, i);
233
        Q_ASSERT(0 != fieldDefn);
234

  
235
        if (OGRERR_NONE != OGR_L_CreateField(layer, fieldDefn, true))
236
        {
237
            return false;
238
        }
239
    }
240

  
241
    return true;
242
}
243

  
244
bool Translator::copyFeatures(OGRLayerH srcLayer, OGRLayerH dstLayer)
245
{
246
    Q_ASSERT(0 != srcLayer);
247
    Q_ASSERT(0 != dstLayer);
248

  
249
    bool success = false;
250
    OGRFeatureDefnH srcLayerDefn = OGR_L_GetLayerDefn(srcLayer);
251
    long srcFid = 0;
252
    long count = 0;
253

  
254
    // TODO: RAII for feature handlers!!!
255
 
256
    while (true)
257
    {
258
        OGRFeatureH srcFeat = OGR_L_GetNextFeature(srcLayer);
259
        if (0 == srcFeat)
260
        {
261
            QgsDebugMsg("Next source feature is null, finishing");
262
            success = true;
263
            break;
264
        }
265
        srcFid = OGR_F_GetFID(srcFeat);
266

  
267
        // FIXME: Do we need it here?
268
        //CPLErrorReset();
269

  
270
        OGRFeatureH dstFeat = OGR_F_Create(srcLayerDefn);
271

  
272
        if (OGRERR_NONE !=  OGR_F_SetFrom(dstFeat, srcFeat, true))
273
        {
274
            QString msg = QString("Unable to translate feature %1 from layer %2").arg(srcFid).arg(mSrcLayer);
275
            QgsDebugMsg(msg);
276

  
277
            OGR_F_Destroy(srcFeat);
278
            OGR_F_Destroy(dstFeat);
279
            success = false;
280
            break;
281
        }
282
        Q_ASSERT(0 != dstFeat);
283

  
284
        // TODO: Transform feature geometry
285

  
286
        OGR_F_Destroy(srcFeat);
287
        
288
        // FIXME: Do we need it here?
289
        //CPLErrorReset();
290

  
291
        // TODO: Skip failures support
292
        if (OGRERR_NONE != OGR_L_CreateFeature(dstLayer, dstFeat))
293
        {
294
            QgsDebugMsg("Feature creation failed");
295
            OGR_F_Destroy(dstFeat);
296
            success = false;
297
            break;
298
        }
299

  
300
        OGR_F_Destroy(dstFeat);
301
        
302
        count += 1;
303
        success = true;
304
    }
305

  
306
    QgsDebugMsg(QString("Number of copied features: %1").arg(count));
307

  
308
    return success;
309
}
310

  
311
OGRSFDriverH Translator::findDriver(QString const& name)
312
{
313
    if (OGRGetDriverCount() <= 0)
314
    {
315
        OGRRegisterAll(); 
316
    }
317
    int const drvCount = OGRGetDriverCount();
318

  
319
    OGRSFDriverH drv = 0;
320
    QString drvName;
321

  
322
    for (int i = 0; i < drvCount; ++i)
323
    {
324
        OGRSFDriverH drvTmp = OGRGetDriver(i);
325
        Q_CHECK_PTR(drvTmp);
326
        if (0 != drvTmp)
327
        {
328
            drvName = OGR_Dr_GetName(drvTmp);
329
            if (name == drvName
330
                && 0 != OGR_Dr_TestCapability(drvTmp, ODrCCreateDataSource))
331
            {
332
                QgsDebugMsg("Driver found: " + name);
333
                drv = drvTmp;
334
                break;
335
            }
336
        }
337
    }
338

  
339
    return drv;
340
}
341

  
342
OGRLayerH Translator::findLayer(OGRDataSourceH ds, QString const& name, int& index)
343
{
344
    if (0 == ds)
345
    {
346
        index = -1;
347
        return 0;
348
    }
349

  
350
    OGRLayerH lyr = 0;
351
    int const count = OGR_DS_GetLayerCount(ds);
352

  
353
    for (int i = 0; i < count; ++i)
354
    {
355
        OGRLayerH lyrTmp = OGR_DS_GetLayer(ds, i);
356
        if (0 != lyrTmp)
357
        {
358
            OGRFeatureDefnH defn = OGR_L_GetLayerDefn(lyrTmp);
359
            Q_ASSERT(0 != defn);
360
            
361
            QString nameTmp(OGR_FD_GetName(defn));
362
            if (name == nameTmp)
363
            {
364
                QgsDebugMsg("Layer found: " + nameTmp);
365
                index = i;
366
                lyr = lyrTmp;
367
                break;
368
            }
369
        }
370
    }
371

  
372
    return lyr;
373
}
374

  
375
OGRDataSourceH Translator::openDataSource(QString const& url, bool readOnly)
376
{
377
    OGRDataSourceH ds = OGROpen(url.toAscii().constData(), !readOnly, 0);
378
    if (0 == ds)
379
    {
380
        QgsDebugMsg("Failed to open: " + url);
381
    }
382

  
383
    return ds;
384
}
385

  
386
OGRDataSourceH Translator::openDataTarget(QString const& url, bool update)
387
{
388
    OGRDataSourceH ds = 0;
389

  
390
    if (update)
391
    {
392
        // Try opening the output datasource as an existing, writable
393
        ds = openDataSource(url, false);
394
    }
395
    else
396
    {
397
        // Find the output driver
398
        OGRSFDriverH drv = findDriver(mDstFormat);
399
        if (0 == drv)
400
        {
401
            QgsDebugMsg("Could not find driver: " + mDstFormat);
402
            return 0;
403
        }
404

  
405
        // Create the output data source
406
        //
407
        // TODO: Add support for creation options
408
        ds = OGR_Dr_CreateDataSource(drv, url.toAscii().constData(), 0);
409
        if (0 == ds)
410
        {
411
            QgsDebugMsg("Failed to open: " + url);
412
        }
413
    }
414

  
415
    return ds;
416
}
417

  
418
}}} // namespace qgis::plugin::ogrconv
419

  
qgis/src/plugins/ogr_converter/ogrconverterguibase.ui (revision 0)
1
<ui version="4.0" >
2
 <class>OgrConverterGuiBase</class>
3
 <widget class="QDialog" name="OgrConverterGuiBase" >
4
  <property name="geometry" >
5
   <rect>
6
    <x>0</x>
7
    <y>0</y>
8
    <width>521</width>
9
    <height>450</height>
10
   </rect>
11
  </property>
12
  <property name="sizePolicy" >
13
   <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
14
    <horstretch>0</horstretch>
15
    <verstretch>0</verstretch>
16
   </sizepolicy>
17
  </property>
18
  <property name="minimumSize" >
19
   <size>
20
    <width>520</width>
21
    <height>450</height>
22
   </size>
23
  </property>
24
  <property name="windowTitle" >
25
   <string>OGR Layer Converter</string>
26
  </property>
27
  <property name="windowIcon" >
28
   <iconset>
29
    <normaloff/>
30
   </iconset>
31
  </property>
32
  <layout class="QGridLayout" name="gridLayout" >
33
   <item row="0" column="0" >
34
    <widget class="QGroupBox" name="srcGroupBox" >
35
     <property name="title" >
36
      <string>Source</string>
37
     </property>
38
     <widget class="QWidget" name="" >
39
      <property name="geometry" >
40
       <rect>
... This diff was truncated because it exceeds the maximum size that can be displayed.