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 can't 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 op->setPasteInfo( pi ); 00423 QTimer::singleShot( 0, op, SLOT( slotKIOPaste() ) ); 00424 } 00425 ev->acceptAction(); 00426 } 00427 } 00428 00429 void KonqOperations::slotKIOPaste() 00430 { 00431 assert(m_pasteInfo); // setPasteInfo should have been called before 00432 KIO::CopyJob *job = KIO::pasteDataAsync( m_pasteInfo->destURL, m_pasteInfo->data ); 00433 if ( job ) 00434 { 00435 setOperation( job, COPY, KURL::List(), job->destURL() ); 00436 (void) new KonqCommandRecorder( KonqCommand::COPY, KURL::List(), m_destURL, job ); 00437 } 00438 else 00439 { 00440 delete this; 00441 } 00442 } 00443 00444 void KonqOperations::asyncDrop( const KFileItem * destItem ) 00445 { 00446 assert(m_info); // setDropInfo should have been called before asyncDrop 00447 m_destURL = destItem->url(); 00448 00449 //kdDebug(1203) << "KonqOperations::asyncDrop destItem->mode=" << destItem->mode() << " url=" << m_destURL << endl; 00450 // Check what the destination is 00451 if ( destItem->isDir() ) 00452 { 00453 doFileCopy(); 00454 return; 00455 } 00456 if ( !m_destURL.isLocalFile() ) 00457 { 00458 // We dropped onto a remote URL that is not a directory! 00459 // (e.g. an HTTP link in the sidebar). 00460 // Can't do that, but we can't prevent it before stating the dest.... 00461 kdWarning(1203) << "Cannot drop onto " << m_destURL << endl; 00462 delete this; 00463 return; 00464 } 00465 if ( destItem->mimetype() == "application/x-desktop") 00466 { 00467 // Local .desktop file. What type ? 00468 KDesktopFile desktopFile( m_destURL.path() ); 00469 if ( desktopFile.hasApplicationType() ) 00470 { 00471 QString error; 00472 QStringList stringList; 00473 KURL::List lst = m_info->lst; 00474 KURL::List::Iterator it = lst.begin(); 00475 for ( ; it != lst.end() ; it++ ) 00476 { 00477 stringList.append((*it).url()); 00478 } 00479 if ( KApplication::startServiceByDesktopPath( m_destURL.path(), stringList, &error ) > 0 ) 00480 KMessageBox::error( 0L, error ); 00481 } 00482 else 00483 { 00484 // Device or Link -> adjust dest 00485 if ( desktopFile.hasDeviceType() && desktopFile.hasKey("MountPoint") ) { 00486 QString point = desktopFile.readEntry( "MountPoint" ); 00487 m_destURL.setPath( point ); 00488 QString dev = desktopFile.readDevice(); 00489 QString mp = KIO::findDeviceMountPoint( dev ); 00490 // Is the device already mounted ? 00491 if ( !mp.isNull() ) 00492 doFileCopy(); 00493 else 00494 { 00495 bool ro = desktopFile.readBoolEntry( "ReadOnly", false ); 00496 QString fstype = desktopFile.readEntry( "FSType" ); 00497 KAutoMount* am = new KAutoMount( ro, fstype, dev, point, m_destURL.path(), false ); 00498 connect( am, SIGNAL( finished() ), this, SLOT( doFileCopy() ) ); 00499 } 00500 return; 00501 } 00502 else if ( desktopFile.hasLinkType() && desktopFile.hasKey("URL") ) { 00503 m_destURL = desktopFile.readPathEntry("URL"); 00504 doFileCopy(); 00505 return; 00506 } 00507 // else, well: mimetype, service, servicetype or .directory. Can't really drop anything on those. 00508 } 00509 } 00510 else 00511 { 00512 // Should be a local executable 00513 // (If this fails, there is a bug in KFileItem::acceptsDrops) 00514 kdDebug(1203) << "KonqOperations::doDrop " << m_destURL.path() << "should be an executable" << endl; 00515 Q_ASSERT ( access( QFile::encodeName(m_destURL.path()), X_OK ) == 0 ); 00516 KProcess proc; 00517 proc << m_destURL.path() ; 00518 // Launch executable for each of the files 00519 KURL::List lst = m_info->lst; 00520 KURL::List::Iterator it = lst.begin(); 00521 for ( ; it != lst.end() ; it++ ) 00522 proc << (*it).path(); // assume local files 00523 kdDebug(1203) << "starting " << m_destURL.path() << " with " << lst.count() << " arguments" << endl; 00524 proc.start( KProcess::DontCare ); 00525 } 00526 delete this; 00527 } 00528 00529 void KonqOperations::doFileCopy() 00530 { 00531 assert(m_info); // setDropInfo - and asyncDrop - should have been called before asyncDrop 00532 KURL::List lst = m_info->lst; 00533 QDropEvent::Action action = m_info->action; 00534 QString newTrashPath; 00535 bool isDesktopFile = false; 00536 bool itemIsOnDesktop = false; 00537 KURL::List mlst; 00538 for (KURL::List::ConstIterator it = lst.begin(); it != lst.end(); ++it) 00539 { 00540 bool local = (*it).isLocalFile(); 00541 if ( local && ((*it).path(1) == KGlobalSettings::trashPath())) 00542 newTrashPath=m_destURL.path()+(*it).path().right((*it).path().length()-(*it).directory().length()); 00543 if ( KProtocolInfo::supportsDeleting( *it ) && (!local || QFileInfo((*it).directory()).isWritable() )) 00544 mlst.append(*it); 00545 if ( local && KDesktopFile::isDesktopFile((*it).path())) 00546 isDesktopFile = true; 00547 if ( local && (*it).path().startsWith(KGlobalSettings::desktopPath())) 00548 itemIsOnDesktop = true; 00549 } 00550 00551 bool linkOnly = false; 00552 if (isDesktopFile && !kapp->authorize("run_desktop_files") && 00553 (m_destURL.path(1) == KGlobalSettings::desktopPath()) ) 00554 { 00555 linkOnly = true; 00556 } 00557 00558 if ( !mlst.isEmpty() && m_destURL.path( 1 ) == KGlobalSettings::trashPath() ) 00559 { 00560 if ( itemIsOnDesktop && !kapp->authorize("editable_desktop_icons") ) 00561 { 00562 delete this; 00563 return; 00564 } 00565 00566 if ( askDeleteConfirmation( mlst, DEFAULT_CONFIRMATION ) ) 00567 action = QDropEvent::Move; 00568 else 00569 { 00570 delete this; 00571 return; 00572 } 00573 } 00574 else if ( (((m_info->keybstate & ControlMask) == 0) && ((m_info->keybstate & ShiftMask) == 0)) || 00575 linkOnly ) 00576 { 00577 KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent()); 00578 bool bSetWallpaper = false; 00579 if (iconView && iconView->maySetWallpaper() && 00580 (lst.count() == 1) && 00581 ((!KImageIO::type(lst.first().path()).isEmpty()) || 00582 (KImageIO::isSupported(KMimeType::findByURL(lst.first())->name(), 00583 KImageIO::Reading)))) 00584 { 00585 bSetWallpaper = true; 00586 } 00587 00588 // Check what the source can do 00589 KURL url = lst.first(); // we'll assume it's the same for all URLs (hack) 00590 bool sReading = KProtocolInfo::supportsReading( url ); 00591 bool sDeleting = KProtocolInfo::supportsDeleting( url ); 00592 bool sMoving = KProtocolInfo::supportsMoving( url ); 00593 // Check what the destination can do 00594 bool dWriting = KProtocolInfo::supportsWriting( m_destURL ); 00595 if ( !dWriting ) 00596 { 00597 delete this; 00598 return; 00599 } 00600 //bool sTrash = url.path(1) == KGlobalSettings::trashPath(); 00601 // Nor control nor shift are pressed => show popup menu 00602 00603 QPopupMenu popup; 00604 if (!mlst.isEmpty() && (sMoving || (sReading && sDeleting)) && !linkOnly ) 00605 popup.insertItem( i18n( "&Move Here" ), 2 ); 00606 if ( sReading && !linkOnly) 00607 popup.insertItem(SmallIconSet("editcopy"), i18n( "&Copy Here" ), 1 ); 00608 popup.insertItem(SmallIconSet("www"), i18n( "&Link Here" ), 3 ); 00609 if (bSetWallpaper) 00610 popup.insertItem(SmallIconSet("background"), i18n( "Set as &Wallpaper" ), 4 ); 00611 popup.insertSeparator(); 00612 popup.insertItem(SmallIconSet("cancel"), i18n( "C&ancel" ), 5); 00613 00614 int result = popup.exec( m_info->mousePos ); 00615 00616 switch (result) { 00617 case 1 : action = QDropEvent::Copy; break; 00618 case 2 : action = QDropEvent::Move; break; 00619 case 3 : action = QDropEvent::Link; break; 00620 case 4 : 00621 { 00622 kdDebug(1203) << "setWallpaper iconView=" << iconView << " url=" << lst.first().url() << endl; 00623 if (iconView && iconView->isDesktop() ) iconView->setWallpaper(lst.first()); 00624 delete this; 00625 return; 00626 } 00627 case 5 : 00628 default : delete this; return; 00629 } 00630 } 00631 00632 KIO::Job * job = 0; 00633 switch ( action ) { 00634 case QDropEvent::Move : 00635 job = KIO::move( lst, m_destURL ); 00636 job->setMetaData( m_info->metaData ); 00637 setOperation( job, MOVE, lst, m_destURL ); 00638 if ( !newTrashPath.isEmpty() ) 00639 { 00640 00641 kdDebug(1203) << "Update trash path" <<newTrashPath<< endl; 00642 KConfig *globalConfig = KGlobal::config(); 00643 KConfigGroupSaver cgs( globalConfig, "Paths" ); 00644 globalConfig->writePathEntry("Trash" , newTrashPath, true, true ); 00645 globalConfig->sync(); 00646 KIPC::sendMessageAll(KIPC::SettingsChanged, KApplication::SETTINGS_PATHS); 00647 } 00648 00649 (void) new KonqCommandRecorder( KonqCommand::MOVE, lst, m_destURL, job ); 00650 return; // we still have stuff to do -> don't delete ourselves 00651 case QDropEvent::Copy : 00652 job = KIO::copy( lst, m_destURL ); 00653 job->setMetaData( m_info->metaData ); 00654 setOperation( job, COPY, lst, m_destURL ); 00655 (void) new KonqCommandRecorder( KonqCommand::COPY, lst, m_destURL, job ); 00656 return; 00657 case QDropEvent::Link : 00658 kdDebug(1203) << "KonqOperations::asyncDrop lst.count=" << lst.count() << endl; 00659 job = KIO::link( lst, m_destURL ); 00660 job->setMetaData( m_info->metaData ); 00661 setOperation( job, LINK, lst, m_destURL ); 00662 (void) new KonqCommandRecorder( KonqCommand::LINK, lst, m_destURL, job ); 00663 return; 00664 default : kdError(1203) << "Unknown action " << (int)action << endl; 00665 } 00666 delete this; 00667 } 00668 00669 void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const KURL& newurl ) 00670 { 00671 kdDebug(1203) << "KonqOperations::rename oldurl=" << oldurl.prettyURL() << " newurl=" << newurl.prettyURL() << endl; 00672 if ( oldurl == newurl ) 00673 return; 00674 00675 KURL::List lst; 00676 lst.append(oldurl); 00677 KIO::Job * job = KIO::moveAs( oldurl, newurl, !oldurl.isLocalFile() ); 00678 KonqOperations * op = new KonqOperations( parent ); 00679 op->setOperation( job, MOVE, lst, newurl ); 00680 (void) new KonqCommandRecorder( KonqCommand::MOVE, lst, newurl, job ); 00681 // if old trash then update config file and emit 00682 if(oldurl.isLocalFile() ) 00683 { 00684 if ( oldurl.path(1) == KGlobalSettings::trashPath() ) { 00685 kdDebug(1203) << "That rename was the Trashcan, updating config files" << endl; 00686 KConfig *globalConfig = KGlobal::config(); 00687 KConfigGroupSaver cgs( globalConfig, "Paths" ); 00688 globalConfig->writePathEntry("Trash" , newurl.path(), true, true ); 00689 globalConfig->sync(); 00690 KIPC::sendMessageAll(KIPC::SettingsChanged, KApplication::SETTINGS_PATHS); 00691 } 00692 // if old trash then update config file and emit 00693 if(oldurl.path(1) == KGlobalSettings::desktopPath() ) 00694 { 00695 kdDebug(1203) << "That rename was the Desktop path, updating config files" << endl; 00696 KConfig *globalConfig = KGlobal::config(); 00697 KConfigGroupSaver cgs( globalConfig, "Paths" ); 00698 globalConfig->writePathEntry("Desktop" , newurl.path(), true, true ); 00699 if ( KGlobalSettings::trashPath().startsWith(oldurl.path(1) )) 00700 { 00701 QString newTrashPath = newurl.path()+KGlobalSettings::trashPath().right(KGlobalSettings::trashPath().length()-KURL(KGlobalSettings::trashPath()).directory().length()); 00702 00703 globalConfig->writePathEntry("Trash" , newTrashPath, true, true ); 00704 } 00705 globalConfig->sync(); 00706 KIPC::sendMessageAll(KIPC::SettingsChanged, KApplication::SETTINGS_PATHS); 00707 } 00708 } 00709 00710 } 00711 00712 void KonqOperations::setOperation( KIO::Job * job, int method, const KURL::List & /*src*/, const KURL & dest ) 00713 { 00714 m_method = method; 00715 //m_srcURLs = src; 00716 m_destURL = dest; 00717 if ( job ) 00718 { 00719 connect( job, SIGNAL( result( KIO::Job * ) ), 00720 SLOT( slotResult( KIO::Job * ) ) ); 00721 } 00722 else // for link 00723 slotResult( 0L ); 00724 00725 KIO::CopyJob *copyJob = dynamic_cast<KIO::CopyJob*>(job); 00726 KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent()); 00727 if (copyJob && iconView) 00728 { 00729 connect(copyJob, SIGNAL(aboutToCreate(KIO::Job *,const QValueList<KIO::CopyInfo> &)), 00730 this, SLOT(slotAboutToCreate(KIO::Job *,const QValueList<KIO::CopyInfo> &))); 00731 connect(this, SIGNAL(aboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)), 00732 iconView, SLOT(slotAboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &))); 00733 } 00734 } 00735 00736 void KonqOperations::slotAboutToCreate(KIO::Job *, const QValueList<KIO::CopyInfo> &files) 00737 { 00738 emit aboutToCreate( m_info ? m_info->mousePos : m_pasteInfo ? m_pasteInfo->mousePos : QPoint(), files); 00739 } 00740 00741 void KonqOperations::statURL( const KURL & url, const QObject *receiver, const char *member ) 00742 { 00743 KonqOperations * op = new KonqOperations( 0L ); 00744 op->_statURL( url, receiver, member ); 00745 op->m_method = STAT; 00746 } 00747 00748 void KonqOperations::_statURL( const KURL & url, const QObject *receiver, const char *member ) 00749 { 00750 connect( this, SIGNAL( statFinished( const KFileItem * ) ), receiver, member ); 00751 KIO::StatJob * job = KIO::stat( url /*, false?*/ ); 00752 connect( job, SIGNAL( result( KIO::Job * ) ), 00753 SLOT( slotStatResult( KIO::Job * ) ) ); 00754 } 00755 00756 void KonqOperations::slotStatResult( KIO::Job * job ) 00757 { 00758 if ( job->error()) 00759 job->showErrorDialog( (QWidget*)parent() ); 00760 else 00761 { 00762 KIO::StatJob * statJob = static_cast<KIO::StatJob*>(job); 00763 KFileItem * item = new KFileItem( statJob->statResult(), statJob->url() ); 00764 emit statFinished( item ); 00765 delete item; 00766 } 00767 // If we're only here for a stat, we're done. But not if we used _statURL internally 00768 if ( m_method == STAT ) 00769 delete this; 00770 } 00771 00772 void KonqOperations::slotResult( KIO::Job * job ) 00773 { 00774 if (job && job->error()) 00775 job->showErrorDialog( (QWidget*)parent() ); 00776 00777 // Update trash bin icon if trashing files or emptying trash 00778 bool bUpdateTrash = m_method == TRASH || m_method == EMPTYTRASH; 00779 // ... or if creating a new file in the trash 00780 if ( m_method == MOVE || m_method == COPY || m_method == LINK ) 00781 { 00782 KURL trash; 00783 trash.setPath( KGlobalSettings::trashPath() ); 00784 if ( m_destURL.equals( trash, true /*ignore trailing slash*/ ) ) 00785 bUpdateTrash = true; 00786 } 00787 if (bUpdateTrash) 00788 { 00789 // Update trash bin icon 00790 KURL trash; 00791 trash.setPath( KGlobalSettings::trashPath() ); 00792 KURL::List lst; 00793 lst.append(trash); 00794 KDirNotify_stub allDirNotify("*", "KDirNotify*"); 00795 allDirNotify.FilesChanged( lst ); 00796 } 00797 delete this; 00798 } 00799 00800 void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const QString & name ) 00801 { 00802 KURL newurl( oldurl ); 00803 newurl.setPath( oldurl.directory(false, true) + name ); 00804 kdDebug(1203) << "KonqOperations::rename("<<name<<") called. newurl=" << newurl.prettyURL() << endl; 00805 rename( parent, oldurl, newurl ); 00806 } 00807 00808 void KonqOperations::newDir( QWidget * parent, const KURL & baseURL ) 00809 { 00810 bool ok; 00811 QString name = i18n( "New Folder" ); 00812 if (baseURL.isLocalFile()) 00813 { 00814 QString base = name; 00815 int n = 2; 00816 while(true) 00817 { 00818 KURL url=baseURL; 00819 url.addPath( name ); 00820 00821 if (access(QFile::encodeName(url.path()), F_OK) == -1) 00822 break; 00823 00824 name = base + QString("_%1").arg(n++); 00825 } 00826 } 00827 00828 name = KInputDialog::getText ( i18n( "New Folder" ), 00829 i18n( "Enter folder name:" ), name, &ok, parent ); 00830 if ( ok && !name.isEmpty() ) 00831 { 00832 KURL url; 00833 if ((name[0] == '/') || (name[0] == '~')) 00834 { 00835 url.setPath(KShell::tildeExpand(name)); 00836 } 00837 else 00838 { 00839 name = KIO::encodeFileName( name ); 00840 url = baseURL; 00841 url.addPath( name ); 00842 } 00843 KonqOperations::mkdir( 0L, url ); 00844 } 00845 } 00846 00847 #include "konq_operations.moc"
KDE Logo
This file is part of the documentation for libkonq Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Aug 31 00:02:07 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003