~ubuntu-branches/ubuntu/wily/qgis/wily

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
 *   (at your option) any later version.                                   *
14
14
 *                                                                         *
15
15
 ***************************************************************************/
16
 
#include <iostream>
17
 
#include <qdir.h>
18
 
#include <qevent.h>
19
 
#include <qfile.h>
20
 
#include <qsettings.h>
21
 
#include <qpixmap.h>
22
 
#include <q3listbox.h>
23
 
#include <qstringlist.h>
24
 
#include <qlabel.h>
25
 
#include <QComboBox>
26
 
#include <qspinbox.h>
27
 
#include <qmessagebox.h>
28
 
#include <qinputdialog.h>
29
 
#include <qsettings.h>
30
 
#include <qpainter.h>
31
 
#include <qpixmap.h>
32
 
#include <qpen.h>
33
 
#include <q3pointarray.h>
34
 
#include <qcursor.h>
35
 
#include <qnamespace.h>
36
 
#include <q3listview.h>
37
 
#include <qcolordialog.h>
38
 
#include <q3table.h>
39
 
#include <qstatusbar.h>
40
 
#include <qglobal.h>
41
 
 
42
 
#include <QActionGroup>
43
 
#include <QCloseEvent>
44
 
#include <QToolBar>
45
 
 
46
 
#include "qgis.h"
 
16
 
 
17
#include "qgsgrassedit.h"
 
18
#include "qgsgrassattributes.h"
 
19
#include "qgsgrassedittools.h"
 
20
#include "qgsgrassplugin.h"
 
21
#include "qgsgrassutils.h"
 
22
#include "qgsgrassprovider.h"
 
23
#include "qgsgrass.h"
 
24
 
 
25
#include "qgisinterface.h"
47
26
#include "qgsapplication.h"
 
27
#include "qgsfield.h"
 
28
#include "qgslogger.h"
48
29
#include "qgsmapcanvas.h"
 
30
#include "qgsmapcanvasitem.h"
49
31
#include "qgsmaplayer.h"
 
32
#include "qgsmaprenderer.h"
 
33
#include "qgsproject.h"
 
34
#include "qgsrubberband.h"
50
35
#include "qgsvectorlayer.h"
51
 
#include "qgsdataprovider.h"
52
 
#include "qgsmaptopixel.h"
53
 
#include "qgsfield.h"
54
 
#include "qgsfeatureattribute.h"
55
 
#include "qgslegend.h"
56
36
#include "qgsvertexmarker.h"
57
 
#include "qgsrubberband.h"
58
 
#include "qgsproject.h"
59
 
#include "qgslogger.h"
60
 
 
61
 
extern "C" {
62
 
#include <grass/gis.h>
 
37
 
 
38
#include <QCloseEvent>
 
39
#include <QColorDialog>
 
40
#include <QDir>
 
41
#include <QHeaderView>
 
42
#include <QKeyEvent>
 
43
#include <QMessageBox>
 
44
#include <QSettings>
 
45
#include <QToolBar>
 
46
 
 
47
extern "C"
 
48
{
63
49
#include <grass/Vect.h>
64
50
}
65
51
 
66
 
#include "../../src/providers/grass/qgsgrass.h"
67
 
#include "../../src/providers/grass/qgsgrassprovider.h"
68
 
#include "qgsgrassattributes.h"
69
 
#include "qgsgrassedit.h"
70
 
#include "qgsgrassedittools.h"
71
 
#include "qgsgrassutils.h"
 
52
#ifdef _MSC_VER
 
53
#define round(x)  ((x) >= 0 ? floor((x)+0.5) : floor((x)-0.5))
 
54
#endif
72
55
 
73
 
#include "qgsmapcanvasitem.h"
74
 
#include "qgsmaptoolpan.h"
75
56
 
76
57
class QgsGrassEditLayer : public QgsMapCanvasItem
77
58
{
78
59
  public:
79
 
    
80
 
    QgsGrassEditLayer(QgsMapCanvas* mapCanvas):QgsMapCanvasItem(mapCanvas)
81
 
    {
82
 
      updatePosition();
83
 
    }
84
 
    
85
 
    virtual void drawShape(QPainter & p)
86
 
    {
87
 
      p.drawPixmap(mPanningOffset.x(),mPanningOffset.y(), mPixmap);
88
 
    }
89
 
    
 
60
 
 
61
    QgsGrassEditLayer( QgsMapCanvas* mapCanvas ): QgsMapCanvasItem( mapCanvas )
 
62
    {
 
63
    }
 
64
 
 
65
    virtual void paint( QPainter* p )
 
66
    {
 
67
      p->drawPixmap( 0, 0, mPixmap );
 
68
    }
 
69
 
 
70
    virtual QRectF boundingRect() const
 
71
    {
 
72
      return QRectF( 0, 0, mMapCanvas->width(), mMapCanvas->height() );
 
73
    }
 
74
 
90
75
    virtual void updatePosition()
91
 
    {      
92
 
      move(mPanningOffset.x(),mPanningOffset.y());
93
 
      setSize(mMapCanvas->width(), mMapCanvas->height());      
 
76
    {
 
77
      setPos( QPointF( mPanningOffset ) );
94
78
    }
95
 
    
 
79
 
96
80
    QPixmap& pixmap() { return mPixmap; }
97
 
    
 
81
 
98
82
  private:
99
 
    
 
83
 
100
84
    QPixmap mPixmap;
101
85
};
102
86
 
103
87
 
 
88
#include <QItemDelegate>
 
89
class QgsGrassEditAttributeTableItemDelegate : public QItemDelegate
 
90
{
 
91
  public:
 
92
    QgsGrassEditAttributeTableItemDelegate( QObject *parent = 0 );
 
93
    QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
 
94
    void setEditorData( QWidget *editor, const QModelIndex &index ) const;
 
95
    void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const;
 
96
};
 
97
 
 
98
QgsGrassEditAttributeTableItemDelegate::QgsGrassEditAttributeTableItemDelegate( QObject *parent )
 
99
    : QItemDelegate( parent )
 
100
{}
 
101
 
 
102
QWidget *QgsGrassEditAttributeTableItemDelegate::createEditor( QWidget *parent,
 
103
    const QStyleOptionViewItem &option, const QModelIndex &index ) const
 
104
{
 
105
  QWidget *editor;
 
106
  if ( index.column() == 1 )
 
107
  {
 
108
    QComboBox *cb = new QComboBox( parent );
 
109
    cb->addItems( QStringList() << "integer" << "double precision" << "varchar" );
 
110
    editor = cb;
 
111
  }
 
112
  else
 
113
  {
 
114
    editor = QItemDelegate::createEditor( parent, option, index );
 
115
  }
 
116
  return editor;
 
117
}
 
118
 
 
119
#include<QDebug>
 
120
void QgsGrassEditAttributeTableItemDelegate::setEditorData( QWidget *editor,
 
121
    const QModelIndex &index ) const
 
122
{
 
123
  if ( index.column() == 1 )
 
124
  {
 
125
    QComboBox *cb = static_cast<QComboBox *>( editor );
 
126
    cb->setCurrentIndex( cb->findData( index.model()->data( index ), Qt::DisplayRole ) );
 
127
  }
 
128
  else
 
129
  {
 
130
    QItemDelegate::setEditorData( editor, index );
 
131
  }
 
132
}
 
133
 
 
134
void QgsGrassEditAttributeTableItemDelegate::setModelData( QWidget *editor,
 
135
    QAbstractItemModel *model, const QModelIndex &index ) const
 
136
{
 
137
  if ( index.column() == 1 )
 
138
  {
 
139
    QComboBox *cb = static_cast<QComboBox *>( editor );
 
140
    model->setData( index, cb->currentText(), Qt::EditRole );
 
141
  }
 
142
  else
 
143
  {
 
144
    QItemDelegate::setModelData( editor, model, index );
 
145
  }
 
146
}
 
147
 
104
148
 
105
149
bool QgsGrassEdit::mRunning = false;
106
150
 
107
 
QgsGrassEdit::QgsGrassEdit ( QgisApp *qgisApp, QgisIface *iface, 
108
 
    QWidget * parent, Qt::WFlags f )
109
 
    :QMainWindow(parent,f), QgsGrassEditBase (), mMapTool(0),
110
 
    mCanvasEdit(0), mRubberBandLine(0), mRubberBandIcon(0), mInited(false)
 
151
QgsGrassEdit::QgsGrassEdit( QgisInterface *iface, QgsMapLayer* layer, bool newMap,
 
152
                            QWidget * parent, Qt::WFlags f )
 
153
    : QMainWindow( parent, f ), QgsGrassEditBase(), mInited( false ),
 
154
    mMapTool( 0 ), mCanvasEdit( 0 ), mRubberBandLine( 0 ), mRubberBandIcon( 0 )
111
155
{
112
 
#ifdef QGISDEBUG
113
 
  std::cerr << "QgsGrassEdit()" << std::endl;
114
 
#endif
115
 
 
116
 
  setupUi(this);
117
 
  
 
156
  QgsDebugMsg( "QgsGrassEdit()" );
 
157
 
 
158
  setupUi( this );
 
159
 
118
160
  mRunning = true;
119
161
  mValid = false;
120
162
  mTool = QgsGrassEdit::NONE;
121
163
  mSuspend = false;
122
 
  mQgisApp = qgisApp;
123
164
  mIface = iface;
124
 
  mNewMap = false;
125
 
 
126
 
  mProjectionEnabled = (QgsProject::instance()->readNumEntry("SpatialRefSys","/ProjectionsEnabled",0)!=0);
127
 
 
128
 
  mCanvas = mIface->getMapCanvas();
129
 
 
130
 
  // TODO QGIS: crash if canvas is empty
131
 
 
132
 
  // At moment QgisIface::activeLayer() does not work
133
 
  QgsMapLayer *layer = (QgsMapLayer *) mIface->activeLayer();
134
 
 
135
 
  if ( !isEditable(layer) ) return;
136
 
 
137
 
  //TODO dynamic_cast ?
138
 
  mLayer = (QgsVectorLayer*)layer;
139
 
 
140
 
  //TODO dynamic_cast ?
141
 
  mProvider = (QgsGrassProvider *) mLayer->getDataProvider();
 
165
  mNewMap = newMap;
 
166
 
 
167
  mProjectionEnabled = ( QgsProject::instance()->readNumEntry( "SpatialRefSys", "/ProjectionsEnabled", 0 ) != 0 );
 
168
 
 
169
  mCanvas = mIface->mapCanvas();
 
170
 
 
171
  if ( !isEditable( layer ) ) return;
 
172
 
 
173
  //TODO dynamic_cast ?
 
174
  mLayer = ( QgsVectorLayer* )layer;
 
175
 
 
176
  //TODO dynamic_cast ?
 
177
  mProvider = ( QgsGrassProvider * ) mLayer->dataProvider();
142
178
 
143
179
  init();
144
180
 
145
181
}
146
182
 
147
 
bool QgsGrassEdit::isEditable ( QgsMapLayer *layer )
 
183
bool QgsGrassEdit::isEditable( QgsMapLayer *layer )
148
184
{
149
185
  if ( !layer ) return false;
150
186
 
151
 
  QgsDebugMsg("layer name: " + layer->name());
 
187
  QgsDebugMsgLevel( "layer name: " + layer->name(), 3 );
152
188
 
153
 
  if ( layer->type() != QgsMapLayer::VECTOR ) {
154
 
    QgsDebugMsg("The selected layer is not vector.");
 
189
  if ( layer->type() != QgsMapLayer::VectorLayer )
 
190
  {
 
191
    QgsDebugMsgLevel( "The selected layer is not vector.", 3 );
155
192
    return false;
156
193
  }
157
194
 
158
195
  //TODO dynamic_cast ?
159
 
  QgsVectorLayer *vector = (QgsVectorLayer*)layer;
160
 
 
161
 
  QgsDebugMsg("Vector layer type: " + vector->providerType());
162
 
 
163
 
  if ( vector->providerType() != "grass" ) {
164
 
    QgsDebugMsg("The selected layer is not GRASS.");
 
196
  QgsVectorLayer *vector = ( QgsVectorLayer* )layer;
 
197
 
 
198
  QgsDebugMsgLevel( "Vector layer type: " + vector->providerType(), 3 );
 
199
 
 
200
  if ( vector->providerType() != "grass" )
 
201
  {
 
202
    QgsDebugMsgLevel( "The selected layer is not GRASS.", 3 );
165
203
    return false;
166
204
  }
167
205
 
168
206
  return true;
169
207
}
170
208
 
171
 
void QgsGrassEdit::keyPress(QKeyEvent *e) 
172
 
{
173
 
    std::cerr << "QgsGrassEdit::keyPress" << std::endl;
174
 
    // This does not work:
175
 
    //keyPressEvent(e); 
176
 
 
177
 
    // TODO: this is not optimal
178
 
    switch ( e->key() )
179
 
    {
180
 
        case Qt::Key_F1: newPoint(); break;  
181
 
        case Qt::Key_F2: newLine(); break;  
182
 
        case Qt::Key_F3: newBoundary(); break;  
183
 
        case Qt::Key_F4: newCentroid(); break;  
184
 
        case Qt::Key_F5: moveVertex(); break;  
185
 
        case Qt::Key_F6: addVertex(); break;  
186
 
        case Qt::Key_F7: deleteVertex(); break;  
187
 
        case Qt::Key_F9: moveLine(); break;  
188
 
        case Qt::Key_F10: splitLine(); break;  
189
 
        case Qt::Key_F11: deleteLine(); break;  
190
 
        default: break;
191
 
    }
192
 
}
193
 
 
194
 
QgsGrassEdit::QgsGrassEdit ( QgisApp *qgisApp, QgisIface *iface, 
195
 
    QgsGrassProvider *provider,
196
 
    QWidget * parent, Qt::WFlags f )
197
 
    :QMainWindow(parent, 0, f), QgsGrassEditBase (), mMapTool(0),
198
 
    mCanvasEdit(0), mRubberBandLine(0), mRubberBandIcon(0), mInited(false)
199
 
{
200
 
#ifdef QGISDEBUG
201
 
  std::cerr << "QgsGrassEdit()" << std::endl;
202
 
#endif
203
 
 
204
 
  setupUi(this);
205
 
 
206
 
  mRunning = true;
207
 
  mValid = false;
208
 
  mTool = QgsGrassEdit::NONE;
209
 
  mSuspend = false;
210
 
  mQgisApp = qgisApp;
211
 
  mIface = iface;
212
 
  mNewMap = true;
213
 
 
214
 
  mProjectionEnabled = (QgsProject::instance()->readNumEntry("SpatialRefSys","/ProjectionsEnabled",0)!=0);
215
 
 
216
 
  mCanvas = mIface->getMapCanvas();
217
 
 
218
 
  mProvider = provider;
219
 
 
220
 
  init();
221
 
}
 
209
void QgsGrassEdit::keyPress( QKeyEvent *e )
 
210
{
 
211
  QgsDebugMsg( "entered." );
 
212
  // This does not work:
 
213
  //keyPressEvent(e);
 
214
 
 
215
  // TODO: this is not optimal
 
216
  switch ( e->key() )
 
217
  {
 
218
    case Qt::Key_F1: newPoint(); break;
 
219
    case Qt::Key_F2: newLine(); break;
 
220
    case Qt::Key_F3: newBoundary(); break;
 
221
    case Qt::Key_F4: newCentroid(); break;
 
222
    case Qt::Key_F5: moveVertex(); break;
 
223
    case Qt::Key_F6: addVertex(); break;
 
224
    case Qt::Key_F7: deleteVertex(); break;
 
225
    case Qt::Key_F9: moveLine(); break;
 
226
    case Qt::Key_F10: splitLine(); break;
 
227
    case Qt::Key_F11: deleteLine(); break;
 
228
    default: break;
 
229
  }
 
230
}
 
231
 
222
232
 
223
233
void QgsGrassEdit::init()
224
234
{
225
 
  if ( !(mProvider->isGrassEditable()) ) {
226
 
    QMessageBox::warning( 0, tr("Warning"), tr("You are not owner of the mapset, "
227
 
        "cannot open the vector for editing.") );
228
 
    return;
229
 
  }
230
 
 
231
 
  if ( !(mProvider->startEdit()) ) {
232
 
    QMessageBox::warning( 0, tr("Warning"), tr("Cannot open vector for update." ));
233
 
    return;
234
 
  }
235
 
 
236
 
  connect ( mCanvas, SIGNAL(keyPressed(QKeyEvent *)), this, SLOT(keyPress(QKeyEvent *)) );
237
 
 
238
 
  QString myIconPath = QgsApplication::themePath() + "/grass/";
239
 
 
240
 
  mToolBar = addToolBar(tr("Edit tools"));
 
235
  if ( !( mProvider->isGrassEditable() ) )
 
236
  {
 
237
    QMessageBox::warning( 0, tr( "Warning" ),
 
238
                          tr( "You are not owner of the mapset, cannot open the vector for editing." ) );
 
239
    return;
 
240
  }
 
241
 
 
242
  if ( !( mProvider->startEdit() ) )
 
243
  {
 
244
    QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open vector for update." ) );
 
245
    return;
 
246
  }
 
247
 
 
248
  mRubberBandLine = new QgsRubberBand( mCanvas );
 
249
  mRubberBandIcon = new QgsVertexMarker( mCanvas );
 
250
  mRubberBandLine->setZValue( 20 );
 
251
  mRubberBandIcon->setZValue( 20 );
 
252
 
 
253
  connect( mCanvas, SIGNAL( keyPressed( QKeyEvent * ) ), this, SLOT( keyPress( QKeyEvent * ) ) );
 
254
 
 
255
 
 
256
  mToolBar = addToolBar( tr( "Edit tools" ) );
241
257
 
242
258
  mNewPointAction = new QAction(
243
 
          QIcon(myIconPath+"grass_new_point.png"), tr("New point"), this);
244
 
  mNewPointAction->setShortcut ( QKeySequence(Qt::Key_F1) ); 
245
 
  mToolBar->addAction ( mNewPointAction );
246
 
  connect ( mNewPointAction, SIGNAL(triggered()), this, SLOT(newPoint()) );
 
259
    QgsGrassPlugin::getThemeIcon( "grass_new_point.png" ), tr( "New point" ), this );
 
260
  mNewPointAction->setShortcut( QKeySequence( Qt::Key_F1 ) );
 
261
  mToolBar->addAction( mNewPointAction );
 
262
  connect( mNewPointAction, SIGNAL( triggered() ), this, SLOT( newPoint() ) );
247
263
 
248
264
  mNewLineAction = new QAction(
249
 
          QIcon(myIconPath+"grass_new_line.png"), tr("New line"), this);
250
 
  mNewLineAction->setShortcut ( QKeySequence(Qt::Key_F2) ); 
251
 
  mToolBar->addAction ( mNewLineAction );
252
 
  connect ( mNewLineAction, SIGNAL(triggered()), this, SLOT(newLine()) );
 
265
    QgsGrassPlugin::getThemeIcon( "grass_new_line.png" ), tr( "New line" ), this );
 
266
  mNewLineAction->setShortcut( QKeySequence( Qt::Key_F2 ) );
 
267
  mToolBar->addAction( mNewLineAction );
 
268
  connect( mNewLineAction, SIGNAL( triggered() ), this, SLOT( newLine() ) );
253
269
 
254
270
  mNewBoundaryAction = new QAction(
255
 
          QIcon(myIconPath+"grass_new_boundary.png"), tr("New boundary"), this);
256
 
  mNewBoundaryAction->setShortcut ( QKeySequence(Qt::Key_F3) ); 
257
 
  mToolBar->addAction ( mNewBoundaryAction );
258
 
  connect ( mNewBoundaryAction, SIGNAL(triggered()), this, SLOT(newBoundary()) );
 
271
    QgsGrassPlugin::getThemeIcon( "grass_new_boundary.png" ), tr( "New boundary" ), this );
 
272
  mNewBoundaryAction->setShortcut( QKeySequence( Qt::Key_F3 ) );
 
273
  mToolBar->addAction( mNewBoundaryAction );
 
274
  connect( mNewBoundaryAction, SIGNAL( triggered() ), this, SLOT( newBoundary() ) );
259
275
 
260
276
  mNewCentroidAction = new QAction(
261
 
          QIcon(myIconPath+"grass_new_centroid.png"), tr("New centroid"), this);
262
 
  mNewCentroidAction->setShortcut ( QKeySequence(Qt::Key_F4) ); 
263
 
  mToolBar->addAction ( mNewCentroidAction );
264
 
  connect ( mNewCentroidAction, SIGNAL(triggered()), this, SLOT(newCentroid()) );
 
277
    QgsGrassPlugin::getThemeIcon( "grass_new_centroid.png" ), tr( "New centroid" ), this );
 
278
  mNewCentroidAction->setShortcut( QKeySequence( Qt::Key_F4 ) );
 
279
  mToolBar->addAction( mNewCentroidAction );
 
280
  connect( mNewCentroidAction, SIGNAL( triggered() ), this, SLOT( newCentroid() ) );
265
281
 
266
282
  mMoveVertexAction = new QAction(
267
 
          QIcon(myIconPath+"grass_move_vertex.png"), tr("Move vertex"), this);
268
 
  mMoveVertexAction->setShortcut ( QKeySequence(Qt::Key_F5) ); 
269
 
  mToolBar->addAction ( mMoveVertexAction );
270
 
  connect ( mMoveVertexAction, SIGNAL(triggered()), this, SLOT(moveVertex()) );
 
283
    QgsGrassPlugin::getThemeIcon( "grass_move_vertex.png" ), tr( "Move vertex" ), this );
 
