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