[QGIS Commit] r15353 - in trunk/qgis/src: app ui

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sat Mar 5 21:19:47 EST 2011


Author: jef
Date: 2011-03-05 18:19:47 -0800 (Sat, 05 Mar 2011)
New Revision: 15353

Added:
   trunk/qgis/src/app/qgshandlebadlayers.cpp
   trunk/qgis/src/app/qgshandlebadlayers.h
   trunk/qgis/src/ui/qgshandlebadlayersbase.ui
Modified:
   trunk/qgis/src/app/CMakeLists.txt
Log:
[FEATURE] allow managing missing layers in a list

Modified: trunk/qgis/src/app/CMakeLists.txt
===================================================================
--- trunk/qgis/src/app/CMakeLists.txt	2011-03-06 02:18:18 UTC (rev 15352)
+++ trunk/qgis/src/app/CMakeLists.txt	2011-03-06 02:19:47 UTC (rev 15353)
@@ -92,6 +92,7 @@
   qgsvectorlayerproperties.cpp
   qgsquerybuilder.cpp
   qgshighlight.cpp
+  qgshandlebadlayers.cpp
 
   qgsmanageconnectionsdialog.cpp
 
@@ -218,6 +219,7 @@
   qgsuniquevaluedialog.h
   qgsvectorlayerproperties.h
   qgswmssourceselect.h
+  qgshandlebadlayers.h
 
   composer/qgsattributeselectiondialog.h
   composer/qgscomposer.h

