File indexing completed on 2025-01-19 13:27:13
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 "csvexportdialog.h" 0022 #include "csvexport.h" 0023 0024 #include "sheets/Map.h" 0025 #include "sheets/Sheet.h" 0026 0027 #include <kcharsets.h> 0028 #include <kmessagebox.h> 0029 #include <KSharedConfig> 0030 0031 #include <QGuiApplication> 0032 #include <QTextCodec> 0033 #include <QValidator> 0034 #include <QDebug> 0035 0036 using namespace Calligra::Sheets; 0037 0038 CSVExportDialog::CSVExportDialog(QWidget * parent) 0039 : KoDialog(parent), 0040 m_dialog(new ExportDialogUI(this)), 0041 m_delimiter(","), 0042 m_textquote('"') 0043 { 0044 setButtons(KoDialog::Ok | KoDialog::Cancel); 0045 setDefaultButton(KoDialog::Ok); 0046 QGuiApplication::restoreOverrideCursor(); 0047 0048 QStringList encodings; 0049 encodings << i18nc("Descriptive encoding name", "Recommended ( %1 )" , "UTF-8"); 0050 encodings << i18nc("Descriptive encoding name", "Locale ( %1 )" , QString(QTextCodec::codecForLocale()->name())); 0051 encodings += KCharsets::charsets()->descriptiveEncodingNames(); 0052 // Add a few non-standard encodings, which might be useful for text files 0053 const QString description(i18nc("Descriptive encoding name", "Other ( %1 )")); 0054 encodings << description.arg("Apple Roman"); // Apple 0055 encodings << description.arg("IBM 850") << description.arg("IBM 866"); // MS DOS 0056 encodings << description.arg("CP 1258"); // Windows 0057 0058 m_dialog->comboBoxEncoding->addItems(encodings); 0059 0060 setMainWidget(m_dialog); 0061 0062 // Invalid 'Other' delimiters 0063 // - Quotes 0064 // - CR,LF,Vertical-tab,Formfeed,ASCII bel 0065 QRegExp rx("^[^\"'\r\n\v\f\a]{0,1}$"); 0066 m_delimiterValidator = new QRegExpValidator(rx, m_dialog->m_delimiterBox); 0067 m_dialog->m_delimiterEdit->setValidator(m_delimiterValidator); 0068 0069 connect(m_dialog->m_delimiterBox, SIGNAL(clicked(int)), 0070 this, SLOT(delimiterClicked(int))); 0071 connect(m_dialog->m_delimiterEdit, SIGNAL(returnPressed()), 0072 this, SLOT(returnPressed())); 0073 connect(m_dialog->m_delimiterEdit, SIGNAL(textChanged(QString)), 0074 this, SLOT(textChanged(QString))); 0075 connect(m_dialog->m_comboQuote, SIGNAL(activated(QString)), 0076 this, SLOT(textquoteSelected(QString))); 0077 connect(m_dialog->m_selectionOnly, SIGNAL(toggled(bool)), 0078 this, SLOT(selectionOnlyChanged(bool))); 0079 connect(this, SIGNAL(okClicked()), SLOT(slotOk())); 0080 connect(this, SIGNAL(cancelClicked()), this, SLOT(slotCancel())); 0081 0082 loadSettings(); 0083 } 0084 0085 CSVExportDialog::~CSVExportDialog() 0086 { 0087 saveSettings(); 0088 QGuiApplication::setOverrideCursor(Qt::WaitCursor); 0089 delete m_delimiterValidator; 0090 } 0091 0092 void CSVExportDialog::loadSettings() 0093 { 0094 KConfigGroup configGroup = KSharedConfig::openConfig()->group("CSVDialog Settings"); 0095 m_textquote = configGroup.readEntry("textQuote", "\"")[0]; 0096 m_delimiter = configGroup.readEntry("delimiter", ","); 0097 const QString codecText = configGroup.readEntry("codec", ""); 0098 bool selectionOnly = configGroup.readEntry("selectionOnly", false); 0099 const QString sheetDelim = configGroup.readEntry("sheetDelimiter", m_dialog->m_sheetDelimiter->text()); 0100 bool delimAbove = configGroup.readEntry("sheetDelimiterAbove", false); 0101 const QString eol = configGroup.readEntry("eol", "\r\n"); 0102 0103 // update widgets 0104 if (!codecText.isEmpty()) { 0105 m_dialog->comboBoxEncoding->setCurrentIndex(m_dialog->comboBoxEncoding->findText(codecText)); 0106 } 0107 if (m_delimiter == ",") 0108 m_dialog->m_radioComma->setChecked(true); 0109 else if (m_delimiter == "\t") 0110 m_dialog->m_radioTab->setChecked(true); 0111 else if (m_delimiter == " ") 0112 m_dialog->m_radioSpace->setChecked(true); 0113 else if (m_delimiter == ";") 0114 m_dialog->m_radioSemicolon->setChecked(true); 0115 else { 0116 m_dialog->m_radioOther->setChecked(true); 0117 m_dialog->m_delimiterEdit->setText(m_delimiter); 0118 } 0119 m_dialog->m_comboQuote->setCurrentIndex(m_textquote == '\'' ? 1 : m_textquote == '"' ? 0 : 2); 0120 m_dialog->m_selectionOnly->setChecked(selectionOnly); 0121 m_dialog->m_sheetDelimiter->setText(sheetDelim); 0122 m_dialog->m_delimiterAboveAll->setChecked(delimAbove); 0123 if (eol == "\r\n") 0124 m_dialog->radioEndOfLineCRLF->setChecked(true); 0125 else if (eol == "\r") 0126 m_dialog->radioEndOfLineCR->setChecked(true); 0127 else 0128 m_dialog->radioEndOfLineLF->setChecked(true); 0129 } 0130 0131 void CSVExportDialog::saveSettings() 0132 { 0133 KConfigGroup configGroup = KSharedConfig::openConfig()->group("CSVDialog Settings"); 0134 configGroup.writeEntry("textQuote", QString(m_textquote)); 0135 configGroup.writeEntry("delimiter", m_delimiter); 0136 configGroup.writeEntry("codec", m_dialog->comboBoxEncoding->currentText()); 0137 configGroup.writeEntry("selectionOnly", exportSelectionOnly()); 0138 configGroup.writeEntry("sheetDelimiter", getSheetDelimiter()); 0139 configGroup.writeEntry("sheetDelimiterAbove", printAlwaysSheetDelimiter()); 0140 configGroup.writeEntry("eol", getEndOfLine()); 0141 configGroup.sync(); 0142 } 0143 0144 void CSVExportDialog::fillSheet(Map * map) 0145 { 0146 m_dialog->m_sheetList->clear(); 0147 QListWidgetItem *item; 0148 0149 foreach(Sheet* sheet, map->sheetList()) { 0150 item = new QListWidgetItem(sheet->sheetName() ,m_dialog->m_sheetList); 0151 item->setCheckState(Qt::Checked); 0152 m_dialog->m_sheetList->addItem(item); 0153 } 0154 } 0155 0156 QChar CSVExportDialog::getDelimiter() const 0157 { 0158 return m_delimiter[0]; 0159 } 0160 0161 QChar CSVExportDialog::getTextQuote() const 0162 { 0163 return m_textquote; 0164 } 0165 0166 bool CSVExportDialog::printAlwaysSheetDelimiter() const 0167 { 0168 return m_dialog->m_delimiterAboveAll->isChecked(); 0169 } 0170 0171 QString CSVExportDialog::getSheetDelimiter() const 0172 { 0173 return m_dialog->m_sheetDelimiter->text(); 0174 } 0175 0176 bool CSVExportDialog::exportSheet(QString const & sheetName) const 0177 { 0178 for (int i = 0; i < m_dialog->m_sheetList->count(); ++i) { 0179 QListWidgetItem *const item = m_dialog->m_sheetList->item(i); 0180 if (item->checkState() == Qt::Checked) { 0181 if (item->text() == sheetName) { 0182 return true; 0183 } 0184 } 0185 } 0186 return false; 0187 } 0188 0189 void CSVExportDialog::slotOk() 0190 { 0191 accept(); 0192 } 0193 0194 void CSVExportDialog::slotCancel() 0195 { 0196 reject(); 0197 } 0198 0199 void CSVExportDialog::returnPressed() 0200 { 0201 if (!m_dialog->m_radioOther->isChecked()) 0202 return; 0203 0204 m_delimiter = m_dialog->m_delimiterEdit->text(); 0205 } 0206 0207 void CSVExportDialog::textChanged(const QString &) 0208 { 0209 0210 if (m_dialog->m_delimiterEdit->text().isEmpty()) { 0211 enableButtonOk(! m_dialog->m_radioOther->isChecked()); 0212 return; 0213 } 0214 0215 m_dialog->m_radioOther->setChecked(true); 0216 delimiterClicked(4); 0217 } 0218 0219 void CSVExportDialog::delimiterClicked(int id) 0220 { 0221 enableButtonOk(true); 0222 0223 //Erase "Other Delimiter" text box if the user has selected one of 0224 //the standard options instead (comma, semicolon, tab or space) 0225 if (id != 4) 0226 m_dialog->m_delimiterEdit->setText(""); 0227 0228 switch (id) { 0229 case 0: // comma 0230 m_delimiter = ","; 0231 break; 0232 case 1: // semicolon 0233 m_delimiter = ";"; 0234 break; 0235 case 2: // tab 0236 m_delimiter = "\t"; 0237 break; 0238 case 3: // space 0239 m_delimiter = " "; 0240 break; 0241 case 4: // other 0242 enableButtonOk(! m_dialog->m_delimiterEdit->text().isEmpty()); 0243 m_delimiter = m_dialog->m_delimiterEdit->text(); 0244 break; 0245 } 0246 } 0247 0248 void CSVExportDialog::textquoteSelected(const QString & mark) 0249 { 0250 m_textquote = mark[0]; 0251 } 0252 0253 void CSVExportDialog::selectionOnlyChanged(bool on) 0254 { 0255 m_dialog->m_sheetList->setEnabled(!on); 0256 m_dialog->m_delimiterLineBox->setEnabled(!on); 0257 0258 if (on) 0259 m_dialog->m_tabWidget->setCurrentIndex(1); 0260 } 0261 0262 bool CSVExportDialog::exportSelectionOnly() const 0263 { 0264 return m_dialog->m_selectionOnly->isChecked(); 0265 } 0266 0267 QTextCodec* CSVExportDialog::getCodec(void) const 0268 { 0269 const QString strCodec(KCharsets::charsets()->encodingForName(m_dialog->comboBoxEncoding->currentText())); 0270 qDebug(lcCsvExport) << "Encoding:" << strCodec; 0271 0272 bool ok = false; 0273 QTextCodec* codec = QTextCodec::codecForName(strCodec.toUtf8()); 0274 0275 // If QTextCodec has not found a valid encoding, so try with KCharsets. 0276 if (codec) { 0277 ok = true; 0278 } else { 0279 codec = KCharsets::charsets()->codecForName(strCodec, ok); 0280 } 0281 0282 // Still nothing? 0283 if (!codec || !ok) { 0284 // Default: UTF-8 0285 qWarning(lcCsvExport) << "Cannot find encoding:" << strCodec; 0286 // ### TODO: what parent to use? 0287 KMessageBox::error(0, i18n("Cannot find encoding: %1", strCodec)); 0288 return 0; 0289 } 0290 0291 return codec; 0292 } 0293 0294 QString CSVExportDialog::getEndOfLine(void) const 0295 { 0296 QString strReturn; 0297 if (m_dialog->radioEndOfLineLF->isChecked()) 0298 strReturn = "\n"; 0299 else if (m_dialog->radioEndOfLineCRLF->isChecked()) 0300 strReturn = "\r\n"; 0301 else if (m_dialog->radioEndOfLineCR->isChecked()) 0302 strReturn = "\r"; 0303 else 0304 strReturn = "\n"; 0305 0306 return strReturn; 0307 }