13
13
* (at your option) any later version. *
15
15
***************************************************************************/
20
#include <qsettings.h>
22
#include <q3listbox.h>
23
#include <qstringlist.h>
27
#include <qmessagebox.h>
28
#include <qinputdialog.h>
29
#include <qsettings.h>
33
#include <q3pointarray.h>
35
#include <qnamespace.h>
36
#include <q3listview.h>
37
#include <qcolordialog.h>
39
#include <qstatusbar.h>
42
#include <QActionGroup>
43
#include <QCloseEvent>
17
#include "qgsgrassedit.h"
18
#include "qgsgrassattributes.h"
19
#include "qgsgrassedittools.h"
20
#include "qgsgrassplugin.h"
21
#include "qgsgrassutils.h"
22
#include "qgsgrassprovider.h"
25
#include "qgisinterface.h"
47
26
#include "qgsapplication.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"
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"
62
#include <grass/gis.h>
38
#include <QCloseEvent>
39
#include <QColorDialog>
41
#include <QHeaderView>
43
#include <QMessageBox>
63
49
#include <grass/Vect.h>
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"
53
#define round(x) ((x) >= 0 ? floor((x)+0.5) : floor((x)-0.5))
73
#include "qgsmapcanvasitem.h"
74
#include "qgsmaptoolpan.h"
76
57
class QgsGrassEditLayer : public QgsMapCanvasItem
80
QgsGrassEditLayer(QgsMapCanvas* mapCanvas):QgsMapCanvasItem(mapCanvas)
85
virtual void drawShape(QPainter & p)
87
p.drawPixmap(mPanningOffset.x(),mPanningOffset.y(), mPixmap);
61
QgsGrassEditLayer( QgsMapCanvas* mapCanvas ): QgsMapCanvasItem( mapCanvas )
65
virtual void paint( QPainter* p )
67
p->drawPixmap( 0, 0, mPixmap );
70
virtual QRectF boundingRect() const
72
return QRectF( 0, 0, mMapCanvas->width(), mMapCanvas->height() );
90
75
virtual void updatePosition()
92
move(mPanningOffset.x(),mPanningOffset.y());
93
setSize(mMapCanvas->width(), mMapCanvas->height());
77
setPos( QPointF( mPanningOffset ) );
96
80
QPixmap& pixmap() { return mPixmap; }
88
#include <QItemDelegate>
89
class QgsGrassEditAttributeTableItemDelegate : public QItemDelegate
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;
98
QgsGrassEditAttributeTableItemDelegate::QgsGrassEditAttributeTableItemDelegate( QObject *parent )
99
: QItemDelegate( parent )
102
QWidget *QgsGrassEditAttributeTableItemDelegate::createEditor( QWidget *parent,
103
const QStyleOptionViewItem &option, const QModelIndex &index ) const
106
if ( index.column() == 1 )
108
QComboBox *cb = new QComboBox( parent );
109
cb->addItems( QStringList() << "integer" << "double precision" << "varchar" );
114
editor = QItemDelegate::createEditor( parent, option, index );
120
void QgsGrassEditAttributeTableItemDelegate::setEditorData( QWidget *editor,
121
const QModelIndex &index ) const
123
if ( index.column() == 1 )
125
QComboBox *cb = static_cast<QComboBox *>( editor );
126
cb->setCurrentIndex( cb->findData( index.model()->data( index ), Qt::DisplayRole ) );
130
QItemDelegate::setEditorData( editor, index );
134
void QgsGrassEditAttributeTableItemDelegate::setModelData( QWidget *editor,
135
QAbstractItemModel *model, const QModelIndex &index ) const
137
if ( index.column() == 1 )
139
QComboBox *cb = static_cast<QComboBox *>( editor );
140
model->setData( index, cb->currentText(), Qt::EditRole );
144
QItemDelegate::setModelData( editor, model, index );
105
149
bool QgsGrassEdit::mRunning = false;
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 )
113
std::cerr << "QgsGrassEdit()" << std::endl;
156
QgsDebugMsg( "QgsGrassEdit()" );
120
162
mTool = QgsGrassEdit::NONE;
121
163
mSuspend = false;
126
mProjectionEnabled = (QgsProject::instance()->readNumEntry("SpatialRefSys","/ProjectionsEnabled",0)!=0);
128
mCanvas = mIface->getMapCanvas();
130
// TODO QGIS: crash if canvas is empty
132
// At moment QgisIface::activeLayer() does not work
133
QgsMapLayer *layer = (QgsMapLayer *) mIface->activeLayer();
135
if ( !isEditable(layer) ) return;
137
//TODO dynamic_cast ?
138
mLayer = (QgsVectorLayer*)layer;
140
//TODO dynamic_cast ?
141
mProvider = (QgsGrassProvider *) mLayer->getDataProvider();
167
mProjectionEnabled = ( QgsProject::instance()->readNumEntry( "SpatialRefSys", "/ProjectionsEnabled", 0 ) != 0 );
169
mCanvas = mIface->mapCanvas();
171
if ( !isEditable( layer ) ) return;
173
//TODO dynamic_cast ?
174
mLayer = ( QgsVectorLayer* )layer;
176
//TODO dynamic_cast ?
177
mProvider = ( QgsGrassProvider * ) mLayer->dataProvider();
147
bool QgsGrassEdit::isEditable ( QgsMapLayer *layer )
183
bool QgsGrassEdit::isEditable( QgsMapLayer *layer )
149
185
if ( !layer ) return false;
151
QgsDebugMsg("layer name: " + layer->name());
187
QgsDebugMsgLevel( "layer name: " + layer->name(), 3 );
153
if ( layer->type() != QgsMapLayer::VECTOR ) {
154
QgsDebugMsg("The selected layer is not vector.");
189
if ( layer->type() != QgsMapLayer::VectorLayer )
191
QgsDebugMsgLevel( "The selected layer is not vector.", 3 );
158
195
//TODO dynamic_cast ?
159
QgsVectorLayer *vector = (QgsVectorLayer*)layer;
161
QgsDebugMsg("Vector layer type: " + vector->providerType());
163
if ( vector->providerType() != "grass" ) {
164
QgsDebugMsg("The selected layer is not GRASS.");
196
QgsVectorLayer *vector = ( QgsVectorLayer* )layer;
198
QgsDebugMsgLevel( "Vector layer type: " + vector->providerType(), 3 );
200
if ( vector->providerType() != "grass" )
202
QgsDebugMsgLevel( "The selected layer is not GRASS.", 3 );
171
void QgsGrassEdit::keyPress(QKeyEvent *e)
173
std::cerr << "QgsGrassEdit::keyPress" << std::endl;
174
// This does not work:
177
// TODO: this is not optimal
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;
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)
201
std::cerr << "QgsGrassEdit()" << std::endl;
208
mTool = QgsGrassEdit::NONE;
214
mProjectionEnabled = (QgsProject::instance()->readNumEntry("SpatialRefSys","/ProjectionsEnabled",0)!=0);
216
mCanvas = mIface->getMapCanvas();
218
mProvider = provider;
209
void QgsGrassEdit::keyPress( QKeyEvent *e )
211
QgsDebugMsg( "entered." );
212
// This does not work:
215
// TODO: this is not optimal
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;
223
233
void QgsGrassEdit::init()
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.") );
231
if ( !(mProvider->startEdit()) ) {
232
QMessageBox::warning( 0, tr("Warning"), tr("Cannot open vector for update." ));
236
connect ( mCanvas, SIGNAL(keyPressed(QKeyEvent *)), this, SLOT(keyPress(QKeyEvent *)) );
238
QString myIconPath = QgsApplication::themePath() + "/grass/";
240
mToolBar = addToolBar(tr("Edit tools"));
235
if ( !( mProvider->isGrassEditable() ) )
237
QMessageBox::warning( 0, tr( "Warning" ),
238
tr( "You are not owner of the mapset, cannot open the vector for editing." ) );
242
if ( !( mProvider->startEdit() ) )
244
QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot open vector for update." ) );
248
mRubberBandLine = new QgsRubberBand( mCanvas );
249
mRubberBandIcon = new QgsVertexMarker( mCanvas );
250
mRubberBandLine->setZValue( 20 );
251
mRubberBandIcon->setZValue( 20 );
253
connect( mCanvas, SIGNAL( keyPressed( QKeyEvent * ) ), this, SLOT( keyPress( QKeyEvent * ) ) );
256
mToolBar = addToolBar( tr( "Edit tools" ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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()) );
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 );
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 );
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() ) );
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 );
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 );
353
mEditPoints = Vect_new_line_struct();
354
mPoints = Vect_new_line_struct();
355
mCats = Vect_new_cats_struct();
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++ )
362
mLineSymb[line] = lineSymbFromMap( line );
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++ )
370
mNodeSymb[node] = nodeSymbFromMap( node );
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
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;
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)" );
403
421
// Restore symbology
404
422
QString spath = "/GRASS/edit/symb/";
405
423
QSettings settings;
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 );
414
for ( int i = 0; i < SYMB_COUNT; i++ ) {
416
bool displ = settings.readBoolEntry (
417
spath + "display/" + QString::number(i),
432
for ( int i = 0; i < SYMB_COUNT; i++ )
434
bool ok = settings.contains(
435
spath + "display/" + QString::number( i ) );
436
bool displ = settings.value(
437
spath + "display/" + QString::number( i ),
420
441
mSymbDisplay[i] = displ;
423
QString colorName = settings.readEntry (
424
spath + "color/" + QString::number(i),
444
ok = settings.contains(
445
spath + "color/" + QString::number( i ) );
446
QString colorName = settings.value(
447
spath + "color/" + QString::number( i ),
427
451
QColor color( colorName );
428
452
mSymb[i].setColor( color );
453
// Use the 'dynamic' color for mRubberBand
454
if ( i == SYMB_DYNAMIC )
456
mRubberBandLine->setColor( QColor( colorName ) );
430
459
mSymb[i].setWidth( mLineWidth );
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 );
444
for ( int i = SYMB_COUNT-1; i >= 0; i-- ) {
467
for ( int i = 0; i < SYMB_COUNT; i++ )
445
469
if ( i == SYMB_NODE_0 ) continue;
447
QPixmap pm ( 40, 15 );
471
QPixmap pm( 40, 15 );
448
472
pm.fill( mSymb[i].color() );
450
index.sprintf ("%d", i );
474
index.sprintf( "%d", i );
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 );
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 ) )
479
item->setCheckState( 0, mSymbDisplay[i] ? Qt::Checked : Qt::Unchecked );
481
item->setIcon( 1, pm );
482
item->setText( 2, mSymbName[i] );
483
item->setText( 3, index );
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 ) ) );
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();
474
493
int ndblinks = mProvider->numDbLinks();
476
if ( ndblinks > 0 ) {
477
for ( int i = 0; i < ndblinks; i++ ) {
478
int f = mProvider->dbLinkField ( i );
497
for ( int i = 0; i < ndblinks; i++ )
499
int f = mProvider->dbLinkField( i );
481
str.sprintf ( "%d", f );
482
mTableField->insertItem ( str );
483
mFieldBox->insertItem( str );
502
str.sprintf( "%d", f );
503
mTableField->addItem( str );
504
mFieldBox->addItem( str );
485
507
setAttributeTable( f );
488
mTableField->setCurrentItem ( 0 );
489
mFieldBox->setCurrentItem ( 0 );
491
mTableField->insertItem ( "1" );
492
setAttributeTable ( 1 );
494
mFieldBox->insertItem("1");
497
connect( mAttributeTable, SIGNAL(valueChanged(int,int)), this, SLOT(columnTypeChanged(int,int)) );
510
mTableField->setCurrentIndex( 0 );
511
mFieldBox->setCurrentIndex( 0 );
515
mTableField->addItem( "1" );
516
setAttributeTable( 1 );
518
mFieldBox->addItem( "1" );
521
connect( mAttributeTable, SIGNAL( cellChanged( int, int ) ), this, SLOT( columnTypeChanged( int, int ) ) );
500
524
mSelectedLine = 0;
504
for (int i = 0; i < mProvider->cidxGetNumFields(); i++ ) {
505
int field = mProvider->cidxGetFieldNumber(i);
507
int cat = mProvider->cidxGetMaxCat(i);
528
for ( int i = 0; i < mProvider->cidxGetNumFields(); i++ )
530
int field = mProvider->cidxGetFieldNumber( i );
533
int cat = mProvider->cidxGetMaxCat( i );
509
535
mc.field = field;
511
mMaxCats.push_back(mc);
537
mMaxCats.push_back( mc );
515
connect( mCanvas, SIGNAL(renderComplete(QPainter *)), this, SLOT(postRender(QPainter *)));
517
mCanvasEdit = new QgsGrassEditLayer(mCanvas);
541
connect( mCanvas, SIGNAL( renderComplete( QPainter * ) ), this, SLOT( postRender( QPainter * ) ) );
543
mCanvasEdit = new QgsGrassEditLayer( mCanvas );
520
545
mPixmap = &mCanvasEdit->pixmap();
522
mRubberBandLine = new QgsRubberBand(mCanvas);
523
mRubberBandIcon = new QgsVertexMarker(mCanvas);
524
mRubberBandLine->setZ(20);
525
mRubberBandIcon->setZ(20);
526
mRubberBandLine->show();
527
mRubberBandIcon->show();
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 );
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 );
535
553
// TODO: how to get keyboard events from canvas (shortcuts)
539
555
restorePosition();
545
void QgsGrassEdit::attributeTableFieldChanged ( void )
561
void QgsGrassEdit::attributeTableFieldChanged( void )
548
std::cerr << "QgsGrassEdit::attributeTableFieldChanged" << std::endl;
563
QgsDebugMsg( "entered." );
550
564
int field = mTableField->currentText().toInt();
552
setAttributeTable ( field );
566
setAttributeTable( field );
555
void QgsGrassEdit::setAttributeTable ( int field )
569
void QgsGrassEdit::setAttributeTable( int field )
557
mAttributeTable->setNumRows ( 0 );
559
QString *key = mProvider->key ( field );
561
if ( !key->isEmpty() ) { // Database link defined
562
std::vector<QgsField> *cols = mProvider->columns ( field );
564
mAttributeTable->setNumRows ( cols->size() );
567
for ( int c = 0; c < cols->size(); c++ ) {
568
QgsField col = (*cols)[c];
572
ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, col.name() );
573
ti->setEnabled( false );
574
mAttributeTable->setItem ( c, 0, ti );
576
ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, col.type() );
577
ti->setEnabled( false );
578
mAttributeTable->setItem ( c, 1, ti );
571
mAttributeTable->setRowCount( 0 );
573
QString *key = mProvider->key( field );
575
if ( !key->isEmpty() ) // Database link defined
577
std::vector<QgsField> *cols = mProvider->columns( field );
579
mAttributeTable->setRowCount( cols->size() );
582
for ( unsigned int c = 0; c < cols->size(); c++ )
584
QgsField col = ( *cols )[c];
586
QTableWidgetItem *ti;
588
ti = new QTableWidgetItem( col.name() );
589
ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
590
mAttributeTable->setItem( c, 0, ti );
592
ti = new QTableWidgetItem( col.typeName() );
593
ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
594
mAttributeTable->setItem( c, 1, ti );
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 );
587
mAttributeTable->setNumRows ( 1 );
591
ti = new Q3TableItem( mAttributeTable, Q3TableItem::Always, "cat" );
592
mAttributeTable->setItem ( 0, 0, ti );
594
ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, "integer" );
595
ti->setEnabled( false );
596
mAttributeTable->setItem ( 0, 1, ti );
598
ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, "" );
599
ti->setEnabled( false );
600
mAttributeTable->setItem ( 0, 2, ti );
605
mAttributeTable->setRowCount( 1 );
607
QTableWidgetItem *ti;
609
ti = new QTableWidgetItem( "cat" );
610
mAttributeTable->setItem( 0, 0, ti );
612
ti = new QTableWidgetItem( "integer" );
613
ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
614
mAttributeTable->setItem( 0, 1, ti );
616
ti = new QTableWidgetItem( "" );
617
ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
618
mAttributeTable->setItem( 0, 2, ti );
604
void QgsGrassEdit::addColumn ( void )
622
void QgsGrassEdit::addColumn( void )
607
std::cerr << "QgsGrassEdit::addColumn()" << std::endl;
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 );
614
cn.sprintf ( "column%d", r+1 );
618
ti = new Q3TableItem( mAttributeTable, Q3TableItem::Always, cn );
619
mAttributeTable->setItem ( r, 0, ti );
622
types.push_back ( "integer" );
623
types.push_back ( "double precision" );
624
types.push_back ( "varchar" );
626
Q3ComboTableItem *cti = new Q3ComboTableItem ( mAttributeTable, types );
627
cti->setCurrentItem(0);
628
mAttributeTable->setItem ( r, 1, cti );
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 );
631
QTableWidgetItem *ti;
633
ti = new QTableWidgetItem( cn );
634
mAttributeTable->setItem( r, 0, ti );
636
ti = new QTableWidgetItem( "integer" );
637
mAttributeTable->setItem( r, 1, ti );
639
ti = new QTableWidgetItem( "20" );
640
ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
641
mAttributeTable->setItem( r, 2, ti );
635
void QgsGrassEdit::columnTypeChanged ( int row, int col )
644
void QgsGrassEdit::columnTypeChanged( int row, int col )
638
std::cerr << "QgsGrassEdit::columnChanged() row = " << row << " col = " << col << std::endl;
646
QgsDebugMsg( QString( "row = %1 col = %2" ).arg( row ).arg( col ) );
641
648
if ( col != 1 ) return;
643
Q3ComboTableItem *cti = (Q3ComboTableItem *) mAttributeTable->item ( row, 1 );
645
Q3TableItem *ti = mAttributeTable->item ( row, 2 );
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 );
653
Q3TableItem *nti = new Q3TableItem( mAttributeTable, Q3TableItem::Always, ti->text() );
654
nti->setEnabled(true);
655
mAttributeTable->setItem ( row, 2, nti );
650
QTableWidgetItem *ti = mAttributeTable->item( row, 2 );
653
if ( mAttributeTable->item( row, 1 )->text().compare( "varchar" ) == 0 )
655
ti->setFlags( ti->flags() | Qt::ItemIsEnabled );
659
ti->setFlags( ti->flags() & ~Qt::ItemIsEnabled );
658
mAttributeTable->updateCell ( row, 2 );
661
void QgsGrassEdit::alterTable ( void )
664
void QgsGrassEdit::alterTable( void )
664
std::cerr << "QgsGrassEdit::alterTable()" << std::endl;
666
QgsDebugMsg( "entered." );
667
668
// Create new table if first column name is editable otherwise alter table
668
669
int field = mTableField->currentText().toInt();
671
ti = mAttributeTable->item ( 0, 0 );
675
if ( mAttributeTable->item(0,0)->isEnabled() ) {
677
std::cerr << "Create new table" << std::endl;
680
for ( int i = 0; i < mAttributeTable->numRows(); i++ ) {
681
if ( i > 0 ) sql.append(", " );
684
sql.append ( mAttributeTable->item(i,0)->text() + " " + mAttributeTable->item(i,1)->text() );
686
if ( mAttributeTable->item(i,1)->text().compare("varchar") == 0 ) {
687
sql.append ( " (" + mAttributeTable->item(i,2)->text() + ")" );
674
if ( mAttributeTable->item( 0, 0 )->flags() & Qt::ItemIsEnabled )
676
QgsDebugMsg( "Create new table" );
678
for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
680
if ( i > 0 ) sql.append( ", " );
682
type = mAttributeTable->item( i, 1 )->text();
683
sql.append( mAttributeTable->item( i, 0 )->text() + " " + type );
685
if ( type.compare( "varchar" ) == 0 )
687
sql.append( " (" + mAttributeTable->item( i, 2 )->text() + ")" );
691
QString *error = mProvider->createTable ( field, mAttributeTable->item(0,0)->text(), sql );
691
QString *error = mProvider->createTable( field, mAttributeTable->item( 0, 0 )->text(), sql );
693
if ( !error->isEmpty() ) {
694
QMessageBox::warning( 0, tr("Warning"), *error );
696
QMessageBox::information( 0, tr("Info"), tr("The table was created") );
693
if ( !error->isEmpty() )
695
QMessageBox::warning( 0, tr( "Warning" ), *error );
699
QMessageBox::information( 0, tr( "Info" ), tr( "The table was created" ) );
698
str.sprintf ( "%d", field );
699
mFieldBox->insertItem( str );
701
str.sprintf( "%d", field );
702
mFieldBox->addItem( str );
704
std::cerr << "Alter table" << std::endl;
707
for ( int i = 0; i < mAttributeTable->numRows(); i++ ) {
708
if ( !(mAttributeTable->item(i,0)->isEnabled()) ) continue;
710
sql = mAttributeTable->item(i,0)->text() + " " + mAttributeTable->item(i,1)->text();
712
if ( mAttributeTable->item(i,1)->text().compare("varchar") == 0 ) {
713
sql.append ( " (" + mAttributeTable->item(i,2)->text() + ")" );
708
QgsDebugMsg( "Alter table" );
710
for ( int i = 0; i < mAttributeTable->rowCount(); i++ )
712
if ( !( mAttributeTable->item( i, 0 )->flags() & Qt::ItemIsEnabled ) ) continue;
714
type = mAttributeTable->item( i, 1 )->text();
715
sql = mAttributeTable->item( i, 0 )->text() + " " + type;
717
if ( type.compare( "varchar" ) == 0 )
719
sql.append( " (" + mAttributeTable->item( i, 2 )->text() + ")" );
716
QString *error = mProvider->addColumn ( field, sql );
722
QString *error = mProvider->addColumn( field, sql );
718
if ( !error->isEmpty() ) {
719
QMessageBox::warning( 0, tr("Warning"), *error );
724
if ( !error->isEmpty() )
726
QMessageBox::warning( 0, tr( "Warning" ), *error );
725
setAttributeTable ( field );
732
setAttributeTable( field );
728
void QgsGrassEdit::changeSymbology(Q3ListViewItem * item, const QPoint & pnt, int col)
735
void QgsGrassEdit::changeSymbology( QTreeWidgetItem * item, int col )
731
std::cerr << "QgsGrassEdit::changeSymbology() col = " << col << std::endl;
737
QgsDebugMsg( QString( "col = %1" ).arg( col ) );
734
739
QSettings settings;
736
741
if ( !item ) return;
738
int index = item->text(3).toInt();
741
if ( index == SYMB_BACKGROUND || index == SYMB_HIGHLIGHT || index == SYMB_DYNAMIC ) return;
743
Q3CheckListItem *clvi = (Q3CheckListItem *) item;
744
mSymbDisplay[index] = clvi->isOn();
746
int ww = settings.readNumEntry("/GRASS/windows/edit/w", 420);
743
int index = item->text( 3 ).toInt();
747
if ( index == SYMB_BACKGROUND || index == SYMB_HIGHLIGHT || index == SYMB_DYNAMIC ) return;
749
mSymbDisplay[index] = item->checkState( 0 ) == Qt::Checked;
751
//int ww = settings.readNumEntry("/GRASS/windows/edit/w", 420);
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] );
759
QColor color = QColorDialog::getColor( mSymb[index].color(), this );
753
760
mSymb[index].setColor( color );
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 );
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 )
773
mRubberBandLine->setColor( color );
766
778
void QgsGrassEdit::lineWidthChanged()
769
std::cerr << "QgsGrassEdit::lineWidthChanged()" << std::endl;
772
mLineWidth = mLineWidthSpinBox->value();
774
for ( int i = 0; i < SYMB_COUNT; i++ ) {
775
mSymb[i].setWidth( mLineWidth );
778
QString spath = "/GRASS/edit/symb/";
779
settings.writeEntry ( spath + "lineWidth", mLineWidth );
780
QgsDebugMsg( "entered." );
782
mLineWidth = mLineWidthSpinBox->value();
784
for ( int i = 0; i < SYMB_COUNT; i++ )
786
mSymb[i].setWidth( mLineWidth );
789
QString spath = "/GRASS/edit/symb/";
790
settings.setValue( spath + "lineWidth", mLineWidth );
782
793
void QgsGrassEdit::markerSizeChanged()
785
std::cerr << "QgsGrassEdit::markerSizeChanged()" << std::endl;
788
mSize = mMarkerSizeSpinBox->value();
789
QString spath = "/GRASS/edit/symb/";
790
settings.writeEntry ( spath + "markerSize", mSize );
795
QgsDebugMsg( "entered." );
797
mSize = mMarkerSizeSpinBox->value();
798
QString spath = "/GRASS/edit/symb/";
799
settings.setValue( spath + "markerSize", mSize );
793
802
void QgsGrassEdit::restorePosition()
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);
805
restoreGeometry( settings.value( "/GRASS/windows/edit/geometry" ).toByteArray() );
804
808
void QgsGrassEdit::saveWindowLocation()
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());
811
settings.setValue( "/GRASS/windows/edit/geometry", saveGeometry() );
815
void QgsGrassEdit::updateSymb ( void )
814
void QgsGrassEdit::updateSymb( void )
818
std::cerr << "QgsGrassEdit::updateSymb" << std::endl;
816
QgsDebugMsg( "entered." );
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 );
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++ )
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 );
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 );
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++ )
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] ) );
848
int QgsGrassEdit::nodeSymbFromMap ( int node )
847
int QgsGrassEdit::nodeSymbFromMap( int node )
851
std::cerr << "QgsGrassEdit::nodeSymbFromMap() node = " << node << std::endl;
849
QgsDebugMsg( QString( "node = %1" ).arg( node ) );
854
int nlines = mProvider->nodeNLines ( node );
851
int nlines = mProvider->nodeNLines( node );
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++ )
857
int line = abs( mProvider->nodeLine( node, i ) );
858
int type = mProvider->readLine( NULL, NULL, line );
862
860
if ( type & GV_LINES )
867
865
return SYMB_NODE_0;
868
866
else if ( count == 1 )
869
867
return SYMB_NODE_1;
935
930
mRubberBandLine->reset();
936
931
delete mRubberBandLine;
937
932
delete mRubberBandIcon;
939
934
delete mCanvasEdit;
941
936
mCanvas->refresh();
943
938
saveWindowLocation();
945
940
mRunning = false;
948
bool QgsGrassEdit::isRunning(void)
943
bool QgsGrassEdit::isRunning( void )
953
bool QgsGrassEdit::isValid(void)
948
bool QgsGrassEdit::isValid( void )
958
void QgsGrassEdit::closeEdit(void)
953
void QgsGrassEdit::closeEdit( void )
961
std::cerr << "QgsGrassEdit::close()" << std::endl;
964
// grass edit tool would become invalid
965
// so change it to another one, e.g. pan tool
955
QgsDebugMsg( "entered." );
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 * ) ) );
973
962
mValid = false; // important for postRender
976
966
delete mAttributes;
979
mProvider->closeEdit(mNewMap);
969
mProvider->closeEdit( mNewMap );
983
973
// Add new layers
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();
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();
998
QgsGrassUtils::addVectorLayers ( mIface, QgsGrass::getDefaultGisdbase(),
999
QgsGrass::getDefaultLocation(),
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();
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();
988
QgsGrassUtils::addVectorLayers( mIface, QgsGrass::getDefaultGisdbase(),
989
QgsGrass::getDefaultLocation(),
1002
992
emit finished();
1006
void QgsGrassEdit::closeEvent(QCloseEvent *e)
996
void QgsGrassEdit::closeEvent( QCloseEvent *e )
1009
std::cerr << "QgsGrassEdit::closeEvent()" << std::endl;
998
QgsDebugMsg( "entered." );
1017
void QgsGrassEdit::catModeChanged ( void )
1020
std::cerr << "QgsGrassEdit::catModeChanged()" << std::endl;
1022
int mode = mCatModeBox->currentItem();
1024
int field = mFieldBox->currentText().toInt();
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);
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);
1047
void QgsGrassEdit::fieldChanged ( void )
1050
std::cerr << "QgsGrassEdit::fieldChanged()" << std::endl;
1052
int mode = mCatModeBox->currentItem();
1053
int field = mFieldBox->currentText().toInt();
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);
1063
mCatEntry->setText ( c );
1067
int QgsGrassEdit::writeLine ( int type, struct line_pnts *Points )
1069
int mode = mCatModeBox->currentItem();
1005
void QgsGrassEdit::catModeChanged( void )
1007
QgsDebugMsg( "entered." );
1008
int mode = mCatModeBox->currentIndex();
1010
int field = mFieldBox->currentText().toInt();
1012
if ( mode == CAT_MODE_NEXT ) // Find next not used
1014
QString c = "1"; // Default for new field
1015
for ( unsigned int i = 0; i < mMaxCats.size(); i++ )
1017
if ( mMaxCats[i].field == field )
1019
c.sprintf( "%d", mMaxCats[i].maxCat + 1 );
1023
mCatEntry->setText( c );
1024
mCatEntry->setEnabled( false );
1025
mFieldBox->setDisabled( false );
1027
else if ( mode == CAT_MODE_MANUAL )
1029
mCatEntry->setEnabled( true );
1030
mFieldBox->setDisabled( false );
1032
else // CAT_MODE_NOCAT
1035
mCatEntry->setEnabled( false );
1036
mFieldBox->setDisabled( true );
1040
void QgsGrassEdit::fieldChanged( void )
1042
QgsDebugMsg( "entered." );
1043
int mode = mCatModeBox->currentIndex();
1044
int field = mFieldBox->currentText().toInt();
1046
if ( mode == CAT_MODE_NEXT ) // Find next not used
1048
QString c = "1"; // Default for new field
1049
for ( unsigned int i = 0; i < mMaxCats.size(); i++ )
1051
if ( mMaxCats[i].field == field )
1053
c.sprintf( "%d", mMaxCats[i].maxCat + 1 );
1057
mCatEntry->setText( c );
1061
int QgsGrassEdit::writeLine( int type, struct line_pnts *Points )
1063
int mode = mCatModeBox->currentIndex();
1070
1064
int field = mFieldBox->currentText().toInt();
1071
1065
int cat = mCatEntry->text().toInt();
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 )
1070
Vect_cat_set( mCats, field, cat );
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 );
1080
if ( !key->isEmpty() ) { // Database link defined
1081
std::vector<QgsFeatureAttribute> *atts = mProvider->attributes ( field, cat );
1083
if ( atts->size() == 0 ) { // Nothing selected
1084
QString *error = mProvider->insertAttributes ( field, cat );
1086
if ( !error->isEmpty() ) {
1087
QMessageBox::warning( 0, tr("Warning"), *error );
1073
QString *key = mProvider->key( field );
1075
if ( !key->isEmpty() ) // Database link defined
1077
QgsAttributeMap *atts = mProvider->attributes( field, cat );
1079
if ( atts->count() == 0 ) // Nothing selected
1081
QString *error = mProvider->insertAttributes( field, cat );
1083
if ( !error->isEmpty() )
1085
QMessageBox::warning( 0, tr( "Warning" ), *error );
1264
1320
// Start new tool
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 );
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 );
1280
mMapTool = new QgsGrassEditNewLine(this, false);
1281
mMapTool->setAction(mNewLineAction);
1336
mMapTool = new QgsGrassEditNewLine( this, false );
1337
mMapTool->setAction( mNewLineAction );
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 );
1289
1345
case MOVE_VERTEX:
1290
mMapTool = new QgsGrassEditMoveVertex(this);
1291
mMapTool->setAction(mMoveVertexAction);
1346
mMapTool = new QgsGrassEditMoveVertex( this );
1347
mMapTool->setAction( mMoveVertexAction );
1294
1350
case ADD_VERTEX:
1295
mMapTool = new QgsGrassEditAddVertex(this);
1296
mMapTool->setAction(mAddVertexAction);
1351
mMapTool = new QgsGrassEditAddVertex( this );
1352
mMapTool->setAction( mAddVertexAction );
1299
1355
case DELETE_VERTEX:
1300
mMapTool = new QgsGrassEditDeleteVertex(this);
1301
mMapTool->setAction(mDeleteVertexAction);
1356
mMapTool = new QgsGrassEditDeleteVertex( this );
1357
mMapTool->setAction( mDeleteVertexAction );
1304
1360
case MOVE_LINE:
1305
mMapTool = new QgsGrassEditMoveLine(this);
1306
mMapTool->setAction(mMoveLineAction);
1361
mMapTool = new QgsGrassEditMoveLine( this );
1362
mMapTool->setAction( mMoveLineAction );
1309
1365
case DELETE_LINE:
1310
mMapTool = new QgsGrassEditDeleteLine(this);
1311
mMapTool->setAction(mDeleteLineAction);
1366
mMapTool = new QgsGrassEditDeleteLine( this );
1367
mMapTool->setAction( mDeleteLineAction );
1314
1370
case SPLIT_LINE:
1315
mMapTool = new QgsGrassEditSplitLine(this);
1316
mMapTool->setAction(mSplitLineAction);
1371
mMapTool = new QgsGrassEditSplitLine( this );
1372
mMapTool->setAction( mSplitLineAction );
1319
1375
case EDIT_ATTRIBUTES:
1320
mMapTool = new QgsGrassEditAttributes(this);
1321
mMapTool->setAction(mEditAttributesAction);
1376
mMapTool = new QgsGrassEditAttributes( this );
1377
mMapTool->setAction( mEditAttributesAction );
1324
1380
case EDIT_CATS:
1326
QMessageBox::warning( 0, tr("Warning"), tr("Tool not yet implemented.") );
1382
QMessageBox::warning( 0, tr( "Warning" ), tr( "Tool not yet implemented." ) );
1330
std::cerr << "Unknown tool" << std::endl;
1386
QgsDebugMsg( "Unknown tool" );
1334
1390
// assign newly created tool to map canvas
1335
mCanvas->setMapTool(mMapTool);
1391
mCanvas->setMapTool( mMapTool );
1340
void QgsGrassEdit::checkOrphan ( int field, int cat )
1394
void QgsGrassEdit::checkOrphan( int field, int cat )
1343
std::cerr << "QgsGrassEdit::checkOrphan field = " << field
1344
<< " cat = " << cat << std::endl;
1396
QgsDebugMsg( QString( "field = %1 cat = %2" ).arg( field ).arg( cat ) );
1348
QString *error = mProvider->isOrphan ( field, cat, &orphan );
1399
QString *error = mProvider->isOrphan( field, cat, &orphan );
1350
if ( !error->isEmpty() ) {
1351
QMessageBox::warning( 0, tr("Warning"), tr("Cannot check orphan record: ")
1401
if ( !error->isEmpty() )
1403
QMessageBox::warning( 0, tr( "Warning" ),
1404
tr( "Cannot check orphan record: %1" ).arg( *error ) );
1355
1407
if ( !orphan ) return;
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 );
1362
if ( ret == QMessageBox::No ) return;
1414
if ( ret == QMessageBox::Cancel ) return;
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: ")
1417
error = mProvider->deleteAttributes( field, cat );
1418
if ( !error->isEmpty() )
1420
QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot delete orphan record: " )
1373
void QgsGrassEdit::addAttributes ( int field, int cat )
1426
void QgsGrassEdit::addAttributes( int field, int cat )
1375
QString *key = mProvider->key ( field );
1428
QString *key = mProvider->key( field );
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 );
1382
1435
QString catLabel;
1383
if ( key->isEmpty() ) {
1436
if ( key->isEmpty() )
1384
1438
catLabel = "Category";
1386
1442
catLabel = *key;
1388
mAttributes->setCat ( tab, catLabel, cat );
1390
if ( !key->isEmpty() ) { // Database link defined
1391
std::vector<QgsField> *cols = mProvider->columns ( field );
1393
if ( cols->size() == 0 ) {
1444
mAttributes->setCat( tab, catLabel, cat );
1446
if ( !key->isEmpty() ) // Database link defined
1448
std::vector<QgsField> *cols = mProvider->columns( field );
1450
if ( cols->size() == 0 )
1395
1453
str.setNum( field );
1396
QMessageBox::warning( 0, tr("Warning"), tr("Cannot describe table for field ") + str );
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 ) );
1458
QgsAttributeMap *atts = mProvider->attributes( field, cat );
1401
if ( atts->size() == 0 ) { // cannot select attributes
1402
mAttributes->addTextRow ( tab, "WARNING: ATTRIBUTES MISSING" );
1460
if ( atts->size() == 0 ) // cannot select attributes
1462
mAttributes->addTextRow( tab, "WARNING: ATTRIBUTES MISSING" );
1405
if ( atts->size() < cols->size() )
1467
if ( atts->size() < ( int ) cols->size() )
1406
1468
size = atts->size();
1408
1470
size = cols->size();
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++ )
1474
QgsField col = ( *cols )[j];
1475
QVariant att = ( *atts )[j];
1476
QgsDebugMsg( QString( " name = %1" ).arg( col.name() ) );
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 )
1480
QgsDebugMsg( QString( " value = %1" ).arg( att.toString() ) );
1481
mAttributes->addAttribute( tab, col.name(), att.toString(), col.typeName() );
1499
1563
// Redisplay highlighted
1500
if ( mSelectedLine ) {
1501
displayElement ( mSelectedLine, mSymb[SYMB_HIGHLIGHT], mSize );
1564
if ( mSelectedLine )
1566
displayElement( mSelectedLine, mSymb[SYMB_HIGHLIGHT], mSize );
1505
void QgsGrassEdit::displayMap ()
1570
void QgsGrassEdit::displayMap()
1508
std::cerr << "QgsGrassEdit::displayMap" << std::endl;
1572
QgsDebugMsg( "entered." );
1511
1574
mTransform = mCanvas->getCoordinateTransform();
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 ) );
1517
1580
QPainter *painter = new QPainter();
1518
painter->begin(mPixmap);
1581
painter->begin( mPixmap );
1520
1583
// Display lines
1521
int nlines = mProvider->numLines();
1584
int nlines = mProvider->numLines();
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++ )
1591
displayElement( line, mSymb[mLineSymb[line]], mSize, painter );
1530
1594
// Display nodes
1531
int nnodes = mProvider->numNodes();
1533
pen.setColor(QColor(255,0,0));
1535
if ( mSymbDisplay[SYMB_NODE_1] || mSymbDisplay[SYMB_NODE_2] ) {
1536
for ( int node = 1; node <= nnodes; node++ ) {
1595
int nnodes = mProvider->numNodes();
1597
pen.setColor( QColor( 255, 0, 0 ) );
1599
if ( mSymbDisplay[SYMB_NODE_1] || mSymbDisplay[SYMB_NODE_2] )
1601
for ( int node = 1; node <= nnodes; node++ )
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 );
1542
1608
painter->end();
1543
1609
delete painter;
1545
mCanvas->updateContents();
1611
// porting mCanvas->update();
1612
mCanvasEdit->update();
1613
mRubberBandIcon->update();
1614
mRubberBandLine->update();
1548
void QgsGrassEdit::displayUpdated (void)
1617
void QgsGrassEdit::displayUpdated( void )
1551
std::cerr << "QgsGrassEdit::displayUpdated" << std::endl;
1619
QgsDebugMsg( "entered." );
1554
1621
mTransform = mCanvas->getCoordinateTransform();
1555
mProjectionEnabled = (QgsProject::instance()->readNumEntry("SpatialRefSys","/ProjectionsEnabled",0)!=0);
1622
mProjectionEnabled = ( QgsProject::instance()->readNumEntry( "SpatialRefSys", "/ProjectionsEnabled", 0 ) != 0 );
1557
1624
QPainter *painter = new QPainter();
1558
painter->begin(mPixmap);
1625
painter->begin( mPixmap );
1560
1627
// Display lines
1561
1628
int nlines = mProvider->numUpdatedLines();
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++ )
1632
int line = mProvider->updatedLine( i );
1633
if ( !( mProvider->lineAlive( line ) ) ) continue;
1567
displayElement ( line, mSymb[mLineSymb[line]], mSize, painter );
1635
displayElement( line, mSymb[mLineSymb[line]], mSize, painter );
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++ )
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 );
1579
1648
painter->end();
1580
1649
delete painter;
1582
mCanvas->updateContents();
1651
// porting mCanvas->update();
1652
mCanvasEdit->update();
1653
mRubberBandIcon->update();
1654
mRubberBandLine->update();
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 )
1588
std::cerr << "QgsGrassEdit::displayElement() line = " << line << std::endl;
1659
QgsDebugMsg( QString( "line = %1" ).arg( line ) );
1661
// is it a valid line?
1591
1665
if ( !mSymbDisplay[mLineSymb[line]] ) return;
1593
int type = mProvider->readLine ( mPoints, NULL, line );
1667
int type = mProvider->readLine( mPoints, NULL, line );
1594
1668
if ( type < 0 ) return;
1596
1670
QPainter *myPainter;
1598
1673
myPainter = new QPainter();
1599
myPainter->begin(mPixmap);
1674
myPainter->begin( mPixmap );
1601
1678
myPainter = painter;
1604
if ( type & GV_POINTS ) {
1605
displayIcon ( mPoints->x[0], mPoints->y[0], pen, QgsVertexMarker::ICON_CROSS, size, myPainter );
1681
if ( type & GV_POINTS )
1683
displayIcon( mPoints->x[0], mPoints->y[0], pen, QgsVertexMarker::ICON_CROSS, size, myPainter );
1607
1687
QgsPoint point;
1608
Q3PointArray pointArray(mPoints->n_points);
1688
QPolygon pointArray( mPoints->n_points );
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++ )
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() ) ) );
1618
myPainter->setPen ( pen );
1619
myPainter->drawPolyline ( pointArray );
1699
myPainter->setPen( pen );
1700
myPainter->drawPolyline( pointArray );
1623
1705
myPainter->end();
1624
mCanvas->updateContents();
1706
// porting mCanvas->update();
1707
mCanvasEdit->update();
1625
1708
delete myPainter;
1629
void QgsGrassEdit::eraseElement ( int line )
1712
void QgsGrassEdit::eraseElement( int line )
1632
std::cerr << "QgsGrassEdit::eraseElement() line = " << line << std::endl;
1714
QgsDebugMsg( QString( "line = %1" ).arg( line ) );
1635
int type = mProvider->readLine ( NULL, NULL, line );
1716
int type = mProvider->readLine( NULL, NULL, line );
1636
1717
if ( type < 0 ) return;
1639
displayElement ( line, mSymb[SYMB_BACKGROUND], mSize );
1720
displayElement( line, mSymb[SYMB_BACKGROUND], mSize );
1642
if ( type & GV_LINES ) {
1723
if ( type & GV_LINES )
1643
1725
int node1, node2;
1644
1726
mProvider->lineNodes( line, &node1, &node2 );
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 );
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 );
1655
void QgsGrassEdit::eraseDynamic ( void )
1657
displayDynamic ( 0, 0.0, 0.0, QgsVertexMarker::ICON_NONE, 0 );
1660
void QgsGrassEdit::displayDynamic ( struct line_pnts *Points )
1662
displayDynamic ( Points, 0.0, 0.0, QgsVertexMarker::ICON_NONE, 0 );
1665
void QgsGrassEdit::displayDynamic ( double x, double y, int type, int size )
1668
std::cerr << "QgsGrassEdit::displayDynamic icon" << std::endl;
1671
displayDynamic ( 0, x, y, type, size );
1674
void QgsGrassEdit::displayDynamic ( struct line_pnts *Points, double x, double y, int type, int size )
1677
std::cerr << "QgsGrassEdit::displayDynamic Points = " << Points << " type = " << type << std::endl;
1681
//mTransform = mCanvas->getCoordinateTransform();
1683
// Dynamic points are in layer coordinate system, we have to
1684
// reproject them to current coordinate system if necessary
1686
mRubberBandLine->reset();
1737
void QgsGrassEdit::eraseDynamic( void )
1739
displayDynamic( 0, 0.0, 0.0, QgsVertexMarker::ICON_NONE, 0 );
1742
void QgsGrassEdit::displayDynamic( struct line_pnts *Points )
1744
displayDynamic( Points, 0.0, 0.0, QgsVertexMarker::ICON_NONE, 0 );
1747
void QgsGrassEdit::displayDynamic( double x, double y, int type, int size )
1749
QgsDebugMsg( "entered." );
1751
displayDynamic( 0, x, y, type, size );
1754
void QgsGrassEdit::displayDynamic( struct line_pnts *Points, double x, double y, int type, int size )
1756
QgsDebugMsg( QString( "Points = %1 type = %2" ).arg( QString::number(( qulonglong )Points, 16 ).toLocal8Bit().constData() ).arg( type ) );
1759
//mTransform = mCanvas->getCoordinateTransform();
1761
// Dynamic points are in layer coordinate system, we have to
1762
// reproject them to current coordinate system if necessary
1764
mRubberBandLine->reset();
1768
for ( int i = 0; i < Points->n_points; i++ )
1690
for ( int i = 0; i < Points->n_points; i++ )
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
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
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 );
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 );
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 )
1712
std::cerr << "QgsGrassEdit::displayNode() node = " << node << std::endl;
1789
QgsDebugMsg( QString( "node = %1" ).arg( node ) );
1715
1791
if ( !mSymbDisplay[mNodeSymb[node]] ) return;
1719
if ( !(mProvider->nodeCoor(node,&x,&y )) ) return;
1721
displayIcon ( x, y, pen, QgsVertexMarker::ICON_X, size, painter );
1724
QgsPoint QgsGrassEdit::transformLayerToCanvas ( QgsPoint point)
1726
if ( mProjectionEnabled && mLayer->coordinateTransform() )
1730
point = mLayer->coordinateTransform()->transform(point);
1732
catch(QgsCsException &cse)
1734
std::cout << "cannot transform point" << std::endl;
1738
mTransform->transform(&point);
1742
QgsPoint QgsGrassEdit::transformLayerToMap ( QgsPoint point)
1744
std::cout << "mProjectionEnabled = " << mProjectionEnabled << std::endl;
1745
if ( mProjectionEnabled && mLayer->coordinateTransform() )
1749
point = mLayer->coordinateTransform()->transform(point);
1751
catch(QgsCsException &cse)
1753
std::cout << "cannot transform point" << std::endl;
1760
void QgsGrassEdit::displayIcon ( double x, double y, const QPen & pen,
1761
int type, int size, QPainter *painter )
1764
std::cerr << "QgsGrassEdit::displayIcon()" << std::endl;
1795
if ( !( mProvider->nodeCoor( node, &x, &y ) ) ) return;
1797
displayIcon( x, y, pen, QgsVertexMarker::ICON_X, size, painter );
1800
QgsPoint QgsGrassEdit::transformLayerToCanvas( QgsPoint point )
1802
point = mCanvas->mapRenderer()->layerToMapCoordinates( mLayer, point );
1803
return mTransform->transform( point );
1806
QgsPoint QgsGrassEdit::transformLayerToMap( QgsPoint point )
1808
return mCanvas->mapRenderer()->layerToMapCoordinates( mLayer, point );
1811
void QgsGrassEdit::displayIcon( double x, double y, const QPen & pen,
1812
int type, int size, QPainter *painter )
1814
QgsDebugMsg( "entered." );
1767
1816
QgsPoint point;
1768
Q3PointArray pointArray(2);
1773
point = transformLayerToCanvas ( point );
1775
int px = static_cast<int>(round(point.x()));
1776
int py = static_cast<int>(round(point.y()));
1817
QPolygon pointArray( 2 );
1822
point = transformLayerToCanvas( point );
1824
int px = static_cast<int>( round( point.x() ) );
1825
int py = static_cast<int>( round( point.y() ) );
1826
int m = ( size - 1 ) / 2;
1779
1828
QPainter *myPainter;
1781
1831
myPainter = new QPainter();
1782
myPainter->begin(mPixmap);
1832
myPainter->begin( mPixmap );
1784
1836
myPainter = painter;
1787
myPainter->setPen ( pen );
1839
myPainter->setPen( pen );
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 );
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 );
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 );
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 );
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 );
1820
1874
myPainter->end();
1821
mCanvas->updateContents();
1875
//mCanvas->update();
1876
mCanvasEdit->update();
1822
1877
delete myPainter;
1826
void QgsGrassEdit::setCanvasPropmt( QString left, QString mid, QString rigth)
1881
void QgsGrassEdit::setCanvasPrompt( QString left, QString mid, QString right )
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 ) );
1835
1890
void QgsGrassEdit::attributesClosed()