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