284
  mMoveVertexAction->setShortcut( QKeySequence( Qt::Key_F5 ) );
 
285
  mToolBar->addAction( mMoveVertexAction );
 
286
  connect( mMoveVertexAction, SIGNAL( triggered() ), this, SLOT( moveVertex() ) );
271
287
 
272
288
  mAddVertexAction = new QAction(
273
 
          QIcon(myIconPath+"grass_add_vertex.png"), tr("Add vertex"), this);
274
 
  mAddVertexAction->setShortcut ( QKeySequence(Qt::Key_F6) ); 
275
 
  mToolBar->addAction ( mAddVertexAction );
276
 
  connect ( mAddVertexAction, SIGNAL(triggered()), this, SLOT(addVertex()) );
 
289
    QgsGrassPlugin::getThemeIcon( "grass_add_vertex.png" ), tr( "Add vertex" ), this );
 
290
  mAddVertexAction->setShortcut( QKeySequence( Qt::Key_F6 ) );
 
291
  mToolBar->addAction( mAddVertexAction );
 
292
  connect( mAddVertexAction, SIGNAL( triggered() ), this, SLOT( addVertex() ) );
277
293
 
278
294
  mDeleteVertexAction = new QAction(
279
 
          QIcon(myIconPath+"grass_delete_vertex.png"), tr("Delete vertex"), this);
280
 
  mDeleteVertexAction->setShortcut ( QKeySequence(Qt::Key_F7) ); 
281
 
  mToolBar->addAction ( mDeleteVertexAction );
282
 
  connect ( mDeleteVertexAction, SIGNAL(triggered()), this, SLOT(deleteVertex()) );
 
295
    QgsGrassPlugin::getThemeIcon( "grass_delete_vertex.png" ), tr( "Delete vertex" ), this );
 
296
  mDeleteVertexAction->setShortcut( QKeySequence( Qt::Key_F7 ) );
 
297
  mToolBar->addAction( mDeleteVertexAction );
 
298
  connect( mDeleteVertexAction, SIGNAL( triggered() ), this, SLOT( deleteVertex() ) );
283
299
 
284
300
  mMoveLineAction = new QAction(
285
 
          QIcon(myIconPath+"grass_move_line.png"), tr("Move element"), this);
286
 
  mMoveLineAction->setShortcut ( QKeySequence(Qt::Key_F9) ); 
287
 
  mToolBar->addAction ( mMoveLineAction );
288
 
  connect ( mMoveLineAction, SIGNAL(triggered()), this, SLOT(moveLine()) );
 
301
    QgsGrassPlugin::getThemeIcon( "grass_move_line.png" ), tr( "Move element" ), this );
 
302
  mMoveLineAction->setShortcut( QKeySequence( Qt::Key_F9 ) );
 
303
  mToolBar->addAction( mMoveLineAction );
 
304
  connect( mMoveLineAction, SIGNAL( triggered() ), this, SLOT( moveLine() ) );
289
305
 
290
306
  mSplitLineAction = new QAction(
291
 
          QIcon(myIconPath+"grass_split_line.png"), tr("Split line"), this);
292
 
  mSplitLineAction->setShortcut ( QKeySequence(Qt::Key_F10) ); 
293
 
  mToolBar->addAction ( mSplitLineAction );
294
 
  connect ( mSplitLineAction, SIGNAL(triggered()), this, SLOT(splitLine()) );
 
307
    QgsGrassPlugin::getThemeIcon( "grass_split_line.png" ), tr( "Split line" ), this );
 
308
  mSplitLineAction->setShortcut( QKeySequence( Qt::Key_F10 ) );
 
309
  mToolBar->addAction( mSplitLineAction );
 
310
  connect( mSplitLineAction, SIGNAL( triggered() ), this, SLOT( splitLine() ) );
295
311
 
296
312
  mDeleteLineAction = new QAction(
297
 
          QIcon(myIconPath+"grass_delete_line.png"), tr("Delete element"), this);
298
 
  mDeleteLineAction->setShortcut ( QKeySequence(Qt::Key_F11) ); 
299
 
  mToolBar->addAction ( mDeleteLineAction );
300
 
  connect ( mDeleteLineAction, SIGNAL(triggered()), this, SLOT(deleteLine()) );
 
313
    QgsGrassPlugin::getThemeIcon( "grass_delete_line.png" ), tr( "Delete element" ), this );
 
314
  mDeleteLineAction->setShortcut( QKeySequence( Qt::Key_F11 ) );
 
315
  mToolBar->addAction( mDeleteLineAction );
 
316
  connect( mDeleteLineAction, SIGNAL( triggered() ), this, SLOT( deleteLine() ) );
301
317
 
302
318
  mEditAttributesAction = new QAction(
303
 
          QIcon(myIconPath+"grass_edit_attributes.png"), tr("Edit attributes"), this);
304
 
  mToolBar->addAction ( mEditAttributesAction );
305
 
  connect ( mEditAttributesAction, SIGNAL(triggered()), this, SLOT(editAttributes()) );
 
319
    QgsGrassPlugin::getThemeIcon( "grass_edit_attributes.png" ), tr( "Edit attributes" ), this );
 
320
  mToolBar->addAction( mEditAttributesAction );
 
321
  connect( mEditAttributesAction, SIGNAL( triggered() ), this, SLOT( editAttributes() ) );
306
322
 
307
323
  mCloseEditAction = new QAction(
308
 
          QIcon(myIconPath+"grass_close_edit.png"), tr("Close"), this);
309
 
  mToolBar->addAction ( mCloseEditAction );
310
 
  connect ( mCloseEditAction, SIGNAL(triggered()), this, SLOT(closeEdit()) );
311
 
  
312
 
  mNewPointAction->setCheckable ( true );
313
 
  mNewLineAction->setCheckable ( true );
314
 
  mNewBoundaryAction->setCheckable ( true );
315
 
  mNewCentroidAction->setCheckable ( true );
316
 
  mMoveVertexAction->setCheckable ( true );
317
 
  mAddVertexAction->setCheckable ( true );
318
 
  mDeleteVertexAction->setCheckable ( true );
319
 
  mMoveLineAction->setCheckable ( true );
320
 
  mSplitLineAction->setCheckable ( true );
321
 
  mDeleteLineAction->setCheckable ( true );
322
 
  mEditAttributesAction->setCheckable ( true );
323
 
  
324
 
  QActionGroup *ag = new QActionGroup ( this );
325
 
  ag->addAction ( mNewPointAction );
326
 
  ag->addAction ( mNewLineAction );
327
 
  ag->addAction ( mNewBoundaryAction );
328
 
  ag->addAction ( mNewCentroidAction );
329
 
  ag->addAction ( mMoveVertexAction );
330
 
  ag->addAction ( mAddVertexAction );
331
 
  ag->addAction ( mDeleteVertexAction );
332
 
  ag->addAction ( mMoveLineAction );
333
 
  ag->addAction ( mSplitLineAction );
334
 
  ag->addAction ( mDeleteLineAction );
335
 
  ag->addAction ( mEditAttributesAction );
336
 
  
337
 
  mEditPoints = Vect_new_line_struct ();
338
 
  mPoints = Vect_new_line_struct ();
339
 
  mCats = Vect_new_cats_struct ();
 
324
    QgsGrassPlugin::getThemeIcon( "grass_close_edit.png" ), tr( "Close" ), this );
 
325
  mToolBar->addAction( mCloseEditAction );
 
326
  connect( mCloseEditAction, SIGNAL( triggered() ), this, SLOT( closeEdit() ) );
 
327
 
 
328
  mNewPointAction->setCheckable( true );
 
329
  mNewLineAction->setCheckable( true );
 
330
  mNewBoundaryAction->setCheckable( true );
 
331
  mNewCentroidAction->setCheckable( true );
 
332
  mMoveVertexAction->setCheckable( true );
 
333
  mAddVertexAction->setCheckable( true );
 
334
  mDeleteVertexAction->setCheckable( true );
 
335
  mMoveLineAction->setCheckable( true );
 
336
  mSplitLineAction->setCheckable( true );
 
337
  mDeleteLineAction->setCheckable( true );
 
338
  mEditAttributesAction->setCheckable( true );
 
339
 
 
340
  QActionGroup *ag = new QActionGroup( this );
 
341
  ag->addAction( mNewPointAction );
 
342
  ag->addAction( mNewLineAction );
 
343
  ag->addAction( mNewBoundaryAction );
 
344
  ag->addAction( mNewCentroidAction );
 
345
  ag->addAction( mMoveVertexAction );
 
346
  ag->addAction( mAddVertexAction );
 
347
  ag->addAction( mDeleteVertexAction );
 
348
  ag->addAction( mMoveLineAction );
 
349
  ag->addAction( mSplitLineAction );
 
350
  ag->addAction( mDeleteLineAction );
 
351
  ag->addAction( mEditAttributesAction );
 
352
 
 
353
  mEditPoints = Vect_new_line_struct();
 
354
  mPoints = Vect_new_line_struct();
 
355
  mCats = Vect_new_cats_struct();
340
356
 
341
357
  // Set lines symbology from map
342
 
  int nlines = mProvider->numLines(); 
343
 
  mLineSymb.resize(nlines+1000);
