2012-02-20 21:47:14 +00:00
|
|
|
/* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org>
|
2009-10-21 19:37:07 +00:00
|
|
|
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
|
|
|
|
|
|
|
#include "history.hh"
|
|
|
|
#include "config.hh"
|
|
|
|
#include "atomic_rename.hh"
|
|
|
|
#include <QFile>
|
|
|
|
|
2013-01-17 14:24:13 +00:00
|
|
|
History::History( unsigned size, unsigned maxItemLength_ ):
|
|
|
|
maxSize( size ),
|
|
|
|
maxItemLength( maxItemLength_ ),
|
|
|
|
addingEnabled( true ),
|
2017-05-05 14:39:51 +00:00
|
|
|
dirty( false ),
|
|
|
|
timerId( 0 )
|
2009-10-21 19:37:07 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-01-17 14:24:13 +00:00
|
|
|
History::History( Load, unsigned size, unsigned maxItemLength_ ):
|
|
|
|
maxSize( size ),
|
|
|
|
maxItemLength( maxItemLength_ ),
|
|
|
|
addingEnabled( true ),
|
2013-02-05 12:51:23 +00:00
|
|
|
dirty( false ),
|
|
|
|
timerId( 0 )
|
2009-10-21 19:37:07 +00:00
|
|
|
{
|
|
|
|
QFile file( Config::getHistoryFileName() );
|
|
|
|
|
|
|
|
if ( !file.open( QFile::ReadOnly | QIODevice::Text ) )
|
|
|
|
return; // No file -- no history
|
|
|
|
|
|
|
|
for ( unsigned count = 0; count < maxSize; ++count ) {
|
|
|
|
QByteArray lineUtf8 = file.readLine( 4096 );
|
|
|
|
|
|
|
|
if ( lineUtf8.endsWith( '\n' ) )
|
|
|
|
lineUtf8.chop( 1 );
|
|
|
|
|
2012-09-10 13:01:04 +00:00
|
|
|
if ( lineUtf8.isEmpty() )
|
|
|
|
break;
|
|
|
|
|
2009-10-21 19:37:07 +00:00
|
|
|
QString line = QString::fromUtf8( lineUtf8 );
|
|
|
|
|
|
|
|
int firstSpace = line.indexOf( ' ' );
|
|
|
|
|
2012-09-10 13:01:04 +00:00
|
|
|
if ( firstSpace < 0 || firstSpace + 1 == line.size() )
|
|
|
|
// No spaces or value? Bad line. End this.
|
2009-10-21 19:37:07 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
bool isNumber;
|
|
|
|
|
|
|
|
unsigned groupId = line.left( firstSpace ).toUInt( &isNumber, 10 );
|
|
|
|
|
|
|
|
if ( !isNumber )
|
|
|
|
break; // That's not right
|
|
|
|
|
|
|
|
items.push_back( Item( groupId, line.right( line.size() - firstSpace - 1 ) ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-17 09:08:53 +00:00
|
|
|
History::Item History::getItem( int index )
|
|
|
|
{
|
|
|
|
if ( index < 0 || index >= items.size() ) {
|
|
|
|
return Item();
|
|
|
|
}
|
|
|
|
return items.at( index );
|
|
|
|
}
|
|
|
|
|
2009-10-21 19:37:07 +00:00
|
|
|
void History::addItem( Item const & item )
|
|
|
|
{
|
2013-01-17 09:08:53 +00:00
|
|
|
// qDebug() << "adding item " << item.word << ", enabled=" << enabled();
|
2012-02-16 14:56:25 +00:00
|
|
|
if ( !enabled() )
|
|
|
|
return;
|
|
|
|
|
2013-01-17 14:24:13 +00:00
|
|
|
if ( (unsigned)item.word.size() > getMaxItemLength() || item.word.isEmpty() ) {
|
2009-10-21 20:50:00 +00:00
|
|
|
// The search looks bogus. Don't save it.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-10-21 19:37:07 +00:00
|
|
|
if ( items.contains( item ) )
|
|
|
|
items.removeAll( item );
|
|
|
|
|
|
|
|
// Special case: if this items differs from the previous one only by group,
|
|
|
|
// remove it too.
|
|
|
|
|
|
|
|
if ( items.size() && items.first().word == item.word )
|
|
|
|
items.pop_front();
|
|
|
|
|
|
|
|
items.push_front( item );
|
|
|
|
|
2013-01-17 09:08:53 +00:00
|
|
|
ensureSizeConstraints();
|
|
|
|
|
2013-02-05 12:51:23 +00:00
|
|
|
dirty = true;
|
|
|
|
|
2013-01-17 09:08:53 +00:00
|
|
|
emit itemsChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool History::ensureSizeConstraints()
|
|
|
|
{
|
|
|
|
bool changed = false;
|
2009-10-21 19:37:07 +00:00
|
|
|
while ( items.size() > (int)maxSize ) {
|
|
|
|
items.pop_back();
|
2013-01-17 09:08:53 +00:00
|
|
|
changed = true;
|
2013-02-05 12:51:23 +00:00
|
|
|
dirty = true;
|
2013-01-17 09:08:53 +00:00
|
|
|
}
|
2009-10-21 19:37:07 +00:00
|
|
|
|
2013-01-17 09:08:53 +00:00
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
void History::setMaxSize( unsigned maxSize_ )
|
|
|
|
{
|
|
|
|
maxSize = maxSize_;
|
|
|
|
if ( ensureSizeConstraints() ) {
|
|
|
|
emit itemsChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int History::size() const
|
|
|
|
{
|
|
|
|
return items.size();
|
2009-10-21 19:37:07 +00:00
|
|
|
}
|
|
|
|
|
2013-02-05 12:51:23 +00:00
|
|
|
bool History::save()
|
2009-10-21 19:37:07 +00:00
|
|
|
{
|
2013-02-05 12:51:23 +00:00
|
|
|
if ( !dirty )
|
|
|
|
return true;
|
|
|
|
|
2009-10-21 19:37:07 +00:00
|
|
|
QFile file( Config::getHistoryFileName() + ".tmp" );
|
|
|
|
|
|
|
|
if ( !file.open( QFile::WriteOnly | QIODevice::Text ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for ( QList< Item >::const_iterator i = items.constBegin(); i != items.constEnd(); ++i ) {
|
|
|
|
QByteArray line = i->word.toUtf8();
|
|
|
|
|
|
|
|
// Those could ruin our format, so we replace them by spaces. They shouldn't
|
|
|
|
// be there anyway.
|
|
|
|
line.replace( '\n', ' ' );
|
|
|
|
line.replace( '\r', ' ' );
|
|
|
|
|
|
|
|
line = QByteArray::number( i->groupId ) + " " + line + "\n";
|
|
|
|
|
|
|
|
if ( file.write( line ) != line.size() )
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
file.close();
|
|
|
|
|
2013-02-05 12:51:23 +00:00
|
|
|
dirty = false;
|
|
|
|
|
2009-10-21 19:37:07 +00:00
|
|
|
return renameAtomically( file.fileName(), Config::getHistoryFileName() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void History::clear()
|
|
|
|
{
|
|
|
|
items.clear();
|
2013-03-05 12:23:50 +00:00
|
|
|
dirty = true;
|
2009-10-21 19:37:07 +00:00
|
|
|
|
|
|
|
emit itemsChanged();
|
|
|
|
}
|
2013-02-05 12:51:23 +00:00
|
|
|
|
|
|
|
void History::setSaveInterval( unsigned interval )
|
|
|
|
{
|
|
|
|
if ( timerId ) {
|
|
|
|
killTimer( timerId );
|
|
|
|
timerId = 0;
|
|
|
|
}
|
|
|
|
if ( interval ) {
|
|
|
|
if ( dirty )
|
|
|
|
save();
|
|
|
|
timerId = startTimer( interval * 60000 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void History::timerEvent( QTimerEvent * ev )
|
|
|
|
{
|
|
|
|
Q_UNUSED( ev );
|
|
|
|
save();
|
|
|
|
}
|