~ubuntu-branches/ubuntu/hardy/qgis/hardy

« back to all changes in this revision

Viewing changes to src/plugins/grass/qgsgrassbrowser.cpp

  • Committer: Bazaar Package Importer
  • Author(s): William Grant
  • Date: 2007-05-06 13:42:32 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070506134232-pyli6t388w5asd8x
Tags: 0.8.0-3ubuntu1
* Merge from Debian unstable. Remaining Ubuntu changes:
  - debian/rules, debian/qgis.install, debian/qgis.dirs debian/qgis.desktop:
    Add and install .desktop.
* debian/qgis.desktop: Remove Applications category; it's not real.
* Modify Maintainer value to match Debian-Maintainer-Field Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************
 
2
                              qgsgrassbrowser.cpp
 
3
                             -------------------
 
4
    begin                : February, 2006
 
5
    copyright            : (C) 2006 by Radim Blazek
 
6
    email                : radim.blazek@gmail.com
 
7
********************************************************************/
 
8
/********************************************************************
 
9
 This program is free software; you can redistribute it and/or modify  
 
10
 it under the terms of the GNU General Public License as published by 
 
11
 the Free Software Foundation; either version 2 of the License, or     
 
12
 (at your option) any later version.                                   
 
13
*******************************************************************/
 
14
#include <iostream>
 
15
#include <vector>
 
16
 
 
17
#include <QApplication>
 
18
#include <QStyle>
 
19
#include <qdir.h>
 
20
#include <qfile.h>
 
21
#include <qsettings.h>
 
22
#include <qstringlist.h>
 
23
#include <qmessagebox.h>
 
24
#include <qpainter.h>
 
25
#include <qpixmap.h>
 
26
#include <qnamespace.h>
 
27
#include <qevent.h>
 
28
#include <qsize.h>
 
29
#include <qicon.h>
 
30
#include <QTreeView>
 
31
#include <QHeaderView>
 
32
#include <QMainWindow>
 
33
#include <QActionGroup>
 
34
#include <QToolBar>
 
35
#include <QAction>
 
36
#include <QTextBrowser>
 
37
#include <QSplitter>
 
38
#include <QProcess>
 
39
#include <QScrollBar>
 
40
 
 
41
#include "qgis.h"
 
42
#include "qgsapplication.h"
 
43
#include "qgsrasterlayer.h"
 
44
 
 
45
extern "C" {
 
46
#include <grass/gis.h>
 
47
#include <grass/Vect.h>
 
48
}
 
49
 
 
50
#include "../../src/providers/grass/qgsgrass.h"
 
51
#include "qgsgrassmodel.h"
 
52
#include "qgsgrassbrowser.h"
 
53
#include "qgsgrassselect.h"
 
54
#include "qgsgrassutils.h"
 
55
 
 
56
QgsGrassBrowser::QgsGrassBrowser ( QgisIface *iface, 
 
57
         QWidget * parent, Qt::WFlags f )
 
58
             :mIface(iface), QMainWindow(parent, Qt::WType_Dialog)
 
