libkonq Library API Documentation

konq_dirpart.cc

00001 /* This file is part of the KDE projects 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 General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (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 GNU 00012 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; see the file COPYING. If not, write to 00016 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include "konq_dirpart.h" 00021 #include "konq_bgnddlg.h" 00022 #include "konq_propsview.h" 00023 #include "konq_settings.h" 00024 00025 #include <kaction.h> 00026 #include <kdatastream.h> 00027 #include <kcolordialog.h> 00028 #include <kdebug.h> 00029 #include <kiconloader.h> 00030 #include <klocale.h> 00031 #include <kmessagebox.h> 00032 #include <konq_drag.h> 00033 #include <kparts/browserextension.h> 00034 #include <kurldrag.h> 00035 #include <kuserprofile.h> 00036 #include <kurifilter.h> 00037 #include <kglobalsettings.h> 00038 00039 #include <qapplication.h> 00040 #include <qclipboard.h> 00041 #include <qfile.h> 00042 #include <assert.h> 00043 00044 class KonqDirPart::KonqDirPartPrivate 00045 { 00046 public: 00047 QStringList mimeFilters; 00048 }; 00049 00050 KonqDirPart::KonqDirPart( QObject *parent, const char *name ) 00051 :KParts::ReadOnlyPart( parent, name ), 00052 m_pProps( 0L ), 00053 m_findPart( 0L ) 00054 { 00055 d = new KonqDirPartPrivate; 00056 m_lDirSize = 0; 00057 m_lFileCount = 0; 00058 m_lDirCount = 0; 00059 //m_bMultipleItemsSelected = false; 00060 00061 connect( QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slotClipboardDataChanged()) ); 00062 00063 actionCollection()->setHighlightingEnabled( true ); 00064 00065 m_paIncIconSize = new KAction( i18n( "Increase Icon Size" ), "viewmag+", 0, this, SLOT( slotIncIconSize() ), actionCollection(), "incIconSize" ); 00066 m_paDecIconSize = new KAction( i18n( "Decrease Icon Size" ), "viewmag-", 0, this, SLOT( slotDecIconSize() ), actionCollection(), "decIconSize" ); 00067 00068 m_paDefaultIcons = new KRadioAction( i18n( "&Default Size" ), 0, actionCollection(), "modedefault" ); 00069 m_paHugeIcons = new KRadioAction( i18n( "&Huge" ), 0, actionCollection(), "modehuge" ); 00070 m_paLargeIcons = new KRadioAction( i18n( "&Large" ), 0, actionCollection(), "modelarge" ); 00071 m_paMediumIcons = new KRadioAction( i18n( "&Medium" ), 0, actionCollection(), "modemedium" ); 00072 m_paSmallIcons = new KRadioAction( i18n( "&Small" ), 0, actionCollection(), "modesmall" ); 00073 00074 m_paDefaultIcons->setExclusiveGroup( "ViewMode" ); 00075 m_paHugeIcons->setExclusiveGroup( "ViewMode" ); 00076 m_paLargeIcons->setExclusiveGroup( "ViewMode" ); 00077 m_paMediumIcons->setExclusiveGroup( "ViewMode" ); 00078 m_paSmallIcons->setExclusiveGroup( "ViewMode" ); 00079 00080 connect( m_paDefaultIcons, SIGNAL( toggled( bool ) ), this, SLOT( slotIconSizeToggled( bool ) ) ); 00081 connect( m_paHugeIcons, SIGNAL( toggled( bool ) ), this, SLOT( slotIconSizeToggled( bool ) ) ); 00082 connect( m_paLargeIcons, SIGNAL( toggled( bool ) ), this, SLOT( slotIconSizeToggled( bool ) ) ); 00083 connect( m_paMediumIcons, SIGNAL( toggled( bool ) ), this, SLOT( slotIconSizeToggled( bool ) ) ); 00084 connect( m_paSmallIcons, SIGNAL( toggled( bool ) ), this, SLOT( slotIconSizeToggled( bool ) ) ); 00085 00086 // Extract 4 icon sizes from the icon theme. Use 16,32,48,64 as default. 00087 int i; 00088 m_iIconSize[0] = 0; // Default value 00089 m_iIconSize[1] = KIcon::SizeSmall; // 16 00090 m_iIconSize[2] = KIcon::SizeMedium; // 32 00091 m_iIconSize[3] = KIcon::SizeLarge; // 48 00092 m_iIconSize[4] = KIcon::SizeHuge; // 64 00093 KIconTheme *root = KGlobal::instance()->iconLoader()->theme(); 00094 if (root) 00095 { 00096 QValueList<int> avSizes = root->querySizes(KIcon::Desktop); 00097 QValueList<int>::Iterator it; 00098 for (i=1, it=avSizes.begin(); (it!=avSizes.end()) && (i<5); it++, i++) 00099 { 00100 m_iIconSize[i] = *it; 00101 //kdDebug(1203) << "m_iIconSize[" << i << "] = " << *it << endl; 00102 } 00103 } 00104 00105 KAction *a = new KAction( i18n( "Background Color..." ), 0, this, SLOT( slotBackgroundColor() ), 00106 actionCollection(), "bgcolor" ); 00107 00108 a->setStatusText( i18n( "Allows choosing of a background color for this view" ) ); 00109 00110 a = new KAction( i18n( "Background Image..." ), "background", 0, 00111 this, SLOT( slotBackgroundImage() ), 00112 actionCollection(), "bgimage" ); 00113 00114 a->setStatusText( i18n( "Allows choosing a background image for this view" ) ); 00115 } 00116 00117 KonqDirPart::~KonqDirPart() 00118 { 00119 // Close the find part with us 00120 delete m_findPart; 00121 delete d; 00122 } 00123 00124 void KonqDirPart::setMimeFilter (const QStringList& mime) 00125 { 00126 QString u = url().url(); 00127 00128 if ( u.isEmpty () ) 00129 return; 00130 00131 if ( mime.isEmpty() ) 00132 d->mimeFilters.clear(); 00133 else 00134 d->mimeFilters = mime; 00135 } 00136 00137 QStringList KonqDirPart::mimeFilter() const 00138 { 00139 return d->mimeFilters; 00140 } 00141 00142 QScrollView * KonqDirPart::scrollWidget() 00143 { 00144 return static_cast<QScrollView *>(widget()); 00145 } 00146 00147 void KonqDirPart::slotBackgroundColor() 00148 { 00149 QColor bgndColor = m_pProps->bgColor( widget() ); 00150 QColor defaultColor = KGlobalSettings::baseColor(); 00151 if ( KColorDialog::getColor( bgndColor,defaultColor ) == KColorDialog::Accepted ) 00152 { 00153 if ( bgndColor.isValid() ) 00154 m_pProps->setBgColor( bgndColor ); 00155 else 00156 m_pProps->setBgColor( defaultColor ); 00157 m_pProps->setBgPixmapFile( "" ); 00158 m_pProps->applyColors( scrollWidget()->viewport() ); 00159 scrollWidget()->viewport()->repaint(); 00160 } 00161 } 00162 00163 void KonqDirPart::slotBackgroundImage() 00164 { 00165 KonqBgndDialog dlg( m_pProps->bgPixmapFile(), instance() ); 00166 if ( dlg.exec() == KonqBgndDialog::Accepted ) 00167 { 00168 m_pProps->setBgPixmapFile( dlg.pixmapFile() ); 00169 m_pProps->applyColors( scrollWidget()->viewport() ); 00170 scrollWidget()->viewport()->repaint(); 00171 } 00172 } 00173 00174 void KonqDirPart::lmbClicked( KFileItem * fileItem ) 00175 { 00176 KURL url = fileItem->url(); 00177 if ( !fileItem->isReadable() ) 00178 { 00179 // No permissions or local file that doesn't exist - need to find out which 00180 if ( ( !fileItem->isLocalFile() ) || QFile::exists( url.path() ) ) 00181 { 00182 KMessageBox::error( widget(), i18n("<p>You do not have enough permissions to read <b>%1</b></p>").arg(url.prettyURL()) ); 00183 return; 00184 } 00185 KMessageBox::error( widget(), i18n("<p><b>%1</b> doesn't seem to exist anymore</p>").arg(url.prettyURL()) ); 00186 return; 00187 } 00188 00189 KParts::URLArgs args; 00190 fileItem->determineMimeType(); 00191 if ( fileItem->isMimeTypeKnown() ) 00192 args.serviceType = fileItem->mimetype(); 00193 args.trustedSource = true; 00194 00195 if ( fileItem->isLink() && fileItem->isLocalFile() ) // see KFileItem::run 00196 url = KURL( url, KURL::encode_string( fileItem->linkDest() ) ); 00197 00198 if (KonqFMSettings::settings()->alwaysNewWin() && fileItem->isDir()) { 00199 //args.frameName = "_blank"; // open new window 00200 // We tried the other option, passing the path as framename so that 00201 // an existing window for that dir is reused (like MSWindows does when 00202 // the similar option is activated and the sidebar is hidden (!)). 00203 // But this requires some work, including changing the framename 00204 // when navigating, etc. Not very much requested yet, in addition. 00205 KParts::WindowArgs wargs; 00206 KParts::ReadOnlyPart* dummy; 00207 emit m_extension->createNewWindow( url, args, wargs, dummy ); 00208 } 00209 else 00210 { 00211 kdDebug() << "emit m_extension->openURLRequest( " << url.url() << "," << args.serviceType << ")" << endl; 00212 emit m_extension->openURLRequest( url, args ); 00213 } 00214 } 00215 00216 void KonqDirPart::mmbClicked( KFileItem * fileItem ) 00217 { 00218 if ( fileItem ) 00219 { 00220 // Optimisation to avoid KRun to call kfmclient that then tells us 00221 // to open a window :-) 00222 KService::Ptr offer = KServiceTypeProfile::preferredService(fileItem->mimetype(), "Application"); 00223 //if (offer) kdDebug(1203) << "KonqDirPart::mmbClicked: got service " << offer->desktopEntryName() << endl; 00224 if ( offer && offer->desktopEntryName().startsWith("kfmclient") ) 00225 { 00226 KParts::URLArgs args; 00227 args.serviceType = fileItem->mimetype(); 00228 emit m_extension->createNewWindow( fileItem->url(), args ); 00229 } 00230 else 00231 fileItem->run(); 00232 } 00233 else 00234 { 00235 m_extension->pasteRequest(); 00236 } 00237 } 00238 00239 void KonqDirPart::saveState( QDataStream& stream ) 00240 { 00241 stream << m_nameFilter; 00242 } 00243 00244 void KonqDirPart::restoreState( QDataStream& stream ) 00245 { 00246 stream >> m_nameFilter; 00247 } 00248 00249 void KonqDirPart::saveFindState( QDataStream& stream ) 00250 { 00251 // assert only doable in KDE4. 00252 //assert( m_findPart ); // test done by caller. 00253 if ( !m_findPart ) 00254 return; 00255 00256 // When we have a find part, our own URL wasn't saved (see KonqDirPartBrowserExtension) 00257 // So let's do it here 00258 stream << m_url; 00259 00260 KParts::BrowserExtension* ext = KParts::BrowserExtension::childObject( m_findPart ); 00261 if( !ext ) 00262 return; 00263 00264 ext->saveState( stream ); 00265 } 00266 00267 void KonqDirPart::restoreFindState( QDataStream& stream ) 00268 { 00269 // Restore our own URL 00270 stream >> m_url; 00271 00272 emit findOpen( this ); 00273 00274 KParts::BrowserExtension* ext = KParts::BrowserExtension::childObject( m_findPart ); 00275 slotClear(); 00276 00277 if( !ext ) 00278 return; 00279 00280 ext->restoreState( stream ); 00281 } 00282 00283 void KonqDirPart::slotClipboardDataChanged() 00284 { 00285 // This is very related to KDIconView::slotClipboardDataChanged 00286 00287 KURL::List lst; 00288 QMimeSource *data = QApplication::clipboard()->data(); 00289 if ( data->provides( "application/x-kde-cutselection" ) && data->provides( "text/uri-list" ) ) 00290 if ( KonqDrag::decodeIsCutSelection( data ) ) 00291 (void) KURLDrag::decode( data, lst ); 00292 00293 disableIcons( lst ); 00294 00295 updatePasteAction(); 00296 } 00297 00298 void KonqDirPart::updatePasteAction() 00299 { 00300 QMimeSource *data = QApplication::clipboard()->data(); 00301 bool paste = ( data->format() != 0 ); 00302 00303 emit m_extension->enableAction( "paste", paste ); // TODO : if only one url, check that it's a dir 00304 } 00305 00306 void KonqDirPart::newItems( const KFileItemList & entries ) 00307 { 00308 for (KFileItemListIterator it(entries); it.current(); ++it) 00309 { 00310 if ( !it.current()->isDir() ) 00311 { 00312 if (!it.current()->isLink()) // ignore symlinks 00313 m_lDirSize += it.current()->size(); 00314 m_lFileCount++; 00315 } 00316 else 00317 m_lDirCount++; 00318 } 00319 if ( m_findPart ) 00320 emitTotalCount(); 00321 00322 emit itemsAdded( entries ); 00323 } 00324 00325 void KonqDirPart::deleteItem( KFileItem * fileItem ) 00326 { 00327 if ( !fileItem->isDir() ) 00328 { 00329 if ( !fileItem->isLink() ) 00330 m_lDirSize -= fileItem->size(); 00331 m_lFileCount--; 00332 } 00333 else 00334 m_lDirCount--; 00335 00336 emit itemRemoved( fileItem ); 00337 } 00338 00339 void KonqDirPart::emitTotalCount() 00340 { 00341 QString summary = 00342 KIO::itemsSummaryString(m_lFileCount + m_lDirCount, 00343 m_lFileCount, 00344 m_lDirCount, 00345 m_lDirSize, 00346 true); 00347 bool bShowsResult = false; 00348 if (m_findPart) 00349 { 00350 QVariant prop = m_findPart->property( "showsResult" ); 00351 bShowsResult = prop.isValid() && prop.toBool(); 00352 } 00353 //kdDebug(1203) << "KonqDirPart::emitTotalCount bShowsResult=" << bShowsResult << endl; 00354 emit setStatusBarText( bShowsResult ? i18n("Search result: %1").arg(summary) : summary ); 00355 } 00356 00357 void KonqDirPart::emitCounts( const KFileItemList & lst, bool selectionChanged ) 00358 { 00359 // Compare the new value with our cache 00360 /*bool multiple = lst.count()>1; 00361 if (multiple != m_bMultipleItemsSelected) 00362 { 00363 m_bMultipleItemsSelected = multiple; 00364 updatePasteAction(); 00365 }*/ 00366 00367 if ( lst.count()==1) 00368 { 00369 emit setStatusBarText( ((KFileItemList)lst).first()->getStatusBarInfo() ); 00370 } 00371 else if ( lst.count()>1) 00372 { 00373 long long fileSizeSum = 0; 00374 uint fileCount = 0; 00375 uint dirCount = 0; 00376 00377 for (KFileItemListIterator it( lst ); it.current(); ++it ) 00378 if ( it.current()->isDir() ) 00379 dirCount++; 00380 else 00381 { 00382 if (!it.current()->isLink()) // ignore symlinks 00383 fileSizeSum += it.current()->size(); 00384 fileCount++; 00385 } 00386 00387 emit setStatusBarText( KIO::itemsSummaryString(fileCount + dirCount, 00388 fileCount, 00389 dirCount, 00390 fileSizeSum, 00391 true)); 00392 } 00393 else 00394 emitTotalCount(); 00395 00396 // Yes, the caller could do that too :) 00397 // But this bool could also be used to cache the QString for the last 00398 // selection, as long as selectionChanged is false. 00399 // Not sure it's worth it though. 00400 if ( selectionChanged ) 00401 emit m_extension->selectionInfo( lst ); 00402 } 00403 00404 void KonqDirPart::emitMouseOver( const KFileItem* item ) 00405 { 00406 emit m_extension->mouseOverInfo( item ); 00407 } 00408 00409 void KonqDirPart::slotIconSizeToggled( bool ) 00410 { 00411 //kdDebug(1203) << "KonqDirPart::slotIconSizeToggled" << endl; 00412 if ( m_paDefaultIcons->isChecked() ) 00413 setIconSize(0); 00414 else if ( m_paHugeIcons->isChecked() ) 00415 setIconSize(m_iIconSize[4]); 00416 else if ( m_paLargeIcons->isChecked() ) 00417 setIconSize(m_iIconSize[3]); 00418 else if ( m_paMediumIcons->isChecked() ) 00419 setIconSize(m_iIconSize[2]); 00420 else if ( m_paSmallIcons->isChecked() ) 00421 setIconSize(m_iIconSize[1]); 00422 } 00423 00424 void KonqDirPart::slotIncIconSize() 00425 { 00426 int s = m_pProps->iconSize(); 00427 s = s ? s : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 00428 int sizeIndex = 0; 00429 for ( int idx=1; idx < 5 ; ++idx ) 00430 if (s == m_iIconSize[idx]) 00431 sizeIndex = idx; 00432 if ( sizeIndex > 0 && sizeIndex < 4 ) 00433 { 00434 setIconSize( m_iIconSize[sizeIndex + 1] ); 00435 } 00436 } 00437 00438 void KonqDirPart::slotDecIconSize() 00439 { 00440 int s = m_pProps->iconSize(); 00441 s = s ? s : KGlobal::iconLoader()->currentSize( KIcon::Desktop ); 00442 int sizeIndex = 0; 00443 for ( int idx=1; idx < 5 ; ++idx ) 00444 if (s == m_iIconSize[idx]) 00445 sizeIndex = idx; 00446 if ( sizeIndex > 1 ) 00447 { 00448 setIconSize( m_iIconSize[sizeIndex - 1] ); 00449 } 00450 } 00451 00452 // Only updates the GUI (that's the one that is reimplemented by the views, too) 00453 void KonqDirPart::newIconSize( int size /*0=default, or 16,32,48....*/ ) 00454 { 00455 int realSize = (size==0) ? KGlobal::iconLoader()->currentSize( KIcon::Desktop ) : size; 00456 m_paDecIconSize->setEnabled(realSize > m_iIconSize[1]); 00457 m_paIncIconSize->setEnabled(realSize < m_iIconSize[4]); 00458 00459 m_paDefaultIcons->setChecked( size == 0 ); 00460 m_paHugeIcons->setChecked( size == m_iIconSize[4] ); 00461 m_paLargeIcons->setChecked( size == m_iIconSize[3] ); 00462 m_paMediumIcons->setChecked( size == m_iIconSize[2] ); 00463 m_paSmallIcons->setChecked( size == m_iIconSize[1] ); 00464 } 00465 00466 // Stores the new icon size and updates the GUI 00467 void KonqDirPart::setIconSize( int size ) 00468 { 00469 //kdDebug(1203) << "KonqDirPart::setIconSize " << size << " -> updating props and GUI" << endl; 00470 m_pProps->setIconSize( size ); 00471 newIconSize( size ); 00472 } 00473 00474 bool KonqDirPart::closeURL() 00475 { 00476 // Tell all the childern objects to clean themselves up for dinner :) 00477 return doCloseURL(); 00478 } 00479 00480 bool KonqDirPart::openURL(const KURL& url) 00481 { 00482 if ( m_findPart ) 00483 { 00484 kdDebug(1203) << "KonqDirPart::openURL -> emit findClosed " << this << endl; 00485 delete m_findPart; 00486 m_findPart = 0L; 00487 emit findClosed( this ); 00488 } 00489 00490 m_url = url; 00491 emit aboutToOpenURL (); 00492 00493 return doOpenURL(url); 00494 } 00495 00496 void KonqDirPart::setFindPart( KParts::ReadOnlyPart * part ) 00497 { 00498 assert(part); 00499 m_findPart = part; 00500 connect( m_findPart, SIGNAL( started() ), 00501 this, SLOT( slotStarted() ) ); 00502 connect( m_findPart, SIGNAL( started() ), 00503 this, SLOT( slotStartAnimationSearching() ) ); 00504 connect( m_findPart, SIGNAL( clear() ), 00505 this, SLOT( slotClear() ) ); 00506 connect( m_findPart, SIGNAL( newItems( const KFileItemList & ) ), 00507 this, SLOT( slotNewItems( const KFileItemList & ) ) ); 00508 connect( m_findPart, SIGNAL( finished() ), // can't name it completed, it conflicts with a KROP signal 00509 this, SLOT( slotCompleted() ) ); 00510 connect( m_findPart, SIGNAL( finished() ), 00511 this, SLOT( slotStopAnimationSearching() ) ); 00512 connect( m_findPart, SIGNAL( canceled() ), 00513 this, SLOT( slotCanceled() ) ); 00514 connect( m_findPart, SIGNAL( canceled() ), 00515 this, SLOT( slotStopAnimationSearching() ) ); 00516 00517 connect( m_findPart, SIGNAL( findClosed() ), 00518 this, SLOT( slotFindClosed() ) ); 00519 00520 emit findOpened( this ); 00521 00522 // set the initial URL in the find part 00523 m_findPart->openURL( url() ); 00524 } 00525 00526 void KonqDirPart::slotFindClosed() 00527 { 00528 kdDebug(1203) << "KonqDirPart::slotFindClosed -> emit findClosed " << this << endl; 00529 delete m_findPart; 00530 m_findPart = 0L; 00531 emit findClosed( this ); 00532 // reload where we were before 00533 openURL( url() ); 00534 } 00535 00536 void KonqDirPart::slotStartAnimationSearching() 00537 { 00538 started(0); 00539 } 00540 00541 void KonqDirPart::slotStopAnimationSearching() 00542 { 00543 completed(); 00544 } 00545 00546 void KonqDirPartBrowserExtension::saveState( QDataStream &stream ) 00547 { 00548 m_dirPart->saveState( stream ); 00549 bool hasFindPart = m_dirPart->findPart(); 00550 stream << hasFindPart; 00551 assert( ! ( hasFindPart && m_dirPart->className() == "KFindPart" ) ); 00552 if ( !hasFindPart ) 00553 KParts::BrowserExtension::saveState( stream ); 00554 else { 00555 m_dirPart->saveFindState( stream ); 00556 } 00557 } 00558 00559 void KonqDirPartBrowserExtension::restoreState( QDataStream &stream ) 00560 { 00561 m_dirPart->restoreState( stream ); 00562 bool hasFindPart; 00563 stream >> hasFindPart; 00564 assert( ! ( hasFindPart && m_dirPart->className() == "KFindPart" ) ); 00565 if ( !hasFindPart ) 00566 // This calls openURL, that's why we don't want to call it in case of a find part 00567 KParts::BrowserExtension::restoreState( stream ); 00568 else { 00569 m_dirPart->restoreFindState( stream ); 00570 } 00571 } 00572 00573 00574 #include "konq_dirpart.moc"
KDE Logo
This file is part of the documentation for libkonq Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Dec 16 19:08:35 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003