Skip to content

Commit 964e842

Browse files
committedJan 7, 2013
Merge branch 'master' of https://github.com/qgis/Quantum-GIS
2 parents e59de66 + 7e29d7c commit 964e842

40 files changed

+5105
-4673
lines changed
 

‎doc/TRANSLATORS

Lines changed: 37 additions & 37 deletions
Large diffs are not rendered by default.

‎i18n/qgis_de.ts

Lines changed: 1172 additions & 1634 deletions
Large diffs are not rendered by default.

‎python/core/qgsapplication.sip

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ static void qtgui_UpdatePyArgv(PyObject *argvlist, int argc, char **argv)
152152
//! @note added in 1.4
153153
static const QStringList svgPaths();
154154

155+
//! Returns the system environment variables passed to application.
156+
//! @note added in 1.9
157+
static const QMap<QString, QString> systemEnvVars();
158+
155159
//! Returns the path to the application prefix directory.
156160
static const QString prefixPath();
157161

‎python/core/qgsmaplayerregistry.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ class QgsMapLayerRegistry : QObject
2222
//! Retrieve a pointer to a loaded layer by id
2323
QgsMapLayer *mapLayer( QString theLayerId );
2424

25+
//! Retrieve all layers using their name
26+
QList<QgsMapLayer *> mapLayersByName( QString layerName );
27+
2528
//! Retrieve the mapLayers collection (mainly intended for use by projection)
2629
QMap<QString, QgsMapLayer*> & mapLayers();
2730

‎python/core/qgsvectorlayerimport.sip

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class QgsVectorLayerImport
99
%TypeHeaderCode
1010
#include <qgsvectorlayerimport.h>
1111
#include <qgsfield.h>
12+
class QProgressDialog;
1213
%End
1314

1415
public:
@@ -37,7 +38,8 @@ class QgsVectorLayerImport
3738
bool onlySelected = false,
3839
QString *errorMessage /Out/ = 0,
3940
bool skipAttributeCreation = false,
40-
QMap<QString, QVariant> *options = 0
41+
QMap<QString, QVariant> *options = 0,
42+
QProgressDialog *progress = 0
4143
);
4244

4345
/** create a empty layer and add fields to it */
@@ -47,7 +49,8 @@ class QgsVectorLayerImport
4749
QGis::WkbType geometryType,
4850
const QgsCoordinateReferenceSystem* crs,
4951
bool overwrite = false,
50-
const QMap<QString, QVariant> *options = 0
52+
const QMap<QString, QVariant> *options = 0,
53+
QProgressDialog *progress = 0
5154
);
5255

5356
/** checks whether there were any errors */

‎src/app/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ SET(QGIS_APP_SRCS
9191
qgsmeasuretool.cpp
9292
qgsmergeattributesdialog.cpp
9393
qgsoptions.cpp
94-
qgspastetransformations.cpp
94+
#qgspastetransformations.cpp
9595
qgspointrotationitem.cpp
9696
qgspluginitem.cpp
9797
qgspluginmanager.cpp
@@ -244,7 +244,7 @@ SET (QGIS_APP_MOC_HDRS
244244
qgsmeasuretool.h
245245
qgsmergeattributesdialog.h
246246
qgsoptions.h
247-
qgspastetransformations.h
247+
#qgspastetransformations.h
248248
qgspluginmanager.h
249249
qgsprojectlayergroupdialog.h
250250
qgsprojectproperties.h

‎src/app/main.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,60 @@ int main( int argc, char *argv[] )
569569

570570
QSettings mySettings;
571571

572+
// custom environment variables
573+
QMap<QString, QString> systemEnvVars = QgsApplication::systemEnvVars();
574+
bool useCustomVars = mySettings.value( "qgis/customEnvVarsUse", QVariant( false ) ).toBool();
575+
if ( useCustomVars )
576+
{
577+
QStringList customVarsList = mySettings.value( "qgis/customEnvVars", "" ).toStringList();
578+
if ( !customVarsList.isEmpty() )
579+
{
580+
foreach ( const QString &varStr, customVarsList )
581+
{
582+
int pos = varStr.indexOf( QLatin1Char( '|' ) );
583+
if ( pos == -1 )
584+
continue;
585+
QString envVarApply = varStr.left( pos );
586+
QString varStrNameValue = varStr.mid( pos + 1 );
587+
pos = varStrNameValue.indexOf( QLatin1Char( '=' ) );
588+
if ( pos == -1 )
589+
continue;
590+
QString envVarName = varStrNameValue.left( pos );
591+
QString envVarValue = varStrNameValue.mid( pos + 1 );
592+
593+
if ( systemEnvVars.contains( envVarName ) )
594+
{
595+
if ( envVarApply == "prepend" )
596+
{
597+
envVarValue += systemEnvVars.value( envVarName );
598+
}
599+
else if ( envVarApply == "append" )
600+
{
601+
envVarValue = systemEnvVars.value( envVarName ) + envVarValue;
602+
}
603+
}
604+
605+
if ( systemEnvVars.contains( envVarName ) && envVarApply == "unset" )
606+
{
607+
#ifdef Q_WS_WIN
608+
putenv( envVarName.toUtf8().constData() );
609+
#else
610+
unsetenv( envVarName.toUtf8().constData() );
611+
#endif
612+
}
613+
else
614+
{
615+
#ifdef Q_WS_WIN
616+
if ( envVarApply != "undefined" || !getenv( envVarName.toUtf8().constData() ) )
617+
putenv( QString( "%1=%2" ).arg( envVarName ).arg( envVarValue ).toUtf8().constData() );
618+
#else
619+
setenv( envVarName.toUtf8().constData(), envVarValue.toUtf8().constData(), envVarApply == "undefined" ? 0 : 1 );
620+
#endif
621+
}
622+
}
623+
}
624+
}
625+
572626
// Set the application style. If it's not set QT will use the platform style except on Windows
573627
// as it looks really ugly so we use QPlastiqueStyle.
574628
QString style = mySettings.value( "/qgis/style" ).toString();

‎src/app/qgisapp.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@
147147
#include "qgsmultibandcolorrenderer.h"
148148
#include "qgsnewvectorlayerdialog.h"
149149
#include "qgsoptions.h"
150-
#include "qgspastetransformations.h"
150+
// #include "qgspastetransformations.h"
151151
#include "qgspluginitem.h"
152152
#include "qgspluginlayer.h"
153153
#include "qgspluginlayerregistry.h"
@@ -3330,11 +3330,12 @@ bool QgisApp::addProject( QString projectFile )
33303330

33313331
if ( ! QgsProject::instance()->read( projectFile ) )
33323332
{
3333+
QApplication::restoreOverrideCursor();
3334+
33333335
QMessageBox::critical( this,
33343336
tr( "Unable to open project" ),
33353337
QgsProject::instance()->error() );
33363338

3337-
QApplication::restoreOverrideCursor();
33383339

33393340
mMapCanvas->freeze( false );
33403341
mMapCanvas->refresh();
@@ -4964,11 +4965,13 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
49644965

49654966
QHash<int, int> remap;
49664967
const QgsFieldMap &fields = clipboard()->fields();
4968+
QgsAttributeList pkAttrList = pasteVectorLayer->pendingPkAttributesList();
49674969
for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); it++ )
49684970
{
49694971
int dst = pasteVectorLayer->fieldNameIndex( it->name() );
4970-
if ( dst < 0 )
4972+
if ( dst < 0 || pkAttrList.contains( dst ) )
49714973
{
4974+
// skip primary key attributes
49724975
continue;
49734976
}
49744977
remap.insert( it.key(), dst );
@@ -5064,6 +5067,7 @@ void QgisApp::pasteStyle( QgsMapLayer * destinationLayer )
50645067
}
50655068
}
50665069

5070+
#if 0
50675071
void QgisApp::pasteTransformations()
50685072
{
50695073
QgsPasteTransformations *pt = new QgsPasteTransformations();
@@ -5072,7 +5076,7 @@ void QgisApp::pasteTransformations()
50725076

50735077
pt->exec();
50745078
}
5075-
5079+
#endif
50765080

