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