File indexing completed on 2024-05-05 17:15:11

0001 /*****************************************************************************************
0002     begin                : Sun Apr 27 2003
0003     copyright            : (C) 2003 by Jeroen Wijnhout (wijnhout@science.uva.nl)
0004                                2007 by Michel Ludwig (michel.ludwig@kdemail.net)
0005  *****************************************************************************************/
0006 
0007 /***************************************************************************
0008  *                                                                         *
0009  *   This program is free software; you can redistribute it and/or modify  *
0010  *   it under the terms of the GNU General Public License as published by  *
0011  *   the Free Software Foundation; either version 2 of the License, or     *
0012  *   (at your option) any later version.                                   *
0013  *                                                                         *
0014  ***************************************************************************/
0015 
0016 #include "dialogs/managetemplatesdialog.h"
0017 
0018 #include <QCheckBox>
0019 #include <QDialogButtonBox>
0020 #include <QFileInfo>
0021 #include <QGridLayout>
0022 #include <QLabel>
0023 #include <QLayout>
0024 #include <QLineEdit>
0025 #include <QPushButton>
0026 #include <QTreeWidget>
0027 #include <QUrl>
0028 #include <QVBoxLayout>
0029 
0030 #include <KConfigGroup>
0031 #include <KIconDialog>
0032 #include <KIconLoader>
0033 #include <KIO/Job>
0034 #include <KJobWidgets>
0035 #include <KLocalizedString>
0036 #include <KMessageBox>
0037 
0038 #include "kiledebug.h"
0039 #include "kileextensions.h"
0040 #include "kileinfo.h"
0041 #include "templates.h"
0042 #include "utilities.h"
0043 
0044 class TemplateListViewItem : public QTreeWidgetItem {
0045 public:
0046     TemplateListViewItem(QTreeWidget* parent, QTreeWidgetItem* preceding, const QString& mode, const KileTemplate::Info& info) : QTreeWidgetItem(parent, preceding), m_info(info) {
0047         setText(0, mode);
0048         setText(1, info.name);
0049         setText(2, KileInfo::documentTypeToString(info.type));
0050     }
0051 
0052     virtual ~TemplateListViewItem() {
0053     }
0054 
0055     KileTemplate::Info getTemplateInfo() {
0056         return m_info;
0057     }
0058 
0059 protected:
0060     KileTemplate::Info m_info;
0061 };
0062 
0063 // dialog to create a template
0064 ManageTemplatesDialog::ManageTemplatesDialog(KileTemplate::Manager *templateManager, const QUrl &sourceURL, const QString &caption, QWidget *parent, const char *name)
0065     : QDialog(parent)
0066     , m_templateManager(templateManager)
0067     , m_sourceURL(sourceURL)
0068 {
0069     setObjectName(name);
0070     setWindowTitle(caption);
0071     setModal(true);
0072     QVBoxLayout *mainLayout = new QVBoxLayout;
0073     setLayout(mainLayout);
0074 
0075     m_templateType = KileDocument::Extensions().determineDocumentType(sourceURL);
0076 
0077     QWidget *page = new QWidget(this);
0078     page->setObjectName("managetemplates_mainwidget");
0079     mainLayout->addWidget(page);
0080     QGridLayout *topLayout = new QGridLayout();
0081     topLayout->setContentsMargins(0, 0, 0, 0);
0082     page->setLayout(topLayout);
0083 
0084     topLayout->addWidget(new QLabel(i18n("Name:"), page), 0, 0);
0085 
0086     QString fileName = m_sourceURL.fileName();
0087     //remove the extension
0088     int dotPos = fileName.lastIndexOf('.');
0089     if (dotPos >= 0) {
0090         fileName = fileName.mid(0, dotPos);
0091     }
0092     m_nameEdit = new QLineEdit(fileName, page);
0093     mainLayout->addWidget(m_nameEdit);
0094     topLayout->addWidget(m_nameEdit, 0, 1);
0095 
0096     topLayout->addWidget(new QLabel(i18n("Type: %1", KileInfo::documentTypeToString(m_templateType)), page), 0, 2);
0097     topLayout->addWidget(new QLabel(i18n("Icon:"), page), 1, 0);
0098 
0099     m_iconEdit = new QLineEdit(KileUtilities::locate(QStandardPaths::AppDataLocation, "pics/type_Default.png"), page);
0100     mainLayout->addWidget(m_iconEdit);
0101     topLayout->addWidget(m_iconEdit, 1, 1);
0102 
0103     QPushButton *iconbut = new QPushButton(i18n("Select..."), page);
0104     mainLayout->addWidget(iconbut);
0105     topLayout->addWidget(iconbut, 1, 2);
0106 
0107     m_templateList = new QTreeWidget(page);
0108     mainLayout->addWidget(m_templateList);
0109     m_templateList->setSortingEnabled(false);
0110     m_templateList->setHeaderLabels(QStringList() << i18nc("marked", "M")
0111                                     << i18n("Existing Templates")
0112                                     << i18n("Document Type"));
0113     m_templateList->setAllColumnsShowFocus(true);
0114     m_templateList->setRootIsDecorated(false);
0115 
0116     populateTemplateListView(m_templateType);
0117 
0118     topLayout->addWidget(m_templateList, 2, 0, 1, 3);
0119 
0120     m_showAllTypesCheckBox = new QCheckBox(i18n("Show all the templates"), page);
0121     mainLayout->addWidget(m_showAllTypesCheckBox);
0122     m_showAllTypesCheckBox->setChecked(false);
0123     connect(m_showAllTypesCheckBox, &QCheckBox::toggled, this, &ManageTemplatesDialog::updateTemplateListView);
0124     topLayout->addWidget(m_showAllTypesCheckBox, 3, 0, 1, 2);
0125 
0126     QPushButton *clearSelectionButton = new QPushButton(page);
0127     mainLayout->addWidget(clearSelectionButton);
0128     clearSelectionButton->setIcon(QIcon::fromTheme("edit-clear-locationbar"));
0129     int buttonSize = clearSelectionButton->sizeHint().height();
0130     clearSelectionButton->setFixedSize(buttonSize, buttonSize);
0131     clearSelectionButton->setToolTip(i18n("Clear Selection"));
0132     connect(clearSelectionButton, &QPushButton::clicked, this, &ManageTemplatesDialog::clearSelection);
0133     topLayout->addWidget(clearSelectionButton, 3, 2, Qt::AlignRight);
0134 
0135     topLayout->addWidget(new QLabel(i18n("Select an existing template if you want to overwrite it with your new template.\nNote that you cannot overwrite templates marked with an asterisk:\nif you do select such a template, a new template with the same name\nwill be created in a location you have write access to."), page), 4, 0, 1, 3);
0136 
0137     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
0138     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
0139     okButton->setDefault(true);
0140     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0141     mainLayout->addWidget(buttonBox);
0142     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0143     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0144 
0145     connect(m_templateList, &QTreeWidget::itemClicked, this, &ManageTemplatesDialog::slotSelectedTemplate);
0146     connect(iconbut, &QPushButton::clicked, this, &ManageTemplatesDialog::slotSelectIcon);
0147     connect(this, &QDialog::accepted, this, &ManageTemplatesDialog::addTemplate);
0148 }
0149 
0150 // dialog to remove a template
0151 ManageTemplatesDialog::ManageTemplatesDialog(KileTemplate::Manager *templateManager, const QString &caption, QWidget *parent, const char *name)
0152     : QDialog(parent)
0153     , m_templateManager(templateManager)
0154     , m_templateType(KileDocument::Undefined)
0155     , m_showAllTypesCheckBox(Q_NULLPTR)
0156 {
0157     setObjectName(name);
0158     setWindowTitle(caption);
0159     setModal(true);
0160 
0161     QVBoxLayout *mainLayout = new QVBoxLayout();
0162     setLayout(mainLayout);
0163 
0164     m_templateList = new QTreeWidget(this);
0165     m_templateList->setSortingEnabled(false);
0166     m_templateList->setHeaderLabels(QStringList() << i18nc("marked", "M")
0167                                     << i18n("Existing Templates")
0168                                     << i18n("Document Type"));
0169     m_templateList->setAllColumnsShowFocus(true);
0170     m_templateList->setRootIsDecorated(false);
0171 
0172     populateTemplateListView(KileDocument::Undefined);
0173 
0174     mainLayout->addWidget(m_templateList);
0175     mainLayout->addWidget(new QLabel(i18n("Please select the template that you want to remove.\nNote that you cannot delete templates marked with an asterisk (for which you lack the necessary deletion permissions)."), this));
0176 
0177     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
0178     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
0179     okButton->setDefault(true);
0180     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0181     mainLayout->addWidget(buttonBox);
0182     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0183     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0184 
0185     connect(this, &QDialog::accepted, this, &ManageTemplatesDialog::removeTemplate);
0186 }
0187 
0188 ManageTemplatesDialog::~ManageTemplatesDialog()
0189 {
0190 }
0191 
0192 void ManageTemplatesDialog::updateTemplateListView(bool showAllTypes)
0193 {
0194     populateTemplateListView((showAllTypes ? KileDocument::Undefined : m_templateType));
0195 }
0196 
0197 void ManageTemplatesDialog::clearSelection()
0198 {
0199     m_templateList->clearSelection();
0200 }
0201 
0202 void ManageTemplatesDialog::populateTemplateListView(KileDocument::Type type)
0203 {
0204     m_templateManager->scanForTemplates();
0205     KileTemplate::TemplateList templateList = m_templateManager->getTemplates(type);
0206     QTreeWidgetItem* previousItem = Q_NULLPTR;
0207 
0208     m_templateList->clear();
0209     for (KileTemplate::TemplateListIterator i = templateList.begin(); i != templateList.end(); ++i)
0210     {
0211         KileTemplate::Info info = *i;
0212         QFileInfo iconFileInfo(info.icon);
0213         QString mode = (QFileInfo(info.path).isWritable() && (!iconFileInfo.exists() || iconFileInfo.isWritable())) ? " " : "*";
0214         if ((type == KileDocument::Undefined) || (info.type == type)) {
0215             previousItem = new TemplateListViewItem(m_templateList, previousItem, mode, info);
0216         }
0217     }
0218 
0219     m_templateList->resizeColumnToContents(0);
0220     m_templateList->resizeColumnToContents(1);
0221 }
0222 
0223 void ManageTemplatesDialog::slotSelectedTemplate(QTreeWidgetItem *item)
0224 {
0225     TemplateListViewItem *templateItem = dynamic_cast<TemplateListViewItem*>(item);
0226     if (templateItem) {
0227         KileTemplate::Info info = templateItem->getTemplateInfo();
0228         m_nameEdit->setText(info.name);
0229         m_iconEdit->setText(info.icon);
0230     }
0231 }
0232 
0233 void ManageTemplatesDialog::slotSelectIcon()
0234 {
0235     KIconDialog *dlg = new KIconDialog();
0236     QString res = dlg->openDialog();
0237     KIconLoader kil;
0238 
0239     if (!res.isNull()) {
0240         m_iconEdit->setText(kil.iconPath(res, -KIconLoader::SizeLarge, false));
0241     }
0242 }
0243 
0244 void ManageTemplatesDialog::addTemplate()
0245 {
0246     QString templateName = (m_nameEdit->text()).trimmed();
0247 
0248     if (templateName.isEmpty()) {
0249         KMessageBox::error(this, i18n("The template name that you have entered is invalid.\nPlease enter a new name."));
0250         return;
0251     }
0252 
0253     QString icon = (m_iconEdit->text()).trimmed();
0254     QUrl iconURL = QUrl::fromUserInput(icon);
0255 
0256     if (icon.isEmpty()) {
0257         KMessageBox::error(this, i18n("Please choose an icon first."));
0258         return;
0259     }
0260 
0261     KIO::StatJob* statJob = KIO::statDetails(iconURL, KIO::StatJob::SourceSide, KIO::StatNoDetails);
0262     KJobWidgets::setWindow(statJob, this);
0263     statJob->exec();
0264     if (statJob->error()) {
0265         KMessageBox::error(this, i18n("The icon file: %1\ndoes not seem to exist. Please choose a new icon.", icon));
0266         return;
0267     }
0268 
0269     statJob = KIO::statDetails(m_sourceURL, KIO::StatJob::SourceSide, KIO::StatNoDetails);
0270     KJobWidgets::setWindow(statJob, this);
0271     statJob->exec();
0272     if (statJob->error()) {
0273         KMessageBox::error(this, i18n("The file: %1\ndoes not seem to exist. Maybe you forgot to save the file?", m_sourceURL.toString()));
0274         return;
0275     }
0276 
0277     QTreeWidgetItem* item = m_templateList->currentItem();
0278 
0279     if (!item && m_templateManager->searchForTemplate(templateName, m_templateType)) {
0280         KMessageBox::error(this, i18n("A template named \"%1\" already exists.\nPlease remove it first.", templateName));
0281         return;
0282     }
0283 
0284     bool returnValue;
0285     if (item) {
0286         TemplateListViewItem *templateItem = dynamic_cast<TemplateListViewItem*>(item);
0287         Q_ASSERT(templateItem);
0288         KileTemplate::Info templateInfo = templateItem->getTemplateInfo();
0289         if (KMessageBox::warningTwoActions(this, i18n("You are about to replace the template \"%1\"; are you sure?", templateInfo.name),
0290                                            i18n("Replace template"),
0291                                            KStandardGuiItem::ok(), KStandardGuiItem::cancel()) == KMessageBox::SecondaryAction) {
0292             reject();
0293             return;
0294         }
0295     }
0296 
0297     returnValue = m_templateManager->add(m_sourceURL, templateName, iconURL);
0298 
0299     if (!returnValue) {
0300         KMessageBox::error(this, i18n("Failed to create the template."));
0301         reject();
0302         return;
0303     }
0304 }
0305 
0306 bool ManageTemplatesDialog::removeTemplate()
0307 {
0308     QTreeWidgetItem* item = m_templateList->currentItem();
0309     if (!item) {
0310         KMessageBox::information(this, i18n("Please select a template that should be removed."));
0311         return true;
0312     }
0313 
0314     TemplateListViewItem *templateItem = dynamic_cast<TemplateListViewItem*>(item);
0315     Q_ASSERT(templateItem);
0316 
0317     KileTemplate::Info templateInfo = templateItem->getTemplateInfo();
0318 
0319     if (KMessageBox::warningTwoActions(this, i18n("You are about to remove the template \"%1\"; are you sure?", templateInfo.name),
0320                                        i18n("Replace template"),
0321                                        KStandardGuiItem::remove(), KStandardGuiItem::cancel()) == KMessageBox::SecondaryAction) {
0322         return false;
0323     }
0324 
0325     if (!m_templateManager->remove(templateInfo)) {
0326         KMessageBox::error(this, i18n("The template could not be removed."));
0327         reject();
0328         return false;
0329     }
0330     return true;
0331 }