File indexing completed on 2024-04-21 05:51:48
0001 // SPDX-License-Identifier: GPL-2.0-or-later 0002 // SPDX-FileCopyrightText: 2007 Dominik Seichter <domseichter@web.de> 0003 0004 #include "tokenhelpdialog.h" 0005 0006 #include "batchrenamer.h" 0007 #include "krenamemodel.h" 0008 0009 #include <KSharedConfig> 0010 #include <KTreeWidgetSearchLine> 0011 #include <QPushButton> 0012 #include <KConfigGroup> 0013 #include <QDialogButtonBox> 0014 #include <QVBoxLayout> 0015 #include <QLineEdit> 0016 0017 #define COLUMN_PREVIEW 2 0018 0019 /** 0020 * A wrapper class for KRenameModel that 0021 * replaces display role with customer Qt::UserRole 0022 * so that the KRenameModel will always return unformatted 0023 * data, because QComboBox cannot display richtext. 0024 */ 0025 class KRenameUnformattedWrappedModel : public QAbstractListModel 0026 { 0027 Q_OBJECT 0028 public: 0029 KRenameUnformattedWrappedModel(KRenameModel *model) 0030 : m_model(model) 0031 { 0032 } 0033 0034 /** Get the file at position index. 0035 * 0036 * @param a valid index in the internal vector 0037 * 0038 * @returns a KRenameFile object 0039 */ 0040 const KRenameFile &file(int index) const 0041 { 0042 return m_model->file(index); 0043 } 0044 0045 /** Get the file at position index. 0046 * 0047 * @param a valid index in the internal vector 0048 * 0049 * @returns a KRenameFile object 0050 */ 0051 KRenameFile &file(int index) 0052 { 0053 return m_model->file(index); 0054 } 0055 0056 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override 0057 { 0058 if (role == Qt::DisplayRole) { 0059 return static_cast<KRenameModel *>(m_model)->data(index, Qt::UserRole); 0060 } else { 0061 return static_cast<KRenameModel *>(m_model)->data(index, role); 0062 } 0063 } 0064 0065 int rowCount(const QModelIndex &parent = QModelIndex()) const override 0066 { 0067 return m_model->rowCount(parent); 0068 } 0069 0070 private: 0071 KRenameModel *m_model; 0072 }; 0073 0074 const int TokenHelpDialog::S_MAX_RECENT = 10; 0075 0076 TokenHelpDialog::TokenHelpDialog(KRenameModel *model, BatchRenamer *renamer, 0077 QLineEdit *edit, QWidget *parent) 0078 : QDialog(parent), m_edit(edit), m_renamer(renamer) 0079 { 0080 m_model = new KRenameUnformattedWrappedModel(model); 0081 0082 QWidget *mainWidget = new QWidget(this); 0083 QVBoxLayout *mainLayout = new QVBoxLayout; 0084 setLayout(mainLayout); 0085 mainLayout->addWidget(mainWidget); 0086 m_widget.setupUi(mainWidget); 0087 0088 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); 0089 QPushButton *insert = new QPushButton; 0090 buttonBox->addButton(insert, QDialogButtonBox::ActionRole); 0091 this->connect(buttonBox, &QDialogButtonBox::accepted, 0092 this, &TokenHelpDialog::accept); 0093 this->connect(buttonBox, &QDialogButtonBox::rejected, 0094 this, &TokenHelpDialog::reject); 0095 mainLayout->addWidget(buttonBox); 0096 insert->setText(i18n("&Insert")); 0097 0098 QPushButton *close = buttonBox->button(QDialogButtonBox::Close); 0099 0100 m_widget.searchCategory->searchLine()->setTreeWidget(m_widget.listCategories); 0101 m_widget.searchToken ->searchLine()->setTreeWidget(m_widget.listTokens); 0102 m_widget.comboPreview->setModel(m_model); 0103 m_widget.listTokens->sortItems(0, Qt::AscendingOrder); 0104 0105 connect(insert, &QPushButton::clicked, 0106 this, &TokenHelpDialog::slotInsert); 0107 connect(close, &QPushButton::clicked, 0108 this, &TokenHelpDialog::saveConfig); 0109 0110 connect(m_widget.listCategories, &QTreeWidget::itemClicked, 0111 this, &TokenHelpDialog::slotCategoryChanged); 0112 connect(m_widget.listTokens, &QTreeWidget::itemClicked, 0113 this, &TokenHelpDialog::slotInsert); 0114 connect(m_widget.checkPreview, &QCheckBox::clicked, 0115 this, &TokenHelpDialog::slotPreviewClicked); 0116 connect(m_widget.comboPreview, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), 0117 this, &TokenHelpDialog::slotUpdatePreview); 0118 0119 slotEnableControls(); 0120 loadConfig(); 0121 } 0122 0123 TokenHelpDialog::~TokenHelpDialog() 0124 { 0125 delete m_model; 0126 } 0127 0128 const QString TokenHelpDialog::getTokenSeparator() 0129 { 0130 return QString::fromLatin1(";;"); 0131 } 0132 0133 void TokenHelpDialog::add(const QString &headline, const QStringList &commands, const QIcon &icon, bool first) 0134 { 0135 m_map[headline] = commands; 0136 0137 QTreeWidgetItem *item = new QTreeWidgetItem(m_widget.listCategories); 0138 item->setText(0, headline); 0139 item->setIcon(0, icon); 0140 0141 if (first) { 0142 m_first = headline; 0143 } 0144 } 0145 0146 int TokenHelpDialog::exec() 0147 { 0148 addRecentTokens(); 0149 0150 m_widget.listCategories->sortItems(0, Qt::AscendingOrder); 0151 0152 if (!m_lastSelected.isEmpty()) { 0153 selectCategory(m_lastSelected); 0154 } else if (!m_first.isEmpty()) { 0155 selectCategory(m_first); 0156 } 0157 0158 return QDialog::exec(); 0159 } 0160 0161 void TokenHelpDialog::selectCategory(const QString &category) 0162 { 0163 for (int i = 0; i < m_widget.listCategories->topLevelItemCount(); i++) 0164 if (m_widget.listCategories->topLevelItem(i)->text(0) == category) { 0165 m_widget.listCategories->topLevelItem(i)->setSelected(true); 0166 this->slotCategoryChanged(m_widget.listCategories->topLevelItem(i)); 0167 break; 0168 } 0169 } 0170 0171 void TokenHelpDialog::slotCategoryChanged(QTreeWidgetItem *item) 0172 { 0173 m_widget.listTokens->clear(); 0174 0175 const QStringList &commands = m_map[item->text(0)]; 0176 for (int i = 0; i < commands.count(); i++) { 0177 QTreeWidgetItem *item = new QTreeWidgetItem(m_widget.listTokens); 0178 item->setText(0, commands[i].section(getTokenSeparator(), 0, 0)); 0179 item->setText(1, commands[i].section(getTokenSeparator(), 1, 1)); 0180 } 0181 0182 slotUpdatePreview(); 0183 } 0184 0185 void TokenHelpDialog::slotInsert() 0186 { 0187 QTreeWidgetItem *category = m_widget.listCategories->currentItem(); 0188 if (category) { 0189 m_lastSelected = category->text(0); 0190 } 0191 0192 QTreeWidgetItem *item = m_widget.listTokens->currentItem(); 0193 if (item) { 0194 const QString &token = item->text(0); 0195 const QString &help = item->text(1); 0196 0197 addToRecentTokens(token, help); 0198 saveConfig(); 0199 0200 m_edit->insert(token); 0201 } 0202 0203 this->accept(); 0204 } 0205 0206 void TokenHelpDialog::loadConfig() 0207 { 0208 KSharedConfigPtr config = KSharedConfig::openConfig(); 0209 0210 KConfigGroup groupGui = config->group(QString("TokenHelpDialog")); 0211 0212 m_lastSelected = groupGui.readEntry("LastSelectedCategory", m_lastSelected); 0213 m_recent = groupGui.readEntry("RecentTokens", m_recent); 0214 0215 bool preview = groupGui.readEntry("Preview", m_widget.checkPreview->isChecked()); 0216 m_widget.checkPreview->setChecked(preview); 0217 0218 int width = groupGui.readEntry("Column0", QVariant(m_widget.listTokens->columnWidth(0))).toInt(); 0219 if (width > 0) { 0220 m_widget.listTokens->setColumnWidth(0, width); 0221 } 0222 0223 width = groupGui.readEntry("Column1", QVariant(m_widget.listTokens->columnWidth(1))).toInt(); 0224 if (width > 0) { 0225 m_widget.listTokens->setColumnWidth(1, width); 0226 } 0227 0228 width = groupGui.readEntry("Column2", QVariant(m_widget.listTokens->columnWidth(2))).toInt(); 0229 if (width > 0) { 0230 m_widget.listTokens->setColumnWidth(2, width); 0231 } 0232 0233 restoreGeometry(groupGui.readEntry<QByteArray>("Geometry", QByteArray())); 0234 0235 QList<int> sizes = groupGui.readEntry("Splitter", QList<int>()); 0236 if (sizes.size() == 2) { 0237 m_widget.splitter->setSizes(sizes); 0238 } 0239 } 0240 0241 void TokenHelpDialog::saveConfig() 0242 { 0243 KSharedConfigPtr config = KSharedConfig::openConfig(); 0244 0245 KConfigGroup groupGui = config->group(QString("TokenHelpDialog")); 0246 0247 groupGui.writeEntry("Column0", m_widget.listTokens->columnWidth(0)); 0248 groupGui.writeEntry("Column1", m_widget.listTokens->columnWidth(1)); 0249 groupGui.writeEntry("Column2", m_widget.listTokens->columnWidth(2)); 0250 groupGui.writeEntry("Splitter", m_widget.splitter->sizes()); 0251 groupGui.writeEntry("Preview", m_widget.checkPreview->isChecked()); 0252 groupGui.writeEntry("LastSelectedCategory", m_lastSelected); 0253 groupGui.writeEntry("RecentTokens", m_recent); 0254 0255 groupGui.writeEntry("Geometry", saveGeometry()); 0256 } 0257 0258 void TokenHelpDialog::slotEnableControls() 0259 { 0260 m_widget.comboPreview->setEnabled(m_widget.checkPreview->isChecked()); 0261 m_widget.labelPreview->setEnabled(m_widget.checkPreview->isChecked()); 0262 } 0263 0264 void TokenHelpDialog::slotPreviewClicked(bool bPreview) 0265 { 0266 slotEnableControls(); 0267 0268 if (bPreview) { 0269 m_widget.listTokens->setColumnHidden(COLUMN_PREVIEW, false); 0270 slotUpdatePreview(); 0271 0272 // make sure preview column is visible 0273 m_widget.listTokens->resizeColumnToContents(0); 0274 m_widget.listTokens->resizeColumnToContents(1); 0275 } else { 0276 m_widget.listTokens->setColumnHidden(COLUMN_PREVIEW, true); 0277 } 0278 } 0279 0280 void TokenHelpDialog::slotUpdatePreview() 0281 { 0282 if (!m_widget.checkPreview->isChecked()) { 0283 return; 0284 } 0285 0286 int index = m_widget.comboPreview->currentIndex(); 0287 if (index >= 0 && m_widget.listCategories->currentItem() != nullptr) { 0288 const KRenameFile &file = m_model->file(index); 0289 QApplication::setOverrideCursor(Qt::WaitCursor); 0290 0291 QString token; 0292 for (int i = 0; i < m_widget.listTokens->topLevelItemCount(); i++) { 0293 QTreeWidgetItem *item = m_widget.listTokens->topLevelItem(i); 0294 if (item) { 0295 token = m_renamer->processString(item->text(0), file.srcFilename(), index); 0296 item->setText(COLUMN_PREVIEW, token); 0297 } 0298 } 0299 QApplication::restoreOverrideCursor(); 0300 } 0301 } 0302 0303 void TokenHelpDialog::addRecentTokens() 0304 { 0305 this->add(i18n("Recent"), m_recent, QIcon::fromTheme("document-open-recent")); 0306 } 0307 0308 void TokenHelpDialog::addToRecentTokens(const QString &token, const QString &help) 0309 { 0310 // 1. Check if m_recent contains token and remove it 0311 QStringList::iterator it = m_recent.begin(); 0312 while (it != m_recent.end()) { 0313 if ((*it).startsWith(token + getTokenSeparator())) { 0314 m_recent.erase(it); 0315 break; 0316 } 0317 0318 ++it; 0319 } 0320 0321 // 2. remove first token if more than 10 0322 if (m_recent.count() >= S_MAX_RECENT) { 0323 m_recent.removeAt(0); 0324 } 0325 0326 // 3. append token 0327 QString recent = token + getTokenSeparator() + help; 0328 m_recent << recent; 0329 } 0330 0331 #include "tokenhelpdialog.moc" 0332 0333 #include "moc_tokenhelpdialog.cpp"