libkonq Library API Documentation

konq_operations.cc

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 modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or 00007 (at your option) any later version. 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 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #include <qclipboard.h> 00020 #include "konq_operations.h" 00021 00022 #include <kautomount.h> 00023 #include <kinputdialog.h> 00024 #include <klocale.h> 00025 #include <kmessagebox.h> 00026 #include <krun.h> 00027 #include <kshell.h> 00028 00029 #include <kdirnotify_stub.h> 00030 00031 #include <dcopclient.h> 00032 #include "konq_undo.h" 00033 #include "konq_defaults.h" 00034 #include "konqbookmarkmanager.h" 00035 00036 // For doDrop 00037 #include <qdir.h>//first 00038 #include <assert.h> 00039 #include <kapplication.h> 00040 #include <kipc.h> 00041 #include <kdebug.h> 00042 #include <kfileitem.h> 00043 #include <kdesktopfile.h> 00044 #include <kurldrag.h> 00045 #include <kglobalsettings.h> 00046 #include <kimageio.h> 00047 #include <kio/job.h> 00048 #include <kio/jobclasses.h> 00049 #include <kio/paste.h> 00050 #include <konq_drag.h> 00051 #include <konq_iconviewwidget.h> 00052 #include <kprotocolinfo.h> 00053 #include <kprocess.h> 00054 #include <kstringhandler.h> 00055 #include <qpopupmenu.h> 00056 #include <unistd.h> 00057 #include <X11/Xlib.h> 00058 00059 KBookmarkManager * KonqBookmarkManager::s_bookmarkManager; 00060 00061 KonqOperations::KonqOperations( QWidget *parent ) 00062 : QObject( parent, "KonqOperations" ), m_info(0L), m_pasteInfo(0L) 00063 { 00064 } 00065 00066 KonqOperations::~KonqOperations() 00067 { 00068 delete m_info; 00069 delete m_pasteInfo; 00070 } 00071 00072 void KonqOperations::editMimeType( const QString & mimeType ) 00073 { 00074 QString keditfiletype = QString::fromLatin1("keditfiletype"); 00075 KRun::runCommand( keditfiletype + " " + KProcess::quote(mimeType), 00076 keditfiletype, keditfiletype /*unused*/); 00077 } 00078 00079 void KonqOperations::del( QWidget * parent, int method, const KURL::List & selectedURLs ) 00080 { 00081 kdDebug(1203) << "KonqOperations::del " << parent->className() << endl; 00082 if ( selectedURLs.isEmpty() ) 00083 { 00084 kdWarning(1203) << "Empty URL list !" << endl; 00085 return; 00086 } 00087 // We have to check the trash itself isn't part of the selected 00088 // URLs. 00089 bool bTrashIncluded = false; 00090 KURL::List::ConstIterator it = selectedURLs.begin(); 00091 for ( ; it != selectedURLs.end() && !bTrashIncluded; ++it ) 00092 if ( (*it).isLocalFile() && (*it).path(1) == KGlobalSettings::trashPath() ) 00093 bTrashIncluded = true; 00094 int confirmation = DEFAULT_CONFIRMATION; 00095 if ( bTrashIncluded ) 00096 { 00097 switch ( method ) { 00098 case TRASH: 00099 KMessageBox::sorry(0, i18n("You cannot trash the trash bin.")); 00100 return; 00101 case DEL: 00102 case SHRED: 00103 confirmation = FORCE_CONFIRMATION; 00104 break; 00105 } 00106 } 00107 KonqOperations * op = new KonqOperations( parent ); 00108 op->_del( method, selectedURLs, confirmation ); 00109 } 00110 00111 void KonqOperations::emptyTrash() 00112 { 00113 KonqOperations *op = new KonqOperations( 0L ); 00114 00115 QDir trashDir( KGlobalSettings::trashPath() ); 00116 QStringList files = trashDir.entryList( QDir::All | QDir::Hidden | QDir::System ); 00117 files.remove(QString(".")); 00118 files.remove(QString("..")); 00119 files.remove(QString(".directory")); 00120 00121 QStringList::Iterator it(files.begin()); 00122 for (; it != files.end(); ++it ) 00123 (*it).prepend( KGlobalSettings::trashPath() ); 00124 00125 KURL::List urls; 00126 it = files.begin(); 00127 for (; it != files.end(); ++it ) 00128 { 00129 KURL u; 00130 u.setPath( *it ); 00131 urls.append( u ); 00132 } 00133 00134 if ( urls.count() > 0 ) 00135 op->_del( EMPTYTRASH, urls, SKIP_CONFIRMATION ); 00136 00137 } 00138 00139 void KonqOperations::mkdir( QWidget *parent, const KURL & url ) 00140 { 00141 KIO::Job * job = KIO::mkdir( url ); 00142 KonqOperations * op = new KonqOperations( parent ); 00143 op->setOperation( job, MKDIR, KURL::List(), url ); 00144 (void) new KonqCommandRecorder( KonqCommand::MKDIR, KURL(), url, job ); // no support yet, apparently 00145 } 00146 00147 void KonqOperations::doPaste( QWidget * parent, const KURL & destURL ) 00148 { 00149 doPaste(parent, destURL, QPoint()); 00150 } 00151 00152 void KonqOperations::doPaste( QWidget * parent, const KURL & destURL, const QPoint &pos ) 00153 { 00154 // move or not move ? 00155 bool move = false; 00156 QMimeSource *data = QApplication::clipboard()->data(); 00157 if ( data->provides( "application/x-kde-cutselection" ) ) { 00158 move = KonqDrag::decodeIsCutSelection( data ); 00159 kdDebug(1203) << "move (from clipboard data) = " << move << endl; 00160 } 00161 00162 KIO::Job *job = KIO::pasteClipboard( destURL, move ); 00163 if ( job ) 00164 { 00165 KonqOperations * op = new KonqOperations( parent ); 00166 KIO::CopyJob * copyJob = static_cast<KIO::CopyJob *>(job); 00167 KIOPasteInfo * pi = new KIOPasteInfo; 00168 pi->destURL = destURL; 00169 pi->mousePos = pos; 00170 op->setPasteInfo( pi ); 00171 op->setOperation( job, move ? MOVE : COPY, copyJob->srcURLs(), copyJob->destURL() ); 00172 (void) new KonqCommandRecorder( move ? KonqCommand::MOVE : KonqCommand::COPY, KURL::List(), destURL, job ); 00173 } 00174 } 00175 00176 void KonqOperations::copy( QWidget * parent, int method, const KURL::List & selectedURLs, const KURL& destUrl ) 00177 { 00178 kdDebug(1203) << "KonqOperations::copy() " << parent->className() << endl; 00179 if ((method!=COPY) && (method!=MOVE) && (method!=LINK)) 00180 { 00181 kdWarning(1203) << "Illegal copy method !" << endl; 00182 return; 00183 } 00184 if ( selectedURLs.isEmpty() ) 00185 { 00186 kdWarning(1203) << "Empty URL list !" << endl; 00187 return; 00188 } 00189 00190 KonqOperations * op = new KonqOperations( parent ); 00191 KIO::Job* job(0); 00192 if (method==LINK) 00193 job= KIO::link( selectedURLs, destUrl); 00194 else if (method==MOVE) 00195 job= KIO::move( selectedURLs, destUrl); 00196 else 00197 job= KIO::copy( selectedURLs, destUrl); 00198 00199 op->setOperation( job, method, selectedURLs, destUrl ); 00200 00201 if (method==COPY) 00202 (void) new KonqCommandRecorder( KonqCommand::COPY, selectedURLs, destUrl, job ); 00203 else 00204 (void) new KonqCommandRecorder( method==MOVE?KonqCommand::MOVE:KonqCommand::LINK, selectedURLs, destUrl, job ); 00205 } 00206 00207 void KonqOperations::_del( int method, const KURL::List & _selectedURLs, int confirmation ) 00208 { 00209 KURL::List selectedURLs; 00210 for (KURL::List::ConstIterator it = _selectedURLs.begin(); it != _selectedURLs.end(); ++it) 00211 if (KProtocolInfo::supportsDeleting(*it)) 00212 selectedURLs.append(*it); 00213 if (selectedURLs.isEmpty()) { 00214 delete this; 00215 return; 00216 } 00217 00218 m_method = method; 00219 if ( confirmation == SKIP_CONFIRMATION || askDeleteConfirmation( selectedURLs, confirmation ) ) 00220 { 00221 //m_srcURLs = selectedURLs; 00222 KIO::Job *job; 00223 switch( method ) 00224 { 00225 case TRASH: 00226 { 00227 // Make sure the trash exists. Usually the case, but not when starting 00228 // konq standalone. 00229 QString trashPath = KGlobalSettings::trashPath(); 00230 if ( !QFile::exists( trashPath ) ) 00231 KStandardDirs::makeDir( QFile::encodeName( trashPath ) ); 00232 KURL u; 00233 u.setPath( trashPath ); 00234 job = KIO::move( selectedURLs, u ); 00235 (void) new KonqCommandRecorder( KonqCommand::MOVE, selectedURLs, u, job ); 00236 break; 00237 } 00238 case EMPTYTRASH: 00239 case DEL: 00240 job = KIO::del( selectedURLs ); 00241 break; 00242 case SHRED: 00243 job = KIO::del( selectedURLs, true ); 00244 break; 00245 default: 00246 Q_ASSERT(0); 00247 delete this; 00248 return; 00249 } 00250 connect( job, SIGNAL( result( KIO::Job * ) ), 00251 SLOT( slotResult( KIO::Job * ) ) ); 00252 } else 00253 delete this; 00254 } 00255 00256 bool KonqOperations::askDeleteConfirmation( const KURL::List & selectedURLs, int confirmation ) 00257 { 00258 QString keyName; 00259 bool ask = ( confirmation == FORCE_CONFIRMATION ); 00260 if ( !ask ) 00261 { 00262 KConfig config("konquerorrc", true, false); 00263 config.setGroup( "Trash" ); 00264 keyName = ( m_method == DEL ? "ConfirmDelete" : m_method == SHRED ? "ConfirmShred" : "ConfirmTrash" ); 00265 bool defaultValue = ( m_method == DEL ? DEFAULT_CONFIRMDELETE : m_method == SHRED ? DEFAULT_CONFIRMSHRED : DEFAULT_CONFIRMTRASH ); 00266 ask = config.readBoolEntry( keyName, defaultValue ); 00267 } 00268 if ( ask ) 00269 { 00270 KURL::List::ConstIterator it = selectedURLs.begin(); 00271 QStringList prettyList; 00272 for ( ; it != selectedURLs.end(); ++it ) 00273 prettyList.append( (*it).prettyURL() ); 00274 00275 int result; 00276 switch(m_method) 00277 { 00278 case DEL: 00279 result = KMessageBox::warningContinueCancelList( 0, 00280 i18n( "Do you really want to delete this item?", "Do you really want to delete these %n items?", prettyList.count()), 00281 prettyList, 00282 i18n( "Delete Files" ), 00283 KGuiItem( i18n( "Delete" ), "editdelete" ), 00284 keyName, KMessageBox::Dangerous); 00285 break; 00286 00287 case SHRED: 00288 result = KMessageBox::warningContinueCancelList( 0, 00289 i18n( "Do you really want to shred this item?", "Do you really want to shred these %n items?", prettyList.count()), 00290 prettyList, 00291 i18n( "Shred Files" ), 00292 KGuiItem( i18n( "Shred" ), "editshred" ), 00293 keyName, KMessageBox::Dangerous); 00294 break; 00295 00296 case MOVE: 00297 default: 00298 result = KMessageBox::warningContinueCancelList( 0, 00299 i18n( "Do you really want to move this item to the trash?", "Do you really want to move these %n items to the trash?", prettyList.count()), 00300 prettyList, 00301 i18n( "Move to Trash" ), 00302 KGuiItem( i18n( "Verb", "Trash" ), "edittrash"), 00303 keyName, KMessageBox::Dangerous); 00304 } 00305 if (!keyName.isEmpty()) 00306 { 00307 // Check kmessagebox setting... erase & copy to konquerorrc. 00308 KConfig *config = kapp->config(); 00309 KConfigGroupSaver saver(config, "Notification Messages"); 00310 if (!config->readBoolEntry(keyName, true)) 00311 { 00312 config->writeEntry(keyName, true); 00313 config->sync(); 00314 KConfig konq_config("konquerorrc", false); 00315 konq_config.setGroup( "Trash" ); 00316 konq_config.writeEntry( keyName, false ); 00317 } 00318 } 00319 return (result == KMessageBox::Continue); 00320 } 00321 return true; 00322 } 00323 00324 void KonqOperations::doDrop( const KFileItem * destItem, const KURL & dest, QDropEvent * ev, QWidget * parent ) 00325 { 00326 kdDebug(1203) << "doDrop: dest : " << dest.url() << endl; 00327 KURL::List lst; 00328 QMap<QString, QString> metaData; 00329 if ( KURLDrag::decode( ev, lst, metaData ) ) // Are they urls ? 00330 { 00331 if( lst.count() == 0 ) 00332 { 00333 kdWarning(1203) << "Oooops, no data ...." << endl; 00334 ev->accept(false); 00335 return; 00336 } 00337 kdDebug(1203) << "KonqOperations::doDrop metaData: " << metaData.count() << " entries." << endl; 00338 QMap<QString,QString>::ConstIterator mit; 00339 for( mit = metaData.begin(); mit != metaData.end(); ++mit ) 00340 { 00341 kdDebug(1203) << "metaData: key=" << mit.key() << " value=" << mit.data() << endl; 00342 } 00343 // Check if we dropped something on itself 00344 KURL::List::Iterator it = lst.begin(); 00345 for ( ; it != lst.end() ; it++ ) 00346 { 00347 kdDebug(1203) << "URL : " << (*it).url() << endl; 00348 if ( dest.equals( *it, true /*ignore trailing slashes*/ ) ) 00349 { 00350 // The event source may be the view or an item (icon) 00351 // Note: ev->source() can be 0L! (in case of kdesktop) (Simon) 00352 if ( !ev->source() || ev->source() != parent && ev->source()->parent() != parent ) 00353 KMessageBox::sorry( parent, i18n("You cannot drop a folder on to itself") ); 00354 kdDebug(1203) << "Dropped on itself" << endl; 00355 ev->accept(false); 00356 return; // do nothing instead of displaying kfm's annoying error box 00357 } 00358 } 00359 00360 // Check the state of the modifiers key at the time of the drop 00361 Window root; 00362 Window child; 00363 int root_x, root_y, win_x, win_y; 00364 uint keybstate; 00365 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child, 00366 &root_x, &root_y, &win_x, &win_y, &keybstate ); 00367 00368 QDropEvent::Action action = ev->action(); 00369 // Check for the drop of a bookmark -> we want a Link action 00370 if ( ev->provides("application/x-xbel") ) 00371 { 00372 keybstate |= ControlMask | ShiftMask; 00373 action = QDropEvent::Link; 00374 kdDebug(1203) << "KonqOperations::doDrop Bookmark -> emulating Link" << endl; 00375 } 00376 00377 KonqOperations * op = new KonqOperations(parent); 00378 op->setDropInfo( new DropInfo( keybstate, lst, metaData, win_x, win_y, action ) ); 00379 00380 // Ok, now we need destItem. 00381 if ( destItem ) 00382 { 00383 op->asyncDrop( destItem ); // we have it already 00384 } 00385 else 00386 { 00387 // we need to stat to get it. 00388 op->_statURL( dest, op, SLOT( asyncDrop( const KFileItem * ) ) ); 00389 } 00390 // In both cases asyncDrop will delete op when done 00391 00392 ev->acceptAction(); 00393 } 00394 else 00395 { 00396 QStrList formats; 00397 00398 for ( int i = 0; ev->format( i ); i++ ) 00399 if ( *( ev->format( i ) ) ) 00400 formats.append( ev->format( i ) ); 00401 if ( formats.count() >= 1 ) 00402 { 00403 //kdDebug(1203) << "Pasting to " << dest.url() << endl; 00404 00405 QByteArray data; 00406 00407 QString text; 00408 if ( QTextDrag::canDecode( ev ) && QTextDrag::decode( ev, text ) ) 00409 { 00410 QTextStream txtStream( data, IO_WriteOnly ); 00411 txtStream << text; 00412 } 00413 else 00414 data = ev->data( formats.first() ); 00415 00416 // Delay the call to KIO::pasteData so that the event filters can return. See #38688. 00417 KonqOperations * op = new KonqOperations(parent); 00418 KIOPasteInfo * pi = new KIOPasteInfo; 00419 pi->data = data; 00420 pi->destURL = dest; 00421 pi->mousePos = ev->pos(); 00422 pi->dialogText = i18n( "File name for dropped contents:" ); 00423 op->setPasteInfo( pi ); 00424 QTimer::singleShot( 0, op, SLOT( slotKIOPaste() ) ); 00425 } 00426 ev->acceptAction(); 00427 } 00428 } 00429 00430 void KonqOperations::slotKIOPaste() 00431 { 00432 assert(m_pasteInfo); // setPasteInfo should have been called before 00433 KIO::CopyJob *job = KIO::pasteDataAsync( m_pasteInfo->destURL, m_pasteInfo->data, m_pasteInfo->dialogText ); 00434 if ( job ) 00435 { 00436 setOperation( job, COPY, KURL::List(), job->destURL() ); 00437 (void) new KonqCommandRecorder( KonqCommand::COPY, KURL::List(), m_destURL, job ); 00438 } 00439 else 00440 { 00441 delete this; 00442 } 00443 } 00444 00445 void KonqOperations::asyncDrop( const KFileItem * destItem ) 00446 { 00447 assert(m_info); // setDropInfo should have been called before asyncDrop 00448 m_destURL = destItem->url(); 00449 00450 //kdDebug(1203) << "KonqOperations::asyncDrop destItem->mode=" << destItem->mode() << " url=" << m_destURL << endl; 00451 // Check what the destination is 00452 if ( destItem->isDir() ) 00453 { 00454 doFileCopy(); 00455 return; 00456 } 00457 if ( !m_destURL.isLocalFile() ) 00458 { 00459 // We dropped onto a remote URL that is not a directory! 00460 // (e.g. an HTTP link in the sidebar). 00461 // Can't do that, but we can't prevent it before stating the dest.... 00462 kdWarning(1203) << "Cannot drop onto " << m_destURL << endl; 00463 delete this; 00464 return; 00465 } 00466 if ( destItem->mimetype() == "application/x-desktop") 00467 { 00468 // Local .desktop file. What type ? 00469 KDesktopFile desktopFile( m_destURL.path() ); 00470 if ( desktopFile.hasApplicationType() ) 00471 { 00472 QString error; 00473 QStringList stringList; 00474 KURL::List lst = m_info->lst; 00475 KURL::List::Iterator it = lst.begin(); 00476 for ( ; it != lst.end() ; it++ ) 00477 { 00478 stringList.append((*it).url()); 00479 } 00480 if ( KApplication::startServiceByDesktopPath( m_destURL.path(), stringList, &error ) > 0 ) 00481 KMessageBox::error( 0L, error ); 00482 } 00483 else 00484 { 00485 // Device or Link -> adjust dest 00486 if ( desktopFile.hasDeviceType() && desktopFile.hasKey("MountPoint") ) { 00487 QString point = desktopFile.readEntry( "MountPoint" ); 00488 m_destURL.setPath( point ); 00489 QString dev = desktopFile.readDevice(); 00490 QString mp = KIO::findDeviceMountPoint( dev ); 00491 // Is the device already mounted ? 00492 if ( !mp.isNull() ) 00493 doFileCopy(); 00494 else 00495 { 00496 bool ro = desktopFile.readBoolEntry( "ReadOnly", false ); 00497 QString fstype = desktopFile.readEntry( "FSType" ); 00498 KAutoMount* am = new KAutoMount( ro, fstype, dev, point, m_destURL.path(), false ); 00499 connect( am, SIGNAL( finished() ), this, SLOT( doFileCopy() ) ); 00500 } 00501 return; 00502 } 00503 else if ( desktopFile.hasLinkType() && desktopFile.hasKey("URL") ) { 00504 m_destURL = desktopFile.readPathEntry("URL"); 00505 doFileCopy(); 00506 return; 00507 } 00508 // else, well: mimetype, service, servicetype or .directory. Can't really drop anything on those. 00509 } 00510 } 00511 else 00512 { 00513 // Should be a local executable 00514 // (If this fails, there is a bug in KFileItem::acceptsDrops) 00515 kdDebug(1203) << "KonqOperations::doDrop " << m_destURL.path() << "should be an executable" << endl; 00516 Q_ASSERT ( access( QFile::encodeName(m_destURL.path()), X_OK ) == 0 ); 00517 KProcess proc; 00518 proc << m_destURL.path() ; 00519 // Launch executable for each of the files 00520 KURL::List lst = m_info->lst; 00521 KURL::List::Iterator it = lst.begin(); 00522 for ( ; it != lst.end() ; it++ ) 00523 proc << (*it).path(); // assume local files 00524 kdDebug(1203) << "starting " << m_destURL.path() << " with " << lst.count() << " arguments" << endl; 00525 proc.start( KProcess::DontCare ); 00526 } 00527 delete this; 00528 } 00529 00530 void KonqOperations::doFileCopy() 00531 { 00532 assert(m_info); // setDropInfo - and asyncDrop - should have been called before asyncDrop 00533 KURL::List lst = m_info->lst; 00534 QDropEvent::Action action = m_info->action; 00535 QString newTrashPath; 00536 bool isDesktopFile = false; 00537 bool itemIsOnDesktop = false; 00538 KURL::List mlst; 00539 for (KURL::List::ConstIterator it = lst.begin(); it != lst.end(); ++it) 00540 { 00541 bool local = (*it).isLocalFile(); 00542 if ( local && ((*it).path(1) == KGlobalSettings::trashPath())) 00543 newTrashPath=m_destURL.path()+(*it).path().right((*it).path().length()-(*it).directory().length()); 00544 if ( KProtocolInfo::supportsDeleting( *it ) && (!local || QFileInfo((*it).directory()).isWritable() )) 00545 mlst.append(*it); 00546 if ( local && KDesktopFile::isDesktopFile((*it).path())) 00547 isDesktopFile = true; 00548 if ( local && (*it).path().startsWith(KGlobalSettings::desktopPath())) 00549 itemIsOnDesktop = true; 00550 } 00551 00552 bool linkOnly = false; 00553 if (isDesktopFile && !kapp->authorize("run_desktop_files") && 00554 (m_destURL.path(1) == KGlobalSettings::desktopPath()) ) 00555 { 00556 linkOnly = true; 00557 } 00558 00559 if ( !mlst.isEmpty() && m_destURL.path( 1 ) == KGlobalSettings::trashPath() ) 00560 { 00561 if ( itemIsOnDesktop && !kapp->authorize("editable_desktop_icons") ) 00562 { 00563 delete this; 00564 return; 00565 } 00566 00567 if ( askDeleteConfirmation( mlst, DEFAULT_CONFIRMATION ) ) 00568 action = QDropEvent::Move; 00569 else 00570 { 00571 delete this; 00572 return; 00573 } 00574 } 00575 else if ( (((m_info->keybstate & ControlMask) == 0) && ((m_info->keybstate & ShiftMask) == 0)) || 00576 linkOnly ) 00577 { 00578 KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent()); 00579 bool bSetWallpaper = false; 00580 if (iconView && iconView->maySetWallpaper() && 00581 (lst.count() == 1) && 00582 ((!KImageIO::type(lst.first().path()).isEmpty()) || 00583 (KImageIO::isSupported(KMimeType::findByURL(lst.first())->name(), 00584 KImageIO::Reading)))) 00585 { 00586 bSetWallpaper = true; 00587 } 00588 00589 // Check what the source can do 00590 KURL url = lst.first(); // we'll assume it's the same for all URLs (hack) 00591 bool sReading = KProtocolInfo::supportsReading( url ); 00592 bool sDeleting = KProtocolInfo::supportsDeleting( url ); 00593 bool sMoving = KProtocolInfo::supportsMoving( url ); 00594 // Check what the destination can do 00595 bool dWriting = KProtocolInfo::supportsWriting( m_destURL ); 00596 if ( !dWriting ) 00597 { 00598 delete this; 00599 return; 00600 } 00601 //bool sTrash = url.path(1) == KGlobalSettings::trashPath(); 00602 // Nor control nor shift are pressed => show popup menu 00603 00604 QPopupMenu popup; 00605 if (!mlst.isEmpty() && (sMoving || (sReading && sDeleting)) && !linkOnly ) 00606 popup.insertItem(SmallIconSet("goto"), i18n( "&Move Here" ), 2 ); 00607 if ( sReading && !linkOnly) 00608 popup.insertItem(SmallIconSet("editcopy"), i18n( "&Copy Here" ), 1 ); 00609 popup.insertItem(SmallIconSet("www"), i18n( "&Link Here" ), 3 ); 00610 if (bSetWallpaper) 00611 popup.insertItem(SmallIconSet("background"), i18n( "Set as &Wallpaper" ), 4 ); 00612 popup.insertSeparator(); 00613 popup.insertItem(SmallIconSet("cancel"), i18n( "C&ancel" ), 5); 00614 00615 int result = popup.exec( m_info->mousePos ); 00616 00617 switch (result) { 00618 case 1 : action = QDropEvent::Copy; break; 00619 case 2 : action = QDropEvent::Move; break; 00620 case 3 : action = QDropEvent::Link; break; 00621 case 4 : 00622 { 00623 kdDebug(1203) << "setWallpaper iconView=" << iconView << " url=" << lst.first().url() << endl; 00624 if (iconView && iconView->isDesktop() ) iconView->setWallpaper(lst.first()); 00625 delete this; 00626 return; 00627 } 00628 case 5 : 00629 default : delete this; return; 00630 } 00631 } 00632 00633 KIO::Job * job = 0; 00634 switch ( action ) { 00635 case QDropEvent::Move : 00636 job = KIO::move( lst, m_destURL ); 00637 job->setMetaData( m_info->metaData ); 00638 setOperation( job, MOVE, lst, m_destURL ); 00639 if ( !newTrashPath.isEmpty() ) 00640 { 00641 00642 kdDebug(1203) << "Update trash path" <<newTrashPath<< endl; 00643 KConfig *globalConfig = KGlobal::config(); 00644 KConfigGroupSaver cgs( globalConfig, "Paths" ); 00645 globalConfig->writePathEntry("Trash" , newTrashPath, true, true ); 00646 globalConfig->sync(); 00647 KIPC::sendMessageAll(KIPC::SettingsChanged, KApplication::SETTINGS_PATHS); 00648 } 00649 00650 (void) new KonqCommandRecorder( KonqCommand::MOVE, lst, m_destURL, job ); 00651 return; // we still have stuff to do -> don't delete ourselves 00652 case QDropEvent::Copy : 00653 job = KIO::copy( lst, m_destURL ); 00654 job->setMetaData( m_info->metaData ); 00655 setOperation( job, COPY, lst, m_destURL ); 00656 (void) new KonqCommandRecorder( KonqCommand::COPY, lst, m_destURL, job ); 00657 return; 00658 case QDropEvent::Link : 00659 kdDebug(1203) << "KonqOperations::asyncDrop lst.count=" << lst.count() << endl; 00660 job = KIO::link( lst, m_destURL ); 00661 job->setMetaData( m_info->metaData ); 00662 setOperation( job, LINK, lst, m_destURL ); 00663 (void) new KonqCommandRecorder( KonqCommand::LINK, lst, m_destURL, job ); 00664 return; 00665 default : kdError(1203) << "Unknown action " << (int)action << endl; 00666 } 00667 delete this; 00668 } 00669 00670 void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const KURL& newurl ) 00671 { 00672 kdDebug(1203) << "KonqOperations::rename oldurl=" << oldurl.prettyURL() << " newurl=" << newurl.prettyURL() << endl; 00673 if ( oldurl == newurl ) 00674 return; 00675 00676 KURL::List lst; 00677 lst.append(oldurl); 00678 KIO::Job * job = KIO::moveAs( oldurl, newurl, !oldurl.isLocalFile() ); 00679 KonqOperations * op = new KonqOperations( parent ); 00680 op->setOperation( job, MOVE, lst, newurl ); 00681 (void) new KonqCommandRecorder( KonqCommand::MOVE, lst, newurl, job ); 00682 // if old trash then update config file and emit 00683 if(oldurl.isLocalFile() ) 00684 { 00685 if ( oldurl.path(1) == KGlobalSettings::trashPath() ) { 00686 kdDebug(1203) << "That rename was the Trashcan, updating config files" << endl; 00687 KConfig *globalConfig = KGlobal::config(); 00688 KConfigGroupSaver cgs( globalConfig, "Paths" ); 00689 globalConfig->writePathEntry("Trash" , newurl.path(), true, true ); 00690 globalConfig->sync(); 00691 KIPC::sendMessageAll(KIPC::SettingsChanged, KApplication::SETTINGS_PATHS); 00692 } 00693 // if old trash then update config file and emit 00694 if(oldurl.path(1) == KGlobalSettings::desktopPath() ) 00695 { 00696 kdDebug(1203) << "That rename was the Desktop path, updating config files" << endl; 00697 KConfig *globalConfig = KGlobal::config(); 00698 KConfigGroupSaver cgs( globalConfig, "Paths" ); 00699 globalConfig->writePathEntry("Desktop" , newurl.path(), true, true ); 00700 if ( KGlobalSettings::trashPath().startsWith(oldurl.path(1) )) 00701 { 00702 QString newTrashPath = newurl.path()+KGlobalSettings::trashPath().right(KGlobalSettings::trashPath().length()-KURL(KGlobalSettings::trashPath()).directory().length()); 00703 00704 globalConfig->writePathEntry("Trash" , newTrashPath, true, true ); 00705 } 00706 globalConfig->sync(); 00707 KIPC::sendMessageAll(KIPC::SettingsChanged, KApplication::SETTINGS_PATHS); 00708 } 00709 } 00710 00711 } 00712 00713 void KonqOperations::setOperation( KIO::Job * job, int method, const KURL::List & /*src*/, const KURL & dest ) 00714 { 00715 m_method = method; 00716 //m_srcURLs = src; 00717 m_destURL = dest; 00718 if ( job ) 00719 { 00720 connect( job, SIGNAL( result( KIO::Job * ) ), 00721 SLOT( slotResult( KIO::Job * ) ) ); 00722 } 00723 else // for link 00724 slotResult( 0L ); 00725 00726 KIO::CopyJob *copyJob = dynamic_cast<KIO::CopyJob*>(job); 00727 KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent()); 00728 if (copyJob && iconView) 00729 { 00730 connect(copyJob, SIGNAL(aboutToCreate(KIO::Job *,const QValueList<KIO::CopyInfo> &)), 00731 this, SLOT(slotAboutToCreate(KIO::Job *,const QValueList<KIO::CopyInfo> &))); 00732 connect(this, SIGNAL(aboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)), 00733 iconView, SLOT(slotAboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &))); 00734 } 00735 } 00736 00737 void KonqOperations::slotAboutToCreate(KIO::Job *, const QValueList<KIO::CopyInfo> &files) 00738 { 00739 emit aboutToCreate( m_info ? m_info->mousePos : m_pasteInfo ? m_pasteInfo->mousePos : QPoint(), files); 00740 } 00741 00742 void KonqOperations::statURL( const KURL & url, const QObject *receiver, const char *member ) 00743 { 00744 KonqOperations * op = new KonqOperations( 0L ); 00745 op->_statURL( url, receiver, member ); 00746 op->m_method = STAT; 00747 } 00748 00749 void KonqOperations::_statURL( const KURL & url, const QObject *receiver, const char *member ) 00750 { 00751 connect( this, SIGNAL( statFinished( const KFileItem * ) ), receiver, member ); 00752 KIO::StatJob * job = KIO::stat( url /*, false?*/ ); 00753 connect( job, SIGNAL( result( KIO::Job * ) ), 00754 SLOT( slotStatResult( KIO::Job * ) ) ); 00755 } 00756 00757 void KonqOperations::slotStatResult( KIO::Job * job ) 00758 { 00759 if ( job->error()) 00760 job->showErrorDialog( (QWidget*)parent() ); 00761 else 00762 { 00763 KIO::StatJob * statJob = static_cast<KIO::StatJob*>(job); 00764 KFileItem * item = new KFileItem( statJob->statResult(), statJob->url() ); 00765 emit statFinished( item ); 00766 delete item; 00767 } 00768 // If we're only here for a stat, we're done. But not if we used _statURL internally 00769 if ( m_method == STAT ) 00770 delete this; 00771 } 00772 00773 void KonqOperations::slotResult( KIO::Job * job ) 00774 { 00775 if (job && job->error()) 00776 job->showErrorDialog( (QWidget*)parent() ); 00777 00778 // Update trash bin icon if trashing files or emptying trash 00779 bool bUpdateTrash = m_method == TRASH || m_method == EMPTYTRASH; 00780 // ... or if creating a new file in the trash 00781 if ( m_method == MOVE || m_method == COPY || m_method == LINK ) 00782 { 00783 KURL trash; 00784 trash.setPath( KGlobalSettings::trashPath() ); 00785 if ( m_destURL.equals( trash, true /*ignore trailing slash*/ ) ) 00786 bUpdateTrash = true; 00787 } 00788 if (bUpdateTrash) 00789 { 00790 // Update trash bin icon 00791 KURL trash; 00792 trash.setPath( KGlobalSettings::trashPath() ); 00793 KURL::List lst; 00794 lst.append(trash); 00795 KDirNotify_stub allDirNotify("*", "KDirNotify*"); 00796 allDirNotify.FilesChanged( lst ); 00797 } 00798 delete this; 00799 } 00800 00801 void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const QString & name ) 00802 { 00803 KURL newurl( oldurl ); 00804 newurl.setPath( oldurl.directory(false, true) + name ); 00805 kdDebug(1203) << "KonqOperations::rename("<<name<<") called. newurl=" << newurl.prettyURL() << endl; 00806 rename( parent, oldurl, newurl ); 00807 } 00808 00809 void KonqOperations::newDir( QWidget * parent, const KURL & baseURL ) 00810 { 00811 bool ok; 00812 QString name = i18n( "New Folder" ); 00813 if (baseURL.isLocalFile()) 00814 { 00815 QString base = name; 00816 int n = 2; 00817 while(true) 00818 { 00819 KURL url=baseURL; 00820 url.addPath( name ); 00821 00822 if (access(QFile::encodeName(url.path()), F_OK) == -1) 00823 break; 00824 00825 name = base + QString("_%1").arg(n++); 00826 } 00827 } 00828 00829 name = KInputDialog::getText ( i18n( "New Folder" ), 00830 i18n( "Enter folder name:" ), name, &ok, parent ); 00831 if ( ok && !name.isEmpty() ) 00832 { 00833 KURL url; 00834 if ((name[0] == '/') || (name[0] == '~')) 00835 { 00836 url.setPath(KShell::tildeExpand(name)); 00837 } 00838 else 00839 { 00840 name = KIO::encodeFileName( name ); 00841 url = baseURL; 00842 url.addPath( name ); 00843 } 00844 KonqOperations::mkdir( 0L, url ); 00845 } 00846 } 00847 00848 #include "konq_operations.moc"
KDE Logo
This file is part of the documentation for libkonq Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 13 21:46:59 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003