File indexing completed on 2022-10-04 17:30:22

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 }