[QGIS Commit] r14642 - in trunk/qgis/src: plugins/delimited_text providers/delimitedtext

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sun Nov 14 09:49:17 EST 2010


Author: jef
Date: 2010-11-14 06:49:17 -0800 (Sun, 14 Nov 2010)
New Revision: 14642

Modified:
   trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugin.cpp
   trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp
   trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.h
   trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextpluginguibase.ui
   trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
   trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h
Log:
improve delimited text plugin ui and allow skipping lines

Modified: trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugin.cpp
===================================================================
--- trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugin.cpp	2010-11-14 14:48:12 UTC (rev 14641)
+++ trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugin.cpp	2010-11-14 14:49:17 UTC (rev 14642)
@@ -124,7 +124,7 @@
   connect( myQgsDelimitedTextPluginGui,
            SIGNAL( drawVectorLayer( QString, QString, QString ) ),
            this, SLOT( drawVectorLayer( QString, QString, QString ) ) );
-  myQgsDelimitedTextPluginGui->show();
+  myQgsDelimitedTextPluginGui->exec();
 }
 //!draw a vector layer in the qui - intended to respond to signal
 //sent by diolog when it as finished creating a layer

Modified: trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp
===================================================================
--- trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp	2010-11-14 14:48:12 UTC (rev 14641)
+++ trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp	2010-11-14 14:49:17 UTC (rev 14642)
@@ -32,10 +32,9 @@
 {
   setupUi( this );
   pbnOK = buttonBox->button( QDialogButtonBox::Ok );
-  pbnParse = buttonBox->addButton( tr( "Parse" ), QDialogButtonBox::ActionRole );
-  connect( pbnParse, SIGNAL( clicked() ), this, SLOT( pbnParse_clicked() ) );
-  connect( txtFilePath, SIGNAL( textChanged( const QString& ) ), this, SLOT( pbnParse_clicked() ) );
-  enableButtons();
+
+  enableAccept();
+
   // at startup, fetch the last used delimiter and directory from
   // settings
   QSettings settings;
@@ -43,21 +42,40 @@
   txtDelimiter->setText( settings.value( key + "/delimiter" ).toString() );
 
   // and how to use the delimiter
-  QString delimiterType = settings.value( key + "/delimiterType",
-                                          "plain" ).toString();
-  if ( delimiterType == "plain" )
+  QString delimiterType = settings.value( key + "/delimiterType", "plain" ).toString();
+  if ( delimiterType == "selection" )
   {
+    delimiterSelection->setChecked( true );
+  }
+  else if ( delimiterType == "plain" )
+  {
     delimiterPlain->setChecked( true );
-    delimiterRegexp->setChecked( false );
   }
   else
   {
-    delimiterPlain->setChecked( false );
     delimiterRegexp->setChecked( true );
   }
 
-  txtSample->setFixedHeight( 120 );
+  cmbXField->setDisabled( true );
+  cmbYField->setDisabled( true );
+
+  connect( txtFilePath, SIGNAL( textChanged( QString ) ), this, SLOT( enableAccept() ) );
+
+  connect( delimiterSelection, SIGNAL( toggled( bool ) ), this, SLOT( enableAccept() ) );
+  connect( delimiterPlain, SIGNAL( toggled( bool ) ), this, SLOT( enableAccept() ) );
+  connect( delimiterRegexp, SIGNAL( toggled( bool ) ), this, SLOT( enableAccept() ) );
+
+  connect( cbxDelimSpace, SIGNAL( stateChanged( int ) ), this, SLOT( enableAccept() ) );
+  connect( cbxDelimTab, SIGNAL( stateChanged( int ) ), this, SLOT( enableAccept() ) );
+  connect( cbxDelimSemicolon, SIGNAL( stateChanged( int ) ), this, SLOT( enableAccept() ) );
+  connect( cbxDelimComma, SIGNAL( stateChanged( int ) ), this, SLOT( enableAccept() ) );
+  connect( cbxDelimColon, SIGNAL( stateChanged( int ) ), this, SLOT( enableAccept() ) );
+
+  connect( txtDelimiter, SIGNAL( editingFinished() ), this, SLOT( enableAccept() ) );
+
+  connect( rowCounter, SIGNAL( valueChanged( int ) ), this, SLOT( enableAccept() ) );
 }
