KDEUI
kclipboard.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2, as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "kclipboard.h" 00020 #include "ksharedconfig.h" 00021 #include "kglobal.h" 00022 #include "kglobalsettings.h" 00023 00024 #include <QtCore/QMimeData> 00025 #include <QtDBus/QtDBus> 00026 #include <QtGui/QApplication> 00027 #include <kconfiggroup.h> 00028 00029 /* 00030 * This class provides an automatic synchronization of the X11 Clipboard and Selection 00031 * buffers. There are two configuration options in the kdeglobals configuration file, 00032 * in the [General] section: 00033 * - SynchronizeClipboardAndSelection - whenever the Selection changes, Clipboard is 00034 * set to the same value. This can be also enabled in Klipper. 00035 * - ClipboardSetSelection - whenever the Clipboard changes, Selection is set 00036 * to the same value. This setting is only for die-hard fans of the old broken 00037 * KDE1/2 behavior, which can potentionally lead to unexpected problems, 00038 * and this setting therefore can be enabled only in the configuration file. 00039 * 00040 * Whenever reporting any bug only remotely related to clipboard, first make 00041 * sure you can reproduce it when both these two options are turned off, 00042 * especially the second one. 00043 */ 00044 00045 class KClipboardSynchronizer::Private 00046 { 00047 public: 00048 Private(KClipboardSynchronizer *q) 00049 : q(q) 00050 { 00051 } 00052 00053 void setupSignals(); 00054 00055 static void setClipboard( const QMimeData* data, QClipboard::Mode mode ); 00056 00057 void _k_slotSelectionChanged(); 00058 void _k_slotClipboardChanged(); 00059 void _k_slotNotifyChange(int, int); 00060 00061 KClipboardSynchronizer *q; 00062 static bool s_sync; 00063 static bool s_reverse_sync; 00064 static bool s_blocked; 00065 }; 00066 00067 bool KClipboardSynchronizer::Private::s_sync = false; 00068 bool KClipboardSynchronizer::Private::s_reverse_sync = false; 00069 bool KClipboardSynchronizer::Private::s_blocked = false; 00070 00071 KClipboardSynchronizer * KClipboardSynchronizer::self() 00072 { 00073 K_GLOBAL_STATIC(KClipboardSynchronizer, s_self) 00074 return s_self; 00075 } 00076 00077 KClipboardSynchronizer::KClipboardSynchronizer( QObject *parent ) 00078 : QObject( parent ), d(new Private(this)) 00079 { 00080 KConfigGroup config( KGlobal::config(), "General" ); 00081 Private::s_sync = config.readEntry("SynchronizeClipboardAndSelection", Private::s_sync); 00082 Private::s_reverse_sync = config.readEntry("ClipboardSetSelection", Private::s_reverse_sync); 00083 00084 d->setupSignals(); 00085 } 00086 00087 KClipboardSynchronizer::~KClipboardSynchronizer() 00088 { 00089 delete d; 00090 } 00091 00092 void KClipboardSynchronizer::Private::setupSignals() 00093 { 00094 QClipboard *clip = QApplication::clipboard(); 00095 disconnect( clip, NULL, q, NULL ); 00096 if( s_sync ) 00097 connect( clip, SIGNAL( selectionChanged() ), 00098 q, SLOT( _k_slotSelectionChanged() )); 00099 if( s_reverse_sync ) 00100 connect( clip, SIGNAL( dataChanged() ), 00101 q, SLOT( _k_slotClipboardChanged() )); 00102 00103 QDBusConnection::sessionBus().connect( QString(), "/KGlobalSettings", "org.kde.KGlobalSettings", 00104 "notifyChange", q, SLOT(_k_slotNotifyChange(int,int)) ); 00105 } 00106 00107 void KClipboardSynchronizer::Private::_k_slotSelectionChanged() 00108 { 00109 QClipboard *clip = QApplication::clipboard(); 00110 00111 // qDebug("*** sel changed: %i", s_blocked); 00112 if ( s_blocked || !clip->ownsSelection() ) 00113 return; 00114 00115 setClipboard( clip->mimeData( QClipboard::Selection ), 00116 QClipboard::Clipboard ); 00117 } 00118 00119 void KClipboardSynchronizer::Private::_k_slotClipboardChanged() 00120 { 00121 QClipboard *clip = QApplication::clipboard(); 00122 00123 // qDebug("*** clip changed : %i (implicit: %i, ownz: clip: %i, selection: %i)", s_blocked, s_implicitSelection, clip->ownsClipboard(), clip->ownsSelection()); 00124 if ( s_blocked || !clip->ownsClipboard() ) 00125 return; 00126 00127 setClipboard( clip->mimeData( QClipboard::Clipboard ), 00128 QClipboard::Selection ); 00129 } 00130 00131 void KClipboardSynchronizer::Private::_k_slotNotifyChange(int changeType, int arg) 00132 { 00133 if (changeType == KGlobalSettings::ClipboardConfigChanged) { 00134 s_sync = (arg & Synchronize); 00135 KClipboardSynchronizer::self()->d->setupSignals(); 00136 } 00137 } 00138 00139 void KClipboardSynchronizer::Private::setClipboard( const QMimeData *data, QClipboard::Mode mode ) 00140 { 00141 // qDebug("---> setting clipboard: %p", data); 00142 00143 QClipboard *clip = QApplication::clipboard(); 00144 00145 s_blocked = true; 00146 00147 QMimeData* clipData = const_cast<QMimeData*>( data ); 00148 if ( mode == QClipboard::Clipboard ) 00149 { 00150 clip->setMimeData( clipData, QClipboard::Clipboard ); 00151 } 00152 else if ( mode == QClipboard::Selection ) 00153 { 00154 clip->setMimeData( clipData, QClipboard::Selection ); 00155 } 00156 00157 s_blocked = false; 00158 } 00159 00160 void KClipboardSynchronizer::setSynchronizing( bool sync ) 00161 { 00162 Private::s_sync = sync; 00163 self()->d->setupSignals(); 00164 } 00165 00166 bool KClipboardSynchronizer::isSynchronizing() 00167 { 00168 return Private::s_sync; 00169 } 00170 00171 void KClipboardSynchronizer::setReverseSynchronizing( bool enable ) 00172 { 00173 Private::s_reverse_sync = enable; 00174 self()->d->setupSignals(); 00175 } 00176 00177 bool KClipboardSynchronizer::isReverseSynchronizing() 00178 { 00179 return Private::s_reverse_sync; 00180 } 00181 00182 #include "kclipboard.moc"
KDE 4.6 API Reference