KDE3Support
k3urldrag.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project 00002 Copyright (C) 2000 David Faure <faure@kde.org> 00003 00004 This program is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this program; see the file COPYING. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "k3urldrag.h" 00021 #include <Qt3Support/Q3CString> 00022 #include <Qt3Support/Q3StrIList> 00023 #include <Qt3Support/Q3ColorDrag> 00024 #include <QtGui/QFont> 00025 #include <unistd.h> 00026 00027 #include <kglobal.h> 00028 #include <klocale.h> 00029 #include <kdebug.h> 00030 00031 class K3URLDragPrivate 00032 { 00033 public: 00034 bool m_exportAsText; 00035 }; 00036 00037 K3URLDrag::K3URLDrag( const KUrl::List &urls, QWidget* dragSource ) 00038 : Q3UriDrag(dragSource), m_metaData(), d( 0 ) 00039 { 00040 init(urls); 00041 } 00042 00043 K3URLDrag::K3URLDrag( const KUrl::List &urls, 00044 const QMap<QString,QString>& metaData, 00045 QWidget* dragSource ) 00046 : Q3UriDrag(dragSource), m_metaData(metaData), d( 0 ) 00047 { 00048 init(urls); 00049 } 00050 00051 K3URLDrag::~K3URLDrag() 00052 { 00053 delete d; 00054 } 00055 00056 void K3URLDrag::init(const KUrl::List &urls) 00057 { 00058 KUrl::List::ConstIterator uit = urls.begin(); 00059 KUrl::List::ConstIterator uEnd = urls.end(); 00060 // Get each URL encoded in utf8 - and since we get it in escaped 00061 // form on top of that, .toLatin1().constData() is fine. 00062 for ( ; uit != uEnd ; ++uit ) 00063 { 00064 m_urls.append( urlToString(*uit).toLatin1().constData() ); 00065 } 00066 setUris(m_urls); 00067 } 00068 00069 void K3URLDrag::setExportAsText( bool exp ) 00070 { 00071 // For now d is only used here, so create it on demand 00072 if ( !d ) 00073 d = new K3URLDragPrivate; 00074 d->m_exportAsText = exp; 00075 } 00076 00077 K3URLDrag * K3URLDrag::newDrag( const KUrl::List &urls, QWidget* dragSource ) 00078 { 00079 return new K3URLDrag( urls, QMap<QString, QString>(), dragSource ); 00080 } 00081 00082 K3URLDrag * K3URLDrag::newDrag( const KUrl::List &urls, const QMap<QString, QString>& metaData, 00083 QWidget* dragSource ) 00084 { 00085 return new K3URLDrag( urls, metaData, dragSource ); 00086 } 00087 00088 QMap<QString, QString> &K3URLDrag::metaData() 00089 { 00090 return m_metaData; 00091 } 00092 00093 bool K3URLDrag::decode( const QMimeSource *e, KUrl::List &uris ) 00094 { 00095 // x-kde4-urilist is the same format as text/uri-list, but contains 00096 // KDE-aware urls, like media:/ and system:/, whereas text/uri-list is resolved to 00097 // local files. 00098 if ( e->provides( "application/x-kde4-urilist" ) ) { 00099 QByteArray payload = e->encodedData( "application/x-kde4-urilist" ); 00100 if ( payload.size() ) { 00101 int c=0; 00102 const char* d = payload.data(); 00103 while (c < payload.size() && d[c]) { 00104 int f = c; 00105 // Find line end 00106 while (c < payload.size() && d[c] && d[c]!='\r' 00107 && d[c] != '\n') 00108 c++; 00109 Q3CString s(d+f,c-f+1); 00110 if ( s[0] != '#' ) // non-comment? 00111 uris.append(stringToUrl(s)); 00112 // Skip junk 00113 while (c < payload.size() && d[c] && 00114 (d[c]=='\n' || d[c]=='\r')) 00115 c++; 00116 } 00117 return !uris.isEmpty(); 00118 } 00119 } 00120 00121 Q3StrList lst; 00122 Q3UriDrag::decode( e, lst ); 00123 for (Q3StrListIterator it(lst); *it; ++it) 00124 { 00125 KUrl url = stringToUrl( *it ); 00126 if ( !url.isValid() ) 00127 { 00128 uris.clear(); 00129 break; 00130 } 00131 uris.append( url ); 00132 } 00133 return !uris.isEmpty(); 00134 } 00135 00136 bool K3URLDrag::decode( const QMimeSource *e, KUrl::List &uris, QMap<QString,QString>& metaData ) 00137 { 00138 if ( decode( e, uris ) ) // first decode the URLs (see above) 00139 { 00140 QByteArray ba = e->encodedData( "application/x-kio-metadata" ); 00141 if ( ba.size() ) 00142 { 00143 QString s = ba.data(); 00144 const QStringList l = s.split( "$@@$", QString::SkipEmptyParts ); 00145 QStringList::ConstIterator it = l.begin(); 00146 bool readingKey = true; // true, then false, then true, etc. 00147 QString key; 00148 for ( ; it != l.end(); ++it ) { 00149 if ( readingKey ) 00150 key = *it; 00151 else 00152 metaData.replace( key, *it ); 00153 readingKey = !readingKey; 00154 } 00155 Q_ASSERT( readingKey ); // an odd number of items would be, well, odd ;-) 00156 } 00157 return true; // Success, even if no metadata was found 00158 } 00159 return false; // Couldn't decode the URLs 00160 } 00161 00163 00164 const char * K3URLDrag::format( int i ) const 00165 { 00166 if ( i == 0 ) 00167 return "text/uri-list"; 00168 else if ( i == 1 ) 00169 return "application/x-kio-metadata"; 00170 if ( d && d->m_exportAsText == false ) 00171 return 0; 00172 if ( i == 2 ) 00173 return "text/plain"; 00174 else if ( i == 3 ) //Support this for apps that use plain XA_STRING clipboard 00175 return "text/plain;charset=ISO-8859-1"; 00176 else if ( i == 4 ) //Support this for apps that use the UTF_STRING clipboard 00177 return "text/plain;charset=UTF-8"; 00178 else return 0; 00179 } 00180 00181 QByteArray K3URLDrag::encodedData( const char* mime ) const 00182 { 00183 QByteArray a; 00184 QByteArray mimetype( mime ); 00185 if ( mimetype == "text/uri-list" ) 00186 return Q3UriDrag::encodedData( mime ); 00187 else if ( mimetype == "text/plain" ) 00188 { 00189 QStringList uris; 00190 for (Q3StrListIterator it(m_urls); *it; ++it) 00191 uris.append(stringToUrl(*it).prettyUrl()); 00192 00193 QByteArray s = uris.join( "\n" ).toLocal8Bit(); 00194 if( uris.count() > 1 ) // terminate last line, unless it's the only line 00195 s.append( "\n" ); 00196 a.resize( s.length()); 00197 memcpy( a.data(), s.data(), s.length()); // no trailing zero in clipboard text 00198 } 00199 else if ( mimetype.toLower() == "text/plain;charset=iso-8859-1") 00200 { 00201 QStringList uris; 00202 for (Q3StrListIterator it(m_urls); *it; ++it) 00203 uris.append(stringToUrl(*it).url()); // was using ",4" - the mib for latin1 00204 00205 QByteArray s = uris.join( "\n" ).toLatin1(); 00206 if( uris.count() > 1 ) 00207 s.append( "\n" ); 00208 a.resize( s.length()); 00209 memcpy( a.data(), s.data(), s.length()); 00210 } 00211 else if ( mimetype.toLower() == "text/plain;charset=utf-8") 00212 { 00213 QStringList uris; 00214 for (Q3StrListIterator it(m_urls); *it; ++it) 00215 uris.append(stringToUrl(*it).prettyUrl()); 00216 00217 QByteArray s = uris.join( "\n" ).toUtf8(); 00218 if( uris.count() > 1 ) 00219 s.append( "\n" ); 00220 a.resize( s.length()); 00221 memcpy( a.data(), s.data(), s.length()); 00222 } 00223 else if ( mimetype == "application/x-kio-metadata" ) 00224 { 00225 if ( !m_metaData.isEmpty() ) 00226 { 00227 QString s; 00228 QMap<QString,QString>::ConstIterator it; 00229 for( it = m_metaData.begin(); it != m_metaData.end(); ++it ) 00230 { 00231 s += it.key(); 00232 s += "$@@$"; 00233 s += it.data(); 00234 s += "$@@$"; 00235 } 00236 a.resize( s.length() + 1 ); 00237 memcpy( a.data(), s.toLatin1().constData(), a.size() ); 00238 } 00239 } 00240 return a; 00241 } 00242 00243 KUrl K3URLDrag::stringToUrl(const QByteArray &s) 00244 { 00245 if (strncmp(s.data(), "file:", 5) == 0) 00246 return KUrl(s /*, KGlobal::locale()->fileEncodingMib()*/); 00247 00248 return KUrl(s /*, 106*/); // 106 is mib enum for utf8 codec; 00249 } 00250 00251 QString K3URLDrag::urlToString(const KUrl &url) 00252 { 00253 if (url.isLocalFile()) 00254 { 00255 #if 1 00256 return url.url(/*0 , KGlobal::locale()->fileEncodingMib()*/); 00257 #else 00258 // According to the XDND spec, file:/ URLs for DND must have 00259 // the hostname part. But in really it just breaks many apps, 00260 // so it's disabled for now. 00261 QString s = url.url(0, KGlobal::locale()->fileEncodingMib()); 00262 if( !s.startsWith( "file://" )) 00263 { 00264 char hostname[257]; 00265 if ( gethostname( hostname, 255 ) == 0 ) 00266 { 00267 hostname[256] = '\0'; 00268 return QString( "file://" ) + hostname + s.mid( 5 ); 00269 } 00270 } 00271 #endif 00272 } 00273 00274 if ( url.protocol() == "mailto" ) { 00275 return url.path(); 00276 } 00277 00278 return url.url(/*0 , 106*/); // 106 is mib enum for utf8 codec 00279 } 00280 00281 // deprecated ctor 00282 K3URLDrag::K3URLDrag( const Q3StrList & urls, const QMap<QString,QString>& metaData, 00283 QWidget * dragSource ) : 00284 Q3UriDrag( urls, dragSource ), m_urls( urls ), m_metaData( metaData ), d( 0 ) {}
KDE 4.6 API Reference