[prev in list] [next in list] [prev in thread] [next in thread] 

List:       koffice-devel
Subject:    [patch] fix some csv issues
From:       Leo Savernik <l.savernik () aon ! at>
Date:       2007-01-12 22:44:59
Message-ID: 200701122345.06162.l.savernik () aon ! at
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


Hello,

Before KOffice 1.6 is frozen for good, I'd like to point out a few 
shortcomings of the current csv-importer/exporter.

- Config dialog's settings are not remembered. #132462
- Content is garbled regardless of encoding when finally opening a csv-file 
(preview is ok).
- Only Unix-newlines are exported, regardless of export setting.

The attached patch fixes the above bugs and additionally produces output more 
similar to Excel's.

Please approve for commit. I'd really like to have these CSV-issues fixed 
before KOffice 1.6 is discontinued.

mfg
	Leo

["kspread_cvs-filter_1.diff" (text/x-diff)]

Index: filters/kspread/csv/csvexport.cc
===================================================================
--- filters/kspread/csv/csvexport.cc	(Revision 622128)
+++ filters/kspread/csv/csvexport.cc	(Arbeitskopie)
@@ -64,7 +64,7 @@
 {
 }
 
-QString CSVExport::exportCSVCell( Sheet const * const sheet, int col, int row, QChar \
const & textQuote ) +QString CSVExport::exportCSVCell( Sheet const * const sheet, int \
col, int row, QChar const & textQuote, QChar csvDelimiter )  {
   // This function, given a cell, returns a string corresponding to its export in \
CSV format  // It proceeds by:
@@ -89,6 +89,8 @@
         text = cell->strOutText();
   }
 
+  // quote only when needed (try to mimic excel)
+  bool quote = false;
   if ( !text.isEmpty() )
   {
     if ( text.find( textQuote ) != -1 )
@@ -96,8 +98,15 @@
       QString doubleTextQuote(textQuote);
       doubleTextQuote.append(textQuote);
       text.replace(textQuote, doubleTextQuote);
-    }
+      quote = true;
 
+    } else if ( text[0].isSpace() || text[text.length()-1].isSpace() )
+      quote = true;
+    else if ( text.find( csvDelimiter ) != -1 )
+      quote = true;
+  }
+
+  if ( quote ) {
     text.prepend(textQuote);
     text.append(textQuote);
   }
@@ -164,6 +173,7 @@
       return KoFilter::StupidError;
     }
     csvDelimiter = expDialog->getDelimiter();
+    m_eol = expDialog->getEndOfLine();
   }
   else
   {
@@ -229,7 +239,7 @@
       for ( int col = selection.left();
             col <= right && idxCol <= CSVMaxCol; ++col, ++idxCol )
       {
-        str += exportCSVCell( sheet, col, row, textQuote );
+        str += exportCSVCell( sheet, col, row, textQuote, csvDelimiter );
 
         if ( idxCol < CSVMaxCol )
           str += csvDelimiter;
@@ -324,13 +334,22 @@
           i = 0;
         }
 
+        QString collect;  // buffer delimiters while reading empty cells
+
         for ( int col = 1 ; col <= CSVMaxCol ; col++ )
         {
-          str += exportCSVCell( sheet, col, row, textQuote );
+          const QString txt = exportCSVCell( sheet, col, row, textQuote, \
csvDelimiter );  
-          if ( col < CSVMaxCol )
-            str += csvDelimiter;
+          // if we encounter a non-empty cell, commit the buffered delimiters
+	  if (!txt.isEmpty()) {
+	    str += collect + txt;
+	    collect = QString();
+	  }
+
+          collect += csvDelimiter;
         }
+        // Here, throw away buffered delimiters. They're trailing and therefore
+	// superfluous.
 
         str += m_eol;
       }
Index: filters/kspread/csv/csvexport.h
===================================================================
--- filters/kspread/csv/csvexport.h	(Revision 622128)
+++ filters/kspread/csv/csvexport.h	(Arbeitskopie)
@@ -40,7 +40,7 @@
   virtual KoFilter::ConversionStatus convert( const QCString & from, const QCString \
& to );  
   private:
-  QString exportCSVCell( KSpread::Sheet const * const sheet, int col, int row, QChar \
const & textQuote ); +  QString exportCSVCell( KSpread::Sheet const * const sheet, \
int col, int row, QChar const & textQuote, QChar delimiter );  
   private:
   QString m_eol; ///< End of line (LF, CR or CRLF)  
