summaryrefslogtreecommitdiffstats
path: root/filters/kspread/csv/csvimport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'filters/kspread/csv/csvimport.cpp')
-rw-r--r--filters/kspread/csv/csvimport.cpp264
1 files changed, 264 insertions, 0 deletions
diff --git a/filters/kspread/csv/csvimport.cpp b/filters/kspread/csv/csvimport.cpp
new file mode 100644
index 000000000..72cadfa2b
--- /dev/null
+++ b/filters/kspread/csv/csvimport.cpp
@@ -0,0 +1,264 @@
+/* This file is part of the KDE project
+ Copyright (C) 1999 David Faure <faure@kde.org>
+ Copyright (C) 2004 Nicolas GOUTTE <goutte@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <csvimport.h>
+
+#include <tqfile.h>
+#include <tqregexp.h>
+
+#include <tdeapplication.h>
+#include <tdemessagebox.h>
+#include <kdebug.h>
+#include <kgenericfactory.h>
+
+#include <KoFilterChain.h>
+#include <KoFilterManager.h>
+#include <kspread_doc.h>
+#include <kspread_global.h>
+#include <kspread_map.h>
+#include <kspread_sheet.h>
+#include <kspread_style.h>
+#include <kspread_style_manager.h>
+#include <kspread_cell.h>
+
+#include <csvdialog.h>
+
+using namespace KSpread;
+
+// hehe >:->
+
+/*
+ To generate a test CSV file:
+
+ perl -e '$i=0;while($i<30000) { print rand().",".rand()."\n"; $i++ }' > file.csv
+*/
+
+typedef KGenericFactory<CSVFilter, KoFilter> CSVImportFactory;
+K_EXPORT_COMPONENT_FACTORY( libcsvimport, CSVImportFactory( "kofficefilters" ) )
+
+CSVFilter::CSVFilter(KoFilter *, const char*, const TQStringList&) :
+ KoFilter() {
+}
+
+KoFilter::ConversionStatus CSVFilter::convert( const TQCString& from, const TQCString& to )
+{
+ TQString file( m_chain->inputFile() );
+ KoDocument* document = m_chain->outputDocument();
+
+ if ( !document )
+ return KoFilter::StupidError;
+
+ kdDebug(30501) << "here we go... " << document->className() << endl;
+
+ if ( !::tqqt_cast<const KSpread::Doc *>( document ) )
+ {
+ kdWarning(30501) << "document isn't a KSpread::Doc but a " << document->className() << endl;
+ return KoFilter::NotImplemented;
+ }
+ if(from!="text/x-csv" && from!="text/plain" || to!="application/x-kspread")
+ {
+ kdWarning(30501) << "Invalid mimetypes " << from << " " << to << endl;
+ return KoFilter::NotImplemented;
+ }
+
+ kdDebug(30501) << "...still here..." << endl;
+
+ Doc *ksdoc = static_cast<Doc *>( document ); // type checked above
+
+ if(ksdoc->mimeType()!="application/x-kspread")
+ {
+ kdWarning(30501) << "Invalid document mimetype " << ksdoc->mimeType() << endl;
+ return KoFilter::NotImplemented;
+ }
+
+ TQFile in(file);
+ if(!in.open(IO_ReadOnly)) {
+ KMessageBox::sorry( 0L, i18n("CSV filter cannot open input file - please report.") );
+ in.close();
+ return KoFilter::FileNotFound;
+ }
+
+ TQString csv_delimiter;
+ // ###### FIXME: disabled for now
+ //if (!config.isNull())
+ // csv_delimiter = config[0];
+
+ TQByteArray inputFile( in.readAll() );
+ in.close();
+
+ CSVDialog *dialog = new CSVDialog(0L, inputFile, csv_delimiter );
+ if (!m_chain->manager()->getBatchMode() && !dialog->exec())
+ return KoFilter::UserCancelled;
+ inputFile.resize( 0 ); // Release memory (input file content)
+
+ ElapsedTime t( "Filling data into document" );
+
+ Cell*cell;
+ Sheet *sheet=ksdoc->map()->addNewSheet();
+
+ int numRows = dialog->getRows();
+ int numCols = dialog->getCols();
+
+ if (numRows == 0)
+ ++numRows;
+
+ int step = 100 / numRows * numCols;
+ int value = 0;
+
+ emit sigProgress(value);
+ TQApplication::setOverrideCursor(TQt::waitCursor);
+
+ int i;
+ double init = sheet->nonDefaultColumnFormat( 1 )->dblWidth();
+ TQMemArray<double> widths( numCols );
+ for ( i = 0; i < numCols; ++i )
+ widths[i] = init;
+
+ Cell* c = sheet->nonDefaultCell( 1, 1 );
+ TQFontMetrics fm( c->format()->textFont( 1, 1 ) );
+
+ Style * s = ksdoc->styleManager()->defaultStyle();
+
+ for ( int row = 0; row < numRows; ++row )
+ {
+ for (int col = 0; col < numCols; ++col)
+ {
+ value += step;
+ emit sigProgress(value);
+ const TQString text( dialog->getText( row, col ) );
+
+ // ### FIXME: how to calculate the width of numbers (as they might not be in the right format)
+ const double len = fm.width( text );
+ if ( len > widths[col] )
+ widths[col] = len;
+
+ switch (dialog->getHeader(col))
+ {
+ case CSVDialog::TEXT:
+ //see CSVDialog::accept(), Tomas introduced the Generic format between KOffice 1.3 and 1.4
+ //the Insert->External Data-> ... dialog uses the generic format for everything (see mentioned method)
+ //I will use this approach only for the TEXT format in the CSV import filter... (raphael)
+ //### FIXME: long term solution is to allow to select Generic format ("autodetect") in the dialog and make it the default
+
+ cell = sheet->nonDefaultCell( col + 1, row + 1, false, s );
+ cell->setCellText( text );
+
+ cell->format()->setFormatType (Generic_format);
+
+ /* old code
+ cell = sheet->nonDefaultCell( col + 1, row + 1, false, s );
+ cell->setCellText( text, true );
+ */
+ break;
+ // ### TODO: put the code for the different numbers together (at least partially)
+ case CSVDialog::NUMBER:
+ {
+ bool ok = false;
+ double d = ksdoc->locale()->readNumber( text, &ok );
+ // If not, try with the '.' as decimal separator
+ if ( !ok )
+ d = text.toDouble( &ok );
+ if ( !ok )
+ {
+ cell = sheet->nonDefaultCell( col + 1, row + 1, false, s );
+ cell->setCellText( text, true );
+ }
+ else
+ {
+ cell = sheet->nonDefaultCell( col + 1, row + 1, false, s );
+ cell->setNumber( d );
+ }
+ cell->format()->setPrecision( 2 );
+ break;
+ }
+ case CSVDialog::COMMANUMBER:
+ {
+ bool ok = false;
+ TQString tmp ( text );
+ tmp.remove ( TQRegExp( "[^0-9,Ee+-]" ) ); // Keep only 0 to 9, comma, E, e, plus, minus
+ tmp.replace ( ',', '.' );
+ kdDebug(30501) << "Comma: " << text << " => " << tmp << endl;
+ const double d = tmp.toDouble( &ok );
+ if ( !ok )
+ {
+ cell = sheet->nonDefaultCell( col + 1, row + 1, false, s );
+ cell->setCellText( text, true );
+ }
+ else
+ {
+ cell = sheet->nonDefaultCell( col + 1, row + 1, false, s );
+ cell->setNumber( d );
+ }
+ cell->format()->setPrecision( 2 );
+ break;
+ }
+ case CSVDialog::POINTNUMBER:
+ {
+ bool ok = false;
+ TQString tmp ( text );
+ tmp.remove ( TQRegExp( "[^0-9\\.EeD+-]" ) ); // Keep only 0 to 9, dot, E, e, D, plus, minus
+ tmp.replace ( 'D', 'E' ); // double from FORTRAN use D instead of E
+ kdDebug(30501) << "Point: " << text << " => " << tmp << endl;
+ const double d = tmp.toDouble( &ok );
+ if ( !ok )
+ {
+ cell = sheet->nonDefaultCell( col + 1, row + 1, false, s );
+ cell->setCellText( text, true );
+ }
+ else
+ {
+ cell = sheet->nonDefaultCell( col + 1, row + 1, false, s );
+ cell->setNumber( d );
+ }
+ cell->format()->setPrecision( 2 );
+ break;
+ }
+ case CSVDialog::DATE:
+ cell = sheet->nonDefaultCell( col + 1, row + 1, false, s );
+ cell->setCellText( text );
+ cell->format()->setFormatType( ShortDate_format );
+ break;
+ case CSVDialog::CURRENCY:
+ cell = sheet->nonDefaultCell( col + 1, row + 1, false, s );
+ cell->setCellText( text, false );
+ cell->format()->setFormatType( Money_format );
+ cell->format()->setPrecision( 2 );
+ break;
+ }
+ }
+ }
+
+ emit sigProgress( 98 );
+
+ ElapsedTime t2( "Resizing columns" );
+ for ( i = 0; i < numCols; ++i )
+ {
+ ColumnFormat * c = sheet->nonDefaultColumnFormat( i + 1 );
+ c->setDblWidth( widths[i] );
+ }
+
+ emit sigProgress( 100 );
+ TQApplication::restoreOverrideCursor();
+ delete dialog;
+
+ return KoFilter::OK;
+}
+
+#include <csvimport.moc>