//Author: Max Howell , (C) 2003-4 //Copyright: See COPYING file that comes with this distribution #include "Config.h" #include "debug.h" #include "define.h" #include "fileTree.h" #include "part.h" #include "progressBox.h" #include "radialMap/widget.h" #include "scan.h" #include "settingsDialog.h" #include "summaryWidget.h" #include //::createAboutData() #include #include #include //::start() //#include #include #include #include #include //encodeName() #include //postInit() hack #include #include //access() namespace Filelight { typedef KParts::GenericFactory Factory; K_EXPORT_COMPONENT_FACTORY( libfilelight, Filelight::Factory ) BrowserExtension::BrowserExtension( Part *parent, const char *name ) : KParts::BrowserExtension( parent, name ) {} Part::Part( TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList& ) : ReadOnlyPart( parent, name ) , m_ext( new BrowserExtension( this ) ) , m_statusbar( new StatusBarExtension( this ) ) , m_map( 0 ) , m_manager( new ScanManager( this ) ) , m_started( false ) { TQPixmap::setDefaultOptimization( TQPixmap::BestOptim ); Config::read(); setInstance( Factory::instance() ); setWidget( new TQVBox( parentWidget, widgetName ) ); setXMLFile( "filelight_partui.rc" ); m_map = new RadialMap::Widget( widget() ); m_map->hide(); KStdAction::zoomIn( TQT_TQOBJECT(m_map), TQT_SLOT(zoomIn()), actionCollection() ); KStdAction::zoomOut( TQT_TQOBJECT(m_map), TQT_SLOT(zoomOut()), actionCollection() ); KStdAction::preferences( this, TQT_SLOT(configFilelight()), actionCollection(), "configure_filelight" )->setText( i18n( "Configure Filelight..." ) ); connect( m_map, TQT_SIGNAL(created( const Directory* )), TQT_SIGNAL(completed()) ); connect( m_map, TQT_SIGNAL(created( const Directory* )), TQT_SLOT(mapChanged( const Directory* )) ); connect( m_map, TQT_SIGNAL(activated( const KURL& )), TQT_SLOT(updateURL( const KURL& )) ); // TODO make better system connect( m_map, TQT_SIGNAL(giveMeTreeFor( const KURL& )), TQT_SLOT(updateURL( const KURL& )) ); connect( m_map, TQT_SIGNAL(giveMeTreeFor( const KURL& )), TQT_SLOT(openURL( const KURL& )) ); connect( m_manager, TQT_SIGNAL(completed( Directory* )), TQT_SLOT(scanCompleted( Directory* )) ); connect( m_manager, TQT_SIGNAL(aboutToEmptyCache()), m_map, TQT_SLOT(invalidate()) ); TQTimer::singleShot( 0, this, TQT_SLOT(postInit()) ); } void Part::postInit() { if( m_url.isEmpty() ) //if url is not empty openURL() has been called immediately after ctor, which happens { TQWidget *summary = new SummaryWidget( widget(), "summaryWidget" ); connect( summary, TQT_SIGNAL(activated( const KURL& )), TQT_SLOT(openURL( const KURL& )) ); summary->show(); //FIXME KXMLGUI is b0rked, it should allow us to set this //BEFORE createGUI is called but it doesn't stateChanged( "scan_failed" ); } } bool Part::openURL( const KURL &u ) { //we don't want to be using the summary screen anymore delete widget()->child( "summaryWidget" ); m_map->show(); //TODO everyone hates dialogs, instead render the text in big fonts on the Map //TODO should have an empty KURL until scan is confirmed successful //TODO probably should set caption to TQString() while map is unusable #define KMSG( s ) KMessageBox::information( widget(), s ) KURL url = u; url.cleanPath( true ); const TQString path = url.path( 1 ); const TQCString path8bit = TQFile::encodeName( path ); const bool isLocal = url.protocol() == "file"; if( url.isEmpty() ) { //do nothing, chances are the user accidently pressed ENTER } else if( !url.isValid() ) { KMSG( i18n( "The entered URL cannot be parsed; it is invalid." ) ); } else if( path[0] != '/' ) { KMSG( i18n( "Filelight only accepts absolute paths, eg. /%1" ).arg( path ) ); } else if( isLocal && access( path8bit, F_OK ) != 0 ) //stat( path, &statbuf ) == 0 { KMSG( i18n( "Directory not found: %1" ).arg( path ) ); } else if( isLocal && access( path8bit, R_OK | X_OK ) != 0 ) { KMSG( i18n( "Unable to enter: %1\nYou do not have access rights to this location." ).arg( path ) ); } else { if( url == m_url ) m_manager->emptyCache(); //same as rescan() return start( url ); } return false; } bool Part::closeURL() { if( m_manager->abort() ) statusBar()->message( i18n( "Aborting Scan..." ) ); m_url = KURL(); return true; } void Part::updateURL( const KURL &u ) { //the map has changed internally, update the interface to reflect this emit m_ext->openURLNotify(); //must be done first emit m_ext->setLocationBarURL( u.prettyURL() ); //do this last, or it breaks Konqi location bar m_url = u; } void Part::configFilelight() { TQWidget *dialog = new SettingsDialog( widget(), "settings_dialog" ); connect( dialog, TQT_SIGNAL(canvasIsDirty( int )), m_map, TQT_SLOT(refresh( int )) ); connect( dialog, TQT_SIGNAL(mapIsInvalid()), m_manager, TQT_SLOT(emptyCache()) ); dialog->show(); //deletes itself } TDEAboutData* Part::createAboutData() { return new TDEAboutData( APP_NAME, I18N_NOOP( APP_PRETTYNAME ), APP_VERSION ); } bool Part::start( const KURL &url ) { if( !m_started ) { m_statusbar->addStatusBarItem( new ProgressBox( statusBar(), this ), 0, true ); connect( m_map, TQT_SIGNAL(mouseHover( const TQString& )), statusBar(), TQT_SLOT(message( const TQString& )) ); connect( m_map, TQT_SIGNAL(created( const Directory* )), statusBar(), TQT_SLOT(clear()) ); m_started = true; } if( m_manager->start( url ) ) { m_url = url; const TQString s = i18n( "Scanning: %1" ).arg( prettyURL() ); stateChanged( "scan_started" ); emit started( 0 ); //as a Part, we have to do this emit setWindowCaption( s ); statusBar()->message( s ); m_map->invalidate(); //to maintain ui consistency return true; } return false; } void Part::rescan() { //FIXME we have to empty the cache because otherwise rescan picks up the old tree.. m_manager->emptyCache(); //causes canvas to invalidate start( m_url ); } void Part::scanCompleted( Directory *tree ) { if( tree ) { statusBar()->message( i18n( "Scan completed, generating map..." ) ); m_map->create( tree ); //do after creating map stateChanged( "scan_complete" ); } else { stateChanged( "scan_failed" ); emit canceled( i18n( "Scan failed: %1" ).arg( prettyURL() ) ); emit setWindowCaption( TQString() ); statusBar()->clear(); // TQTimer::singleShot( 2000, statusBar(), TQT_SLOT(clear()) ); m_url = KURL(); } } void Part::mapChanged( const Directory *tree ) { //IMPORTANT -> m_url has already been set emit setWindowCaption( prettyURL() ); ProgressBox *progress = static_cast(TQT_TQWIDGET(statusBar()->child( "ProgressBox" ))); if( progress ) progress->setText( tree->children() ); } } //namespace Filelight #include "part.moc"