59
{
 
60
    #ifdef QGISDEBUG
 
61
    std::cerr << "QgsGrassBrowser()" << std::endl;
 
62
    #endif
 
63
 
 
64
    QActionGroup *ag = new QActionGroup ( this );
 
65
    QToolBar *tb = addToolBar(tr("Tools"));
 
66
 
 
67
    QString myIconPath = QgsApplication::themePath() + "/grass/";
 
68
    mActionAddMap = new QAction( 
 
69
                             QIcon(myIconPath+"grass_add_map.png"), 
 
70
                             tr("Add selected map to canvas"), this);
 
71
    mActionAddMap->setEnabled(false); 
 
72
    ag->addAction ( mActionAddMap );
 
73
    tb->addAction ( mActionAddMap );
 
74
    connect ( mActionAddMap, SIGNAL(triggered()), this, SLOT(addMap()) );
 
75
 
 
76
    mActionCopyMap = new QAction( 
 
77
                             QIcon(myIconPath+"grass_copy_map.png"), 
 
78
                             tr("Copy selected map"), this);
 
79
    mActionCopyMap->setEnabled(false); 
 
80
    ag->addAction ( mActionCopyMap );
 
81
    tb->addAction ( mActionCopyMap );
 
82
    connect ( mActionCopyMap, SIGNAL(triggered()), this, SLOT(copyMap()) );
 
83
 
 
84
    mActionRenameMap = new QAction( 
 
85
                             QIcon(myIconPath+"grass_rename_map.png"), 
 
86
                             tr("Rename selected map"), this);
 
87
    mActionRenameMap->setEnabled(false); 
 
88
    ag->addAction ( mActionRenameMap );
 
89
    tb->addAction ( mActionRenameMap );
 
90
    connect ( mActionRenameMap, SIGNAL(triggered()), this, SLOT(renameMap()) );
 
91
 
 
92
    mActionDeleteMap = new QAction( 
 
93
                             QIcon(myIconPath+"grass_delete_map.png"), 
 
94
                             tr("Delete selected map"), this);
 
95
    mActionDeleteMap->setEnabled(false); 
 
96
    ag->addAction ( mActionDeleteMap );
 
97
    tb->addAction ( mActionDeleteMap );
 
98
    connect ( mActionDeleteMap, SIGNAL(triggered()), this, SLOT(deleteMap()) );
 
99
 
 
100
    mActionSetRegion = new QAction( 
 
101
                             QIcon(myIconPath+"grass_set_region.png"), 
 
102
                             tr("Set current region to selected map"), this);
 
103
    mActionSetRegion->setEnabled(false); 
 
104
    ag->addAction ( mActionSetRegion );
 
105
    tb->addAction ( mActionSetRegion );
 
106
    connect ( mActionSetRegion, SIGNAL(triggered()), this, SLOT(setRegion()) );
 
107
 
 
108
    mActionRefresh = new QAction( 
 
109
                             QIcon(myIconPath+"grass_refresh.png"), 
 
110
                             tr("Refresh"), this);
 
111
    ag->addAction ( mActionRefresh );
 
112
    tb->addAction ( mActionRefresh );
 
113
    connect ( mActionRefresh, SIGNAL(triggered()), this, SLOT(refresh()) );
 
114
 
 
115
    // Add model
 
116
    mModel = new QgsGrassModel ( this );
 
117
 
 
118
    mTree = new QTreeView(0);
 
119
    mTree->header()->hide();
 
120
    mTree->setModel(mModel);
 
121
 
 
122
    mTextBrowser = new QTextBrowser(0);
 
123
    mTextBrowser->setTextFormat(Qt::RichText);
 
124
    mTextBrowser->setReadOnly(TRUE);
 
125
 
 
126
    mSplitter = new QSplitter(0);
 
127
    mSplitter->addWidget(mTree);
 
128
    mSplitter->addWidget(mTextBrowser);
 
129
 
 
130
    this->setCentralWidget(mSplitter);
 
131
 
 
132
    connect ( mTree->selectionModel(), 
 
133
              SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
 
134
              this, SLOT(selectionChanged(QItemSelection,QItemSelection)) );
 
135
 
 
136
    connect ( mTree->selectionModel(), 
 
137
              SIGNAL(currentChanged(QModelIndex,QModelIndex)),
 
138
              this, SLOT(currentChanged(QModelIndex,QModelIndex)) );
 
139
 
 
140
    connect ( mTree, SIGNAL(doubleClicked(QModelIndex)),
 
141
              this, SLOT(doubleClicked(QModelIndex)) );
 
142
}
 
143
 
 
144
QgsGrassBrowser::~QgsGrassBrowser() { }
 
145
 
 
146
void QgsGrassBrowser::refresh()
 
147
{
 
148
    #ifdef QGISDEBUG
 
149
    std::cerr << "QgsGrassBrowser::refresh()" << std::endl;
 
150
    #endif
 
151
 
 
152
    mModel->refresh();
 
153
    mTree->update();
 
154
}
 
155
 
 
156
void QgsGrassBrowser::addMap()
 
