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

0001 /*
0002     This file is part of the Kasten Framework, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2006-2008 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 "clipboardcontroller.hpp"
0010 
0011 // Kasten gui
0012 #include <Kasten/DataSelectable>
0013 #include <Kasten/SelectedDataWriteable>
0014 // Kasten core
0015 #include <Kasten/AbstractModel>
0016 // KF
0017 #include <KXMLGUIClient>
0018 #include <KLocalizedString>
0019 #include <KActionCollection>
0020 #include <KStandardAction>
0021 // Qt
0022 #include <QClipboard>
0023 #include <QApplication>
0024 #include <QMimeData>
0025 #include <QAction>
0026 
0027 namespace Kasten {
0028 
0029 ClipboardController::ClipboardController(KXMLGUIClient* guiClient)
0030 {
0031     mCutAction =   KStandardAction::cut(  this, &ClipboardController::cut,   this);
0032     mCopyAction =  KStandardAction::copy( this, &ClipboardController::copy,  this);
0033     mPasteAction = KStandardAction::paste(this, &ClipboardController::paste, this);
0034 
0035     guiClient->actionCollection()->addActions({
0036         mCutAction,
0037         mCopyAction,
0038         mPasteAction,
0039     });
0040 
0041     connect(QApplication::clipboard(), &QClipboard::dataChanged,
0042             this, &ClipboardController::onClipboardDataChanged);
0043 
0044     setTargetModel(nullptr);
0045 }
0046 
0047 void ClipboardController::setTargetModel(AbstractModel* model)
0048 {
0049     if (mModel) {
0050         mModel->disconnect(this);
0051     }
0052 
0053     mModel = model ? model->findBaseModelWithInterface<If::DataSelectable*>() : nullptr;
0054     mSelectionControl = mModel ? qobject_cast<If::DataSelectable*>(mModel) : nullptr;
0055 
0056     if (mSelectionControl) {
0057         connect(mModel, SIGNAL(hasSelectedDataChanged(bool)), SLOT(onHasSelectedDataChanged(bool)));
0058 
0059         mMimeDataControl = qobject_cast<If::SelectedDataWriteable*>(mModel);
0060         if (mMimeDataControl) {
0061             connect(mModel, &AbstractModel::readOnlyChanged,
0062                     this, &ClipboardController::onReadOnlyChanged);
0063             connect(mModel, SIGNAL(canCutSelectedDataChanged(bool)),
0064                     this, SLOT(onCanCutSelectedDataChanged(bool)));
0065         }
0066     } else {
0067         mMimeDataControl = nullptr;
0068     }
0069 
0070     const QMimeData* mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard);
0071 
0072     const bool hasSelectedData = mSelectionControl ? mSelectionControl->hasSelectedData() : false;
0073     const bool isWriteable = (mMimeDataControl && !mModel->isReadOnly());
0074     const bool isCutable = (hasSelectedData && isWriteable && (!mMimeDataControl || mMimeDataControl->canCutSelectedData()));
0075     const bool isPastable = isWriteable && !mimeData->formats().isEmpty() && mMimeDataControl->canReadData(mimeData);
0076 
0077     mCopyAction->setEnabled(hasSelectedData);
0078     mCutAction->setEnabled(isCutable);
0079     mPasteAction->setEnabled(isPastable);
0080 }
0081 
0082 void ClipboardController::cut()
0083 {
0084     QMimeData* data = mMimeDataControl->cutSelectedData();
0085     if (!data) {
0086         return;
0087     }
0088 
0089     QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
0090 }
0091 
0092 void ClipboardController::copy()
0093 {
0094     QMimeData* data = mSelectionControl->copySelectedData();
0095     if (!data) {
0096         return;
0097     }
0098 
0099     QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
0100 }
0101 
0102 void ClipboardController::paste()
0103 {
0104     const QMimeData* data = QApplication::clipboard()->mimeData(QClipboard::Clipboard);
0105 
0106     mMimeDataControl->insertData(data);
0107 }
0108 
0109 void ClipboardController::onReadOnlyChanged(bool isReadOnly)
0110 {
0111     const QMimeData* mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard);
0112 
0113     const bool hasSelectedData = mSelectionControl ? mSelectionControl->hasSelectedData() : false;
0114     const bool isWriteable = !isReadOnly;
0115     // backward compatibility: assume true by default
0116     const bool canCutSelectedData = mMimeDataControl ? mMimeDataControl->canCutSelectedData() : true;
0117     const bool isCutable = (hasSelectedData && isWriteable && canCutSelectedData);
0118     const bool isPastable = isWriteable && !mimeData->formats().isEmpty() && mMimeDataControl->canReadData(mimeData);
0119 
0120     mCutAction->setEnabled(isCutable);
0121     mPasteAction->setEnabled(isPastable);
0122 }
0123 
0124 void ClipboardController::onHasSelectedDataChanged(bool hasSelectedData)
0125 {
0126     const bool isWriteable = (mMimeDataControl && !mModel->isReadOnly());
0127     // backward compatibility: assume true by default
0128     const bool canCutSelectedData = mMimeDataControl ? mMimeDataControl->canCutSelectedData() : true;
0129     const bool isCutable = (hasSelectedData && isWriteable && canCutSelectedData);
0130 
0131     mCopyAction->setEnabled(hasSelectedData);
0132     mCutAction->setEnabled(isCutable);
0133 }
0134 
0135 void ClipboardController::onCanCutSelectedDataChanged(bool canCutSelectedData)
0136 {
0137     const bool hasSelectedData = mSelectionControl ? mSelectionControl->hasSelectedData() : false;
0138     const bool isWriteable = (mMimeDataControl && !mModel->isReadOnly());
0139     const bool isCutable = (hasSelectedData && isWriteable && canCutSelectedData);
0140 
0141     mCutAction->setEnabled(isCutable);
0142 }
0143 
0144 void ClipboardController::onClipboardDataChanged()
0145 {
0146     const QMimeData* mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard);
0147 
0148     const bool isWriteable = (mMimeDataControl && !mModel->isReadOnly());
0149     const bool isPastable = isWriteable && !mimeData->formats().isEmpty() && mMimeDataControl->canReadData(mimeData);
0150 
0151     mPasteAction->setEnabled(isPastable);
0152 }
0153 
0154 }
0155 
0156 #include "moc_clipboardcontroller.cpp"