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"