Logo Search packages:      
Sourcecode: adept version File versions  Download package

app.cpp

#include <unistd.h>
#include <sys/stat.h>
#include <qtooltip.h>
#include <qtimer.h>

#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kglobalaccel.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kiconloader.h>
#include <kaboutapplication.h>
#include <kaction.h>
#include <kpopupmenu.h>
#include <kconfig.h>

#include <apt-front/init.h>
#include <apt-front/cache/cache.h>
#include <apt-front/cache/component/packages.h>
#include <apt-front/predicate/factory.h>

#include <adept/utils.h>

#include "app.h"

using namespace aptFront;
using namespace cache;
using namespace utils;
using namespace adept;

TrayWindow::TrayWindow(QWidget *parent, const char *name)
    : KSystemTray(parent, name), m_updates( 0 )
{
    setAvailableUpdates( m_updates );
    // actionCollection()->remove( actionCollection()->action( "quit" ) );
    m_quit = KStdAction::quit( this, SIGNAL( quitSelected() ), actionCollection() );
    m_about = KStdAction::aboutApp( this, SIGNAL( aboutSelected() ), actionCollection() );
    // setPixmap( loadIcon( u8( "adept_notifier_warning" ) ) );
}

void TrayWindow::contextMenuAboutToShow( KPopupMenu *r ) {
    kdDebug() << "TrayWindow::contextMenu()" << endl;
    r->clear();
    m_about->plug( r );
    m_quit->plug( r );
}

void TrayWindow::setAvailableUpdates( int n )
{
    m_updates = n;
    kdDebug() << "TrayWindow obtained " << n << endl;

    setPixmap( m_updates == 0 ?
               loadIcon( u8( "adept_notifier_ok" ) ) :
               loadIcon( u8( "adept_notifier_warning" ) ) );

    if ( m_updates == 0 )
        hide();
    else
        show();

    QToolTip::remove(this);
    QToolTip::add(this, n == 0 ? i18n( "No updates needed." )
                  : i18n( "There is %n updated package available",
                          "There are %n updated packages available", n ) );
}

void TrayWindow::mouseReleaseEvent(QMouseEvent *ev)
{
    if (ev->button() == QMouseEvent::LeftButton)
        emit clicked();
    KSystemTray::mouseReleaseEvent(ev);
}

NotifierApp::NotifierApp(bool allowStyles, bool GUIenabled)
    : KUniqueApplication(allowStyles, GUIenabled),
      m_tray( 0 )
{
    sharedConfig()->setGroup( "General" );
    m_okAutostart = sharedConfig()->readBoolEntry( "Autostart", true );
    m_timer = new QTimer( this );
    m_tray = new TrayWindow( 0, 0 );
    m_tray->show();

    aptFront::init();

    fileUpdated( "/var/cache/apt/pkglist.bin", m_updateStamp );
    // fileUpdated( "/var/lib/apt/periodic/update-stamp", m_updateStamp );
    fileUpdated( "/var/lib/dpkg/status", m_statusStamp );

    m_tray->setAvailableUpdates( upgradable() );

    connect( m_tray, SIGNAL( clicked() ), this, SLOT( clicked() ) );
    // connect( m_tray, SIGNAL( quitSelected() ), this, SLOT( quit() ) );
    connect( m_tray, SIGNAL( quitSelected() ), this, SLOT( askQuit() ) );
    connect( m_tray, SIGNAL( aboutSelected() ), this, SLOT( about() ) );
    connect( m_timer, SIGNAL( timeout() ), this, SLOT( checkUpdates() ) );
    m_timer->start( 1000*5 ); // 5 secs now, used to be 60
    if ( !m_okAutostart ) {
        int r = KMessageBox::questionYesNo(
            m_tray, i18n( "You disabled automatic startup of Adept Notifier last time "
                        "you quit the application. "
                        "Do you want to start Adept Notifier next time you log in?" ),
            i18n( "Automatic Startup" ),
            KGuiItem( i18n( "Start" ) ), KGuiItem( i18n( "Don't Start" ) ),
            u8( "enableAutostart" ) );
        if ( r == KMessageBox::Yes ) {
            sharedConfig()->setGroup( "General" );
            sharedConfig()->writeEntry( "Autostart", true );
            m_okAutostart = true;
        }
    }
}

