Warning, file /office/calligra/libs/widgets/KoCsvImportDialog.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 Copyright (C) 1999 David Faure <faure@kde.org> 0003 Copyright (C) 2004 Nicolas GOUTTE <goutte@kde.org> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "KoCsvImportDialog.h" 0022 0023 // Qt 0024 #include <QButtonGroup> 0025 #include <QTextCodec> 0026 #include <QTextStream> 0027 0028 #include <QTableWidget> 0029 #include <QTableWidgetSelectionRange> 0030 0031 // KF5 0032 #include <kcharsets.h> 0033 #include <kconfig.h> 0034 #include <WidgetsDebug.h> 0035 #include <klocalizedstring.h> 0036 #include <kmessagebox.h> 0037 #include <ksharedconfig.h> 0038 0039 #include "ui_KoCsvImportDialog.h" 0040 0041 class KoCsvImportWidget : public QWidget, public Ui::KoCsvImportWidget 0042 { 0043 Q_OBJECT 0044 public: 0045 explicit KoCsvImportWidget(QWidget* parent) : QWidget(parent) { setupUi(this); } 0046 }; 0047 0048 0049 class Q_DECL_HIDDEN KoCsvImportDialog::Private 0050 { 0051 public: 0052 KoCsvImportDialog* q; 0053 KoCsvImportWidget* dialog; 0054 0055 bool rowsAdjusted; 0056 bool columnsAdjusted; 0057 int startRow; 0058 int startCol; 0059 int endRow; 0060 int endCol; 0061 QChar textQuote; 0062 QString delimiter; 0063 QString commentSymbol; 0064 bool ignoreDuplicates; 0065 QByteArray data; 0066 QTextCodec* codec; 0067 QStringList formatList; ///< List of the column formats 0068 0069 explicit Private(KoCsvImportDialog* qq) : q(qq) {} 0070 void loadSettings(); 0071 void saveSettings(); 0072 void fillTable(); 0073 void setText(int row, int col, const QString& text); 0074 void adjustRows(int iRows); 0075 void adjustCols(int iCols); 0076 bool checkUpdateRange(); 0077 QTextCodec* updateCodec() const; 0078 }; 0079 0080 KoCsvImportDialog::KoCsvImportDialog(QWidget* parent) 0081 : KoDialog(parent) 0082 , d(new Private(this)) 0083 { 0084 d->dialog = new KoCsvImportWidget(this); 0085 d->rowsAdjusted = false; 0086 d->columnsAdjusted = false; 0087 d->startRow = 0; 0088 d->startCol = 0; 0089 d->endRow = -1; 0090 d->endCol = -1; 0091 d->textQuote = QChar('"'); 0092 d->delimiter = QString(','); 0093 d->commentSymbol = QString('#'); 0094 d->ignoreDuplicates = false; 0095 d->codec = QTextCodec::codecForName("UTF-8"); 0096 0097 setButtons( KoDialog::Ok|KoDialog::Cancel ); 0098 setCaption( i18n( "Import Data" ) ); 0099 0100 QStringList encodings; 0101 encodings << i18nc( "Descriptive encoding name", "Recommended ( %1 )" ,"UTF-8" ); 0102 encodings << i18nc( "Descriptive encoding name", "Locale ( %1 )" ,QString(QTextCodec::codecForLocale()->name() )); 0103 encodings += KCharsets::charsets()->descriptiveEncodingNames(); 0104 // Add a few non-standard encodings, which might be useful for text files 0105 const QString description(i18nc("Descriptive encoding name","Other ( %1 )")); 0106 encodings << description.arg("Apple Roman"); // Apple 0107 encodings << description.arg("IBM 850") << description.arg("IBM 866"); // MS DOS 0108 encodings << description.arg("CP 1258"); // Windows 0109 d->dialog->comboBoxEncoding->insertItems( 0, encodings ); 0110 0111 setDataTypes(Generic|Text|Date|None); 0112 0113 // XXX: Qt3->Q4 0114 //d->dialog->m_sheet->setReadOnly( true ); 0115 0116 d->loadSettings(); 0117 0118 //resize(sizeHint()); 0119 resize( 600, 400 ); // Try to show as much as possible of the table view 0120 setMainWidget(d->dialog); 0121 0122 d->dialog->m_sheet->setSelectionMode( QAbstractItemView::MultiSelection ); 0123 0124 QButtonGroup* buttonGroup = new QButtonGroup( this ); 0125 buttonGroup->addButton(d->dialog->m_radioComma, 0); 0126 buttonGroup->addButton(d->dialog->m_radioSemicolon, 1); 0127 buttonGroup->addButton(d->dialog->m_radioSpace, 2); 0128 buttonGroup->addButton(d->dialog->m_radioTab, 3); 0129 buttonGroup->addButton(d->dialog->m_radioOther, 4); 0130 0131 connect(d->dialog->m_formatComboBox, SIGNAL(activated(QString)), 0132 this, SLOT(formatChanged(QString))); 0133 connect(buttonGroup, SIGNAL(buttonClicked(int)), 0134 this, SLOT(delimiterClicked(int))); 0135 connect(d->dialog->m_delimiterEdit, SIGNAL(returnPressed()), 0136 this, SLOT(returnPressed())); 0137 connect(d->dialog->m_delimiterEdit, SIGNAL(textChanged(QString)), 0138 this, SLOT(genericDelimiterChanged(QString))); 0139 connect(d->dialog->m_comboQuote, SIGNAL(activated(QString)), 0140 this, SLOT(textquoteSelected(QString))); 0141 connect(d->dialog->m_sheet, SIGNAL(currentCellChanged(int,int,int,int)), 0142 this, SLOT(currentCellChanged(int,int))); 0143 connect(d->dialog->m_ignoreDuplicates, SIGNAL(stateChanged(int)), 0144 this, SLOT(ignoreDuplicatesChanged(int))); 0145 connect(d->dialog->m_updateButton, SIGNAL(clicked()), 0146 this, SLOT(updateClicked())); 0147 connect(d->dialog->comboBoxEncoding, SIGNAL(textChanged(QString)), 0148 this, SLOT(encodingChanged(QString))); 0149 } 0150 0151 0152 KoCsvImportDialog::~KoCsvImportDialog() 0153 { 0154 d->saveSettings(); 0155 delete d; 0156 } 0157 0158 0159 // ---------------------------------------------------------------- 0160 // public methods 0161 0162 0163 void KoCsvImportDialog::setData( const QByteArray& data ) 0164 { 0165 d->data = data; 0166 d->fillTable(); 0167 } 0168 0169 0170 bool KoCsvImportDialog::firstRowContainHeaders() const 0171 { 0172 return d->dialog->m_firstRowHeader->isChecked(); 0173 } 0174 0175 0176 bool KoCsvImportDialog::firstColContainHeaders() const 0177 { 0178 return d->dialog->m_firstColHeader->isChecked(); 0179 } 0180 0181 0182 int KoCsvImportDialog::rows() const 0183 { 0184 int rows = d->dialog->m_sheet->rowCount(); 0185 0186 if ( d->endRow >= 0 ) 0187 rows = d->endRow - d->startRow + 1; 0188 0189 return rows; 0190 } 0191 0192 0193 int KoCsvImportDialog::cols() const 0194 { 0195 int cols = d->dialog->m_sheet->columnCount(); 0196 0197 if ( d->endCol >= 0 ) 0198 cols = d->endCol - d->startCol + 1; 0199 0200 return cols; 0201 } 0202 0203 0204 QString KoCsvImportDialog::text(int row, int col) const 0205 { 0206 // Check for overflow. 0207 if ( row >= rows() || col >= cols()) 0208 return QString(); 0209 0210 QTableWidgetItem* item = d->dialog->m_sheet->item( row - d->startRow, col - d->startCol ); 0211 if ( !item ) 0212 return QString(); 0213 return item->text(); 0214 } 0215 0216 void KoCsvImportDialog::setDataTypes(DataTypes dataTypes) 0217 { 0218 d->formatList.clear(); 0219 if (dataTypes & Generic) 0220 d->formatList << i18n("Generic"); 0221 if (dataTypes & Text) 0222 d->formatList << i18n("Text"); 0223 if (dataTypes & Date) 0224 d->formatList << i18n("Date"); 0225 if (dataTypes & Currency) 0226 d->formatList << i18n("Currency"); 0227 if (dataTypes & None) 0228 d->formatList << i18n("None"); 0229 d->dialog->m_formatComboBox->insertItems(0, d->formatList); 0230 } 0231 0232 void KoCsvImportDialog::setDataWidgetEnabled(bool enable) 0233 { 0234 d->dialog->m_tabWidget->setTabEnabled(0, enable); 0235 } 0236 0237 QString KoCsvImportDialog::decimalSymbol() const 0238 { 0239 return d->dialog->m_decimalSymbol->text(); 0240 } 0241 0242 void KoCsvImportDialog::setDecimalSymbol(const QString& symbol) 0243 { 0244 d->dialog->m_decimalSymbol->setText(symbol); 0245 } 0246 0247 QString KoCsvImportDialog::thousandsSeparator() const 0248 { 0249 return d->dialog->m_thousandsSeparator->text(); 0250 } 0251 0252 void KoCsvImportDialog::setThousandsSeparator(const QString& separator) 0253 { 0254 d->dialog->m_thousandsSeparator->setText(separator); 0255 } 0256 0257 QString KoCsvImportDialog::delimiter() const 0258 { 0259 return d->delimiter; 0260 } 0261 0262 void KoCsvImportDialog::setDelimiter(const QString& delimit) 0263 { 0264 d->delimiter = delimit; 0265 if (delimit == ",") 0266 d->dialog->m_radioComma->setChecked(true); 0267 else if (delimit == "\t") 0268 d->dialog->m_radioTab->setChecked(true); 0269 else if (delimit == " ") 0270 d->dialog->m_radioSpace->setChecked(true); 0271 else if (delimit == ";") 0272 d->dialog->m_radioSemicolon->setChecked(true); 0273 else { 0274 d->dialog->m_radioOther->setChecked(true); 0275 d->dialog->m_delimiterEdit->setText(delimit); 0276 } 0277 } 0278 0279 0280 // ---------------------------------------------------------------- 0281 0282 0283 void KoCsvImportDialog::Private::loadSettings() 0284 { 0285 KConfigGroup configGroup = KSharedConfig::openConfig()->group("CSVDialog Settings"); 0286 textQuote = configGroup.readEntry("textQuote", "\"").at(0); 0287 delimiter = configGroup.readEntry("delimiter", ","); 0288 ignoreDuplicates = configGroup.readEntry("ignoreDups", false); 0289 const QString codecText = configGroup.readEntry("codec", ""); 0290 0291 // update widgets 0292 if (!codecText.isEmpty()) { 0293 dialog->comboBoxEncoding->setCurrentIndex(dialog->comboBoxEncoding->findText(codecText)); 0294 codec = updateCodec(); 0295 } 0296 q->setDelimiter(delimiter); 0297 dialog->m_ignoreDuplicates->setChecked(ignoreDuplicates); 0298 dialog->m_comboQuote->setCurrentIndex(textQuote == '\'' ? 1 : textQuote == '"' ? 0 : 2); 0299 } 0300 0301 void KoCsvImportDialog::Private::saveSettings() 0302 { 0303 KConfigGroup configGroup = KSharedConfig::openConfig()->group("CSVDialog Settings"); 0304 configGroup.writeEntry("textQuote", QString(textQuote)); 0305 configGroup.writeEntry("delimiter", delimiter); 0306 configGroup.writeEntry("ignoreDups", ignoreDuplicates); 0307 configGroup.writeEntry("codec", dialog->comboBoxEncoding->currentText()); 0308 configGroup.sync(); 0309 } 0310 0311 void KoCsvImportDialog::Private::fillTable() 0312 { 0313 int row, column; 0314 bool lastCharDelimiter = false; 0315 enum { Start, InQuotedField, MaybeQuotedFieldEnd, QuotedFieldEnd, 0316 MaybeInNormalField, InNormalField } state = Start; 0317 0318 QChar x; 0319 QString field; 0320 0321 QApplication::setOverrideCursor(Qt::WaitCursor); 0322 0323 dialog->m_sheet->setRowCount(0); 0324 dialog->m_sheet->setColumnCount(0); 0325 0326 int maxColumn = 1; 0327 row = column = 1; 0328 QTextStream inputStream(data, QIODevice::ReadOnly); 0329 debugWidgets <<"Encoding:" << codec->name(); 0330 inputStream.setCodec( codec ); 0331 0332 int delimiterIndex = 0; 0333 const int delimiterLength = delimiter.size(); 0334 bool lastCharWasCr = false; // Last character was a Carriage Return 0335 while (!inputStream.atEnd()) 0336 { 0337 inputStream >> x; // read one char 0338 0339 // ### TODO: we should perhaps skip all other control characters 0340 if ( x == '\r' ) 0341 { 0342 // We have a Carriage Return, assume that its role is the one of a LineFeed 0343 lastCharWasCr = true; 0344 x = '\n'; // Replace by Line Feed 0345 } 0346 else if ( x == '\n' && lastCharWasCr ) 0347 { 0348 // The end of line was already handled by the Carriage Return, so do nothing for this character 0349 lastCharWasCr = false; 0350 continue; 0351 } 0352 else if ( x == QChar( 0xc ) ) 0353 { 0354 // We have a FormFeed, skip it 0355 lastCharWasCr = false; 0356 continue; 0357 } 0358 else 0359 { 0360 lastCharWasCr = false; 0361 } 0362 0363 if ( column > maxColumn ) 0364 maxColumn = column; 0365 switch (state) 0366 { 0367 case Start : 0368 if (x == textQuote) 0369 { 0370 state = InQuotedField; 0371 } 0372 else if (delimiterIndex < delimiterLength && x == delimiter.at(delimiterIndex)) 0373 { 0374 field += x; 0375 delimiterIndex++; 0376 if (field.right(delimiterIndex) == delimiter) 0377 { 0378 if ((ignoreDuplicates == false) || (lastCharDelimiter == false)) 0379 column += delimiterLength; 0380 lastCharDelimiter = true; 0381 field.clear(); 0382 delimiterIndex = 0; 0383 state = Start; 0384 } 0385 else if (delimiterIndex >= delimiterLength) 0386 delimiterIndex = 0; 0387 } 0388 else if (x == '\n') 0389 { 0390 ++row; 0391 column = 1; 0392 if ( row > ( endRow - startRow ) && endRow >= 0 ) 0393 break; 0394 } 0395 else 0396 { 0397 field += x; 0398 state = MaybeInNormalField; 0399 } 0400 break; 0401 case InQuotedField : 0402 if (x == textQuote) 0403 { 0404 state = MaybeQuotedFieldEnd; 0405 } 0406 else if (x == '\n') 0407 { 0408 setText(row - startRow, column - startCol, field); 0409 field.clear(); 0410 0411 ++row; 0412 column = 1; 0413 if ( row > ( endRow - startRow ) && endRow >= 0 ) 0414 break; 0415 0416 state = Start; 0417 } 0418 else 0419 { 0420 field += x; 0421 } 0422 break; 0423 case MaybeQuotedFieldEnd : 0424 if (x == textQuote) 0425 { 0426 field += x; 0427 state = InQuotedField; 0428 } 0429 else if (x == '\n') 0430 { 0431 setText(row - startRow, column - startCol, field); 0432 field.clear(); 0433 ++row; 0434 column = 1; 0435 if ( row > ( endRow - startRow ) && endRow >= 0 ) 0436 break; 0437 state = Start; 0438 } 0439 else if (delimiterIndex < delimiterLength && x == delimiter.at(delimiterIndex)) 0440 { 0441 field += x; 0442 delimiterIndex++; 0443 if (field.right(delimiterIndex) == delimiter) 0444 { 0445 setText(row - startRow, column - startCol, field.left(field.count()-delimiterIndex)); 0446 field.clear(); 0447 if ((ignoreDuplicates == false) || (lastCharDelimiter == false)) 0448 column += delimiterLength; 0449 lastCharDelimiter = true; 0450 field.clear(); 0451 delimiterIndex = 0; 0452 } 0453 else if (delimiterIndex >= delimiterLength) 0454 delimiterIndex = 0; 0455 state = Start; 0456 } 0457 else 0458 { 0459 state = QuotedFieldEnd; 0460 } 0461 break; 0462 case QuotedFieldEnd : 0463 if (x == '\n') 0464 { 0465 setText(row - startRow, column - startCol, field); 0466 field.clear(); 0467 ++row; 0468 column = 1; 0469 if ( row > ( endRow - startRow ) && endRow >= 0 ) 0470 break; 0471 state = Start; 0472 } 0473 else if (delimiterIndex < delimiterLength && x == delimiter.at(delimiterIndex)) 0474 { 0475 field += x; 0476 delimiterIndex++; 0477 if (field.right(delimiterIndex) == delimiter) 0478 { 0479 setText(row - startRow, column - startCol, field.left(field.count()-delimiterIndex)); 0480 field.clear(); 0481 if ((ignoreDuplicates == false) || (lastCharDelimiter == false)) 0482 column += delimiterLength; 0483 lastCharDelimiter = true; 0484 field.clear(); 0485 delimiterIndex = 0; 0486 } 0487 else if (delimiterIndex >= delimiterLength) 0488 delimiterIndex = 0; 0489 state = Start; 0490 } 0491 else 0492 { 0493 state = QuotedFieldEnd; 0494 } 0495 break; 0496 case MaybeInNormalField : 0497 if (x == textQuote) 0498 { 0499 field.clear(); 0500 state = InQuotedField; 0501 break; 0502 } 0503 state = InNormalField; 0504 case InNormalField : 0505 if (x == '\n') 0506 { 0507 setText(row - startRow, column - startCol, field); 0508 field.clear(); 0509 ++row; 0510 column = 1; 0511 if ( row > ( endRow - startRow ) && endRow >= 0 ) 0512 break; 0513 state = Start; 0514 } 0515 else if (delimiterIndex < delimiterLength && x == delimiter.at(delimiterIndex)) 0516 { 0517 field += x; 0518 delimiterIndex++; 0519 if (field.right(delimiterIndex) == delimiter) 0520 { 0521 setText(row - startRow, column - startCol, field.left(field.count()-delimiterIndex)); 0522 field.clear(); 0523 if ((ignoreDuplicates == false) || (lastCharDelimiter == false)) 0524 column += delimiterLength; 0525 lastCharDelimiter = true; 0526 field.clear(); 0527 delimiterIndex = 0; 0528 } 0529 else if (delimiterIndex >= delimiterLength) 0530 delimiterIndex = 0; 0531 state = Start; 0532 } 0533 else 0534 { 0535 field += x; 0536 } 0537 } 0538 if (delimiter.isEmpty() || x != delimiter.at(0)) 0539 lastCharDelimiter = false; 0540 } 0541 0542 if ( !field.isEmpty() ) 0543 { 0544 // the last line of the file had not any line end 0545 setText(row - startRow, column - startCol, field); 0546 ++row; 0547 field.clear(); 0548 } 0549 if (row) row--; // row is higher by 1, so reduce it 0550 0551 columnsAdjusted = true; 0552 adjustRows( row - startRow ); 0553 adjustCols( maxColumn - startCol ); 0554 0555 for (column = 0; column < dialog->m_sheet->columnCount(); ++column) 0556 { 0557 const QTableWidgetItem* headerItem = dialog->m_sheet->horizontalHeaderItem(column); 0558 if (!headerItem || !formatList.contains(headerItem->text())) { 0559 dialog->m_sheet->setHorizontalHeaderItem(column, new QTableWidgetItem(i18n("Generic"))); 0560 } 0561 } 0562 0563 dialog->m_rowStart->setMinimum(1); 0564 dialog->m_colStart->setMinimum(1); 0565 dialog->m_rowStart->setMaximum(row); 0566 dialog->m_colStart->setMaximum(maxColumn); 0567 0568 dialog->m_rowEnd->setMinimum(1); 0569 dialog->m_colEnd->setMinimum(1); 0570 dialog->m_rowEnd->setMaximum(row); 0571 dialog->m_colEnd->setMaximum(maxColumn); 0572 dialog->m_rowEnd->setValue(endRow == -1 ? row : endRow); 0573 dialog->m_colEnd->setValue(endCol == -1 ? maxColumn : endCol); 0574 0575 QApplication::restoreOverrideCursor(); 0576 } 0577 0578 KoCsvImportDialog::DataType KoCsvImportDialog::dataType(int col) const 0579 { 0580 const QString header = d->dialog->m_sheet->model()->headerData(col, Qt::Horizontal).toString(); 0581 0582 if (header == i18n("Generic")) 0583 return Generic; 0584 else if (header == i18n("Text")) 0585 return Text; 0586 else if (header == i18n("Date")) 0587 return Date; 0588 else if (header == i18n("Currency")) 0589 return Currency; 0590 else if (header == i18n("None")) 0591 return None; 0592 return Generic; 0593 } 0594 0595 void KoCsvImportDialog::Private::setText(int row, int col, const QString& text) 0596 { 0597 if (row < 1 || col < 1) // skipped by the user 0598 return; 0599 0600 if ((row > (endRow - startRow) && endRow > 0) || (col > (endCol - startCol) && endCol > 0)) 0601 return; 0602 0603 if (dialog->m_sheet->rowCount() < row) 0604 { 0605 dialog->m_sheet->setRowCount(row + 5000); /* We add 5000 at a time to limit recalculations */ 0606 rowsAdjusted = true; 0607 } 0608 0609 if (dialog->m_sheet->columnCount() < col) 0610 { 0611 dialog->m_sheet->setColumnCount(col); 0612 columnsAdjusted = true; 0613 } 0614 0615 QTableWidgetItem* item = dialog->m_sheet->item(row - 1, col - 1); 0616 if (!item) { 0617 item = new QTableWidgetItem(); 0618 dialog->m_sheet->setItem(row - 1, col - 1, item); 0619 } 0620 item->setText(text); 0621 } 0622 0623 /* 0624 * Called after the first fillTable() when number of rows are unknown. 0625 */ 0626 void KoCsvImportDialog::Private::adjustRows(int iRows) 0627 { 0628 if (rowsAdjusted) 0629 { 0630 dialog->m_sheet->setRowCount(iRows); 0631 rowsAdjusted = false; 0632 } 0633 } 0634 0635 void KoCsvImportDialog::Private::adjustCols(int iCols) 0636 { 0637 if (columnsAdjusted) 0638 { 0639 dialog->m_sheet->setColumnCount(iCols); 0640 columnsAdjusted = false; 0641 0642 if (endCol == -1) 0643 { 0644 if (iCols > (endCol - startCol)) 0645 iCols = endCol - startCol; 0646 0647 dialog->m_sheet->setColumnCount(iCols); 0648 } 0649 } 0650 } 0651 0652 void KoCsvImportDialog::returnPressed() 0653 { 0654 if (d->dialog->m_radioOther->isChecked()) 0655 return; 0656 0657 d->delimiter = d->dialog->m_delimiterEdit->text(); 0658 d->fillTable(); 0659 } 0660 0661 void KoCsvImportDialog::genericDelimiterChanged( const QString & ) 0662 { 0663 d->dialog->m_radioOther->setChecked ( true ); 0664 delimiterClicked(d->dialog->m_radioOther->group()->id(d->dialog->m_radioOther)); // other 0665 } 0666 0667 void KoCsvImportDialog::formatChanged( const QString& newValue ) 0668 { 0669 QList<QTableWidgetSelectionRange> selectionRanges = d->dialog->m_sheet->selectedRanges(); 0670 foreach (const QTableWidgetSelectionRange &selectionRange, selectionRanges) { 0671 for (int j = selectionRange.leftColumn(); j <= selectionRange.rightColumn(); ++j) { 0672 d->dialog->m_sheet->horizontalHeaderItem(j)->setText(newValue); 0673 } 0674 } 0675 } 0676 0677 void KoCsvImportDialog::delimiterClicked(int id) 0678 { 0679 const QButtonGroup* group = d->dialog->m_radioComma->group(); 0680 if (id == group->id(d->dialog->m_radioComma) ) 0681 d->delimiter = ','; 0682 else if (id == group->id(d->dialog->m_radioOther)) 0683 d->delimiter = d->dialog->m_delimiterEdit->text(); 0684 else if (id == group->id(d->dialog->m_radioTab)) 0685 d->delimiter = '\t'; 0686 else if (id == group->id(d->dialog->m_radioSpace)) 0687 d->delimiter = ' '; 0688 else if (id == group->id(d->dialog->m_radioSemicolon)) 0689 d->delimiter = ';'; 0690 0691 debugWidgets << "Delimiter" << d->delimiter << "selected."; 0692 d->fillTable(); 0693 } 0694 0695 void KoCsvImportDialog::textquoteSelected(const QString& mark) 0696 { 0697 if (mark == i18n("None")) 0698 d->textQuote = 0; 0699 else 0700 d->textQuote = mark[0]; 0701 0702 d->fillTable(); 0703 } 0704 0705 void KoCsvImportDialog::updateClicked() 0706 { 0707 if ( !d->checkUpdateRange() ) 0708 return; 0709 0710 d->startRow = d->dialog->m_rowStart->value() - 1; 0711 d->endRow = d->dialog->m_rowEnd->value(); 0712 0713 d->startCol = d->dialog->m_colStart->value() - 1; 0714 d->endCol = d->dialog->m_colEnd->value(); 0715 0716 d->fillTable(); 0717 } 0718 0719 bool KoCsvImportDialog::Private::checkUpdateRange() 0720 { 0721 if ((dialog->m_rowStart->value() > dialog->m_rowEnd->value()) || 0722 (dialog->m_colStart->value() > dialog->m_colEnd->value())) 0723 { 0724 KMessageBox::error(0, i18n("Please check the ranges you specified. The start value must be lower than the end value.")); 0725 return false; 0726 } 0727 return true; 0728 } 0729 0730 void KoCsvImportDialog::currentCellChanged(int, int col) 0731 { 0732 const QString header = d->dialog->m_sheet->model()->headerData(col, Qt::Horizontal).toString(); 0733 const int index = d->dialog->m_formatComboBox->findText(header); 0734 d->dialog->m_formatComboBox->setCurrentIndex(index > -1 ? index : 0); 0735 } 0736 0737 void KoCsvImportDialog::ignoreDuplicatesChanged(int) 0738 { 0739 if (d->dialog->m_ignoreDuplicates->isChecked()) 0740 d->ignoreDuplicates = true; 0741 else 0742 d->ignoreDuplicates = false; 0743 d->fillTable(); 0744 } 0745 0746 QTextCodec* KoCsvImportDialog::Private::updateCodec() const 0747 { 0748 const QString strCodec( KCharsets::charsets()->encodingForName( dialog->comboBoxEncoding->currentText() ) ); 0749 debugWidgets <<"Encoding:" << strCodec; 0750 0751 bool ok = false; 0752 QTextCodec* codec = QTextCodec::codecForName( strCodec.toUtf8() ); 0753 0754 // If QTextCodec has not found a valid encoding, so try with KCharsets. 0755 if ( codec ) 0756 { 0757 ok = true; 0758 } 0759 else 0760 { 0761 codec = KCharsets::charsets()->codecForName( strCodec, ok ); 0762 } 0763 0764 // Still nothing? 0765 if ( !codec || !ok ) 0766 { 0767 // Default: UTF-8 0768 warnWidgets << "Cannot find encoding:" << strCodec; 0769 // ### TODO: what parent to use? 0770 KMessageBox::error( 0, i18n("Cannot find encoding: %1", strCodec ) ); 0771 return 0; 0772 } 0773 0774 return codec; 0775 } 0776 0777 void KoCsvImportDialog::encodingChanged(const QString &) 0778 { 0779 QTextCodec* codec = d->updateCodec(); 0780 0781 if ( codec ) 0782 { 0783 d->codec = codec; 0784 d->fillTable(); 0785 } 0786 } 0787 #include "KoCsvImportDialog.moc"