diff options
Diffstat (limited to 'libkonq/konq_historymgr.cc')
-rw-r--r-- | libkonq/konq_historymgr.cc | 733 |
1 files changed, 0 insertions, 733 deletions
diff --git a/libkonq/konq_historymgr.cc b/libkonq/konq_historymgr.cc deleted file mode 100644 index 25cfef345..000000000 --- a/libkonq/konq_historymgr.cc +++ /dev/null @@ -1,733 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2000,2001 Carsten Pfeiffer <[email protected]> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "konq_historymgr.h" - -#include <dcopclient.h> - -#include <tdeapplication.h> -#include <kdebug.h> -#include <ksavefile.h> -#include <ksimpleconfig.h> -#include <kstandarddirs.h> - -#include <zlib.h> - -#include "konqbookmarkmanager.h" - -const TQ_UINT32 KonqHistoryManager::s_historyVersion = 3; - -KonqHistoryManager::KonqHistoryManager( TQObject *parent, const char *name ) - : KParts::HistoryProvider( parent, name ), - KonqHistoryComm( "KonqHistoryManager" ) -{ - m_updateTimer = new TQTimer( this ); - - // defaults - TDEConfig *config = TDEGlobal::config(); - TDEConfigGroupSaver cs( config, "HistorySettings" ); - m_maxCount = config->readNumEntry( "Maximum of History entries", 500 ); - m_maxCount = TQMAX( 1, m_maxCount ); - m_maxAgeDays = config->readNumEntry( "Maximum age of History entries", 90); - - m_history.setAutoDelete( true ); - m_filename = locateLocal( "data", - TQString::fromLatin1("konqueror/konq_history" )); - - if ( !kapp->dcopClient()->isAttached() ) - kapp->dcopClient()->attach(); - - - // take care of the completion object - m_pCompletion = new TDECompletion; - m_pCompletion->setOrder( TDECompletion::Weighted ); - - // and load the history - loadHistory(); - - connect( m_updateTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotEmitUpdated() )); -} - - -KonqHistoryManager::~KonqHistoryManager() -{ - delete m_pCompletion; - clearPending(); -} - -bool KonqHistoryManager::isSenderOfBroadcast() -{ - DCOPClient *dc = callingDcopClient(); - return !dc || (dc->senderId() == dc->appId()); -} - -// loads the entire history -bool KonqHistoryManager::loadHistory() -{ - clearPending(); - m_history.clear(); - m_pCompletion->clear(); - - TQFile file( m_filename ); - if ( !file.open( IO_ReadOnly ) ) { - if ( file.exists() ) - kdWarning() << "Can't open " << file.name() << endl; - - // try to load the old completion history - bool ret = loadFallback(); - emit loadingFinished(); - return ret; - } - - TQDataStream fileStream( &file ); - TQByteArray data; // only used for version == 2 - // we construct the stream object now but fill in the data later. - // thanks to QBA's explicit sharing this works :) - TQDataStream crcStream( data, IO_ReadOnly ); - - if ( !fileStream.atEnd() ) { - TQ_UINT32 version; - fileStream >> version; - - TQDataStream *stream = &fileStream; - - bool crcChecked = false; - bool crcOk = false; - - if ( version == 2 || version == 3) { - TQ_UINT32 crc; - crcChecked = true; - fileStream >> crc >> data; - crcOk = crc32( 0, reinterpret_cast<unsigned char *>( data.data() ), data.size() ) == crc; - stream = &crcStream; // pick up the right stream - } - - if ( version == 3 ) - { - //Use KURL marshalling for V3 format. - KonqHistoryEntry::marshalURLAsStrings = false; - } - - if ( version != 0 && version < 3 ) //Versions 1,2 (but not 0) are also valid - { - //Turn on backwards compatibility mode.. - KonqHistoryEntry::marshalURLAsStrings = true; - // it doesn't make sense to save to save maxAge and maxCount in the - // binary file, this would make backups impossible (they would clear - // themselves on startup, because all entries expire). - // [But V1 and V2 formats did it, so we do a dummy read] - TQ_UINT32 dummy; - *stream >> dummy; - *stream >> dummy; - - //OK. - version = 3; - } - - if ( s_historyVersion != version || ( crcChecked && !crcOk ) ) { - kdWarning() << "The history version doesn't match, aborting loading" << endl; - file.close(); - emit loadingFinished(); - return false; - } - - - while ( !stream->atEnd() ) { - KonqHistoryEntry *entry = new KonqHistoryEntry; - TQ_CHECK_PTR( entry ); - *stream >> *entry; - // kdDebug(1203) << "## loaded entry: " << entry->url << ", Title: " << entry->title << endl; - m_history.append( entry ); - TQString urlString2 = entry->url.prettyURL(); - - addToCompletion( urlString2, entry->typedURL, entry->numberOfTimesVisited ); - - // and fill our baseclass. - TQString urlString = entry->url.url(); - KParts::HistoryProvider::insert( urlString ); - // DF: also insert the "pretty" version if different - // This helps getting 'visited' links on websites which don't use fully-escaped urls. - - if ( urlString != urlString2 ) - KParts::HistoryProvider::insert( urlString2 ); - } - - kdDebug(1203) << "## loaded: " << m_history.count() << " entries." << endl; - - m_history.sort(); - adjustSize(); - } - - - //This is important - we need to switch to a consistent marshalling format for - //communicating between different konqueror instances. Since during an upgrade - //some "old" copies may still running, we use the old format for the DCOP transfers. - //This doesn't make that much difference performance-wise for single entries anyway. - KonqHistoryEntry::marshalURLAsStrings = true; - - - // Theoretically, we should emit update() here, but as we only ever - // load items on startup up to now, this doesn't make much sense. Same - // thing for the above loadFallback(). - // emit KParts::HistoryProvider::update( some list ); - - - - file.close(); - emit loadingFinished(); - - return true; -} - - -// saves the entire history -bool KonqHistoryManager::saveHistory() -{ - KSaveFile file( m_filename ); - if ( file.status() != 0 ) { - kdWarning() << "Can't open " << file.name() << endl; - return false; - } - - TQDataStream *fileStream = file.dataStream(); - *fileStream << s_historyVersion; - - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - - //We use KURL for marshalling URLs in entries in the V3 - //file format - KonqHistoryEntry::marshalURLAsStrings = false; - TQPtrListIterator<KonqHistoryEntry> it( m_history ); - KonqHistoryEntry *entry; - while ( (entry = it.current()) ) { - stream << *entry; - ++it; - } - - //For DCOP, transfer strings instead - wire compat. - KonqHistoryEntry::marshalURLAsStrings = true; - - TQ_UINT32 crc = crc32( 0, reinterpret_cast<unsigned char *>( data.data() ), data.size() ); - *fileStream << crc << data; - - file.close(); - - return true; -} - - -void KonqHistoryManager::adjustSize() -{ - KonqHistoryEntry *entry = m_history.getFirst(); - - while ( m_history.count() > m_maxCount || isExpired( entry ) ) { - removeFromCompletion( entry->url.prettyURL(), entry->typedURL ); - - TQString urlString = entry->url.url(); - KParts::HistoryProvider::remove( urlString ); - - addToUpdateList( urlString ); - - emit entryRemoved( m_history.getFirst() ); - m_history.removeFirst(); // deletes the entry - - entry = m_history.getFirst(); - } -} - - -void KonqHistoryManager::addPending( const KURL& url, const TQString& typedURL, - const TQString& title ) -{ - addToHistory( true, url, typedURL, title ); -} - -void KonqHistoryManager::confirmPending( const KURL& url, - const TQString& typedURL, - const TQString& title ) -{ - addToHistory( false, url, typedURL, title ); -} - - -void KonqHistoryManager::addToHistory( bool pending, const KURL& _url, - const TQString& typedURL, - const TQString& title ) -{ - kdDebug(1203) << "## addToHistory: " << _url.prettyURL() << " Typed URL: " << typedURL << ", Title: " << title << endl; - - if ( filterOut( _url ) ) // we only want remote URLs - return; - - // http URLs without a path will get redirected immediately to url + '/' - if ( _url.path().isEmpty() && _url.protocol().startsWith("http") ) - return; - - KURL url( _url ); - bool hasPass = url.hasPass(); - url.setPass( TQString::null ); // No password in the history, especially not in the completion! - url.setHost( url.host().lower() ); // All host parts lower case - KonqHistoryEntry entry; - TQString u = url.prettyURL(); - entry.url = url; - if ( (u != typedURL) && !hasPass ) - entry.typedURL = typedURL; - - // we only keep the title if we are confirming an entry. Otherwise, - // we might get bogus titles from the previous url (actually it's just - // konqueror's window caption). - if ( !pending && u != title ) - entry.title = title; - entry.firstVisited = TQDateTime::currentDateTime(); - entry.lastVisited = entry.firstVisited; - - // always remove from pending if available, otherwise the else branch leaks - // if the map already contains an entry for this key. - TQMapIterator<TQString,KonqHistoryEntry*> it = m_pending.find( u ); - if ( it != m_pending.end() ) { - delete it.data(); - m_pending.remove( it ); - } - - if ( !pending ) { - if ( it != m_pending.end() ) { - // we make a pending entry official, so we just have to update - // and not increment the counter. No need to care about - // firstVisited, as this is not taken into account on update. - entry.numberOfTimesVisited = 0; - } - } - - else { - // We add a copy of the current history entry of the url to the - // pending list, so that we can restore it if the user canceled. - // If there is no entry for the url yet, we just store the url. - KonqHistoryEntry *oldEntry = findEntry( url ); - m_pending.insert( u, oldEntry ? - new KonqHistoryEntry( *oldEntry ) : 0L ); - } - - // notify all konqueror instances about the entry - emitAddToHistory( entry ); -} - -// interface of KParts::HistoryManager -// Usually, we only record the history for non-local URLs (i.e. filterOut() -// returns false). But when using the HistoryProvider interface, we record -// exactly those filtered-out urls. -// Moreover, we don't get any pending/confirming entries, just one insert() -void KonqHistoryManager::insert( const TQString& url ) -{ - KURL u ( url ); - if ( !filterOut( u ) || u.protocol() == "about" ) { // remote URL - return; - } - // Local URL -> add to history - KonqHistoryEntry entry; - entry.url = u; - entry.firstVisited = TQDateTime::currentDateTime(); - entry.lastVisited = entry.firstVisited; - emitAddToHistory( entry ); -} - -void KonqHistoryManager::emitAddToHistory( const KonqHistoryEntry& entry ) -{ - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - stream << entry << objId(); - // Protection against very long urls (like data:) - if ( data.size() > 4096 ) - return; - kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", - "notifyHistoryEntry(KonqHistoryEntry, TQCString)", - data ); -} - - -void KonqHistoryManager::removePending( const KURL& url ) -{ - // kdDebug(1203) << "## Removing pending... " << url.prettyURL() << endl; - - if ( url.isLocalFile() ) - return; - - TQMapIterator<TQString,KonqHistoryEntry*> it = m_pending.find( url.prettyURL() ); - if ( it != m_pending.end() ) { - KonqHistoryEntry *oldEntry = it.data(); // the old entry, may be 0L - emitRemoveFromHistory( url ); // remove the current pending entry - - if ( oldEntry ) // we had an entry before, now use that instead - emitAddToHistory( *oldEntry ); - - delete oldEntry; - m_pending.remove( it ); - } -} - -// clears the pending list and makes sure the entries get deleted. -void KonqHistoryManager::clearPending() -{ - TQMapIterator<TQString,KonqHistoryEntry*> it = m_pending.begin(); - while ( it != m_pending.end() ) { - delete it.data(); - ++it; - } - m_pending.clear(); -} - -void KonqHistoryManager::emitRemoveFromHistory( const KURL& url ) -{ - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - stream << url << objId(); - kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", - "notifyRemove(KURL, TQCString)", data ); -} - -void KonqHistoryManager::emitRemoveFromHistory( const KURL::List& urls ) -{ - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - stream << urls << objId(); - kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", - "notifyRemove(KURL::List, TQCString)", data ); -} - -void KonqHistoryManager::emitClear() -{ - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - stream << objId(); - kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", - "notifyClear(TQCString)", data ); -} - -void KonqHistoryManager::emitSetMaxCount( TQ_UINT32 count ) -{ - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - stream << count << objId(); - kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", - "notifyMaxCount(TQ_UINT32, TQCString)", data ); -} - -void KonqHistoryManager::emitSetMaxAge( TQ_UINT32 days ) -{ - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - stream << days << objId(); - kapp->dcopClient()->send( "konqueror*", "KonqHistoryManager", - "notifyMaxAge(TQ_UINT32, TQCString)", data ); -} - -/////////////////////////////////////////////////////////////////// -// DCOP called methods - -void KonqHistoryManager::notifyHistoryEntry( KonqHistoryEntry e, - TQCString ) -{ - //kdDebug(1203) << "Got new entry from Broadcast: " << e.url.prettyURL() << endl; - - KonqHistoryEntry *entry = findEntry( e.url ); - TQString urlString = e.url.url(); - - if ( !entry ) { // create a new history entry - entry = new KonqHistoryEntry; - entry->url = e.url; - entry->firstVisited = e.firstVisited; - entry->numberOfTimesVisited = 0; // will get set to 1 below - m_history.append( entry ); - KParts::HistoryProvider::insert( urlString ); - } - - if ( !e.typedURL.isEmpty() ) - entry->typedURL = e.typedURL; - if ( !e.title.isEmpty() ) - entry->title = e.title; - entry->numberOfTimesVisited += e.numberOfTimesVisited; - entry->lastVisited = e.lastVisited; - - addToCompletion( entry->url.prettyURL(), entry->typedURL ); - - // bool pending = (e.numberOfTimesVisited != 0); - - adjustSize(); - - // note, no need to do the updateBookmarkMetadata for every - // history object, only need to for the broadcast sender as - // the history object itself keeps the data consistant. - bool updated = KonqBookmarkManager::self()->updateAccessMetadata( urlString ); - - if ( isSenderOfBroadcast() ) { - // we are the sender of the broadcast, so we save - saveHistory(); - // note, bk save does not notify, and we don't want to! - if (updated) - KonqBookmarkManager::self()->save(); - } - - addToUpdateList( urlString ); - emit entryAdded( entry ); -} - -void KonqHistoryManager::notifyMaxCount( TQ_UINT32 count, TQCString ) -{ - m_maxCount = count; - clearPending(); - adjustSize(); - - TDEConfig *config = TDEGlobal::config(); - TDEConfigGroupSaver cs( config, "HistorySettings" ); - config->writeEntry( "Maximum of History entries", m_maxCount ); - - if ( isSenderOfBroadcast() ) { - saveHistory(); - config->sync(); - } -} - -void KonqHistoryManager::notifyMaxAge( TQ_UINT32 days, TQCString ) -{ - m_maxAgeDays = days; - clearPending(); - adjustSize(); - - TDEConfig *config = TDEGlobal::config(); - TDEConfigGroupSaver cs( config, "HistorySettings" ); - config->writeEntry( "Maximum age of History entries", m_maxAgeDays ); - - if ( isSenderOfBroadcast() ) { - saveHistory(); - config->sync(); - } -} - -void KonqHistoryManager::notifyClear( TQCString ) -{ - clearPending(); - m_history.clear(); - m_pCompletion->clear(); - - if ( isSenderOfBroadcast() ) - saveHistory(); - - KParts::HistoryProvider::clear(); // also emits the cleared() signal -} - -void KonqHistoryManager::notifyRemove( KURL url, TQCString ) -{ - kdDebug(1203) << "#### Broadcast: remove entry:: " << url.prettyURL() << endl; - - - KonqHistoryEntry *entry = m_history.findEntry( url ); - - if ( entry ) { // entry is now the current item - removeFromCompletion( entry->url.prettyURL(), entry->typedURL ); - - TQString urlString = entry->url.url(); - KParts::HistoryProvider::remove( urlString ); - - addToUpdateList( urlString ); - - m_history.take(); // does not delete - emit entryRemoved( entry ); - delete entry; - - if ( isSenderOfBroadcast() ) - saveHistory(); - } -} - -void KonqHistoryManager::notifyRemove( KURL::List urls, TQCString ) -{ - kdDebug(1203) << "#### Broadcast: removing list!" << endl; - - bool doSave = false; - KURL::List::Iterator it = urls.begin(); - while ( it != urls.end() ) { - KonqHistoryEntry *entry = m_history.findEntry( *it ); - - if ( entry ) { // entry is now the current item - removeFromCompletion( entry->url.prettyURL(), entry->typedURL ); - - TQString urlString = entry->url.url(); - KParts::HistoryProvider::remove( urlString ); - - addToUpdateList( urlString ); - - m_history.take(); // does not delete - emit entryRemoved( entry ); - delete entry; - doSave = true; - } - - ++it; - } - - if (doSave && isSenderOfBroadcast()) - saveHistory(); -} - - -// compatibility fallback, try to load the old completion history -bool KonqHistoryManager::loadFallback() -{ - TQString file = locateLocal( "config", TQString::fromLatin1("konq_history")); - if ( file.isEmpty() ) - return false; - - KonqHistoryEntry *entry; - KSimpleConfig config( file ); - config.setGroup("History"); - TQStringList items = config.readListEntry( "CompletionItems" ); - TQStringList::Iterator it = items.begin(); - - while ( it != items.end() ) { - entry = createFallbackEntry( *it ); - if ( entry ) { - m_history.append( entry ); - addToCompletion( entry->url.prettyURL(), TQString::null, entry->numberOfTimesVisited ); - - KParts::HistoryProvider::insert( entry->url.url() ); - } - ++it; - } - - m_history.sort(); - adjustSize(); - saveHistory(); - - return true; -} - -// tries to create a small KonqHistoryEntry out of a string, where the string -// looks like "http://www.bla.com/bla.html:23" -// the attached :23 is the weighting from TDECompletion -KonqHistoryEntry * KonqHistoryManager::createFallbackEntry(const TQString& item) const -{ - // code taken from TDECompletion::addItem(), adjusted to use weight = 1 - uint len = item.length(); - uint weight = 1; - - // find out the weighting of this item (appended to the string as ":num") - int index = item.findRev(':'); - if ( index > 0 ) { - bool ok; - weight = item.mid( index + 1 ).toUInt( &ok ); - if ( !ok ) - weight = 1; - - len = index; // only insert until the ':' - } - - - KonqHistoryEntry *entry = 0L; - KURL u( item.left( len )); - if ( u.isValid() ) { - entry = new KonqHistoryEntry; - // that's the only entries we know about... - entry->url = u; - entry->numberOfTimesVisited = weight; - // to make it not expire immediately... - entry->lastVisited = TQDateTime::currentDateTime(); - } - - return entry; -} - -KonqHistoryEntry * KonqHistoryManager::findEntry( const KURL& url ) -{ - // small optimization (dict lookup) for items _not_ in our history - if ( !KParts::HistoryProvider::contains( url.url() ) ) - return 0L; - - return m_history.findEntry( url ); -} - -bool KonqHistoryManager::filterOut( const KURL& url ) -{ - return ( url.isLocalFile() || url.host().isEmpty() ); -} - -void KonqHistoryManager::slotEmitUpdated() -{ - emit KParts::HistoryProvider::updated( m_updateURLs ); - m_updateURLs.clear(); -} - -TQStringList KonqHistoryManager::allURLs() const -{ - TQStringList list; - KonqHistoryIterator it ( m_history ); - for ( ; it.current(); ++it ) - list.append( it.current()->url.url() ); - - return list; -} - -void KonqHistoryManager::addToCompletion( const TQString& url, const TQString& typedURL, - int numberOfTimesVisited ) -{ - m_pCompletion->addItem( url, numberOfTimesVisited ); - // typed urls have a higher priority - m_pCompletion->addItem( typedURL, numberOfTimesVisited +10 ); -} - -void KonqHistoryManager::removeFromCompletion( const TQString& url, const TQString& typedURL ) -{ - m_pCompletion->removeItem( url ); - m_pCompletion->removeItem( typedURL ); -} - -////////////////////////////////////////////////////////////////// - - -KonqHistoryEntry * KonqHistoryList::findEntry( const KURL& url ) -{ - // we search backwards, probably faster to find an entry - KonqHistoryEntry *entry = last(); - while ( entry ) { - if ( entry->url == url ) - return entry; - - entry = prev(); - } - - return 0L; -} - -// sort by lastVisited date (oldest go first) -int KonqHistoryList::compareItems( TQPtrCollection::Item item1, - TQPtrCollection::Item item2 ) -{ - KonqHistoryEntry *entry1 = static_cast<KonqHistoryEntry *>( item1 ); - KonqHistoryEntry *entry2 = static_cast<KonqHistoryEntry *>( item2 ); - - if ( entry1->lastVisited > entry2->lastVisited ) - return 1; - else if ( entry1->lastVisited < entry2->lastVisited ) - return -1; - else - return 0; -} - -using namespace KParts; // for IRIX - -#include "konq_historymgr.moc" |