Added: trunk/qgis/src/app/qgshandlebadlayers.cpp
===================================================================
--- trunk/qgis/src/app/qgshandlebadlayers.cpp	                        (rev 0)
+++ trunk/qgis/src/app/qgshandlebadlayers.cpp	2011-03-06 02:19:47 UTC (rev 15353)
@@ -0,0 +1,358 @@
+/***************************************************************************
+                          qgshandlebadlayers.cpp  -  description
+                             -------------------
+    begin                : Sat 5 Mar 2011
+    copyright            : (C) 2011 by Juergen E. Fischer, norBIT GmbH
+    email                : jef at norbit dot de
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+/* $Id$ */
+
+#include "qgshandlebadlayers.h"
+#include "qgisapp.h"
+#include "qgisgui.h"
+#include "qgsdatasourceuri.h"
+#include "qgslogger.h"
+#include "qgsrasterlayer.h"
+#include "qgsproviderregistry.h"
+
+#include <QDomDocument>
+#include <QDomElement>
+#include <QPushButton>
+#include <QMessageBox>
+
+QgsHandleBadLayersHandler::QgsHandleBadLayersHandler()
+{
+}
+
+void QgsHandleBadLayersHandler::handleBadLayers( QList<QDomNode> layers, QDomDocument projectDom )
+{
+  QApplication::setOverrideCursor( Qt::ArrowCursor );
+  QgsHandleBadLayers *dialog = new QgsHandleBadLayers( layers, projectDom );
+  dialog->exec();
+  delete dialog;
+  QApplication::restoreOverrideCursor();
+}
+
+
+QgsHandleBadLayers::QgsHandleBadLayers( const QList<QDomNode> &layers, const QDomDocument &projectDom )
+    : QDialog( QgisApp::instance() )
+    , mLayers( layers )
+{
+  setupUi( this );
+
+
+  mVectorFileFilter = QgsProviderRegistry::instance()->fileVectorFilters();
+  QgsRasterLayer::buildSupportedRasterFileFilter( mRasterFileFilter );
+
+  mBrowseButton = new QPushButton( tr( "Browse" ) );
+  buttonBox->addButton( mBrowseButton, QDialogButtonBox::ActionRole );
+  mBrowseButton->setDisabled( true );
+
+  connect( mLayerList, SIGNAL( itemSelectionChanged() ), this, SLOT( selectionChanged() ) );
+  connect( mLayerList, SIGNAL( itemChanged( QTableWidgetItem * ) ), this, SLOT( itemChanged( QTableWidgetItem * ) ) );
+  connect( mLayerList, SIGNAL( cellDoubleClicked( int, int ) ), this, SLOT( cellDoubleClicked( int, int ) ) );
+  connect( mBrowseButton, SIGNAL( clicked() ), this, SLOT( browseClicked() ) );
+
+  mLayerList->clear();
+  mLayerList->setSortingEnabled( true );
+  mLayerList->setSelectionBehavior( QAbstractItemView::SelectRows );
+  mLayerList->setColumnCount( 5 );
+
+  mLayerList->setHorizontalHeaderLabels( QStringList()
+                                         << tr( "Layer name" )
+                                         << tr( "Type" )
+                                         << tr( "Provider" )
+                                         << tr( "New file" )
+                                         << tr( "New datasource" )
+                                       );
+
+  int j = 0;
+  for ( int i = 0; i < mLayers.size(); i++ )
+  {
+    const QDomNode &node = mLayers[i];
+
+    QString name = node.namedItem( "layername" ).toElement().text();
+    QString type = node.toElement().attribute( "type" );
+    QString datasource = node.namedItem( "datasource" ).toElement().text();
+    QString provider;
+
+    QString filename = datasource;
+
+    if ( type == "vector" )
+    {
+      provider = node.namedItem( "provider" ).toElement().text();
+      if ( provider == "spatialite" )
+      {
+        QgsDataSourceURI uri( datasource );
+        filename = uri.database();
+      }
+      else if ( provider == "ogr" )
+      {
+        QStringList theURIParts = datasource.split( "|" );
+        filename = theURIParts[0];
+      }
+      else if ( provider == "delimitedtext" )
+      {
+        QStringList theURIParts = datasource.split( "?" );
+        filename = theURIParts[0];
+      }
+      else if ( provider == "postgres" || provider == "sqlanywhere" )
+      {
+        continue;
+      }
+    }
+    else
+    {
+      provider = tr( "none" );
+    }
+
+    QgsDebugMsg( QString( "name=%1 type=%2 provider=%3 filename=%4 datasource='%5'" )
+                 .arg( name )
+                 .arg( type )
+                 .arg( provider )
+                 .arg( filename )
+                 .arg( datasource ) );
+
+    mLayerList->setRowCount( j + 1 );
+
+    QTableWidgetItem *item;
+
+    item = new QTableWidgetItem( name );
+    item->setData( Qt::UserRole + 0, i );
+    item->setFlags( item->flags() & ~Qt::ItemIsEditable );
+    mLayerList->setItem( j, 0, item );
+
+    item = new QTableWidgetItem( type );
+    item->setFlags( item->flags() & ~Qt::ItemIsEditable );
+    mLayerList->setItem( j, 1, item );
+
+    item = new QTableWidgetItem( provider );
+    item->setFlags( item->flags() & ~Qt::ItemIsEditable );
+    mLayerList->setItem( j, 2, item );
+
+    item = new QTableWidgetItem( filename );
+    mLayerList->setItem( j, 3, item );
+
+    item = new QTableWidgetItem( datasource );
+    item->setFlags( item->flags() & ~Qt::ItemIsEditable );
+    mLayerList->setItem( j, 4, item );
+
+    j++;
+  }
+
+  mLayerList->resizeColumnsToContents();
+}
+
+QgsHandleBadLayers::~QgsHandleBadLayers()
+{
+}
+
+void QgsHandleBadLayers::itemChanged( QTableWidgetItem *item )
+{
+  if ( item->column() != 3 )
+    return;
+
+  QFileInfo fi( item->text() );
+
+  item->setForeground( fi.exists() ? QBrush( Qt::green ) : QBrush( Qt::red ) );
+}
+
+void QgsHandleBadLayers::cellDoubleClicked( int row, int column )
+{
+  if ( column != 3 || !mBrowseButton->isEnabled() )
+    return;
+
+  mBrowseButton->click();
+}
+
+void QgsHandleBadLayers::selectionChanged()
+{
+  QgsDebugMsg( "entered." );
+
+  mRows.clear();
+
+  foreach( QTableWidgetItem *item, mLayerList->selectedItems() )
+  {
+    if ( item->column() != 0 )
+      continue;
+
+    mRows << item->row();
+  }
+
+  mBrowseButton->setEnabled( mRows.size() > 0 );
+}
+
+void QgsHandleBadLayers::browseClicked()
+{
+  QgsDebugMsg( "entered." );
+
+  if ( mRows.size() == 1 )
+  {
+    QString memoryQualifier;
+    QString fileFilter;
+    int idx = mLayerList->item( mRows[0], 0 )->data( Qt::UserRole ).toInt();
+    QTableWidgetItem *fileItem = mLayerList->item( mRows[0], 3 );
+
+    if ( mLayers[ idx ].toElement().attribute( "type" ) == "vector" )
+    {
+      memoryQualifier = "lastVectorFileFilter";
+      fileFilter = mVectorFileFilter;
+    }
+    else
+    {
+      memoryQualifier = "lastRasterFileFilter";
+      fileFilter = mRasterFileFilter;
+    }
+
+    QStringList selectedFiles;
+    QString enc;
+    QString title = tr( "Select file to replace '%1'" ).arg( fileItem->text() );
+
+    QgisGui::openFilesRememberingFilter( memoryQualifier, fileFilter, selectedFiles, enc, title );
+
+    if ( selectedFiles.size() != 1 )
+    {
+      QMessageBox::information( this, title, tr( "Please select exactly one file." ) );
+      return;
+    }
+
+    fileItem->setText( selectedFiles[0] );
+  }
+  else if ( mRows.size() > 1 )
+  {
+    QStringList selectedFiles;
+    QString enc;
+    QString title = tr( "Select new directory of selected files" );
+
+    QgisGui::openFilesRememberingFilter( "missingDirectory", tr( "All files (*)" ), selectedFiles, enc, title );
+
+    if ( selectedFiles.isEmpty() )
+    {
+      return;
+    }
+
+    QFileInfo path( selectedFiles[0] );
+    if ( !path.exists() )
+    {
+      return;
+    }
+
+    foreach( int i, mRows )
+    {
+      QTableWidgetItem *fileItem = mLayerList->item( i, 3 );
+
+      QFileInfo fi( fileItem->text() );
+      fi.setFile( path.dir(), fi.fileName() );
+
+      if ( !fi.exists() )
+        continue;
+
+      fileItem->setText( fi.absoluteFilePath() );
+    }
+  }
+}
+
+void QgsHandleBadLayers::apply()
+{
+  QgsDebugMsg( "entered." );
+  for ( int i = 0; i < mLayerList->rowCount(); i++ )
+  {
+    int idx = mLayerList->item( i, 0 )->data( Qt::UserRole ).toInt();
+    QDomNode &node = const_cast<QDomNode &>( mLayers[ idx ] );
+
+    QString type = mLayerList->item( i, 1 )->text();
+    QString provider = mLayerList->item( i, 2 )->text();
+    QTableWidgetItem *fileItem = mLayerList->item( i, 3 );
+    QString datasource = mLayerList->item( i, 4 )->text();
+
+    QString filename = fileItem->text();
+    if ( !QFileInfo( filename ).exists() )
+    {
+      continue;
+    }
+
+    if ( type == "vector" )
+    {
+      if ( provider == "spatialite" )
+      {
+        QgsDataSourceURI uri( datasource );
+        uri.setDatabase( filename );
+        datasource = uri.uri();
+      }
+      else if ( provider == "ogr" )
+      {
+        QStringList theURIParts = datasource.split( "|" );
+        theURIParts[0] = filename;
+        datasource = theURIParts.join( "|" );
+      }
+      else if ( provider == "delimitedtext" )
+      {
+        QStringList theURIParts = datasource.split( "?" );
+        theURIParts[0] = filename;
+        datasource = theURIParts.join( "?" );
+      }
+    }
+    else
+    {
+      datasource = filename;
+    }
+
+    node.namedItem( "datasource" ).toElement().firstChild().toText().setData( datasource );
+    if ( QgsProject::instance()->read( node ) )
+    {
+      mLayerList->removeRow( i-- );
+    }
+    else
+    {
+      fileItem->setForeground( QBrush( Qt::red ) );
+    }
+  }
+}
+
+void QgsHandleBadLayers::accept()
+{
+  QgsDebugMsg( "entered." );
+  apply();
+
+  if ( mLayerList->rowCount() > 0  &&
+       QMessageBox::warning( this,
+                             tr( "Unhandled layer will be lost." ),
+                             tr( "There are still %n unhandled layer(s), that will be lost if you closed now.",
+                                 "unhandled layers",
+                                 mLayerList->rowCount() ),
+                             QMessageBox::Ok | QMessageBox::Cancel,
+                             QMessageBox::Cancel ) == QMessageBox::Cancel )
+  {
+    return;
+  }
+
+  QDialog::accept();
+}
+
+void QgsHandleBadLayers::rejected()
+{
+  QgsDebugMsg( "entered." );
+
+  if ( mLayerList->rowCount() > 0  &&
+       QMessageBox::warning( this,
+                             tr( "Unhandled layer will be lost." ),
+                             tr( "There are still %n unhandled layer(s), that will be lost if you closed now.",
+                                 "unhandled layers",
+                                 mLayerList->rowCount() ),
+                             QMessageBox::Ok | QMessageBox::Cancel,
+                             QMessageBox::Cancel ) == QMessageBox::Cancel )
+  {
+    return;
+  }
+
+  QDialog::reject();
+}

