konq_historymgr.cc
00001 /* This file is part of the KDE project 00002 Copyright (C) 2000,2001 Carsten Pfeiffer <pfeiffer@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., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "konq_historymgr.h" 00021 00022 #include <dcopclient.h> 00023 00024 #include <tdeapplication.h> 00025 #include <kdebug.h> 00026 #include <ksavefile.h> 00027 #include <ksimpleconfig.h> 00028 #include <kstandarddirs.h> 00029 00030 #include <zlib.h> 00031 00032 #include "konqbookmarkmanager.h" 00033 00034 const TQ_UINT32 KonqHistoryManager::s_historyVersion = 3; 00035 00036 KonqHistoryManager::KonqHistoryManager( TQObject *parent, const char *name ) 00037 : KParts::HistoryProvider( parent, name ), 00038 KonqHistoryComm( "KonqHistoryManager" ) 00039 { 00040 m_updateTimer = new TQTimer( this ); 00041 00042 // defaults 00043 TDEConfig *config = TDEGlobal::config(); 00044 TDEConfigGroupSaver cs( config, "HistorySettings" ); 00045 m_maxCount = config->readNumEntry( "Maximum of History entries", 500 ); 00046 m_maxCount = TQMAX( 1, m_maxCount ); 00047 m_maxAgeDays = config->readNumEntry( "Maximum age of History entries", 90); 00048 00049 m_history.setAutoDelete( true ); 00050 m_filename = locateLocal( "data", 00051 TQString::fromLatin1("konqueror/konq_history" )); 00052 00053 if ( !kapp->dcopClient()->isAttached() ) 00054 kapp->dcopClient()->attach(); 00055 00056 00057 // take care of the completion object 00058 m_pCompletion = new TDECompletion; 00059 m_pCompletion->setOrder( TDECompletion::Weighted ); 00060 00061 // and load the history 00062 loadHistory(); 00063 00064 connect( m_updateTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotEmitUpdated() )); 00065 } 00066 00067 00068 KonqHistoryManager::~KonqHistoryManager() 00069 { 00070 delete m_pCompletion; 00071 clearPending(); 00072 } 00073 00074 bool KonqHistoryManager::isSenderOfBroadcast() 00075 { 00076 DCOPClient *dc = callingDcopClient(); 00077 return !dc || (dc->senderId() == dc->appId()); 00078 } 00079 00080 // loads the entire history 00081 bool KonqHistoryManager::loadHistory() 00082 { 00083 clearPending(); 00084 m_history.clear(); 00085 m_pCompletion->clear(); 00086 00087 TQFile file( m_filename ); 00088 if ( !file.open( IO_ReadOnly ) ) { 00089 if ( file.exists() ) 00090 kdWarning() << "Can't open " << file.name() << endl; 00091 00092 // try to load the old completion history 00093 bool ret = loadFallback(); 00094 emit loadingFinished(); 00095 return ret; 00096 } 00097 00098 TQDataStream fileStream( &file ); 00099 TQByteArray data; // only used for version == 2 00100 // we construct the stream object now but fill in the data later. 00101 // thanks to QBA's explicit sharing this works :) 00102 TQDataStream crcStream( data, IO_ReadOnly ); 00103 00104 if ( !fileStream.atEnd() ) { 00105 TQ_UINT32 version; 00106 fileStream >> version; 00107 00108 TQDataStream *stream = &fileStream; 00109 00110 bool crcChecked = false; 00111 bool crcOk = false; 00112 00113 if ( version == 2 || version == 3) { 00114 TQ_UINT32 crc; 00115 crcChecked = true; 00116 fileStream >> crc >> data; 00117 crcOk = crc32( 0, reinterpret_cast<unsigned char *>( data.data() ), data.size() ) == crc; 00118 stream = &crcStream; // pick up the right stream 00119 } 00120 00121 if ( version == 3 ) 00122 { 00123 //Use KURL marshalling for V3 format. 00124 KonqHistoryEntry::marshalURLAsStrings = false; 00125 } 00126 00127 if ( version != 0 && version < 3 ) //Versions 1,2 (but not 0) are also valid 00128 { 00129 //Turn on backwards compatibility mode.. 00130 KonqHistoryEntry::marshalURLAsStrings = true; 00131 // it doesn't make sense to save to save maxAge and maxCount in the 00132 // binary file, this would make backups impossible (they would clear 00133 // themselves on startup, because all entries expire). 00134 // [But V1 and V2 formats did it, so we do a dummy read] 00135 TQ_UINT32 dummy; 00136 *stream >> dummy; 00137 *stream >> dummy; 00138 00139 //OK. 00140 version = 3; 00141 } 00142 00143 if ( s_historyVersion != version || ( crcChecked && !crcOk ) ) { 00144 kdWarning() << "The history version doesn't match, aborting loading" << endl; 00145 file.close(); 00146 emit loadingFinished(); 00147 return false; 00148 } 00149 00150 00151 while ( !stream->atEnd() ) { 00152 KonqHistoryEntry *entry = new KonqHistoryEntry; 00153 TQ_CHECK_PTR( entry ); 00154 *stream >> *entry; 00155 // kdDebug(1203) << "## loaded entry: " << entry->url << ", Title: " << entry->title << endl; 00156 m_history.append( entry ); 00157 TQString urlString2 = entry->url.prettyURL(); 00158 00159 addToCompletion( urlString2, entry->typedURL, entry->numberOfTimesVisited ); 00160 00161 // and fill our baseclass. 00162 TQString urlString = entry->url.url(); 00163 KParts::HistoryProvider::insert( urlString ); 00164 // DF: also insert the "pretty" version if different 00165 // This helps getting 'visited' links on websites which don't use fully-escaped urls. 00166 00167 if ( urlString != urlString2 ) 00168 KParts::HistoryProvider::insert( urlString2 ); 00169 } 00170 00171 kdDebug(1203) << "## loaded: " << m_history.count() << " entries." << endl; 00172 00173 m_history.sort(); 00174 adjustSize(); 00175 } 00176 00177 00178 //This is important - we need to switch to a consistent marshalling format for 00179 //communicating between different konqueror instances. Since during an upgrade 00180 //some "old" copies may still running, we use the old format for the DCOP transfers. 00181 //This doesn't make that much difference performance-wise for single entries anyway. 00182 KonqHistoryEntry::marshalURLAsStrings = true; 00183 00184 00185 // Theoretically, we should emit update() here, but as we only ever 00186 // load items on startup up to now, this doesn't make much sense. Same 00187 // thing for the above loadFallback(). 00188 // emit KParts::HistoryProvider::update( some list ); 00189 00190 00191 00192 file.close(); 00193 emit loadingFinished(); 00194 00195 return true; 00196 } 00197 00198 00199 // saves the entire history 00200 bool KonqHistoryManager::saveHistory() 00201 { 00202 KSaveFile file( m_filename ); 00203 if ( file.status() != 0 ) { 00204 kdWarning() << "Can't open " << file.name() << endl; 00205 return false; 00206 } 00207 00208 TQDataStream *fileStream = file.dataStream(); 00209 *fileStream << s_historyVersion; 00210 00211 TQByteArray data; 00212 TQDataStream stream( data, IO_WriteOnly ); 00213 00214 //We use KURL for marshalling URLs in entries in the V3 00215 //file format 00216 KonqHistoryEntry::marshalURLAsStrings = false; 00217 TQPtrListIterator<KonqHistoryEntry> it( m_history ); 00218 KonqHistoryEntry *entry; 00219 while ( (entry = it.current()) ) { 00220 stream << *entry; 00221 ++it; 00222 } 00223 00224 //For DCOP, transfer strings instead - wire compat. 00225 KonqHistoryEntry::marshalURLAsStrings = true; 00226 00227 TQ_UINT32 crc = crc32( 0, reinterpret_cast<unsigned char *>( data.data() ), data.size() ); 00228 *fileStream << crc << data; 00229 00230 file.close(); 00231 00232 return true; 00233 } 00234 00235 00236 void KonqHistoryManager::adjustSize() 00237 { 00238 KonqHistoryEntry *entry = m_history.getFirst(); 00239 00240 while ( m_history.count() > m_maxCount || isExpired( entry ) ) { 00241 removeFromCompletion( entry->url.prettyURL(), entry->typedURL ); 00242 00243 TQString urlString = entry->url.url(); 00244 KParts::HistoryProvider::remove( urlString ); 00245 00246 addToUpdateList( urlString ); 00247 00248 emit entryRemoved( m_history.getFirst() ); 00249 m_history.removeFirst(); // deletes the entry 00250 00251 entry = m_history.getFirst(); 00252 } 00253 } 00254 00255 00256 void KonqHistoryManager::addPending( const KURL& url, const TQString& typedURL, 00257 const TQString& title ) 00258 { 00259 addToHistory( true, url, typedURL, title ); 00260 } 00261 00262 void KonqHistoryManager::confirmPending( const KURL& url, 00263 const TQString& typedURL, 00264 const TQString& title ) 00265 { 00266 addToHistory( false, url, typedURL, title ); 00267 } 00268 00269 00270 void KonqHistoryManager::addToHistory( bool pending, const KURL& _url, 00271 const TQString& typedURL, 00272 const TQString& title ) 00273 { 00274 kdDebug(1203) << "## addToHistory: " << _url.prettyURL() << " Typed URL: " << typedURL << ", Title: " << title << endl; 00275 00276 if ( filterOut( _url ) ) // we only want remote URLs 00277 return; 00278 00279 // http URLs without a path will get redirected immediately to url + '/' 00280 if ( _url.path().isEmpty() && _url.protocol().startsWith("http") ) 00281 return; 00282 00283 KURL url( _url ); 00284 bool hasPass = url.hasPass(); 00285 url.setPass( TQString::null ); // No password in the history, especially not in the completion! 00286 url.setHost( url.host().lower() ); // All host parts lower case 00287 KonqHistoryEntry entry; 00288 TQString u = url.prettyURL(); 00289 entry.url = url; 00290 if ( (u != typedURL) && !hasPass ) 00291 entry.typedURL = typedURL; 00292 00293 // we only keep the title if we are confirming an entry. Otherwise, 00294 // we might get bogus titles from the previous url (actually it's just 00295 // konqueror's window caption). 00296 if ( !pending && u != title ) 00297 entry.title = title; 00298 entry.firstVisited = TQDateTime::currentDateTime(); 00299 entry.lastVisited = entry.firstVisited; 00300 00301 // always remove from pending if available, otherwise the else branch leaks 00302 // if the map already contains an entry for this key. 00303 TQMapIterator<TQString,KonqHistoryEntry*> it = m_pending.find( u ); 00304 if ( it != m_pending.end() ) { 00305 delete it.data(); 00306 m_pending.remove( it ); 00307 } 00308 00309 if ( !pending ) { 00310 if ( it != m_pending.end() ) { 00311 // we make a pending entry official, so we just have to update 00312 // and not increment the counter. No need to care about 00313 // firstVisited, as this is not taken into account on update. 00314 entry.numberOfTimesVisited = 0; 00315 } 00316 } 00317 00318 else { 00319 // We add a copy of the current history entry of the url to the 00320 // pending list, so that we can restore it if the user canceled. 00321 // If there is no entry for the url yet, we just store the url. 00322 KonqHistoryEntry *oldEntry = findEntry( url ); 00323 m_pending.insert( u, oldEntry ? 00324 new KonqHistoryEntry( *oldEntry ) : 0L ); 00325 } 00326 00327 // notify all konqueror instances about the entry 00328 emitAddToHistory( entry ); 00329 } 00330 00331 // interface of KParts::HistoryManager 00332 // Usually, we only record the history for non-local URLs (i.e. filterOut() 00333 // returns false). But when using the HistoryProvider interface, we record 00334 // exactly those filtered-out urls. 00335 // Moreover, we don't get any pending/confirming entries, just one insert() 00336 void KonqHistoryManager::insert( const TQString& url ) 00337 { 00338 KURL u ( url ); 00339 if ( !filterOut( u ) || u.protocol() == "about" ) { // remote URL 00340 return; 00341 } 00342 // Local URL -> add to history 00343 KonqHistoryEntry entry; 00344 entry.url = u; 00345 entry.firstVisited = TQDateTime::currentDateTime(); 00346 entry.lastVisited = entry.firstVisited; 00347 emitAddToHistory( entry ); 00348 } 00349 00350 void KonqHistoryManager::emitAddToHistory( const KonqHistoryEntry& entry ) 00351 { 00352 TQByteArray data; 00353 TQDataStream stream( data, IO_WriteOnly ); 00354 stream << entry << objId(); 00355 // Protection against very long urls (like data:) 00356 if ( data.size() > 4096 ) 00357 return; 00358 kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", 00359 "notifyHistoryEntry(KonqHistoryEntry, TQCString)", 00360 data ); 00361 } 00362 00363 00364 void KonqHistoryManager::removePending( const KURL& url ) 00365 { 00366 // kdDebug(1203) << "## Removing pending... " << url.prettyURL() << endl; 00367 00368 if ( url.isLocalFile() ) 00369 return; 00370 00371 TQMapIterator<TQString,KonqHistoryEntry*> it = m_pending.find( url.prettyURL() ); 00372 if ( it != m_pending.end() ) { 00373 KonqHistoryEntry *oldEntry = it.data(); // the old entry, may be 0L 00374 emitRemoveFromHistory( url ); // remove the current pending entry 00375 00376 if ( oldEntry ) // we had an entry before, now use that instead 00377 emitAddToHistory( *oldEntry ); 00378 00379 delete oldEntry; 00380 m_pending.remove( it ); 00381 } 00382 } 00383 00384 // clears the pending list and makes sure the entries get deleted. 00385 void KonqHistoryManager::clearPending() 00386 { 00387 TQMapIterator<TQString,KonqHistoryEntry*> it = m_pending.begin(); 00388 while ( it != m_pending.end() ) { 00389 delete it.data(); 00390 ++it; 00391 } 00392 m_pending.clear(); 00393 } 00394 00395 void KonqHistoryManager::emitRemoveFromHistory( const KURL& url ) 00396 { 00397 TQByteArray data; 00398 TQDataStream stream( data, IO_WriteOnly ); 00399 stream << url << objId(); 00400 kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", 00401 "notifyRemove(KURL, TQCString)", data ); 00402 } 00403 00404 void KonqHistoryManager::emitRemoveFromHistory( const KURL::List& urls ) 00405 { 00406 TQByteArray data; 00407 TQDataStream stream( data, IO_WriteOnly ); 00408 stream << urls << objId(); 00409 kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", 00410 "notifyRemove(KURL::List, TQCString)", data ); 00411 } 00412 00413 void KonqHistoryManager::emitClear() 00414 { 00415 TQByteArray data; 00416 TQDataStream stream( data, IO_WriteOnly ); 00417 stream << objId(); 00418 kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", 00419 "notifyClear(TQCString)", data ); 00420 } 00421 00422 void KonqHistoryManager::emitSetMaxCount( TQ_UINT32 count ) 00423 { 00424 TQByteArray data; 00425 TQDataStream stream( data, IO_WriteOnly ); 00426 stream << count << objId(); 00427 kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", 00428 "notifyMaxCount(TQ_UINT32, TQCString)", data ); 00429 } 00430 00431 void KonqHistoryManager::emitSetMaxAge( TQ_UINT32 days ) 00432 { 00433 TQByteArray data; 00434 TQDataStream stream( data, IO_WriteOnly ); 00435 stream << days << objId(); 00436 kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", 00437 "notifyMaxAge(TQ_UINT32, TQCString)", data ); 00438 } 00439 00441 // DCOP called methods 00442 00443 void KonqHistoryManager::notifyHistoryEntry( KonqHistoryEntry e, 00444 TQCString ) 00445 { 00446 //kdDebug(1203) << "Got new entry from Broadcast: " << e.url.prettyURL() << endl; 00447 00448 KonqHistoryEntry *entry = findEntry( e.url ); 00449 TQString urlString = e.url.url(); 00450 00451 if ( !entry ) { // create a new history entry 00452 entry = new KonqHistoryEntry; 00453 entry->url = e.url; 00454 entry->firstVisited = e.firstVisited; 00455 entry->numberOfTimesVisited = 0; // will get set to 1 below 00456 m_history.append( entry ); 00457 KParts::HistoryProvider::insert( urlString ); 00458 } 00459 00460 if ( !e.typedURL.isEmpty() ) 00461 entry->typedURL = e.typedURL; 00462 if ( !e.title.isEmpty() ) 00463 entry->title = e.title; 00464 entry->numberOfTimesVisited += e.numberOfTimesVisited; 00465 entry->lastVisited = e.lastVisited; 00466 00467 addToCompletion( entry->url.prettyURL(), entry->typedURL ); 00468 00469 // bool pending = (e.numberOfTimesVisited != 0); 00470 00471 adjustSize(); 00472 00473 // note, no need to do the updateBookmarkMetadata for every 00474 // history object, only need to for the broadcast sender as 00475 // the history object itself keeps the data consistant. 00476 bool updated = KonqBookmarkManager::self()->updateAccessMetadata( urlString ); 00477 00478 if ( isSenderOfBroadcast() ) { 00479 // we are the sender of the broadcast, so we save 00480 saveHistory(); 00481 // note, bk save does not notify, and we don't want to! 00482 if (updated) 00483 KonqBookmarkManager::self()->save(); 00484 } 00485 00486 addToUpdateList( urlString ); 00487 emit entryAdded( entry ); 00488 } 00489 00490 void KonqHistoryManager::notifyMaxCount( TQ_UINT32 count, TQCString ) 00491 { 00492 m_maxCount = count; 00493 clearPending(); 00494 adjustSize(); 00495 00496 TDEConfig *config = TDEGlobal::config(); 00497 TDEConfigGroupSaver cs( config, "HistorySettings" ); 00498 config->writeEntry( "Maximum of History entries", m_maxCount ); 00499 00500 if ( isSenderOfBroadcast() ) { 00501 saveHistory(); 00502 config->sync(); 00503 } 00504 } 00505 00506 void KonqHistoryManager::notifyMaxAge( TQ_UINT32 days, TQCString ) 00507 { 00508 m_maxAgeDays = days; 00509 clearPending(); 00510 adjustSize(); 00511 00512 TDEConfig *config = TDEGlobal::config(); 00513 TDEConfigGroupSaver cs( config, "HistorySettings" ); 00514 config->writeEntry( "Maximum age of History entries", m_maxAgeDays ); 00515 00516 if ( isSenderOfBroadcast() ) { 00517 saveHistory(); 00518 config->sync(); 00519 } 00520 } 00521 00522 void KonqHistoryManager::notifyClear( TQCString ) 00523 { 00524 clearPending(); 00525 m_history.clear(); 00526 m_pCompletion->clear(); 00527 00528 if ( isSenderOfBroadcast() ) 00529 saveHistory(); 00530 00531 KParts::HistoryProvider::clear(); // also emits the cleared() signal 00532 } 00533 00534 void KonqHistoryManager::notifyRemove( KURL url, TQCString ) 00535 { 00536 kdDebug(1203) << "#### Broadcast: remove entry:: " << url.prettyURL() << endl; 00537 00538 00539 KonqHistoryEntry *entry = m_history.findEntry( url ); 00540 00541 if ( entry ) { // entry is now the current item 00542 removeFromCompletion( entry->url.prettyURL(), entry->typedURL ); 00543 00544 TQString urlString = entry->url.url(); 00545 KParts::HistoryProvider::remove( urlString ); 00546 00547 addToUpdateList( urlString ); 00548 00549 m_history.take(); // does not delete 00550 emit entryRemoved( entry ); 00551 delete entry; 00552 00553 if ( isSenderOfBroadcast() ) 00554 saveHistory(); 00555 } 00556 } 00557 00558 void KonqHistoryManager::notifyRemove( KURL::List urls, TQCString ) 00559 { 00560 kdDebug(1203) << "#### Broadcast: removing list!" << endl; 00561 00562 bool doSave = false; 00563 KURL::List::Iterator it = urls.begin(); 00564 while ( it != urls.end() ) { 00565 KonqHistoryEntry *entry = m_history.findEntry( *it ); 00566 00567 if ( entry ) { // entry is now the current item 00568 removeFromCompletion( entry->url.prettyURL(), entry->typedURL ); 00569 00570 TQString urlString = entry->url.url(); 00571 KParts::HistoryProvider::remove( urlString ); 00572 00573 addToUpdateList( urlString ); 00574 00575 m_history.take(); // does not delete 00576 emit entryRemoved( entry ); 00577 delete entry; 00578 doSave = true; 00579 } 00580 00581 ++it; 00582 } 00583 00584 if (doSave && isSenderOfBroadcast()) 00585 saveHistory(); 00586 } 00587 00588 00589 // compatibility fallback, try to load the old completion history 00590 bool KonqHistoryManager::loadFallback() 00591 { 00592 TQString file = locateLocal( "config", TQString::fromLatin1("konq_history")); 00593 if ( file.isEmpty() ) 00594 return false; 00595 00596 KonqHistoryEntry *entry; 00597 KSimpleConfig config( file ); 00598 config.setGroup("History"); 00599 TQStringList items = config.readListEntry( "CompletionItems" ); 00600 TQStringList::Iterator it = items.begin(); 00601 00602 while ( it != items.end() ) { 00603 entry = createFallbackEntry( *it ); 00604 if ( entry ) { 00605 m_history.append( entry ); 00606 addToCompletion( entry->url.prettyURL(), TQString::null, entry->numberOfTimesVisited ); 00607 00608 KParts::HistoryProvider::insert( entry->url.url() ); 00609 } 00610 ++it; 00611 } 00612 00613 m_history.sort(); 00614 adjustSize(); 00615 saveHistory(); 00616 00617 return true; 00618 } 00619 00620 // tries to create a small KonqHistoryEntry out of a string, where the string 00621 // looks like "http://www.bla.com/bla.html:23" 00622 // the attached :23 is the weighting from TDECompletion 00623 KonqHistoryEntry * KonqHistoryManager::createFallbackEntry(const TQString& item) const 00624 { 00625 // code taken from TDECompletion::addItem(), adjusted to use weight = 1 00626 uint len = item.length(); 00627 uint weight = 1; 00628 00629 // find out the weighting of this item (appended to the string as ":num") 00630 int index = item.findRev(':'); 00631 if ( index > 0 ) { 00632 bool ok; 00633 weight = item.mid( index + 1 ).toUInt( &ok ); 00634 if ( !ok ) 00635 weight = 1; 00636 00637 len = index; // only insert until the ':' 00638 } 00639 00640 00641 KonqHistoryEntry *entry = 0L; 00642 KURL u( item.left( len )); 00643 if ( u.isValid() ) { 00644 entry = new KonqHistoryEntry; 00645 // that's the only entries we know about... 00646 entry->url = u; 00647 entry->numberOfTimesVisited = weight; 00648 // to make it not expire immediately... 00649 entry->lastVisited = TQDateTime::currentDateTime(); 00650 } 00651 00652 return entry; 00653 } 00654 00655 KonqHistoryEntry * KonqHistoryManager::findEntry( const KURL& url ) 00656 { 00657 // small optimization (dict lookup) for items _not_ in our history 00658 if ( !KParts::HistoryProvider::contains( url.url() ) ) 00659 return 0L; 00660 00661 return m_history.findEntry( url ); 00662 } 00663 00664 bool KonqHistoryManager::filterOut( const KURL& url ) 00665 { 00666 return ( url.isLocalFile() || url.host().isEmpty() ); 00667 } 00668 00669 void KonqHistoryManager::slotEmitUpdated() 00670 { 00671 emit KParts::HistoryProvider::updated( m_updateURLs ); 00672 m_updateURLs.clear(); 00673 } 00674 00675 TQStringList KonqHistoryManager::allURLs() const 00676 { 00677 TQStringList list; 00678 KonqHistoryIterator it ( m_history ); 00679 for ( ; it.current(); ++it ) 00680 list.append( it.current()->url.url() ); 00681 00682 return list; 00683 } 00684 00685 void KonqHistoryManager::addToCompletion( const TQString& url, const TQString& typedURL, 00686 int numberOfTimesVisited ) 00687 { 00688 m_pCompletion->addItem( url, numberOfTimesVisited ); 00689 // typed urls have a higher priority 00690 m_pCompletion->addItem( typedURL, numberOfTimesVisited +10 ); 00691 } 00692 00693 void KonqHistoryManager::removeFromCompletion( const TQString& url, const TQString& typedURL ) 00694 { 00695 m_pCompletion->removeItem( url ); 00696 m_pCompletion->removeItem( typedURL ); 00697 } 00698 00700 00701 00702 KonqHistoryEntry * KonqHistoryList::findEntry( const KURL& url ) 00703 { 00704 // we search backwards, probably faster to find an entry 00705 KonqHistoryEntry *entry = last(); 00706 while ( entry ) { 00707 if ( entry->url == url ) 00708 return entry; 00709 00710 entry = prev(); 00711 } 00712 00713 return 0L; 00714 } 00715 00716 // sort by lastVisited date (oldest go first) 00717 int KonqHistoryList::compareItems( TQPtrCollection::Item item1, 00718 TQPtrCollection::Item item2 ) 00719 { 00720 KonqHistoryEntry *entry1 = static_cast<KonqHistoryEntry *>( item1 ); 00721 KonqHistoryEntry *entry2 = static_cast<KonqHistoryEntry *>( item2 ); 00722 00723 if ( entry1->lastVisited > entry2->lastVisited ) 00724 return 1; 00725 else if ( entry1->lastVisited < entry2->lastVisited ) 00726 return -1; 00727 else 00728 return 0; 00729 } 00730 00731 using namespace KParts; // for IRIX 00732 00733 #include "konq_historymgr.moc"