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

app.cpp

#include <qvbox.h>
#include <qlabel.h>
#include <qpopupmenu.h>
#include <qsplitter.h>
#include <qtimer.h>
#include <qwidgetstack.h>

#include <kpushbutton.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kaction.h>
#include <kactionclasses.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kparts/part.h>
#include <ktrader.h>
#include <klibloader.h>
#include <kstatusbar.h>
#include <kstandarddirs.h>

#include <apt-pkg/packagemanager.h>
#include <apt-front/manager.h>
#include <apt-front/init.h>
#include <apt-front/cache/entity/package.h>
#include <apt-front/cache/component/state.h>
#include <apt-front/cache/component/desktop.h>
#include <apt-front/cache/component/history.h>
#include <apt-front/predicate/factory.h>

#include <adept/acqprogresswidget.h>
#include <adept/desktoplist.h>
#include <adept/utils.h>

#include "app.h"

#include <adept/dpkgpm-gui.h> // EVIL

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

std::string GroupPolicy::groupForCategories( Range< std::string > r ) {
    /* std::cerr << "groupForCategories: ";
    for ( Range< std::string > i = r; i != i.end(); ++i ) {
        std::cerr << *i << " ";
    }
    std::cerr << std::endl; */
    for ( Range< std::string > i = r; i != i.end(); ++i ) {
        if ( i->find( "X-KDE-settings" ) != std::string::npos )
            return "Settings";
        if ( i->find( "X-KDE-information" ) != std::string::npos )
            return "Settings";
    }
    if ( r.contains( "Development" ) ) return "Development";
    if ( !r.contains( "Education" ) ) {
        if ( r.contains( "Astronomy" ) || r.contains( "Biology" )
             || r.contains( "Chemistry" ) || r.contains( "Geology" )
             || r.contains( "MedicalSoftware" ) || r.contains( "Physics" )
             || r.contains( "Math" ) || r.contains( "Science" ) )
            return "Science";
    } else {
        return "Edutainment";
    }
    if ( r.contains( "Game" ) ) return "Games";
    if ( r.contains( "Graphics" ) ) return "Graphics";
    if ( r.contains( "Network" ) ) return "Internet";
    if ( r.contains( "AudioVideo" ) ) return "Multimedia";
    if ( r.contains( "Office" ) ) return "Office";
    if ( r.contains( "Settings" ) ) return "Settings";
    if ( r.contains( "System" ) ) return "System";
    if ( r.contains( "Utility" ) ) {
        if ( r.contains( "Accessibility" ) )
            return "Accessibility";
        return "Utilities";
    }
    return "Others";
}

QString IconPolicy::iconForGroup( QString g ) {
    if ( g == u8( "Office" ) ) return u8( "package_wordprocessing" );
    if ( g == u8( "Internet" ) ) return u8( "package_network" );
    if ( g == u8( "Science" ) ) return u8( "edu_science" );
    if ( g == u8( "Others" ) ) return u8( "package" );
    return QString( "package_" ) + g.lower();
}

void WaitForLister::waiting()
{
    kdDebug() << "WaitForLister::waiting()" << endl;
    /* if (app->m_list->lister()->busy())
        QTimer::singleShot( 100, this, SLOT( waiting() ) );
        else */ {
        QTimer::singleShot( 0, app, slot );
        deleteLater();
    }
}

App::App() {

    m_all = new QVBox( this );
    m_stack = new QWidgetStack( m_all );

    m_stack->addWidget( m_loading = new QLabel( i18n( "Loading, please wait..." ), m_stack ) );
    m_loading->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );

    m_buttons = new QHBox( m_all );
    QLabel *space = new QLabel( m_buttons ); // spacing
    m_next = new KPushButton( i18n( "Next" ), m_buttons );
    m_quit = new KPushButton( i18n( "Quit" ), m_buttons );
    m_next->setEnabled( false );
    m_quit->setEnabled( false );

    m_buttons->setSpacing( 2 );
    m_buttons->setMargin( 2 );
    QSizePolicy buttons( QSizePolicy::Preferred, QSizePolicy::Fixed, false );
    m_buttons->setSizePolicy( buttons );
    m_next->setSizePolicy( buttons );
    m_quit->setSizePolicy( buttons );
    space->setSizePolicy( QSizePolicy(
                               QSizePolicy::Expanding,
                               QSizePolicy::Fixed, false ) );

    setStandardToolBarMenuEnabled( false );
    createStandardStatusBarAction();
    setupActions();
    setupGUI( Keys|StatusBar|Save|Create );
    delete toolBar();

    Application::setStatusBar( statusBar() );

    QTimer::singleShot(
        0, this,
        SLOT( delayed() ) );

    setCentralWidget( m_all );
    setMinimumSize( 400, 300 );
}

