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 }