+
 QgsDelimitedTextPluginGui::~QgsDelimitedTextPluginGui()
 {
 }
@@ -66,26 +84,36 @@
 {
   getOpenFileName();
 }
-void QgsDelimitedTextPluginGui::pbnParse_clicked()
-{
-  updateFieldLists();
-}
+
 void QgsDelimitedTextPluginGui::on_buttonBox_accepted()
 {
-  if ( txtLayerName->text().length() > 0 )
+  if ( !txtLayerName->text().isEmpty() )
   {
     //Build the delimited text URI from the user provided information
-    QString delimiterType = "plain";
-    if ( delimiterRegexp->isChecked() )
+    QString delimiterType;
+    if ( delimiterSelection->isChecked() )
       delimiterType = "regexp";
+    else if ( delimiterPlain->isChecked() )
+      delimiterType = "plain";
+    else if ( delimiterRegexp->isChecked() )
+      delimiterType = "regexp";
 
-    QString uri = QString( "%1?delimiter=%2&delimiterType=%3&xField=%4&yField=%5" )
+    QString uri = QString( "%1?delimiter=%2&delimiterType=%3" )
                   .arg( txtFilePath->text() )
                   .arg( txtDelimiter->text() )
-                  .arg( delimiterType )
-                  .arg( cmbXField->currentText() )
-                  .arg( cmbYField->currentText() );
+                  .arg( delimiterType );
 
+    if ( !cmbXField->currentText().isEmpty() && !cmbYField->currentText().isEmpty() )
+    {
+      uri += QString( "&xField=%1&yField=%2" )
+             .arg( cmbXField->currentText() )
+             .arg( cmbYField->currentText() );
+    }
+
+    int skipLines = rowCounter->value();
+    if ( skipLines > 0 )
+      uri += QString( "&skipLines=%1" ).arg( skipLines );
+
     // add the layer to the map
     emit drawVectorLayer( uri, txtLayerName->text(), "delimitedtext" );
     // store the settings
@@ -96,6 +124,8 @@
     QFileInfo fi( txtFilePath->text() );
     settings.setValue( key + "/text_path", fi.path() );
 
+    if ( delimiterSelection->isChecked() )
+      settings.setValue( key + "/delimiterType", "selection" );
     if ( delimiterPlain->isChecked() )
       settings.setValue( key + "/delimiterType", "plain" );
     else
@@ -114,120 +144,170 @@
   reject();
 }
 
+QStringList QgsDelimitedTextPluginGui::splitLine( QString line )
+{
+  QStringList fieldList;
+  QString delimiter = txtDelimiter->text();
+
+  if ( delimiterPlain->isChecked() )
+  {
+    // convert \t to tabulator
+    delimiter = txtDelimiter->text();
+    delimiter.replace( "\\t", "\t" );
+    fieldList = line.split( delimiter );
+  }
+  else if ( delimiterSelection->isChecked() )
+  {
+    delimiter = "[";
+    if ( cbxDelimSpace->isChecked() ) delimiter += " ";
+    if ( cbxDelimTab->isChecked() ) delimiter += "\t";
+    if ( cbxDelimSemicolon->isChecked() ) delimiter += ";";
+    if ( cbxDelimComma->isChecked() ) delimiter += ",";
+    if ( cbxDelimColon->isChecked() ) delimiter += ":";
+    delimiter += "]";
+    txtDelimiter->setText( delimiter );
+    fieldList = line.split( QRegExp( delimiter ) );
+  }
+  else
+  {
+    QRegExp del( delimiter );
+    fieldList = line.split( QRegExp( delimiter ) );
+  }
+
+  return fieldList;
+}
+
 void QgsDelimitedTextPluginGui::updateFieldLists()
 {
   // Update the x and y field dropdown boxes
   QgsDebugMsg( "Updating field lists" );
-  // open the file
 
-  if ( QFile::exists( txtFilePath->text() ) )
+  disconnect( cmbXField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
+  disconnect( cmbYField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
+
+  QString columnX = cmbXField->currentText();
+  QString columnY = cmbYField->currentText();
+
+  // clear the field lists
+  cmbXField->clear();
+  cmbYField->clear();
+
+  cmbXField->setEnabled( false );
+  cmbYField->setEnabled( false );
+
+  QFile file( txtFilePath->text() );
+  if ( !file.open( QIODevice::ReadOnly ) )
+    return;
+
+  int skipLines = rowCounter->value();
+
+  QTextStream stream( &file );
+  QString line;
+  do
   {
-    QFile *file = new QFile( txtFilePath->text() );
-    if ( file->open( QIODevice::ReadOnly ) )
-    {
-      // clear the field lists
-      cmbXField->clear();
-      cmbYField->clear();
-      QTextStream stream( file );
-      QString line;
-      line = readLine( stream ); // line of text excluding '\n'
-      if ( txtDelimiter->text().length() > 0 )
-      {
-        QgsDebugMsg( QString( "Attempting to split the input line: %1 using delimiter %2" ).arg( line ).arg( txtDelimiter->text() ) );
-        QString delimiter = txtDelimiter->text();
+    line = readLine( stream ); // line of text excluding '\n'
+  }
+  while ( !line.isEmpty() && skipLines-- > 0 );
 
-        QStringList fieldList;
+  QgsDebugMsg( QString( "Attempting to split the input line: %1 using delimiter %2" ).arg( line ).arg( txtDelimiter->text() ) );
 
-        if ( delimiterPlain->isChecked() )
-        {
-          // convert \t to tabulator
-          delimiter.replace( "\\t", "\t" );
-          fieldList = line.split( delimiter );
-        }
-        else
-        {
-          QRegExp del( delimiter );
-          fieldList = line.split( QRegExp( delimiter ) );
-        }
+  QString delimiter = txtDelimiter->text();
 
-        QgsDebugMsg( QString( "Split line into %1 parts" ).arg( fieldList.size() ) );
-        //
-        // We don't know anything about a text based field other
-        // than its name. All fields are assumed to be text
-        foreach( QString field, fieldList )
-        {
-          if (( field.left( 1 ) == "'" || field.left( 1 ) == "\"" ) &&
-              field.left( 1 ) == field.right( 1 ) )
-            // eat quotes
-            field = field.mid( 1, field.length() - 2 );
+  QStringList fieldList = splitLine( line );
 
-          if ( field.length() == 0 )
-            // skip empty field names
-            continue;
+  QgsDebugMsg( QString( "Split line into %1 parts" ).arg( fieldList.size() ) );
 
-          cmbXField->addItem( field );
-          cmbYField->addItem( field );
-        }
+  //
+  // We don't know anything about a text based field other
+  // than its name. All fields are assumed to be text
+  foreach( QString field, fieldList )
+  {
+    if (( field.left( 1 ) == "'" || field.left( 1 ) == "\"" ) &&
+        field.left( 1 ) == field.right( 1 ) )
+      // eat quotes
+      field = field.mid( 1, field.length() - 2 );
 
-        //x/y fields might be missing
-        cmbXField->addItem( "" );
-        cmbYField->addItem( "" );
+    if ( field.length() == 0 )
+      // skip empty field names
+      continue;
 
-        // Have a go at setting the selected items in the X and Y
-        // combo boxes to something sensible.
-        int indexX = cmbXField->findText( "lon", Qt::MatchContains );
-        int indexY = cmbXField->findText( "lat", Qt::MatchContains );
-        if ( indexX != -1 && indexY != -1 )
-        {
-          cmbXField->setCurrentIndex( indexX );
-          cmbYField->setCurrentIndex( indexY );
-        }
-        else
-        {
-          indexX = cmbXField->findText( "x", Qt::MatchContains );
-          indexY = cmbXField->findText( "y", Qt::MatchContains );
-          //leave x- and y-field empty by default if no match found
-          if ( indexX == -1 )
-          {
-            indexX = cmbXField->findText( "" );
-          }
-          if ( indexY == -1 )
-          {
-            indexY = cmbYField->findText( "" );
-          }
-          cmbXField->setCurrentIndex( indexX );
-          cmbYField->setCurrentIndex( indexY );
-        }
-        // enable the buttons
-        enableButtons();
-      }
-      else
-      {
-        QMessageBox::warning( this, tr( "No delimiter" ), tr( "Please specify a delimiter prior to parsing the file" ) );
-      }
-      // clear the sample text box
-      txtSample->clear();
-      // put the header row in the sample box
-      txtSample->insertPlainText( line + "\n" );
-      // put a few more lines into the sample box
-      int counter = 0;
-      line = readLine( stream );
-      while ( !line.isEmpty() && ( counter < 20 ) )
-      {
-        txtSample->insertPlainText( line + "\n" );
-        counter++;
-        line = readLine( stream );
-      }
-      // close the file
-      file->close();
-      // put a default layer name in the text entry
-      QFileInfo finfo( txtFilePath->text() );
-      txtLayerName->setText( finfo.completeBaseName() );
+    cmbXField->addItem( field );
+    cmbYField->addItem( field );
+  }
+
+  cmbXField->setEnabled( cmbXField->count() > 0 );
+  cmbYField->setEnabled( cmbYField->count() > 0 );
+
+  int indexX = -1;
+  if ( !columnX.isEmpty() )
+  {
+    indexX = cmbXField->findText( columnX );
+  }
+
+  if ( indexX < 0 )
+  {
+    indexX = cmbXField->findText( "lon", Qt::MatchContains );
+  }
+
+  if ( indexX < 0 )
+  {
+    indexX = cmbXField->findText( "x", Qt::MatchContains );
+  }
+
+  cmbXField->setCurrentIndex( indexX );
+
+  int indexY = -1;
+  if ( !columnY.isEmpty() )
+  {
+    indexY = cmbYField->findText( columnY );
+  }
+
+  if ( indexY < 0 )
+  {
+    indexY = cmbYField->findText( "lat", Qt::MatchContains );
+  }
+
+  if ( indexY < 0 )
+  {
+    indexY = cmbYField->findText( "y", Qt::MatchContains );
+  }
+
+  cmbYField->setCurrentIndex( indexY );
+
+  connect( cmbXField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
+  connect( cmbYField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
+
+  // clear the sample text box
+  tblSample->clear();
+
+  tblSample->setColumnCount( fieldList.size() );
+  tblSample->setHorizontalHeaderLabels( fieldList );
+
+  // put a few more lines into the sample box
+  int counter = 0;
+  line = readLine( stream );
+  while ( !line.isEmpty() && counter < 20 )
+  {
+    QStringList values = splitLine( line );
+
+    tblSample->setRowCount( counter + 1 );
+
+    for ( int i = 0; i < tblSample->columnCount(); i++ )
+    {
+      tblSample->setItem( counter, i, new QTableWidgetItem( i < values.size() ? values[i] : "" ) );
     }
 
+    counter++;
+    line = readLine( stream );
   }
+  // close the file
+  file.close();
 
+  // put a default layer name in the text entry
+  QFileInfo finfo( txtFilePath->text() );
+  txtLayerName->setText( finfo.completeBaseName() );
 }
+
 void QgsDelimitedTextPluginGui::getOpenFileName()
 {
   // Get a file to process, starting at the current directory
@@ -242,21 +322,40 @@
 
   // set path
   txtFilePath->setText( s );
-  // update the field drop-down boxes by parsing and splitting
-  // the header row
-  updateFieldLists();
 }
-void QgsDelimitedTextPluginGui::enableButtons()
+
+void QgsDelimitedTextPluginGui::enableAccept()
 {
-  pbnParse->setEnabled( txtDelimiter->text().length() > 0 && txtFilePath->text().length() > 0 );
-  pbnOK->setEnabled( txtDelimiter->text().length() > 0 && txtFilePath->text().length() > 0 );
-}
-void QgsDelimitedTextPluginGui::on_txtDelimiter_textChanged( const QString & text )
-{
-  if ( !text.isEmpty() )
+  bool enabled = false;
+
+  if ( txtFilePath->text().isEmpty() || !QFile( txtFilePath->text() ).exists() )
   {
-    pbnParse->setEnabled( true );
+    enabled = false;
   }
+  else if ( delimiterSelection->isChecked() )
+  {
+    enabled =
+      cbxDelimSpace->isChecked() ||
+      cbxDelimTab->isChecked() ||
+      cbxDelimSemicolon->isChecked() ||
+      cbxDelimComma->isChecked() ||
+      cbxDelimColon->isChecked();
+  }
+  else
+  {
+    enabled = !txtDelimiter->text().isEmpty();
+  }
+
+
+  if ( enabled )
+  {
+    updateFieldLists();
+
+    enabled = ( cmbXField->currentText().isEmpty() && cmbYField->currentText().isEmpty() )
+              || ( !cmbXField->currentText().isEmpty() && !cmbYField->currentText().isEmpty() && cmbXField->currentText() != cmbYField->currentText() );
+  }
+
+  pbnOK->setEnabled( enabled );
 }
 
 QString QgsDelimitedTextPluginGui::readLine( QTextStream &stream )

Modified: trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.h
===================================================================
--- trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.h	2010-11-14 14:48:12 UTC (rev 14641)
+++ trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextplugingui.h	2010-11-14 14:49:17 UTC (rev 14642)
@@ -30,25 +30,25 @@
     QgsDelimitedTextPluginGui( QgisInterface * _qI, QWidget* parent = 0, Qt::WFlags fl = 0 );
     ~QgsDelimitedTextPluginGui();
 
-    static QString readLine( QTextStream & stream );
+    QString readLine( QTextStream & stream );
+    QStringList splitLine( QString line );
 
   private:
     void updateFieldLists();
     void getOpenFileName();
-    void enableButtons();
 
     QgisInterface * qI;
     QAbstractButton *pbnOK;
-    QAbstractButton *pbnParse;
 
   private slots:
     void on_buttonBox_accepted();
     void on_buttonBox_rejected();
     void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
     void on_btnBrowseForFile_clicked();
-    void on_txtDelimiter_textChanged( const QString & text );
-    void pbnParse_clicked();
 
+  public slots:
+    void enableAccept();
+
   signals:
     void drawRasterLayer( QString );
     void drawVectorLayer( QString, QString, QString );

Modified: trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextpluginguibase.ui
===================================================================
--- trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextpluginguibase.ui	2010-11-14 14:48:12 UTC (rev 14641)
+++ trunk/qgis/src/plugins/delimited_text/qgsdelimitedtextpluginguibase.ui	2010-11-14 14:49:17 UTC (rev 14642)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>522</width>
-    <height>424</height>
+    <width>532</width>
+    <height>513</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -20,104 +20,150 @@
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <layout class="QGridLayout" name="gridLayout_3">
-     <item row="0" column="0">
-      <widget class="QLabel" name="textLabel1">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="text">
-        <string>Delimited text file</string>
-       </property>
-       <property name="buddy">
-        <cstring>txtFilePath</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="1">
-      <widget class="QgsFileDropEdit" name="txtFilePath">
-       <property name="toolTip">
-        <string>Full path to the delimited text file</string>
-       </property>
-       <property name="whatsThis">
-        <string>Full path to the delimited text file. In order to properly parse the fields in the file, the delimiter must be defined prior to entering the file name. Use the Browse button to the right of this field to choose the input file.</string>
-       </property>
-       <property name="readOnly">
-        <bool>true</bool>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="2">
-      <widget class="QPushButton" name="btnBrowseForFile">
-       <property name="enabled">
-        <bool>true</bool>
-       </property>
-       <property name="toolTip">
-        <string>Browse to find the delimited text file to be processed</string>
-       </property>
-       <property name="whatsThis">
-        <string>Use this button to browse to the location of the delimited text file. This button will not be enabled until a delimiter has been entered in the &lt;i&gt;Delimiter&lt;/i&gt; box. Once a file is chosen, the X and Y field drop-down boxes will be populated with the fields from the delimited text file.</string>
-       </property>
-       <property name="text">
-        <string>...</string>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="0">
-      <widget class="QLabel" name="textLabel1_2">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="text">
-        <string>Layer name</string>
-       </property>
-       <property name="buddy">
-        <cstring>txtLayerName</cstring>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="1">
-      <widget class="QLineEdit" name="txtLayerName">
-       <property name="toolTip">
-        <string>Name to display in the map legend</string>
-       </property>
-       <property name="whatsThis">
-        <string>Name displayed in the map legend</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupBox">
-     <property name="title">
-      <string>Delimiter</string>
+    <widget class="QWidget" name="widget_3" native="true">
+     <property name="acceptDrops">
+      <bool>true</bool>
      </property>
-     <layout class="QGridLayout" name="gridLayout">
+     <layout class="QGridLayout" name="gridLayout_4">
       <item row="0" column="0">
-       <widget class="QLabel" name="textLabel3">
+       <widget class="QLabel" name="textLabelFileName">
         <property name="sizePolicy">
+         <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>File Name</string>
+        </property>
+        <property name="indent">
+         <number>0</number>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QgsFileDropEdit" name="txtFilePath">
+        <property name="toolTip">
+         <string>Full path to the delimited text file</string>
+        </property>
+        <property name="whatsThis">
+         <string>Full path to the delimited text file. In order to properly parse the fields in the file, the delimiter must be defined prior to entering the file name. Use the Browse button to the right of this field to choose the input file.</string>
+        </property>
+        <property name="readOnly">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="textLabelLayerName">
+        <property name="sizePolicy">
          <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="text">
-         <string>Delimiter string</string>
+         <string>Layer name</string>
         </property>
-        <property name="buddy">
-         <cstring>txtDelimiter</cstring>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QLineEdit" name="txtLayerName">
+        <property name="toolTip">
+         <string>Name to display in the map legend</string>
         </property>
+        <property name="whatsThis">
+         <string>Name displayed in the map legend</string>
+        </property>
        </widget>
       </item>
+      <item row="0" column="3">
+       <widget class="QPushButton" name="btnBrowseForFile">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="toolTip">
+         <string>Browse to find the delimited text file to be processed</string>
+        </property>
+        <property name="whatsThis">
+         <string>Use this button to browse to the location of the delimited text file. This button will not be enabled until a delimiter has been entered in the &lt;i&gt;Delimiter&lt;/i&gt; box. Once a file is chosen, the X and Y field drop-down boxes will be populated with the fields from the delimited text file.</string>
+        </property>
+        <property name="text">
+         <string>Browse...</string>
+        </property>
+        <property name="flat">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QFrame" name="frame_select_delimiters">
+     <property name="enabled">
+      <bool>true</bool>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_5">
+      <item row="0" column="0">
+       <widget class="QRadioButton" name="delimiterSelection">
+        <property name="text">
+         <string>Selected delimiters</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QCheckBox" name="cbxDelimSemicolon">
+        <property name="text">
+         <string>Semicolon</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QCheckBox" name="cbxDelimTab">
+        <property name="text">
+         <string>Tab</string>
+        </property>
+       </widget>
+      </item>
       <item row="0" column="1">
+       <widget class="QCheckBox" name="cbxDelimSpace">
+        <property name="text">
+         <string>Space</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QCheckBox" name="cbxDelimComma">
+        <property name="text">
+         <string>Comma</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1">
+       <widget class="QCheckBox" name="cbxDelimColon">
+        <property name="text">
+         <string>Colon</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="0">
        <widget class="QLineEdit" name="txtDelimiter">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
         <property name="sizePolicy">
          <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -138,24 +184,30 @@
         </property>
        </widget>
       </item>
-      <item row="0" column="2">
-       <widget class="QLabel" name="label_2">
+      <item row="3" column="0">
+       <widget class="QRadioButton" name="delimiterRegexp">
         <property name="sizePolicy">
-         <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+         <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
+        <property name="toolTip">
+         <string>The delimiter is a regular expression</string>
+        </property>
+        <property name="whatsThis">
+         <string>The delimiter is a regular expression</string>
+        </property>
         <property name="text">
-         <string>Type</string>
+         <string>Regular expression</string>
         </property>
-        <property name="buddy">
-         <cstring>delimiterPlain</cstring>
-        </property>
        </widget>
       </item>
-      <item row="0" column="3">
+      <item row="2" column="0">
        <widget class="QRadioButton" name="delimiterPlain">
+        <property name="enabled">
+         <bool>true</bool>
+        </property>
         <property name="toolTip">
          <string>The delimiter is taken as is</string>
         </property>
@@ -165,18 +217,58 @@
         <property name="text">
          <string>Plain characters</string>
         </property>
+        <property name="checked">
+         <bool>false</bool>
+        </property>
        </widget>
       </item>
-      <item row="0" column="4">
-       <widget class="QRadioButton" name="delimiterRegexp">
-        <property name="toolTip">
-         <string>The delimiter is a regular expression</string>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="widget_5" native="true">
+     <property name="enabled">
+      <bool>true</bool>
+     </property>
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_6">
+      <item row="1" column="1">
+       <widget class="QSpinBox" name="rowCounter">
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>0</height>
+         </size>
         </property>
-        <property name="whatsThis">
-         <string>The delimiter is a regular expression</string>
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>16777215</height>
+         </size>
         </property>
+        <property name="wrapping">
+         <bool>false</bool>
+        </property>
+        <property name="value">
+         <number>0</number>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_4">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
         <property name="text">
-         <string>Regular expression</string>
+         <string>Start import at row</string>
         </property>
        </widget>
       </item>
@@ -184,22 +276,16 @@
     </widget>
    </item>
    <item>
-    <widget class="QGroupBox" name="groupBox_2">
-     <property name="title">
-      <string>Geometry</string>
-     </property>
+    <widget class="QWidget" name="widget_2" native="true">
      <layout class="QGridLayout" name="gridLayout_2">
-      <item row="0" column="0">
-       <widget class="QLabel" name="textLabel2">
+      <item row="0" column="2">
+       <widget class="QLabel" name="textLabelx">
         <property name="text">
          <string>&lt;p align=&quot;right&quot;&gt;X field&lt;/p&gt;</string>
         </property>
-        <property name="buddy">
-         <cstring>cmbXField</cstring>
-        </property>
        </widget>
       </item>
-      <item row="0" column="1">
+      <item row="0" column="3">
        <widget class="QComboBox" name="cmbXField">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@@ -224,7 +310,14 @@
         </property>
        </widget>
       </item>
-      <item row="0" column="4">
+      <item row="0" column="5">
+       <widget class="QLabel" name="textLabely">
+        <property name="text">
+         <string>&lt;p align=&quot;right&quot;&gt;Y field&lt;/p&gt;</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="6">
        <widget class="QComboBox" name="cmbYField">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@@ -249,16 +342,6 @@
         </property>
        </widget>
       </item>
-      <item row="0" column="3">
-       <widget class="QLabel" name="textLabel2_2">
-        <property name="text">
-         <string>&lt;p align=&quot;right&quot;&gt;Y field&lt;/p&gt;</string>
-        </property>
-        <property name="buddy">
-         <cstring>cmbYField</cstring>
-        </property>
-       </widget>
-      </item>
      </layout>
     </widget>
    </item>
@@ -267,17 +350,10 @@
      <property name="text">
       <string>Sample text</string>
      </property>
-     <property name="buddy">
-      <cstring>txtSample</cstring>
-     </property>
     </widget>
    </item>
    <item>
-    <widget class="QTextEdit" name="txtSample">
-     <property name="readOnly">
-      <bool>true</bool>
-     </property>
-    </widget>
+    <widget class="QTableWidget" name="tblSample"/>
    </item>
    <item>
     <widget class="QDialogButtonBox" name="buttonBox">
@@ -300,19 +376,109 @@
   </customwidget>
  </customwidgets>
  <tabstops>
-  <tabstop>txtFilePath</tabstop>
-  <tabstop>btnBrowseForFile</tabstop>
-  <tabstop>txtLayerName</tabstop>
-  <tabstop>txtDelimiter</tabstop>
-  <tabstop>delimiterPlain</tabstop>
-  <tabstop>delimiterRegexp</tabstop>
   <tabstop>cmbXField</tabstop>
   <tabstop>cmbYField</tabstop>
-  <tabstop>txtSample</tabstop>
   <tabstop>buttonBox</tabstop>
  </tabstops>
  <resources>
   <include location="delimited_text.qrc"/>
  </resources>
- <connections/>
+ <connections>
+  <connection>
+   <sender>delimiterSelection</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>cbxDelimSpace</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>91</x>
+     <y>121</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>282</x>
+     <y>115</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>delimiterSelection</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>cbxDelimTab</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>150</x>
+     <y>110</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>277</x>
+     <y>149</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>delimiterSelection</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>cbxDelimSemicolon</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>81</x>
+     <y>109</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>281</x>
+     <y>175</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>delimiterSelection</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>cbxDelimComma</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>59</x>
+     <y>114</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>293</x>
+     <y>203</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>delimiterSelection</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>txtDelimiter</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>109</x>
+     <y>114</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>118</x>
+     <y>218</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>delimiterSelection</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>cbxDelimColon</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>99</x>
+     <y>113</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>301</x>
+     <y>225</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
 </ui>

Modified: trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
===================================================================
--- trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp	2010-11-14 14:48:12 UTC (rev 14641)
+++ trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.cpp	2010-11-14 14:49:17 UTC (rev 14642)
@@ -151,19 +151,25 @@
   QString xField = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
   temp = parameters.filter( "yField=" );
   QString yField = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
+  temp = parameters.filter( "skipLines=" );
+  QString skipLines = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "0";
   // Decode the parts of the uri. Good if someone entered '=' as a delimiter, for instance.
   mFileName  = QUrl::fromPercentEncoding( mFileName.toUtf8() );
   mDelimiter = QUrl::fromPercentEncoding( mDelimiter.toUtf8() );
   mDelimiterType = QUrl::fromPercentEncoding( mDelimiterType.toUtf8() );
   xField    = QUrl::fromPercentEncoding( xField.toUtf8() );
   yField    = QUrl::fromPercentEncoding( yField.toUtf8() );
+  skipLines = QUrl::fromPercentEncoding( skipLines.toUtf8() );
 
+  mSkipLines = skipLines.toInt();
+
   QgsDebugMsg( "Data source uri is " + uri );
   QgsDebugMsg( "Delimited text file is: " + mFileName );
   QgsDebugMsg( "Delimiter is: " + mDelimiter );
   QgsDebugMsg( "Delimiter type is: " + mDelimiterType );
   QgsDebugMsg( "xField is: " + xField );
   QgsDebugMsg( "yField is: " + yField );
+  QgsDebugMsg( "skipLines is: " + QString::number( mSkipLines ) );
 
   // if delimiter contains some special characters, convert them
   if ( mDelimiterType == "regexp" )
@@ -221,6 +227,9 @@
     if ( line.isEmpty() )
       continue;
 
+    if ( lineNumber < mSkipLines + 1 )
+      continue;
+
     if ( !hasFields )
     {
       // Get the fields from the header row and store them in the
@@ -230,8 +239,7 @@
       // We don't know anything about a text based field other
       // than its name. All fields are assumed to be text
       int fieldPos = 0;
-      for ( QStringList::Iterator it = fieldList.begin();
-            it != fieldList.end(); ++it )
+      for ( QStringList::Iterator it = fieldList.begin(); it != fieldList.end(); ++it )
       {
         QString field = *it;
         if ( field.length() > 0 )
@@ -401,7 +409,7 @@
 
     feature.setFeatureId( mFid );
 
-    QByteArray  buffer;
+    QByteArray buffer;
     QDataStream s( &buffer, static_cast<QIODevice::OpenMode>( QIODevice::WriteOnly ) ); // open on buffers's data
 
     switch ( QgsApplication::endian() )
@@ -562,7 +570,9 @@
   // Skip ahead one line since first record is always assumed to be
   // the header record
   mStream->seek( 0 );
-  readLine( mStream );
+  int n = mSkipLines + 1;
+  while ( n-- )
+    readLine( mStream );
 }
 
 bool QgsDelimitedTextProvider::isValid()

Modified: trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h
===================================================================
--- trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h	2010-11-14 14:48:12 UTC (rev 14641)
+++ trunk/qgis/src/providers/delimitedtext/qgsdelimitedtextprovider.h	2010-11-14 14:49:17 UTC (rev 14642)
@@ -201,6 +201,7 @@
     int mGeomType;
 
     long mNumberFeatures;
+    int mSkipLines;
 
     //! Storage for any lines in the file that couldn't be loaded
     QStringList mInvalidLines;



More information about the QGIS-commit mailing list