50775081
void QgisApp::refreshMapCanvas()
50785082
{

‎src/app/qgisapp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
10481048
//! Read Well Known Binary stream from PostGIS
10491049
//void readWKB(const char *, QStringList tables);
10501050
//! shows the paste-transformations dialog
1051-
void pasteTransformations();
1051+
// void pasteTransformations();
10521052
//! check to see if file is dirty and if so, prompt the user th save it
10531053
bool saveDirty();
10541054
/** Helper function to union several geometries together (used in function mergeSelectedFeatures)

‎src/app/qgsbrowserdockwidget.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "qgsrasterlayer.h"
2929
#include "qgsvectorlayer.h"
3030
#include "qgisapp.h"
31+
#include "qgsproject.h"
3132

3233
// browser layer properties dialog
3334
#include "qgsapplication.h"
@@ -285,6 +286,10 @@ void QgsBrowserDockWidget::showEvent( QShowEvent * e )
285286
if ( item && item->type() == QgsDataItem::Favourites )
286287
mBrowserView->expand( index );
287288
}
289+
290+
connect( QgsProject::instance(), SIGNAL( readProject( const QDomDocument & ) ), mModel, SLOT( reload() ) );
291+
connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument & ) ), mModel, SLOT( reload() ) );
292+
connect( QgisApp::instance(), SIGNAL( newProject() ), mModel, SLOT( reload() ) );
288293
}
289294

290295
QDockWidget::showEvent( e );

‎src/app/qgsfieldsproperties.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ QgsAttributeEditorElement* QgsFieldsProperties::createAttributeEditorWidget( QTr
752752

753753
if ( item->data( 0, Qt::UserRole ) == "field" )
754754
{
755-
int idx = *mLayer->dataProvider()->fieldNameMap().find( item->text( 0 ) );
755+
int idx = *( mLayer->dataProvider()->fieldNameMap() ).find( item->text( 0 ) );
756756
widgetDef = new QgsAttributeEditorField( item->text( 0 ), idx, parent );
757757
}
758758
else

‎src/app/qgsmergeattributesdialog.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ void QgsMergeAttributesDialog::createTableWidgetContents()
8484

8585
//create combo boxes and insert attribute names
8686
const QgsFieldMap& fieldMap = mVectorLayer->pendingFields();
87+
QgsAttributeList pkAttrList = mVectorLayer->pendingPkAttributesList();
8788

8889
int col = 0;
8990
for ( QgsFieldMap::const_iterator fieldIt = fieldMap.constBegin();
@@ -96,7 +97,12 @@ void QgsMergeAttributesDialog::createTableWidgetContents()
9697

9798
mTableWidget->setColumnCount( col + 1 );
9899

99-
mTableWidget->setCellWidget( 0, col, createMergeComboBox( fieldIt->type() ) );
100+
QComboBox *cb = createMergeComboBox( fieldIt->type() );
101+
if ( pkAttrList.contains( fieldIt.key() ) )
102+
{
103+
cb->setCurrentIndex( cb->findText( tr( "Skip attribute" ) ) );
104+
}
105+
mTableWidget->setCellWidget( 0, col, cb );
100106

101107
QTableWidgetItem *item = new QTableWidgetItem( fieldIt.value().name() );
102108
item->setData( Qt::UserRole, fieldIt.key() );
@@ -135,14 +141,14 @@ void QgsMergeAttributesDialog::createTableWidgetContents()
135141
}
136142
}
137143

138-
QComboBox* QgsMergeAttributesDialog::createMergeComboBox( QVariant::Type columnType ) const
144+
QComboBox *QgsMergeAttributesDialog::createMergeComboBox( QVariant::Type columnType ) const
139145
{
140-
QComboBox* newComboBox = new QComboBox();
146+
QComboBox *newComboBox = new QComboBox();
141147
//add items for feature
142148
QgsFeatureList::const_iterator f_it = mFeatureList.constBegin();
143149
for ( ; f_it != mFeatureList.constEnd(); ++f_it )
144150
{
145-
newComboBox->addItem( tr( "feature %1" ).arg( f_it->id() ) );
151+
newComboBox->addItem( tr( "Feature %1" ).arg( f_it->id() ) );
146152
}
147153

148154
if ( columnType == QVariant::Double || columnType == QVariant::Int )
@@ -183,7 +189,7 @@ int QgsMergeAttributesDialog::findComboColumn( QComboBox* c ) const
183189
void QgsMergeAttributesDialog::comboValueChanged( const QString &text )
184190
{
185191
Q_UNUSED( text );
186-
QComboBox* senderComboBox = qobject_cast<QComboBox *>( sender() );
192+
QComboBox *senderComboBox = qobject_cast<QComboBox *>( sender() );
187193
if ( !senderComboBox )
188194
{
189195
return;

‎src/app/qgsoptions.cpp

Lines changed: 225 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
#include <QSettings>
4040
#include <QColorDialog>
4141
#include <QLocale>
42+
#include <QProcess>
4243
#include <QToolBar>
44+
#include <QScrollBar>
4345
#include <QSize>
4446
#include <QStyleFactory>
4547
#include <QMessageBox>
@@ -68,6 +70,8 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
6870
{
6971
setupUi( this );
7072

73+
connect( mOptionsSplitter, SIGNAL( splitterMoved( int, int ) ), this, SLOT( updateVerticalTabs() ) );
74+
7175
connect( cmbTheme, SIGNAL( activated( const QString& ) ), this, SLOT( themeChanged( const QString& ) ) );
7276
connect( cmbTheme, SIGNAL( highlighted( const QString& ) ), this, SLOT( themeChanged( const QString& ) ) );
7377
connect( cmbTheme, SIGNAL( textChanged( const QString& ) ), this, SLOT( themeChanged( const QString& ) ) );
@@ -110,6 +114,97 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
110114
spinBoxIdentifyValue->setMinimum( 0.01 );
111115
spinBoxIdentifyValue->setValue( identifyValue );
112116

117+
// custom environment variables
118+
bool useCustomVars = settings.value( "qgis/customEnvVarsUse", QVariant( false ) ).toBool();
119+
mCustomVariablesChkBx->setChecked( useCustomVars );
120+
if ( !useCustomVars )
121+
{
122+
mAddCustomVarBtn->setEnabled( false );
123+
mRemoveCustomVarBtn->setEnabled( false );
124+
mCustomVariablesTable->setEnabled( false );
125+
}
126+
QStringList customVarsList = settings.value( "qgis/customEnvVars", "" ).toStringList();
127+
foreach ( const QString &varStr, customVarsList )
128+
{
129+
int pos = varStr.indexOf( QLatin1Char( '|' ) );
130+
if ( pos == -1 )
131+
continue;
132+
QString varStrApply = varStr.left( pos );
133+
QString varStrNameValue = varStr.mid( pos + 1 );
134+
pos = varStrNameValue.indexOf( QLatin1Char( '=' ) );
135+
if ( pos == -1 )
136+
continue;
137+
QString varStrName = varStrNameValue.left( pos );
138+
QString varStrValue = varStrNameValue.mid( pos + 1 );
139+
140+
addCustomEnvVarRow( varStrName, varStrValue, varStrApply );
141+
}
142+
QFontMetrics fmCustomVar( mCustomVariablesTable->horizontalHeader()->font() );
143+
int fmCustomVarH = fmCustomVar.height() + 2;
144+
mCustomVariablesTable->horizontalHeader()->setFixedHeight( fmCustomVarH );
145+
146+
mCustomVariablesTable->setColumnWidth( 0, 120 );
147+
if ( mCustomVariablesTable->rowCount() > 0 )
148+
{
149+
mCustomVariablesTable->resizeColumnToContents( 1 );
150+
}
151+
else
152+
{
153+
mCustomVariablesTable->setColumnWidth( 1, 120 );
154+
}
155+
156+
// current environment variables
157+
mCurrentVariablesTable->horizontalHeader()->setFixedHeight( fmCustomVarH );
158+
QMap<QString, QString> sysVarsMap = QgsApplication::systemEnvVars();
159+
QStringList currentVarsList = QProcess::systemEnvironment();
160+
161+
foreach ( const QString &varStr, currentVarsList )
162+
{
163+
int pos = varStr.indexOf( QLatin1Char( '=' ) );
164+
if ( pos == -1 )
165+
continue;
166+
QStringList varStrItms;
167+
QString varStrName = varStr.left( pos );
168+
QString varStrValue = varStr.mid( pos + 1 );
169+
varStrItms << varStrName << varStrValue;
170+
171+
// check if different than system variable
172+
QString sysVarVal = QString( "" );
173+
bool sysVarMissing = !sysVarsMap.contains( varStrName );
174+
if ( sysVarMissing )
175+
sysVarVal = tr( "not present" );
176+
177+
if ( !sysVarMissing && sysVarsMap.value( varStrName ) != varStrValue )
178+
sysVarVal = sysVarsMap.value( varStrName );
179+
180+
if ( !sysVarVal.isEmpty() )
181+
sysVarVal = tr( "System value: %1" ).arg( sysVarVal );
182+
183+
int rowCnt = mCurrentVariablesTable->rowCount();
184+
mCurrentVariablesTable->insertRow( rowCnt );
185+
186+
QFont fItm;
187+
for ( int i = 0; i < varStrItms.size(); ++i )
188+
{
189+
QTableWidgetItem* varNameItm = new QTableWidgetItem( varStrItms.at( i ) );
190+
varNameItm->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable
191+
| Qt::ItemIsEditable | Qt::ItemIsDragEnabled );
192+
fItm = varNameItm->font();
193+
if ( !sysVarVal.isEmpty() )
194+
{
195+
fItm.setBold( true );
196+
varNameItm->setFont( fItm );
197+
varNameItm->setToolTip( sysVarVal );
198+
}
199+
mCurrentVariablesTable->setItem( rowCnt, i, varNameItm );
200+
}
201+
fItm.setBold( true );
202+
QFontMetrics fmRow( fItm );
203+
mCurrentVariablesTable->setRowHeight( rowCnt, fmRow.height() + 6 );
204+
}
205+
if ( mCurrentVariablesTable->rowCount() > 0 )
206+
mCurrentVariablesTable->resizeColumnToContents( 0 );
207+
113208
//local directories to search when loading c++ plugins
114209
QString myPaths = settings.value( "plugins/searchPathsForPlugins", "" ).toString();
115210
if ( !myPaths.isEmpty() )
@@ -611,23 +706,61 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
611706
mOverlayAlgorithmComboBox->setCurrentIndex( 0 );
612707
} //default is central point
613708

709+
// restore window and widget geometry/state
614710
restoreGeometry( settings.value( "/Windows/Options/geometry" ).toByteArray() );
711+
mOptionsSplitter->restoreState( settings.value( "/Windows/Options/splitState" ).toByteArray() );
712+
713+
int currentIndx = settings.value( "/Windows/Options/row" ).toInt();
714+
mOptionsListWidget->setCurrentRow( currentIndx );
715+
mOptionsStackedWidget->setCurrentIndex( currentIndx );
615716

616717
// load gdal driver list only when gdal tab is first opened
617718
mLoadedGdalDriverList = false;
618719

619-
// tabWidget->setCurrentIndex( settings.value( "/Windows/Options/row" ).toInt() );
620-
int currentTab = settings.value( "/Windows/Options/row" ).toInt();
621-
tabWidget->setCurrentIndex( currentTab );
622-
on_tabWidget_currentChanged( currentTab );
720+
// update option section frame state
721+
on_mOptionsListWidget_currentRowChanged( currentIndx );
623722
}
624723

625724
//! Destructor
626725
QgsOptions::~QgsOptions()
627726
{
628727
QSettings settings;
629728
settings.setValue( "/Windows/Options/geometry", saveGeometry() );
630-
settings.setValue( "/Windows/Options/row", tabWidget->currentIndex() );
729+
settings.setValue( "/Windows/Options/splitState", mOptionsSplitter->saveState() );
730+
settings.setValue( "/Windows/Options/row", mOptionsListWidget->currentRow() );
731+
}
732+
733+
void QgsOptions::showEvent( QShowEvent * e )
734+
{
735+
Q_UNUSED( e );
736+
updateVerticalTabs();
737+
}
738+
739+
void QgsOptions::resizeEvent( QResizeEvent * e )
740+
{
741+
Q_UNUSED( e );
742+
if ( mOptionsListWidget->isVisible() )
743+
updateVerticalTabs();
744+
}
745+
746+
void QgsOptions::updateVerticalTabs()
747+
{
748+
// auto-resize splitter for vert scrollbar without covering icons in icon-only mode
749+
// TODO: mOptionsListWidget has fixed 32px wide icons for now, allow user-defined
750+
int iconWidth = mOptionsListWidget->iconSize().width();
751+
int snapToIconWidth = iconWidth + 32;
752+
QList<int> splitSizes = mOptionsSplitter->sizes();
753+
bool iconOnly = splitSizes.at( 0 ) <= snapToIconWidth;
754+
755+
int newWidth = mOptionsListWidget->verticalScrollBar()->isVisible() ? iconWidth + 26 : iconWidth + 12;
756+
mOptionsListWidget->setMinimumWidth( newWidth );
757+
if ( iconOnly )
758+
{
759+
splitSizes[1] = splitSizes.at( 1 ) - ( splitSizes.at( 0 ) - newWidth );
760+
splitSizes[0] = newWidth;
761+
mOptionsSplitter->setSizes( splitSizes );
762+
}
763+
mOptionsListWidget->setWordWrap( !iconOnly );
631764
}
632765

633766
void QgsOptions::on_cbxProjectDefaultNew_toggled( bool checked )
@@ -781,6 +914,23 @@ void QgsOptions::saveOptions()
781914
{
782915
QSettings settings;
783916

917+
// custom environment variables
918+
settings.setValue( "qgis/customEnvVarsUse", QVariant( mCustomVariablesChkBx->isChecked() ) );
919+
QStringList customVars;
920+
for ( int i = 0; i < mCustomVariablesTable->rowCount(); ++i )
921+
{
922+
if ( mCustomVariablesTable->item( i, 1 )->text().isEmpty() )
923+
continue;
924+
QComboBox* varApplyCmbBx = qobject_cast<QComboBox*>( mCustomVariablesTable->cellWidget( i, 0 ) );
925+
QString customVar = varApplyCmbBx->itemData( varApplyCmbBx->currentIndex() ).toString();
926+
customVar += "|";
927+
customVar += mCustomVariablesTable->item( i, 1 )->text();
928+
customVar += "=";
929+
customVar += mCustomVariablesTable->item( i, 2 )->text();
930+
customVars << customVar;
931+
}
932+
settings.setValue( "qgis/customEnvVars", QVariant( customVars ) );
933+
784934
//search directories for user plugins
785935
QString myPaths;
786936
for ( int i = 0; i < mListPluginPaths->count(); ++i )
@@ -1211,6 +1361,74 @@ QStringList QgsOptions::i18nList()
12111361
return myList;
12121362
}
12131363

1364+
void QgsOptions::addCustomEnvVarRow( QString varName, QString varVal, QString varApply )
1365+
{
1366+
int rowCnt = mCustomVariablesTable->rowCount();
1367+
mCustomVariablesTable->insertRow( rowCnt );
1368+
1369+
QComboBox* varApplyCmbBx = new QComboBox( this );
1370+
varApplyCmbBx->addItem( tr( "Overwrite" ), QVariant( "overwrite" ) );
1371+
varApplyCmbBx->addItem( tr( "If Undefined" ), QVariant( "undefined" ) );
1372+
varApplyCmbBx->addItem( tr( "Unset" ), QVariant( "unset" ) );
1373+
varApplyCmbBx->addItem( tr( "Prepend" ), QVariant( "prepend" ) );
1374+
varApplyCmbBx->addItem( tr( "Append" ), QVariant( "append" ) );
1375+
varApplyCmbBx->setCurrentIndex( varApply.isEmpty() ? 0 : varApplyCmbBx->findData( QVariant( varApply ) ) );
1376+
1377+
QFont cbf = varApplyCmbBx->font();
1378+
QFontMetrics cbfm = QFontMetrics( cbf );
1379+
cbf.setPointSize( cbf.pointSize() - 2 );
1380+
varApplyCmbBx->setFont( cbf );
1381+
mCustomVariablesTable->setCellWidget( rowCnt, 0, varApplyCmbBx );
1382+
1383+
Qt::ItemFlags itmFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable
1384+
| Qt::ItemIsEditable | Qt::ItemIsDropEnabled;
1385+
1386+
QTableWidgetItem* varNameItm = new QTableWidgetItem( varName );
1387+
varNameItm->setFlags( itmFlags );
1388+
mCustomVariablesTable->setItem( rowCnt, 1, varNameItm );
1389+
1390+
QTableWidgetItem* varValueItm = new QTableWidgetItem( varVal );
1391+
varNameItm->setFlags( itmFlags );
1392+
mCustomVariablesTable->setItem( rowCnt, 2, varValueItm );
1393+
1394+
mCustomVariablesTable->setRowHeight( rowCnt, cbfm.height() + 8 );
1395+
}
1396+
1397+
void QgsOptions::on_mAddCustomVarBtn_clicked()
1398+
{
1399+
addCustomEnvVarRow( QString( "" ), QString( "" ) );
1400+
mCustomVariablesTable->setFocus();
1401+
mCustomVariablesTable->setCurrentCell( mCustomVariablesTable->rowCount() - 1, 1 );
1402+
mCustomVariablesTable->edit( mCustomVariablesTable->currentIndex() );
1403+
}
1404+
1405+
void QgsOptions::on_mRemoveCustomVarBtn_clicked()
1406+
{
1407+
mCustomVariablesTable->removeRow( mCustomVariablesTable->currentRow() );
1408+
}
1409+
1410+
void QgsOptions::on_mCurrentVariablesQGISChxBx_toggled( bool qgisSpecific )
1411+
{
1412+
for ( int i = mCurrentVariablesTable->rowCount() - 1; i >= 0; --i )
1413+
{
1414+
if ( qgisSpecific )
1415+
{
1416+
QString itmTxt = mCurrentVariablesTable->item( i, 0 )->text();
1417+
if ( !itmTxt.startsWith( "QGIS", Qt::CaseInsensitive ) )
1418+
mCurrentVariablesTable->hideRow( i );
1419+
}
1420+
else
1421+
{
1422+
mCurrentVariablesTable->showRow( i );
1423+
}
1424+
}
1425+
if ( mCurrentVariablesTable->rowCount() > 0 )
1426+
{
1427+
mCurrentVariablesTable->sortByColumn( 0, Qt::AscendingOrder );
1428+
mCurrentVariablesTable->resizeColumnToContents( 0 );
1429+
}
1430+
}
1431+
12141432
void QgsOptions::on_mBtnAddPluginPath_clicked()
12151433
{
12161434
QString myDir = QFileDialog::getExistingDirectory(
@@ -1302,10 +1520,10 @@ void QgsOptions::on_mClearCache_clicked()
13021520
#endif
13031521
}
13041522

1305-
void QgsOptions::on_tabWidget_currentChanged( int theTab )
1523+
void QgsOptions::on_mOptionsListWidget_currentRowChanged( int theIndx )
13061524
{
13071525
// load gdal driver list when gdal tab is first opened
1308-
if ( theTab == 1 && ! mLoadedGdalDriverList )
1526+
if ( theIndx == 2 && ! mLoadedGdalDriverList )
13091527
{
13101528
loadGdalDriverList();
13111529
}

‎src/app/qgsoptions.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,21 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase
117117
/**Remove an URL to exclude from Proxy*/
118118
void on_mRemoveUrlPushButton_clicked();
119119

120+
/** Slot to add a custom environment variable to the app
121+
* @note added in QGIS 1.9
122+
*/
123+
void on_mAddCustomVarBtn_clicked();
124+
125+
/** Slot to remove a custom environment variable from the app
126+
* @note added in QGIS 1.9
127+
*/
128+
void on_mRemoveCustomVarBtn_clicked();
129+
130+
/** Slot to filter out current environment variables not specific to QGIS
131+
* @note added in QGIS 1.9
132+
*/
133+
void on_mCurrentVariablesQGISChxBx_toggled( bool qgisSpecific );
134+
120135
/* Let the user add a path to the list of search paths
121136
* used for finding user Plugin libs.
122137
* @note added in QGIS 1.7
@@ -174,10 +189,15 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase
174189
*/
175190
void on_pbnExportScales_clicked();
176191

177-
/** Auto slot executed when the active page in the main widget stack is changed
178-
* @note added in 2.0
192+
/** Auto slot executed when the active item in the option section list widget is changed
193+
* @note added in 1.9
194+
*/
195+
void on_mOptionsListWidget_currentRowChanged( int theIndx );
196+
197+
/** Slot to update widget of vertical tabs
198+
* @note added in QGIS 1.9
179199
*/
180-
void on_tabWidget_currentChanged( int theTab );
200+
void updateVerticalTabs();
181201

182202
/* Load the list of drivers available in GDAL
183203
* @note added in 2.0
@@ -197,6 +217,14 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase
197217
QgsCoordinateReferenceSystem mLayerDefaultCrs;
198218
bool mLoadedGdalDriverList;
199219

220+
/** Generate table row for custom environment variables
221+
* @note added in QGIS 1.9
222+
*/
223+
void addCustomEnvVarRow( QString varName, QString varVal, QString varApply = QString() );
224+
225+
protected:
226+
void showEvent( QShowEvent * e );
227+
void resizeEvent( QResizeEvent * e );
200228
};
201229