Index: filters/kspread/csv/csvdialog.cpp
===================================================================
--- filters/kspread/csv/csvdialog.cpp	(Revision 622128)
+++ filters/kspread/csv/csvdialog.cpp	(Arbeitskopie)
@@ -34,6 +34,7 @@
 #include <qtextcodec.h>
 
 #include <kapplication.h>
+#include <kconfig.h>
 #include <kdebug.h>
 #include <klocale.h>
 #include <kcombobox.h>
@@ -57,7 +58,7 @@
 {
     setCaption( i18n( "Import" ) );
     kapp->restoreOverrideCursor();
-
+    
     QStringList encodings;
     encodings << i18n( "Descriptive encoding name", "Recommended ( %1 )" ).arg( \
                "UTF-8" );
     encodings << i18n( "Descriptive encoding name", "Locale ( %1 )" ).arg( \
QTextCodec::codecForLocale()->name() ); @@ -79,6 +80,8 @@
 
     m_dialog->m_sheet->setReadOnly( true );
 
+    loadSettings();
+
     fillTable();
 
     //resize(sizeHint());
@@ -109,9 +112,49 @@
 
 CSVDialog::~CSVDialog()
 {
+    saveSettings();
     kapp->setOverrideCursor(Qt::waitCursor);
 }
 
+void CSVDialog::loadSettings()
+{
+    KConfig *config = kapp->config();
+    config->setGroup("CSVDialog Settings");
+    m_textquote = config->readEntry("textquote", "\"")[0];
+    m_delimiter = config->readEntry("delimiter", ",");
+    m_ignoreDups = config->readBoolEntry("ignoreDups", false);
+    const QString codecText = config->readEntry("codec", "");
+
+    // update widgets
+    if (!codecText.isEmpty()) {
+      m_dialog->comboBoxEncoding->setCurrentText(codecText);
+      m_codec = getCodec();
+    }
+    if (m_delimiter == ",") m_dialog->m_radioComma->setChecked(true);
+    else if (m_delimiter == "\t") m_dialog->m_radioTab->setChecked(true);
+    else if (m_delimiter == " ") m_dialog->m_radioSpace->setChecked(true);
+    else if (m_delimiter == ";") m_dialog->m_radioSemicolon->setChecked(true);
+    else {
+        m_dialog->m_radioOther->setChecked(true);
+        m_dialog->m_delimiterEdit->setText(m_delimiter);
+    }
+    m_dialog->m_ignoreDuplicates->setChecked(m_ignoreDups);
+    m_dialog->m_comboQuote->setCurrentItem(m_textquote == '\'' ? 1
+        : m_textquote == '"' ? 0 : 2);
+}
+
+void CSVDialog::saveSettings()
+{
+    KConfig *config = kapp->config();
+    config->setGroup("CSVDialog Settings");
+    QString q = m_textquote;
+    config->writeEntry("textquote", q);
+    config->writeEntry("delimiter", m_delimiter);
+    config->writeEntry("ignoreDups", m_ignoreDups);
+    config->writeEntry("codec", m_dialog->comboBoxEncoding->currentText());
+    config->sync();
+}
+
 void CSVDialog::fillTable( )
 {
     int row, column;
Index: filters/kspread/csv/csvexportdialog.cpp
===================================================================
--- filters/kspread/csv/csvexportdialog.cpp	(Revision 622128)
+++ filters/kspread/csv/csvexportdialog.cpp	(Arbeitskopie)
@@ -39,6 +39,7 @@
 #include <qvalidator.h>
 
 #include <kapplication.h>
+#include <kconfig.h>
 #include <klocale.h>
 #include <kdebug.h>
 #include <kcombobox.h>
@@ -88,14 +89,66 @@
            this, SLOT( textquoteSelected( const QString & ) ) );
   connect( m_dialog->m_selectionOnly, SIGNAL( toggled( bool ) ),
            this, SLOT( selectionOnlyChanged( bool ) ) );
+
+  loadSettings();
 }
 
 CSVExportDialog::~CSVExportDialog()
 {
+  saveSettings();
   kapp->setOverrideCursor(Qt::waitCursor);
   delete m_delimiterValidator;
 }
 
