Beispiel #1
0
void QgsLabelDialog::init( )
{
  QgsDebugMsg( "entering." );

  QgsLabelAttributes * myLabelAttributes = mLabel->labelAttributes();
  //populate a string list with all the field names which will be used to set up the
  //data bound combos
  QgsFieldMap& myFieldsMap = mLabel->fields();
  QStringList myFieldStringList;
  myFieldStringList.append( "" );
  for ( QgsFieldMap::iterator it = myFieldsMap.begin(); it != myFieldsMap.end(); ++it )
  {
    myFieldStringList.append( it->name() );
  }
  //
  //now set all the combos that need field lists using the string list
  //
  cboLabelField->clear();
  cboLabelField->addItems( myFieldStringList );
  cboLabelField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Text ), myFieldStringList ) );

  cboFontField->clear();
  cboFontField->addItems( myFieldStringList );
  cboFontField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Family ), myFieldStringList ) );

  cboBoldField->clear();
  cboBoldField->addItems( myFieldStringList );
  cboBoldField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Bold ), myFieldStringList ) );


  cboItalicField->clear();
  cboItalicField->addItems( myFieldStringList );
  cboItalicField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Italic ), myFieldStringList ) );

  cboUnderlineField->clear();
  cboUnderlineField->addItems( myFieldStringList );
  cboUnderlineField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Underline ), myFieldStringList ) );

  cboStrikeOutField->clear();
  cboStrikeOutField->addItems( myFieldStringList );
  cboStrikeOutField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::StrikeOut ), myFieldStringList ) );

  cboFontSizeField->clear();
  cboFontSizeField->addItems( myFieldStringList );
  cboFontSizeField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Size ), myFieldStringList ) );

  cboFontSizeTypeField->clear();
  cboFontSizeTypeField->addItems( myFieldStringList );
  cboFontSizeTypeField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::SizeType ), myFieldStringList ) );

#if 0
  cboFontTransparencyField->clear();
  cboFontTransparencyField->addItems( myFieldStringList );
  cboFontTransparencyField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::FontTransparency ), myFieldStringList ) );
