QStringList QgsDelimitedTextSourceSelect::splitLine( QString line )
{
  QString delimiter;
  if ( delimiterSelection->isChecked() )
  {
    if ( selectedChars().size() > 1 )
    {
      delimiter = "[" + selectedChars().join( "" ) + "]";
    }
    else
    {
      delimiter = selectedChars().join( "" );
    }
    txtDelimiter->setText( delimiter );
  }
  else
  {
    delimiter = txtDelimiter->text();
  }

  if ( delimiterPlain->isChecked() )
  {
    return QgsDelimitedTextProvider::splitLine( line, "plain", delimiter );
  }

  if ( delimiterSelection->isChecked() && selectedChars().size() <= 1 )
  {
    return QgsDelimitedTextProvider::splitLine( line, "plain", delimiter );
  }

  return QgsDelimitedTextProvider::splitLine( line, "regexp", delimiter );
}
void QgsDelimitedTextSourceSelect::saveSettings( QString subkey, bool saveGeomSettings )
{
  QSettings settings;
  QString key = mPluginKey;
  if ( ! subkey.isEmpty() ) key.append( "/" ).append( subkey );
  settings.setValue( key + "/encoding", cmbEncoding->currentText() );
  settings.setValue( key + "/geometry", saveGeometry() );

  if ( delimiterCSV->isChecked() )
    settings.setValue( key + "/delimiterType", "csv" );
  else if ( delimiterChars->isChecked() )
    settings.setValue( key + "/delimiterType", "chars" );
  else
    settings.setValue( key + "/delimiterType", "regexp" );
  settings.setValue( key + "/delimiters", selectedChars() );
  settings.setValue( key + "/quoteChars", txtQuoteChars->text() );
  settings.setValue( key + "/escapeChars", txtEscapeChars->text() );
  settings.setValue( key + "/delimiterRegexp", txtDelimiterRegexp->text() );
  settings.setValue( key + "/startFrom", rowCounter->value() );
  settings.setValue( key + "/useHeader", cbxUseHeader->isChecked() ? "true" : "false" );
  settings.setValue( key + "/trimFields", cbxTrimFields->isChecked() ? "true" : "false" );
  settings.setValue( key + "/skipEmptyFields", cbxSkipEmptyFields->isChecked() ? "true" : "false" );
  settings.setValue( key + "/decimalPoint", cbxPointIsComma->isChecked() ? "," : "." );
  if ( saveGeomSettings )
  {
    QString geomColumnType = "none";
    if ( geomTypeXY->isChecked() ) geomColumnType = "xy";
    if ( geomTypeWKT->isChecked() ) geomColumnType = "wkt";
    settings.setValue( key + "/geomColumnType", geomColumnType );
    settings.setValue( key + "/xyDms", cbxXyDms->isChecked() ? "true" : "false" );
  }

}
bool QgsDelimitedTextSourceSelect::loadDelimitedFileDefinition()
{
  mFile->setFileName( txtFilePath->text() );
  mFile->setEncoding( cmbEncoding->currentText() );
  if ( delimiterChars->isChecked() )
  {
    mFile->setTypeCSV( selectedChars(), txtQuoteChars->text(), txtEscapeChars->text() );
  }
  else if ( delimiterRegexp->isChecked() )
  {
    mFile->setTypeRegexp( txtDelimiterRegexp->text() );
  }
  else
  {
    mFile->setTypeCSV();
  }
  mFile->setSkipLines( rowCounter->value() );
  mFile->setUseHeader( cbxUseHeader->isChecked() );
  mFile->setDiscardEmptyFields( cbxSkipEmptyFields->isChecked() );
  mFile->setTrimFields( cbxTrimFields->isChecked() );
  return mFile->isValid();
}
bool QgsDelimitedTextSourceSelect::validate()
{
  // Check that input data is valid - provide a status message if not..

  QString message( "" );
  bool enabled = false;

  if ( txtFilePath->text().trimmed().isEmpty() )
  {
    message = tr( "Please select an input file" );
  }
  else if ( ! QFileInfo( txtFilePath->text() ).exists() )
  {
    message = tr( "File %1 does not exist" ).arg( txtFilePath->text() );
  }
  else if ( txtLayerName->text().isEmpty() )
  {
    message = tr( "Please enter a layer name" );
  }
  else if ( delimiterChars->isChecked() && selectedChars().size() == 0 )
  {
    message = tr( "At least one delimiter character must be specified" );
  }

  if ( message.isEmpty() && delimiterRegexp->isChecked() )
  {
    QRegExp re( txtDelimiterRegexp->text() );
    if ( ! re.isValid() )
    {
      message = tr( "Regular expression is not valid" );
    }
    else if ( re.pattern().startsWith( "^" ) && re.captureCount() == 0 )
    {
      message = tr( "^.. expression needs capture groups" );
    }
    lblRegexpError->setText( message );
  }
  if ( ! message.isEmpty() )
  {
    // continue...
  }
  // Hopefully won't hit this none-specific message, but just in case ...
  else if ( ! mFile->isValid() )
  {
    message = tr( "Definition of filename and delimiters is not valid" );
  }
  // Assume that the sample table will have been populated if data was found
  else if ( tblSample->rowCount() == 0 )
  {
    message = tr( "No data found in file" );
    if ( mBadRowCount > 0 )
    {
      message = message + " (" + tr( "%1 badly formatted records discarded" ).arg( mBadRowCount ) + ")";
    }
  }
  else if ( geomTypeXY->isChecked() && ( cmbXField->currentText().isEmpty()  || cmbYField->currentText().isEmpty() ) )
  {
    message = tr( "X and Y field names must be selected" );
  }
  else if ( geomTypeXY->isChecked() && ( cmbXField->currentText() == cmbYField->currentText() ) )
  {
    message = tr( "X and Y field names cannot be the same" );
  }
  else if ( geomTypeWKT->isChecked() && cmbWktField->currentText().isEmpty() )
  {
    message = tr( "The WKT field name must be selected" );
  }
  else
  {
    enabled = true;
    if ( mBadRowCount > 0 )
    {
      message = tr( "%1 badly formatted records discarded from sample data" ).arg( mBadRowCount );
    }

  }
  lblStatus->setText( message );
  return enabled;
}
void QgsDelimitedTextSourceSelect::on_buttonBox_accepted()
{
  // The following conditions should not be hit! OK will not be enabled...
  if ( txtLayerName->text().isEmpty() )
  {
    QMessageBox::warning( this, tr( "No layer name" ), tr( "Please enter a layer name before adding the layer to the map" ) );
    txtLayerName->setFocus();
    return;
  }
  if ( delimiterChars->isChecked() )
  {
    if ( selectedChars().size() == 0 )
    {
      QMessageBox::warning( this, tr( "No delimiters set" ), tr( "Please one or more characters to use as the delimiter, or choose a different delimiter type" ) );
      txtDelimiterOther->setFocus();
      return;
    }
  }
  if ( delimiterRegexp->isChecked() )
  {
    QRegExp re( txtDelimiterRegexp->text() );
    if ( ! re.isValid() )
    {
      QMessageBox::warning( this, tr( "Invalid regular expression" ), tr( "Please enter a valid regular expression as the delimiter, or choose a different delimiter type" ) );
      txtDelimiterRegexp->setFocus();
      return;
    }
  }
  if ( ! mFile->isValid() )
  {
    QMessageBox::warning( this, tr( "Invalid delimited text file" ), tr( "Please enter a valid file and delimiter" ) );
    return;
  }

  //Build the delimited text URI from the user provided information

  QUrl url = mFile->url();

  if ( cbxPointIsComma->isChecked() )
  {
    url.addQueryItem( "decimalPoint", "," );
  }
  if ( cbxXyDms->isChecked() )
  {
    url.addQueryItem( "xyDms", "yes" );
  }

  if ( geomTypeXY->isChecked() )
  {
    if ( !cmbXField->currentText().isEmpty() && !cmbYField->currentText().isEmpty() )
    {
      QString field = cmbXField->currentText();
      url.addQueryItem( "xField", field );
      field = cmbYField->currentText();
      url.addQueryItem( "yField", field );
    }
  }
  else if ( geomTypeWKT->isChecked() )
  {
    if ( ! cmbWktField->currentText().isEmpty() )
    {
      QString field = cmbWktField->currentText();
      url.addQueryItem( "wktField", field );
    }
    if ( cmbGeometryType->currentIndex() > 0 )
    {
      url.addQueryItem( "geomType", cmbGeometryType->currentText() );
    }
  }
  else
  {
    url.addQueryItem( "geomType", "none" );
  }

  // store the settings
  saveSettings();
  saveSettingsForFile( txtFilePath->text() );


  // add the layer to the map
  emit addVectorLayer( QString::fromAscii( url.toEncoded() ), txtLayerName->text(), "delimitedtext" );

  accept();
}
void QgsDelimitedTextSourceSelect::on_buttonBox_accepted()
{
  if ( !txtLayerName->text().isEmpty() )
  {
    //Build the delimited text URI from the user provided information
    QString delimiterType;
    if ( delimiterSelection->isChecked() )
      delimiterType = ( selectedChars().size() <= 1 ) ? "plain" : "regexp";
    else if ( delimiterPlain->isChecked() )
      delimiterType = "plain";
    else if ( delimiterRegexp->isChecked() )
      delimiterType = "regexp";

    QUrl url = QUrl::fromLocalFile( txtFilePath->text() );
    url.addQueryItem( "delimiter", txtDelimiter->text() );
    url.addQueryItem( "delimiterType", delimiterType );

    if ( !decimalPoint->text().isEmpty() )
    {
      url.addQueryItem( "decimalPoint", decimalPoint->text() );
    }

    if ( geomTypeXY->isChecked() )
    {
      if ( !cmbXField->currentText().isEmpty() && !cmbYField->currentText().isEmpty() )
      {
        url.addQueryItem( "xField", cmbXField->currentText() );
        url.addQueryItem( "yField", cmbYField->currentText() );
      }
    }
    else
    {
      if ( ! cmbWktField->currentText().isEmpty() )
      {
        url.addQueryItem( "wktField", cmbWktField->currentText() );
      }
    }

    int skipLines = rowCounter->value();
    if ( skipLines > 0 )
      url.addQueryItem( "skipLines", QString( "%1" ).arg( skipLines ) );

    // add the layer to the map
    emit addVectorLayer( QString::fromAscii( url.toEncoded() ), txtLayerName->text(), "delimitedtext" );

    // store the settings
    QSettings settings;
    QString key = "/Plugin-DelimitedText";
    settings.setValue( key + "/geometry", saveGeometry() );
    settings.setValue( key + "/delimiter", txtDelimiter->text() );
    QFileInfo fi( txtFilePath->text() );
    settings.setValue( key + "/text_path", fi.path() );
    settings.setValue( key + "/startFrom", rowCounter->value() );

    if ( delimiterSelection->isChecked() )
      settings.setValue( key + "/delimiterType", "selection" );
    else if ( delimiterPlain->isChecked() )
      settings.setValue( key + "/delimiterType", "plain" );
    else
      settings.setValue( key + "/delimiterType", "regexp" );
    settings.setValue( key + "/delimiterChars", selectedChars().join( "" ) );

    accept();
  }
  else
  {
    QMessageBox::warning( this, tr( "No layer name" ), tr( "Please enter a layer name before adding the layer to the map" ) );
  }
}