/* * history.cc * * Copyright (c) 2002, 2003 Frerich Raabe * * 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 #include #include #include #include #include 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 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( 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( kapp->mainWidget() ); Q_ASSERT( mainWindow ); QPopupMenu *goMenu = dynamic_cast( 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( id ) != m_idx ) { if ( static_cast( id ) > m_idx ) forward(); else back(); } if ( id >= origIdx ) forward(); } #include "history.moc" // vim:ts=4:sw=4:noet:list