202230
#endif // #ifndef QGSOPTIONS_H

‎src/core/gps/tok.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,10 @@ double nmea_atof( const char *str, int str_sz )
8585

8686
if ( str_sz < NMEA_CONVSTR_BUF )
8787
{
88+
const char *oldlocale = setlocale( LC_NUMERIC, NULL );
89+
8890
memcpy( &buff[0], str, str_sz );
8991
buff[str_sz] = '\0';
90-
const char *oldlocale = setlocale( LC_NUMERIC, NULL );
9192
setlocale( LC_NUMERIC, "C" );
9293
res = strtod( &buff[0], &tmp_ptr );
9394
setlocale( LC_NUMERIC, oldlocale );

‎src/core/qgsapplication.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <QFileOpenEvent>
2626
#include <QMessageBox>
2727
#include <QPalette>
28+
#include <QProcess>
2829
#include <QSettings>
2930
#include <QIcon>
3031
#include <QPixmap>
@@ -50,6 +51,7 @@ QString ABISYM( QgsApplication::mLibraryPath );
5051
QString ABISYM( QgsApplication::mLibexecPath );
5152
QString ABISYM( QgsApplication::mThemeName );
5253
QStringList ABISYM( QgsApplication::mDefaultSvgPaths );
54+
QMap<QString, QString> ABISYM( QgsApplication::mSystemEnvVars );
5355
QString ABISYM( QgsApplication::mConfigPath );
5456
bool ABISYM( QgsApplication::mRunningFromBuildDir ) = false;
5557
QString ABISYM( QgsApplication::mBuildSourcePath );
@@ -152,6 +154,19 @@ void QgsApplication::init( QString customConfigPath )
152154

153155
ABISYM( mDefaultSvgPaths ) << qgisSettingsDirPath() + QString( "svg/" );
154156

157+
// store system environment variables passed to application, before they are adjusted
158+
QMap<QString, QString> systemEnvVarMap;
159+
foreach ( const QString &varStr, QProcess::systemEnvironment() )
160+
{
161+
int pos = varStr.indexOf( QLatin1Char( '=' ) );
162+
if ( pos == -1 )
163+
continue;
164+
QString varStrName = varStr.left( pos );
165+
QString varStrValue = varStr.mid( pos + 1 );
166+
systemEnvVarMap.insert( varStrName, varStrValue );
167+
}
168+
ABISYM( mSystemEnvVars ) = systemEnvVarMap;
169+
155170
// set a working directory up for gdal to write .aux.xml files into
156171
// for cases where the raster dir is read only to the user
157172
// if the env var is already set it will be used preferentially

‎src/core/qgsapplication.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ class CORE_EXPORT QgsApplication: public QApplication
120120
//! @note added in 1.4
121121
static const QStringList svgPaths();
122122

123+
//! Returns the system environment variables passed to application.
124+
//! @note added in 1.9
125+
static const QMap<QString, QString> systemEnvVars() { return ABISYM( mSystemEnvVars ); }
126+
123127
//! Returns the path to the application prefix directory.
124128
static const QString prefixPath();
125129

@@ -253,7 +257,7 @@ class CORE_EXPORT QgsApplication: public QApplication
253257
* GDAL_SKIP environment variable)
254258
* @note added in 2.0
255259
*/
256-
static QStringList skippedGdalDrivers( ) { return ABISYM( mGdalSkipList ); };
260+
static QStringList skippedGdalDrivers( ) { return ABISYM( mGdalSkipList ); }
257261