157
{
 
158
    #ifdef QGISDEBUG
 
159
    std::cerr << "QgsGrassBrowser::addMap()" << std::endl;
 
160
    #endif
 
161
    
 
162
    QModelIndexList indexes = mTree->selectionModel()->selectedIndexes();
 
163
    bool mapSelected = false;
 
164
 
 
165
    QList<QModelIndex>::const_iterator it = indexes.begin();
 
166
    for (; it != indexes.end(); ++it)
 
167
    {
 
168
        int type = mModel->itemType(*it);
 
169
        QString uri = mModel->uri(*it);
 
170
        QString mapset = mModel->itemMapset(*it);
 
171
        QString map = mModel->itemMap(*it);
 
172
        if ( type == QgsGrassModel::Raster )
 
173
        {
 
174
            std::cerr << "add raster: " << uri.ascii() << std::endl;
 
175
            QgsRasterLayer *layer = new QgsRasterLayer( uri, map );
 
176
            mIface->addRasterLayer(layer);
 
177
            mapSelected = true;
 
178
        }
 
179
        else if ( type == QgsGrassModel::Vector )
 
180
        {
 
181
            QgsGrassUtils::addVectorLayers ( mIface, 
 
182
                                QgsGrass::getDefaultGisdbase(),
 
183
                                QgsGrass::getDefaultLocation(),
 
184
                                mapset, map );
 
185
        } 
 
186
        else if ( type == QgsGrassModel::VectorLayer )
 
187
        {
 
188
 
 
189
            QStringList list = QgsGrassSelect::vectorLayers(
 
190
                                   QgsGrass::getDefaultGisdbase(),
 
191
                                   QgsGrass::getDefaultLocation(),
 
192
                          mModel->itemMapset(*it), map );
 
193
 
 
194
            // TODO: common method for vector names
 
195
            QStringList split = QStringList::split ( '/', uri );
 
196
            QString layer = split.last();
 
197
 
 
198
            QString name = QgsGrassUtils::vectorLayerName ( 
 
199
                                map, layer, list.size() );
 
200
            
 
201
            mIface->addVectorLayer( uri, name, "grass");
 
202
            mapSelected = true;
 
203
        }
 
204
        else if ( type == QgsGrassModel::Region )
 
205
        {
 
206
            struct Cell_head window;
 
207
            if ( !getItemRegion (*it, &window) ) continue;
 
208
            writeRegion ( &window );
 
209
        }
 
210
    }
 
211
}
 
212
 
 
213
void QgsGrassBrowser::doubleClicked(const QModelIndex & index)
 
214
{
 
215
    #ifdef QGISDEBUG
 
216
    std::cerr << "QgsGrassBrowser::doubleClicked()" << std::endl;
 
217
    #endif
 
218
 
 
219
    addMap();
 
220
}
 
221
 
 
222
QString QgsGrassBrowser::formatMessage( QString msg )
 
223
{
 
224
    return msg.replace("<","&lt;").replace(">","&gt;").replace("\n","<br>");
 
225
}
 
226
 
 
227
void QgsGrassBrowser::copyMap()
 
