File indexing completed on 2024-12-08 13:34:35
0001 /*************************************************************************** 0002 replacedialog.cpp - description 0003 ------------------- 0004 begin : Sun Jul 22 2007 0005 copyright : (C) 2007 by Dominik Seichter 0006 email : domseichter@web.de 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This program is free software; you can redistribute it and/or modify * 0012 * it under the terms of the GNU General Public License as published by * 0013 * the Free Software Foundation; either version 2 of the License, or * 0014 * (at your option) any later version. * 0015 * * 0016 ***************************************************************************/ 0017 0018 #include "replacedialog.h" 0019 0020 #include <QFileDialog> 0021 #include <QTextStream> 0022 #include <QMessageBox> 0023 #include <QDomDocument> 0024 #include <QDomElement> 0025 0026 #include <KLocalizedString> 0027 #include <KMessageBox> 0028 0029 #include <iostream> 0030 0031 #include "ui_replaceitemdlg.h" 0032 #include "batchrenamer.h" 0033 0034 ReplaceDialog::ReplaceDialog(const QList<TReplaceItem> &items, QWidget *parent) 0035 : QDialog(parent) 0036 { 0037 m_widget.setupUi(this); 0038 0039 connect(m_widget.buttonBox, &QDialogButtonBox::accepted, 0040 this, &ReplaceDialog::accept); 0041 connect(m_widget.buttonBox, &QDialogButtonBox::rejected, 0042 this, &ReplaceDialog::reject); 0043 0044 connect(m_widget.buttonAdd, &QPushButton::clicked, 0045 this, &ReplaceDialog::slotAdd); 0046 connect(m_widget.buttonRemove, &QPushButton::clicked, 0047 this, &ReplaceDialog::slotRemove); 0048 connect(m_widget.buttonEdit, &QPushButton::clicked, 0049 this, &ReplaceDialog::slotEdit); 0050 0051 connect(m_widget.buttonLoadList, &QPushButton::clicked, 0052 this, &ReplaceDialog::slotLoadList); 0053 connect(m_widget.buttonSaveList, &QPushButton::clicked, 0054 this, &ReplaceDialog::slotSaveList); 0055 0056 connect(m_widget.list, &QTableWidget::itemSelectionChanged, 0057 this, &ReplaceDialog::slotEnableControls); 0058 0059 this->slotEnableControls(); 0060 0061 QList<TReplaceItem>::const_iterator it = items.begin(); 0062 while (it != items.end()) { 0063 int row = m_widget.list->rowCount(); 0064 m_widget.list->setRowCount(row + 1); 0065 0066 m_widget.list->setItem(row, 0, this->createTableItem("", true)); 0067 m_widget.list->item(row, 0)->setCheckState((*it).reg ? Qt::Checked : Qt::Unchecked); 0068 m_widget.list->setItem(row, 1, this->createTableItem((*it).find)); 0069 m_widget.list->setItem(row, 2, this->createTableItem((*it).replace)); 0070 m_widget.list->setItem(row, 3, this->createTableItem("", true)); 0071 m_widget.list->item(row, 3)->setCheckState((*it).doProcessTokens ? Qt::Checked : Qt::Unchecked); 0072 0073 ++it; 0074 } 0075 } 0076 0077 void ReplaceDialog::slotSaveList() 0078 { 0079 QTableWidget *table = m_widget.list; 0080 0081 QString fileName = QFileDialog::getSaveFileName(this, i18n("Save Find & Replace Settings as:"), 0082 QDir::currentPath(), i18n("KRename Find & Replace Settings XML (*.xml)")); 0083 0084 if (fileName.isEmpty()) { 0085 return; 0086 } 0087 0088 QFile f(fileName); 0089 0090 if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) { 0091 KMessageBox::error(this, i18n("Failed to save the Find & Replace Settings File.")); 0092 return; 0093 } 0094 0095 QTextStream data(&f); 0096 0097 QDomDocument xmlDocument("KRename"); 0098 QDomElement root = xmlDocument.createElement("KRename"); 0099 root.setAttribute("version", "1.0"); 0100 0101 QDomElement frElement = xmlDocument.createElement("FindReplaceList"); 0102 frElement.setAttribute("rows", table->rowCount()); 0103 root.appendChild(frElement); 0104 0105 for (int r = 0; r < table->rowCount(); ++r) { 0106 QDomElement RegExpElement = xmlDocument.createElement("RegularExpression"); 0107 QDomElement FindElement = xmlDocument.createElement("Find"); 0108 QDomElement ReplaceWithElement = xmlDocument.createElement("ReplaceWith"); 0109 QDomElement ProcessTokensElement = xmlDocument.createElement("ProcessTokens"); 0110 QDomElement RowElement = xmlDocument.createElement("Row"); 0111 RowElement.setAttribute("num", r); 0112 0113 int RegExpCheck = static_cast<int>(table->item(r, 0)->checkState()); 0114 QString RegExpCheckStr = QString::number(RegExpCheck, 10); 0115 0116 RegExpElement.appendChild(xmlDocument.createTextNode(RegExpCheckStr)); 0117 RowElement.appendChild(RegExpElement); 0118 0119 FindElement.appendChild(xmlDocument.createTextNode(table->item(r, 1)->data(Qt::EditRole).toString())); 0120 RowElement.appendChild(FindElement); 0121 ReplaceWithElement.appendChild(xmlDocument.createTextNode(table->item(r, 2)->data(Qt::EditRole).toString())); 0122 RowElement.appendChild(ReplaceWithElement); 0123 0124 int ProcessTokensCheck = static_cast<int>(table->item(r, 3)->checkState()); 0125 QString ProcessTokensCheckStr = QString::number(ProcessTokensCheck, 10); 0126 ProcessTokensElement.appendChild(xmlDocument.createTextNode(ProcessTokensCheckStr)); 0127 RowElement.appendChild(ProcessTokensElement); 0128 0129 frElement.appendChild(RowElement); 0130 0131 } 0132 xmlDocument.appendChild(root); 0133 0134 data << xmlDocument.toString(-1); 0135 f.close(); 0136 0137 } 0138 0139 void ReplaceDialog::slotLoadList() 0140 { 0141 QTableWidget *table = m_widget.list; 0142 0143 QString fileName = QFileDialog::getOpenFileName(this, i18n("Save Find and Replace Settings File"), 0144 QDir::currentPath(), 0145 i18n("KRename Find and Replace Settings XML (*.xml)")); 0146 if (fileName.isEmpty()) { 0147 return; 0148 } 0149 //open file 0150 QFile f(fileName); 0151 if (!f.open(QFile::ReadOnly | QFile::Text)) { 0152 KMessageBox::error(this, 0153 i18n("Failed to open the Find and Replace Settings File. Cannot read file %1:\n%2.", fileName, f.errorString())); 0154 return; 0155 } 0156 //load XML 0157 QIODevice *device = &f; 0158 QDomDocument xmlDocument; 0159 QString errorStr; 0160 int errorLine; 0161 int errorColumn; 0162 0163 if (!xmlDocument.setContent(device, true, &errorStr, &errorLine, &errorColumn)) { 0164 KMessageBox::information(window(), i18n("KRename Find and Replace Settings XML File"), 0165 i18n("Parse error at line %1, column %2:\n%3", 0166 errorLine, errorColumn, errorStr)); 0167 return; 0168 } 0169 0170 QDomElement root = xmlDocument.documentElement(); 0171 // check if valid 0172 if (root.tagName() != "KRename") { 0173 KMessageBox::information(window(), 0174 i18n("The file is not a KRename XML file."), 0175 i18n("KRename Find and Replace Settings XML File")); 0176 return; 0177 } else if (root.hasAttribute("version") && root.attribute("version") != "1.0") { 0178 KMessageBox::information(window(), 0179 i18n("The file is not an KRename XML version 1.0 file."), 0180 i18n("KRename Find and Replace Settings XML File")); 0181 return; 0182 } 0183 //parse XML file 0184 0185 QDomElement frElement = root.firstChild().toElement(); 0186 0187 int Rows; 0188 bool ok; 0189 Rows = frElement.attribute("rows").toInt(&ok, 10); 0190 table->setRowCount(Rows); 0191 int rc; 0192 rc = 0; 0193 0194 QDomElement RowElement = frElement.firstChildElement("Row"); 0195 while (!RowElement.isNull()) { 0196 0197 QString RegExpCheckStr = RowElement.firstChildElement("RegularExpression").text(); 0198 int RegExpCheck = RegExpCheckStr.toInt(); 0199 0200 switch (RegExpCheck) { 0201 case 0 : 0202 table->setItem(rc, 0, this->createTableItem("", true)); 0203 table->item(rc, 0)->setCheckState(Qt::Unchecked); 0204 break; 0205 case 1 : 0206 table->setItem(rc, 0, this->createTableItem("", true)); 0207 table->item(rc, 0)->setCheckState(Qt::PartiallyChecked); 0208 break; 0209 case 2 : 0210 table->setItem(rc, 0, this->createTableItem("", true)); 0211 table->item(rc, 0)->setCheckState(Qt::Checked); 0212 break; 0213 default : 0214 break; 0215 } 0216 0217 table->setItem(rc, 1, this->createTableItem(RowElement.firstChildElement("Find").text())); 0218 table->setItem(rc, 2, this->createTableItem(RowElement.firstChildElement("ReplaceWith").text())); 0219 0220 QString ProcessTokensCheckStr = RowElement.firstChildElement("ProcessTokens").text(); 0221 int ProcessTokensCheck = ProcessTokensCheckStr.toInt(); 0222 0223 switch (ProcessTokensCheck) { 0224 case 0 : 0225 table->setItem(rc, 3, this->createTableItem("", true)); 0226 table->item(rc, 3)->setCheckState(Qt::Unchecked); 0227 break; 0228 case 1 : 0229 table->setItem(rc, 3, this->createTableItem("", true)); 0230 table->item(rc, 3)->setCheckState(Qt::PartiallyChecked); 0231 break; 0232 case 2 : 0233 table->setItem(rc, 3, this->createTableItem("", true)); 0234 table->item(rc, 3)->setCheckState(Qt::Checked); 0235 break; 0236 default : 0237 break; 0238 } 0239 0240 RowElement = RowElement.nextSiblingElement("Row"); 0241 rc = rc + 1; 0242 } 0243 if (rc != Rows) { 0244 KMessageBox::information(window(), 0245 i18n("Problem with loading KRename XML file."), 0246 i18n("KRename Find and Replace Settings XML File")); 0247 return; 0248 } 0249 } 0250 0251 void ReplaceDialog::slotAdd() 0252 { 0253 QDialog dlg; 0254 Ui::ReplaceItemDlg replace; 0255 replace.setupUi(&dlg); 0256 0257 if (dlg.exec() == QDialog::Accepted) { 0258 int row = m_widget.list->rowCount(); 0259 m_widget.list->setRowCount(row + 1); 0260 m_widget.list->setItem(row, 0, this->createTableItem("", true)); 0261 m_widget.list->item(row, 0)->setCheckState(replace.checkRegular->isChecked() ? Qt::Checked : Qt::Unchecked); 0262 m_widget.list->setItem(row, 1, this->createTableItem(replace.lineFind->text())); 0263 m_widget.list->setItem(row, 2, this->createTableItem(replace.lineReplace->text())); 0264 m_widget.list->setItem(row, 3, this->createTableItem("", true)); 0265 m_widget.list->item(row, 3)->setCheckState(replace.checkProcess->isChecked() ? Qt::Checked : Qt::Unchecked); 0266 } 0267 int row = m_widget.list->rowCount(); 0268 m_widget.buttonSaveList->setEnabled(row); 0269 } 0270 0271 void ReplaceDialog::slotEdit() 0272 { 0273 QDialog dlg; 0274 Ui::ReplaceItemDlg replace; 0275 replace.setupUi(&dlg); 0276 0277 int row = m_widget.list->currentRow(); 0278 replace.checkRegular->setChecked(m_widget.list->item(row, 0)->checkState() == Qt::Checked); 0279 replace.lineFind->setText(m_widget.list->item(row, 1)->text()); 0280 replace.lineReplace->setText(m_widget.list->item(row, 2)->text()); 0281 replace.checkProcess->setChecked(m_widget.list->item(row, 3)->checkState() == Qt::Checked); 0282 0283 if (dlg.exec() == QDialog::Accepted) { 0284 m_widget.list->setItem(row, 0, this->createTableItem("", true)); 0285 m_widget.list->item(row, 0)->setCheckState(replace.checkRegular->isChecked() ? Qt::Checked : Qt::Unchecked); 0286 m_widget.list->setItem(row, 1, this->createTableItem(replace.lineFind->text())); 0287 m_widget.list->setItem(row, 2, this->createTableItem(replace.lineReplace->text())); 0288 m_widget.list->setItem(row, 3, this->createTableItem("", true)); 0289 m_widget.list->item(row, 3)->setCheckState(replace.checkProcess->isChecked() ? Qt::Checked : Qt::Unchecked); 0290 } 0291 } 0292 0293 void ReplaceDialog::slotRemove() 0294 { 0295 m_widget.list->removeRow(m_widget.list->currentRow()); 0296 int row = m_widget.list->rowCount(); 0297 m_widget.buttonSaveList->setEnabled(row); 0298 } 0299 0300 void ReplaceDialog::slotEnableControls() 0301 { 0302 QList<QTableWidgetItem *> selected = m_widget.list->selectedItems(); 0303 0304 m_widget.buttonEdit->setEnabled(selected.count()); 0305 m_widget.buttonRemove->setEnabled(selected.count()); 0306 0307 m_widget.buttonLoadList->setEnabled(true); 0308 0309 int row = m_widget.list->rowCount(); 0310 m_widget.buttonSaveList->setEnabled(row); 0311 } 0312 0313 QTableWidgetItem *ReplaceDialog::createTableItem(const QString &text, bool isCheckable) 0314 { 0315 // TODO: Enclose text in quotes, but remove them before the item is edited by the user directly in the table 0316 // and add them again if the user presses enter. 0317 QString t = text; // text.isEmpty() ? QString::null : "\"" + text + "\""; 0318 QTableWidgetItem *item = new QTableWidgetItem(t); 0319 0320 if (isCheckable) { 0321 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); 0322 } else { 0323 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled); 0324 } 0325 0326 return item; 0327 } 0328 0329 QList<TReplaceItem> ReplaceDialog::replaceList() const 0330 { 0331 QList<TReplaceItem> items; 0332 0333 for (int i = 0; i < m_widget.list->rowCount(); i++) { 0334 TReplaceItem item; 0335 item.reg = m_widget.list->item(i, 0)->checkState() == Qt::Checked; 0336 item.find = m_widget.list->item(i, 1)->text(); 0337 item.replace = m_widget.list->item(i, 2)->text(); 0338 item.doProcessTokens = m_widget.list->item(i, 3)->checkState() == Qt::Checked; 0339 items.append(item); 0340 } 0341 0342 return items; 0343 }