File indexing completed on 2024-04-28 13:25:35
0001 /* 0002 SPDX-FileCopyrightText: 2021 Michail Vourlakos <mvourlakos@gmail.com> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "exporttemplatehandler.h" 0007 0008 // local 0009 #include <coretypes.h> 0010 #include "ui_exporttemplatedialog.h" 0011 #include "exporttemplatedialog.h" 0012 #include "appletsmodel.h" 0013 #include "delegates/normalcheckboxdelegate.h" 0014 #include "../settingsdialog/layoutscontroller.h" 0015 #include "../../lattecorona.h" 0016 #include "../../data/appletdata.h" 0017 #include "../../layout/genericlayout.h" 0018 #include "../../layouts/storage.h" 0019 #include "../../templates/templatesmanager.h" 0020 #include "../../view/view.h" 0021 0022 // Qt 0023 #include <QAction> 0024 #include <QDir> 0025 #include <QFileDialog> 0026 #include <QFileInfo> 0027 #include <QList> 0028 0029 // KDE 0030 #include <KLocalizedString> 0031 #include <KMessageBox> 0032 #include <KIO/OpenFileManagerWindowJob> 0033 0034 // Plasma 0035 #include <Plasma/Containment> 0036 0037 namespace Latte { 0038 namespace Settings { 0039 namespace Handler { 0040 0041 ExportTemplateHandler::ExportTemplateHandler(Dialog::ExportTemplateDialog *dialog) 0042 : Generic(dialog), 0043 m_dialog(dialog), 0044 m_ui(m_dialog->ui()), 0045 m_appletsModel(new Model::Applets(this)) 0046 { 0047 init(); 0048 } 0049 0050 ExportTemplateHandler::ExportTemplateHandler(Dialog::ExportTemplateDialog *dialog, const Data::Layout &layout) 0051 : ExportTemplateHandler(dialog) 0052 { 0053 loadApplets(layout.id); 0054 m_dialog->setWindowTitle(i18n("Export Layout Template")); 0055 o_filepath = dialog->corona()->templatesManager()->proposedTemplateAbsolutePath(layout.name + ".layout.latte"); 0056 setFilepath(o_filepath); 0057 } 0058 0059 ExportTemplateHandler::ExportTemplateHandler(Dialog::ExportTemplateDialog *dialog, const Data::View &view) 0060 : ExportTemplateHandler(dialog) 0061 { 0062 loadApplets(view.id); 0063 m_dialog->setWindowTitle(i18n("Export Dock/Panel Template")); 0064 0065 QString viewname = view.name.isEmpty() ? view.originLayout() + " " + i18n("Dock") : view.name; 0066 o_filepath = dialog->corona()->templatesManager()->proposedTemplateAbsolutePath(viewname + ".view.latte"); 0067 setFilepath(o_filepath); 0068 } 0069 0070 ExportTemplateHandler::ExportTemplateHandler(Dialog::ExportTemplateDialog *dialog, Latte::View *view) 0071 : ExportTemplateHandler(dialog) 0072 { 0073 QString type = (view->type() == Latte::Types::PanelView ? i18n("Panel") : i18n("Dock")); 0074 0075 QString temporiginfile = view->layout()->storedView(view->containment()->id()); 0076 0077 loadApplets(temporiginfile); 0078 m_dialog->setWindowTitle(i18n("Export %1 Template", type)); 0079 0080 QString viewname = view->name().isEmpty() ? view->layout()->name() + " " + type : view->name(); 0081 0082 o_filepath = dialog->corona()->templatesManager()->proposedTemplateAbsolutePath(viewname + ".view.latte"); 0083 setFilepath(o_filepath); 0084 } 0085 0086 ExportTemplateHandler::~ExportTemplateHandler() 0087 { 0088 } 0089 0090 void ExportTemplateHandler::init() 0091 { 0092 m_ui->appletsTable->horizontalHeader()->setStretchLastSection(true); 0093 m_ui->appletsTable->horizontalHeader()->setSectionsClickable(false); 0094 0095 m_ui->appletsTable->verticalHeader()->setVisible(false); 0096 0097 m_ui->appletsTable->setItemDelegateForColumn(Model::Applets::NAMECOLUMN, new Settings::Applets::Delegate::NormalCheckBox(this)); 0098 0099 //! Data Changed 0100 connect(this, &ExportTemplateHandler::filepathChanged, this, &ExportTemplateHandler::dataChanged); 0101 connect(m_appletsModel, &Settings::Model::Applets::appletsDataChanged, this, &ExportTemplateHandler::dataChanged); 0102 0103 //! Applets Model 0104 m_appletsProxyModel = new QSortFilterProxyModel(this); 0105 m_appletsProxyModel->setSourceModel(m_appletsModel); 0106 m_appletsProxyModel->setSortRole(Model::Applets::SORTINGROLE); 0107 m_appletsProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); 0108 // m_appletsProxyModel->sort(Model::Applets::NAMECOLUMN, Qt::AscendingOrder); 0109 0110 m_ui->appletsTable->setModel(m_appletsProxyModel); 0111 0112 //! Buttons 0113 connect(m_ui->deselectAllBtn, &QPushButton::clicked, this, &ExportTemplateHandler::onDeselectAll); 0114 connect(m_ui->selectAllBtn, &QPushButton::clicked, this, &ExportTemplateHandler::onSelectAll); 0115 connect(m_ui->buttonBox->button(QDialogButtonBox::Reset), &QPushButton::clicked, this, &ExportTemplateHandler::reset); 0116 0117 connect(m_ui->chooseBtn, &QPushButton::clicked, this, &ExportTemplateHandler::chooseFileDialog); 0118 connect(m_dialog->exportButton(), &QPushButton::clicked, this, &ExportTemplateHandler::onExport); 0119 0120 //! Labels 0121 connect(this, &ExportTemplateHandler::filepathChanged, this, &ExportTemplateHandler::onFilepathChanged); 0122 } 0123 0124 void ExportTemplateHandler::setFilepath(const QString &filepath) 0125 { 0126 if (c_filepath == filepath) { 0127 return; 0128 } 0129 0130 c_filepath = filepath; 0131 emit filepathChanged(); 0132 } 0133 0134 void ExportTemplateHandler::loadApplets(const QString &file) 0135 { 0136 m_originFilePath = file; 0137 Data::AppletsTable c_data = Latte::Layouts::Storage::self()->plugins(file); 0138 m_appletsModel->setData(c_data); 0139 } 0140 0141 void ExportTemplateHandler::chooseFileDialog() 0142 { 0143 QFileInfo currentFile(c_filepath); 0144 bool inLayoutState = c_filepath.endsWith("layout.latte"); 0145 0146 QFileDialog *chooseFileDlg = new QFileDialog(m_dialog, 0147 inLayoutState ? i18n("Choose Layout Template file") : i18n("Choose View Template file"), 0148 currentFile.absoluteFilePath(), 0149 inLayoutState ? QStringLiteral(".layout.latte") : QStringLiteral(".view.latte")); 0150 0151 chooseFileDlg->setLabelText(QFileDialog::Accept, i18nc("choose file","Choose")); 0152 chooseFileDlg->setFileMode(QFileDialog::AnyFile); 0153 chooseFileDlg->setAcceptMode(QFileDialog::AcceptSave); 0154 if (inLayoutState) { 0155 chooseFileDlg->setDefaultSuffix("layout.latte"); 0156 } else { 0157 chooseFileDlg->setDefaultSuffix("view.latte"); 0158 } 0159 0160 QStringList filters; 0161 0162 if (inLayoutState) { 0163 filters << QString(i18nc("layout template", "Latte Dock Layout Template file v0.2") + "(*.layout.latte)"); 0164 } else { 0165 filters << QString(i18nc("view template", "Latte Dock View Template file v0.2") + "(*.view.latte)"); 0166 } 0167 0168 chooseFileDlg->setNameFilters(filters); 0169 0170 connect(chooseFileDlg, &QFileDialog::finished, chooseFileDlg, &QFileDialog::deleteLater); 0171 connect(chooseFileDlg, &QFileDialog::fileSelected, this, [&, inLayoutState](const QString &file) { 0172 if (inLayoutState) { 0173 if (!file.endsWith(".layout.latte")) { 0174 QString selected = file; 0175 selected = selected.replace(QDir::homePath(), "~"); 0176 showInlineMessage(i18n("<i>%1</i> does not end with <i>.layout.latte</i> extension. Selected file <b>rejected</b>.", selected), 0177 KMessageWidget::Error, 0178 true); 0179 } else { 0180 setFilepath(file); 0181 } 0182 } else { 0183 if (!file.endsWith(".view.latte")) { 0184 QString selected = file; 0185 selected = selected.replace(QDir::homePath(), "~"); 0186 showInlineMessage(i18n("<i>%1</i> does not end with <i>.view.latte</i> extension. Selected file <b>rejected</b>.", selected), 0187 KMessageWidget::Error, 0188 true); 0189 } else { 0190 setFilepath(file); 0191 } 0192 } 0193 }); 0194 0195 chooseFileDlg->open(); 0196 chooseFileDlg->selectFile(currentFile.fileName()); 0197 } 0198 0199 void ExportTemplateHandler::onExport() 0200 { 0201 QString curbasename = QFileInfo(c_filepath).baseName(); 0202 QString curfilename = QFileInfo(c_filepath).fileName(); 0203 0204 //! Confirm Overwrite if that is the case 0205 if (QFile(c_filepath).exists()) { 0206 if (!overwriteConfirmation(curfilename)) { 0207 return; 0208 } 0209 } 0210 0211 //! Proceed with export 0212 auto showExportTemplateError = [this](const QString &templateName) { 0213 showInlineMessage(i18nc("settings:template export fail","Template <b>%1</b> export <b>failed</b>...", templateName), 0214 KMessageWidget::Error, 0215 true); 0216 }; 0217 0218 bool result = m_dialog->corona()->templatesManager()->exportTemplate(m_originFilePath, 0219 c_filepath, 0220 m_appletsModel->selectedApplets()); 0221 if (result) { 0222 QAction *openUrlAction = new QAction(i18n("Open Location..."), this); 0223 openUrlAction->setIcon(QIcon::fromTheme("document-open")); 0224 openUrlAction->setData(c_filepath); 0225 QList<QAction *> actions; 0226 actions << openUrlAction; 0227 0228 connect(openUrlAction, &QAction::triggered, this, [&, openUrlAction]() { 0229 QString file = openUrlAction->data().toString(); 0230 0231 if (!file.isEmpty()) { 0232 KIO::highlightInFileManager({file}); 0233 } 0234 }); 0235 0236 showInlineMessage(i18nc("settings:template export success","Template <b>%1</b> export succeeded...", curbasename), 0237 KMessageWidget::Positive, 0238 false, 0239 actions); 0240 0241 emit exportSucceeded(); 0242 } else { 0243 showExportTemplateError(QFileInfo(c_filepath).baseName()); 0244 } 0245 } 0246 0247 void ExportTemplateHandler::onFilepathChanged() 0248 { 0249 QString filepath = c_filepath; 0250 0251 filepath = filepath.replace(QDir::homePath(), "~"); 0252 m_ui->fileLbl->setText(filepath); 0253 } 0254 0255 void ExportTemplateHandler::onSelectAll() 0256 { 0257 m_appletsModel->selectAll(); 0258 0259 } 0260 0261 void ExportTemplateHandler::onDeselectAll() 0262 { 0263 m_appletsModel->deselectAll(); 0264 } 0265 0266 bool ExportTemplateHandler::hasChangedData() const 0267 { 0268 return (c_filepath != o_filepath) || m_appletsModel->hasChangedData(); 0269 } 0270 0271 bool ExportTemplateHandler::inDefaultValues() const 0272 { 0273 return (c_filepath == o_filepath) && m_appletsModel->inDefaultValues(); 0274 } 0275 0276 void ExportTemplateHandler::reset() 0277 { 0278 setFilepath(o_filepath); 0279 0280 if (m_appletsModel->hasChangedData()) { 0281 m_appletsModel->reset(); 0282 } 0283 } 0284 0285 void ExportTemplateHandler::resetDefaults() 0286 { 0287 reset(); 0288 } 0289 0290 void ExportTemplateHandler::save() 0291 { 0292 //do nothing 0293 } 0294 0295 bool ExportTemplateHandler::overwriteConfirmation(const QString &fileName) 0296 { 0297 return (KMessageBox::warningYesNo(m_dialog, 0298 i18n("The file \"%1\" already exists. Do you wish to overwrite it?", fileName), 0299 i18n("Overwrite File?"), 0300 KStandardGuiItem::overwrite(), 0301 KStandardGuiItem::cancel()) == KMessageBox::Yes); 0302 } 0303 0304 } 0305 } 0306 }