228
{
 
229
    #ifdef QGISDEBUG
 
230
    std::cerr << "QgsGrassBrowser::copyMap()" << std::endl;
 
231
    #endif
 
232
    
 
233
    QModelIndexList indexes = mTree->selectionModel()->selectedIndexes();
 
234
 
 
235
    QList<QModelIndex>::const_iterator it = indexes.begin();
 
236
    for (; it != indexes.end(); ++it)
 
237
    {
 
238
        int type = mModel->itemType(*it);
 
239
        QString mapset = mModel->itemMapset(*it);
 
240
        QString map = mModel->itemMap(*it);
 
241
 
 
242
        QString typeName;
 
243
        QString element;
 
244
        if ( type == QgsGrassModel::Raster ) 
 
245
        {
 
246
           element = "cell";
 
247
           typeName = "rast";
 
248
        } 
 
249
        else if ( type == QgsGrassModel::Vector )
 
250
        {
 
251
            element = "vector";
 
252
            typeName = "vect";
 
253
        }
 
254
        else if ( type == QgsGrassModel::Region ) 
 
255
        {
 
256
            element = "windows";
 
257
            typeName = "region";
 
258
        }
 
259
 
 
260
        QgsGrassElementDialog ed;
 
261
        bool ok;
 
262
        QString source;
 
263
        QString suggest;
 
264
        if ( mapset == QgsGrass::getDefaultMapset() )
 
265
        {
 
266
            source = map;
 
267
        } 
 
268
        else
 
269
        {
 
270
            suggest = map;
 
271
        }
 
272
        QString newName = ed.getItem ( element, "New name",
 
273
                          "New name", suggest, source, &ok );
 
274
 
 
275
        if ( !ok ) return;
 
276
         
 
277
        QString module = "g.copy";
 
278
#ifdef WIN32
 
279
        module.append(".exe");
 
280
#endif
 
281
        QProcess process(this);
 
282
        QStringList args(typeName + "=" + map + "@" + mapset + "," + newName );
 
283
        process.start(module, args );
 
284
        if ( !process.waitForFinished() || process.exitCode() != 0 )
 
285
        {
 
286
            QString output ( process.readAllStandardOutput () );
 
287
            QString error ( process.readAllStandardError () );
 
288
            QMessageBox::warning( 0, tr("Warning"), tr("Cannot copy map ")
 
289
                       + map + "@" + mapset 
 
290
                       + tr("<br>command: ") + module + " " + args.join(" ")
 
291
                       + "<br>" + formatMessage(output)
 
292
                       + "<br>" + formatMessage(error) ); 
 
293
        }
 
294
        else
 
295
        {
 
296
            refresh();
 
297
        }
 
298
    }
 
299
}
 
300
 
 
301
void QgsGrassBrowser::renameMap()
 
302
{
 
303
    #ifdef QGISDEBUG
 
304
    std::cerr << "QgsGrassBrowser::renameMap()" << std::endl;
 
305
    #endif
 
306
 
 
307
    QModelIndexList indexes = mTree->selectionModel()->selectedIndexes();
 
308
 
 
309
    QList<QModelIndex>::const_iterator it = indexes.begin();
 
310
    for (; it != indexes.end(); ++it)
 
311
    {
 
312
        int type = mModel->itemType(*it);
 
313
        QString mapset = mModel->itemMapset(*it);
 
314
        QString map = mModel->itemMap(*it);
 
315
 
 
316
        if ( mapset != QgsGrass::getDefaultMapset() ) continue; // should not happen
 
317
 
 
318
        QString typeName;
 
319
        QString element;
 
320
        if ( type == QgsGrassModel::Raster ) 
 
321
        {
 
322
           element = "cell";
 
323
           typeName = "rast";
 
324
        } 
 
325
        else if ( type == QgsGrassModel::Vector )
 
326
        {
 
327
            element = "vector";
 
328
            typeName = "vect";
 
329
        }
 
330
        else if ( type == QgsGrassModel::Region ) 
 
331
        {
 
332
            element = "windows";
 
333
            typeName = "region";
 
334
        }
 
335
 
 
336
        QgsGrassElementDialog ed;
 
337
        bool ok;
 
338
        QString newName = ed.getItem ( element, "New name",
 
339
                          "New name", "", map, &ok );
 
340
 
 
341
        if ( !ok ) return;
 
342
         
 
343
        QString module = "g.rename";
 
344
#ifdef WIN32
 
345
        module.append(".exe");
 
346
#endif
 
347
        QProcess process(this);
 
348
        QStringList args(typeName + "=" + map + "," + newName );
 
349
        process.start(module, QStringList( typeName + "=" + map + "," + newName ) );
 
350
        if ( !process.waitForFinished() || process.exitCode() != 0 )
 
351
        {
 
352
            QString output ( process.readAllStandardOutput () );
 
353
            QString error ( process.readAllStandardError () );
 
354
            QMessageBox::warning( 0, tr("Warning"), tr("Cannot rename map ")
 
355
                       + map  
 
356
                       + tr("<br>command: ") + module + " " + args.join(" ")
 
357
                       + "<br>" + formatMessage(output)
 
358
                       + "<br>" + formatMessage(error) ); 
 
359
        }
 
360
        else
 
361
        {
 
362
            refresh();
 
363
        }
 
364
    }
 
365
}
 
