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