File indexing completed on 2024-09-22 05:16:06

0001 /*
0002     This file is part of the Kasten Framework, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2009, 2011 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "insertcontroller.hpp"
0010 
0011 // lib
0012 #include "insertdialog.hpp"
0013 // Kasten gui
0014 #include <Kasten/ModelCodecViewManager>
0015 #include <Kasten/SelectedDataWriteable>
0016 #include <Kasten/AbstractModelDataGeneratorConfigEditor>
0017 // Kasten core
0018 #include <Kasten/ModelDataGenerateThread>
0019 #include <Kasten/ModelCodecManager>
0020 #include <Kasten/AbstractModelDataGenerator>
0021 #include <Kasten/AbstractModel>
0022 // KF
0023 #include <KXMLGUIClient>
0024 #include <KXMLGUIFactory>
0025 #include <KActionCollection>
0026 #include <KLocalizedString>
0027 #include <KSelectAction>
0028 // Qt
0029 #include <QMimeData>
0030 #include <QApplication>
0031 
0032 namespace Kasten {
0033 
0034 InsertController::InsertController(ModelCodecViewManager* modelCodecViewManager,
0035                                    ModelCodecManager* modelCodecManager,
0036                                    KXMLGUIClient* guiClient)
0037     : mModelCodecViewManager(modelCodecViewManager)
0038     , mModelCodecManager(modelCodecManager)
0039 {
0040     mInsertSelectAction = new KSelectAction(i18nc("@title:menu", "Insert"), this);
0041 //     mInsertSelectAction->setIcon( QIcon::fromTheme( QStringLiteral("insert-text") ) );
0042     mInsertSelectAction->setToolBarMode(KSelectAction::MenuMode);
0043     connect(mInsertSelectAction, qOverload<QAction*>(&KSelectAction::triggered),
0044             this, &InsertController::onActionTriggered);
0045 
0046     // TODO: find better id
0047     guiClient->actionCollection()->addAction(QStringLiteral("insert"), mInsertSelectAction);
0048 
0049     setTargetModel(nullptr);
0050 }
0051 
0052 void InsertController::setTargetModel(AbstractModel* model)
0053 {
0054     if (mModel) {
0055         mModel->disconnect(this);
0056     }
0057 
0058     mModel = model ? model->findBaseModelWithInterface<If::SelectedDataWriteable*>() : nullptr;
0059     mSelectedDataWriteableControl = mModel ? qobject_cast<If::SelectedDataWriteable*>(mModel) : nullptr;
0060 
0061     if (mSelectedDataWriteableControl) {
0062         // TODO: only fill the list on menu call...
0063         connect(mModel, &AbstractModel::readOnlyChanged,
0064                 this, &InsertController::onReadOnlyChanged);
0065     }
0066 
0067     updateActions();
0068 }
0069 
0070 void InsertController::updateActions()
0071 {
0072     mInsertSelectAction->removeAllActions();
0073 
0074     // TODO: pass model to find which mimetypes it can read
0075     // mSelectedDataWriteableControl->canReadData( QMimeData() ) needs already data
0076     // TODO: it this depend on the current selection/focus? So it needs to be updated on every change?
0077     const QVector<AbstractModelDataGenerator*> generatorList =
0078         mModelCodecManager->generatorList();
0079     const bool hasGenerators = (!generatorList.isEmpty());
0080 
0081     if (hasGenerators) {
0082         for (AbstractModelDataGenerator* generator : generatorList) {
0083             const QString title = generator->typeName();
0084             auto* action = new QAction(title, mInsertSelectAction);
0085 
0086             action->setData(QVariant::fromValue(generator));
0087             mInsertSelectAction->addAction(action);
0088         }
0089     } else {
0090         auto* noneAction = new QAction(i18nc("@item There are no generators.", "Not available."), mInsertSelectAction);
0091         noneAction->setEnabled(false);
0092         mInsertSelectAction->addAction(noneAction);
0093     }
0094 
0095     // TODO: need a call AbstractModelSelection::isEmpty
0096     const bool isWriteable = (mSelectedDataWriteableControl && !mModel->isReadOnly());
0097     mInsertSelectAction->setEnabled(isWriteable);
0098 }
0099 
0100 void InsertController::onActionTriggered(QAction* action)
0101 {
0102     auto* generator = action->data().value<AbstractModelDataGenerator*>();
0103 
0104     AbstractModelDataGeneratorConfigEditor* configEditor =
0105         mModelCodecViewManager->createConfigEditor(generator);
0106 
0107     if (configEditor) {
0108         auto* dialog = new InsertDialog(configEditor, generator, QApplication::activeWindow());
0109 //         dialog->setData( mModel, selection ); TODO
0110         connect(dialog, &InsertDialog::insertAccepted, this, &InsertController::triggerExecution);
0111         dialog->open();
0112         return;
0113     }
0114 
0115     triggerExecution(generator);
0116 }
0117 
0118 void InsertController::triggerExecution(AbstractModelDataGenerator* generator)
0119 {
0120     QApplication::setOverrideCursor(Qt::WaitCursor);
0121 
0122     auto* generateThread = new ModelDataGenerateThread(this, generator);
0123     generateThread->start();
0124     while (!generateThread->wait(100)) {
0125         QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
0126     }
0127 
0128     QMimeData* mimeData = generateThread->data();
0129 
0130     delete generateThread;
0131 
0132     mSelectedDataWriteableControl->insertData(mimeData);
0133 
0134     QApplication::restoreOverrideCursor();
0135 }
0136 
0137 void InsertController::onReadOnlyChanged(bool isReadOnly)
0138 {
0139     const bool isWriteable = (!isReadOnly);
0140 
0141     mInsertSelectAction->setEnabled(isWriteable);
0142 }
0143 
0144 }
0145 
0146 #include "moc_insertcontroller.cpp"