366
 
 
367
void QgsGrassBrowser::deleteMap()
 
368
{
 
369
    #ifdef QGISDEBUG
 
370
    std::cerr << "QgsGrassBrowser::deleteMap()" << std::endl;
 
371
    #endif
 
372
    
 
373
    QModelIndexList indexes = mTree->selectionModel()->selectedIndexes();
 
374
 
 
375
    QList<QModelIndex>::const_iterator it = indexes.begin();
 
376
    for (; it != indexes.end(); ++it)
 
377
    {
 
378
        int type = mModel->itemType(*it);
 
379
        QString mapset = mModel->itemMapset(*it);
 
380
        QString map = mModel->itemMap(*it);
 
381
 
 
382
        QString typeName;
 
383
        if ( type == QgsGrassModel::Raster ) typeName = "rast";
 
384
        else if ( type == QgsGrassModel::Vector ) typeName = "vect";
 
385
        else if ( type == QgsGrassModel::Region ) typeName = "region";
 
386
 
 
387
        if ( mapset != QgsGrass::getDefaultMapset() ) 
 
388
        {
 
389
            continue; // should not happen
 
390
        }
 
391
         
 
392
        int ret = QMessageBox::question ( 0, tr("Warning"),
 
393
              tr("Delete map <b>") + map + "</b>",
 
394
              QMessageBox::Yes,  QMessageBox::No );
 
395
 
 
396
        if ( ret == QMessageBox::No ) continue;
 
397
 
 
398
        QString module = "g.remove";
 
399
#ifdef WIN32
 
400
        module.append(".exe");
 
401
#endif
 
402
        QProcess process(this);
 
403
        QStringList args(typeName + "=" + map );
 
404
        process.start(module, QStringList( typeName + "=" + map ) );
 
405
        if ( !process.waitForFinished() || process.exitCode() != 0 )
 
406
        {
 
407
            QString output ( process.readAllStandardOutput () );
 
408
            QString error ( process.readAllStandardError () );
 
409
            QMessageBox::warning( 0, tr("Warning"), tr("Cannot delete map ")
 
410
                       + map  
 
411
                       + tr("<br>command: ") + module + " " + args.join(" ")
 
412
                       + "<br>" + formatMessage(output)
 
413
                       + "<br>" + formatMessage(error) ); 
 
414
        }
 
415
        else
 
416
        {
 
417
            refresh();
 
418
        }
 
419
    }
 
420
}
 
421
 
 
422
void QgsGrassBrowser::setRegion()
 
423
{
 
424
    #ifdef QGISDEBUG
 
425
    std::cerr << "QgsGrassBrowser::setRegion()" << std::endl;
 
426
    #endif
 
427
 
 
428
    struct Cell_head window;
 
429
 
 
430
    QModelIndexList indexes = mTree->selectionModel()->selectedIndexes();
 
431
 
 
432
    // TODO multiple selection - extent region to all maps
 
433
    QList<QModelIndex>::const_iterator it = indexes.begin();
 
434
    for (; it != indexes.end(); ++it)
 
435
    {
 
436
        if ( !getItemRegion (*it, &window) ) return;
 
437
    }
 
438
    writeRegion ( &window );
 
439
}
 
440
 
 
441
void QgsGrassBrowser::writeRegion(struct Cell_head *window )
 
442
{
 
443
    #ifdef QGISDEBUG
 
444
    std::cerr << "QgsGrassBrowser::writeRegion()" << std::endl;
 
445
    #endif
 
446
 
 
447
    QgsGrass::setMapset( QgsGrass::getDefaultGisdbase(),
 
448
                         QgsGrass::getDefaultLocation(),
 
449
                         QgsGrass::getDefaultMapset() );
 
450
 
 
451
    if ( G_put_window ( window ) == -1 )
 
452
    { 
 
453
        QMessageBox::warning( 0, tr("Warning"), 
 
454
                 tr("Cannot write new region") ); 
 
455
        return;
 
456
    }
 
457
    emit regionChanged();
 
458
}
 
