kclipboard.cpp Source File (kdecore Library)

| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# 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"

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