Added: trunk/qgis/src/app/qgshandlebadlayers.h
===================================================================
--- trunk/qgis/src/app/qgshandlebadlayers.h	                        (rev 0)
+++ trunk/qgis/src/app/qgshandlebadlayers.h	2011-03-06 02:19:47 UTC (rev 15353)
@@ -0,0 +1,67 @@
+/***************************************************************************
+                          qgshandlebadlayers.h  -  description
+                             -------------------
+    begin                : Sat 05 Mar 2011
+    copyright            : (C) 2011 by Juergen E. Fischer, norBIT GmbH
+    email                : jef at norbit dot de
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+/* $Id:$ */
+#ifndef QGSHANDLEBADLAYERS_H
+#define QGSHANDLEBADLAYERS_H
+
+#include "ui_qgshandlebadlayersbase.h"
+#include "qgsproject.h"
+
+class QgsHandleBadLayersHandler
+      : public QObject
+      , public QgsProjectBadLayerHandler
+{
+    Q_OBJECT
+
+  public:
+    QgsHandleBadLayersHandler();
+
+    /** implementation of the handler */
+    virtual void handleBadLayers( QList<QDomNode> layers, QDomDocument projectDom );
+};
+
+
+class QPushButton;
+
+class QgsHandleBadLayers
+      : public QDialog
+      , private Ui::QgsHandleBadLayersBase
+{
+    Q_OBJECT
+
+  public:
+    QgsHandleBadLayers( const QList<QDomNode> &layers, const QDomDocument &dom );
+    ~QgsHandleBadLayers();
+
+  private slots:
+    void selectionChanged();
+    void browseClicked();
+    void apply();
+    void accept();
+    void rejected();
+    void itemChanged( QTableWidgetItem * );
+    void cellDoubleClicked( int row, int column );
+
+  private:
+    QPushButton *mBrowseButton;
+    const QList<QDomNode> &mLayers;
+    QList<int> mRows;
+    QString mVectorFileFilter;
+    QString mRasterFileFilter;
+};
+
+#endif

Added: trunk/qgis/src/ui/qgshandlebadlayersbase.ui
===================================================================
--- trunk/qgis/src/ui/qgshandlebadlayersbase.ui	                        (rev 0)
+++ trunk/qgis/src/ui/qgshandlebadlayersbase.ui	2011-03-06 02:19:47 UTC (rev 15353)
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QgsHandleBadLayersBase</class>
+ <widget class="QDialog" name="QgsHandleBadLayersBase">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>834</width>
+    <height>505</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Handle bad layers</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTableWidget" name="mLayerList">
+     <column>
+      <property name="text">
+       <string>Layer name</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Type</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Provider</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Original filename</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>New filename</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>Original datasource</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>New datasource</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>QgsHandleBadLayersBase</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>QgsHandleBadLayersBase</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>



More information about the QGIS-commit mailing list