kspread

kspread_dlg_csv.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002-2003 Norbert Andres <nandres@web.de>
00003              (C) 2002-2003 Ariya Hidayat <ariya@kde.org>
00004              (C) 2002      Laurent Montel <montel@kde.org>
00005              (C) 1999 David Faure <faure@kde.org>
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016 
00017    You should have received a copy of the GNU Library General Public License
00018    along with this library; see the file COPYING.LIB.  If not, write to
00019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include <qbuttongroup.h>
00024 #include <qcheckbox.h>
00025 #include <qclipboard.h>
00026 #include <qcombobox.h>
00027 #include <qlabel.h>
00028 #include <qlineedit.h>
00029 #include <qmime.h>
00030 #include <qpushbutton.h>
00031 #include <qradiobutton.h>
00032 #include <qtable.h>
00033 #include <qlayout.h>
00034 
00035 #include <kapplication.h>
00036 #include <kdebug.h>
00037 #include <kdialogbase.h>
00038 #include <kfiledialog.h>
00039 #include <klocale.h>
00040 #include <kmessagebox.h>
00041 
00042 #include <kspread_cell.h>
00043 #include <kspread_doc.h>
00044 #include <kspread_sheet.h>
00045 #include <kspread_undo.h>
00046 #include <kspread_view.h>
00047 
00048 #include "kspread_dlg_csv.h"
00049 
00050 using namespace KSpread;
00051 
00052 CSVDialog::CSVDialog( View * parent, const char * name, QRect const & rect, Mode mode)
00053   : KDialogBase( parent, name, true, QString::null, Ok|Cancel ),
00054     m_pView( parent ),
00055     m_cancelled( false ),
00056     m_adjustRows( 0 ),
00057     m_startline( 0 ),
00058     m_textquote( '"' ),
00059     m_delimiter( "," ),
00060     m_targetRect( rect ),
00061     m_mode( mode )
00062 {
00063   if ( !name )
00064     setName( "CSV" );
00065 
00066   setSizeGripEnabled( TRUE );
00067 
00068   QWidget* page = new QWidget( this );
00069   setMainWidget( page );
00070   //  MyDialogLayout = new QGridLayout( page, 4, 4, marginHint(), spacingHint(), "MyDialogLayout");
00071   MyDialogLayout = new QGridLayout( page, 1, 1, 11, 6, "MyDialogLayout");
00072 
00073   // Limit the range
00074   int column = m_targetRect.left();
00075   Cell* lastCell = m_pView->activeSheet()->getLastCellColumn( column );
00076   if( lastCell )
00077     if( m_targetRect.bottom() > lastCell->row() )
00078       m_targetRect.setBottom( lastCell->row() );
00079 
00080   m_sheet = new QTable( page, "m_table" );
00081   //m_sheet->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)5, (QSizePolicy::SizeType)7, 0, 0, m_sheet->sizePolicy().hasHeightForWidth() ) );
00082   m_sheet->setNumRows( 0 );
00083   m_sheet->setNumCols( 0 );
00084 
00085   MyDialogLayout->addMultiCellWidget( m_sheet, 3, 3, 0, 3 );
00086 
00087   // Delimiter: comma, semicolon, tab, space, other
00088   m_delimiterBox = new QButtonGroup( page, "m_delimiterBox" );
00089   m_delimiterBox->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)1, 0, 0, m_delimiterBox->sizePolicy().hasHeightForWidth() ) );
00090   m_delimiterBox->setTitle( i18n( "Delimiter" ) );
00091   m_delimiterBox->setColumnLayout(0, Qt::Vertical );
00092   m_delimiterBox->layout()->setSpacing( KDialog::spacingHint() );
00093   m_delimiterBox->layout()->setMargin( KDialog::marginHint() );
00094   m_delimiterBoxLayout = new QGridLayout( m_delimiterBox->layout() );
00095   m_delimiterBoxLayout->setAlignment( Qt::AlignTop );
00096   MyDialogLayout->addMultiCellWidget( m_delimiterBox, 0, 2, 0, 0 );
00097 
00098   m_ignoreDuplicates = new QCheckBox( page, "m_ignoreDuplicates" );
00099   m_ignoreDuplicates->setText( i18n( "Ignore duplicate delimiters" ) );
00100 
00101   MyDialogLayout->addMultiCellWidget( m_ignoreDuplicates, 2, 2, 2, 3 );
00102 
00103   m_radioComma = new QRadioButton( m_delimiterBox, "m_radioComma" );
00104   m_radioComma->setText( i18n( "Comma" ) );
00105   m_radioComma->setChecked( TRUE );
00106   m_delimiterBoxLayout->addWidget( m_radioComma, 0, 0 );
00107 
00108   m_radioSemicolon = new QRadioButton( m_delimiterBox, "m_radioSemicolon" );
00109   m_radioSemicolon->setText( i18n( "Semicolon" ) );
00110   m_delimiterBoxLayout->addWidget( m_radioSemicolon, 0, 1 );
00111 
00112   m_radioTab = new QRadioButton( m_delimiterBox, "m_radioTab" );
00113   m_radioTab->setText( i18n( "Tabulator" ) );
00114   m_delimiterBoxLayout->addWidget( m_radioTab, 1, 0 );
00115 
00116   m_radioSpace = new QRadioButton( m_delimiterBox, "m_radioSpace" );
00117   m_radioSpace->setText( i18n( "Space" ) );
00118   m_delimiterBoxLayout->addWidget( m_radioSpace, 1, 1 );
00119 
00120   m_radioOther = new QRadioButton( m_delimiterBox, "m_radioOther" );
00121   m_radioOther->setText( i18n( "Other" ) );
00122   m_delimiterBoxLayout->addWidget( m_radioOther, 0, 2 );
00123 
00124   m_delimiterEdit = new QLineEdit( m_delimiterBox, "m_delimiterEdit" );
00125   m_delimiterEdit->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, m_delimiterEdit->sizePolicy().hasHeightForWidth() ) );
00126   m_delimiterEdit->setMaximumSize( QSize( 30, 32767 ) );
00127   m_delimiterBoxLayout->addWidget( m_delimiterEdit, 1, 2 );
00128 
00129 
00130   // Format: number, text, currency,
00131   m_formatBox = new QButtonGroup( page, "m_formatBox" );
00132   m_formatBox->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)1, 0, 0, m_formatBox->sizePolicy().hasHeightForWidth() ) );
00133   m_formatBox->setTitle( i18n( "Format" ) );
00134   m_formatBox->setColumnLayout(0, Qt::Vertical );
00135   m_formatBox->layout()->setSpacing( KDialog::spacingHint() );
00136   m_formatBox->layout()->setMargin( KDialog::marginHint() );
00137   m_formatBoxLayout = new QGridLayout( m_formatBox->layout() );
00138   m_formatBoxLayout->setAlignment( Qt::AlignTop );
00139   MyDialogLayout->addMultiCellWidget( m_formatBox, 0, 2, 1, 1 );
00140 
00141   m_radioNumber = new QRadioButton( m_formatBox, "m_radioNumber" );
00142   m_radioNumber->setText( i18n( "Number" ) );
00143   m_formatBoxLayout->addMultiCellWidget( m_radioNumber, 1, 1, 0, 1 );
00144 
00145   m_radioText = new QRadioButton( m_formatBox, "m_radioText" );
00146   m_radioText->setText( i18n( "Text" ) );
00147   m_radioText->setChecked( TRUE );
00148   m_formatBoxLayout->addWidget( m_radioText, 0, 0 );
00149 
00150   m_radioCurrency = new QRadioButton( m_formatBox, "m_radioCurrency" );
00151   m_radioCurrency->setText( i18n( "Currency" ) );
00152   m_formatBoxLayout->addMultiCellWidget( m_radioCurrency, 0, 0, 1, 2 );
00153 
00154   m_radioDate = new QRadioButton( m_formatBox, "m_radioDate" );
00155   m_radioDate->setText( i18n( "Date" ) );
00156   m_formatBoxLayout->addWidget( m_radioDate, 1, 2 );
00157 
00158   m_comboLine = new QComboBox( FALSE, page, "m_comboLine" );
00159   m_comboLine->insertItem( i18n( "1" ) );
00160   m_comboLine->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, m_comboLine->sizePolicy().hasHeightForWidth() ) );
00161 
00162   MyDialogLayout->addWidget( m_comboLine, 1, 3 );
00163 
00164   m_comboQuote = new QComboBox( FALSE, page, "m_comboQuote" );
00165   m_comboQuote->insertItem( i18n( "\"" ) );
00166   m_comboQuote->insertItem( i18n( "'" ) );
00167   m_comboQuote->insertItem( i18n( "None" ) );
00168   m_comboQuote->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, m_comboQuote->sizePolicy().hasHeightForWidth() ) );
00169 
00170   MyDialogLayout->addWidget( m_comboQuote, 1, 2 );
00171   QSpacerItem* spacer_2 = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Preferred );
00172   MyDialogLayout->addItem( spacer_2, 2, 3 );
00173 
00174   TextLabel3 = new QLabel( page, "TextLabel3" );
00175   TextLabel3->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, TextLabel3->sizePolicy().hasHeightForWidth() ) );
00176   TextLabel3->setText( i18n( "Start at line:" ) );
00177 
00178   MyDialogLayout->addWidget( TextLabel3, 0, 3 );
00179 
00180   TextLabel2 = new QLabel( page, "TextLabel2" );
00181   TextLabel2->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)0, 0, 0, TextLabel2->sizePolicy().hasHeightForWidth() ) );
00182   TextLabel2->setText( i18n( "Textquote:" ) );
00183 
00184   MyDialogLayout->addWidget( TextLabel2, 0, 2 );
00185 
00186   if ( m_mode == Clipboard )
00187   {
00188     setCaption( i18n( "Inserting From Clipboard" ) );
00189     QMimeSource * mime = QApplication::clipboard()->data();
00190     if ( !mime )
00191     {
00192       KMessageBox::information( this, i18n("There is no data in the clipboard.") );
00193       m_cancelled = true;
00194       return;
00195     }
00196 
00197     if ( !mime->provides( "text/plain" ) )
00198     {
00199       KMessageBox::information( this, i18n("There is no usable data in the clipboard.") );
00200       m_cancelled = true;
00201       return;
00202     }
00203     m_fileArray = QByteArray(mime->encodedData( "text/plain" ) );
00204   }
00205   else if ( mode == File )
00206   {
00207     setCaption( i18n( "Inserting Text File" ) );
00208     QString file = KFileDialog::getOpenFileName(":",
00209                                                 "text/plain",
00210                                                 this);
00211     //cancel action !
00212     if ( file.isEmpty() )
00213     {
00214         actionButton( Ok )->setEnabled( false );
00215         m_cancelled = true;
00216         return;
00217     }
00218     QFile in(file);
00219     if (!in.open(IO_ReadOnly))
00220     {
00221       KMessageBox::sorry( this, i18n("Cannot open input file.") );
00222       in.close();
00223       actionButton( Ok )->setEnabled( false );
00224       m_cancelled = true;
00225       return;
00226     }
00227     m_fileArray = QByteArray(in.size());
00228     in.readBlock(m_fileArray.data(), in.size());
00229     in.close();
00230   }
00231   else
00232   {
00233     setCaption( i18n( "Text to Columns" ) );
00234     m_data = "";
00235     Cell  * cell;
00236     Sheet * sheet = m_pView->activeSheet();
00237     int col = m_targetRect.left();
00238     for (int i = m_targetRect.top(); i <= m_targetRect.bottom(); ++i)
00239     {
00240       cell = sheet->cellAt( col, i );
00241       if ( !cell->isEmpty() && !cell->isDefault() )
00242       {
00243         m_data += cell->strOutText();
00244       }
00245       m_data += "\n";
00246     }
00247   }
00248 
00249   fillSheet();
00250   fillComboBox();
00251 
00252   resize(sizeHint());
00253 
00254   m_sheet->setSelectionMode(QTable::NoSelection);
00255 
00256   connect(m_formatBox, SIGNAL(clicked(int)),
00257           this, SLOT(formatClicked(int)));
00258   connect(m_delimiterBox, SIGNAL(clicked(int)),
00259           this, SLOT(delimiterClicked(int)));
00260   connect(m_delimiterEdit, SIGNAL(returnPressed()),
00261           this, SLOT(returnPressed()));
00262   connect(m_delimiterEdit, SIGNAL(textChanged ( const QString & )),
00263           this, SLOT(textChanged ( const QString & ) ));
00264   connect(m_comboLine, SIGNAL(activated(const QString&)),
00265           this, SLOT(lineSelected(const QString&)));
00266   connect(m_comboQuote, SIGNAL(activated(const QString&)),
00267           this, SLOT(textquoteSelected(const QString&)));
00268   connect(m_sheet, SIGNAL(currentChanged(int, int)),
00269           this, SLOT(currentCellChanged(int, int)));
00270   connect(m_ignoreDuplicates, SIGNAL(stateChanged(int)),
00271           this, SLOT(ignoreDuplicatesChanged(int)));
00272 }
00273 
00274 CSVDialog::~CSVDialog()
00275 {
00276   // no need to delete child widgets, Qt does it all for us
00277 }
00278 
00279 bool CSVDialog::cancelled()
00280 {
00281   return m_cancelled;
00282 }
00283 
00284 void CSVDialog::fillSheet()
00285 {
00286   int row, column;
00287   bool lastCharDelimiter = false;
00288   bool ignoreDups = m_ignoreDuplicates->isChecked();
00289   enum { S_START, S_QUOTED_FIELD, S_MAYBE_END_OF_QUOTED_FIELD, S_END_OF_QUOTED_FIELD,
00290          S_MAYBE_NORMAL_FIELD, S_NORMAL_FIELD } state = S_START;
00291 
00292   QChar x;
00293   QString field = "";
00294 
00295   for (row = 0; row < m_sheet->numRows(); ++row)
00296     for (column = 0; column < m_sheet->numCols(); ++column)
00297       m_sheet->clearCell(row, column);
00298 
00299   row = column = 1;
00300   if (m_mode != Column)
00301   {
00302     m_mode = Column;
00303     m_data = QString(m_fileArray);
00304     m_fileArray.resize(0);
00305   }
00306 
00307   QTextStream inputStream(m_data, IO_ReadOnly);
00308   inputStream.setEncoding(QTextStream::Locale);
00309 
00310   while (!inputStream.atEnd())
00311   {
00312     inputStream >> x; // read one char
00313 
00314     if (x == '\r') inputStream >> x; // eat '\r', to handle DOS/LOSEDOWS files correctly
00315 
00316     switch (state)
00317     {
00318      case S_START :
00319       if (x == m_textquote)
00320       {
00321         state = S_QUOTED_FIELD;
00322       }
00323       else if (x == m_delimiter)
00324       {
00325         if ((ignoreDups == false) || (lastCharDelimiter == false))
00326           ++column;
00327         lastCharDelimiter = true;
00328       }
00329       else if (x == '\n')
00330       {
00331         ++row;
00332         column = 1;
00333       }
00334       else
00335       {
00336         field += x;
00337         state = S_MAYBE_NORMAL_FIELD;
00338       }
00339       break;
00340      case S_QUOTED_FIELD :
00341       if (x == m_textquote)
00342       {
00343         state = S_MAYBE_END_OF_QUOTED_FIELD;
00344       }
00345       else if (x == '\n')
00346       {
00347         setText(row - m_startline, column, field);
00348         field = "";
00349         if (x == '\n')
00350         {
00351           ++row;
00352           column = 1;
00353         }
00354         else
00355         {
00356           if ((ignoreDups == false) || (lastCharDelimiter == false))
00357             ++column;
00358           lastCharDelimiter = true;
00359         }
00360         state = S_START;
00361       }
00362       else
00363       {
00364         field += x;
00365       }
00366       break;
00367      case S_MAYBE_END_OF_QUOTED_FIELD :
00368       if (x == m_textquote)
00369       {
00370         field += x;
00371         state = S_QUOTED_FIELD;
00372       }
00373       else if (x == m_delimiter || x == '\n')
00374       {
00375         setText(row - m_startline, column, field);
00376         field = "";
00377         if (x == '\n')
00378         {
00379           ++row;
00380           column = 1;
00381         }
00382         else
00383         {
00384           if ((ignoreDups == false) || (lastCharDelimiter == false))
00385             ++column;
00386           lastCharDelimiter = true;
00387         }
00388         state = S_START;
00389       }
00390       else
00391       {
00392         state = S_END_OF_QUOTED_FIELD;
00393       }
00394       break;
00395      case S_END_OF_QUOTED_FIELD :
00396       if (x == m_delimiter || x == '\n')
00397       {
00398         setText(row - m_startline, column, field);
00399         field = "";
00400         if (x == '\n')
00401         {
00402           ++row;
00403           column = 1;
00404         }
00405         else
00406         {
00407           if ((ignoreDups == false) || (lastCharDelimiter == false))
00408             ++column;
00409           lastCharDelimiter = true;
00410         }
00411         state = S_START;
00412       }
00413       else
00414       {
00415         state = S_END_OF_QUOTED_FIELD;
00416       }
00417       break;
00418      case S_MAYBE_NORMAL_FIELD :
00419       if (x == m_textquote)
00420       {
00421         field = "";
00422         state = S_QUOTED_FIELD;
00423         break;
00424       }
00425      case S_NORMAL_FIELD :
00426       if (x == m_delimiter || x == '\n')
00427       {
00428         setText(row - m_startline, column, field);
00429         field = "";
00430         if (x == '\n')
00431         {
00432           ++row;
00433           column = 1;
00434         }
00435         else
00436         {
00437           if ((ignoreDups == false) || (lastCharDelimiter == false))
00438             ++column;
00439           lastCharDelimiter = true;
00440         }
00441         state = S_START;
00442       }
00443       else
00444       {
00445         field += x;
00446       }
00447     }
00448     if (x != m_delimiter)
00449       lastCharDelimiter = false;
00450   }
00451 
00452   // file with only one line without '\n'
00453   if (field.length() > 0)
00454   {
00455     setText(row - m_startline, column, field);
00456     ++row;
00457     field = "";
00458   }
00459 
00460   adjustRows( row - m_startline );
00461 
00462   for (column = 0; column < m_sheet->numCols(); ++column)
00463   {
00464     QString header = m_sheet->horizontalHeader()->label(column);
00465     if (header != i18n("Text") && header != i18n("Number") &&
00466         header != i18n("Date") && header != i18n("Currency"))
00467       m_sheet->horizontalHeader()->setLabel(column, i18n("Text"));
00468 
00469     m_sheet->adjustColumn(column);
00470   }
00471 }
00472 
00473 void CSVDialog::fillComboBox()
00474 {
00475   m_comboLine->clear();
00476   for (int row = 0; row < m_sheet->numRows(); ++row)
00477     m_comboLine->insertItem(QString::number(row + 1), row);
00478 }
00479 
00480 void CSVDialog::setText(int row, int col, const QString& text)
00481 {
00482   if (row < 1) // skipped by the user
00483     return;
00484 
00485   if (m_sheet->numRows() < row) {
00486     m_sheet->setNumRows(row+5000); /* We add 5000 at a time to limit recalculations */
00487     m_adjustRows=1;
00488   }
00489 
00490   if (m_sheet->numCols() < col)
00491     m_sheet->setNumCols(col);
00492 
00493   m_sheet->setText(row - 1, col - 1, text);
00494 }
00495 
00496 /*
00497  * Called after the first fillSheet() when number of rows are unknown.
00498  */
00499 void CSVDialog::adjustRows(int iRows)
00500 {
00501   if (m_adjustRows)
00502   {
00503     m_sheet->setNumRows( iRows );
00504     m_adjustRows=0;
00505   }
00506 }
00507 
00508 void CSVDialog::returnPressed()
00509 {
00510   if (m_delimiterBox->id(m_delimiterBox->selected()) != 4)
00511     return;
00512 
00513   m_delimiter = m_delimiterEdit->text();
00514   fillSheet();
00515 }
00516 
00517 void CSVDialog::textChanged ( const QString & )
00518 {
00519   m_radioOther->setChecked ( true );
00520   delimiterClicked(4); // other
00521 }
00522 
00523 void CSVDialog::formatClicked(int id)
00524 {
00525   QString header;
00526 
00527   switch (id)
00528   {
00529    case 1: // text
00530     header = i18n("Text");
00531     break;
00532    case 0: // number
00533     header = i18n("Number");
00534     break;
00535    case 3: // date
00536     header = i18n("Date");
00537     break;
00538    case 2: // currency
00539     header = i18n("Currency");
00540     break;
00541   }
00542 
00543   m_sheet->horizontalHeader()->setLabel(m_sheet->currentColumn(), header);
00544 }
00545 
00546 void CSVDialog::delimiterClicked(int id)
00547 {
00548   switch (id)
00549   {
00550    case 0: // comma
00551     m_delimiter = ",";
00552     break;
00553    case 4: // other
00554     m_delimiter = m_delimiterEdit->text();
00555     break;
00556    case 2: // tab
00557     m_delimiter = "\t";
00558     break;
00559    case 3: // space
00560     m_delimiter = " ";
00561     break;
00562    case 1: // semicolon
00563     m_delimiter = ";";
00564     break;
00565   }
00566 
00567   fillSheet();
00568 }
00569 
00570 void CSVDialog::textquoteSelected(const QString& mark)
00571 {
00572   if (mark == i18n("none"))
00573     m_textquote = 0;
00574   else
00575     m_textquote = mark[0];
00576 
00577   fillSheet();
00578 }
00579 
00580 void CSVDialog::lineSelected(const QString& line)
00581 {
00582   m_startline = line.toInt() - 1;
00583   fillSheet();
00584 }
00585 
00586 void CSVDialog::currentCellChanged(int, int col)
00587 {
00588   int id;
00589   QString header = m_sheet->horizontalHeader()->label(col);
00590 
00591   if (header == i18n("Text"))
00592     id = 1;
00593   else if (header == i18n("Number"))
00594     id = 0;
00595   else if (header == i18n("Date"))
00596     id = 3;
00597   else
00598     id = 2;
00599 
00600   m_formatBox->setButton(id);
00601 }
00602 
00603 void CSVDialog::accept()
00604 {
00605   Sheet * sheet  = m_pView->activeSheet();
00606   QString csv_delimiter = QString::null;
00607   Cell  * cell;
00608 
00609   int numRows = m_sheet->numRows();
00610   int numCols = m_sheet->numCols();
00611 
00612   if (numRows == 0)
00613     ++numRows;
00614 
00615   if ( (numCols > m_targetRect.width()) && (m_targetRect.width() > 1) )
00616   {
00617     numCols = m_targetRect.width();
00618   }
00619   else
00620     m_targetRect.setRight( m_targetRect.left() + numCols );
00621 
00622   if ( (numRows > m_targetRect.height()) && (m_targetRect.height() > 1) )
00623     numRows = m_targetRect.height();
00624   else
00625     m_targetRect.setBottom( m_targetRect.top() + numRows );
00626 
00627   if ( numRows == 1 && numCols == 1)
00628   {
00629     Doc * doc = m_pView->doc();
00630     cell = sheet->nonDefaultCell( m_targetRect.left(), m_targetRect.top() );
00631     if ( !doc->undoLocked() )
00632     {
00633       UndoSetText * undo = new UndoSetText( doc, sheet , cell->text(), m_targetRect.left(),
00634                                                           m_targetRect.top(), cell->formatType() );
00635       doc->addCommand( undo );
00636     }
00637   }
00638   else
00639   {
00640       UndoChangeAreaTextCell * undo = new UndoChangeAreaTextCell( m_pView->doc(), sheet , m_targetRect );
00641       m_pView->doc()->addCommand( undo );
00642   }
00643 
00644   m_pView->doc()->emitBeginOperation();
00645 
00646   int i;
00647   int left = m_targetRect.left();
00648   int top  = m_targetRect.top();
00649 
00650   QMemArray<double> widths( numCols );
00651   for ( i = 0; i < numCols; ++i )
00652   {
00653     ColumnFormat * c  = sheet->nonDefaultColumnFormat( left + i );
00654     widths[i] = c->dblWidth();
00655   }
00656 
00657   for (int row = 0; row < numRows; ++row)
00658   {
00659     for (int col = 0; col < numCols; ++col)
00660     {
00661       cell = sheet->nonDefaultCell( left + col, top + row );
00662       cell->setCellText( getText( row, col ) );
00663 
00664       QFontMetrics fm = sheet->painter().fontMetrics();
00665       double w = fm.width( cell->strOutText() );
00666       if ( w == 0.0 )
00667       {
00668         QFontMetrics fm( cell->format()->textFont( left + col, top + row ) );
00669         w = fm.width('x') * (double) getText( row, col ).length();
00670       }
00671 
00672       if ( w > widths[col] )
00673         widths[col] = w;
00674 
00675       cell->format()->setFormatType(Generic_format);
00676       /*
00677       Disabling this code for now, everything will use Generic formatting,
00678       hoping for the best (Tomas)
00679       //### FIXME: long term solution is to allow to select Generic format ("autodetect") in the dialog and make it the default
00680       
00681       switch (getHeader(col))
00682       {
00683        case TEXT:
00684         break;
00685        case NUMBER:
00686         cell->format()->setFormatType(Number_format);
00687         cell->setPrecision(2);
00688         break;
00689        case DATE:
00690         cell->format()->setFormatType(ShortDate_format);
00691         break;
00692        case CURRENCY:
00693         cell->format()->setFormatType(Money_format);
00694         break;
00695       }
00696       */
00697     }
00698   }
00699 
00700   for ( i = 0; i < numCols; ++i )
00701   {
00702     ColumnFormat * c  = sheet->nonDefaultColumnFormat( left + i );
00703     c->setDblWidth( widths[i] );
00704     sheet->emit_updateColumn( c, left + i );
00705   }
00706 
00707   m_pView->slotUpdateView( sheet );
00708   QDialog::accept();
00709 }
00710 
00711 int CSVDialog::getHeader(int col)
00712 {
00713   QString header = m_sheet->horizontalHeader()->label(col);
00714 
00715   if (header == i18n("Text"))
00716     return TEXT;
00717   else if (header == i18n("Number"))
00718     return NUMBER;
00719   else if (header == i18n("Currency"))
00720     return CURRENCY;
00721   else
00722     return DATE;
00723 }
00724 
00725 QString CSVDialog::getText(int row, int col)
00726 {
00727   return m_sheet->text(row, col);
00728 }
00729 
00730 void CSVDialog::ignoreDuplicatesChanged(int)
00731 {
00732   fillSheet();
00733 }
00734 
00735 #include "kspread_dlg_csv.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys