kdecore Library API Documentation

kclipboard.cpp

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., 59 Temple Place - Suite 330,
00016     Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #include <kapplication.h>
00020 #include <kconfig.h>
00021 #include <kglobal.h>
00022 
00023 #include "kclipboard.h"
00024 
00025 /*
00026  * This class provides an automatic synchronization of the X11 Clipboard and Selection
00027  * buffers. There are two configuration options in the kdeglobals configuration file,
00028  * in the [General] section:
00029  * - SynchronizeClipboardAndSelection - whenever the Selection changes, Clipboard is
00030  *   set to the same value. This can be also enabled in Klipper.
00031  * - ClipboardSetSelection - whenever the Clipboard changes, Selection is set
00032  *   to the same value. This setting is only for die-hard fans of the old broken
00033  *   KDE1/2 behavior, which can potentionally lead to unexpected problems,
00034  *   and this setting therefore can be enabled only in the configuration file.
00035  *
00036  *  Whenever reporting any bug only remotely related to clipboard, first make
00037  *  sure you can reproduce it when both these two options are turned off,
00038  *  especially the second one.
00039  */
00040 
00041 class KClipboardSynchronizer::MimeSource : public QMimeSource
00042 {
00043 public:
00044     MimeSource( const QMimeSource * src )
00045         : QMimeSource(),
00046           m_formats( true ) // deep copies!
00047     {
00048         m_formats.setAutoDelete( true );
00049         m_data.setAutoDelete( true );
00050 
00051         if ( src )
00052         {
00053             QByteArray *byteArray;
00054             const char *format;
00055             int i = 0;
00056             while ( (format = src->format( i++ )) )
00057             {
00058                 byteArray = new QByteArray();
00059                 *byteArray = src->encodedData( format ).copy();
00060                 m_data.append( byteArray );
00061                 m_formats.append( format );
00062             }
00063         }
00064     }
00065 
00066     ~MimeSource() {}
00067 
00068     virtual const char *format( int i ) const {
00069         if ( i < (int) m_formats.count() )
00070             return m_formats.at( i );
00071         else
00072             return 0L;
00073     }
00074     virtual bool provides( const char *mimeType ) const {
00075         return ( m_formats.find( mimeType ) > -1 );
00076     }
00077     virtual QByteArray encodedData( const char *format ) const
00078     {
00079         int index = m_formats.find( format );
00080         if ( index > -1 )
00081         {
00082             // grmbl, gcc (2.95.3 at least) doesn't let me call m_data.at(),
00083             // due to it being non-const. Even if mutable.
00084             QPtrList<QByteArray> *list =
00085                 const_cast<QPtrList<QByteArray> *>( &m_data );
00086             return *(list->at( index ));
00087         }
00088 
00089         return QByteArray();
00090     }
00091 
00092 private:
00093     mutable QStrList m_formats;
00094     QPtrList<QByteArray> m_data;
00095 };
00096 
00097 
00098 KClipboardSynchronizer * KClipboardSynchronizer::s_self = 0L;
00099 bool KClipboardSynchronizer::s_sync = false;
00100 bool KClipboardSynchronizer::s_reverse_sync = false;
00101 bool KClipboardSynchronizer::s_blocked = false;
00102 
00103 KClipboardSynchronizer * KClipboardSynchronizer::self()
00104 {
00105     if ( !s_self )
00106         s_self = new KClipboardSynchronizer( kapp, "KDE Clipboard" );
00107 
00108     return s_self;
00109 }
00110 
00111 KClipboardSynchronizer::KClipboardSynchronizer( QObject *parent, const char *name )
00112     : QObject( parent, name )
00113 {
00114     s_self = this;
00115 
00116     KConfigGroup config( KGlobal::config(), "General" );
00117     s_sync = config.readBoolEntry( "SynchronizeClipboardAndSelection", s_sync);
00118     s_reverse_sync = config.readBoolEntry( "ClipboardSetSelection",
00119                                                 s_reverse_sync );
00120 
00121     setupSignals();
00122 }
00123 
00124 KClipboardSynchronizer::~KClipboardSynchronizer()
00125 {
00126     if ( s_self == this )
00127         s_self = 0L;
00128 }
00129 
00130 void KClipboardSynchronizer::setupSignals()
00131 {
00132     QClipboard *clip = QApplication::clipboard();
00133     disconnect( clip, NULL, this, NULL );
00134     if( s_sync )
00135         connect( clip, SIGNAL( selectionChanged() ),
00136                  SLOT( slotSelectionChanged() ));
00137     if( s_reverse_sync )
00138         connect( clip, SIGNAL( dataChanged() ),
00139                  SLOT( slotClipboardChanged() ));
00140 }
00141 
00142 void KClipboardSynchronizer::slotSelectionChanged()
00143 {
00144     QClipboard *clip = QApplication::clipboard();
00145 
00146 //     qDebug("*** sel changed: %i", s_blocked);
00147     if ( s_blocked || !clip->ownsSelection() )
00148         return;
00149 
00150     setClipboard( new MimeSource( clip->data( QClipboard::Selection) ),
00151                   QClipboard::Clipboard );
00152 }
00153 
00154 void KClipboardSynchronizer::slotClipboardChanged()
00155 {
00156     QClipboard *clip = QApplication::clipboard();
00157 
00158 //     qDebug("*** clip changed : %i (implicit: %i, ownz: clip: %i, selection: %i)", s_blocked, s_implicitSelection, clip->ownsClipboard(), clip->ownsSelection());
00159     if ( s_blocked || !clip->ownsClipboard() )
00160         return;
00161 
00162     setClipboard( new MimeSource( clip->data( QClipboard::Clipboard ) ),
00163                   QClipboard::Selection );
00164 }
00165 
00166 void KClipboardSynchronizer::setClipboard( QMimeSource *data, QClipboard::Mode mode )
00167 {
00168 //     qDebug("---> setting clipboard: %p", data);
00169 
00170     QClipboard *clip = QApplication::clipboard();
00171 
00172     s_blocked = true;
00173 
00174     if ( mode == QClipboard::Clipboard )
00175     {
00176         clip->setData( data, QClipboard::Clipboard );
00177     }
00178     else if ( mode == QClipboard::Selection )
00179     {
00180         clip->setData( data, QClipboard::Selection );
00181     }
00182 
00183     s_blocked = false;
00184 }
00185 
00186 void KClipboardSynchronizer::setSynchronizing( bool sync )
00187 {
00188     s_sync = sync;
00189     self()->setupSignals();
00190 }
00191 
00192 void KClipboardSynchronizer::setReverseSynchronizing( bool enable )
00193 {
00194     s_reverse_sync = enable;
00195     self()->setupSignals();
00196 }
00197 
00198 // private, called by KApplication
00199 void KClipboardSynchronizer::newConfiguration( int config )
00200 {
00201     s_sync = (config & Synchronize);
00202     self()->setupSignals();
00203 }
00204 
00205 #include "kclipboard.moc"
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:46:20 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001