00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "qgsprojectbadlayerguihandler.h"
00017
00018 #include <QApplication>
00019 #include <QDomDocument>
00020 #include <QFileInfo>
00021 #include <QMessageBox>
00022 #include <QPushButton>
00023
00024 #include "qgslogger.h"
00025 #include "qgisgui.h"
00026 #include "qgsproviderregistry.h"
00027
00028 QgsProjectBadLayerGuiHandler::QgsProjectBadLayerGuiHandler()
00029 {
00030 }
00031
00032 bool QgsProjectBadLayerGuiHandler::mIgnore = false;
00033
00034 void QgsProjectBadLayerGuiHandler::handleBadLayers( QList<QDomNode> layers, QDomDocument projectDom )
00035 {
00036 Q_UNUSED( projectDom );
00037
00038 QgsDebugMsg( QString( "%1 bad layers found" ).arg( layers.size() ) );
00039
00040
00041 QApplication::setOverrideCursor( Qt::ArrowCursor );
00042
00043 QMessageBox messageBox;
00044
00045 QAbstractButton *ignoreButton =
00046 messageBox.addButton( tr( "Ignore" ), QMessageBox::ActionRole );
00047
00048 QAbstractButton *okButton = messageBox.addButton( QMessageBox :: Ok );
00049
00050 messageBox.addButton( QMessageBox :: Cancel );
00051
00052 messageBox.setWindowTitle( tr( "QGIS Project Read Error" ) );
00053 messageBox.setText( tr( "Unable to open one or more project layers.\nChoose "
00054 "ignore to continue loading without the missing layers. Choose cancel to "
00055 "return to your pre-project load state. Choose OK to try to find the "
00056 "missing layers." ) );
00057 messageBox.setIcon( QMessageBox::Critical );
00058 messageBox.exec();
00059
00060 QgsProjectBadLayerGuiHandler::mIgnore = false;
00061
00062 if ( messageBox.clickedButton() == okButton )
00063 {
00064 QgsDebugMsg( "want to find missing layers is true" );
00065
00066
00067
00068
00069 QString filter = QgsProviderRegistry::instance()->fileVectorFilters();
00070 findLayers( filter, layers );
00071 }
00072 else if ( messageBox.clickedButton() == ignoreButton )
00073 {
00074 QgsProjectBadLayerGuiHandler::mIgnore = true;
00075 }
00076 else
00077 {
00078
00079 }
00080
00081 QApplication::restoreOverrideCursor();
00082 }
00083
00084 QgsProjectBadLayerGuiHandler::DataType QgsProjectBadLayerGuiHandler::dataType( QDomNode & layerNode )
00085 {
00086 QString type = layerNode.toElement().attribute( "type" );
00087
00088 if ( QString::null == type )
00089 {
00090 QgsDebugMsg( "cannot find ``type'' attribute" );
00091
00092 return IS_BOGUS;
00093 }
00094
00095 if ( "raster" == type )
00096 {
00097 QgsDebugMsg( "is a raster" );
00098
00099 return IS_RASTER;
00100 }
00101 else if ( "vector" == type )
00102 {
00103 QgsDebugMsg( "is a vector" );
00104
00105 return IS_VECTOR;
00106 }
00107
00108 QgsDebugMsg( "is unknown type " + type );
00109
00110 return IS_BOGUS;
00111 }
00112
00113
00114 QString QgsProjectBadLayerGuiHandler::dataSource( QDomNode & layerNode )
00115 {
00116 QDomNode dataSourceNode = layerNode.namedItem( "datasource" );
00117
00118 if ( dataSourceNode.isNull() )
00119 {
00120 QgsDebugMsg( "cannot find datasource node" );
00121
00122 return QString::null;
00123 }
00124
00125 return dataSourceNode.toElement().text();
00126
00127 }
00128
00129
00130
00131
00132 QgsProjectBadLayerGuiHandler::ProviderType QgsProjectBadLayerGuiHandler::providerType( QDomNode & layerNode )
00133 {
00134
00135
00136 switch ( dataType( layerNode ) )
00137 {
00138 case IS_VECTOR:
00139 {
00140 QString ds = dataSource( layerNode );
00141
00142 QgsDebugMsg( "datasource is " + ds );
00143
00144 if ( ds.contains( "host=" ) )
00145 {
00146 return IS_URL;
00147 }
00148 #ifdef HAVE_POSTGRESQL
00149 else if ( ds.contains( "dbname=" ) )
00150 {
00151 return IS_DATABASE;
00152 }
00153 #endif
00154
00155
00156
00157 return IS_FILE;
00158 }
00159
00160 case IS_RASTER:
00161
00162 return IS_FILE;
00163
00164 default:
00165 QgsDebugMsg( "unknown ``type'' attribute" );
00166 }
00167
00168 return IS_Unknown;
00169
00170 }
00171
00172
00173
00174 void QgsProjectBadLayerGuiHandler::setDataSource( QDomNode & layerNode, QString const & dataSource )
00175 {
00176 QDomNode dataSourceNode = layerNode.namedItem( "datasource" );
00177 QDomElement dataSourceElement = dataSourceNode.toElement();
00178 QDomText dataSourceText = dataSourceElement.firstChild().toText();
00179
00180 QgsDebugMsg( "datasource changed from " + dataSourceText.data() );
00181
00182 dataSourceText.setData( dataSource );
00183
00184 QgsDebugMsg( "to " + dataSourceText.data() );
00185 }
00186
00187
00188
00189
00190 bool QgsProjectBadLayerGuiHandler::findMissingFile( QString const & fileFilters, QDomNode & layerNode )
00191 {
00192
00193
00194
00195
00196 QFileInfo originalDataSource( dataSource( layerNode ) );
00197
00198 QString memoryQualifier;
00199
00200
00201 switch ( dataType( layerNode ) )
00202 {
00203 case IS_VECTOR:
00204 {
00205 memoryQualifier = "lastVectorFileFilter";
00206
00207 break;
00208 }
00209 case IS_RASTER:
00210 {
00211 memoryQualifier = "lastRasterFileFilter";
00212
00213 break;
00214 }
00215 default:
00216 QgsDebugMsg( "unable to determine data type" );
00217 return false;
00218 }
00219
00220
00221
00222
00223
00224
00225 QString myFileFilters = originalDataSource.fileName() + ";;" + fileFilters;
00226
00227 QStringList selectedFiles;
00228 QString enc;
00229 QString title = QObject::tr( "Where is '%1' (original location: %2)?" )
00230 .arg( originalDataSource.fileName() )
00231 .arg( originalDataSource.absoluteFilePath() );
00232
00233 bool retVal = QgisGui::openFilesRememberingFilter( memoryQualifier,
00234 myFileFilters,
00235 selectedFiles,
00236 enc,
00237 title,
00238 true );
00239
00240 if ( selectedFiles.isEmpty() )
00241 {
00242 return retVal;
00243 }
00244 else
00245 {
00246 setDataSource( layerNode, selectedFiles.first() );
00247 if ( ! QgsProject::instance()->read( layerNode ) )
00248 {
00249 QgsDebugMsg( "unable to re-read layer" );
00250 }
00251 }
00252 return retVal;
00253 }
00254
00255
00256
00257
00258 bool QgsProjectBadLayerGuiHandler::findLayer( QString const & fileFilters, QDomNode const & constLayerNode )
00259 {
00260
00261 QDomNode & layerNode = const_cast<QDomNode&>( constLayerNode );
00262
00263 bool retVal = false;
00264
00265 switch ( providerType( layerNode ) )
00266 {
00267 case IS_FILE:
00268 QgsDebugMsg( "layer is file based" );
00269 retVal = findMissingFile( fileFilters, layerNode );
00270 break;
00271
00272 case IS_DATABASE:
00273 QgsDebugMsg( "layer is database based" );
00274 break;
00275
00276 case IS_URL:
00277 QgsDebugMsg( "layer is URL based" );
00278 break;
00279
00280 case IS_Unknown:
00281 QgsDebugMsg( "layer has an unknown type" );
00282 break;
00283 }
00284 return retVal;
00285 }
00286
00287
00288
00289
00290 void QgsProjectBadLayerGuiHandler::findLayers( QString const & fileFilters, QList<QDomNode> const & layerNodes )
00291 {
00292
00293 for ( QList<QDomNode>::const_iterator i = layerNodes.begin();
00294 i != layerNodes.end();
00295 ++i )
00296 {
00297 if ( findLayer( fileFilters, *i ) )
00298 {
00299
00300 break;
00301 }
00302 }
00303
00304 }
00305