344
 
  for ( int line = 1; line <= nlines; line++ ) {
345
 
    mLineSymb[line] = lineSymbFromMap ( line );
 
358
  int nlines = mProvider->numLines();
 
359
  mLineSymb.resize( nlines + 1000 );
 
360
  for ( int line = 1; line <= nlines; line++ )
 
361
  {
 
362
    mLineSymb[line] = lineSymbFromMap( line );
346
363
  }
347
364
 
348
365
  // Set nodes symbology from map
349
 
  int nnodes = mProvider->numNodes(); 
350
 
  mNodeSymb.resize(nnodes+1000); 
351
 
  for ( int node = 1; node <= nnodes; node++ ) {
352
 
    mNodeSymb[node] = nodeSymbFromMap ( node );
 
366
  int nnodes = mProvider->numNodes();
 
367
  mNodeSymb.resize( nnodes + 1000 );
 
368
  for ( int node = 1; node <= nnodes; node++ )
 
369
  {
 
370
    mNodeSymb[node] = nodeSymbFromMap( node );
353
371
  }
354
372
 
355
373
  // Set default colors
356
 
  mSymb.resize(SYMB_COUNT);
357
 
  mSymb[SYMB_BACKGROUND].setColor    ( QColor ( 255, 255, 255 ) );  // white
358
 
  mSymb[SYMB_HIGHLIGHT].setColor     ( QColor ( 255, 255,   0 ) );  // yellow
359
 
  mSymb[SYMB_DYNAMIC].setColor       ( QColor ( 125, 125, 125 ) );  // grey
360
 
  mSymb[SYMB_POINT].setColor         ( QColor (   0,   0,   0 ) );  // black
361
 
  mSymb[SYMB_LINE].setColor          ( QColor (   0,   0,   0 ) );  // black
362
 
  mSymb[SYMB_BOUNDARY_0].setColor    ( QColor ( 255,   0,   0 ) );  // red
363
 
  mSymb[SYMB_BOUNDARY_1].setColor    ( QColor ( 255, 125,   0 ) );  // orange
364
 
  mSymb[SYMB_BOUNDARY_2].setColor    ( QColor (   0, 255,   0 ) );  // green
365
 
  mSymb[SYMB_CENTROID_IN].setColor   ( QColor (   0, 255,   0 ) );  // green
366
 
  mSymb[SYMB_CENTROID_OUT].setColor  ( QColor ( 255,   0,   0 ) );  // red
367
 
  mSymb[SYMB_CENTROID_DUPL].setColor ( QColor ( 255,   0, 255 ) );  // magenta
368
 
  mSymb[SYMB_NODE_1].setColor        ( QColor ( 255,   0,   0 ) );  // red
369
 
  mSymb[SYMB_NODE_2].setColor        ( QColor (   0, 255,   0 ) );  // green
 
374
  mSymb.resize( SYMB_COUNT );
 
375
  mSymb[SYMB_BACKGROUND].setColor( QColor( 255, 255, 255 ) );       // white
 
376
  mSymb[SYMB_HIGHLIGHT].setColor( QColor( 255, 255,   0 ) );        // yellow
 
377
  mSymb[SYMB_DYNAMIC].setColor( QColor( 125, 125, 125 ) );          // grey
 
378
  mSymb[SYMB_POINT].setColor( QColor( 0,   0,   0 ) );              // black
 
379
  mSymb[SYMB_LINE].setColor( QColor( 0,   0,   0 ) );               // black
 
380
  mSymb[SYMB_BOUNDARY_0].setColor( QColor( 255,   0,   0 ) );       // red
 
381
  mSymb[SYMB_BOUNDARY_1].setColor( QColor( 255, 125,   0 ) );       // orange
 
382
  mSymb[SYMB_BOUNDARY_2].setColor( QColor( 0, 255,   0 ) );         // green
 
383
  mSymb[SYMB_CENTROID_IN].setColor( QColor( 0, 255,   0 ) );        // green
 
384
  mSymb[SYMB_CENTROID_OUT].setColor( QColor( 255,   0,   0 ) );     // red
 
385
  mSymb[SYMB_CENTROID_DUPL].setColor( QColor( 255,   0, 255 ) );    // magenta
 
386
  mSymb[SYMB_NODE_1].setColor( QColor( 255,   0,   0 ) );           // red
 
387
  mSymb[SYMB_NODE_2].setColor( QColor( 0, 255,   0 ) );             // green
370
388
 
371
389
  // Set mSymbDisplay
372
 
  mSymbDisplay.resize(SYMB_COUNT);
 
390
  mSymbDisplay.resize( SYMB_COUNT );
373
391
  mSymbDisplay[SYMB_BACKGROUND] = true;
374
392
  mSymbDisplay[SYMB_HIGHLIGHT] = true;
375
393
  mSymbDisplay[SYMB_DYNAMIC] = true;
385
403
  mSymbDisplay[SYMB_NODE_2] = true;
386
404
 
387
405
  // Set symbology names
388
 
  mSymbName.resize(SYMB_COUNT);
389
 
  mSymbName[SYMB_BACKGROUND]    = tr("Background");
390
 
  mSymbName[SYMB_HIGHLIGHT]     = tr("Highlight");
391
 
  mSymbName[SYMB_DYNAMIC]       = tr("Dynamic");
392
 
  mSymbName[SYMB_POINT]         = tr("Point");
393
 
  mSymbName[SYMB_LINE]          = tr("Line");
394
 
  mSymbName[SYMB_BOUNDARY_0]    = tr("Boundary (no area)");
395
 
  mSymbName[SYMB_BOUNDARY_1]    = tr("Boundary (1 area)");
396
 
  mSymbName[SYMB_BOUNDARY_2]    = tr("Boundary (2 areas)");
397
 
  mSymbName[SYMB_CENTROID_IN]   = tr("Centroid (in area)");
398
 
  mSymbName[SYMB_CENTROID_OUT]  = tr("Centroid (outside area)");
399
 
  mSymbName[SYMB_CENTROID_DUPL] = tr("Centroid (duplicate in area)");
400
 
  mSymbName[SYMB_NODE_1]        = tr("Node (1 line)");
401
 
  mSymbName[SYMB_NODE_2]        = tr("Node (2 lines)");
 
406
  mSymbName.resize( SYMB_COUNT );
 
407
  mSymbName[SYMB_BACKGROUND]    = tr( "Background" );
 
408
  mSymbName[SYMB_HIGHLIGHT]     = tr( "Highlight" );
 
409
  mSymbName[SYMB_DYNAMIC]       = tr( "Dynamic" );
 
410
  mSymbName[SYMB_POINT]         = tr( "Point" );
 
411
  mSymbName[SYMB_LINE]          = tr( "Line" );
 
412
  mSymbName[SYMB_BOUNDARY_0]    = tr( "Boundary (no area)" );
 
413
  mSymbName[SYMB_BOUNDARY_1]    = tr( "Boundary (1 area)" );
 
414
  mSymbName[SYMB_BOUNDARY_2]    = tr( "Boundary (2 areas)" );
 
415
  mSymbName[SYMB_CENTROID_IN]   = tr( "Centroid (in area)" );
 
416
  mSymbName[SYMB_CENTROID_OUT]  = tr( "Centroid (outside area)" );
 
417
  mSymbName[SYMB_CENTROID_DUPL] = tr( "Centroid (duplicate in area)" );
 
418
  mSymbName[SYMB_NODE_1]        = tr( "Node (1 line)" );
 
419
  mSymbName[SYMB_NODE_2]        = tr( "Node (2 lines)" );
402
420
 
403
421
  // Restore symbology
404
422
  QString spath = "/GRASS/edit/symb/";
405
423
  QSettings settings;
406
424
 
407
 
  mLineWidth = settings.readNumEntry (
408
 
                 spath + "lineWidth", 1 );
409
 
  mSize = settings.readNumEntry (
410
 
                 spath + "markerSize", 9 );
411
 
  mLineWidthSpinBox->setValue(mLineWidth);
412
 
  mMarkerSizeSpinBox->setValue(mSize);
 
425
  mLineWidth = settings.value(
 
426
                 spath + "lineWidth", 1 ).toInt();
 
427
  mSize = settings.value(
 
428
            spath + "markerSize", 9 ).toInt();
 
429
  mLineWidthSpinBox->setValue( mLineWidth );
 
430
  mMarkerSizeSpinBox->setValue( mSize );
413
431
 
414
 
  for ( int i = 0; i < SYMB_COUNT; i++ ) {
415
 
    bool ok;
416
 
    bool displ = settings.readBoolEntry ( 
417
 
                  spath + "display/" + QString::number(i), 
418
 
                  true, &ok );
419
 
    if ( ok ) {
 
432
  for ( int i = 0; i < SYMB_COUNT; i++ )
 
433
  {
 
434
    bool ok = settings.contains(
 
435
                spath + "display/" + QString::number( i ) );
 
436
    bool displ = settings.value(
 
437
                   spath + "display/" + QString::number( i ),
 
438
                   true ).toBool();
 
439
    if ( ok )
 
440
    {
420
441
      mSymbDisplay[i] = displ;
421
442
    }
422
443
 
423
 
    QString colorName = settings.readEntry (
424
 
                 spath + "color/" + QString::number(i), 
425
 
                 "", &ok );
426
 
    if ( ok ) {
 
444
    ok = settings.contains(
 
445
           spath + "color/" + QString::number( i ) );
 
446
    QString colorName = settings.value(
 
447
                          spath + "color/" + QString::number( i ),
 
448
                          "" ).toString();
 
449
    if ( ok )
 
450
    {
427
451
      QColor color( colorName );
428
452
      mSymb[i].setColor( color );
 
453
      // Use the 'dynamic' color for mRubberBand
 
454
      if ( i == SYMB_DYNAMIC )
 
455
      {
 
456
        mRubberBandLine->setColor( QColor( colorName ) );
 
457
      }
429
458
    }
430
459
    mSymb[i].setWidth( mLineWidth );
431
460
  }
432
461
 
433
462
  // Set Symbology in dialog
434
 
  symbologyList->setColumnText(0,tr("Disp","Column title") );
435
 
  symbologyList->setColumnWidth(0,20);
436
 
  symbologyList->addColumn( tr("Color","Column title") );
437
 
  symbologyList->setColumnWidth(0,50);
438
 
  symbologyList->addColumn( tr("Type","Column title") );
439
 
  symbologyList->setColumnWidthMode(2,Q3ListView::Maximum);
440
 
  symbologyList->addColumn(tr("Index","Column title") , 0);
441
 
  symbologyList->clear();
442
 
  symbologyList->setSorting(-1);
 
463
  symbologyList->setColumnWidth( 0, 40 );
 
464
  symbologyList->setColumnWidth( 1, 50 );
 
465
  symbologyList->setColumnWidth( 2, 200 );
443
466
 
444
 
  for ( int i = SYMB_COUNT-1; i >= 0; i-- ) {
 
467
  for ( int i = 0; i < SYMB_COUNT; i++ )
 
468
  {
445
469
    if ( i == SYMB_NODE_0 ) continue;
446
470
 
447
 
    QPixmap pm ( 40, 15 );
 
471
    QPixmap pm( 40, 15 );
448
472
    pm.fill( mSymb[i].color() );
449
473
    QString index;
450
 
    index.sprintf ("%d", i );
 
474
    index.sprintf( "%d", i );
451
475
 
452
 
    if ( i == SYMB_BACKGROUND || i == SYMB_HIGHLIGHT || i == SYMB_DYNAMIC ) { 
453
 
      Q3ListViewItem *lvi = new Q3ListViewItem ( symbologyList , "", "", mSymbName[i] );
454
 
      lvi->setPixmap ( 1, pm );
455
 
      lvi->setText ( 3, index );
456
 
    } else {
457
 
      Q3CheckListItem *clvi = new Q3CheckListItem ( symbologyList , "", Q3CheckListItem::CheckBox );
458
 
      clvi->setText ( 2, mSymbName[i] );
459
 
      clvi->setPixmap ( 1, pm );
460
 
      clvi->setOn ( mSymbDisplay[i] );
461
 
      clvi->setText ( 3, index );
 
476
    QTreeWidgetItem *item = new QTreeWidgetItem( symbologyList );
 
477
    if ( !( i == SYMB_BACKGROUND || i == SYMB_HIGHLIGHT || i == SYMB_DYNAMIC ) )
 
478
    {
 
479
      item->setCheckState( 0, mSymbDisplay[i] ? Qt::Checked : Qt::Unchecked );
462
480
    }
 
481
    item->setIcon( 1, pm );
 
482
    item->setText( 2, mSymbName[i] );
 
483
    item->setText( 3, index );
463
484
  }
464
485
 
465
 
  connect( symbologyList, SIGNAL(pressed(Q3ListViewItem *, const QPoint &, int)), 
466
 
      this, SLOT(changeSymbology(Q3ListViewItem *, const QPoint &, int)));
 
486
  connect( symbologyList, SIGNAL( itemPressed( QTreeWidgetItem *, int ) ),
 
487
           this, SLOT( changeSymbology( QTreeWidgetItem *, int ) ) );
467
488
 
468
489
  // Init table tab
469
 
  mAttributeTable->setLeftMargin(0); // hide row labels
470
 
  mAttributeTable->horizontalHeader()->setLabel( 0, tr("Column") );
471
 
  mAttributeTable->horizontalHeader()->setLabel( 1, tr("Type") );
472
 
  mAttributeTable->horizontalHeader()->setLabel( 2, tr("Length") );
 
490
  mAttributeTable->setItemDelegate( new QgsGrassEditAttributeTableItemDelegate( this ) );
 
491
  mAttributeTable->verticalHeader()->hide();
473
492
 
474
493
  int ndblinks = mProvider->numDbLinks();
475
494
 
476
 
  if ( ndblinks > 0 ) {
477
 
    for ( int i = 0; i < ndblinks; i++ ) {
478
 
      int f = mProvider->dbLinkField ( i ); 
 
495
  if ( ndblinks > 0 )
 
496
  {
 
497
    for ( int i = 0; i < ndblinks; i++ )
 
498
    {
 
499
      int f = mProvider->dbLinkField( i );
479
500
 
480
501
      QString str;
481
 
      str.sprintf ( "%d", f );  
482
 
      mTableField->insertItem ( str );
483
 
      mFieldBox->insertItem( str );
484
 
      if ( i == 0 ) {
 
502
      str.sprintf( "%d", f );
 
503
      mTableField->addItem( str );
 
504
      mFieldBox->addItem( str );
 
505
      if ( i == 0 )
 
506
      {
485
507
        setAttributeTable( f );
486
508
      }
487
509
    }
488
 
    mTableField->setCurrentItem ( 0 ); 
489
 
    mFieldBox->setCurrentItem ( 0 );
490
 
  } else { 
491
 
    mTableField->insertItem ( "1" );
492
 
    setAttributeTable ( 1 );
493
 
 
494
 
    mFieldBox->insertItem("1");
495
 
  }
496
 
 
497
 
  connect( mAttributeTable, SIGNAL(valueChanged(int,int)), this, SLOT(columnTypeChanged(int,int)) );
 
510
    mTableField->setCurrentIndex( 0 );
 
511
    mFieldBox->setCurrentIndex( 0 );
 
512
  }
 
513
  else
 
514
  {
 
515
    mTableField->addItem( "1" );
 
516
    setAttributeTable( 1 );
 
517
 
 
518
    mFieldBox->addItem( "1" );
 
519
  }
 
520
 
 
521
  connect( mAttributeTable, SIGNAL( cellChanged( int, int ) ), this, SLOT( columnTypeChanged( int, int ) ) );
498
522
 
499
523
  // Set variables
500
524
  mSelectedLine = 0;
501
525
  mAttributes = 0;
502
526
 
503
527
  // Read max cats
504
 
  for (int i = 0; i < mProvider->cidxGetNumFields(); i++ ) {
505
 
    int field = mProvider->cidxGetFieldNumber(i);
506
 
    if ( field > 0 ) {
507
 
      int cat = mProvider->cidxGetMaxCat(i);
 
528
  for ( int i = 0; i < mProvider->cidxGetNumFields(); i++ )
 
529
  {
 
530
    int field = mProvider->cidxGetFieldNumber( i );
 
531
    if ( field > 0 )
 
532
    {
 
533
      int cat = mProvider->cidxGetMaxCat( i );
508
534
      MaxCat mc;
509
535
      mc.field = field;
510
536
      mc.maxCat = cat;
511
 
      mMaxCats.push_back(mc);
 
537
      mMaxCats.push_back( mc );
512
538
    }
513
539
  }
514
540
 
515
 
  connect( mCanvas, SIGNAL(renderComplete(QPainter *)), this, SLOT(postRender(QPainter *)));
516
 
 
517
 
  mCanvasEdit = new QgsGrassEditLayer(mCanvas);
518
 
  mCanvasEdit->show();
519
 
  
 
541
  connect( mCanvas, SIGNAL( renderComplete( QPainter * ) ), this, SLOT( postRender( QPainter * ) ) );
 
542
 
 
543
  mCanvasEdit = new QgsGrassEditLayer( mCanvas );
 
544
 
520
545
  mPixmap = &mCanvasEdit->pixmap();
521
546
 
522
 
  mRubberBandLine = new QgsRubberBand(mCanvas);
523
 
  mRubberBandIcon = new QgsVertexMarker(mCanvas);
524
 
  mRubberBandLine->setZ(20);
525
 
  mRubberBandIcon->setZ(20);
526
 
  mRubberBandLine->show();
527
 
  mRubberBandIcon->show();
528
 
 
529
547
  // Init GUI values
530
 
  mCatModeBox->insertItem( tr("Next not used"), CAT_MODE_NEXT );
531
 
  mCatModeBox->insertItem( tr("Manual entry"), CAT_MODE_MANUAL );
532
 
  mCatModeBox->insertItem( tr("No category"), CAT_MODE_NOCAT );
533
 
  catModeChanged ( );
 
548
  mCatModeBox->addItem( tr( "Next not used" ), CAT_MODE_NEXT );
 
549
  mCatModeBox->addItem( tr( "Manual entry" ), CAT_MODE_MANUAL );
 
550
  mCatModeBox->addItem( tr( "No category" ), CAT_MODE_NOCAT );
 
551
  catModeChanged( );
534
552
 
535
553
  // TODO: how to get keyboard events from canvas (shortcuts)
536
554
 
537
 
  newPoint();
538
 
 
539
555
  restorePosition();
540
556
 
541
 
  mValid = true; 
542
 
  mInited = true; 
 
557
  mValid = true;
 
558
  mInited = true;
543
559
}
544
560
 
545
 
void QgsGrassEdit::attributeTableFieldChanged ( void )
 
561
void QgsGrassEdit::attributeTableFieldChanged( void )
546
562
{
547
 
#ifdef QGISDEBUG
548
 
  std::cerr << "QgsGrassEdit::attributeTableFieldChanged" << std::endl;
549
 
#endif
 
563
  QgsDebugMsg( "entered." );
550
564
  int field = mTableField->currentText().toInt();
551
565
 
552
 
  setAttributeTable ( field );
 
566
  setAttributeTable( field );
553
567
}
554
568
 
555
 
void QgsGrassEdit::setAttributeTable ( int field )
 
569
void QgsGrassEdit::setAttributeTable( int field )
556
570
{
557
 
  mAttributeTable->setNumRows ( 0 );
558
 
 
559
 
  QString *key = mProvider->key ( field );
560
 
 
561
 
  if ( !key->isEmpty() ) { // Database link defined
562
 
    std::vector<QgsField> *cols = mProvider->columns ( field );
563
 
 
564
 
    mAttributeTable->setNumRows ( cols->size() );
565
 
 
566
 
 
567
 
    for ( int c = 0; c < cols->size(); c++ ) {
568
 
      QgsField col = (*cols)[c];
569
 
 
570
 
      Q3TableItem *ti;
571
 
 
572
 
      ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, col.name() );
573
 
      ti->setEnabled( false );
574
 
      mAttributeTable->setItem ( c, 0, ti );
575
 
 
576
 
      ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, col.type() );
577
 
      ti->setEnabled( false );
578
 
      mAttributeTable->setItem ( c, 1, ti );
 
571
  mAttributeTable->setRowCount( 0 );
 
572
 
 
573
  QString *key = mProvider->key( field );
 
574
 
 
575
  if ( !key->isEmpty() )   // Database link defined
 
576
  {
 
577
    std::vector<QgsField> *cols = mProvider->columns( field );
 
578
 
 
579
    mAttributeTable->setRowCount( cols->size() );
 
580
 
 
581
 
 
582
    for ( unsigned int c = 0; c < cols->size(); c++ )
 
583
    {
 
584
      QgsField col = ( *cols )[c];
 
585
 
 
586
      QTableWidgetItem *ti;
 
587
 
 
588
      ti = new QTableWidgetItem( col.name() );
 
589
      ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
 
590
      mAttributeTable->setItem( c, 0, ti );
 
591
 
 
592
      ti = new QTableWidgetItem( col.typeName() );
 
593
      ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
 
594
      mAttributeTable->setItem( c, 1, ti );
579
595
 
580
596
      QString str;
581
 
      str.sprintf("%d", col.length() );
582
 
      ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, str );
583
 
      ti->setEnabled( false );
584
 
      mAttributeTable->setItem ( c, 2, ti );
 
597
      str.sprintf( "%d", col.length() );
 
598
      ti = new QTableWidgetItem( str );
 
599
      ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
 
600
      mAttributeTable->setItem( c, 2, ti );
585
601
    }
586
 
  } else {
587
 
    mAttributeTable->setNumRows ( 1 );
588
 
 
589
 
    Q3TableItem *ti;
590
 
 
591
 
    ti = new Q3TableItem( mAttributeTable, Q3TableItem::Always, "cat" );
592
 
    mAttributeTable->setItem ( 0, 0, ti );
593
 
 
594
 
    ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, "integer" );
595
 
    ti->setEnabled( false );
596
 
    mAttributeTable->setItem ( 0, 1, ti );
597
 
 
598
 
    ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, "" );
599
 
    ti->setEnabled( false );
600
 
    mAttributeTable->setItem ( 0, 2, ti );
 
602
  }
 
603
  else
 
604
  {
 
605
    mAttributeTable->setRowCount( 1 );
 
606
 
 
607
    QTableWidgetItem *ti;
 
608
 
 
609
    ti = new QTableWidgetItem( "cat" );
 
610
    mAttributeTable->setItem( 0, 0, ti );
 
611
 
 
612
    ti = new QTableWidgetItem( "integer" );
 
613
    ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
 
614
    mAttributeTable->setItem( 0, 1, ti );
 
615
 
 
616
    ti = new QTableWidgetItem( "" );
 
617
    ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
 
618
    mAttributeTable->setItem( 0, 2, ti );
601
619
  }
602
620
}
603
621
 
604
 
void QgsGrassEdit::addColumn ( void )
 
622
void QgsGrassEdit::addColumn( void )
605
623
{
606
 
#ifdef QGISDEBUG
607
 
  std::cerr << "QgsGrassEdit::addColumn()" << std::endl;
608
 
#endif
609
 
  int r = mAttributeTable->numRows();
610
 
  mAttributeTable->setNumRows( r+1 );
611
 
  mAttributeTable->setRowReadOnly ( r, false );
 
624
  QgsDebugMsg( "entered." );
 
625
  int r = mAttributeTable->rowCount();
 
626
  mAttributeTable->setRowCount( r + 1 );
612
627
 
613
628
  QString cn;
614
 
  cn.sprintf ( "column%d", r+1 );
615
 
 
616
 
  Q3TableItem *ti;
617
 
 
618
 
  ti = new Q3TableItem( mAttributeTable, Q3TableItem::Always, cn );
619
 
  mAttributeTable->setItem ( r, 0, ti );
620
 
 
621
 
  QStringList types;
622
 
  types.push_back ( "integer" );
623
 
  types.push_back ( "double precision" );
624
 
  types.push_back ( "varchar" );
625
 
 
626
 
  Q3ComboTableItem *cti = new Q3ComboTableItem ( mAttributeTable, types ); 
627
 
  cti->setCurrentItem(0);
628
 
  mAttributeTable->setItem ( r, 1, cti );
629
 
 
630
 
  ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, "20" );
631
 
  ti->setEnabled(false);
632
 
  mAttributeTable->setItem ( r, 2, ti );
 
629
  cn.sprintf( "column%d", r + 1 );
 
630
 
 
631
  QTableWidgetItem *ti;
 
632
 
 
633
  ti = new QTableWidgetItem( cn );
 
634
  mAttributeTable->setItem( r, 0, ti );
 
635
 
 
636
  ti = new QTableWidgetItem( "integer" );
 
637
  mAttributeTable->setItem( r, 1, ti );
 
638
 
 
639
  ti = new QTableWidgetItem( "20" );
 
640
  ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
 
641
  mAttributeTable->setItem( r, 2, ti );
633
642
}
634
643
 
635
 
void QgsGrassEdit::columnTypeChanged ( int row, int col )
 
644
void QgsGrassEdit::columnTypeChanged( int row, int col )
636
645
{
637
 
#ifdef QGISDEBUG
638
 
  std::cerr << "QgsGrassEdit::columnChanged() row = " << row << " col = " << col << std::endl;
639
 
#endif
 
646
  QgsDebugMsg( QString( "row = %1 col = %2" ).arg( row ).arg( col ) );
640
647
 
641
648
  if ( col != 1 ) return;
642
649
 
643
 
  Q3ComboTableItem *cti = (Q3ComboTableItem *) mAttributeTable->item ( row, 1 ); 
644
 
 
645
 
  Q3TableItem *ti = mAttributeTable->item ( row, 2 );
646
 
 
647
 
  if ( cti->currentText().compare( "varchar" ) != 0 ) {
648
 
    Q3TableItem *nti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, ti->text() );
649
 
    nti->setEnabled(false);
650
 
    mAttributeTable->setItem ( row, 2, nti );
651
 
    //delete ti;
652
 
  } else {
653
 
    Q3TableItem *nti = new Q3TableItem( mAttributeTable, Q3TableItem::Always, ti->text() );
654
 
    nti->setEnabled(true);
655
 
    mAttributeTable->setItem ( row, 2, nti );
656
 
    //delete ti;
 
650
  QTableWidgetItem *ti = mAttributeTable->item( row, 2 );
 
651
  if ( ti )
 
652
  {
 
653
    if ( mAttributeTable->item( row, 1 )->text().compare( "varchar" ) == 0 )
 
654
    {
 
655
      ti->setFlags( ti->flags() | Qt::ItemIsEnabled );
 
656
    }
 
657
    else
 
658
    {
 
659
      ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
 
660
    }
657
661
  }
658
 
  mAttributeTable->updateCell ( row, 2 );
659
662
}
660
663
 
661
 
void QgsGrassEdit::alterTable ( void )
 
664
void QgsGrassEdit::alterTable( void )
662
665
{
663
 
#ifdef QGISDEBUG
664
 
  std::cerr << "QgsGrassEdit::alterTable()" << std::endl;
665
 
#endif
 
666
  QgsDebugMsg( "entered." );
666
667
 
667
668
  // Create new table if first column name is editable otherwise alter table
668
669
  int field = mTableField->currentText().toInt();
669
670
 
670
 
  Q3TableItem *ti;
671
 
  ti = mAttributeTable->item ( 0, 0 );
672
 
 
673
671
  QString sql;
674
 
 
675
 
  if ( mAttributeTable->item(0,0)->isEnabled() ) {
676
 
#ifdef QGISDEBUG
677
 
    std::cerr << "Create new table" << std::endl;
678
 
#endif
679
 
 
680
 
    for ( int i = 0; i < mAttributeTable->numRows(); i++ ) {
681
 
      if ( i > 0 ) sql.append(", " );
682
 
 
683
 
 
684
 
      sql.append ( mAttributeTable->item(i,0)->text() + " " + mAttributeTable->item(i,1)->text() );
685
 
 
686
 
      if ( mAttributeTable->item(i,1)->text().compare("varchar") == 0 ) {
687
 
        sql.append ( " (" + mAttributeTable->item(i,2)->text() + ")" );
 
672
  QString type;
 
673
 
 
674
  if ( mAttributeTable->item( 0, 0 )->flags() & Qt::ItemIsEnabled )
 
675
  {
 
676
    QgsDebugMsg( "Create new table" );
 
677
 
 
678
    for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
 
679
    {
 
680
      if ( i > 0 ) sql.append( ", " );
 
681
 
 
682
      type = mAttributeTable->item( i, 1 )->text();
 
683
      sql.append( mAttributeTable->item( i, 0 )->text() + " " + type );
 
684
 
 
685
      if ( type.compare( "varchar" ) == 0 )
 
686
      {
 
687
        sql.append( " (" + mAttributeTable->item( i, 2 )->text() + ")" );
688
688
      }
689
689
    }
690
690
 
691
 
    QString *error = mProvider->createTable ( field, mAttributeTable->item(0,0)->text(), sql );  
 
691
    QString *error = mProvider->createTable( field, mAttributeTable->item( 0, 0 )->text(), sql );
692
692
 
693
 
    if ( !error->isEmpty() ) {
694
 
      QMessageBox::warning( 0, tr("Warning"), *error );
695
 
    } else {
696
 
      QMessageBox::information( 0, tr("Info"), tr("The table was created") );
 
693
    if ( !error->isEmpty() )
 
694
    {
 
695
      QMessageBox::warning( 0, tr( "Warning" ), *error );
 
696
    }
 
697
    else
 
698
    {
 
699
      QMessageBox::information( 0, tr( "Info" ), tr( "The table was created" ) );
697
700
      QString str;
698
 
      str.sprintf ( "%d", field );
699
 
      mFieldBox->insertItem( str );
 
701
      str.sprintf( "%d", field );
 
702
      mFieldBox->addItem( str );
700
703
    }
701
704
    delete error;
702
 
  } else { 
703
 
#ifdef QGISDEBUG
704
 
    std::cerr << "Alter table" << std::endl;
705
 
#endif
706
 
 
707
 
    for ( int i = 0; i < mAttributeTable->numRows(); i++ ) {
708
 
      if ( !(mAttributeTable->item(i,0)->isEnabled()) ) continue;
709
 
 
710
 
      sql = mAttributeTable->item(i,0)->text() + " " + mAttributeTable->item(i,1)->text();
711
 
 
712
 
      if ( mAttributeTable->item(i,1)->text().compare("varchar") == 0 ) {
713
 
        sql.append ( " (" + mAttributeTable->item(i,2)->text() + ")" );
 
705
  }
 
706
  else
 
707
  {
 
708
    QgsDebugMsg( "Alter table" );
 
709
 
 
710
    for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
 
711
    {
 
712
      if ( !( mAttributeTable->item( i, 0 )->flags() & Qt::ItemIsEnabled ) ) continue;
 
713
 
 
714
      type = mAttributeTable->item( i, 1 )->text();
 
715
      sql = mAttributeTable->item( i, 0 )->text() + " " + type;
 
716
 
 
717
      if ( type.compare( "varchar" ) == 0 )
 
718
      {
 
719
        sql.append( " (" + mAttributeTable->item( i, 2 )->text() + ")" );
714
720
      }
715
721
 
716
 
      QString *error = mProvider->addColumn ( field, sql );  
 
722
      QString *error = mProvider->addColumn( field, sql );
717
723
 
718
 
      if ( !error->isEmpty() ) {
719
 
        QMessageBox::warning( 0, tr("Warning"), *error );
 
724
      if ( !error->isEmpty() )
 
725
      {
 
726
        QMessageBox::warning( 0, tr( "Warning" ), *error );
720
727
      }
721
728
      delete error;
722
729
    }
723
730
  }
724
731
 
725
 
  setAttributeTable ( field );
 
732
  setAttributeTable( field );
726
733
}
727
734
 
728
 
void QgsGrassEdit::changeSymbology(Q3ListViewItem * item, const QPoint & pnt, int col)
 
735
void QgsGrassEdit::changeSymbology( QTreeWidgetItem * item, int col )
729
736
{
730
 
#ifdef QGISDEBUG
731
 
  std::cerr << "QgsGrassEdit::changeSymbology() col = " << col << std::endl;
732
 
#endif
 
737
  QgsDebugMsg( QString( "col = %1" ).arg( col ) );
733
738
 
734
739
  QSettings settings;
735
740
 
736
741
  if ( !item ) return;
737
742
 
738
 
  int index = item->text(3).toInt();
739
 
 
740
 
  if ( col == 0 ) { 
741
 
    if ( index == SYMB_BACKGROUND || index == SYMB_HIGHLIGHT || index == SYMB_DYNAMIC ) return; 
742
 
 
743
 
    Q3CheckListItem *clvi = (Q3CheckListItem *) item;
744
 
    mSymbDisplay[index] = clvi->isOn();
745
 
 
746
 
    int ww = settings.readNumEntry("/GRASS/windows/edit/w", 420);
 
743
  int index = item->text( 3 ).toInt();
 
744
 
 
745
  if ( col == 0 )
 
746
  {
 
747
    if ( index == SYMB_BACKGROUND || index == SYMB_HIGHLIGHT || index == SYMB_DYNAMIC ) return;
 
748
 
 
749
    mSymbDisplay[index] = item->checkState( 0 ) == Qt::Checked;
 
750
 
 
751
    //int ww = settings.readNumEntry("/GRASS/windows/edit/w", 420);
747
752
    QString sn;
748
753
    // TODO use a name instead of index
749
754
    sn.sprintf( "/GRASS/edit/symb/display/%d", index );
750
 
    settings.writeEntry ( sn, mSymbDisplay[index] );
751
 
  } else if ( col == 1 ) {
752
 
    QColor color = QColorDialog::getColor ( mSymb[index].color(), this );
 
755
    settings.setValue( sn, ( bool )mSymbDisplay[index] );
 
756
  }
 
757
  else if ( col == 1 )
 
758
  {
 
759
    QColor color = QColorDialog::getColor( mSymb[index].color(), this );
753
760
    mSymb[index].setColor( color );
754
761
 
755
 
    QPixmap pm ( 40, 15 );
 
762
    QPixmap pm( 40, 15 );
756
763
    pm.fill( mSymb[index].color() );
757
 
    item->setPixmap ( 1, pm );
 
764
    item->setIcon( 1, pm );
758
765
 
759
766
    QString sn;
760
767
    // TODO use a name instead of index
761
768
    sn.sprintf( "/GRASS/edit/symb/color/%d", index );
762
 
    settings.writeEntry ( sn, mSymb[index].color().name() );
 
769
    settings.setValue( sn, mSymb[index].color().name() );
 
770
    // Use the 'dynamic' color for mRubberBand
 
771
    if ( index == SYMB_DYNAMIC )
 
772
    {
 
773
      mRubberBandLine->setColor( color );
 
774
    }
763
775
  }
764
776
}
765
777
 
766
778
void QgsGrassEdit::lineWidthChanged()
767
779
{
768
 
#ifdef QGISDEBUG
769
 
    std::cerr << "QgsGrassEdit::lineWidthChanged()" << std::endl;
770
 
#endif
771
 
    QSettings settings;
772
 
    mLineWidth = mLineWidthSpinBox->value();
773
 
 
774
 
    for ( int i = 0; i < SYMB_COUNT; i++ ) {
775
 
        mSymb[i].setWidth( mLineWidth );
776
 
    }
777
 
 
778
 
    QString spath = "/GRASS/edit/symb/";
779
 
    settings.writeEntry ( spath + "lineWidth", mLineWidth );
 
780
  QgsDebugMsg( "entered." );
 
781
  QSettings settings;
 
782
  mLineWidth = mLineWidthSpinBox->value();
 
783
 
 
784
  for ( int i = 0; i < SYMB_COUNT; i++ )
 
785
  {
 
786
    mSymb[i].setWidth( mLineWidth );
 
787
  }
 
788
 
 
789
  QString spath = "/GRASS/edit/symb/";
 
790
  settings.setValue( spath + "lineWidth", mLineWidth );
780
791
}
781
792
 
782
793
void QgsGrassEdit::markerSizeChanged()
783
794
{
784
 
#ifdef QGISDEBUG
785
 
    std::cerr << "QgsGrassEdit::markerSizeChanged()" << std::endl;
786
 
#endif
787
 
    QSettings settings;
788
 
    mSize = mMarkerSizeSpinBox->value();
789
 
    QString spath = "/GRASS/edit/symb/";
790
 
    settings.writeEntry ( spath + "markerSize", mSize );
 
795
  QgsDebugMsg( "entered." );
 
796
  QSettings settings;
 
797
  mSize = mMarkerSizeSpinBox->value();
 
798
  QString spath = "/GRASS/edit/symb/";
 
799
  settings.setValue( spath + "markerSize", mSize );
791
800
}
792
801
 
793
802
void QgsGrassEdit::restorePosition()
794
803
{
795
804
  QSettings settings;
796
 
  int ww = settings.readNumEntry("/GRASS/windows/edit/w", 420);
797
 
  int wh = settings.readNumEntry("/GRASS/windows/edit/h", 150);
798
 
  int wx = settings.readNumEntry("/GRASS/windows/edit/x", 100);
799
 
  int wy = settings.readNumEntry("/GRASS/windows/edit/y", 100);
800
 
  resize(ww,wh);
801
 
  move(wx,wy);
 
805
  restoreGeometry( settings.value( "/GRASS/windows/edit/geometry" ).toByteArray() );
802
806
}
803
807
 
804
808
void QgsGrassEdit::saveWindowLocation()
805
809
{
806
810
  QSettings settings;
807
 
  QPoint p = this->pos();
808
 
  QSize s = this->size();
809
 
  settings.writeEntry("/GRASS/windows/edit/x", p.x());
810
 
  settings.writeEntry("/GRASS/windows/edit/y", p.y());
811
 
  settings.writeEntry("/GRASS/windows/edit/w", s.width());
812
 
  settings.writeEntry("/GRASS/windows/edit/h", s.height());
813
 
 
811
  settings.setValue( "/GRASS/windows/edit/geometry", saveGeometry() );
 
812
}
814
813
 
815
 
void QgsGrassEdit::updateSymb ( void )
 
814
void QgsGrassEdit::updateSymb( void )
816
815
{
817
 
#ifdef QGISDEBUG
818
 
  std::cerr << "QgsGrassEdit::updateSymb" << std::endl;
819
 
#endif
 
816
  QgsDebugMsg( "entered." );
820
817
 
821
818
  // Set lines symbology from map
822
 
  int nlines = mProvider->numLines(); 
823
 
  if ( nlines+1 >= mLineSymb.size() )
824
 
    mLineSymb.resize(nlines+1000); 
 
819
  unsigned int nlines = mProvider->numLines();
 
820
  if ( nlines + 1 >= mLineSymb.size() )
 
821
    mLineSymb.resize( nlines + 1000 );
825
822
 
826
823
  nlines = mProvider->numUpdatedLines();
827
 
  for ( int i = 0; i < nlines; i++ ) {
828
 
    int line = mProvider->updatedLine(i);
829
 
    std::cerr << "updated line = " << line << std::endl;
830
 
    if ( !(mProvider->lineAlive(line)) ) continue;
831
 
    mLineSymb[line] = lineSymbFromMap ( line );
 
824
  for ( unsigned int i = 0; i < nlines; i++ )
 
825
  {
 
826
    int line = mProvider->updatedLine( i );
 
827
    QgsDebugMsg( QString( "updated line = %1" ).arg( line ) );
 
828
    if ( !( mProvider->lineAlive( line ) ) ) continue;
 
829
    mLineSymb[line] = lineSymbFromMap( line );
832
830
  }
833
831
 
834
832
  // Set nodes symbology from map
835
 
  int nnodes = mProvider->numNodes(); 
836
 
  if ( nnodes+1 >= mNodeSymb.size() )
837
 
    mNodeSymb.resize(nnodes+1000); 
 
833
  unsigned int nnodes = mProvider->numNodes();
 
834
  if ( nnodes + 1 >= mNodeSymb.size() )
 
835
    mNodeSymb.resize( nnodes + 1000 );
838
836
 
839
 
  nnodes = mProvider->numUpdatedNodes(); 
840
 
  for ( int i = 0; i < nnodes; i++ ) {
841
 
    int node = mProvider->updatedNode(i);
842
 
    if ( !(mProvider->nodeAlive(node)) ) continue;
843
 
    mNodeSymb[node] = nodeSymbFromMap ( node );
844
 
    std::cerr << "node = " << node << " mNodeSymb = " << mNodeSymb[node] << std::endl;
 
837
  nnodes = mProvider->numUpdatedNodes();
 
838
  for ( unsigned int i = 0; i < nnodes; i++ )
 
839
  {
 
840
    int node = mProvider->updatedNode( i );
 
841
    if ( !( mProvider->nodeAlive( node ) ) ) continue;
 
842
    mNodeSymb[node] = nodeSymbFromMap( node );
 
843
    QgsDebugMsg( QString( "node = %1 mNodeSymb = %2" ).arg( node ).arg( mNodeSymb[node] ) );
845
844
  }
846
845
}
847
846
 
848
 
int QgsGrassEdit::nodeSymbFromMap ( int node )
 
847
int QgsGrassEdit::nodeSymbFromMap( int node )
849
848
{
850
 
#ifdef QGISDEBUG
851
 
  std::cerr << "QgsGrassEdit::nodeSymbFromMap() node = " <<  node << std::endl;
852
 
#endif
 
849
  QgsDebugMsg( QString( "node = %1" ).arg( node ) );
853
850
 
854
 
  int nlines = mProvider->nodeNLines ( node );
 
851
  int nlines = mProvider->nodeNLines( node );
855
852
 
856
853
  int count = 0;
857
854
 
858
 
  for ( int i = 0; i < nlines; i++ ) {
859
 
    int line = abs (  mProvider->nodeLine(node,i) );
860
 
    int type = mProvider->readLine ( NULL, NULL, line );
 
855
  for ( int i = 0; i < nlines; i++ )
 
856
  {
 
857
    int line = abs( mProvider->nodeLine( node, i ) );
 
858
    int type = mProvider->readLine( NULL, NULL, line );
861
859
 
862
860
    if ( type & GV_LINES )
863
861
      count++;
864
862
  }
865
863
 
866
 
  if ( count == 0 ) 
 
864
  if ( count == 0 )
867
865
    return SYMB_NODE_0;
868
866
  else if ( count == 1 )
869
867
    return SYMB_NODE_1;
871
869
  return SYMB_NODE_2;
872
870
}
873
871
 
874
 
int QgsGrassEdit::lineSymbFromMap ( int line )
 
872
int QgsGrassEdit::lineSymbFromMap( int line )
875
873
{
876
 
#ifdef QGISDEBUG
877
 
  std::cerr << "QgsGrassEdit::lineSymbFromMap() line = " << line << std::endl;
878
 
#endif
 
874
  QgsDebugMsg( QString( "line = %1" ).arg( line ) );
879
875
 
880
 
  int type = mProvider->readLine ( NULL, NULL, line );
 
876
  int type = mProvider->readLine( NULL, NULL, line );
881
877
 
882
878
  if ( type < 0 ) return 0;
883
879
 
884
 
  switch ( type ) {
 
880
  switch ( type )
 
881
  {
885
882
    case GV_POINT:
886
883
      return SYMB_POINT;
887
884
      break;
893
890
    case GV_BOUNDARY:
894
891
      int left, right, nareas;
895
892
 
896
 
      if ( !(mProvider->lineAreas(line, &left, &right)) ) return 0;
 
893
      if ( !( mProvider->lineAreas( line, &left, &right ) ) ) return 0;
897
894
 
898
895
      /* Count areas/isles on both sides */
899
896
      nareas = 0;
905
902
      break;
906
903
 
907
904
    case GV_CENTROID:
908
 
      int area = mProvider->centroidArea ( line );
 
905
      int area = mProvider->centroidArea( line );
909
906
      if ( area == 0 ) return SYMB_CENTROID_OUT;
910
 
      else if ( area > 0 ) return SYMB_CENTROID_IN;  
911
 
      else return SYMB_CENTROID_DUPL; /* area < 0 */ 
 
907
      else if ( area > 0 ) return SYMB_CENTROID_IN;
 
908
      else return SYMB_CENTROID_DUPL; /* area < 0 */
912
909
      break;
913
910
  }
914
911
 
917
914
 
918
915
QgsGrassEdit::~QgsGrassEdit()
919
916
{
920
 
#ifdef QGISDEBUG
921
 
  std::cerr << "QgsGrassEdit::~QgsGrassEdit()" << std::endl;
922
 
#endif
 
917
  QgsDebugMsg( "entered." );
923
918
 
924
919
  // we can only call some methods if init was complete,
925
920
  // note that we cannot use mValid because it is disabled before
926
921
  // destructor is called
927
 
  if (mInited) 
 
922
  if ( mInited )
928
923
  {
929
924
    // delete tool if exists
930
925
    delete mMapTool;
935
930
    mRubberBandLine->reset();
936
931
    delete mRubberBandLine;
937
932
    delete mRubberBandIcon;
938
 
  
 
933
 
939
934
    delete mCanvasEdit;
940
 
  
 
935
 
941
936
    mCanvas->refresh();
942
 
  
 
937
 
943
938
    saveWindowLocation();
944
939
  }
945
940
  mRunning = false;
946
941
}
947
942
 
948
 
bool QgsGrassEdit::isRunning(void)
 
943
bool QgsGrassEdit::isRunning( void )
949
944
{
950
945
  return mRunning;
951
946
}
952
947
 
953
 
bool QgsGrassEdit::isValid(void)
 
948
bool QgsGrassEdit::isValid( void )
954
949
{
955
950
  return mValid;
956
951
}
957
952
 
958
 
void QgsGrassEdit::closeEdit(void)
 
953
void QgsGrassEdit::closeEdit( void )
959
954
{
960
 
#ifdef QGISDEBUG
961
 
  std::cerr << "QgsGrassEdit::close()" << std::endl;
962
 
#endif
963
 
 
964
 
  // grass edit tool would become invalid
965
 
  // so change it to another one, e.g. pan tool
966
 
  mQgisApp->pan();
 
955
  QgsDebugMsg( "entered." );
967
956
 
968
957
  // Disconnect signals
969
 
  // Warning: it seems that slots (postRender) can be called even 
970
 
  //          after disconnect (is it a queue?) 
971
 
  disconnect( this, SLOT(postRender(QPainter *)));
 
958
  // Warning: it seems that slots (postRender) can be called even
 
959
  //          after disconnect (is it a queue?)
 
960
  disconnect( this, SLOT( postRender( QPainter * ) ) );
972
961
 
973
962
  mValid = false; // important for postRender
974
963
 
975
 
  if ( mAttributes ) {
 
964
  if ( mAttributes )
 
965
  {
976
966
    delete mAttributes;
977
967
  }
978
968
 
979
 
  mProvider->closeEdit(mNewMap);
 
969
  mProvider->closeEdit( mNewMap );
980
970
 
981
971
  hide();
982
972
 
983
973
  // Add new layers
984
974
  if ( mNewMap )
985
975
  {
986
 
     QString uri = QDir::cleanDirPath ( mProvider->getDataSourceUri() );
987
 
     std::cerr << "uri = " << uri.ascii() << std::endl;
988
 
     // Note: QDir::cleanPath is using '/' also on Windows
989
 
     //QChar sep = QDir::separator();
990
 
     QChar sep = '/';
991
 
 
992
 
     QStringList split = QStringList::split ( sep, uri );
993
 
     split.pop_back(); // layer
994
 
     QString map = split.last();
995
 
     split.pop_back(); // map
996
 
     QString mapset = split.last();
997
 
 
998
 
     QgsGrassUtils::addVectorLayers ( mIface, QgsGrass::getDefaultGisdbase(), 
999
 
                                      QgsGrass::getDefaultLocation(),
1000
 
                                      mapset, map );
 
976
    QString uri = QDir::cleanPath( mProvider->dataSourceUri() );
 
977
    QgsDebugMsg( QString( "uri = %1" ).arg( uri ) );
 
978
    // Note: QDir::cleanPath is using '/' also on Windows
 
979
    //QChar sep = QDir::separator();
 
980
    QChar sep = '/';
 
981
 
 
982
    QStringList split = uri.split( sep, QString::SkipEmptyParts );
 
983
    split.pop_back(); // layer
 
984
    QString map = split.last();
 
985
    split.pop_back(); // map
 
986
    QString mapset = split.last();
 
987
 
 
988
    QgsGrassUtils::addVectorLayers( mIface, QgsGrass::getDefaultGisdbase(),
 
989
                                    QgsGrass::getDefaultLocation(),
 
990
                                    mapset, map );
1001
991
  }
1002
992
  emit finished();
1003
 
  delete this; 
 
993
  delete this;
1004
994
}
1005
995
 
1006
 
void QgsGrassEdit::closeEvent(QCloseEvent *e)
 
996
void QgsGrassEdit::closeEvent( QCloseEvent *e )
1007
997
{
1008
 
#ifdef QGISDEBUG
1009
 
  std::cerr << "QgsGrassEdit::closeEvent()" << std::endl;
1010
 
#endif
 
998
  QgsDebugMsg( "entered." );
1011
999
 
1012
1000
  e->accept();
1013
1001
 
1014
1002
  closeEdit();
1015
1003
}
1016
1004
 
1017
 
void QgsGrassEdit::catModeChanged ( void )
1018
 
{
1019
 
#ifdef QGISDEBUG
1020
 
  std::cerr << "QgsGrassEdit::catModeChanged()" << std::endl;
1021
 
#endif
1022
 
  int mode = mCatModeBox->currentItem();
1023
 
 
1024
 
  int field = mFieldBox->currentText().toInt();
1025
 
 
1026
 
  if ( mode == CAT_MODE_NEXT ) { // Find next not used
1027
 
    QString c = "1"; // Default for new field
1028
 
    for (int i = 0; i < mMaxCats.size(); i++ ) {
1029
 
      if ( mMaxCats[i].field == field ) {
1030
 
        c.sprintf("%d", mMaxCats[i].maxCat+1);
1031
 
        break;
1032
 
      }
1033
 
    }
1034
 
    mCatEntry->setText ( c );
1035
 
    mCatEntry->setEnabled(false);
1036
 
    mFieldBox->setDisabled(false);
1037
 
  } else if ( mode == CAT_MODE_MANUAL ) {
1038
 
    mCatEntry->setEnabled(true);
1039
 
    mFieldBox->setDisabled(false);
1040
 
  } else { // CAT_MODE_NOCAT
1041
 
    mCatEntry->clear ();
1042
 
    mCatEntry->setEnabled(false);
1043
 
    mFieldBox->setDisabled(true);
1044
 
  }
1045
 
}
1046
 
 
1047
 
void QgsGrassEdit::fieldChanged ( void )
1048
 
{
1049
 
#ifdef QGISDEBUG
1050
 
  std::cerr << "QgsGrassEdit::fieldChanged()" << std::endl;
1051
 
#endif
1052
 
  int mode = mCatModeBox->currentItem();
1053
 
  int field = mFieldBox->currentText().toInt();
1054
 
 
1055
 
  if ( mode == CAT_MODE_NEXT ) { // Find next not used
1056
 
    QString c = "1"; // Default for new field
1057
 
    for (int i = 0; i < mMaxCats.size(); i++ ) {
1058
 
      if ( mMaxCats[i].field == field ) {
1059
 
        c.sprintf("%d", mMaxCats[i].maxCat+1);
1060
 
        break;
1061
 
      }
1062
 
    }
1063
 
    mCatEntry->setText ( c );
1064
 
  }
1065
 
}
1066
 
 
1067
 
int QgsGrassEdit::writeLine ( int type, struct line_pnts *Points )
1068
 
{
1069
 
  int mode = mCatModeBox->currentItem();
 
1005
void QgsGrassEdit::catModeChanged( void )
 
1006
{
 
1007
  QgsDebugMsg( "entered." );
 
1008
  int mode = mCatModeBox->currentIndex();
 
1009
 
 
1010
  int field = mFieldBox->currentText().toInt();
 
1011
 
 
1012
  if ( mode == CAT_MODE_NEXT )   // Find next not used
 
1013
  {
 
1014
    QString c = "1"; // Default for new field
 
1015
    for ( unsigned int i = 0; i < mMaxCats.size(); i++ )
 
1016
    {
 
1017
      if ( mMaxCats[i].field == field )
 
1018
      {
 
1019
        c.sprintf( "%d", mMaxCats[i].maxCat + 1 );
 
1020
        break;
 
1021
      }
 
1022
    }
 
1023
    mCatEntry->setText( c );
 
1024
    mCatEntry->setEnabled( false );
 
1025
    mFieldBox->setDisabled( false );
 
1026
  }
 
1027
  else if ( mode == CAT_MODE_MANUAL )
 
1028
  {
 
1029
    mCatEntry->setEnabled( true );
 
1030
    mFieldBox->setDisabled( false );
 
1031
  }
 
1032
  else   // CAT_MODE_NOCAT
 
1033
  {
 
1034
    mCatEntry->clear();
 
1035
    mCatEntry->setEnabled( false );
 
1036
    mFieldBox->setDisabled( true );
 
1037
  }
 
1038
}
 
1039
 
 
1040
void QgsGrassEdit::fieldChanged( void )
 
1041
{
 
1042
  QgsDebugMsg( "entered." );
 
1043
  int mode = mCatModeBox->currentIndex();
 
1044
  int field = mFieldBox->currentText().toInt();
 
1045
 
 
1046
  if ( mode == CAT_MODE_NEXT )   // Find next not used
 
1047
  {
 
1048
    QString c = "1"; // Default for new field
 
1049
    for ( unsigned int i = 0; i < mMaxCats.size(); i++ )
 
1050
    {
 
1051
      if ( mMaxCats[i].field == field )
 
1052
      {
 
1053
        c.sprintf( "%d", mMaxCats[i].maxCat + 1 );
 
1054
        break;
 
1055
      }
 
1056
    }
 
1057
    mCatEntry->setText( c );
 
1058
  }
 
1059
}
 
1060
 
 
1061
int QgsGrassEdit::writeLine( int type, struct line_pnts *Points )
 
1062
{
 
1063
  int mode = mCatModeBox->currentIndex();
1070
1064
  int field = mFieldBox->currentText().toInt();
1071
1065
  int cat = mCatEntry->text().toInt();
1072
1066
 
1073
 
  Vect_reset_cats ( mCats );
1074
 
  if ( mode == CAT_MODE_NEXT || mode == CAT_MODE_MANUAL ) {
1075
 
    Vect_cat_set ( mCats, field, cat );
 
1067
  Vect_reset_cats( mCats );
 
1068
  if ( mode == CAT_MODE_NEXT || mode == CAT_MODE_MANUAL )
 
1069
  {
 
1070
    Vect_cat_set( mCats, field, cat );
1076
1071
 
1077
1072
    // Insert new DB record if link is defined and the record for this cat does not exist
1078
 
    QString *key = mProvider->key ( field );
1079
 
 
1080
 
    if ( !key->isEmpty() ) { // Database link defined 
1081
 
      std::vector<QgsFeatureAttribute> *atts = mProvider->attributes ( field, cat );
1082
 
 
1083
 
      if ( atts->size() == 0 ) { // Nothing selected
1084
 
        QString *error = mProvider->insertAttributes ( field, cat );
1085
 
 
1086
 
        if ( !error->isEmpty() ) {
1087
 
          QMessageBox::warning( 0, tr("Warning"), *error );
 
1073
    QString *key = mProvider->key( field );
 
1074
 
 
1075
    if ( !key->isEmpty() )   // Database link defined
 
1076
    {
 
1077
      QgsAttributeMap *atts = mProvider->attributes( field, cat );
 
1078
 
 
1079
      if ( atts->count() == 0 )   // Nothing selected
 
1080
      {
 
1081
        QString *error = mProvider->insertAttributes( field, cat );
 
1082
 
 
1083
        if ( !error->isEmpty() )
 
1084
        {
 
1085
          QMessageBox::warning( 0, tr( "Warning" ), *error );
1088
1086
        }
1089
1087
        delete error;
1090
1088
      }
1092
1090
      delete atts;
1093
1091
    }
1094
1092
  }
1095
 
  Vect_line_prune ( Points );
1096
 
  int line = mProvider->writeLine ( type, Points, mCats );
 
1093
  Vect_line_prune( Points );
 
1094
  int line = mProvider->writeLine( type, Points, mCats );
1097
1095
 
1098
1096
  increaseMaxCat();
1099
1097
  return line;
1100
1098
}
1101
1099
 
1102
 
void QgsGrassEdit::increaseMaxCat ( void )
 
1100
void QgsGrassEdit::increaseMaxCat( void )
1103
1101
{
1104
 
  int mode = mCatModeBox->currentItem();
 
1102
  int mode = mCatModeBox->currentIndex();
1105
1103
  int field = mFieldBox->currentText().toInt();
1106
1104
  int cat = mCatEntry->text().toInt();
1107
1105
 
1108
 
  if ( mode == CAT_MODE_NEXT || mode == CAT_MODE_MANUAL ) {
 
1106
  if ( mode == CAT_MODE_NEXT || mode == CAT_MODE_MANUAL )
 
1107
  {
1109
1108
    int found = 0;
1110
 
    for (int i = 0; i < mMaxCats.size(); i++ ) {
1111
 
      if ( mMaxCats[i].field == field ) {
1112
 
        if ( cat > mMaxCats[i].maxCat ) {
 
1109
    for ( unsigned int i = 0; i < mMaxCats.size(); i++ )
 
1110
    {
 
1111
      if ( mMaxCats[i].field == field )
 
1112
      {
 
1113
        if ( cat > mMaxCats[i].maxCat )
 
1114
        {
1113
1115
          mMaxCats[i].maxCat = cat;
1114
1116
        }
1115
1117
        found = 1;
1116
1118
        break;
1117
1119
      }
1118
1120
    }
1119
 
    if ( !found ) { 
 
1121
    if ( !found )
 
1122
    {
1120
1123
      MaxCat mc;
1121
1124
      mc.field = field;
1122
1125
      mc.maxCat = cat;
1123
 
      mMaxCats.push_back(mc);
 
1126
      mMaxCats.push_back( mc );
1124
1127
    }
1125
1128
 
1126
 
    if ( mode == CAT_MODE_NEXT ) { 
1127
 
      QString c; 
1128
 
      c.sprintf("%d", cat+1);
1129
 
      mCatEntry->setText ( c );
 
1129
    if ( mode == CAT_MODE_NEXT )
 
1130
    {
 
1131
      QString c;
 
1132
      c.sprintf( "%d", cat + 1 );
 
1133
      mCatEntry->setText( c );
1130
1134
    }
1131
1135
  }
1132
1136
 
1133
1137
}
1134
1138
 
1135
 
double QgsGrassEdit::threshold ( void )
 
1139
double QgsGrassEdit::threshold( void )
1136
1140
{
1137
1141
  int snapPixels = mSnapPixels->text().toInt();
1138
1142
 
1139
1143
  // Convert to map units (not nice)
1140
1144
  QgsPoint p1, p2;
1141
 
  p1 = mTransform->toMapCoordinates(0, 0 ); 
1142
 
  p2 = mTransform->toMapCoordinates(snapPixels, 0); 
 
1145
  p1 = mTransform->toMapCoordinates( 0, 0 );
 
1146
  p2 = mTransform->toMapCoordinates( snapPixels, 0 );
1143
1147
 
1144
 
  if ( mProjectionEnabled ) 
 
1148
  if ( mProjectionEnabled )
1145
1149
  {
1146
 
      p1 = mLayer->coordinateTransform()->transform(p1, QgsCoordinateTransform::INVERSE );
1147
 
      p2 = mLayer->coordinateTransform()->transform(p2, QgsCoordinateTransform::INVERSE );
 
1150
    try
 
1151
    {
 
1152
      p1 = mCanvas->mapRenderer()->mapToLayerCoordinates( mLayer, p1 );
 
1153
      p2 = mCanvas->mapRenderer()->mapToLayerCoordinates( mLayer, p2 );
 
1154
    }
 
1155
    catch ( QgsCsException& cse )
 
1156
    {
 
1157
      Q_UNUSED( cse );
 
1158
      //error
 
1159
    }
1148
1160
  }
1149
1161
 
1150
1162
  double dx = p2.x() - p1.x();
1151
1163
  double dy = p2.y() - p1.y();
1152
 
  double thresh = sqrt ( dx*dx + dy*dy );
 
1164
  double thresh = sqrt( dx * dx + dy * dy );
1153
1165
  return thresh;
1154
1166
}
1155
1167
 
1156
 
void QgsGrassEdit::snap (  double *x, double *y )
 
1168
void QgsGrassEdit::snap( double *x, double *y )
1157
1169
{
1158
1170
  double thresh = threshold();
1159
1171
 
1160
 
  int node = mProvider->findNode ( *x, *y, thresh );
 
1172
  int node = mProvider->findNode( *x, *y, thresh );
1161
1173
 
1162
 
  if ( node > 0 ) {
1163
 
    mProvider->nodeCoor ( node, x, y );
 
1174
  if ( node > 0 )
 
1175
  {
 
1176
    mProvider->nodeCoor( node, x, y );
1164
1177
  }
1165
1178
}
1166
1179
 
1167
 
void QgsGrassEdit::snap (  QgsPoint & point )
 
1180
void QgsGrassEdit::snap( QgsPoint & point )
1168
1181
{
1169
1182
  double x = point.x();
1170
1183
  double y = point.y();
1171
1184
 
1172
 
  snap ( &x, &y );
 
1185
  snap( &x, &y );
1173
1186
 
1174
 
  point.setX(x);
1175
 
  point.setY(y);
 
1187
  point.setX( x );
 
1188
  point.setY( y );
1176
1189
}
1177
1190
 
1178
 
void QgsGrassEdit::snap (  QgsPoint & point, double startX, double startY )
 
1191
void QgsGrassEdit::snap( QgsPoint & point, double startX, double startY )
1179
1192
{
1180
1193
  double x = point.x();
1181
1194
  double y = point.y();
1183
1196
  double thresh = threshold();
1184
1197
 
1185
1198
  // Start
1186
 
  double startDist = hypot ( x-startX, y-startY);
 
1199
  double startDist = hypot( x - startX, y - startY );
1187
1200
  bool startIn = false;
1188
1201
  if ( startDist <= thresh ) startIn = true;
1189
1202
 
1190
1203
  // Nearest node
1191
 
  double nodeX, nodeY;     
1192
 
  double nodeDist;
 
1204
  double nodeX = 0;
 
1205
  double  nodeY = 0;
 
1206
  double nodeDist = 0;
1193
1207
  bool nodeIn = false;
1194
 
  int node = mProvider->findNode ( x, y, thresh );
 
1208
  int node = mProvider->findNode( x, y, thresh );
1195
1209
 
1196
 
  if ( node > 0 ) 
 
1210
  if ( node > 0 )
1197
1211
  {
1198
 
       mProvider->nodeCoor ( node, &nodeX, &nodeY );
1199
 
       nodeDist = hypot ( x-nodeX, y-nodeY);
1200
 
       nodeIn = true;
 
1212
    mProvider->nodeCoor( node, &nodeX, &nodeY );
 
1213
    nodeDist = hypot( x - nodeX, y - nodeY );
 
1214
    nodeIn = true;
1201
1215
  }
1202
1216
 
1203
1217
  // Choose
1204
 
  if ( (startIn && !nodeIn) || (startIn && nodeIn && startDist < nodeDist)  ) 
1205
 
  {
1206
 
      x = startX; y = startY;
1207
 
  }
1208
 
  else if ( (!startIn && nodeIn) || (startIn && nodeIn && startDist > nodeDist) ) 
1209
 
  {
1210
 
      x = nodeX; y = nodeY;
1211
 
  } 
1212
 
 
1213
 
  point.setX(x);
1214
 
  point.setY(y);
1215
 
}
1216
 
 
1217
 
void QgsGrassEdit::newPoint(void) { startTool(QgsGrassEdit::NEW_POINT); }
1218
 
void QgsGrassEdit::newLine(void) { 
1219
 
  std::cerr << "QgsGrassEdit::newLine" << std::endl;
1220
 
  startTool(QgsGrassEdit::NEW_LINE); 
1221
 
}
1222
 
void QgsGrassEdit::newBoundary(void) { 
1223
 
  std::cerr << "QgsGrassEdit::newBoundary" << std::endl;
1224
 
  startTool(QgsGrassEdit::NEW_BOUNDARY); 
1225
 
}
1226
 
void QgsGrassEdit::newCentroid(void) { startTool(QgsGrassEdit::NEW_CENTROID); }
1227
 
void QgsGrassEdit::moveVertex(void) { startTool(QgsGrassEdit::MOVE_VERTEX); }
1228
 
void QgsGrassEdit::addVertex(void) { startTool(QgsGrassEdit::ADD_VERTEX); }
1229
 
void QgsGrassEdit::deleteVertex(void) { startTool(QgsGrassEdit::DELETE_VERTEX); }
1230
 
void QgsGrassEdit::splitLine(void) { startTool(QgsGrassEdit::SPLIT_LINE); }
1231
 
void QgsGrassEdit::moveLine(void) { startTool(QgsGrassEdit::MOVE_LINE); }
1232
 
void QgsGrassEdit::deleteLine(void) { startTool(QgsGrassEdit::DELETE_LINE); }
1233
 
void QgsGrassEdit::editCats(void) { startTool(QgsGrassEdit::EDIT_CATS); }
1234
 
void QgsGrassEdit::editAttributes(void) { startTool(QgsGrassEdit::EDIT_ATTRIBUTES); }
1235
 
 
1236
 
void QgsGrassEdit::startTool(int tool)
1237
 
{
1238
 
#ifdef QGISDEBUG
1239
 
  std::cerr << "QgsGrassEdit::startTool() tool = " << tool << std::endl;
1240
 
#endif
 
1218
  if (( startIn && !nodeIn ) || ( startIn && nodeIn && startDist < nodeDist ) )
 
1219
  {
 
1220
    x = startX; y = startY;
 
1221
  }
 
1222
  else if (( !startIn && nodeIn ) || ( startIn && nodeIn && startDist > nodeDist ) )
 
1223
  {
 
1224
    x = nodeX; y = nodeY;
 
1225
  }
 
1226
 
 
1227
  point.setX( x );
 
1228
  point.setY( y );
 
1229
}
 
1230
 
 
1231
void QgsGrassEdit::newPoint( void )
 
1232
{
 
1233
  startTool( QgsGrassEdit::NEW_POINT );
 
1234
}
 
1235
 
 
1236
void QgsGrassEdit::newLine( void )
 
1237
{
 
1238
  QgsDebugMsg( "entered." );
 
1239
  startTool( QgsGrassEdit::NEW_LINE );
 
1240
}
 
1241
 
 
1242
void QgsGrassEdit::newBoundary( void )
 
1243
{
 
1244
  QgsDebugMsg( "entered." );
 
1245
  startTool( QgsGrassEdit::NEW_BOUNDARY );
 
1246
}
 
1247
 
 
1248
void QgsGrassEdit::newCentroid( void )
 
1249
{
 
1250
  startTool( QgsGrassEdit::NEW_CENTROID );
 
1251
}
 
1252
 
 
1253
void QgsGrassEdit::moveVertex( void )
 
1254
{
 
1255
  startTool( QgsGrassEdit::MOVE_VERTEX );
 
1256
}
 
1257
 
 
1258
void QgsGrassEdit::addVertex( void )
 
1259
{
 
1260
  startTool( QgsGrassEdit::ADD_VERTEX );
 
1261
}
 
1262
 
 
1263
void QgsGrassEdit::deleteVertex( void )
 
1264
{
 
1265
  startTool( QgsGrassEdit::DELETE_VERTEX );
 
1266
}
 
1267
 
 
1268
void QgsGrassEdit::splitLine( void )
 
1269
{
 
1270
  startTool( QgsGrassEdit::SPLIT_LINE );
 
1271
}
 
1272
 
 
1273
void QgsGrassEdit::moveLine( void )
 
1274
{
 
1275
  startTool( QgsGrassEdit::MOVE_LINE );
 
1276
}
 
1277
 
 
1278
void QgsGrassEdit::deleteLine( void )
 
1279
{
 
1280
  startTool( QgsGrassEdit::DELETE_LINE );
 
1281
}
 
1282
 
 
1283
void QgsGrassEdit::editCats( void )
 
1284
{
 
1285
  startTool( QgsGrassEdit::EDIT_CATS );
 
1286
}
 
1287
 
 
1288
void QgsGrassEdit::editAttributes( void )
 
1289
{
 
1290
  startTool( QgsGrassEdit::EDIT_ATTRIBUTES );
 
1291
}
 
1292
 
 
1293
void QgsGrassEdit::startTool( int tool )
 
1294
{
 
1295
  QgsDebugMsg( QString( "tool = %1" ).arg( tool ) );
1241
1296
 
1242
1297
  // Delete last dynamic drawing from canvas
1243
1298
  eraseDynamic();
1244
1299
  if ( mSelectedLine > 0 )
1245
 
    displayElement ( mSelectedLine, mSymb[mLineSymb[mSelectedLine]], mSize );
 
1300
    displayElement( mSelectedLine, mSymb[mLineSymb[mSelectedLine]], mSize );
1246
1301
 
1247
1302
  // close old tool
1248
 
  if (mMapTool)
 
1303
  if ( mMapTool )
1249
1304
  {
1250
1305
    delete mMapTool;
1251
1306
    mMapTool = NULL;
1252
1307
  }
1253
1308
 
1254
1309
  // All necessary data were written -> reset mEditPoints etc.
1255
 
  Vect_reset_line ( mEditPoints );
 
1310
  Vect_reset_line( mEditPoints );
1256
1311
  mSelectedLine = 0;
1257
1312
 
1258
 
  // TODO: mTool != NEW_LINE is a hack for lines until more buttons can be recieved
1259
 
  if ( mAttributes && mTool != QgsGrassEdit::NEW_LINE && mTool != QgsGrassEdit::NEW_BOUNDARY ) {
 
1313
  // TODO: mTool != NEW_LINE is a hack for lines until more buttons can be received
 
1314
  if ( mAttributes && mTool != QgsGrassEdit::NEW_LINE && mTool != QgsGrassEdit::NEW_BOUNDARY )
 
1315
  {
1260
1316
    delete mAttributes;
1261
1317
    mAttributes = 0;
1262
1318
  }
1264
1320
  // Start new tool
1265
1321
  mTool = tool;
1266
1322
 
1267
 
  switch (mTool)
 
1323
  switch ( mTool )
1268
1324
  {
1269
1325
    case NEW_POINT:
1270
 
      mMapTool = new QgsGrassEditNewPoint(this, false);
1271
 
      mMapTool->setAction(mNewPointAction);
 
1326
      mMapTool = new QgsGrassEditNewPoint( this, false );
 
1327
      mMapTool->setAction( mNewPointAction );
1272
1328
      break;
1273
 
      
 
1329
 
1274
1330
    case NEW_CENTROID:
1275
 
      mMapTool = new QgsGrassEditNewPoint(this, true);
1276
 
      mMapTool->setAction(mNewCentroidAction);
 
1331
      mMapTool = new QgsGrassEditNewPoint( this, true );
 
1332
      mMapTool->setAction( mNewCentroidAction );
1277
1333
      break;
1278
 
      
 
1334
 
1279
1335
    case NEW_LINE:
1280
 
      mMapTool = new QgsGrassEditNewLine(this, false);
1281
 
      mMapTool->setAction(mNewLineAction);
 
1336
      mMapTool = new QgsGrassEditNewLine( this, false );
 
1337
      mMapTool->setAction( mNewLineAction );
1282
1338
      break;
1283
 
  
 
1339
 
1284
1340
    case NEW_BOUNDARY:
1285
 
      mMapTool = new QgsGrassEditNewLine(this, true);
1286
 
      mMapTool->setAction(mNewBoundaryAction);
 
1341
      mMapTool = new QgsGrassEditNewLine( this, true );
 
1342
      mMapTool->setAction( mNewBoundaryAction );
1287
1343
      break;
1288
 
      
 
1344
 
1289
1345
    case MOVE_VERTEX:
1290
 
      mMapTool = new QgsGrassEditMoveVertex(this);
1291
 
      mMapTool->setAction(mMoveVertexAction);
 
1346
      mMapTool = new QgsGrassEditMoveVertex( this );
 
1347
      mMapTool->setAction( mMoveVertexAction );
1292
1348
      break;
1293
 
      
 
1349
 
1294
1350
    case ADD_VERTEX:
1295
 
      mMapTool = new QgsGrassEditAddVertex(this);
1296
 
      mMapTool->setAction(mAddVertexAction);
 
1351
      mMapTool = new QgsGrassEditAddVertex( this );
 
1352
      mMapTool->setAction( mAddVertexAction );
1297
1353
      break;
1298
 
      
 
1354
 
1299
1355
    case DELETE_VERTEX:
1300
 
      mMapTool = new QgsGrassEditDeleteVertex(this);
1301
 
      mMapTool->setAction(mDeleteVertexAction);
 
1356
      mMapTool = new QgsGrassEditDeleteVertex( this );
 
1357
      mMapTool->setAction( mDeleteVertexAction );
1302
1358
      break;
1303
 
      
 
1359
 
1304
1360
    case MOVE_LINE:
1305
 
      mMapTool = new QgsGrassEditMoveLine(this);
1306
 
      mMapTool->setAction(mMoveLineAction);
 
1361
      mMapTool = new QgsGrassEditMoveLine( this );
 
1362
      mMapTool->setAction( mMoveLineAction );
1307
1363
      break;
1308
 
      
 
1364
 
1309
1365
    case DELETE_LINE:
1310
 
      mMapTool = new QgsGrassEditDeleteLine(this);
1311
 
      mMapTool->setAction(mDeleteLineAction);
 
1366
      mMapTool = new QgsGrassEditDeleteLine( this );
 
1367
      mMapTool->setAction( mDeleteLineAction );
1312
1368
      break;
1313
 
      
 
1369
 
1314
1370
    case SPLIT_LINE:
1315
 
      mMapTool = new QgsGrassEditSplitLine(this);
1316
 
      mMapTool->setAction(mSplitLineAction);
 
1371
      mMapTool = new QgsGrassEditSplitLine( this );
 
1372
      mMapTool->setAction( mSplitLineAction );
1317
1373
      break;
1318
 
      
 
1374
 
1319
1375
    case EDIT_ATTRIBUTES:
1320
 
      mMapTool = new QgsGrassEditAttributes(this);
1321
 
      mMapTool->setAction(mEditAttributesAction);
 
1376
      mMapTool = new QgsGrassEditAttributes( this );
 
1377
      mMapTool->setAction( mEditAttributesAction );
1322
1378
      break;
1323
 
      
 
1379
 
1324
1380
    case EDIT_CATS:
1325
1381
      mTool = NONE;
1326
 
      QMessageBox::warning( 0, tr("Warning"), tr("Tool not yet implemented.") );
 
1382
      QMessageBox::warning( 0, tr( "Warning" ), tr( "Tool not yet implemented." ) );
1327
1383
      break;
1328
1384
 
1329
1385
    default:
1330
 
      std::cerr << "Unknown tool" << std::endl;
 
1386
      QgsDebugMsg( "Unknown tool" );
1331
1387
      break;
1332
1388
  }
1333
 
    
 
1389
 
1334
1390
  // assign newly created tool to map canvas
1335
 
  mCanvas->setMapTool(mMapTool);
 
1391
  mCanvas->setMapTool( mMapTool );
1336
1392
}
1337
1393
 
1338
 
 
1339
 
 
1340
 
void QgsGrassEdit::checkOrphan ( int field, int cat )
 
1394
void QgsGrassEdit::checkOrphan( int field, int cat )
1341
1395
{
1342
 
  #ifdef QGISDEBUG
1343
 
  std::cerr << "QgsGrassEdit::checkOrphan field = " << field
1344
 
               << " cat = " << cat << std::endl;
1345
 
  #endif
 
1396
  QgsDebugMsg( QString( "field = %1 cat = %2" ).arg( field ).arg( cat ) );
1346
1397
 
1347
1398
  int orphan;
1348
 
  QString *error = mProvider->isOrphan ( field, cat, &orphan );
 
1399
  QString *error = mProvider->isOrphan( field, cat, &orphan );
1349
1400
 
1350
 
  if ( !error->isEmpty() ) {
1351
 
      QMessageBox::warning( 0, tr("Warning"), tr("Cannot check orphan record: ")
1352
 
                + *error );
1353
 
      return;
 
1401
  if ( !error->isEmpty() )
 
1402
  {
 
1403
    QMessageBox::warning( 0, tr( "Warning" ),
 
1404
                          tr( "Cannot check orphan record: %1" ).arg( *error ) );
 
1405
    return;
1354
1406
  }
1355
1407
  if ( !orphan ) return;
1356
1408
 
1357
 
  int ret = QMessageBox::question ( 0, tr("Warning"), 
1358
 
             tr("Orphan record was left in attribute table. "
1359
 
              "<br>Delete the record?"),  
1360
 
              QMessageBox::Yes,  QMessageBox::No );
 
1409
  QMessageBox::StandardButton ret = QMessageBox::question( 0, tr( "Warning" ),
 
1410
                                    tr( "Orphan record was left in attribute table. "
 
1411
                                        "<br>Delete the record?" ),
 
1412
                                    QMessageBox::Ok | QMessageBox::Cancel );
1361
1413
 
1362
 
  if ( ret == QMessageBox::No ) return;
 
1414
  if ( ret == QMessageBox::Cancel ) return;
1363
1415
 
1364
1416
  // Delete record
1365
 
  error = mProvider->deleteAttributes ( field, cat );
1366
 
  if ( !error->isEmpty() ) {
1367
 
      QMessageBox::warning( 0, tr("Warning"), tr("Cannot delete orphan record: ")
1368
 
                + *error );
1369
 
      return;
 
1417
  error = mProvider->deleteAttributes( field, cat );
 
1418
  if ( !error->isEmpty() )
 
1419
  {
 
1420
    QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot delete orphan record: " )
 
1421
                          + *error );
 
1422
    return;
1370
1423
  }
1371
1424
}
1372
1425
 
1373
 
void QgsGrassEdit::addAttributes ( int field, int cat )
 
1426
void QgsGrassEdit::addAttributes( int field, int cat )
1374
1427
{
1375
 
  QString *key = mProvider->key ( field );
 
1428
  QString *key = mProvider->key( field );
1376
1429
 
1377
1430
  QString lab;
1378
 
  lab.sprintf ( "%d:%d", field, cat );
 
1431
  lab.sprintf( "%d:%d", field, cat );
1379
1432
  int tab = mAttributes->addTab( lab );
1380
 
  mAttributes->setField ( tab, field );
 
1433
  mAttributes->setField( tab, field );
1381
1434
 
1382
1435
  QString catLabel;
1383
 
  if ( key->isEmpty() ) {
 
1436
  if ( key->isEmpty() )
 
1437
  {
1384
1438
    catLabel = "Category";
1385
 
  } else {
 
1439
  }
 
1440
  else
 
1441
  {
1386
1442
    catLabel = *key;
1387
1443
  }
1388
 
  mAttributes->setCat ( tab, catLabel, cat );
1389
 
 
1390
 
  if ( !key->isEmpty() ) { // Database link defined 
1391
 
    std::vector<QgsField> *cols = mProvider->columns ( field );
1392
 
 
1393
 
    if ( cols->size() == 0 ) {
 
1444
  mAttributes->setCat( tab, catLabel, cat );
 
1445
 
 
1446
  if ( !key->isEmpty() )   // Database link defined
 
1447
  {
 
1448
    std::vector<QgsField> *cols = mProvider->columns( field );
 
1449
 
 
1450
    if ( cols->size() == 0 )
 
1451
    {
1394
1452
      QString str;
1395
1453
      str.setNum( field );
1396
 
      QMessageBox::warning( 0, tr("Warning"), tr("Cannot describe table for field ") + str );
1397
 
    } else {
1398
 
      std::vector<QgsFeatureAttribute> *atts = 
1399
 
        mProvider->attributes ( field, cat );
 
1454
      QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot describe table for field %1" ).arg( str ) );
 
1455
    }
 
1456
    else
 
1457
    {
 
1458
      QgsAttributeMap *atts = mProvider->attributes( field, cat );
1400
1459
 
1401
 
      if ( atts->size() == 0 ) { // cannot select attributes
1402
 
        mAttributes->addTextRow ( tab, "WARNING: ATTRIBUTES MISSING" );
1403
 
      } else {
 
1460
      if ( atts->size() == 0 )   // cannot select attributes
 
1461
      {
 
1462
        mAttributes->addTextRow( tab, "WARNING: ATTRIBUTES MISSING" );
 
1463
      }
 
1464
      else
 
1465
      {
1404
1466
        int size;
1405
 
        if ( atts->size() < cols->size() )
 
1467
        if ( atts->size() < ( int ) cols->size() )
1406
1468
          size = atts->size();
1407
1469
        else
1408
1470
          size = cols->size();
1409
1471
 
1410
 
        for ( int j = 0; j < cols->size(); j++ ) {
1411
 
          QgsField col = (*cols)[j];
1412
 
          QgsFeatureAttribute att = (*atts)[j];
1413
 
          std::cerr << " name = " << col.name().toLocal8Bit().data() <<  std::endl;
 
1472
        for ( unsigned int j = 0; j < cols->size(); j++ )
 
1473
        {
 
1474
          QgsField col = ( *cols )[j];
 
1475
          QVariant att = ( *atts )[j];
 
1476
          QgsDebugMsg( QString( " name = %1" ).arg( col.name() ) );
1414
1477
 
1415
 
          if ( col.name() != *key ) {
1416
 
            std::cerr << " value = " << att.fieldValue().toLocal8Bit().data() <<  std::endl;
1417
 
            mAttributes->addAttribute ( tab, col.name(), att.fieldValue(), col.type() );
 
1478
          if ( col.name() != *key )
 
1479
          {
 
1480
            QgsDebugMsg( QString( " value = %1" ).arg( att.toString() ) );
 
1481
            mAttributes->addAttribute( tab, col.name(), att.toString(), col.typeName() );
1418
1482
          }
1419
1483
        }
1420
1484
      }
1424
1488
  }
1425
1489
}
1426
1490
 
1427
 
void QgsGrassEdit::addCat ( int line )
 
1491
void QgsGrassEdit::addCat( int line )
1428
1492
{
1429
 
  int mode = mCatModeBox->currentItem();
 
1493
  int mode = mCatModeBox->currentIndex();
1430
1494
  int field = mFieldBox->currentText().toInt();
1431
1495
  int cat = mCatEntry->text().toInt();
1432
1496
 
1433
 
  int type = mProvider->readLine ( mPoints, mCats, line );
1434
 
  if ( mode == CAT_MODE_NEXT || mode == CAT_MODE_MANUAL ) {
1435
 
    Vect_cat_set ( mCats, field, cat );
 
1497
  int type = mProvider->readLine( mPoints, mCats, line );
 
1498
  if ( mode == CAT_MODE_NEXT || mode == CAT_MODE_MANUAL )
 
1499
  {
 
1500
    Vect_cat_set( mCats, field, cat );
1436
1501
  }
1437
1502
 
1438
 
  line = mProvider->rewriteLine ( line, type, mPoints, mCats );
 
1503
  line = mProvider->rewriteLine( line, type, mPoints, mCats );
1439
1504
  mSelectedLine = line;
1440
 
  if ( mAttributes ) mAttributes->setLine ( line );
 
1505
  if ( mAttributes ) mAttributes->setLine( line );
1441
1506
  updateSymb();
1442
1507
  increaseMaxCat();
1443
1508
 
1444
1509
  // Insert new DB record if link is defined and the record for this cat does not exist
1445
 
  QString *key = mProvider->key ( field );
1446
 
 
1447
 
  if ( !key->isEmpty() ) { // Database link defined 
1448
 
    std::vector<QgsFeatureAttribute> *atts = mProvider->attributes ( field, cat );
1449
 
 
1450
 
    if ( atts->size() == 0 ) { // Nothing selected
1451
 
      QString *error = mProvider->insertAttributes ( field, cat );
1452
 
 
1453
 
      if ( !error->isEmpty() ) {
1454
 
        QMessageBox::warning( 0, tr("Warning"), *error );
 
1510
  QString *key = mProvider->key( field );
 
1511
 
 
1512
  if ( !key->isEmpty() )   // Database link defined
 
1513
  {
 
1514
    QgsAttributeMap *atts = mProvider->attributes( field, cat );
 
1515
 
 
1516
    if ( atts->size() == 0 )   // Nothing selected
 
1517
    {
 
1518
      QString *error = mProvider->insertAttributes( field, cat );
 
1519
 
 
1520
      if ( !error->isEmpty() )
 
1521
      {
 
1522
        QMessageBox::warning( 0, tr( "Warning" ), *error );
1455
1523
      }
1456
1524
      delete error;
1457
1525
    }
1462
1530
  addAttributes( field, cat );
1463
1531
}
1464
1532
 
1465
 
void QgsGrassEdit::deleteCat ( int line, int field, int cat )
 
1533
void QgsGrassEdit::deleteCat( int line, int field, int cat )
1466
1534
{
1467
 
#ifdef QGISDEBUG
1468
 
  std::cerr << "QgsGrassEdit::deleteCat" << std::endl;
1469
 
#endif
1470
 
 
1471
 
  int type = mProvider->readLine ( mPoints, mCats, line );
1472
 
  Vect_field_cat_del ( mCats, field, cat );
1473
 
 
1474
 
  line = mProvider->rewriteLine ( line, type, mPoints, mCats );
 
1535
  QgsDebugMsg( "entered." );
 
1536
 
 
1537
  int type = mProvider->readLine( mPoints, mCats, line );
 
1538
  Vect_field_cat_del( mCats, field, cat );
 
1539
 
 
1540
  line = mProvider->rewriteLine( line, type, mPoints, mCats );
1475
1541
  mSelectedLine = line;
1476
 
  if ( mAttributes ) mAttributes->setLine ( line );
 
1542
  if ( mAttributes ) mAttributes->setLine( line );
1477
1543
 
1478
1544
  // Check orphan record
1479
 
  checkOrphan ( field, cat );
 
1545
  checkOrphan( field, cat );
1480
1546
 
1481
1547
  updateSymb();
1482
1548
}
1483
1549
 
1484
1550
 
1485
 
void QgsGrassEdit::postRender(QPainter *)
 
1551
void QgsGrassEdit::postRender( QPainter * )
1486
1552
{
1487
 
#ifdef QGISDEBUG
1488
 
  std::cerr << "QgsGrassEdit::postRender" << std::endl;
1489
 
#endif
 
1553
  QgsDebugMsg( "entered." );
1490
1554
 
1491
 
  // Warning: it seems that this slot can be called even 
1492
 
  //          after disconnect (is it a queue?) 
 
1555
  // Warning: it seems that this slot can be called even
 
1556
  //          after disconnect (is it a queue?)
1493
1557
  //          -> check mValid
1494
1558
 
1495
1559
  if ( !mValid ) return;
1497
1561
  displayMap();
1498
1562
 
1499
1563
  // Redisplay highlighted
1500
 
  if ( mSelectedLine ) {
1501
 
    displayElement ( mSelectedLine, mSymb[SYMB_HIGHLIGHT], mSize );
 
1564
  if ( mSelectedLine )
 
1565
  {
 
1566
    displayElement( mSelectedLine, mSymb[SYMB_HIGHLIGHT], mSize );
1502
1567
  }
1503
1568
}
1504
1569
 
1505
 
void QgsGrassEdit::displayMap ()
 
1570
void QgsGrassEdit::displayMap()
1506
1571
{
1507
 
#ifdef QGISDEBUG
1508
 
  std::cerr << "QgsGrassEdit::displayMap" << std::endl;
1509
 
#endif
 
1572
  QgsDebugMsg( "entered." );
1510
1573
 
1511
1574
  mTransform = mCanvas->getCoordinateTransform();
1512
1575
 
1513
1576
  // re-create pixmap - it's transparent by default
1514
 
  *mPixmap = QPixmap(mCanvas->size());
1515
 
  mPixmap->fill(QColor(0,0,0,0));
 
1577
  *mPixmap = QPixmap( mCanvas->size() );
 
1578
  mPixmap->fill( QColor( 0, 0, 0, 0 ) );
1516
1579
 
1517
1580
  QPainter *painter = new QPainter();
1518
 
  painter->begin(mPixmap);
1519
 
  
 
1581
  painter->begin( mPixmap );
 
1582
 
1520
1583
  // Display lines
1521
 
  int nlines = mProvider->numLines(); 
 
1584
  int nlines = mProvider->numLines();
1522
1585
 
1523
1586
  QPen pen;
1524
1587
 
1525
1588
  // TODO?: 2 loops, first lines, then points
1526
 
  for ( int line = 1; line <= nlines; line++ ) {
1527
 
    displayElement ( line, mSymb[mLineSymb[line]], mSize, painter );
 
1589
  for ( int line = 1; line <= nlines; line++ )
 
1590
  {
 
1591
    displayElement( line, mSymb[mLineSymb[line]], mSize, painter );
1528
1592
  }
1529
1593
 
1530
1594
  // Display nodes
1531
 
  int nnodes = mProvider->numNodes(); 
1532
 
 
1533
 
  pen.setColor(QColor(255,0,0));
1534
 
 
1535
 
  if ( mSymbDisplay[SYMB_NODE_1] || mSymbDisplay[SYMB_NODE_2] ) {
1536
 
    for ( int node = 1; node <= nnodes; node++ ) {
 
1595
  int nnodes = mProvider->numNodes();
 
1596
 
 
1597
  pen.setColor( QColor( 255, 0, 0 ) );
 
1598
 
 
1599
  if ( mSymbDisplay[SYMB_NODE_1] || mSymbDisplay[SYMB_NODE_2] )
 
1600
  {
 
1601
    for ( int node = 1; node <= nnodes; node++ )
 
1602
    {
1537
1603
      if ( mNodeSymb[node] == SYMB_NODE_0 ) continue; // do not display nodes with points only
1538
 
      displayNode ( node, mSymb[mNodeSymb[node]], mSize, painter ); 
 
1604
      displayNode( node, mSymb[mNodeSymb[node]], mSize, painter );
1539
1605
    }
1540
1606
  }
1541
1607
 
1542
1608
  painter->end();
1543
1609
  delete painter;
1544
 
  
1545
 
  mCanvas->updateContents();
 
1610
 
 
1611
  // porting mCanvas->update();
 
1612
  mCanvasEdit->update();
 
1613
  mRubberBandIcon->update();
 
1614
  mRubberBandLine->update();
1546
1615
}
1547
1616
 
1548
 
void QgsGrassEdit::displayUpdated (void)
 
1617
void QgsGrassEdit::displayUpdated( void )
1549
1618
{
1550
 
#ifdef QGISDEBUG
1551
 
  std::cerr << "QgsGrassEdit::displayUpdated" << std::endl;
1552
 
#endif
 
1619
  QgsDebugMsg( "entered." );
1553
1620
 
1554
1621
  mTransform = mCanvas->getCoordinateTransform();
1555
 
  mProjectionEnabled = (QgsProject::instance()->readNumEntry("SpatialRefSys","/ProjectionsEnabled",0)!=0);
 
1622
  mProjectionEnabled = ( QgsProject::instance()->readNumEntry( "SpatialRefSys", "/ProjectionsEnabled", 0 ) != 0 );
1556
1623
 
1557
1624
  QPainter *painter = new QPainter();
1558
 
  painter->begin(mPixmap);
 
1625
  painter->begin( mPixmap );
1559
1626
 
1560
1627
  // Display lines
1561
1628
  int nlines = mProvider->numUpdatedLines();
1562
1629
 
1563
 
  for ( int i = 0; i < nlines; i++ ) {
1564
 
    int line = mProvider->updatedLine(i);
1565
 
    if ( !(mProvider->lineAlive(line)) ) continue;
 
1630
  for ( int i = 0; i < nlines; i++ )
 
1631
  {
 
1632
    int line = mProvider->updatedLine( i );
 
1633
    if ( !( mProvider->lineAlive( line ) ) ) continue;
1566
1634
 
1567
 
    displayElement ( line, mSymb[mLineSymb[line]], mSize, painter );
 
1635
    displayElement( line, mSymb[mLineSymb[line]], mSize, painter );
1568
1636
  }
1569
1637
 
1570
1638
  // Display nodes
1571
 
  int nnodes = mProvider->numUpdatedNodes(); 
1572
 
  for ( int i = 0; i < nnodes; i++ ) {
1573
 
    int node = mProvider->updatedNode(i);
1574
 
    if ( !(mProvider->nodeAlive(node)) ) continue;
 
1639
  int nnodes = mProvider->numUpdatedNodes();
 
1640
  for ( int i = 0; i < nnodes; i++ )
 
1641
  {
 
1642
    int node = mProvider->updatedNode( i );
 
1643
    if ( !( mProvider->nodeAlive( node ) ) ) continue;
1575
1644
    if ( mNodeSymb[node] == SYMB_NODE_0 ) continue; // do not display nodes with points only
1576
 
    displayNode ( node, mSymb[mNodeSymb[node]], mSize, painter ); 
 
1645
    displayNode( node, mSymb[mNodeSymb[node]], mSize, painter );
1577
1646
  }
1578
1647
 
1579
1648
  painter->end();
1580
1649
  delete painter;
1581
1650
 
1582
 
  mCanvas->updateContents();
 
1651
  // porting mCanvas->update();
 
1652
  mCanvasEdit->update();
 
1653
  mRubberBandIcon->update();
 
1654
  mRubberBandLine->update();
1583
1655
}
1584
1656
 
1585
 
void QgsGrassEdit::displayElement ( int line, const QPen & pen, int size, QPainter *painter)
 
1657
void QgsGrassEdit::displayElement( int line, const QPen & pen, int size, QPainter *painter )
1586
1658
{
1587
 
#ifdef QGISDEBUG
1588
 
  std::cerr << "QgsGrassEdit::displayElement() line = " << line << std::endl;
1589
 
#endif
 
1659
  QgsDebugMsg( QString( "line = %1" ).arg( line ) );
 
1660
 
 
1661
  // is it a valid line?
 
1662
  if ( line == 0 )
 
1663
    return;
1590
1664
 
1591
1665
  if ( !mSymbDisplay[mLineSymb[line]] ) return;
1592
1666
 
1593
 
  int type = mProvider->readLine ( mPoints, NULL, line );
 
1667
  int type = mProvider->readLine( mPoints, NULL, line );
1594
1668
  if ( type < 0 ) return;
1595
1669
 
1596
1670
  QPainter *myPainter;
1597
 
  if ( !painter ) {
 
1671
  if ( !painter )
 
1672
  {
1598
1673
    myPainter = new QPainter();
1599
 
    myPainter->begin(mPixmap);
1600
 
  } else {
 
1674
    myPainter->begin( mPixmap );
 
1675
  }
 
1676
  else
 
1677
  {
1601
1678
    myPainter = painter;
1602
1679
  }
1603
1680
 
1604
 
  if ( type & GV_POINTS ) {
1605
 
    displayIcon ( mPoints->x[0], mPoints->y[0], pen, QgsVertexMarker::ICON_CROSS, size, myPainter );
1606
 
  } else { // line
 
1681
  if ( type & GV_POINTS )
 
1682
  {
 
1683
    displayIcon( mPoints->x[0], mPoints->y[0], pen, QgsVertexMarker::ICON_CROSS, size, myPainter );
 
1684
  }
 
1685
  else   // line
 
1686
  {
1607
1687
    QgsPoint point;
1608
 
    Q3PointArray pointArray(mPoints->n_points);
 
1688
    QPolygon pointArray( mPoints->n_points );
1609
1689
 
1610
 
    for ( int i = 0; i < mPoints->n_points; i++ ) {
1611
 
      point.setX(mPoints->x[i]);
1612
 
      point.setY(mPoints->y[i]);
1613
 
      point = transformLayerToCanvas ( point );
1614
 
      pointArray.setPoint( i, static_cast<int>(round(point.x())), 
1615
 
          static_cast<int>(round(point.y())) ); 
 
1690
    for ( int i = 0; i < mPoints->n_points; i++ )
 
1691
    {
 
1692
      point.setX( mPoints->x[i] );
 
1693
      point.setY( mPoints->y[i] );
 
1694
      point = transformLayerToCanvas( point );
 
1695
      pointArray.setPoint( i, static_cast<int>( round( point.x() ) ),
 
1696
                           static_cast<int>( round( point.y() ) ) );
1616
1697
    }
1617
1698
 
1618
 
    myPainter->setPen ( pen );
1619
 
    myPainter->drawPolyline ( pointArray );
 
1699
    myPainter->setPen( pen );
 
1700
    myPainter->drawPolyline( pointArray );
1620
1701
  }
1621
1702
 
1622
 
  if ( !painter ) {
 
1703
  if ( !painter )
 
1704
  {
1623
1705
    myPainter->end();
1624
 
    mCanvas->updateContents();
 
1706
    // porting mCanvas->update();
 
1707
    mCanvasEdit->update();
1625
1708
    delete myPainter;
1626
1709
  }
1627
1710
}
1628
1711
 
1629
 
void QgsGrassEdit::eraseElement ( int line )
 
1712
void QgsGrassEdit::eraseElement( int line )
1630
1713
{
1631
 
#ifdef QGISDEBUG
1632
 
  std::cerr << "QgsGrassEdit::eraseElement() line = " << line << std::endl;
1633
 
#endif
 
1714
  QgsDebugMsg( QString( "line = %1" ).arg( line ) );
1634
1715
 
1635
 
  int type = mProvider->readLine ( NULL, NULL, line );
 
1716
  int type = mProvider->readLine( NULL, NULL, line );
1636
1717
  if ( type < 0 ) return;
1637
1718
 
1638
1719
  // Erase line
1639
 
  displayElement ( line, mSymb[SYMB_BACKGROUND], mSize );
 
1720
  displayElement( line, mSymb[SYMB_BACKGROUND], mSize );
1640
1721
 
1641
1722
  // Erase nodes
1642
 
  if ( type & GV_LINES ) {
 
1723
  if ( type & GV_LINES )
 
1724
  {
1643
1725
    int node1, node2;
1644
1726
    mProvider->lineNodes( line, &node1, &node2 );
1645
1727
 
1646
1728
    double x, y;
1647
1729
    mProvider->nodeCoor( node1, &x, &y );
1648
 
    displayIcon ( x, y, mSymb[SYMB_BACKGROUND], QgsVertexMarker::ICON_X, mSize );
 
1730
    displayIcon( x, y, mSymb[SYMB_BACKGROUND], QgsVertexMarker::ICON_X, mSize );
1649
1731
 
1650
1732
    mProvider->nodeCoor( node2, &x, &y );
1651
 
    displayIcon ( x, y, mSymb[SYMB_BACKGROUND], QgsVertexMarker::ICON_X, mSize );
 
1733
    displayIcon( x, y, mSymb[SYMB_BACKGROUND], QgsVertexMarker::ICON_X, mSize );
1652
1734
  }
1653
1735
}
1654
1736
 
1655
 
void QgsGrassEdit::eraseDynamic ( void )
1656
 
{
1657
 
  displayDynamic ( 0, 0.0, 0.0, QgsVertexMarker::ICON_NONE, 0 );
1658
 
}
1659
 
 
1660
 
void QgsGrassEdit::displayDynamic ( struct line_pnts *Points )
1661
 
{
1662
 
  displayDynamic ( Points, 0.0, 0.0, QgsVertexMarker::ICON_NONE, 0 );
1663
 
}
1664
 
 
1665
 
void QgsGrassEdit::displayDynamic ( double x, double y, int type, int size )
1666
 
{
1667
 
#ifdef QGISDEBUG
1668
 
  std::cerr << "QgsGrassEdit::displayDynamic icon" << std::endl;
1669
 
#endif
1670
 
 
1671
 
  displayDynamic ( 0, x, y, type, size );
1672
 
}
1673
 
 
1674
 
void QgsGrassEdit::displayDynamic ( struct line_pnts *Points, double x, double y, int type, int size )
1675
 
{
1676
 
#ifdef QGISDEBUG
1677
 
   std::cerr << "QgsGrassEdit::displayDynamic Points = " << Points << " type = " << type  << std::endl;
1678
 
#endif
1679
 
    QgsPoint point;
1680
 
 
1681
 
    //mTransform = mCanvas->getCoordinateTransform();
1682
 
 
1683
 
    // Dynamic points are in layer coordinate system, we have to 
1684
 
    // reproject them to current coordinate system if necessary
1685
 
 
1686
 
    mRubberBandLine->reset();
1687
 
 
1688
 
    if ( Points )
 
1737
void QgsGrassEdit::eraseDynamic( void )
 
1738
{
 
1739
  displayDynamic( 0, 0.0, 0.0, QgsVertexMarker::ICON_NONE, 0 );
 
1740
}
 
1741
 
 
1742
void QgsGrassEdit::displayDynamic( struct line_pnts *Points )
 
1743
{
 
1744
  displayDynamic( Points, 0.0, 0.0, QgsVertexMarker::ICON_NONE, 0 );
 
1745
}
 
1746
 
 
1747
void QgsGrassEdit::displayDynamic( double x, double y, int type, int size )
 
1748
{
 
1749
  QgsDebugMsg( "entered." );
 
1750
 
 
1751
  displayDynamic( 0, x, y, type, size );
 
1752
}
 
1753
 
 
1754
void QgsGrassEdit::displayDynamic( struct line_pnts *Points, double x, double y, int type, int size )
 
1755
{
 
1756
  QgsDebugMsg( QString( "Points = %1 type = %2" ).arg( QString::number(( qulonglong )Points, 16 ).toLocal8Bit().constData() ).arg( type ) );
 
1757
  QgsPoint point;
 
1758
 
 
1759
  //mTransform = mCanvas->getCoordinateTransform();
 
1760
 
 
1761
  // Dynamic points are in layer coordinate system, we have to
 
1762
  // reproject them to current coordinate system if necessary
 
1763
 
 
1764
  mRubberBandLine->reset();
 
1765
 
 
1766
  if ( Points )
 
1767
  {
 
1768
    for ( int i = 0; i < Points->n_points; i++ )
1689
1769
    {
1690
 
        for ( int i = 0; i < Points->n_points; i++ ) 
1691
 
        {
1692
 
            point.setX(Points->x[i]);
1693
 
            point.setY(Points->y[i]);
1694
 
            point = transformLayerToMap ( point );
1695
 
            mRubberBandLine->addPoint(point, false); // false = don't update now
1696
 
        }
1697
 
        // Now add the last point again and force update of rubberband.
1698
 
        // This should improve the performance as canvas is updated only once
1699
 
        // and not with every added point to rubberband.
1700
 
        mRubberBandLine->addPoint(point, true);
 
1770
      point.setX( Points->x[i] );
 
1771
      point.setY( Points->y[i] );
 
1772
      point = transformLayerToMap( point );
 
1773
      mRubberBandLine->addPoint( point, false ); // false = don't update now
1701
1774
    }
 
1775
    // Now add the last point again and force update of rubberband.
 
1776
    // This should improve the performance as canvas is updated only once
 
1777
    // and not with every added point to rubberband.
 
1778
    mRubberBandLine->addPoint( point, true );
 
1779
  }
1702
1780
 
1703
 
    mRubberBandIcon->setIconType(type);
1704
 
    mRubberBandIcon->setIconSize(size);
1705
 
    point = transformLayerToMap (QgsPoint(x,y) );
1706
 
    mRubberBandIcon->setCenter(point);
 
1781
  mRubberBandIcon->setIconType( type );
 
1782
  mRubberBandIcon->setIconSize( size );
 
1783
  point = transformLayerToMap( QgsPoint( x, y ) );
 
1784
  mRubberBandIcon->setCenter( point );
1707
1785
}
1708
1786
 
1709
 
void QgsGrassEdit::displayNode ( int node, const QPen & pen, int size, QPainter *painter )
 
1787
void QgsGrassEdit::displayNode( int node, const QPen & pen, int size, QPainter *painter )
1710
1788
{
1711
 
#ifdef QGISDEBUG
1712
 
  std::cerr << "QgsGrassEdit::displayNode() node = " << node << std::endl;
1713
 
#endif
 
1789
  QgsDebugMsg( QString( "node = %1" ).arg( node ) );
1714
1790
 
1715
1791
  if ( !mSymbDisplay[mNodeSymb[node]] ) return;
1716
1792
 
1717
1793
  double x, y;
1718
1794
 
1719
 
  if ( !(mProvider->nodeCoor(node,&x,&y )) ) return;
1720
 
 
1721
 
  displayIcon ( x, y, pen, QgsVertexMarker::ICON_X, size, painter );
1722
 
}
1723
 
 
1724
 
QgsPoint QgsGrassEdit::transformLayerToCanvas ( QgsPoint point)
1725
 
{
1726
 
    if ( mProjectionEnabled && mLayer->coordinateTransform() )
1727
 
    {
1728
 
        try
1729
 
        {
1730
 
            point = mLayer->coordinateTransform()->transform(point);
1731
 
        }
1732
 
        catch(QgsCsException &cse)
1733
 
        {
1734
 
            std::cout << "cannot transform point" << std::endl;
1735
 
        }
1736
 
 
1737
 
    }
1738
 
    mTransform->transform(&point);
1739
 
    return point;
1740
 
}
1741
 
 
1742
 
QgsPoint QgsGrassEdit::transformLayerToMap ( QgsPoint point)
1743
 
{
1744
 
    std::cout << "mProjectionEnabled = " << mProjectionEnabled << std::endl;
1745
 
    if ( mProjectionEnabled && mLayer->coordinateTransform() )
1746
 
    {
1747
 
        try
1748
 
        {
1749
 
            point = mLayer->coordinateTransform()->transform(point);
1750
 
        }
1751
 
        catch(QgsCsException &cse)
1752
 
        {
1753
 
            std::cout << "cannot transform point" << std::endl;
1754
 
        }
1755
 
 
1756
 
    }
1757
 
    return point;
1758
 
}
1759
 
 
1760
 
void QgsGrassEdit::displayIcon ( double x, double y, const QPen & pen, 
1761
 
    int type, int size, QPainter *painter )
1762
 
{
1763
 
#ifdef QGISDEBUG
1764
 
  std::cerr << "QgsGrassEdit::displayIcon()" << std::endl;
1765
 
#endif
 
1795
  if ( !( mProvider->nodeCoor( node, &x, &y ) ) ) return;
 
1796
 
 
1797
  displayIcon( x, y, pen, QgsVertexMarker::ICON_X, size, painter );
 
1798
}
 
1799
 
 
1800
QgsPoint QgsGrassEdit::transformLayerToCanvas( QgsPoint point )
 
1801
{
 
1802
  point = mCanvas->mapRenderer()->layerToMapCoordinates( mLayer, point );
 
1803
  return mTransform->transform( point );
 
1804
}
 
1805
 
 
1806
QgsPoint QgsGrassEdit::transformLayerToMap( QgsPoint point )
 
1807
{
 
1808
  return mCanvas->mapRenderer()->layerToMapCoordinates( mLayer, point );
 
1809
}
 
1810
 
 
1811
void QgsGrassEdit::displayIcon( double x, double y, const QPen & pen,
 
1812
                                int type, int size, QPainter *painter )
 
1813
{
 
1814
  QgsDebugMsg( "entered." );
1766
1815
 
1767
1816
  QgsPoint point;
1768
 
  Q3PointArray pointArray(2);
1769
 
 
1770
 
  point.setX(x);
1771
 
  point.setY(y);
1772
 
  
1773
 
  point = transformLayerToCanvas ( point );
1774
 
 
1775
 
  int px = static_cast<int>(round(point.x()));
1776
 
  int py = static_cast<int>(round(point.y()));
1777
 
  int m = (size-1)/2;
 
1817
  QPolygon pointArray( 2 );
 
1818
 
 
1819
  point.setX( x );
 
1820
  point.setY( y );
 
1821
 
 
1822
  point = transformLayerToCanvas( point );
 
1823
 
 
1824
  int px = static_cast<int>( round( point.x() ) );
 
1825
  int py = static_cast<int>( round( point.y() ) );
 
1826
  int m = ( size - 1 ) / 2;
1778
1827
 
1779
1828
  QPainter *myPainter;
1780
 
  if ( !painter ) {
 
1829
  if ( !painter )
 
1830
  {
1781
1831
    myPainter = new QPainter();
1782
 
    myPainter->begin(mPixmap);
1783
 
  } else {
 
1832
    myPainter->begin( mPixmap );
 
1833
  }
 
1834
  else
 
1835
  {
1784
1836
    myPainter = painter;
1785
1837
  }
1786
1838
 
1787
 
  myPainter->setPen ( pen );
 
1839
  myPainter->setPen( pen );
1788
1840
 
1789
 
  switch ( type ) {
 
1841
  switch ( type )
 
1842
  {
1790
1843
    case QgsVertexMarker::ICON_CROSS :
1791
 
      pointArray.setPoint( 0, px-m, py ); 
1792
 
      pointArray.setPoint( 1, px+m, py ); 
1793
 
      myPainter->drawPolyline ( pointArray );
 
1844
      pointArray.setPoint( 0, px - m, py );
 
1845
      pointArray.setPoint( 1, px + m, py );
 
1846
      myPainter->drawPolyline( pointArray );
1794
1847
 
1795
 
      pointArray.setPoint( 0, px, py+m ); 
1796
 
      pointArray.setPoint( 1, px, py-m ); 
1797
 
      myPainter->drawPolyline ( pointArray );
 
1848
      pointArray.setPoint( 0, px, py + m );
 
1849
      pointArray.setPoint( 1, px, py - m );
 
1850
      myPainter->drawPolyline( pointArray );
1798
1851
      break;
1799
1852
    case QgsVertexMarker::ICON_X :
1800
 
      pointArray.setPoint( 0, px-m, py+m ); 
1801
 
      pointArray.setPoint( 1, px+m, py-m ); 
1802
 
      myPainter->drawPolyline ( pointArray );
 
1853
      pointArray.setPoint( 0, px - m, py + m );
 
1854
      pointArray.setPoint( 1, px + m, py - m );
 
1855
      myPainter->drawPolyline( pointArray );
1803
1856
 
1804
 
      pointArray.setPoint( 0, px-m, py-m ); 
1805
 
      pointArray.setPoint( 1, px+m, py+m ); 
1806
 
      myPainter->drawPolyline ( pointArray );
 
1857
      pointArray.setPoint( 0, px - m, py - m );
 
1858
      pointArray.setPoint( 1, px + m, py + m );
 
1859
      myPainter->drawPolyline( pointArray );
1807
1860
      break;
1808
1861
    case QgsVertexMarker::ICON_BOX :
1809
 
      pointArray.resize(5);
1810
 
      pointArray.setPoint( 0, px-m, py-m ); 
1811
 
      pointArray.setPoint( 1, px+m, py-m ); 
1812
 
      pointArray.setPoint( 2, px+m, py+m ); 
1813
 
      pointArray.setPoint( 3, px-m, py+m ); 
1814
 
      pointArray.setPoint( 4, px-m, py-m ); 
1815
 
      myPainter->drawPolyline ( pointArray );
 
1862
      pointArray.resize( 5 );
 
1863
      pointArray.setPoint( 0, px - m, py - m );
 
1864
      pointArray.setPoint( 1, px + m, py - m );
 
1865
      pointArray.setPoint( 2, px + m, py + m );
 
1866
      pointArray.setPoint( 3, px - m, py + m );
 
1867
      pointArray.setPoint( 4, px - m, py - m );
 
1868
      myPainter->drawPolyline( pointArray );
1816
1869
      break;
1817
1870
  }
1818
1871
 
1819
 
  if ( !painter ) {
 
1872
  if ( !painter )
 
1873
  {
1820
1874
    myPainter->end();
1821
 
    mCanvas->updateContents();
 
1875
    //mCanvas->update();
 
1876
    mCanvasEdit->update();
1822
1877
    delete myPainter;
1823
1878
  }
1824
1879
}
1825
1880
 
1826
 
void QgsGrassEdit::setCanvasPropmt( QString left, QString mid, QString rigth)
 
1881
void QgsGrassEdit::setCanvasPrompt( QString left, QString mid, QString right )
1827
1882
{
1828
 
  std::cerr << "QgsGrassEdit::setCanvasPropmt" << std::endl;
 
1883
  QgsDebugMsg( "entered." );
1829
1884
  mCanvasPrompt = "";
1830
 
  if ( left.length() > 0 ) mCanvasPrompt.append ( tr("Left: ") + left + "   " );
1831
 
  if ( mid.length() > 0 ) mCanvasPrompt.append ( tr("Middle: ") + mid + "   " );
1832
 
  if ( rigth.length() > 0 ) mCanvasPrompt.append ( tr("Right: ") + rigth );
 
1885
  if ( left.length() > 0 ) mCanvasPrompt.append( tr( "Left: %1   " ).arg( left ) );
 
1886
  if ( mid.length() > 0 ) mCanvasPrompt.append( tr( "Middle: %1" ).arg( mid ) );
 
1887
  if ( right.length() > 0 ) mCanvasPrompt.append( tr( "Right: %1" ).arg( right ) );
1833
1888
}
1834
1889
 
1835
1890
void QgsGrassEdit::attributesClosed()
1836
1891
{
1837
 
    mAttributes = 0;
 
1892
  mAttributes = 0;
1838
1893
}