Skip to content
Permalink
Browse files

Error message fixes and more regexp testing

  • Loading branch information
ccrook committed Apr 18, 2013
1 parent 8570646 commit b501c9a133e3d6a669ef96e3d380ca6ce04769c4
@@ -8,7 +8,7 @@ Loads and displays delimited text files
<a href="#wkt">How WKT text is interpreted</a><br />
<a href="#example">Example of a text file with X,Y point coordinates</a><br/>
<a href="#wkt_example">Example of a text file with WKT geometries</a><br/>
<a href="#notes">Notes</a><br/>
<a href="#python">Using delimited text layers in Python</a><br/>
</p>

<h4><a name="re">Overview</a></h4>
@@ -170,3 +170,5 @@ id|wkt<br />
<li>Uses <b>|</b> as a delimiter.</li>
<li>Specifies each point using the WKT notation
</ul>

<h4><a name="python">Using delimited text layers in Python</a></h4>
@@ -180,6 +180,10 @@ bool QgsDelimitedTextFile::setFromUrl( QUrl &url )
{
mTrimFields = ! url.queryItemValue( "trimFields" ).toUpper().startsWith( 'N' );;
}
if ( url.hasQueryItem( "maxFields" ) )
{
mMaxFields = url.queryItemValue( "maxFields" ).toInt();
}

QgsDebugMsg( "Delimited text file is: " + mFileName );
QgsDebugMsg( "Encoding is: " + mEncoding );
@@ -188,6 +192,7 @@ bool QgsDelimitedTextFile::setFromUrl( QUrl &url )
QgsDebugMsg( "Quote character is: [" + quote + "]" );
QgsDebugMsg( "Escape character is: [" + escape + "]" );
QgsDebugMsg( "Skip lines: " + QString::number( mSkipLines ) );
QgsDebugMsg( "Maximum number of fields in record: " + QString::number( mMaxFields ) );
QgsDebugMsg( "Use headers: " + QString( mUseHeader ? "Yes" : "No" ) );
QgsDebugMsg( "Discard empty fields: " + QString( mDiscardEmptyFields ? "Yes" : "No" ) );
QgsDebugMsg( "Trim fields: " + QString( mTrimFields ? "Yes" : "No" ) );
@@ -246,6 +251,10 @@ QUrl QgsDelimitedTextFile::url()
{
url.addQueryItem( "skipEmptyFields", "Yes" );
}
if ( mMaxFields > 0 )
{
url.addQueryItem( "maxFields", QString::number( mMaxFields ) );
}
return url;
}

@@ -341,6 +350,12 @@ void QgsDelimitedTextFile::setTrimFields( bool trimFields )
mTrimFields = trimFields;
}

void QgsDelimitedTextFile::setMaxFields( int maxFields )
{
resetDefinition();
mMaxFields = maxFields;
}

