File indexing completed on 2025-02-02 05:43:11
0001 /* 0002 This file is part of the Kasten Framework, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2007-2008, 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 "copyascontroller.hpp" 0010 0011 // lib 0012 #include "copyasdialog.hpp" 0013 // Kasten gui 0014 #include <Kasten/ModelCodecViewManager> 0015 #include <Kasten/DataSelectable> 0016 #include <Kasten/AbstractModelStreamEncoderConfigEditor> 0017 // Kasten core 0018 #include <Kasten/ModelStreamEncodeThread> 0019 #include <Kasten/ModelCodecManager> 0020 #include <Kasten/AbstractModelStreamEncoder> 0021 #include <Kasten/AbstractModelSelection> 0022 #include <Kasten/AbstractModel> 0023 // KF 0024 #include <KXMLGUIClient> 0025 #include <KXMLGUIFactory> 0026 #include <KActionCollection> 0027 #include <KLocalizedString> 0028 #include <KSelectAction> 0029 // Qt 0030 #include <QBuffer> 0031 #include <QMimeData> 0032 #include <QClipboard> 0033 #include <QApplication> 0034 0035 namespace Kasten { 0036 0037 CopyAsController::CopyAsController(ModelCodecViewManager* modelCodecViewManager, 0038 ModelCodecManager* modelCodecManager, 0039 KXMLGUIClient* guiClient) 0040 : mModelCodecViewManager(modelCodecViewManager) 0041 , mModelCodecManager(modelCodecManager) 0042 { 0043 mCopyAsSelectAction = new KSelectAction(QIcon::fromTheme(QStringLiteral("edit-copy")), 0044 i18nc("@title:menu", "Copy As"), 0045 this); 0046 mCopyAsSelectAction->setToolBarMode(KSelectAction::MenuMode); 0047 connect(mCopyAsSelectAction, qOverload<QAction*>(&KSelectAction::triggered), 0048 this, &CopyAsController::onActionTriggered); 0049 0050 guiClient->actionCollection()->addAction(QStringLiteral("copy_as"), mCopyAsSelectAction); 0051 0052 setTargetModel(nullptr); 0053 } 0054 0055 void CopyAsController::setTargetModel(AbstractModel* model) 0056 { 0057 if (mModel) { 0058 mModel->disconnect(this); 0059 } 0060 0061 mModel = model ? model->findBaseModelWithInterface<If::DataSelectable*>() : nullptr; 0062 mSelectionControl = mModel ? qobject_cast<If::DataSelectable*>(mModel) : nullptr; 0063 0064 if (mSelectionControl) { 0065 // TODO: only fill the list on menu call... 0066 connect(mModel, SIGNAL(hasSelectedDataChanged(bool)), SLOT(updateActions())); 0067 } 0068 0069 updateActions(); 0070 } 0071 0072 void CopyAsController::updateActions() 0073 { 0074 mCopyAsSelectAction->removeAllActions(); 0075 0076 const AbstractModelSelection* selection = mSelectionControl ? mSelectionControl->modelSelection() : nullptr; 0077 0078 const QVector<AbstractModelStreamEncoder*> encoderList = 0079 mModelCodecManager->encoderList(mModel, selection); 0080 const bool hasEncoders = (!encoderList.isEmpty()); 0081 0082 if (hasEncoders) { 0083 for (auto* encoder : encoderList) { 0084 const QString title = encoder->remoteTypeName(); 0085 auto* action = new QAction(title, mCopyAsSelectAction); 0086 0087 action->setData(QVariant::fromValue(encoder)); 0088 mCopyAsSelectAction->addAction(action); 0089 } 0090 } else { 0091 auto* noneAction = new QAction(i18nc("@item There are no encoders.", "Not available."), mCopyAsSelectAction); 0092 noneAction->setEnabled(false); 0093 mCopyAsSelectAction->addAction(noneAction); 0094 } 0095 0096 // TODO: need a call AbstractModelSelection::isEmpty 0097 mCopyAsSelectAction->setEnabled(mSelectionControl && mSelectionControl->hasSelectedData()); 0098 } 0099 0100 void CopyAsController::onActionTriggered(QAction* action) 0101 { 0102 auto* encoder = action->data().value<AbstractModelStreamEncoder*>(); 0103 0104 const AbstractModelSelection* selection = mSelectionControl->modelSelection(); 0105 0106 AbstractModelStreamEncoderConfigEditor* configEditor = 0107 mModelCodecViewManager->createConfigEditor(encoder); 0108 0109 if (configEditor) { 0110 auto* dialog = new CopyAsDialog(encoder->remoteTypeName(), configEditor, encoder, 0111 QApplication::activeWindow()); 0112 dialog->setData(mModel, selection); 0113 connect(dialog, &CopyAsDialog::copyAccepted, this, &CopyAsController::triggerExecution); 0114 dialog->open(); 0115 return; 0116 } 0117 0118 triggerExecution(encoder, selection); 0119 } 0120 0121 void CopyAsController::triggerExecution(AbstractModelStreamEncoder* encoder, 0122 const AbstractModelSelection* selection) 0123 { 0124 QApplication::setOverrideCursor(Qt::WaitCursor); 0125 0126 QByteArray exportData; 0127 QBuffer exportDataBuffer(&exportData); 0128 exportDataBuffer.open(QIODevice::WriteOnly); 0129 0130 auto* encodeThread = new ModelStreamEncodeThread(this, &exportDataBuffer, mModel, selection, encoder); 0131 encodeThread->start(); 0132 while (!encodeThread->wait(100)) { 0133 QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); 0134 } 0135 0136 delete encodeThread; 0137 0138 exportDataBuffer.close(); 0139 0140 auto* mimeData = new QMimeData; 0141 mimeData->setData(encoder->remoteClipboardMimeType(), exportData); 0142 QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); 0143 0144 QApplication::restoreOverrideCursor(); 0145 } 0146 0147 } 0148 0149 #include "moc_copyascontroller.cpp"