+void CSVExportDialog::loadSettings()
+{
+    KConfig *config = kapp->config();
+    config->setGroup("CSVDialog Settings");
+    m_textquote = config->readEntry("textquote", "\"")[0];
+    m_delimiter = config->readEntry("delimiter", ",");
+    const QString codecText = config->readEntry("codec", "");
+    bool selectionOnly = config->readBoolEntry("selectionOnly", false);
+    const QString sheetDelim = config->readEntry("sheetDelimiter", \
m_dialog->m_sheetDelimiter->text()); +    bool delimAbove = \
config->readBoolEntry("sheetDelimiterAbove", false); +    const QString eol = \
config->readEntry("eol", "\n"); +
+    // update widgets
+    if (!codecText.isEmpty()) {
+      m_dialog->comboBoxEncoding->setCurrentText(codecText);
+    }
+    if (m_delimiter == ",") m_dialog->m_radioComma->setChecked(true);
+    else if (m_delimiter == "\t") m_dialog->m_radioTab->setChecked(true);
+    else if (m_delimiter == " ") m_dialog->m_radioSpace->setChecked(true);
+    else if (m_delimiter == ";") m_dialog->m_radioSemicolon->setChecked(true);
+    else {
+        m_dialog->m_radioOther->setChecked(true);
+        m_dialog->m_delimiterEdit->setText(m_delimiter);
+    }
+    m_dialog->m_comboQuote->setCurrentItem(m_textquote == '\'' ? 1
+        : m_textquote == '"' ? 0 : 2);
+    m_dialog->m_selectionOnly->setChecked(selectionOnly);
+    m_dialog->m_sheetDelimiter->setText(sheetDelim);
+    m_dialog->m_delimiterAboveAll->setChecked(delimAbove);
+    if (eol == "\r\n") m_dialog->radioEndOfLineCRLF->setChecked(true);
+    else if (eol == "\r") m_dialog->radioEndOfLineCR->setChecked(true);
+    else m_dialog->radioEndOfLineLF->setChecked(true);
+}
+
+void CSVExportDialog::saveSettings()
+{
+    KConfig *config = kapp->config();
+    config->setGroup("CSVDialog Settings");
+    QString q = m_textquote;
+    config->writeEntry("textquote", q);
+    config->writeEntry("delimiter", m_delimiter);
+    config->writeEntry("codec", m_dialog->comboBoxEncoding->currentText());
+    config->writeEntry("selectionOnly", exportSelectionOnly());
+    config->writeEntry("sheetDelimiter", getSheetDelimiter());
+    config->writeEntry("sheetDelimiterAbove", printAlwaysSheetDelimiter());
+    config->writeEntry("eol", getEndOfLine());
+    config->sync();
+}
+
 void CSVExportDialog::fillSheet( Map * map )
 {
   m_dialog->m_sheetList->clear();
Index: filters/kspread/csv/csvdialog.h
===================================================================
--- filters/kspread/csv/csvdialog.h	(Revision 622128)
+++ filters/kspread/csv/csvdialog.h	(Arbeitskopie)
@@ -50,6 +50,8 @@
     QString getText(int row, int col);
 
 private:
+    void loadSettings();
+    void saveSettings();
     void fillTable();
     void fillComboBox();
     void setText(int row, int col, const QString& text);
Index: filters/kspread/csv/csvexportdialog.h
===================================================================
--- filters/kspread/csv/csvexportdialog.h	(Revision 622128)
+++ filters/kspread/csv/csvexportdialog.h	(Arbeitskopie)
@@ -50,6 +50,8 @@
   QTextCodec* getCodec(void) const;
 
  private:
+  void loadSettings();
+  void saveSettings();
   ExportDialogUI * m_dialog;
 
   QValidator* m_delimiterValidator;
Index: filters/kspread/csv/csvimport.cc
===================================================================
--- filters/kspread/csv/csvimport.cc	(Revision 622128)
+++ filters/kspread/csv/csvimport.cc	(Arbeitskopie)
@@ -142,7 +142,7 @@
         {
             value += step;
             emit sigProgress(value);
-            const QString text( dialog->getText( row, col ).utf8() );
+            const QString 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 );


[Attachment #8 (application/pgp-signature)]

_______________________________________________
koffice-devel mailing list
koffice-devel@kde.org
https://mail.kde.org/mailman/listinfo/koffice-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic