File indexing completed on 2024-05-05 04:40:50
0001 /* 0002 SPDX-FileCopyrightText: 2010 Benjamin Port <port.benjamin@gmail.com> 0003 SPDX-FileCopyrightText: 2014 Kevin Funk <kfunk@kde.org> 0004 SPDX-FileCopyrightText: 2016 Andreas Cord-Landwehr <cordlandwehr@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "qthelpconfig.h" 0010 0011 #include <QHelpEngineCore> 0012 #include <QToolButton> 0013 #include <QHeaderView> 0014 #include <QPointer> 0015 0016 #include <KMessageBox> 0017 #include <KLocalizedString> 0018 #include <KNSWidgets/Button> 0019 #include <kio_version.h> 0020 0021 #include "ui_qthelpconfig.h" 0022 #include "ui_qthelpconfigeditdialog.h" 0023 #include "qthelp_config_shared.h" 0024 #include "debug.h" 0025 #include "qthelpplugin.h" 0026 0027 enum Column 0028 { 0029 NameColumn, 0030 PathColumn, 0031 IconColumn, 0032 GhnsColumn, 0033 ConfigColumn 0034 }; 0035 0036 class QtHelpConfigEditDialog : public QDialog, public Ui_QtHelpConfigEditDialog 0037 { 0038 Q_OBJECT 0039 public: 0040 explicit QtHelpConfigEditDialog(QTreeWidgetItem* modifiedItem, QtHelpConfig* parent = nullptr) 0041 : QDialog(parent) 0042 , m_modifiedItem(modifiedItem) 0043 , m_config(parent) 0044 { 0045 setupUi(this); 0046 #if KIO_VERSION >= QT_VERSION_CHECK(5, 108, 0) 0047 qchRequester->setNameFilter(i18n("Qt Compressed Help Files") + QLatin1String(" (*.qch)")); 0048 #else 0049 qchRequester->setFilter(QLatin1String("*.qch|") + i18n("Qt Compressed Help Files")); 0050 #endif 0051 0052 if (modifiedItem) { 0053 setWindowTitle(i18nc("@title:window", "Modify Entry")); 0054 } else { 0055 setWindowTitle(i18nc("@title:window", "Add New Entry")); 0056 } 0057 qchIcon->setIcon(QStringLiteral("qtlogo")); 0058 } 0059 0060 bool checkQtHelpFile(); 0061 0062 void accept() override; 0063 0064 private: 0065 QTreeWidgetItem* m_modifiedItem; 0066 QtHelpConfig* m_config; 0067 }; 0068 0069 bool QtHelpConfigEditDialog::checkQtHelpFile() 0070 { 0071 //verify if the file is valid and if there is a name 0072 if(qchName->text().isEmpty()){ 0073 KMessageBox::error(this, i18n("Name cannot be empty.")); 0074 return false; 0075 } 0076 0077 return m_config->checkNamespace(qchRequester->text(), m_modifiedItem); 0078 } 0079 0080 void QtHelpConfigEditDialog::accept() 0081 { 0082 if (!checkQtHelpFile()) 0083 return; 0084 0085 QDialog::accept(); 0086 } 0087 0088 QtHelpConfig::QtHelpConfig(QtHelpPlugin* plugin, QWidget *parent) 0089 : KDevelop::ConfigPage(plugin, nullptr, parent) 0090 { 0091 m_configWidget = new Ui::QtHelpConfigUI; 0092 m_configWidget->setupUi(this); 0093 m_configWidget->addButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); 0094 connect(m_configWidget->addButton, &QPushButton::clicked, this, &QtHelpConfig::add); 0095 0096 // Table 0097 m_configWidget->qchTable->setColumnHidden(IconColumn, true); 0098 m_configWidget->qchTable->setColumnHidden(GhnsColumn, true); 0099 m_configWidget->qchTable->model()->setHeaderData(ConfigColumn, Qt::Horizontal, QVariant()); 0100 m_configWidget->qchTable->header()->setSectionsMovable(false); 0101 m_configWidget->qchTable->header()->setStretchLastSection(false); 0102 m_configWidget->qchTable->header()->setSectionResizeMode(NameColumn, QHeaderView::Stretch); 0103 m_configWidget->qchTable->header()->setSectionResizeMode(PathColumn, QHeaderView::Stretch); 0104 m_configWidget->qchTable->header()->setSectionResizeMode(ConfigColumn, QHeaderView::Fixed); 0105 0106 // Add GHNS button 0107 auto* knsButton = new KNSWidgets::Button( 0108 i18nc("@action:button Allow user to get some API documentation with GHNS", "Get New Documentation"), 0109 QStringLiteral("kdevelop-qthelp.knsrc"), m_configWidget->boxQchManage); 0110 m_configWidget->tableCtrlLayout->insertWidget(1, knsButton); 0111 connect(knsButton, &KNSWidgets::Button::dialogFinished, this, &QtHelpConfig::knsUpdate); 0112 connect(m_configWidget->loadQtDocsCheckBox, &QCheckBox::toggled, 0113 this, QOverload<>::of(&QtHelpConfig::changed)); 0114 m_configWidget->qchSearchDir->setMode(KFile::Directory); 0115 connect(m_configWidget->qchSearchDir, &KUrlRequester::textChanged, 0116 this, &QtHelpConfig::changed); 0117 0118 // Set availability information for QtHelp 0119 m_configWidget->messageAvailabilityQtDocs->setCloseButtonVisible(false); 0120 if(plugin->isQtHelpAvailable()) { 0121 m_configWidget->messageAvailabilityQtDocs->setVisible(false); 0122 } else { 0123 m_configWidget->messageAvailabilityQtDocs->setText( 0124 i18n("The command \"qmake -query\" could not provide a path to a QtHelp file (QCH).")); 0125 m_configWidget->loadQtDocsCheckBox->setVisible(false); 0126 } 0127 reset(); 0128 } 0129 0130 QtHelpConfig::~QtHelpConfig() 0131 { 0132 delete m_configWidget; 0133 } 0134 0135 KDevelop::ConfigPage::ConfigPageType QtHelpConfig::configPageType() const 0136 { 0137 return KDevelop::ConfigPage::DocumentationConfigPage; 0138 } 0139 0140 void QtHelpConfig::apply() 0141 { 0142 QStringList iconList, nameList, pathList, ghnsList; 0143 for (int i = 0; i < m_configWidget->qchTable->topLevelItemCount(); i++) { 0144 const QTreeWidgetItem* item = m_configWidget->qchTable->topLevelItem(i); 0145 nameList << item->text(0); 0146 pathList << item->text(1); 0147 iconList << item->text(2); 0148 ghnsList << item->text(3); 0149 } 0150 QString searchDir = m_configWidget->qchSearchDir->text(); 0151 bool loadQtDoc = m_configWidget->loadQtDocsCheckBox->isChecked(); 0152 0153 qtHelpWriteConfig(iconList, nameList, pathList, ghnsList, searchDir, loadQtDoc); 0154 static_cast<QtHelpPlugin*>(plugin())->readConfig(); 0155 } 0156 0157 void QtHelpConfig::reset() 0158 { 0159 m_configWidget->qchTable->clear(); 0160 0161 QStringList iconList, nameList, pathList, ghnsList; 0162 QString searchDir; 0163 bool loadQtDoc; 0164 qtHelpReadConfig(iconList, nameList, pathList, ghnsList, searchDir, loadQtDoc); 0165 0166 const int size = qMin(qMin(iconList.size(), nameList.size()), pathList.size()); 0167 for(int i = 0; i < size; ++i) { 0168 QString ghnsStatus = ghnsList.size()>i ? ghnsList.at(i) : QStringLiteral("0"); 0169 addTableItem(iconList.at(i), nameList.at(i), pathList.at(i), ghnsStatus); 0170 } 0171 m_configWidget->qchSearchDir->setText(searchDir); 0172 m_configWidget->loadQtDocsCheckBox->setChecked(loadQtDoc); 0173 0174 emit changed(); 0175 } 0176 0177 void QtHelpConfig::defaults() 0178 { 0179 bool change = false; 0180 if(m_configWidget->qchTable->topLevelItemCount() > 0) { 0181 m_configWidget->qchTable->clear(); 0182 change = true; 0183 } 0184 if(!m_configWidget->loadQtDocsCheckBox->isChecked()){ 0185 m_configWidget->loadQtDocsCheckBox->setChecked(true); 0186 change = true; 0187 } 0188 0189 if (change) { 0190 emit changed(); 0191 } 0192 } 0193 0194 void QtHelpConfig::add() 0195 { 0196 QPointer<QtHelpConfigEditDialog> dialog = new QtHelpConfigEditDialog(nullptr, this); 0197 if (dialog->exec()) { 0198 QTreeWidgetItem* item = addTableItem(dialog->qchIcon->icon(), dialog->qchName->text(), dialog->qchRequester->text(), QStringLiteral("0")); 0199 m_configWidget->qchTable->setCurrentItem(item); 0200 emit changed(); 0201 } 0202 delete dialog; 0203 } 0204 0205 void QtHelpConfig::modify(QTreeWidgetItem* item) 0206 { 0207 if (!item) 0208 return; 0209 0210 QPointer<QtHelpConfigEditDialog> dialog = new QtHelpConfigEditDialog(item, this); 0211 if (item->text(GhnsColumn) != QLatin1String("0")) { 0212 dialog->qchRequester->setText(i18n("Documentation provided by GHNS")); 0213 dialog->qchRequester->setEnabled(false); 0214 } else { 0215 dialog->qchRequester->setText(item->text(PathColumn)); 0216 dialog->qchRequester->setEnabled(true); 0217 } 0218 dialog->qchName->setText(item->text(NameColumn)); 0219 dialog->qchIcon->setIcon(item->text(IconColumn)); 0220 if (dialog->exec()) { 0221 item->setIcon(NameColumn, QIcon(dialog->qchIcon->icon())); 0222 item->setText(NameColumn, dialog->qchName->text()); 0223 item->setText(IconColumn, dialog->qchIcon->icon()); 0224 if(item->text(GhnsColumn) == QLatin1String("0")) { 0225 item->setText(PathColumn, dialog->qchRequester->text()); 0226 } 0227 0228 emit changed(); 0229 } 0230 delete dialog; 0231 } 0232 0233 bool QtHelpConfig::checkNamespace(const QString& filename, QTreeWidgetItem* modifiedItem) 0234 { 0235 QString qtHelpNamespace = QHelpEngineCore::namespaceName(filename); 0236 if (qtHelpNamespace.isEmpty()) { 0237 // Open error message (not valid Qt Compressed Help file) 0238 KMessageBox::error(this, i18n("Qt Compressed Help file is not valid.")); 0239 return false; 0240 } 0241 // verify if it's the namespace it's not already in the list 0242 for(int i=0; i < m_configWidget->qchTable->topLevelItemCount(); i++) { 0243 const QTreeWidgetItem* item = m_configWidget->qchTable->topLevelItem(i); 0244 if (item != modifiedItem){ 0245 if (qtHelpNamespace == QHelpEngineCore::namespaceName(item->text(PathColumn))) { 0246 // Open error message, documentation already imported 0247 KMessageBox::error(this, i18n("Documentation already imported")); 0248 return false; 0249 } 0250 } 0251 } 0252 return true; 0253 } 0254 0255 void QtHelpConfig::remove(QTreeWidgetItem* item) 0256 { 0257 if (!item) 0258 return; 0259 0260 delete item; 0261 emit changed(); 0262 } 0263 0264 void QtHelpConfig::knsUpdate(const QList<KNSCore::Entry>& list) 0265 { 0266 if (list.isEmpty()) 0267 return; 0268 0269 for (const auto& e : list) { 0270 if(e.status() == KNS3::Entry::Installed) { 0271 // For zipped/tarred QCH fules KNewStuff also adds the directory as installed file, first file entry is assumed to be QCH file though 0272 if (e.installedFiles().size() >= 1) { 0273 QString filename = e.installedFiles().at(0); 0274 if(checkNamespace(filename, nullptr)){ 0275 QTreeWidgetItem* item = addTableItem(QStringLiteral("documentation"), e.name(), filename, QStringLiteral("1")); 0276 m_configWidget->qchTable->setCurrentItem(item); 0277 } else { 0278 qCDebug(QTHELP) << "namespace error"; 0279 } 0280 } 0281 } else if(e.status() == KNS3::Entry::Deleted) { 0282 // cmp. note above for installed files 0283 if (e.uninstalledFiles().size() >= 1) { 0284 for(int i=0; i < m_configWidget->qchTable->topLevelItemCount(); i++) { 0285 QTreeWidgetItem* item = m_configWidget->qchTable->topLevelItem(i); 0286 if (e.uninstalledFiles().at(0) == item->text(PathColumn)) { 0287 delete item; 0288 break; 0289 } 0290 } 0291 } 0292 } 0293 } 0294 emit changed(); 0295 } 0296 0297 QString QtHelpConfig::name() const 0298 { 0299 return i18nc("@title:tab", "Qt Help"); 0300 } 0301 0302 QString QtHelpConfig::fullName() const 0303 { 0304 return i18nc("@title:tab", "Configure Qt Help Settings"); 0305 } 0306 0307 QIcon QtHelpConfig::icon() const 0308 { 0309 return QIcon::fromTheme(QStringLiteral("qtlogo")); 0310 } 0311 0312 QTreeWidgetItem * QtHelpConfig::addTableItem(const QString &icon, const QString &name, 0313 const QString &path, const QString &ghnsStatus) 0314 { 0315 auto *item = new QTreeWidgetItem(m_configWidget->qchTable); 0316 item->setIcon(NameColumn, QIcon::fromTheme(icon)); 0317 item->setText(NameColumn, name); 0318 item->setToolTip(NameColumn, name); 0319 item->setText(PathColumn, path); 0320 item->setToolTip(PathColumn, path); 0321 item->setText(IconColumn, icon); 0322 item->setText(GhnsColumn, ghnsStatus); 0323 0324 auto* ctrlWidget = new QWidget(item->treeWidget()); 0325 ctrlWidget->setLayout(new QHBoxLayout(ctrlWidget)); 0326 0327 auto *modifyBtn = new QToolButton(item->treeWidget()); 0328 modifyBtn->setIcon(QIcon::fromTheme(QStringLiteral("document-edit"))); 0329 modifyBtn->setToolTip(i18nc("@info:tooltip", "Modify")); 0330 connect(modifyBtn, &QPushButton::clicked, this, [=](){ 0331 modify(item); 0332 }); 0333 auto *removeBtn = new QToolButton(item->treeWidget()); 0334 removeBtn->setIcon(QIcon::fromTheme(QStringLiteral("entry-delete"))); 0335 removeBtn->setToolTip(i18nc("@info:tooltip", "Delete")); 0336 if (item->text(GhnsColumn) != QLatin1String("0")) { 0337 // KNS3 currently does not provide API to uninstall entries 0338 // just removing the files results in wrong installed states in the KNS3 dialog 0339 // TODO: add API to KNS to remove files without UI interaction 0340 removeBtn->setEnabled(false); 0341 removeBtn->setToolTip(i18nc("@info:tooltip", "Please uninstall this via GHNS.")); 0342 } else { 0343 connect(removeBtn, &QPushButton::clicked, this, [=](){ 0344 remove(item); 0345 }); 0346 } 0347 ctrlWidget->layout()->addWidget(modifyBtn); 0348 ctrlWidget->layout()->addWidget(removeBtn); 0349 m_configWidget->qchTable->setItemWidget(item, ConfigColumn, ctrlWidget); 0350 0351 return item; 0352 } 0353 0354 #include "qthelpconfig.moc" 0355 #include "moc_qthelpconfig.cpp"