258262
/** Apply the skipped drivers list to gdal
259263
* @see skipGdalDriver
@@ -277,6 +281,7 @@ class CORE_EXPORT QgsApplication: public QApplication
277281
static QString ABISYM( mLibexecPath );
278282
static QString ABISYM( mThemeName );
279283
static QStringList ABISYM( mDefaultSvgPaths );
284+
static QMap<QString, QString> ABISYM( mSystemEnvVars );
280285

281286
static QString ABISYM( mConfigPath );
282287

‎src/core/qgsbrowsermodel.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "qgsproviderregistry.h"
2525

2626
#include "qgsbrowsermodel.h"
27+
#include "qgsproject.h"
2728

2829
#include <QSettings>
2930

@@ -40,8 +41,18 @@ QgsBrowserModel::~QgsBrowserModel()
4041

4142
void QgsBrowserModel::addRootItems()
4243
{
43-
// give the home directory a prominent first place
44-
QgsDirectoryItem *item = new QgsDirectoryItem( NULL, tr( "Home" ), QDir::homePath() );
44+
QgsDirectoryItem *item;
45+
46+
QString home = QgsProject::instance()->homePath();
47+
48+
if( !home.isNull() )
49+
{
50+
item = new QgsDirectoryItem( NULL, tr( "Project home" ), home );
51+
mRootItems << item;
52+
}
53+
54+
// give the home directory a prominent second place
55+
item = new QgsDirectoryItem( NULL, tr( "Home" ), QDir::homePath() );
4556
QStyle *style = QApplication::style();
4657
QIcon homeIcon( style->standardPixmap( QStyle::SP_DirHomeIcon ) );
4758
item->setIcon( homeIcon );

‎src/core/qgsbrowsermodel.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,6 @@ class CORE_EXPORT QgsBrowserModel : public QAbstractItemModel
7575

7676
bool hasChildren( const QModelIndex &parent = QModelIndex() ) const;
7777

78-
// Reload the whole model
79-
void reload();
80-
8178
// Refresh item specified by path
8279
void refresh( QString path );
8380

@@ -93,6 +90,8 @@ class CORE_EXPORT QgsBrowserModel : public QAbstractItemModel
9390
void fetchMore( const QModelIndex & parent );
9491

9592
public slots:
93+
// Reload the whole model
94+
void reload();
9695

9796
void beginInsertItems( QgsDataItem *parent, int first, int last );
9897
void endInsertItems();

‎src/core/qgsmaplayerregistry.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,19 @@ QgsMapLayer * QgsMapLayerRegistry::mapLayer( QString theLayerId )
5757
return mMapLayers.value( theLayerId );
5858
}
5959

60+
QList<QgsMapLayer *> QgsMapLayerRegistry::mapLayersByName( QString layerName )
61+
{
62+
QList<QgsMapLayer *> myResultList;
63+
foreach ( QgsMapLayer* layer, mMapLayers )
64+
{
65+
if ( layer->name() == layerName )
66+
{
67+
myResultList << layer;
68+
}
69+
}
70+
return myResultList;
71+
}
72+
6073
//introduced in 1.8
6174
QList<QgsMapLayer *> QgsMapLayerRegistry::addMapLayers(
6275
QList<QgsMapLayer *> theMapLayers,

‎src/core/qgsmaplayerregistry.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class CORE_EXPORT QgsMapLayerRegistry : public QObject
4545
//! Retrieve a pointer to a loaded layer by id
4646
QgsMapLayer *mapLayer( QString theLayerId );
4747

48+
//! Retrieve a pointer to a loaded layer by name
49+
QList<QgsMapLayer *> mapLayersByName( QString layerName );
50+
4851
//! Retrieve the mapLayers collection (mainly intended for use by projection)
4952
QMap<QString, QgsMapLayer*> & mapLayers();
5053

‎src/core/qgsnetworkreplyparser.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@
3232

3333
class CORE_EXPORT QgsNetworkReplyParser : public QObject
3434
{
35-
Q_OBJECT
35+
Q_OBJECT
3636

3737
public:
3838
/** Constructor
3939
* @param reply */
4040
QgsNetworkReplyParser( QNetworkReply *reply );
4141

