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