20 #include "konq_historymgr.h" 22 #include <dcopclient.h> 24 #include <tdeapplication.h> 26 #include <ksavefile.h> 27 #include <ksimpleconfig.h> 28 #include <tdestandarddirs.h> 32 #include "konqbookmarkmanager.h" 34 const TQ_UINT32 KonqHistoryManager::s_historyVersion = 3;
36 KonqHistoryManager::KonqHistoryManager( TQObject *parent,
const char *name )
37 :
KParts::HistoryProvider( parent, name ),
40 m_updateTimer =
new TQTimer(
this );
43 TDEConfig *config = TDEGlobal::config();
44 TDEConfigGroupSaver cs( config,
"HistorySettings" );
45 m_maxCount = config->readNumEntry(
"Maximum of History entries", 500 );
46 m_maxCount = TQMAX( 1, m_maxCount );
47 m_maxAgeDays = config->readNumEntry(
"Maximum age of History entries", 90);
49 m_history.setAutoDelete(
true );
50 m_filename = locateLocal(
"data",
51 TQString::fromLatin1(
"konqueror/konq_history" ));
53 if ( !tdeApp->dcopClient()->isAttached() )
54 tdeApp->dcopClient()->attach();
58 m_pCompletion =
new TDECompletion;
59 m_pCompletion->setOrder( TDECompletion::Weighted );
64 connect( m_updateTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( slotEmitUpdated() ));
68 KonqHistoryManager::~KonqHistoryManager()
74 bool KonqHistoryManager::isSenderOfBroadcast()
76 DCOPClient *dc = callingDcopClient();
77 return !dc || (dc->senderId() == dc->appId());
85 m_pCompletion->clear();
87 TQFile file( m_filename );
88 if ( !file.open( IO_ReadOnly ) ) {
90 kdWarning() <<
"Can't open " << file.name() << endl;
93 bool ret = loadFallback();
94 emit loadingFinished();
98 TQDataStream fileStream( &file );
102 TQDataStream crcStream( data, IO_ReadOnly );
104 if ( !fileStream.atEnd() ) {
106 fileStream >> version;
108 TQDataStream *stream = &fileStream;
110 bool crcChecked =
false;
113 if ( version == 2 || version == 3) {
116 fileStream >> crc >> data;
117 crcOk = crc32( 0, reinterpret_cast<unsigned char *>( data.data() ), data.size() ) == crc;
124 KonqHistoryEntry::marshalURLAsStrings =
false;
127 if ( version != 0 && version < 3 )
130 KonqHistoryEntry::marshalURLAsStrings =
true;
143 if ( s_historyVersion != version || ( crcChecked && !crcOk ) ) {
144 kdWarning() <<
"The history version doesn't match, aborting loading" << endl;
146 emit loadingFinished();
151 while ( !stream->atEnd() ) {
152 KonqHistoryEntry *entry =
new KonqHistoryEntry;
153 TQ_CHECK_PTR( entry );
156 m_history.append( entry );
157 TQString urlString2 = entry->url.prettyURL();
159 addToCompletion( urlString2, entry->typedURL, entry->numberOfTimesVisited );
162 TQString urlString = entry->url.url();
163 KParts::HistoryProvider::insert( urlString );
167 if ( urlString != urlString2 )
168 KParts::HistoryProvider::insert( urlString2 );
171 kdDebug(1203) <<
"## loaded: " << m_history.count() <<
" entries." << endl;
182 KonqHistoryEntry::marshalURLAsStrings =
true;
193 emit loadingFinished();
202 KSaveFile file( m_filename );
203 if ( file.status() != 0 ) {
204 kdWarning() <<
"Can't open " << file.name() << endl;
208 TQDataStream *fileStream = file.dataStream();
209 *fileStream << s_historyVersion;
212 TQDataStream stream( data, IO_WriteOnly );
216 KonqHistoryEntry::marshalURLAsStrings =
false;
217 TQPtrListIterator<KonqHistoryEntry> it( m_history );
218 KonqHistoryEntry *entry;
219 while ( (entry = it.current()) ) {
225 KonqHistoryEntry::marshalURLAsStrings =
true;
227 TQ_UINT32 crc = crc32( 0, reinterpret_cast<unsigned char *>( data.data() ), data.size() );
228 *fileStream << crc << data;
238 KonqHistoryEntry *entry = m_history.getFirst();
240 while ( m_history.count() > m_maxCount || isExpired( entry ) ) {
241 removeFromCompletion( entry->url.prettyURL(), entry->typedURL );
243 TQString urlString = entry->url.url();
244 KParts::HistoryProvider::remove( urlString );
246 addToUpdateList( urlString );
248 emit entryRemoved( m_history.getFirst() );
249 m_history.removeFirst();
251 entry = m_history.getFirst();
257 const TQString& title )
259 addToHistory(
true, url, typedURL, title );
263 const TQString& typedURL,
264 const TQString& title )
266 addToHistory(
false, url, typedURL, title );
271 const TQString& typedURL,
272 const TQString& title )
274 kdDebug(1203) <<
"## addToHistory: " << _url.prettyURL() <<
" Typed URL: " << typedURL <<
", Title: " << title << endl;
276 if ( filterOut( _url ) )
280 if ( _url.path().isEmpty() && _url.protocol().startsWith(
"http") )
284 bool hasPass = url.hasPass();
285 url.setPass( TQString::null );
286 url.setHost( url.host().lower() );
287 KonqHistoryEntry entry;
288 TQString u = url.prettyURL();
290 if ( (u != typedURL) && !hasPass )
291 entry.typedURL = typedURL;
296 if ( !pending && u != title )
298 entry.firstVisited = TQDateTime::currentDateTime();
299 entry.lastVisited = entry.firstVisited;
303 TQMapIterator<TQString,KonqHistoryEntry*> it = m_pending.find( u );
304 if ( it != m_pending.end() ) {
306 m_pending.remove( it );
310 if ( it != m_pending.end() ) {
314 entry.numberOfTimesVisited = 0;
322 KonqHistoryEntry *oldEntry = findEntry( url );
323 m_pending.insert( u, oldEntry ?
324 new KonqHistoryEntry( *oldEntry ) : 0L );
328 emitAddToHistory( entry );
339 if ( !filterOut( u ) || u.protocol() ==
"about" ) {
343 KonqHistoryEntry entry;
345 entry.firstVisited = TQDateTime::currentDateTime();
346 entry.lastVisited = entry.firstVisited;
347 emitAddToHistory( entry );
353 TQDataStream stream( data, IO_WriteOnly );
354 stream << entry << objId();
356 if ( data.size() > 4096 )
358 tdeApp->dcopClient()->send(
"konqueror*",
"KonqHistoryManager",
359 "notifyHistoryEntry(KonqHistoryEntry, TQCString)",
368 if ( url.isLocalFile() )
371 TQMapIterator<TQString,KonqHistoryEntry*> it = m_pending.find( url.prettyURL() );
372 if ( it != m_pending.end() ) {
373 KonqHistoryEntry *oldEntry = it.data();
374 emitRemoveFromHistory( url );
377 emitAddToHistory( *oldEntry );
380 m_pending.remove( it );
385 void KonqHistoryManager::clearPending()
387 TQMapIterator<TQString,KonqHistoryEntry*> it = m_pending.begin();
388 while ( it != m_pending.end() ) {
398 TQDataStream stream( data, IO_WriteOnly );
399 stream << url << objId();
400 tdeApp->dcopClient()->send(
"konqueror*",
"KonqHistoryManager",
401 "notifyRemove(KURL, TQCString)", data );
407 TQDataStream stream( data, IO_WriteOnly );
408 stream << urls << objId();
409 tdeApp->dcopClient()->send(
"konqueror*",
"KonqHistoryManager",
410 "notifyRemove(KURL::List, TQCString)", data );
416 TQDataStream stream( data, IO_WriteOnly );
418 tdeApp->dcopClient()->send(
"konqueror*",
"KonqHistoryManager",
419 "notifyClear(TQCString)", data );
425 TQDataStream stream( data, IO_WriteOnly );
426 stream << count << objId();
427 tdeApp->dcopClient()->send(
"konqueror*",
"KonqHistoryManager",
428 "notifyMaxCount(TQ_UINT32, TQCString)", data );
434 TQDataStream stream( data, IO_WriteOnly );
435 stream << days << objId();
436 tdeApp->dcopClient()->send(
"konqueror*",
"KonqHistoryManager",
437 "notifyMaxAge(TQ_UINT32, TQCString)", data );
448 KonqHistoryEntry *entry = findEntry( e.url );
449 TQString urlString = e.url.url();
452 entry =
new KonqHistoryEntry;
454 entry->firstVisited = e.firstVisited;
455 entry->numberOfTimesVisited = 0;
456 m_history.append( entry );
457 KParts::HistoryProvider::insert( urlString );
460 if ( !e.typedURL.isEmpty() )
461 entry->typedURL = e.typedURL;
462 if ( !e.title.isEmpty() )
463 entry->title = e.title;
464 entry->numberOfTimesVisited += e.numberOfTimesVisited;
465 entry->lastVisited = e.lastVisited;
467 addToCompletion( entry->url.prettyURL(), entry->typedURL );
476 bool updated = KonqBookmarkManager::self()->updateAccessMetadata( urlString );
478 if ( isSenderOfBroadcast() ) {
483 KonqBookmarkManager::self()->save();
486 addToUpdateList( urlString );
487 emit entryAdded( entry );
496 TDEConfig *config = TDEGlobal::config();
497 TDEConfigGroupSaver cs( config,
"HistorySettings" );
498 config->writeEntry(
"Maximum of History entries", m_maxCount );
500 if ( isSenderOfBroadcast() ) {
512 TDEConfig *config = TDEGlobal::config();
513 TDEConfigGroupSaver cs( config,
"HistorySettings" );
514 config->writeEntry(
"Maximum age of History entries", m_maxAgeDays );
516 if ( isSenderOfBroadcast() ) {
526 m_pCompletion->clear();
528 if ( isSenderOfBroadcast() )
531 KParts::HistoryProvider::clear();
536 kdDebug(1203) <<
"#### Broadcast: remove entry:: " << url.prettyURL() << endl;
539 KonqHistoryEntry *entry = m_history.findEntry( url );
542 removeFromCompletion( entry->url.prettyURL(), entry->typedURL );
544 TQString urlString = entry->url.url();
545 KParts::HistoryProvider::remove( urlString );
547 addToUpdateList( urlString );
550 emit entryRemoved( entry );
553 if ( isSenderOfBroadcast() )
560 kdDebug(1203) <<
"#### Broadcast: removing list!" << endl;
563 KURL::List::Iterator it = urls.begin();
564 while ( it != urls.end() ) {
565 KonqHistoryEntry *entry = m_history.findEntry( *it );
568 removeFromCompletion( entry->url.prettyURL(), entry->typedURL );
570 TQString urlString = entry->url.url();
571 KParts::HistoryProvider::remove( urlString );
573 addToUpdateList( urlString );
576 emit entryRemoved( entry );
584 if (doSave && isSenderOfBroadcast())
590 bool KonqHistoryManager::loadFallback()
592 TQString file = locateLocal(
"config", TQString::fromLatin1(
"konq_history"));
593 if ( file.isEmpty() )
596 KonqHistoryEntry *entry;
597 KSimpleConfig config( file );
598 config.setGroup(
"History");
599 TQStringList items = config.readListEntry(
"CompletionItems" );
600 TQStringList::Iterator it = items.begin();
602 while ( it != items.end() ) {
603 entry = createFallbackEntry( *it );
605 m_history.append( entry );
606 addToCompletion( entry->url.prettyURL(), TQString::null, entry->numberOfTimesVisited );
608 KParts::HistoryProvider::insert( entry->url.url() );
623 KonqHistoryEntry * KonqHistoryManager::createFallbackEntry(
const TQString& item)
const 626 uint len = item.length();
630 int index = item.findRev(
':');
633 weight = item.mid( index + 1 ).toUInt( &ok );
641 KonqHistoryEntry *entry = 0L;
642 KURL u( item.left( len ));
644 entry =
new KonqHistoryEntry;
647 entry->numberOfTimesVisited = weight;
649 entry->lastVisited = TQDateTime::currentDateTime();
655 KonqHistoryEntry * KonqHistoryManager::findEntry(
const KURL& url )
658 if ( !KParts::HistoryProvider::contains( url.url() ) )
661 return m_history.findEntry( url );
666 return ( url.isLocalFile() || url.host().isEmpty() );
669 void KonqHistoryManager::slotEmitUpdated()
671 emit KParts::HistoryProvider::updated( m_updateURLs );
672 m_updateURLs.clear();
678 KonqHistoryIterator it ( m_history );
679 for ( ; it.current(); ++it )
680 list.append( it.current()->url.url() );
685 void KonqHistoryManager::addToCompletion(
const TQString& url,
const TQString& typedURL,
686 int numberOfTimesVisited )
688 m_pCompletion->addItem( url, numberOfTimesVisited );
690 m_pCompletion->addItem( typedURL, numberOfTimesVisited +10 );
693 void KonqHistoryManager::removeFromCompletion(
const TQString& url,
const TQString& typedURL )
695 m_pCompletion->removeItem( url );
696 m_pCompletion->removeItem( typedURL );
702 KonqHistoryEntry * KonqHistoryList::findEntry(
const KURL& url )
705 KonqHistoryEntry *entry = last();
707 if ( entry->url == url )
717 int KonqHistoryList::compareItems( TQPtrCollection::Item item1,
718 TQPtrCollection::Item item2 )
720 KonqHistoryEntry *entry1 =
static_cast<KonqHistoryEntry *
>( item1 );
721 KonqHistoryEntry *entry2 =
static_cast<KonqHistoryEntry *
>( item2 );
723 if ( entry1->lastVisited > entry2->lastVisited )
725 else if ( entry1->lastVisited < entry2->lastVisited )
733 #include "konq_historymgr.moc" virtual void notifyRemove(KURL url, TQCString saveId)
Notifes about a url that has to be removed from the history.
void emitSetMaxAge(TQ_UINT32 days)
Sets a new maximum age of history entries and removes all entries that are older than days...
virtual void notifyHistoryEntry(KonqHistoryEntry e, TQCString saveId)
Every konqueror instance broadcasts new history entries to the other konqueror instances.
virtual void notifyMaxCount(TQ_UINT32 count, TQCString saveId)
Called when the configuration of the maximum count changed.
virtual bool filterOut(const KURL &url)
bool loadHistory()
Loads the history and fills the completion object.
void removePending(const KURL &url)
Removes a pending url from the history, e.g.
void confirmPending(const KURL &url, const TQString &typedURL=TQString::null, const TQString &title=TQString::null)
Confirms and updates the entry for url.
virtual void notifyClear(TQCString saveId)
Clears the history completely.
void addPending(const KURL &url, const TQString &typedURL=TQString::null, const TQString &title=TQString::null)
Adds a pending entry to the history.
void emitRemoveFromHistory(const KURL &url)
Removes the history entry for url, if existant.
void addToHistory(bool pending, const KURL &url, const TQString &typedURL=TQString::null, const TQString &title=TQString::null)
Does the work for addPending() and confirmPending().
void adjustSize()
Resizes the history list to contain less or equal than m_maxCount entries.
DCOP Methods for KonqHistoryManager.
void emitAddToHistory(const KonqHistoryEntry &entry)
Notifes all running instances about a new HistoryEntry via DCOP.
virtual TQStringList allURLs() const
bool saveHistory()
Saves the entire history.
virtual void insert(const TQString &)
Reimplemented in such a way that all URLs that would be filtered out normally (see filterOut()) will ...
void emitSetMaxCount(TQ_UINT32 count)
Sets a new maximum size of history and truncates the current history if necessary.
void emitClear()
Clears the history and tells all other Konqueror instances via DCOP to do the same.
virtual void notifyMaxAge(TQ_UINT32 days, TQCString saveId)
Called when the configuration of the maximum age of history-entries changed.