42-
/** Indicates if successfully parsed
42+
/** Indicates if successfully parsed
4343
* @return true if successfully parsed */
4444
bool isValid() const { return mValid; }
4545

@@ -49,20 +49,21 @@ class CORE_EXPORT QgsNetworkReplyParser : public QObject
4949

5050
/** Get part header
5151
* @param part part index
52+
* @param headerName header name
5253
* @return raw header */
53-
QByteArray rawHeader ( int part, const QByteArray & headerName ) const { return mHeaders.value(part).value(headerName); }
54-
54+
QByteArray rawHeader( int part, const QByteArray & headerName ) const { return mHeaders.value( part ).value( headerName ); }
55+
5556
/** Get part part body
5657
* @param part part index
5758
* @return part body */
58-
QByteArray body ( int part ) const { return mBodies.value(part); }
59+
QByteArray body( int part ) const { return mBodies.value( part ); }
5960

6061
/** Parsing error */
6162
QString error() const { return mError; }
6263

6364
/** Test if reply is multipart.
6465
* @return true if reply is multipart */
65-
static bool isMultipart ( QNetworkReply *reply );
66+
static bool isMultipart( QNetworkReply *reply );
6667

6768
private:
6869
QNetworkReply *mReply;
@@ -72,10 +73,10 @@ class CORE_EXPORT QgsNetworkReplyParser : public QObject
7273
QString mError;
7374

7475
/* List of header maps */
75-
QList< QMap<QByteArray,QByteArray> > mHeaders;
76+
QList< QMap<QByteArray, QByteArray> > mHeaders;
7677

7778
/* List of part bodies */
7879
QList<QByteArray> mBodies;
7980
};
8081

81-
#endif
82+
#endif

‎src/core/qgsproject.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,11 +1368,11 @@ QString QgsProject::readPath( QString src ) const
13681368
// That means that it was saved with an earlier version of "relative path support",
13691369
// where the source file had to exist and only the project directory was stripped
13701370
// from the filename.
1371-
QFileInfo pfi( fileName() );
1372-
if ( !pfi.exists() )
1371+
QString home = homePath();
1372+
if( home.isNull() )
13731373
return src;
13741374

1375-
QFileInfo fi( pfi.canonicalPath() + "/" + src );
1375+
QFileInfo fi( home + "/" + src );
13761376