void NotifierApp::askQuit() {
    if ( m_okAutostart ) {
        int r = KMessageBox::questionYesNoCancel(
            m_tray, i18n( "Do you want to start Adept Notifier next time you log in?" ),
            i18n( "Automatic Startup" ),
            KGuiItem( i18n( "Start" ) ), KGuiItem( i18n( "Don't Start" ) ) );
        if ( r == KMessageBox::Cancel )
            return;
        if ( r == KMessageBox::No ) {
            sharedConfig()->setGroup( "General" );
            sharedConfig()->writeEntry( "Autostart", false );
        }
    }
    exit( 0 );

}

bool NotifierApp::fileUpdated( const char *f, time_t &stamp ) {
    time_t old = stamp;
    struct stat s;
    ::stat( f, &s );
    stamp = s.st_mtime;
    if ( stamp > old )
        return true;
    return false;
}

int NotifierApp::upgradable() {
    try {
        kdDebug() << "checking cache for upgradable packages..." << endl;
        cache::Cache &c = cache::Global::get();
        c.open( Cache::OpenReadOnly
                | Cache::OpenPackages
                | Cache::OpenState );

        kdDebug() << "cache opened, listing..." << endl;
        Range< entity::Package > r = range( c.packages().packagesBegin(),
                                            c.packages().packagesEnd() );
        kdDebug() << "looking for upgradable packages..." << endl;
        Range< entity::Package > fr = filteredRange(
            r, predicate::Package::member( &entity::Package::isUpgradable ) );
        VectorRange< entity::Package > vr = VectorRange< entity::Package >();
        fr.output( vr );
        kdDebug() << "found " << vr.size() << " upgradable package(s)" << endl;
        int ret = vr.size();
        c.close();
        return ret;
    } catch ( exception::Error e ) {
        kdDebug() << "error checking cache for upgradable packages..." << endl;
        kdDebug() << "what: " << e.message() << endl;
    } catch ( std::exception e ) {
        kdDebug() << "exception checking cache for upgradable packages..." << endl;
        kdDebug() << "what: " << e.what() << endl;
        // XXX error handling
    }
    return true; // we don't know, so assume true (safe)
}

void NotifierApp::checkUpdates() {
    // kdDebug() << "checking updates status" << endl;
    if ( // fileUpdated( "/var/lib/apt/periodic/update-stamp", m_updateStamp )
        fileUpdated( "/var/cache/apt/pkgcache.bin", m_updateStamp )
         || fileUpdated( "/var/lib/dpkg/status", m_statusStamp ) )
        m_tray->setAvailableUpdates( upgradable() );
}

void NotifierApp::about() {
    KAboutApplication *a = new KAboutApplication( m_tray, "", true );
    a->exec();
    delete a;
}

NotifierApp::~NotifierApp()
{
    delete m_tray;
}

void NotifierApp::clicked()
{
    if ( m_tray->updates() == 0 )
        return KMessageBox::information(
            0, i18n( "There are no known updates available." ),
            i18n( "Nothing to do" ) );
    startServiceByDesktopName( u8( "adept_updater" ) );
}

/* void NotifierApp::menuActivated(int id)
{
    // implement help
} */

const char * DESCRIPTION =
  I18N_NOOP("Adept update notifier utility");

/* extern "C" KDE_EXPORT */
int main(int argc, char *argv[])
{
    KAboutData about("adept_notifier", I18N_NOOP("Adept Notifier"),
                     "2.1 Cruiser",
                     DESCRIPTION, KAboutData::License_BSD,
                     "Copyright (C) 2005, 2006 Peter Rockai");
    KCmdLineArgs::init(argc, argv, &about);
    NotifierApp::addCmdLineOptions();

    if (!NotifierApp::start())
        return 0;

    NotifierApp app;
    app.disableSessionManagement();
    app.exec();
    return 0;
}

Generated by  Doxygen 1.6.0   Back to index