You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
9.2 KiB
274 lines
9.2 KiB
#include <tqtoolbutton.h>
|
|
#include <tqtextbrowser.h>
|
|
#include <tqlabel.h>
|
|
#include <tdelocale.h>
|
|
#include <kiconloader.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tdetoolbar.h>
|
|
#include <tdetoolbarbutton.h>
|
|
|
|
#include <tdefileitem.h>
|
|
#include <tdefiledetailview.h>
|
|
#include <tdeapplication.h>
|
|
|
|
#include <adept/lister.h>
|
|
#include <adept/tagchooser.h>
|
|
#include <adept/packageinfo.h>
|
|
#include <adept/packagedetails.h>
|
|
#include <adept/utils.h>
|
|
#include <adept/changelog.h>
|
|
|
|
#include <fstream>
|
|
|
|
using namespace adept;
|
|
|
|
ItemChangelog* global_changelog = new ItemChangelog();
|
|
|
|
PackageDetails::PackageDetails( TQWidget *w, const char *n )
|
|
: PackageDetailsUi( w, n ),
|
|
m_thread( 0 ),
|
|
m_qtMutex( true ),
|
|
m_logicalAct( 0 ), m_removeAct( 0 ),
|
|
m_fileListRunning( false )
|
|
{
|
|
m_toolbar->setIconSize( 22 );
|
|
m_toolbar->setIconText( TDEToolBar::IconTextRight );
|
|
|
|
m_toolbar->insertButton( u8( "back" ), BBack, false, i18n( "Back" ) );
|
|
m_toolbar->insertButton( u8( "forward" ), BForward, false, i18n( "Forward" ) );
|
|
m_toolbar->insertLineSeparator();
|
|
m_toolbar->insertButton( u8( "" ), BShow, true, i18n( "Show List" ) );
|
|
|
|
m_tags->setTitle( i18n( "Assigned Tags" ) );
|
|
|
|
m_lister->setRangeProvider( this ); // wee
|
|
// m_lister->setOpenToplevel( true );
|
|
|
|
m_description->setPaper( TQBrush( colorGroup().background() ) );
|
|
|
|
connect( m_toolbar->getButton( BShow ), TQT_SIGNAL( clicked() ),
|
|
this, TQT_SIGNAL( showList() ) );
|
|
connect( m_toolbar->getButton( BBack ), TQT_SIGNAL( clicked() ),
|
|
this, TQT_SIGNAL( back() ) );
|
|
connect( m_toolbar->getButton( BForward ), TQT_SIGNAL( clicked() ),
|
|
this, TQT_SIGNAL( forward() ) );
|
|
connect( m_lister, TQT_SIGNAL( detailsRequested( Lister::Entity ) ),
|
|
this, TQT_SIGNAL( detailsRequested( Lister::Entity ) ) );
|
|
|
|
observeComponent< component::State >();
|
|
|
|
adjustFontSize( m_name, 1 );
|
|
|
|
Cache &c = cache::Global::get( m_cache );
|
|
component::Packages::iterator i = c.packages().packagesBegin();
|
|
while ( !i->hasVersion() ) ++i; // ha hum...
|
|
setPackage( *i );
|
|
}
|
|
|
|
Lister::Range PackageDetails::listerRange() {
|
|
utils::Range< entity::Relation > r = m_package.depends();
|
|
utils::VectorRange< entity::Entity > vr;
|
|
while ( r != r.end() ) {
|
|
if ( !r->targetPackages().empty() )
|
|
std::cerr << r->targetPackages()->name() << std::endl;
|
|
vr.consume( *r );
|
|
r = r.next();
|
|
}
|
|
return vr.sorted();
|
|
}
|
|
|
|
void PackageDetails::loadFileListWorker()
|
|
{
|
|
entity::Package p = m_package;
|
|
|
|
std::string fl, flfile = "/var/lib/dpkg/info/" + p.name() + ".list";
|
|
std::ifstream ifl( flfile.c_str() );
|
|
|
|
int i = 0;
|
|
kdDebug() << "PackageDetails::loadFileListWorker() entering loop" << endl;
|
|
|
|
while ( ifl.is_open() && !ifl.eof() ) {
|
|
std::string line;
|
|
getline( ifl, line );
|
|
if ( line == "/." || line == "" )
|
|
continue; // nasty evil thing go away
|
|
m_qtMutex.lock();
|
|
KURL url( "file:///" );
|
|
url.addPath( u8( line ) );
|
|
KFileItem *it = new KFileItem( url, u8( "" ), 0 );
|
|
it->setName( u8( line ) );
|
|
m_fileList->insertItem( it );
|
|
++i;
|
|
m_qtMutex.unlock();
|
|
}
|
|
kdDebug() << "PackageDetails::loadFileListWorker() leaving loop" << endl;
|
|
ifl.close();
|
|
}
|
|
|
|
void PackageDetails::notifyPreRebuild( component::Base * ) {
|
|
kdDebug() << "PackageDetails::notifyPreRebuild()" << endl;
|
|
Threads::wait();
|
|
m_logical->setEnabled( false );
|
|
m_remove->setEnabled( false );
|
|
m_logical->disconnect( TQT_SIGNAL( clicked() ) );
|
|
m_remove->disconnect( TQT_SIGNAL( clicked() ) );
|
|
delete m_logicalAct;
|
|
delete m_removeAct;
|
|
kdDebug() << "PackageDetails::notifyPreRebuild() done" << endl;
|
|
}
|
|
|
|
void PackageDetails::loadFileList() {
|
|
Cache &c = cache::Global::get( m_cache );
|
|
if ( m_fileListRunning || !c.isOpen() ) {
|
|
TQTimer::singleShot( 100, this, TQT_SLOT( loadFileList() ) );
|
|
return;
|
|
}
|
|
|
|
kdDebug() << "PackageDetails::loadFileList()" << endl;
|
|
m_fileListRunning = true;
|
|
|
|
// the following call is neccessary to invoke buildDefaultType of KMimeType
|
|
// the first time the method is called it will check for
|
|
// existence of application/octet-stream and *popup a dialog* if
|
|
// not found -- we don't want that to happen in a non-gui thread
|
|
KMimeType::defaultMimeTypePtr();
|
|
m_thread = asyncCall( std::mem_fun( &PackageDetails::loadFileListWorker ), this );
|
|
|
|
m_qtMutex.lock();
|
|
m_fileList->KFileView::clear();
|
|
c.progress().OverallProgress( 0, 0, 0, i18n( "Loading filelist..." ).ascii() );
|
|
|
|
m_qtMutex.unlock();
|
|
Threads::enqueue( m_thread, &m_qtMutex );
|
|
Threads::wait();
|
|
c.progress().Done();
|
|
m_fileListRunning = false;
|
|
kdDebug() << "PackageDetails::loadFileList() finished" << endl;
|
|
}
|
|
|
|
void PackageDetails::setPackage( cache::entity::Package p )
|
|
{
|
|
kdDebug() << "PackageDetails::setPackage()" << endl;
|
|
m_package = p.stable();
|
|
m_name->setText( TQString( "<b>" ) +
|
|
p.name( std::string( "No package" ) ) + "</b>" );
|
|
m_info->setPackage( p );
|
|
TQString l = u8( p.longDescription(
|
|
std::string( i18n( "No long description available" ).local8Bit() ) ) );
|
|
m_description->setText( TQString( "<qt>" )
|
|
+ formatLongDescription( l ) + "</qt>" );
|
|
|
|
std::string na = u8( i18n( "not available" ) );
|
|
m_tags->setTags( p.tags( entity::Package::TagSet() ) );
|
|
m_tags->openToplevel();
|
|
m_architecture->setText( labelFormat( i18n( "Architecture: " ),
|
|
p.architecture( na ) ) );
|
|
m_filename->setText( labelFormat( i18n( "Filename: " ), p.fileName( na ) ) );
|
|
m_md5->setText( labelFormat( i18n( "MD5: " ), p.md5sum( na ) ) );
|
|
m_source->setText( labelFormat( i18n( "Source Package: " ), p.source( na ) ) );
|
|
|
|
/* IF IT ISN'T KUBUNTU, DON'T SUPPORT CHANGELOGS! */
|
|
#ifdef KUBUNTU
|
|
// Lets go ahead and stick the changelog in there....
|
|
try {
|
|
global_changelog->setParent(p);
|
|
m_changelog->setText(i18n("Loading..."));
|
|
connect(dynamic_cast<TQObject*>(global_changelog), TQT_SIGNAL( changelogReady(TQString) ),
|
|
dynamic_cast<TQObject*>(this), TQT_SLOT( changelogDisplay(TQString) ));
|
|
connect(dynamic_cast<TQObject*>(this), TQT_SIGNAL( requestTheChangelog() ),
|
|
dynamic_cast<TQObject*>(global_changelog), TQT_SIGNAL( changelogNeeded() ));
|
|
emit requestTheChangelog();
|
|
} catch (...) {};
|
|
#endif /* KUBUNTU */
|
|
|
|
notifyPostChange( 0 );
|
|
m_lister->cleanRebuild();
|
|
loadFileList();
|
|
}
|
|
|
|
void PackageDetails::changelogDisplay( TQString content ) {
|
|
m_changelog->setText(content);
|
|
}
|
|
|
|
void PackageDetails::notifyPostChange( cache::component::Base * )
|
|
{
|
|
kdDebug() << "PackageDetails::notifyPostChange()" << endl;
|
|
// without the timer to break it, there could be a loop where
|
|
// we connect the clicked() signal to a slot which would be
|
|
// invoked right away when we return -> evil
|
|
TQTimer::singleShot( 0, this, TQT_SLOT( updateLogical() ) );
|
|
}
|
|
|
|
void PackageDetails::notifyPostRebuild( cache::component::Base *b )
|
|
{
|
|
kdDebug() << "PackageDetails::notifyPostRebuild( " << b << " )" << endl;
|
|
// can't call directly because stable entities are not guaranteed
|
|
// to be stabilised at this point yet
|
|
TQTimer::singleShot( 0, this, TQT_SLOT( updateLogical() ) );
|
|
TQTimer::singleShot( 0, this, TQT_SLOT( loadFileList() ) );
|
|
m_lister->cleanRebuild();
|
|
}
|
|
|
|
void PackageDetails::updateLogical()
|
|
{
|
|
Cache &c = cache::Global::get( m_cache );
|
|
if ( !c.isOpen() ) {
|
|
TQTimer::singleShot( 100, this, TQT_SLOT( updateLogical() ) );
|
|
return;
|
|
}
|
|
kdDebug() << "PackageDetails::updateLogical()" << endl;
|
|
entity::Package p = m_package;
|
|
kdDebug() << "PackageDetails::updateLogical: p = " << p.name()
|
|
<< " p.component() = " << &p.component() << endl;
|
|
if ( !p.valid() ) return; // nothing to update
|
|
EntityActor *a = 0, *b = 0;
|
|
|
|
if ( p.canUpgrade() ) {
|
|
a = new EntityActor( p.upgrade() );
|
|
} else if ( p.canInstall() ) {
|
|
a = new EntityActor( p.install() );
|
|
} else if ( p.canKeep() ) {
|
|
a = new EntityActor( p.keep() );
|
|
}
|
|
|
|
if ( p.canRemove() ) {
|
|
b = new EntityActor( p.remove() );
|
|
}
|
|
|
|
if ( a ) {
|
|
m_logical->setEnabled( true );
|
|
m_logical->setText( u8( a->actor().prettyName() ) );
|
|
connect( m_logical, TQT_SIGNAL( clicked() ),
|
|
a, TQT_SLOT( destructiveAct() ) );
|
|
} else {
|
|
m_logical->setText( i18n( "Install" ) );
|
|
m_logical->setEnabled( false );
|
|
}
|
|
|
|
if ( b ) {
|
|
m_remove->setEnabled( true );
|
|
m_remove->setText( u8( b->actor().prettyName() ) );
|
|
connect( m_remove, TQT_SIGNAL( clicked() ),
|
|
b, TQT_SLOT( destructiveAct() ) );
|
|
} else {
|
|
m_remove->setText( i18n( "Remove" ) );
|
|
m_remove->setEnabled( false );
|
|
}
|
|
|
|
m_logicalAct = a;
|
|
m_removeAct = b;
|
|
// std::copy( r, r.last(), vr );
|
|
|
|
// r.consume( utils::upcastRange< entity::Entity >( p.depends() ) );
|
|
}
|
|
|
|
void PackageDetails::setHasForward( bool e ) {
|
|
m_toolbar->setItemEnabled( BForward, e );
|
|
// m_forward->setEnabled( e );
|
|
}
|
|
|
|
void PackageDetails::setHasBack( bool e ) {
|
|
m_toolbar->setItemEnabled( BBack, e );
|
|
// m_back->setEnabled( e );
|
|
}
|