00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "paste.h"
00020 #include "pastedialog.h"
00021
00022 #include "kio/copyjob.h"
00023 #include "kio/deletejob.h"
00024 #include "kio/global.h"
00025 #include "kio/netaccess.h"
00026 #include "kio/renamedialog.h"
00027 #include "kio/kprotocolmanager.h"
00028 #include "jobuidelegate.h"
00029
00030 #include <kurl.h>
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #include <kinputdialog.h>
00034 #include <kmessagebox.h>
00035 #include <kmimetype.h>
00036 #include <ktemporaryfile.h>
00037
00038 #include <QtGui/QApplication>
00039 #include <QtGui/QClipboard>
00040 #include <QMimeData>
00041 #include <QtCore/QTextIStream>
00042
00043 static KUrl getNewFileName( const KUrl &u, const QString& text, QWidget *widget )
00044 {
00045 bool ok;
00046 QString dialogText( text );
00047 if ( dialogText.isEmpty() )
00048 dialogText = i18n( "Filename for clipboard content:" );
00049 QString file = KInputDialog::getText( QString(), dialogText, QString(), &ok, widget );
00050 if ( !ok )
00051 return KUrl();
00052
00053 KUrl myurl(u);
00054 myurl.addPath( file );
00055
00056
00057
00058 if (KIO::NetAccess::exists(myurl, KIO::NetAccess::DestinationSide, widget))
00059 {
00060 kDebug(7007) << "Paste will overwrite file. Prompting...";
00061 KIO::RenameDialog_Result res = KIO::R_OVERWRITE;
00062
00063 KIO::RenameDialog dlg( widget,
00064 i18n("File Already Exists"),
00065 u.pathOrUrl(),
00066 myurl.pathOrUrl(),
00067 (KIO::RenameDialog_Mode) (KIO::M_OVERWRITE | KIO::M_SINGLE) );
00068 res = static_cast<KIO::RenameDialog_Result>(dlg.exec());
00069
00070 if ( res == KIO::R_RENAME )
00071 {
00072 myurl = dlg.newDestUrl();
00073 }
00074 else if ( res == KIO::R_CANCEL )
00075 {
00076 return KUrl();
00077 } else if (res == KIO::R_OVERWRITE)
00078 {
00079
00080
00081
00082
00083
00084 KIO::Job* delJob = KIO::del(myurl);
00085 delJob->exec();
00086 }
00087 }
00088
00089 return myurl;
00090 }
00091
00092
00093 static KIO::CopyJob* pasteDataAsyncTo( const KUrl& newUrl, const QByteArray& _data )
00094 {
00095
00096
00097
00098
00099
00100 KTemporaryFile tempFile;
00101 tempFile.setAutoRemove(false);
00102 tempFile.open();
00103 tempFile.write(_data.data(), _data.size());
00104 tempFile.flush();
00105
00106 KUrl origUrl(tempFile.fileName());
00107
00108 return KIO::move(origUrl, newUrl);
00109 }
00110
00111 #ifndef QT_NO_MIMECLIPBOARD
00112 static KIO::CopyJob* chooseAndPaste( const KUrl& u, const QMimeData* mimeData,
00113 const QStringList& formats,
00114 const QString& text,
00115 QWidget* widget,
00116 bool clipboard )
00117 {
00118 QStringList formatLabels;
00119 for ( int i = 0; i < formats.size(); ++i ) {
00120 const QString& fmt = formats[i];
00121 KMimeType::Ptr mime = KMimeType::mimeType(fmt, KMimeType::ResolveAliases);
00122 if (mime)
00123 formatLabels.append( i18n("%1 (%2)", mime->comment(), fmt) );
00124 else
00125 formatLabels.append( fmt );
00126 }
00127
00128 QString dialogText( text );
00129 if ( dialogText.isEmpty() )
00130 dialogText = i18n( "Filename for clipboard content:" );
00131
00132 KIO::PasteDialog dlg( QString::null, dialogText, QString(), formatLabels, widget, clipboard );
00133
00134 if ( dlg.exec() != KDialog::Accepted )
00135 return 0;
00136
00137 if ( clipboard && dlg.clipboardChanged() ) {
00138 KMessageBox::sorry( widget,
00139 i18n( "The clipboard has changed since you used 'paste': "
00140 "the chosen data format is no longer applicable. "
00141 "Please copy again what you wanted to paste." ) );
00142 return 0;
00143 }
00144
00145 const QString result = dlg.lineEditText();
00146 const QString chosenFormat = formats[ dlg.comboItem() ];
00147
00148 kDebug() << " result=" << result << " chosenFormat=" << chosenFormat;
00149 KUrl newUrl( u );
00150 newUrl.addPath( result );
00151
00152
00153
00154 if ( clipboard ) {
00155 mimeData = QApplication::clipboard()->mimeData();
00156 }
00157 const QByteArray ba = mimeData->data( chosenFormat );
00158 KIO::CopyJob* job = pasteDataAsyncTo( newUrl, ba );
00159 job->ui()->setWindow(widget);
00160 return job;
00161 }
00162 #endif
00163
00164
00165 #ifndef QT_NO_MIMECLIPBOARD
00166
00167 static QStringList extractFormats(const QMimeData* mimeData)
00168 {
00169 QStringList formats;
00170 const QStringList allFormats = mimeData->formats();
00171 for (QStringList::const_iterator it = allFormats.constBegin(), end = allFormats.constEnd();
00172 it != end; ++it) {
00173 if ((*it) == QLatin1String("application/x-qiconlist"))
00174 continue;
00175 if ((*it) == QLatin1String("application/x-kde-cutselection"))
00176 continue;
00177 if (!(*it).contains(QLatin1Char('/')))
00178 continue;
00179 formats.append(*it);
00180 }
00181 return formats;
00182 }
00183
00184
00185 KIO::CopyJob* KIO::pasteMimeSource( const QMimeData* mimeData, const KUrl& destUrl,
00186 const QString& dialogText, QWidget* widget, bool clipboard )
00187 {
00188 QByteArray ba;
00189
00190
00191
00192 QString text;
00193 if ( mimeData->hasText() )
00194 {
00195 ba = mimeData->text().toLocal8Bit();
00196 }
00197 else
00198 {
00199 const QStringList formats = extractFormats(mimeData);
00200 if ( formats.size() == 0 )
00201 return 0;
00202
00203 if ( formats.size() > 1 ) {
00204 return chooseAndPaste( destUrl, mimeData, formats, dialogText, widget, clipboard );
00205 }
00206 ba = mimeData->data( formats.first() );
00207 }
00208 if ( ba.isEmpty() )
00209 {
00210 KMessageBox::sorry( widget, i18n("The clipboard is empty") );
00211 return 0;
00212 }
00213
00214 return pasteDataAsync( destUrl, ba, widget, dialogText );
00215 }
00216
00217 KIO_EXPORT bool KIO::canPasteMimeSource(const QMimeData* data)
00218 {
00219 return data->hasText() || !extractFormats(data).isEmpty();
00220 }
00221
00222 #endif
00223
00224
00225 KIO_EXPORT KIO::Job *KIO::pasteClipboard( const KUrl& destUrl, QWidget* widget, bool move )
00226 {
00227 if ( !destUrl.isValid() ) {
00228 KMessageBox::error( widget, i18n( "Malformed URL\n%1", destUrl.prettyUrl() ) );
00229 return 0;
00230 }
00231
00232 #ifndef QT_NO_MIMECLIPBOARD
00233 const QMimeData *mimeData = QApplication::clipboard()->mimeData();
00234
00235
00236 const KUrl::List urls = KUrl::List::fromMimeData(mimeData, KUrl::List::PreferLocalUrls);
00237 if ( !urls.isEmpty() ) {
00238 KIO::Job *res = 0;
00239 if ( move )
00240 res = KIO::move( urls, destUrl );
00241 else
00242 res = KIO::copy( urls, destUrl );
00243 res->ui()->setWindow(widget);
00244
00245
00246 if ( move ) {
00247 QApplication::clipboard()->clear();
00248
00249 KUrl::List newUrls;
00250 for (int i = 0; i < urls.size(); i++) {
00251 KUrl dUrl = destUrl;
00252 dUrl.addPath(urls.at(i).fileName());
00253 newUrls.append(dUrl);
00254 }
00255
00256 QMimeData* mime = new QMimeData();
00257 newUrls.populateMimeData(mime);
00258 QApplication::clipboard()->setMimeData(mime);
00259 }
00260
00261 return res;
00262 }
00263 return pasteMimeSource( mimeData, destUrl, QString(), widget, true );
00264 #else
00265 QByteArray ba;
00266 QTextStream txtStream( ba, QIODevice::WriteOnly );
00267
00268 QStringList data = QApplication::clipboard()->text().split('\n', QString::SkipEmptyParts);
00269
00270 KUrl::List urls;
00271 KURLDrag::decode(data, urls);
00272 QStringList::const_iterator end(data.end());
00273 for(QStringList::const_iterator it=data.begin(); it!=end; ++it)
00274 txtStream << *it;
00275 if ( ba.size() == 0 )
00276 {
00277 KMessageBox::sorry(widget, i18n("The clipboard is empty"));
00278 return 0;
00279 }
00280 return pasteDataAsync( destUrl, ba, widget );
00281 #endif
00282 }
00283
00284
00285 KIO_EXPORT void KIO::pasteData( const KUrl& u, const QByteArray& _data, QWidget* widget )
00286 {
00287 const KUrl newUrl = getNewFileName( u, QString(), widget );
00288
00289
00290
00291 if (newUrl.isEmpty())
00292 return;
00293
00294 KTemporaryFile tempFile;
00295 tempFile.open();
00296 tempFile.write( _data.data(), _data.size() );
00297 tempFile.flush();
00298
00299 (void) KIO::NetAccess::upload( tempFile.fileName(), newUrl, widget );
00300 }
00301
00302
00303
00304 KIO_EXPORT KIO::CopyJob* KIO::pasteDataAsync( const KUrl& u, const QByteArray& _data, QWidget *widget, const QString& text )
00305 {
00306 KUrl newUrl = getNewFileName( u, text, widget );
00307
00308 if (newUrl.isEmpty())
00309 return 0;
00310
00311 KIO::CopyJob* job = pasteDataAsyncTo( newUrl, _data );
00312 job->ui()->setWindow(widget);
00313 return job;
00314 }
00315
00316
00317
00318 KIO_EXPORT QString KIO::pasteActionText()
00319 {
00320 const QMimeData *mimeData = QApplication::clipboard()->mimeData();
00321 KUrl::List urls = KUrl::List::fromMimeData( mimeData );
00322 if ( !urls.isEmpty() ) {
00323 if ( urls.first().isLocalFile() )
00324 return i18np( "&Paste File", "&Paste %1 Files", urls.count() );
00325 else
00326 return i18np( "&Paste URL", "&Paste %1 URLs", urls.count() );
00327 } else if ( !mimeData->formats().isEmpty() ) {
00328 return i18n( "&Paste Clipboard Contents" );
00329 } else {
00330 return QString();
00331 }
00332 }