13771377
if ( !fi.exists() )
13781378
{
@@ -1763,4 +1763,11 @@ void QgsProjectBadLayerDefaultHandler::handleBadLayers( QList<QDomNode> /*layers
17631763
// just ignore any bad layers
17641764
}
17651765

1766+
QString QgsProject::homePath() const
1767+
{
1768+
QFileInfo pfi( fileName() );
1769+
if ( !pfi.exists() )
1770+
return QString::null;
17661771

1772+
return pfi.canonicalPath();
1773+
}

‎src/core/qgsproject.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,11 @@ class CORE_EXPORT QgsProject : public QObject
310310
@note added in version 1.9*/
311311
bool topologicalEditing() const;
312312

313+
/** Return project's home path
314+
@return home path of project (or QString::null if not set)
315+
@note added in version 2.0 */
316+
QString homePath() const;
317+
313318
protected:
314319

315320
/** Set error message from read/write operation

‎src/core/qgsvectordataprovider.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,12 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
300300
*/
301301
virtual QgsAttributeList attributeIndexes();
302302

303+
/**
304+
* Return list of indexes of fields that make up the primary key
305+
* @note added in 2.0
306+
*/
307+
virtual QgsAttributeList pkAttributeIndexes() { return QgsAttributeList(); }
308+
303309
/**
304310
* Set whether provider should also return features that don't have
305311
* associated geometry. false by default

‎src/core/qgsvectorlayer.cpp

Lines changed: 126 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
102102
, mLabel( 0 )
103103
, mLabelOn( false )
104104
, mVertexMarkerOnlyForSelection( false )
105+
, mEditorLayout( GeneratedLayout )
105106
, mFetching( false )
106107
, mJoinBuffer( 0 )
107108
, mDiagramRenderer( 0 )
@@ -2512,16 +2513,13 @@ int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topolo
25122513

25132514
if ( mDataProvider )
25142515
{
2515-
//use default value where possible (primary key issue), otherwise the value from the original (split) feature
25162516
QgsAttributeMap newAttributes = select_it->attributeMap();
2517-
QVariant defaultValue;
2518-
foreach ( int j, newAttributes.keys() )
2517+
2518+
// overwrite primary key field with default values
2519+
foreach ( int idx, pendingPkAttributesList() )
25192520
{
2520-
defaultValue = mDataProvider->defaultValue( j );
2521-
if ( !defaultValue.isNull() )
2522-
{
2523-
newAttributes.insert( j, defaultValue );
2524-
}
2521+
if( newAttributes.contains( idx ) )
2522+
newAttributes.insert( idx, mDataProvider->defaultValue( idx ) );
25252523
}
25262524

25272525
newFeature.setAttributeMap( newAttributes );
@@ -3129,28 +3127,6 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
31293127
//also restore custom properties (for labeling-ng)
31303128
readCustomProperties( node, "labeling" );
31313129

3132-
// tab display
3133-
QDomNode editorLayoutNode = node.namedItem( "editorlayout" );
3134-
if ( editorLayoutNode.isNull() )
3135-
{
3136-
mEditorLayout = GeneratedLayout;
3137-
}
3138-
else
3139-
{
3140-
if ( editorLayoutNode.toElement().text() == "uifilelayout" )
3141-
{
3142-
mEditorLayout = UiFileLayout;
3143-
}
3144-
else if ( editorLayoutNode.toElement().text() == "tablayout" )
3145-
{
3146-
mEditorLayout = TabLayout;
3147-
}
3148-
else
3149-
{
3150-
mEditorLayout = GeneratedLayout;
3151-
}
3152-
}
3153-
31543130
// Test if labeling is on or off
31553131
QDomNode labelnode = node.namedItem( "label" );
31563132
QDomElement element = labelnode.toElement();
@@ -3330,6 +3306,27 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
33303306
}
33313307
}
33323308

3309+
// tab display
3310+
QDomNode editorLayoutNode = node.namedItem( "editorlayout" );
3311+
if ( editorLayoutNode.isNull() )
3312+
{
3313+
mEditorLayout = GeneratedLayout;
3314+
}
3315+
else
3316+
{
3317+
if ( editorLayoutNode.toElement().text() == "uifilelayout" )
3318+
{
3319+
mEditorLayout = UiFileLayout;
3320+
}
3321+
else if ( editorLayoutNode.toElement().text() == "tablayout" )
3322+
{
3323+
mEditorLayout = TabLayout;
3324+
}
3325+
else
3326+
{
3327+
mEditorLayout = GeneratedLayout;
3328+
}
3329+
}
33333330

33343331
//Attributes excluded from WMS and WFS
33353332
mExcludeAttributesWMS.clear();
@@ -3390,7 +3387,9 @@ QgsAttributeEditorElement* QgsVectorLayer::attributeEditorElementFromDomElement(
33903387
}
33913388
else if ( elem.tagName() == "attributeEditorField" )
33923389
{
3393-
newElement = new QgsAttributeEditorField( elem.attribute( "name" ), elem.attribute( "idx" ).toInt(), parent );
3390+
QString name = elem.attribute( "name" );
3391+
int idx = *( dataProvider()->fieldNameMap() ).find( name );
3392+
newElement = new QgsAttributeEditorField( name, idx, parent );
33943393
}
33953394

33963395
return newElement;
@@ -3446,26 +3445,6 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
34463445
//save customproperties (for labeling ng)
34473446
writeCustomProperties( node, doc );
34483447

3449-
// tab display
3450-
QDomElement editorLayoutElem = doc.createElement( "editorlayout" );
3451-
switch ( mEditorLayout )
3452-
{
3453-
case UiFileLayout:
3454-
editorLayoutElem.appendChild( doc.createTextNode( "uifilelayout" ) );
3455-
break;
3456-
3457-
case TabLayout:
3458-
editorLayoutElem.appendChild( doc.createTextNode( "tablayout" ) );
3459-
break;
3460-
3461-
case GeneratedLayout:
3462-
default:
3463-
editorLayoutElem.appendChild( doc.createTextNode( "generatedlayout" ) );
3464-
break;
3465-
}
3466-
3467-
node.appendChild( editorLayoutElem );
3468-
34693448
// add the display field
34703449
QDomElement dField = doc.createElement( "displayfield" );
34713450
QDomText dFieldText = doc.createTextNode( displayField() );
@@ -3608,6 +3587,26 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
36083587
afField.appendChild( afText );
36093588
node.appendChild( afField );
36103589

3590+
// tab display
3591+
QDomElement editorLayoutElem = doc.createElement( "editorlayout" );
3592+
switch ( mEditorLayout )
3593+
{
3594+
case UiFileLayout:
3595+
editorLayoutElem.appendChild( doc.createTextNode( "uifilelayout" ) );
3596+
break;
3597+
3598+
case TabLayout:
3599+
editorLayoutElem.appendChild( doc.createTextNode( "tablayout" ) );
3600+
break;
3601+
3602+
case GeneratedLayout:
3603+
default:
3604+
editorLayoutElem.appendChild( doc.createTextNode( "generatedlayout" ) );
3605+
break;
3606+
}
3607+
3608+
node.appendChild( editorLayoutElem );
3609+
36113610
//attribute aliases
36123611
if ( mAttributeAliasMap.size() > 0 )
36133612
{
@@ -3890,6 +3889,21 @@ QgsAttributeList QgsVectorLayer::pendingAllAttributesList()
38903889
return mUpdatedFields.keys();
38913890
}
38923891

3892+
QgsAttributeList QgsVectorLayer::pendingPkAttributesList()
3893+
{
3894+
QgsAttributeList pkAttributesList;
3895+
3896+
foreach ( int idx, mDataProvider->pkAttributeIndexes() )
3897+
{
3898+
if ( !mUpdatedFields.contains( idx ) )
3899+
continue;
3900+
3901+
pkAttributesList << idx;
3902+
}
3903+
3904+
return pkAttributesList;
3905+
}
3906+
38933907
int QgsVectorLayer::pendingFeatureCount()
38943908
{
38953909
return mDataProvider->featureCount()
@@ -3970,14 +3984,31 @@ bool QgsVectorLayer::commitChanges()
39703984
}
39713985
}
39723986

3987+
// collect new feature ids that weren't deleted again and forget still
3988+
// pending updates for deleted features
3989+
QHash<QgsFeatureId, int> addedFeaturesIdx;
3990+
for ( int i = 0; i < mAddedFeatures.size(); i++ )
3991+
{
3992+
const QgsFeature &f = mAddedFeatures.at( i );
3993+
if ( !mDeletedFeatureIds.remove( f.id() ) )
3994+
{
3995+
addedFeaturesIdx.insert( f.id(), i );
3996+
}
3997+
else
3998+
{
3999+
mChangedAttributeValues.remove( f.id() );
4000+
mChangedGeometries.remove( f.id() );
4001+
}
4002+
}
4003+
39734004
//
39744005
// remap changed and attributes of added features
39754006
//
39764007
bool attributeChangesOk = true;
39774008
if ( attributesChanged )
39784009
{
39794010
// map updates field indexes to names
3980-
QMap<int, QString> src;
4011+
QHash<int, QString> src;
39814012
for ( QgsFieldMap::const_iterator it = mUpdatedFields.begin(); it != mUpdatedFields.end(); it++ )
39824013
{
39834014
src[ it.key()] = it.value().name();
@@ -3987,7 +4018,7 @@ bool QgsVectorLayer::commitChanges()
39874018
const QgsFieldMap &pFields = mDataProvider->fields();
39884019

39894020
// map provider table names to field indexes
3990-
QMap<QString, int> dst;
4021+
QHash<QString, int> dst;
39914022
for ( QgsFieldMap::const_iterator it = pFields.begin(); it != pFields.end(); it++ )
39924023
{
39934024
dst[ it.value().name()] = it.key();
@@ -4019,8 +4050,8 @@ bool QgsVectorLayer::commitChanges()
40194050
}
40204051

40214052
// map updated fields to provider fields
4022-
QMap<int, int> remap;
4023-
for ( QMap<int, QString>::const_iterator it = src.begin(); it != src.end(); it++ )
4053+
QHash<int, int> remap;
4054+
for ( QHash<int, QString>::const_iterator it = src.begin(); it != src.end(); it++ )
40244055
{
40254056
if ( dst.contains( it.value() ) )
40264057
{
@@ -4060,7 +4091,7 @@ bool QgsVectorLayer::commitChanges()
40604091
QgsFieldMap attributes;
40614092

40624093
// update private field map
4063-
for ( QMap<int, int>::iterator it = remap.begin(); it != remap.end(); it++ )
4094+
for ( QHash<int, int>::iterator it = remap.begin(); it != remap.end(); it++ )
40644095
attributes[ it.value()] = mUpdatedFields[ it.key()];
40654096

40664097
mUpdatedFields = attributes;
@@ -4088,21 +4119,42 @@ bool QgsVectorLayer::commitChanges()
40884119
}
40894120
}
40904121

4122+
//
4123+
// delete features
4124+
//
4125+
if ( mDeletedFeatureIds.size() > 0 )
4126+
{
4127+
if (( cap & QgsVectorDataProvider::DeleteFeatures ) && mDataProvider->deleteFeatures( mDeletedFeatureIds ) )
4128+
{
4129+
mCommitErrors << tr( "SUCCESS: %n feature(s) deleted.", "deleted features count", mDeletedFeatureIds.size() );
4130+
foreach ( const QgsFeatureId &id, mDeletedFeatureIds )
4131+
{
4132+
mChangedAttributeValues.remove( id );
4133+
mChangedGeometries.remove( id );
4134+
}
4135+
4136+
emit committedFeaturesRemoved( id(), mDeletedFeatureIds );
4137+
4138+
mDeletedFeatureIds.clear();
4139+
}
4140+
else
4141+
{
4142+
mCommitErrors << tr( "ERROR: %n feature(s) not deleted.", "not deleted features count", mDeletedFeatureIds.size() );
4143+
success = false;
4144+
}
4145+
}
4146+
40914147
//
40924148
// add features
40934149
//
40944150
if ( mAddedFeatures.size() > 0 )
40954151
{
4096-
for ( int i = 0; i < mAddedFeatures.size(); i++ )
4152+
foreach ( int i, addedFeaturesIdx.values() )
40974153
{
40984154
QgsFeature &f = mAddedFeatures[i];
40994155

4100-
if ( mDeletedFeatureIds.contains( f.id() ) )
4156+
if ( mDeletedFeatureIds.remove( f.id() ) )
41014157
{
4102-
mDeletedFeatureIds.remove( f.id() );
4103-
4104-
if ( mChangedGeometries.contains( f.id() ) )
4105-
mChangedGeometries.remove( f.id() );
41064158

41074159
mAddedFeatures.removeAt( i-- );
41084160
continue;
@@ -4174,31 +4226,6 @@ bool QgsVectorLayer::commitChanges()
41744226
}
41754227
}
41764228

4177-
//
4178-
// delete features
4179-
//
4180-
if ( mDeletedFeatureIds.size() > 0 )
4181-
{
4182-
if (( cap & QgsVectorDataProvider::DeleteFeatures ) && mDataProvider->deleteFeatures( mDeletedFeatureIds ) )
4183-
{
4184-
mCommitErrors << tr( "SUCCESS: %n feature(s) deleted.", "deleted features count", mDeletedFeatureIds.size() );
4185-
for ( QgsFeatureIds::const_iterator it = mDeletedFeatureIds.begin(); it != mDeletedFeatureIds.end(); it++ )
4186-
{
4187-
mChangedAttributeValues.remove( *it );
4188-
mChangedGeometries.remove( *it );
4189-
}
4190-
4191-
emit committedFeaturesRemoved( id(), mDeletedFeatureIds );
4192-
4193-
mDeletedFeatureIds.clear();
4194-
}
4195-
else
4196-
{
4197-
mCommitErrors << tr( "ERROR: %n feature(s) not deleted.", "not deleted features count", mDeletedFeatureIds.size() );
4198-
success = false;
4199-
}
4200-
}
4201-
42024229
if ( !success )
42034230
{
42044231
if ( mDataProvider->hasErrors() )
@@ -5779,6 +5806,18 @@ QString QgsVectorLayer::metadata()
57795806
myMetadata += "</td></tr>";
57805807
}
57815808

5809+
QgsAttributeList pkAttrList = pendingPkAttributesList();
5810+
if ( !pkAttrList.isEmpty() )
5811+
{
5812+
myMetadata += "<tr><td>";
5813+
myMetadata += tr( "Primary key attributes: " );
5814+
foreach( int idx, pkAttrList )
5815+
{
5816+
myMetadata += pendingFields()[ idx ].name() + " ";
5817+
}
5818+
myMetadata += "</td></tr>";
5819+
}
5820+
57825821

57835822
//feature count
57845823
myMetadata += "<tr><td>";

‎src/core/qgsvectorlayer.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
389389
* @param elem the DOM element
390390
* @param parent the QObject which will own this object
391391
*/
392-
static QgsAttributeEditorElement* attributeEditorElementFromDomElement( QDomElement &elem, QObject* parent );
392+
QgsAttributeEditorElement* attributeEditorElementFromDomElement( QDomElement &elem, QObject* parent );
393393

394394
/** Read the symbology for the current layer from the Dom node supplied.
395395
* @param node node that will contain the symbology definition for this layer.
@@ -632,6 +632,11 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
632632
/** returns list of attributes */
633633
QgsAttributeList pendingAllAttributesList();
634634

635+
/** returns list of attribute making up the primary key
636+
* @note added in 2.0
637+
*/
638+
QgsAttributeList pendingPkAttributesList();
639+
635640
/** returns feature count after commit */
636641
int pendingFeatureCount();
637642

‎src/core/qgsvectorlayerimport.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include "qgsvectorlayerimport.h"
2626
#include "qgsproviderregistry.h"
2727

28+
#include <QProgressDialog>
29+
2830
#define FEATURE_BUFFER_SIZE 200
2931

3032
typedef QgsVectorLayerImport::ImportError createEmptyLayer_t(
@@ -45,8 +47,10 @@ QgsVectorLayerImport::QgsVectorLayerImport( const QString &uri,
4547
QGis::WkbType geometryType,
4648
const QgsCoordinateReferenceSystem* crs,
4749
bool overwrite,
48-
const QMap<QString, QVariant> *options )
50+
const QMap<QString, QVariant> *options,
51+
QProgressDialog *progress )
4952
: mErrorCount( 0 )
53+
, mProgress( progress )
5054
{
5155
mProvider = NULL;
5256

@@ -83,7 +87,7 @@ QgsVectorLayerImport::QgsVectorLayerImport( const QString &uri,
8387
QgsDebugMsg( "Created empty layer" );
8488

8589
QgsVectorDataProvider *vectorProvider = ( QgsVectorDataProvider* ) pReg->provider( providerKey, uri );
86-
if ( !vectorProvider || !vectorProvider->isValid() )
90+
if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & QgsVectorDataProvider::AddFeatures ) == 0 )
8791
{
8892
mError = ErrInvalidLayer;
8993
mErrorMessage = QObject::tr( "Loading of layer failed" );
@@ -181,7 +185,8 @@ QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
181185
bool onlySelected,
182186
QString *errorMessage,
183187
bool skipAttributeCreation,
184-
QMap<QString, QVariant> *options )
188+
QMap<QString, QVariant> *options,
189+
QProgressDialog *progress )
185190
{
186191
const QgsCoordinateReferenceSystem* outputCRS;
187192
QgsCoordinateTransform* ct = 0;
@@ -255,7 +260,7 @@ QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
255260
}
256261

257262
QgsVectorLayerImport * writer =
258-
new QgsVectorLayerImport( uri, providerKey, fields, wkbType, outputCRS, overwrite, options );
263+
new QgsVectorLayerImport( uri, providerKey, fields, wkbType, outputCRS, overwrite, options, progress );
259264

260265
// check whether file creation was successful
261266
ImportError err = writer->hasError();
@@ -298,9 +303,23 @@ QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
298303
*errorMessage = QObject::tr( "Feature write errors:" );
299304
}
300305