#endif

  cboFontColorField->clear();
  cboFontColorField->addItems( myFieldStringList );
  cboFontColorField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Color ), myFieldStringList ) );


  cboBufferSizeField->clear();
  cboBufferSizeField->addItems( myFieldStringList );
  cboBufferSizeField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::BufferSize ), myFieldStringList ) );

  cboBufferTransparencyField->clear();
  cboBufferTransparencyField->addItems( myFieldStringList );
  //cboBufferTransparencyField->setCurrentIndex(itemNoForField(mLabel->labelField(QgsLabel::BufferTransparency),myFieldStringList));

  cboXCoordinateField->clear();
  cboXCoordinateField->addItems( myFieldStringList );
  cboXCoordinateField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::XCoordinate ), myFieldStringList ) );

  cboYCoordinateField->clear();
  cboYCoordinateField->addItems( myFieldStringList );
  cboYCoordinateField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::YCoordinate ), myFieldStringList ) );

  cboXOffsetField->clear();
  cboXOffsetField->addItems( myFieldStringList );
  cboXOffsetField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::XOffset ), myFieldStringList ) );

  cboYOffsetField->clear();
  cboYOffsetField->addItems( myFieldStringList );
  cboYOffsetField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::YOffset ), myFieldStringList ) );

  cboAlignmentField->clear();
  cboAlignmentField->addItems( myFieldStringList );
  cboAlignmentField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Alignment ), myFieldStringList ) );

  cboAngleField->clear();
  cboAngleField->addItems( myFieldStringList );
  cboAngleField->setCurrentIndex( itemNoForField( mLabel->labelField( QgsLabel::Angle ), myFieldStringList ) );

  // set up the scale based layer visibility stuff....
  chkUseScaleDependentRendering->setChecked( mLabel->scaleBasedVisibility() );
  leMinimumScale->setText( QString::number( mLabel->minScale(), 'f' ) );
  leMinimumScale->setValidator( new QDoubleValidator( 0, std::numeric_limits<float>::max(), 1000, this ) );
  leMaximumScale->setText( QString::number( mLabel->maxScale(), 'f' ) );
  leMaximumScale->setValidator( new QDoubleValidator( 0, std::numeric_limits<float>::max(), 1000, this ) );

  //
  //set the non-databound fields up now
  //
  leDefaultLabel->setText( myLabelAttributes->text() );
  mFont.setFamily( myLabelAttributes->family() );
  if ( myLabelAttributes->sizeIsSet() )
  {
    mFont.setPointSizeF( myLabelAttributes->size() );

    int myTypeInt = myLabelAttributes->sizeType();
    cboFontSizeUnits->setCurrentIndex( myTypeInt == QgsLabelAttributes::PointUnits ? 0 : 1 );
  }
  else //defaults for when no size has been set
  {
    mFont.setPointSizeF( myLabelAttributes->size() );
    cboFontSizeUnits->setCurrentIndex( 0 );
  }

  spinFontSize->setValue( myLabelAttributes->size() );

  if ( myLabelAttributes->boldIsSet() )
  {
    mFont.setBold( myLabelAttributes->bold() );
  }
  else
  {
    mFont.setBold( false );
  }
  if ( myLabelAttributes->italicIsSet() )
  {
    mFont.setItalic( myLabelAttributes->italic() );
  }
  else
  {
    mFont.setItalic( false );
  }
  if ( myLabelAttributes->underlineIsSet() )
  {
    mFont.setUnderline( myLabelAttributes->underline() );
  }
  else
  {
    mFont.setUnderline( false );
  }
  if ( myLabelAttributes->strikeOutIsSet() )
  {
    mFont.setStrikeOut( myLabelAttributes->strikeOut() );
  }
  else
  {
    mFont.setStrikeOut( false );
  }

  mFontColor = myLabelAttributes->color();

  if ( myLabelAttributes->offsetIsSet() )
  {
    int myTypeInt = myLabelAttributes->offsetType();
    cboOffsetUnits->setCurrentIndex( myTypeInt == QgsLabelAttributes::PointUnits ? 0 : 1 );
    spinXOffset->setValue( myLabelAttributes->xOffset() );
    spinYOffset->setValue( myLabelAttributes->yOffset() );
  }
  else //defaults for when no offset is defined
  {
    cboOffsetUnits->setCurrentIndex( 0 );
    spinXOffset->setValue( 0 );
    spinYOffset->setValue( 0 );
  }
  spinAngle->setRange( -1, 360 );
  spinAngle->setSpecialValueText( tr( "Auto" ) );
  if ( myLabelAttributes->angleIsAuto() )
  {
    spinAngle->setValue( -1 );
  }
  else
  {
    spinAngle->setValue( static_cast<int>( myLabelAttributes->angle() ) );
  }

  //the values here may seem a bit counterintuitive - basically everything
  //is the reverse of the way you think it should be...
  //TODO investigate in QgsLabel why this needs to be the case
  //TODO add support for corners (e.g. bottom right) to xml serialiser

  if ( myLabelAttributes->alignment() == ( Qt::AlignRight | Qt::AlignBottom ) ) radioAboveLeft->setChecked( true )   ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignRight | Qt::AlignTop ) ) radioBelowLeft->setChecked( true )   ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignLeft  | Qt::AlignBottom ) ) radioAboveRight->setChecked( true )  ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignLeft  | Qt::AlignTop ) ) radioBelowRight->setChecked( true )  ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignRight | Qt::AlignVCenter ) ) radioLeft->setChecked( true )        ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignLeft  | Qt::AlignVCenter ) ) radioRight->setChecked( true )       ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignBottom | Qt::AlignHCenter ) ) radioAbove->setChecked( true )       ;
  if ( myLabelAttributes->alignment() == ( Qt::AlignTop   | Qt::AlignHCenter ) ) radioBelow->setChecked( true )       ;
  if ( myLabelAttributes->alignment() == Qt::AlignCenter ) radioOver->setChecked( true )        ;

  mBufferColor = myLabelAttributes->bufferColor();
  //note that it could be that buffer properties are set, but the bufer is disabled
  if ( myLabelAttributes->bufferSizeIsSet() )
  {
    int myTypeInt = myLabelAttributes->bufferSizeType();
    cboBufferSizeUnits->setCurrentIndex( myTypeInt == QgsLabelAttributes::PointUnits ? 0 : 1 );
    spinBufferSize->setValue( myLabelAttributes->bufferSize() );
  }
  else //defaults for when no offset is defined
  {
    cboBufferSizeUnits->setCurrentIndex( 0 );
    spinBufferSize->setValue( 1 );
  }
  //set the state of the multiline enabled checkbox
  chkUseMultiline->setChecked( myLabelAttributes->multilineEnabled() );
  //set the state of the selected features only checkbox
  chkSelectedOnly->setChecked( myLabelAttributes->selectedOnly() );
  //set the state of the buffer enabled checkbox
  chkUseBuffer->setChecked( myLabelAttributes->bufferEnabled() );

  //NOTE: do we need this line too? TS
  spinBufferSize->setValue( myLabelAttributes->bufferSize() );
}
QgsDelimitedTextProvider::QgsDelimitedTextProvider( QString uri )
    : QgsVectorDataProvider( uri )
    , mDelimiter( "," )
    , mDelimiterType( "plain" )
    , mFieldCount( 0 )
    , mXFieldIndex( -1 )
    , mYFieldIndex( -1 )
    , mWktFieldIndex( -1 )
    , mWktHasZM( false )
    , mWktZMRegexp( "\\s+(?:z|m|zm)(?=\\s*\\()", Qt::CaseInsensitive )
    , mWktCrdRegexp( "(\\-?\\d+(?:\\.\\d*)?\\s+\\-?\\d+(?:\\.\\d*)?)\\s[\\s\\d\\.\\-]+" )
    , mFile( 0 )
    , mStream( 0 )
    , mSkipLines( 0 )
    , mFirstDataLine( 0 )
    , mShowInvalidLines( false )
    , mCrs()
    , mWkbType( QGis::WKBUnknown )
{
  QUrl url = QUrl::fromEncoded( uri.toAscii() );

  // Extract the provider definition from the url
  mFileName = url.toLocalFile();

  QString wktField;
  QString xField;
  QString yField;

  if ( url.hasQueryItem( "delimiter" ) )
    mDelimiter = url.queryItemValue( "delimiter" );
  if ( url.hasQueryItem( "delimiterType" ) )
    mDelimiterType = url.queryItemValue( "delimiterType" );
  if ( url.hasQueryItem( "wktField" ) )
    wktField = url.queryItemValue( "wktField" );
  if ( url.hasQueryItem( "xField" ) )
    xField = url.queryItemValue( "xField" );
  if ( url.hasQueryItem( "yField" ) )
    yField = url.queryItemValue( "yField" );
  if ( url.hasQueryItem( "skipLines" ) )
    mSkipLines = url.queryItemValue( "skipLines" ).toInt();
  if ( url.hasQueryItem( "crs" ) )
    mCrs.createFromString( url.queryItemValue( "crs" ) );
  if ( url.hasQueryItem( "decimalPoint" ) )
    mDecimalPoint = url.queryItemValue( "decimalPoint" );

  QgsDebugMsg( "Data source uri is " + uri );
  QgsDebugMsg( "Delimited text file is: " + mFileName );
  QgsDebugMsg( "Delimiter is: " + mDelimiter );
  QgsDebugMsg( "Delimiter type is: " + mDelimiterType );
  QgsDebugMsg( "wktField is: " + wktField );
  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" )
    mDelimiter.replace( "\\t", "\t" ); // replace "\t" with a real tabulator

  // Set the selection rectangle to null
  mSelectionRectangle = QgsRectangle();
  // assume the layer is invalid until proven otherwise
  mValid = false;
  if ( mFileName.isEmpty() || mDelimiter.isEmpty() )
  {
    // uri is invalid so the layer must be too...
    QgsDebugMsg( "Data source is invalid" );
    return;
  }

  // check to see that the file exists and perform some sanity checks
  if ( !QFile::exists( mFileName ) )
  {
    QgsDebugMsg( "Data source " + dataSourceUri() + " doesn't exist" );
    return;
  }

  // Open the file and get number of rows, etc. We assume that the
  // file has a header row and process accordingly. Caller should make
  // sure that the delimited file is properly formed.
  mFile = new QFile( mFileName );
  if ( !mFile->open( QIODevice::ReadOnly ) )
  {
    QgsDebugMsg( "Data source " + dataSourceUri() + " could not be opened" );
    delete mFile;
    mFile = 0;
    return;
  }

  // now we have the file opened and ready for parsing

  // set the initial extent
  mExtent = QgsRectangle();

  QMap<int, bool> couldBeInt;
  QMap<int, bool> couldBeDouble;

  mStream = new QTextStream( mFile );
  QString line;
  mNumberFeatures = 0;
  int lineNumber = 0;
  bool hasFields = false;
  while ( !mStream->atEnd() )
  {
    lineNumber++;
    line = readLine( mStream ); // line of text excluding '\n', default local 8 bit encoding.

    if ( lineNumber < mSkipLines + 1 )
      continue;

    if ( line.isEmpty() )
      continue;

    if ( !hasFields )
    {
      // Get the fields from the header row and store them in the
      // fields vector
      QStringList fieldList = splitLine( line );

      mFieldCount = fieldList.count();

      // 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 ( int column = 0; column < mFieldCount; column++ )
      {
        QString field = fieldList[column];

        if (( field.left( 1 ) == "'" || field.left( 1 ) == "\"" ) &&
            field.left( 1 ) == field.right( 1 ) )
          // eat quotes
          field = field.mid( 1, field.length() - 2 );

        if ( field.length() == 0 )
          // skip empty field names
          continue;

        // check to see if this field matches either the x or y field
        if ( !wktField.isEmpty() && wktField == field )
        {
          QgsDebugMsg( "Found wkt field: " + ( field ) );
          mWktFieldIndex = column;
        }
        else if ( !xField.isEmpty() && xField == field )
        {
          QgsDebugMsg( "Found x field: " + ( field ) );
          mXFieldIndex = column;
        }
        else if ( !yField.isEmpty() && yField == field )
        {
          QgsDebugMsg( "Found y field: " + ( field ) );
          mYFieldIndex = column;
        }

        // WKT geometry field won't be displayed in attribute tables
        if ( column == mWktFieldIndex )
          continue;

        QgsDebugMsg( "Adding field: " + ( field ) );
        // assume that the field could be integer or double
        // for now, let's set field type as text
        attributeColumns.append( column );
        attributeFields[fieldPos] = QgsField( field, QVariant::String, "Text" );
        couldBeInt.insert( fieldPos, true );
        couldBeDouble.insert( fieldPos, true );
        fieldPos++;
      }
      if ( mWktFieldIndex >= 0 )
      {
        mXFieldIndex = -1;
        mYFieldIndex = -1;
      }
      QgsDebugMsg( "wktfield index: " + QString::number( mWktFieldIndex ) );
      QgsDebugMsg( "xfield index: " + QString::number( mXFieldIndex ) );
      QgsDebugMsg( "yfield index: " + QString::number( mYFieldIndex ) );
      QgsDebugMsg( "Field count for the delimited text file is " + QString::number( attributeFields.size() ) );
      hasFields = true;
    }
    else // hasFields == true - field names already read
    {
      if ( mFirstDataLine == 0 )
        mFirstDataLine = lineNumber;

      // split the line on the delimiter
      QStringList parts = splitLine( line );

      // Ensure that the input has at least the required number of fields (mainly to tolerate
      // missed blank strings at end of row)
      while ( parts.size() < mFieldCount )
        parts.append( QString::null );

      if ( mWktFieldIndex >= 0 )
      {
        // Get the wkt - confirm it is valid, get the type, and
        // if compatible with the rest of file, add to the extents

        QString sWkt = parts[mWktFieldIndex];
        QgsGeometry *geom = 0;
        try
        {
          if ( !mWktHasZM && sWkt.indexOf( mWktZMRegexp ) >= 0 )
            mWktHasZM = true;
          if ( mWktHasZM )
          {
            sWkt.remove( mWktZMRegexp ).replace( mWktCrdRegexp, "\\1" );
          }
          geom = QgsGeometry::fromWkt( sWkt );
        }
        catch ( ... )
        {
          mInvalidLines << line;
          geom = 0;
        }

        if ( geom )
        {
          QGis::WkbType type = geom->wkbType();
          if ( type != QGis::WKBNoGeometry )
          {
            if ( mNumberFeatures == 0 )
            {
              mNumberFeatures++;
              mWkbType = type;
              mExtent = geom->boundingBox();
            }
            else if ( type == mWkbType )
            {
              mNumberFeatures++;
              QgsRectangle bbox( geom->boundingBox() );
              mExtent.combineExtentWith( &bbox );
            }
          }
          delete geom;
        }
      }
      else if ( mWktFieldIndex == -1 && mXFieldIndex >= 0 && mYFieldIndex >= 0 )
      {
        // Get the x and y values, first checking to make sure they
        // aren't null.

        QString sX = parts[mXFieldIndex];
        QString sY = parts[mYFieldIndex];


        if ( !mDecimalPoint.isEmpty() )
        {
          sX.replace( mDecimalPoint, "." );
          sY.replace( mDecimalPoint, "." );
        }

        bool xOk = false;
        bool yOk = false;
        double x = sX.toDouble( &xOk );
        double y = sY.toDouble( &yOk );

        if ( xOk && yOk )
        {
          if ( mNumberFeatures > 0 )
          {
            mExtent.combineExtentWith( x, y );
          }
          else
          {
            // Extent for the first point is just the first point
            mExtent.set( x, y, x, y );
            mWkbType = QGis::WKBPoint;
          }
          mNumberFeatures++;
        }
        else
        {
          mInvalidLines << line;
        }
      }
      else
      {
        mWkbType = QGis::WKBNoGeometry;
        mNumberFeatures++;
      }

      for ( int i = 0; i < attributeFields.size(); i++ )
      {
        QString &value = parts[attributeColumns[i]];
        if ( value.isEmpty() )
          continue;
        // try to convert attribute values to integer and double
        if ( couldBeInt[i] )
        {
          value.toInt( &couldBeInt[i] );
        }
        if ( couldBeDouble[i] )
        {
          value.toDouble( &couldBeDouble[i] );
        }
      }
    }
  }

  QgsDebugMsg( "geometry type is: " + QString::number( mWkbType ) );
  QgsDebugMsg( "feature count is: " + QString::number( mNumberFeatures ) );

  // now it's time to decide the types for the fields
  for ( QgsFieldMap::iterator it = attributeFields.begin(); it != attributeFields.end(); ++it )
  {
    if ( couldBeInt[it.key()] )
    {
      it->setType( QVariant::Int );
      it->setTypeName( "integer" );
    }
    else if ( couldBeDouble[it.key()] )
    {
      it->setType( QVariant::Double );
      it->setTypeName( "double" );
    }
  }

  mValid = mWkbType != QGis::WKBUnknown;
}
QgsDelimitedTextProvider::QgsDelimitedTextProvider( QString uri )
    : QgsVectorDataProvider( uri ),
    mXFieldIndex( -1 ), mYFieldIndex( -1 ),
    mShowInvalidLines( true )
{
  // Get the file name and mDelimiter out of the uri
  mFileName = uri.left( uri.indexOf( "?" ) );
  // split the string up on & to get the individual parameters
  QStringList parameters = uri.mid( uri.indexOf( "?" ) ).split( "&", QString::SkipEmptyParts );

  QgsDebugMsg( "Parameter count after split on &" + QString::number( parameters.size() ) );

  // get the individual parameters and assign values
  QStringList temp = parameters.filter( "delimiter=" );
  mDelimiter = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
  temp = parameters.filter( "delimiterType=" );
  mDelimiterType = temp.size() ? temp[0].mid( temp[0].indexOf( "=" ) + 1 ) : "";
  temp = parameters.filter( "xField=" );
  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 ) : "";
  // 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() );

  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 );

  // if delimiter contains some special characters, convert them
  if ( mDelimiterType == "regexp" )
    mDelimiterRegexp = QRegExp( mDelimiter );
  else
    mDelimiter.replace( "\\t", "\t" ); // replace "\t" with a real tabulator

  // Set the selection rectangle to null
  mSelectionRectangle = QgsRectangle();
  // assume the layer is invalid until proven otherwise
  mValid = false;
  if ( mFileName.isEmpty() || mDelimiter.isEmpty() || xField.isEmpty() || yField.isEmpty() )
  {
    // uri is invalid so the layer must be too...
    QString( "Data source is invalid" );
    return;
  }

  // check to see that the file exists and perform some sanity checks
  if ( !QFile::exists( mFileName ) )
  {
    QgsDebugMsg( "Data source " + dataSourceUri() + " doesn't exist" );
    return;
  }

  // Open the file and get number of rows, etc. We assume that the
  // file has a header row and process accordingly. Caller should make
  // sure the the delimited file is properly formed.
  mFile = new QFile( mFileName );
  if ( !mFile->open( QIODevice::ReadOnly ) )
  {
    QgsDebugMsg( "Data source " + dataSourceUri() + " could not be opened" );
    delete mFile;
    return;
  }

  // now we have the file opened and ready for parsing

  // set the initial extent
  mExtent = QgsRectangle();

  QMap<int, bool> couldBeInt;
  QMap<int, bool> couldBeDouble;

  mStream = new QTextStream( mFile );
  QString line;
  mNumberFeatures = 0;
  int lineNumber = 0;
  bool firstPoint = true;
  bool hasFields = false;
  while ( !mStream->atEnd() )
  {
    lineNumber++;
    line = mStream->readLine(); // line of text excluding '\n', default local 8 bit encoding.
    if ( !hasFields )
    {
      // Get the fields from the header row and store them in the
      // fields vector
      QgsDebugMsg( "Attempting to split the input line: " + line + " using delimiter " + mDelimiter );

      QStringList fieldList;
      if ( mDelimiterType == "regexp" )
        fieldList = line.split( mDelimiterRegexp );
      else
        fieldList = line.split( mDelimiter );
      QgsDebugMsg( "Split line into " + QString::number( fieldList.size() ) + " parts" );

      // 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 )
      {
        QString field = *it;
        if ( field.length() > 0 )
        {
          // for now, let's set field type as text
          attributeFields[fieldPos] = QgsField( *it, QVariant::String, "Text" );

          // check to see if this field matches either the x or y field
          if ( xField == *it )
          {
            QgsDebugMsg( "Found x field: " + ( *it ) );
            mXFieldIndex = fieldPos;
          }
          else if ( yField == *it )
          {
            QgsDebugMsg( "Found y field: " + ( *it ) );
            mYFieldIndex = fieldPos;
          }

          QgsDebugMsg( "Adding field: " + ( *it ) );
          // assume that the field could be integer or double
          couldBeInt.insert( fieldPos, true );
          couldBeDouble.insert( fieldPos, true );
          fieldPos++;
        }
      }
      QgsDebugMsg( "Field count for the delimited text file is " + QString::number( attributeFields.size() ) );
      hasFields = true;
    }
    else if ( mXFieldIndex != -1 && mYFieldIndex != -1 )
    {
      mNumberFeatures++;

      // split the line on the delimiter
      QStringList parts;
      if ( mDelimiterType == "regexp" )
        parts = line.split( mDelimiterRegexp );
      else
        parts = line.split( mDelimiter );

      // Skip malformed lines silently. Report line number with nextFeature()
      if ( attributeFields.size() != parts.size() )
      {
        continue;
      }

      // Get the x and y values, first checking to make sure they
      // aren't null.
      QString sX = parts[mXFieldIndex];
      QString sY = parts[mYFieldIndex];

      bool xOk = true;
      bool yOk = true;
      double x = sX.toDouble( &xOk );
      double y = sY.toDouble( &yOk );

      if ( xOk && yOk )
      {
        if ( !firstPoint )
        {
          mExtent.combineExtentWith( x, y );
        }
        else
        { // Extent for the first point is just the first point
          mExtent.set( x, y, x, y );
          firstPoint = false;
        }
      }

      int i = 0;
      for ( QStringList::iterator it = parts.begin(); it != parts.end(); ++it, ++i )
      {
        // try to convert attribute values to integer and double
        if ( couldBeInt[i] )
        {
          it->toInt( &couldBeInt[i] );
        }
        if ( couldBeDouble[i] )
        {
          it->toDouble( &couldBeDouble[i] );
        }
      }
    }
  }

  // now it's time to decide the types for the fields
  for ( QgsFieldMap::iterator it = attributeFields.begin(); it != attributeFields.end(); ++it )
  {
    if ( couldBeInt[it.key()] )
    {
      it->setType( QVariant::Int );
      it->setTypeName( "integer" );
    }
    else if ( couldBeDouble[it.key()] )
    {
      it->setType( QVariant::Double );
      it->setTypeName( "double" );
    }
  }

  if ( mXFieldIndex != -1 && mYFieldIndex != -1 )
  {
    QgsDebugMsg( "Data store is valid" );
    QgsDebugMsg( "Number of features " + QString::number( mNumberFeatures ) );
    QgsDebugMsg( "Extents " + mExtent.toString() );

    mValid = true;
  }
  else
  {
    QgsDebugMsg( "Data store is invalid. Specified x,y fields do not match those in the database" );
  }
  QgsDebugMsg( "Done checking validity" );

}