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., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include <tdeapplication.h> 00020 #include <tdeconfig.h> 00021 #include <tdeglobal.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 TDEClipboardSynchronizer::MimeSource : public TQMimeSource 00042 { 00043 public: 00044 MimeSource( const TQMimeSource * src ) 00045 : TQMimeSource(), 00046 m_formats( true ) // deep copies! 00047 { 00048 m_formats.setAutoDelete( true ); 00049 m_data.setAutoDelete( true ); 00050 00051 if ( src ) 00052 { 00053 TQByteArray *byteArray; 00054 const char *format; 00055 int i = 0; 00056 while ( (format = src->format( i++ )) ) 00057 { 00058 byteArray = new TQByteArray(); 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 TQByteArray encodedData( const char *format ) const 00078 { 00079 int index = m_formats.find( format ); 00080 if ( index > -1 ) 00081 return *(m_data.at( index )); 00082 00083 return TQByteArray(); 00084 } 00085 00086 private: 00087 mutable TQStrList m_formats; 00088 mutable TQPtrList<TQByteArray> m_data; 00089 }; 00090 00091 00092 TDEClipboardSynchronizer * TDEClipboardSynchronizer::s_self = 0L; 00093 bool TDEClipboardSynchronizer::s_sync = false; 00094 bool TDEClipboardSynchronizer::s_reverse_sync = false; 00095 bool TDEClipboardSynchronizer::s_blocked = false; 00096 00097 TDEClipboardSynchronizer * TDEClipboardSynchronizer::self() 00098 { 00099 if ( !s_self ) 00100 s_self = new TDEClipboardSynchronizer( TQT_TQOBJECT(kapp), "KDE Clipboard" ); 00101 00102 return s_self; 00103 } 00104 00105 TDEClipboardSynchronizer::TDEClipboardSynchronizer( TQObject *parent, const char *name ) 00106 : TQObject( parent, name ) 00107 { 00108 s_self = this; 00109 00110 TDEConfigGroup config( TDEGlobal::config(), "General" ); 00111 s_sync = config.readBoolEntry( "SynchronizeClipboardAndSelection", s_sync); 00112 s_reverse_sync = config.readBoolEntry( "ClipboardSetSelection", 00113 s_reverse_sync ); 00114 00115 setupSignals(); 00116 } 00117 00118 TDEClipboardSynchronizer::~TDEClipboardSynchronizer() 00119 { 00120 if ( s_self == this ) 00121 s_self = 0L; 00122 } 00123 00124 void TDEClipboardSynchronizer::setupSignals() 00125 { 00126 TQClipboard *clip = TQApplication::clipboard(); 00127 disconnect( clip, NULL, this, NULL ); 00128 if( s_sync ) 00129 connect( clip, TQT_SIGNAL( selectionChanged() ), 00130 TQT_SLOT( slotSelectionChanged() )); 00131 if( s_reverse_sync ) 00132 connect( clip, TQT_SIGNAL( dataChanged() ), 00133 TQT_SLOT( slotClipboardChanged() )); 00134 } 00135 00136 void TDEClipboardSynchronizer::slotSelectionChanged() 00137 { 00138 TQClipboard *clip = TQApplication::clipboard(); 00139 00140 // tqDebug("*** sel changed: %i", s_blocked); 00141 if ( s_blocked || !clip->ownsSelection() ) 00142 return; 00143 00144 setClipboard( new MimeSource( clip->data( TQClipboard::Selection) ), 00145 TQClipboard::Clipboard ); 00146 } 00147 00148 void TDEClipboardSynchronizer::slotClipboardChanged() 00149 { 00150 TQClipboard *clip = TQApplication::clipboard(); 00151 00152 // tqDebug("*** clip changed : %i (implicit: %i, ownz: clip: %i, selection: %i)", s_blocked, s_implicitSelection, clip->ownsClipboard(), clip->ownsSelection()); 00153 if ( s_blocked || !clip->ownsClipboard() ) 00154 return; 00155 00156 setClipboard( new MimeSource( clip->data( TQClipboard::Clipboard ) ), 00157 TQClipboard::Selection ); 00158 } 00159 00160 void TDEClipboardSynchronizer::setClipboard( TQMimeSource *data, TQClipboard::Mode mode ) 00161 { 00162 // tqDebug("---> setting clipboard: %p", data); 00163 00164 TQClipboard *clip = TQApplication::clipboard(); 00165 00166 s_blocked = true; 00167 00168 if ( mode == TQClipboard::Clipboard ) 00169 { 00170 clip->setData( data, TQClipboard::Clipboard ); 00171 } 00172 else if ( mode == TQClipboard::Selection ) 00173 { 00174 clip->setData( data, TQClipboard::Selection ); 00175 } 00176 00177 s_blocked = false; 00178 } 00179 00180 void TDEClipboardSynchronizer::setSynchronizing( bool sync ) 00181 { 00182 s_sync = sync; 00183 self()->setupSignals(); 00184 } 00185 00186 void TDEClipboardSynchronizer::setReverseSynchronizing( bool enable ) 00187 { 00188 s_reverse_sync = enable; 00189 self()->setupSignals(); 00190 } 00191 00192 // private, called by TDEApplication 00193 void TDEClipboardSynchronizer::newConfiguration( int config ) 00194 { 00195 s_sync = (config & Synchronize); 00196 self()->setupSignals(); 00197 } 00198 00199 #include "kclipboard.moc"