306+
if ( progress )
307+
{
308+
progress->setRange( 0, layer->featureCount() );
309+
}
310+
301311
// write all features
302312
while ( layer->nextFeature( fet ) )
303313
{
314+
if ( progress && progress->wasCanceled() )
315+
{
316+
if ( errorMessage )
317+
{
318+
*errorMessage += "\n" + QObject::tr( "Import was canceled at %1 of %2" ).arg( progress->value() ).arg( progress->maximum() );
319+
}
320+
break;
321+
}
322+
304323
if ( writer->errorCount() > 1000 )
305324
{
306325
if ( errorMessage )
@@ -348,6 +367,11 @@ QgsVectorLayerImport::importLayer( QgsVectorLayer* layer,
348367
}
349368
}
350369
n++;
370+
371+
if ( progress )
372+
{
373+
progress->setValue( n );
374+
}
351375
}
352376

353377
// flush the buffer to be sure that all features are written

‎src/core/qgsvectorlayerimport.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "qgsvectordataprovider.h"
2323
#include "qgsvectorlayer.h"
2424

25+
class QProgressDialog;
26+
2527
/** \ingroup core
2628
* A convenience class for writing vector files to disk.
2729
There are two possibilities how to use this class:
@@ -59,7 +61,8 @@ class CORE_EXPORT QgsVectorLayerImport
5961
bool onlySelected = false,
6062
QString *errorMessage = 0,
6163
bool skipAttributeCreation = false,
62-
QMap<QString, QVariant> *options = 0
64+
QMap<QString, QVariant> *options = 0,
65+
QProgressDialog *progress = 0
6366
);
6467

6568
/** create a empty layer and add fields to it */
@@ -69,7 +72,8 @@ class CORE_EXPORT QgsVectorLayerImport
6972
QGis::WkbType geometryType,
7073
const QgsCoordinateReferenceSystem* crs,
7174
bool overwrite = false,
72-
const QMap<QString, QVariant> *options = 0
75+
const QMap<QString, QVariant> *options = 0,
76+
QProgressDialog *progress = 0
7377
);
7478

7579
/** checks whether there were any errors */
@@ -102,6 +106,7 @@ class CORE_EXPORT QgsVectorLayerImport
102106
QMap<int, int> mOldToNewAttrIdx;
103107

104108
QgsFeatureList mFeatureBuffer;
109+
QProgressDialog *mProgress;
105110
};
106111

107112
#endif

‎src/core/qgswfsdata.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ class CORE_EXPORT QgsWFSData: public QObject
3535
{
3636
Q_OBJECT
3737
public:
38+
/** Constructor.
39+
@param uri request uri
40+
@param extent the extent of the WFS layer
41+
@param features the features of the layer
42+
@param idMap
43+
@param geometryAttribute
44+
@param thematicAttributes
45+
@param wkbType */
3846
QgsWFSData(
3947
const QString& uri,
4048
QgsRectangle* extent,
@@ -46,11 +54,7 @@ class CORE_EXPORT QgsWFSData: public QObject
4654
~QgsWFSData();
4755

4856
/**Does the Http GET request to the wfs server
49-
@param query string (to define the requested typename)
50-
@param extent the extent of the WFS layer
51-
@param srs the reference system of the layer
52-
@param features the features of the layer
53-
@return 0 in case of success*/
57+
@return 0 in case of success */
5458
int getWFSData();
5559

5660
private slots:
@@ -108,7 +112,9 @@ class CORE_EXPORT QgsWFSData: public QObject
108112
@return 0 in case of success*/
109113
int readEpsgFromAttribute( int& epsgNr, const XML_Char** attr ) const;
110114
/**Reads attribute as string
111-
@return attribute value or an empty string if no such attribute*/
115+
@param attributeName
116+
@param attr
117+
@return attribute value or an empty string if no such attribute*/
112118
QString readAttribute( const QString& attributeName, const XML_Char** attr ) const;
113119
/**Creates a rectangle from a coordinate string.
114120
@return 0 in case of success*/

‎src/gui/attributetable/qgsattributetableidcolumnpair.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ bool QgsAttributeTableIdColumnPair::operator<( const QgsAttributeTableIdColumnPa
2424
//QVariant thinks gid is a string!
2525
QVariant::Type columnType = mItem.type();
2626

27+
if ( mItem.isNull() )
28+
return 1;
29+
30+
if ( b.mItem.isNull() )
31+
return 0;
32+
2733
switch ( columnType )
2834
{
2935
case QVariant::Int:

‎src/gui/qgsattributeeditor.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <qgsmaplayerregistry.h>
2727
#include <qgslogger.h>
2828

29+
#include <QScrollArea>
2930
#include <QPushButton>
3031
#include <QLineEdit>
3132
#include <QTextEdit>
@@ -987,13 +988,23 @@ QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElemen
987988
QGroupBox* groupBox = new QGroupBox( parent );
988989
groupBox->setTitle( container->name() );
989990
myContainer = groupBox;
991+
newWidget = myContainer;
990992
}
991993
else
992994
{
993-
myContainer = new QWidget( parent );
995+
QScrollArea *scrollArea = new QScrollArea( parent );
996+
997+
myContainer = new QWidget( scrollArea );
998+
999+
scrollArea->setWidget( myContainer );
1000+
scrollArea->setWidgetResizable( true );
1001+
scrollArea->setFrameShape( QFrame::NoFrame );
1002+
1003+
newWidget = scrollArea;
9941004
}
9951005

9961006
QGridLayout* gbLayout = new QGridLayout( myContainer );
1007+
myContainer->setLayout( gbLayout );
9971008

9981009
int index = 0;
9991010

@@ -1010,17 +1021,22 @@ QWidget* QgsAttributeEditor::createWidgetFromDef( const QgsAttributeEditorElemen
10101021
}
10111022
else
10121023
{
1024+
const QgsAttributeEditorField* fieldDef = dynamic_cast<const QgsAttributeEditorField*>( childDef );
1025+
1026+
//show attribute alias if available
1027+
QString myFieldName = vl->attributeDisplayName( fieldDef->idx() );
10131028
QLabel * mypLabel = new QLabel( myContainer );
10141029
gbLayout->addWidget( mypLabel, index, 0 );
1015-
mypLabel->setText( childDef->name() );
1030+
mypLabel->setText( myFieldName );
1031+
1032+
// add editor widget
10161033
gbLayout->addWidget( editor, index, 1 );
10171034
}
10181035

10191036
++index;
10201037
}
10211038
gbLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ), index , 0 );
10221039

1023-
newWidget = myContainer;
10241040
break;
10251041
}
10261042

‎src/gui/qgssearchquerybuilder.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,11 @@ void QgsSearchQueryBuilder::populateFields()
7373
return;
7474