void App::delayed() {

    initialize();
    cache().addComponent( new component::Desktop() );
    KGlobal::dirs()->addResourceDir(
        "desktopicon",
        u8( INSTALLER_DATA "/icons/" ) );

    cache().component< component::Desktop >().setPolicy( new GroupPolicy() );
    cache().component< component::Desktop >().loadDirectory(
        INSTALLER_DATA "/desktop/" );

    connect( m_quit, SIGNAL( clicked() ), this, SLOT( close() ) );
    m_quit->setEnabled( true );

    m_stack->addWidget( m_view = new InstallerView( m_stack ) );
    connect( m_view->selector(), SIGNAL( request( cache::entity::Package,
                                                 cache::component::State::Action ) ),
             this, SLOT( request( cache::entity::Package,
                                  cache::component::State::Action ) ) );
    m_stack->addWidget( m_preview = new View( m_stack ) );
    m_preview->setPreviewMode();
    m_view->selector()->setPolicy( new IconPolicy() );

    m_stack->addWidget(
        m_bye = new QLabel( i18n( "Installation Complete!" ), m_stack ) );
    m_bye->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );

    m_stack->addWidget( m_progress = new adept::AcqProgressWidget( m_stack ) );
    m_stack->addWidget( m_commitProgress = new CommitProgress( m_stack ) );

    m_stack->raiseWidget( m_view );

    statusBar()->clear();
    m_view->rebuild();
    start();
}

bool App::confirmRequest( entity::Package p, component::State::Action a )
{
    component::Desktop &d = cache::Global::get().component< component::Desktop >();
    typedef predicate::AttributeAdaptor< entity::Desktop,
        predicate::match::Exact< entity::Package > > Adaptor;

    QString t;

    if ( a == component::State::ARemove )
        t = i18n( "You selected to remove a program. Following applications "
                  "are part of the same package, and they will be removed."
                  " Are you sure you want to remove? " );
    else
        return true;
    // create modal dialog for the question
    KDialogBase *db = new KDialogBase( KDialogBase::Plain, i18n( "Confirm action" ),
                                       KDialogBase::Ok | KDialogBase::Cancel,
                                       KDialogBase::Ok, this );
    QVBoxLayout *layout = new QVBoxLayout( db->plainPage() );
    layout->setSpacing( 4 );
    // db->plainPage()->setLayout( layout = new QVBoxLayout( db->plainPage() ) );
    // QVBox *vb = new QVBox( db );
    QLabel *txt = new QLabel( db->plainPage() );
    txt->setAlignment( Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak );
    txt->setMinimumWidth( 500 );
    txt->setText( t );
    txt->setFixedHeight( txt->heightForWidth( 320 ) );
    txt->setSizePolicy( QSizePolicy(
                            QSizePolicy::Expanding, QSizePolicy::Fixed, false ) );
    DesktopList *l = new DesktopList( db->plainPage() );
    l->setMinimumHeight( 220 );
    l->setMinimumWidth( 320 );
    l->setDisplayCheckboxes( false );
    layout->addWidget( txt );
    layout->addWidget( l );
    l->insertRange( filteredRange( d.entries(),
                                   Adaptor( &entity::Desktop::package, p ) ) );
    db->adjustSize();
    connect( db, SIGNAL( okClicked() ), this, SLOT( requestOk() ) );
    m_currentRequestOk = false;
    db->exec();
    return m_currentRequestOk;
}

void App::request( entity::Package p, component::State::Action a ) {
    if ( !confirmRequest( p, a ) ) return;
    RequestList::iterator rm = m_requests.end(), i;
    for ( i = m_requests.begin(); i != m_requests.end(); ++i ) {
        if ( i->first == p ) {
            rm = i;
            break;
        }
    }
    if ( rm != m_requests.end() )
        m_requests.erase( rm );
    if ( a != component::State::AKeep )
        m_requests.push_back( std::make_pair( p, a ) );
    cache::Global::get().state().revert();
    cache::Global::get().state().replay( range( m_requests.begin(),
                                                m_requests.end() ) );
}