void QgsDelimitedTextFile::setDiscardEmptyFields( bool discardEmptyFields )
{
resetDefinition();
@@ -142,64 +142,79 @@ class QgsDelimitedTextFile
*/
void setTypeCSV( QString delim = QString( "," ), QString quote = QString( "\"" ), QString escape = QString( "\"" ) );

/* Set the number of header lines to skip
/** Set the number of header lines to skip
* @param skiplines The maximum lines to skip
*/
void setSkipLines( int skiplines );
/* Return the number of header lines to skip
/** Return the number of header lines to skip
* @return skiplines The maximum lines to skip
*/
int skipLines()
{
return mSkipLines;
}

/* Set reading field names from the first record
/** Set reading field names from the first record
* @param useheaders Field names will be read if true
*/
void setUseHeader( bool useheader = true );
/* Return the option for reading field names from the first record
/** Return the option for reading field names from the first record
* @return useheaders Field names will be read if true
*/
bool useHeader()
{
return mUseHeader;
}

/* Set the option for dicarding empty fields
/** Set the option for dicarding empty fields
* @param useheaders Empty fields will be discarded if true
*/
void setDiscardEmptyFields( bool discardEmptyFields = true );
/* Return the option for discarding empty fields
/** Return the option for discarding empty fields
* @return useheaders Empty fields will be discarded if true
*/
bool discardEmptyFields()
{
return mDiscardEmptyFields;
}

/* Set the option for trimming whitespace from fields
/** Set the option for trimming whitespace from fields
* @param trimFields Fields will be trimmed if true
*/
void setTrimFields( bool trimFields = true );
/* Return the option for trimming empty fields
/** Return the option for trimming empty fields
* @return useheaders Empty fields will be trimmed if true
*/
bool trimFields()
{
return mTrimFields;
}

/** Set the maximum number of fields that will be read from a record
* By default the maximum number is unlimited (0)
* @param maxFields The maximum number of fields that will be read
*/
void setMaxFields( int maxFields );
/** Return the maximum number of fields that will be read
* @return maxFields The maximum number of fields that will be read
*/
int maxFields() { return mMaxFields; }

/** Set the field names
* Field names are set from QStringList. Names may be modified
* to ensure that they are unique, not empty, and do not conflict
* with default field name (Field_##)
* with default field name (field_##)
* @param names A list of proposed field names
*/
void setFieldNames( const QStringList &names );

/** Return the field names read from the header, or default names
* Col## if none defined. Will open and read the head of the file
* if required, then reset..
* field_## if none defined. Will open and read the head of the file
* if required, then reset. Note that if header record record has
* not been read then the field names are empty until records have
* been read. The list may be expanded as the file is read and records
* with more fields are loaded.
* @return names A list of field names in the file
*/
QStringList &fieldNames();

@@ -129,6 +129,9 @@ QgsDelimitedTextProvider::QgsDelimitedTextProvider( QString uri )
if ( ! mFile->isValid() )
{
// uri is invalid so the layer must be too...
QStringList messages;
messages.append( "File cannot be opened or delimiter parameters are not valid" );
reportErrors( messages );
QgsDebugMsg( "Delimited text source invalid - filename or delimiter parameters" );
return;
}
@@ -539,20 +542,22 @@ void QgsDelimitedTextProvider::recordInvalidLine( QString message )

void QgsDelimitedTextProvider::reportErrors( QStringList messages )
{
if ( !mInvalidLines.isEmpty() )
if ( !mInvalidLines.isEmpty() || ! messages.isEmpty() )
{
QString tag( "DelimitedText" );
QgsMessageLog::logMessage( tr( "Errors in file %1" ).arg( mFile->fileName() ), tag );
foreach ( QString message, messages )
{
QgsMessageLog::logMessage( message );
}
QgsMessageLog::logMessage( tr( "The following lines were not loaded from %1 into QGIS due to errors:\n" ).arg( mFile->fileName() ),
tag );
for ( int i = 0; i < mInvalidLines.size(); ++i )
QgsMessageLog::logMessage( mInvalidLines.at( i ), tag );
if ( mNExtraInvalidLines > 0 )
QgsMessageLog::logMessage( tr( "There are %1 additional errors in the file" ).arg( mNExtraInvalidLines ), tag );
if ( ! mInvalidLines.isEmpty() )
{
QgsMessageLog::logMessage( tr( "The following lines were not loaded into QGIS due to errors:" ), tag );
for ( int i = 0; i < mInvalidLines.size(); ++i )
QgsMessageLog::logMessage( mInvalidLines.at( i ), tag );
if ( mNExtraInvalidLines > 0 )
QgsMessageLog::logMessage( tr( "There are %1 additional errors in the file" ).arg( mNExtraInvalidLines ), tag );
}


// Display errors in a dialog...
@@ -565,11 +570,14 @@ void QgsDelimitedTextProvider::reportErrors( QStringList messages )
{
output->appendMessage( message );
}
output->appendMessage( tr( "The following lines were not loaded from %1 into QGIS due to errors:\n" ).arg( mFile->fileName() ) );
for ( int i = 0; i < mInvalidLines.size(); ++i )
output->appendMessage( mInvalidLines.at( i ) );
if ( mNExtraInvalidLines > 0 )
output->appendMessage( tr( "There are %1 additional errors in the file" ).arg( mNExtraInvalidLines ) );
if ( ! mInvalidLines.isEmpty() )
{
output->appendMessage( tr( "The following lines were not loaded into QGIS due to errors:" ) );
for ( int i = 0; i < mInvalidLines.size(); ++i )
output->appendMessage( mInvalidLines.at( i ) );
if ( mNExtraInvalidLines > 0 )
output->appendMessage( tr( "There are %1 additional errors in the file" ).arg( mNExtraInvalidLines ) );
}
output->showMessage();
}

@@ -56,7 +56,7 @@ QgsDelimitedTextSourceSelect::QgsDelimitedTextSourceSelect( QWidget * parent, Qt
codecs.append( codec );
}
codecs.sort();
foreach( QString codec, codecs )
foreach ( QString codec, codecs )
{
cmbEncoding->addItem( codec );
}
@@ -143,8 +143,6 @@ void QgsDelimitedTextSourceSelect::on_buttonBox_accepted()

QUrl url = mFile->url();

bool useHeader = mFile->useHeader();

if ( cbxPointIsComma->isChecked() )
{
url.addQueryItem( "decimalPoint", "," );
@@ -637,19 +635,11 @@ void QgsDelimitedTextSourceSelect::updateFileName()

void QgsDelimitedTextSourceSelect::updateFieldsAndEnable()
{
// Check the regular expression is valid
lblRegexpError->setText( "" );
if ( delimiterRegexp->isChecked() )
{
QRegExp re( txtDelimiterRegexp->text() );
if ( ! re.isValid() ) lblRegexpError->setText( tr( "Expression is not valid" ) );
}

updateFieldLists();
enableAccept();
}

void QgsDelimitedTextSourceSelect::enableAccept()
bool QgsDelimitedTextSourceSelect::validate()
{
// Check that input data is valid - provide a status message if not..

@@ -672,9 +662,23 @@ void QgsDelimitedTextSourceSelect::enableAccept()
{
message = tr( "At least one delimiter character must be specified" );
}
else if ( delimiterRegexp->isChecked() && ! QRegExp( txtDelimiterRegexp->text() ).isValid() )

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() )
{
message = tr( "Regular expression is not valid" );
// continue...
}
// Hopefully won't hit this none-specific message, but just in case ...
else if ( ! mFile->isValid() )
@@ -702,8 +706,12 @@ void QgsDelimitedTextSourceSelect::enableAccept()
{
enabled = true;
}

lblStatus->setText( message );
return enabled;
}

void QgsDelimitedTextSourceSelect::enableAccept()
{
bool enabled = validate();
buttonBox->button( QDialogButtonBox::Ok )->setEnabled( enabled );
}
@@ -66,6 +66,7 @@ class QgsDelimitedTextSourceSelect : public QDialog, private Ui::QgsDelimitedTex
void updateFileName();
void updateFieldsAndEnable();
void enableAccept();
bool validate();

signals:
void addVectorLayer( QString, QString, QString );

0 comments on commit b501c9a

Please sign in to comment.
You can’t perform that action at this time.