7575
QgsDebugMsg( "entering." );
76-
QRegExp reQuote( "[A-Za-z_][A-Za-z0-9_]*" );
7776
const QgsFieldMap& fields = mLayer->pendingFields();
7877
for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it )
7978
{
8079
QString fieldName = it->name();
8180
mFieldMap[fieldName] = it.key();
82-
if ( !reQuote.exactMatch( fieldName ) ) // quote if necessary
83-
fieldName = QgsExpression::quotedColumnRef( fieldName );
8481
QStandardItem *myItem = new QStandardItem( fieldName );
8582
myItem->setEditable( false );
8683
mModelFields->insertRow( mModelFields->rowCount(), myItem );
@@ -314,7 +311,7 @@ void QgsSearchQueryBuilder::setSearchString( QString searchString )
314311

315312
void QgsSearchQueryBuilder::on_lstFields_doubleClicked( const QModelIndex &index )
316313
{
317-
txtSQL->insertPlainText( "\"" + mModelFields->data( index ).toString() + "\"" );
314+
txtSQL->insertPlainText( QgsExpression::quotedColumnRef( mModelFields->data( index ).toString() ) );
318315
}
319316

320317
void QgsSearchQueryBuilder::on_lstValues_doubleClicked( const QModelIndex &index )

‎src/providers/mssql/qgsmssqlprovider.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1686,7 +1686,7 @@ QgsVectorLayerImport::ImportError QgsMssqlProvider::createEmptyLayer(
16861686
QString pk = primaryKey = "qgs_fid";
16871687
for ( QgsFieldMap::const_iterator fldIt = fields.begin(); fldIt != fields.end(); ++fldIt )
16881688
{
1689-
if ( fldIt.value().name() == pk )
1689+
if ( fldIt.value().name() == primaryKey )
16901690
{
16911691
// it already exists, try again with a new name
16921692
primaryKey = QString( "%1_%2" ).arg( pk ).arg( index++ );

‎src/providers/postgres/qgspostgresdataitems.cpp

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,51 @@
2222
#include "qgsapplication.h"
2323

2424
#include <QMessageBox>
25+
#include <QProgressDialog>
2526

2627
QGISEXTERN bool deleteLayer( const QString& uri, QString& errCause );
2728

2829
// ---------------------------------------------------------------------------
2930
QgsPGConnectionItem::QgsPGConnectionItem( QgsDataItem* parent, QString name, QString path )
3031
: QgsDataCollectionItem( parent, name, path )
32+
, mColumnTypeThread( 0 )
3133
{
3234
mIcon = QgsApplication::getThemeIcon( "mIconConnect.png" );
3335
}
3436

3537
QgsPGConnectionItem::~QgsPGConnectionItem()
3638
{
39+
stop();
40+
}
41+
42+
void QgsPGConnectionItem::stop()
43+
{
44+
if ( mColumnTypeThread )
45+
{
46+
mColumnTypeThread->stop();
47+
mColumnTypeThread->wait();
48+
delete mColumnTypeThread;
49+
mColumnTypeThread = 0;
50+
}
51+
}
52+
53+
void QgsPGConnectionItem::refresh()
54+
{
55+
QApplication::setOverrideCursor( Qt::WaitCursor );
56+
57+
stop();
58+
59+
foreach ( QgsDataItem *child, mChildren )
60+
{
61+
deleteChildItem( child );
62+
}
63+
64+
foreach ( QgsDataItem *item, createChildren() )
65+
{
66+
addChildItem( item, true );
67+
}
68+
69+
QApplication::restoreOverrideCursor();
3770
}
3871

3972
QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
@@ -42,6 +75,8 @@ QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
4275
QVector<QgsDataItem*> children;
4376
QgsDataSourceURI uri = QgsPostgresConn::connUri( mName );
4477

78+
mSchemaMap.clear();
79+
4580
mConn = QgsPostgresConn::connectDb( uri.connectionInfo(), true );
4681
if ( !mConn )
4782
return children;
@@ -62,7 +97,7 @@ QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
6297
return children;
6398
}
6499

65-
QgsGeomColumnTypeThread *columnTypeThread = 0;
100+
stop();
66101

67102
foreach ( QgsPostgresLayerProperty layerProperty, layerProperties )
68103
{
@@ -76,17 +111,17 @@ QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
76111

77112
if ( QgsPostgresConn::wkbTypeFromPostgis( layerProperty.type ) == QGis::WKBUnknown )
78113
{
79-
if ( !columnTypeThread )
114+
if ( !mColumnTypeThread )
80115
{
81116
QgsPostgresConn *conn = QgsPostgresConn::connectDb( uri.connectionInfo(), true /* readonly */ );
82117
if ( conn )
83118
{
84-
columnTypeThread = new QgsGeomColumnTypeThread( conn, true /* use estimated metadata */ );
119+
mColumnTypeThread = new QgsGeomColumnTypeThread( conn, true /* use estimated metadata */ );
85120

86-
connect( columnTypeThread, SIGNAL( setLayerType( QgsPostgresLayerProperty ) ),
121+
connect( mColumnTypeThread, SIGNAL( setLayerType( QgsPostgresLayerProperty ) ),
87122
this, SLOT( setLayerType( QgsPostgresLayerProperty ) ) );
88123
connect( this, SIGNAL( addGeometryColumn( QgsPostgresLayerProperty ) ),
89-
columnTypeThread, SLOT( addGeometryColumn( QgsPostgresLayerProperty ) ) );
124+
mColumnTypeThread, SLOT( addGeometryColumn( QgsPostgresLayerProperty ) ) );
90125
}
91126
}
92127

@@ -98,8 +133,8 @@ QVector<QgsDataItem*> QgsPGConnectionItem::createChildren()
98133
schemaItem->addLayer( layerProperty );
99134
}
100135

101-
if ( columnTypeThread )
102-
columnTypeThread->start();
136+
if ( mColumnTypeThread )
137+
mColumnTypeThread->start();
103138

104139
return children;
105140
}
@@ -186,6 +221,11 @@ bool QgsPGConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )
186221

187222
qApp->setOverrideCursor( Qt::WaitCursor );
188223

224+
QProgressDialog *progress = new QProgressDialog( tr( "Copying features..." ), tr( "Abort" ), 0, 0, 0 );
225+
progress->setWindowTitle( tr( "Import layer" ) );
226+
progress->setWindowModality( Qt::WindowModal );
227+
progress->show();
228+
189229
QStringList importResults;
190230
bool hasError = false;
191231
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
@@ -207,7 +247,7 @@ bool QgsPGConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )
207247
QgsDebugMsg( "URI " + uri.uri() );
208248
QgsVectorLayerImport::ImportError err;
209249
QString importError;
210-
err = QgsVectorLayerImport::importLayer( srcLayer, uri.uri(), "postgres", &srcLayer->crs(), false, &importError );
250+
err = QgsVectorLayerImport::importLayer( srcLayer, uri.uri(), "postgres", &srcLayer->crs(), false, &importError, false, 0, progress );
211251
if ( err == QgsVectorLayerImport::NoError )
212252
importResults.append( tr( "%1: OK!" ).arg( u.name ) );
213253
else
@@ -225,6 +265,8 @@ bool QgsPGConnectionItem::handleDrop( const QMimeData * data, Qt::DropAction )
225265
delete srcLayer;
226266
}
227267

268+
delete progress;
269+
228270
qApp->restoreOverrideCursor();
229271

230272
if ( hasError )

‎src/providers/postgres/qgspostgresdataitems.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class QgsPGConnectionItem : public QgsDataCollectionItem
6161

6262
QgsPostgresConn *connection() const { return mConn; }
6363

64+
void refresh();
65+
6466
signals:
6567
void addGeometryColumn( QgsPostgresLayerProperty );
6668

@@ -71,8 +73,10 @@ class QgsPGConnectionItem : public QgsDataCollectionItem
7173
void setLayerType( QgsPostgresLayerProperty layerProperty );
7274

7375
private:
76+
void stop();
7477
QgsPostgresConn *mConn;
7578
QMap<QString, QgsPGSchemaItem * > mSchemaMap;
79+
QgsGeomColumnTypeThread *mColumnTypeThread;
7680
};
7781

7882
class QgsPGSchemaItem : public QgsDataCollectionItem

‎src/providers/postgres/qgspostgresprovider.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3274,7 +3274,7 @@ QgsVectorLayerImport::ImportError QgsPostgresProvider::createEmptyLayer(
32743274
QString pk = primaryKey = "id";
32753275
for ( QgsFieldMap::const_iterator fldIt = fields.begin(); fldIt != fields.end(); ++fldIt )
32763276
{
3277-
if ( fldIt.value().name() == pk )
3277+
if ( fldIt.value().name() == primaryKey )
32783278
{
32793279
// it already exists, try again with a new name
32803280
primaryKey = QString( "%1_%2" ).arg( pk ).arg( index++ );

‎src/providers/postgres/qgspostgresprovider.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ class QgsPostgresProvider : public QgsVectorDataProvider
205205

206206
QgsAttributeList attributeIndexes();
207207

208+
QgsAttributeList pkAttributeIndexes() { return mPrimaryKeyAttrs; }
209+
208210
/**Returns the default value for field specified by @c fieldName */
209211
QVariant defaultValue( QString fieldName, QString tableName = QString::null, QString schemaName = QString::null );
210212

@@ -445,7 +447,7 @@ class QgsPostgresProvider : public QgsVectorDataProvider
445447
long layerId;
446448
};
447449

448-
TopoLayerInfo mTopoLayerInfo;
450+
TopoLayerInfo mTopoLayerInfo;
449451

450452
bool getTopoLayerInfo();
451453

‎src/providers/wms/qgswmssourceselect.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ QgsWMSSourceSelect::QgsWMSSourceSelect( QWidget * parent, Qt::WFlags fl, bool ma
5858
: QDialog( parent, fl )
5959
, mManagerMode( managerMode )
6060
, mEmbeddedMode( embeddedMode )
61-
, mCurrentTileset( 0 )
6261
, mDefaultCRS( GEO_EPSG_CRS_AUTHID )
62+
, mCurrentTileset( 0 )
6363
{
6464
setupUi( this );
6565

‎src/ui/qgsoptionsbase.ui

Lines changed: 3197 additions & 2840 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.