bool App::consistent() {
    int remove = 0;
    RequestList::iterator i;
    for ( i = m_requests.begin(); i != m_requests.end(); ++i ) {
        if ( i->second == component::State::ARemove ) {
            ++remove;
        }
    }
    if ( remove >= cache::Global::get().state().removeCount() )
        return true;
    return false;
}

void App::setupActions()
{
    KStdAction::quit( kapp, SLOT( quit() ), actionCollection() );
    m_undo = KStdAction::undo( this, SLOT( undo() ), actionCollection() );
    m_redo = KStdAction::redo( this, SLOT( redo() ), actionCollection() );
    m_previewAction = new KToggleAction(
        i18n( "Review Changes" ), u8( "adept_preview" ),
        0, this, SLOT( togglePreview() ), actionCollection(),
        "review" );

    setHistoryEnabled( false );
    createStandardStatusBarAction();
}

void App::togglePreview()
{
    if ( m_state == Preview ) {
        m_previewAction->setChecked( false );
        setState( Select );
        m_stack->raiseWidget( m_view );
        notifyPostChange( 0 );
    } else {
        setState( Preview );
        m_stack->raiseWidget( m_preview );
        setNext( i18n( "Back to Program Selection" ), SLOT( togglePreview() ) );
        m_previewAction->setChecked( true );
        m_preview->lister()->scheduleRebuild();
    }
}

void App::inspect()
{
    m_state = Inspect;
    m_stack->raiseWidget( m_preview );
    setNext( i18n( "Changes are OK, proceed" ), SLOT( commit() ) );
    m_preview->lister()->scheduleRebuild();
}

void App::setHistoryEnabled( bool e ) {
    if ( e && history() ) {
        m_undo->setEnabled( history()->canUndo() );
        m_redo->setEnabled( history()->canRedo() );
    } else {
        m_undo->setEnabled( false );
        m_redo->setEnabled( false );
    }
}

void App::notifyPreRebuild( component::Base *b )
{
    m_requests.clear();
}

void App::notifyPreChange( component::Base *b )
{
    Application::notifyPreChange( b );
    checkpoint();
}

void App::notifyPostChange( component::Base *b )
{
    Application::notifyPostChange( b );

    if ( m_state == Select ) {
        if ( cache().state().changed() )
            if ( consistent() )
                setNext( i18n( "Apply Changes" ), SLOT( commit() ) );
            else
                setNext( i18n( "Inspect Changes" ), SLOT( inspect() ) );
        else
            disableNext();
    }
}

void App::setNext( QString s, const char *slot ) {
    m_next->setText( s );
    m_next->setEnabled( true );
    m_next->disconnect( this );
    connect( m_next, SIGNAL( clicked() ),
             this, slot );
    m_quit->setEnabled( true );
}

void App::disableNext() {
    m_next->setText( i18n( "Next" ) );
    m_next->setEnabled( false );
    disconnect( m_next, SIGNAL( clicked() ), 0, 0 );
}

void App::disableButtons() {
    disableNext();
    m_quit->setEnabled( false );
}

void App::start() {
    m_stack->raiseWidget( m_view );
    m_quit->setText( i18n( "Forget Changes and Quit" ) );
    disableNext();
    setState( Select );
    notifyPostChange( 0 );
}

void App::commit() {
    kdDebug() << "App::commit" << endl;
    setState( Commit );
    disableButtons();
    setHistoryEnabled( false );

    aptFront::Manager m;
    m.setProgressCallback( m_progress->callback() );
    m.setUpdateInterval( 100000 );
    try {
        m_stack->raiseWidget( m_progress );
        m.download();
        m_stack->raiseWidget( m_commitProgress );
        m.commit();
    } catch ( exception::OperationCancelled ) {
        return start();
    } catch ( ... ) {
        KMessageBox::sorry(
            this, i18n( "There was an error commiting changes. "
                        "Possibly there was a problem downloading some "
                        "packages or the commit would break packages. " ),
            i18n( "Could not commit changes" ) );
    }

    cache().addComponent( new component::Desktop() );
    cache().component< component::Desktop >().setPolicy( new GroupPolicy() );
    cache().component< component::Desktop >().loadDirectory(
        INSTALLER_DATA "/desktop/" );
    QTimer::singleShot( 500, m_view, SLOT( rebuild() ) );

    m_stack->raiseWidget( m_bye );
    m_quit->setText( i18n( "Quit" ) );
    setNext( i18n( "Back to Program Selection" ), SLOT( start() ) );
    // setNext( i18n( "Done: Quit" ), SLOT( close() ) );
}

#include "app.moc"

Generated by  Doxygen 1.6.0   Back to index