459
 
 
460
bool QgsGrassBrowser::getItemRegion( QModelIndex index, struct Cell_head *window )
 
461
{
 
462
    #ifdef QGISDEBUG
 
463
    std::cerr << "QgsGrassBrowser::setRegion()" << std::endl;
 
464
    #endif
 
465
 
 
466
    int type = mModel->itemType(index);
 
467
    QString mapset = mModel->itemMapset(index);
 
468
    QString map = mModel->itemMap(index);
 
469
 
 
470
    int mapType;
 
471
    switch (type) {
 
472
        case QgsGrassModel::Raster :
 
473
            mapType = QgsGrass::Raster;
 
474
            break;
 
475
        case QgsGrassModel::Vector :
 
476
            mapType = QgsGrass::Vector;
 
477
            break;
 
478
        case QgsGrassModel::Region :
 
479
            mapType = QgsGrass::Region;
 
480
            break;
 
481
        default:
 
482
            break;
 
483
    }
 
484
     
 
485
    return QgsGrass::mapRegion ( mapType, QgsGrass::getDefaultGisdbase(),
 
486
            QgsGrass::getDefaultLocation(), mapset, map, window ); 
 
487
}
 
488
 
 
489
void QgsGrassBrowser::selectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
 
490
{
 
491
    #ifdef QGISDEBUG
 
492
    std::cerr << "QgsGrassBrowser::selectionChanged()" << std::endl;
 
493
    #endif
 
494
 
 
495
    mActionAddMap->setEnabled(false);
 
496
    mActionCopyMap->setEnabled(false);
 
497
    mActionRenameMap->setEnabled(false);
 
498
    mActionDeleteMap->setEnabled(false);
 
499
    mActionSetRegion->setEnabled(false);
 
500
    
 
501
    QModelIndexList indexes = mTree->selectionModel()->selectedIndexes();
 
502
 
 
503
    mTextBrowser->clear();
 
504
 
 
505
    QList<QModelIndex>::const_iterator it = indexes.begin();
 
506
    for (; it != indexes.end(); ++it)
 
507
    {
 
508
        mTextBrowser->append ( mModel->itemInfo(*it) );
 
509
        mTextBrowser->verticalScrollBar()->setValue(0);
 
510
        
 
511
        int type = mModel->itemType(*it);
 
512
        if ( type == QgsGrassModel::Raster || 
 
513
             type == QgsGrassModel::Vector || 
 
514
             type == QgsGrassModel::VectorLayer )
 
515
        {
 
516
            mActionAddMap->setEnabled(true);
 
517
        }
 
518
        if ( type == QgsGrassModel::Raster || type == QgsGrassModel::Vector || type == QgsGrassModel::Region )
 
519
        {
 
520
            mActionSetRegion->setEnabled(true);
 
521
            mActionCopyMap->setEnabled(true);
 
522
 
 
523
            QString mapset = mModel->itemMapset(*it);
 
524
            if ( mapset == QgsGrass::getDefaultMapset() ) 
 
525
            {
 
526
                mActionDeleteMap->setEnabled(true);
 
527
                mActionRenameMap->setEnabled(true);
 
528
            }
 
529
        }
 
530
    }
 
531
}
 
532
 
 
533
void QgsGrassBrowser::currentChanged(const QModelIndex & current, const QModelIndex & previous)
 
534
{
 
535
    #ifdef QGISDEBUG
 
536
    std::cerr << "QgsGrassBrowser::currentChanged()" << std::endl;
 
537
    #endif
 
538
}
 
539
 
 
540
void QgsGrassBrowser::setLocation( const QString &gisbase, const QString &location )
 
541
{
 
542
    mModel->setLocation(gisbase, location);
 
543
}