/*
* history.cc
*
* Copyright (c) 2002, 2003 Frerich Raabe <raabe@kde.org>
*
* 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. For licensing and distribution details, check the
* accompanying file 'COPYING'.
*/
#include "history.h"
#include <kaction.h>
#include <kapplication.h>
#include <kconfig.h>
#include <kmainwindow.h>
#include <kpopupmenu.h>
#include <kstdguiitem.h>
using namespace Barry;
Command::Command(): m_executed( false )
{
}
Command::~Command()
{
}
void Command::unexec()
{
if ( !m_executed )
return;
m_executed = false;
doUnexec();
}
void Command::exec()
{
if ( m_executed )
return;
m_executed = true;
doExec();
}
History *History::m_instance = 0;
History &History::self()
{
if ( !m_instance )
m_instance = new History;
return *m_instance;
}
History::History(): m_idx( 0 )
{
m_commands.setAutoDelete( true );
reparseConfig();
}
void History::reparseConfig()
{
KConfig *cfg = kapp->config();
m_maxEntries = cfg->readUnsignedNumEntry(
QString::fromLatin1( "History entries" ), 50 );
truncateHistory();
}
void History::truncateHistory()
{
while ( m_commands.count() > m_maxEntries )
m_commands.remove( m_commands.getFirst() );
}
void History::setupActions( KActionCollection *coll )
{
const QPair<KGuiItem, KGuiItem> backForward = KStdGuiItem::backAndForward();
m_backAction = new KToolBarPopupAction( backForward.first, ALT+Key_Left,
this, SLOT( back() ), coll, "back" );
connect( m_backAction->popupMenu(), SIGNAL( aboutToShow() ),
this, SLOT( fillBackMenu() ) );
connect( m_backAction->popupMenu(), SIGNAL( activated( int ) ),
this, SLOT( commandActivated( int ) ) );
m_backAction->setEnabled( false );
m_forwardAction = new KToolBarPopupAction( backForward.second,
ALT+Key_Right, this, SLOT( forward() ), coll, "forward" );
connect( m_forwardAction->popupMenu(), SIGNAL( aboutToShow() ),
this, SLOT( fillForwardMenu() ) );
connect( m_forwardAction->popupMenu(), SIGNAL( activated( int ) ),
this, SLOT( commandActivated( int ) ) );
m_forwardAction->setEnabled( false );
}
void History::installMenuBarHook( KMainWindow *mainWindow )
{
QPopupMenu *goMenu = dynamic_cast<QPopupMenu *>(
mainWindow->guiFactory()->container( QString::fromLatin1( "go" ),
mainWindow )
);
if ( goMenu ) {
connect( goMenu, SIGNAL( aboutToShow() ), this, SLOT( fillGoMenu() ) );
connect( goMenu, SIGNAL( activated( int ) ),
this, SLOT( commandActivated( int ) ) );
}
}
bool History::canBack() const
{
return m_idx > 0;
}
bool History::canForward() const
{
return !m_commands.isEmpty() && m_idx < m_commands.count();
}
void History::back()
{
if ( !canBack() )
return;
Command *cmd = m_commands.at( --m_idx );
Q_ASSERT( cmd );
cmd->unexec();
m_backAction->setEnabled( canBack() );
m_forwardAction->setEnabled( canForward() );
}
void History::forward()
{
if ( !canForward() )
return;
Command *cmd = m_commands.at( m_idx++ );
Q_ASSERT( cmd );
cmd->exec();
m_backAction->setEnabled( canBack() );
m_forwardAction->setEnabled( canForward() );
}
void History::registerCommand( Command *cmd )
{
m_commands.append( cmd );
truncateHistory();
m_idx = m_commands.count();
m_backAction->setEnabled( true );
}
void History::fillBackMenu()
{
QPopupMenu *menu = m_backAction->popupMenu();
menu->clear();
unsigned int i = 0;
for ( Command *cmd = m_commands.at( m_idx - 1 );
cmd && i <= 5;
cmd = m_commands.prev(), ++i )
menu->insertItem( cmd->text(), m_commands.at() );
}
void History::fillForwardMenu()
{
QPopupMenu *menu = m_forwardAction->popupMenu();
menu->clear();
unsigned int i = 0;
for ( Command *cmd = m_commands.at( m_idx );
cmd && i <= 5;
cmd = m_commands.next(), ++i )
menu->insertItem( cmd->text(), m_commands.at() );
}
void History::fillGoMenu()
{
KMainWindow *mainWindow = dynamic_cast<KMainWindow *>( kapp->mainWidget() );
Q_ASSERT( mainWindow );
QPopupMenu *goMenu = dynamic_cast<QPopupMenu *>(
mainWindow->guiFactory()->container( QString::fromLatin1( "go" ), mainWindow )
);
if ( goMenu ) {
while ( goMenu->count() > 3 )
goMenu->removeItemAt( goMenu->count() - 1 );
unsigned int i = 0;
for ( Command *cmd = m_commands.last();
cmd && i <= 10;
cmd = m_commands.prev(), ++i )
goMenu->insertItem( cmd->text(), m_commands.at() );
}
}
void History::commandActivated( int id )
{
const int origIdx = m_idx;
while ( static_cast<unsigned int>( id ) != m_idx ) {
if ( static_cast<unsigned int>( id ) > m_idx )
forward();
else
back();
}
if ( id >= origIdx )
forward();
}
#include "history.moc"
// vim:ts=4:sw=4:noet:list
syntax highlighted by Code2HTML, v. 0.9.1