diff options
Diffstat (limited to 'src/app/KViewer')
-rw-r--r-- | src/app/KViewer/Makefile.am | 11 | ||||
-rw-r--r-- | src/app/KViewer/diskusageviewer.cpp | 129 | ||||
-rw-r--r-- | src/app/KViewer/diskusageviewer.h | 69 | ||||
-rw-r--r-- | src/app/KViewer/kimagefilepreview.cpp | 136 | ||||
-rw-r--r-- | src/app/KViewer/kimagefilepreview.h | 71 | ||||
-rw-r--r-- | src/app/KViewer/krviewer.cpp | 702 | ||||
-rw-r--r-- | src/app/KViewer/krviewer.h | 130 | ||||
-rw-r--r-- | src/app/KViewer/panelviewer.cpp | 307 | ||||
-rw-r--r-- | src/app/KViewer/panelviewer.h | 91 |
9 files changed, 1646 insertions, 0 deletions
diff --git a/src/app/KViewer/Makefile.am b/src/app/KViewer/Makefile.am new file mode 100644 index 0000000..f4bf90f --- /dev/null +++ b/src/app/KViewer/Makefile.am @@ -0,0 +1,11 @@ +noinst_LIBRARIES = libKViewer.a + +INCLUDES = $(all_includes) + +libKViewer_a_METASOURCES = AUTO + +libKViewer_a_SOURCES = \ + krviewer.cpp \ + kimagefilepreview.cpp \ + panelviewer.cpp \ + diskusageviewer.cpp diff --git a/src/app/KViewer/diskusageviewer.cpp b/src/app/KViewer/diskusageviewer.cpp new file mode 100644 index 0000000..3e00283 --- /dev/null +++ b/src/app/KViewer/diskusageviewer.cpp @@ -0,0 +1,129 @@ +/*************************************************************************** + diskusageviewer.cpp - description + ------------------- + copyright : (C) 2005 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "../krusader.h" +#include "../krusaderview.h" +#include "../Panel/listpanel.h" +#include "../Panel/panelfunc.h" +#include "diskusageviewer.h" + +DiskUsageViewer::DiskUsageViewer( TQWidget *parent, char *name ) + : TQWidget( parent, name ), diskUsage( 0 ), statusLabel( 0 ) +{ + layout = new TQGridLayout( this, 1, 1 ); +} + +DiskUsageViewer::~ DiskUsageViewer() +{ + if( diskUsage ) + { + krConfig->setGroup( "DiskUsageViewer" ); + krConfig->writeEntry( "View", diskUsage->getActiveView() ); + delete diskUsage; + } +} + +void DiskUsageViewer::openURL( KURL url ) +{ + if( diskUsage == 0 ) + { + diskUsage = new DiskUsage( "DiskUsageViewer", this ); + + connect( diskUsage, TQ_SIGNAL( enteringDirectory( Directory * ) ), this, TQ_SLOT( slotUpdateStatus() ) ); + connect( diskUsage, TQ_SIGNAL( status( TQString ) ), this, TQ_SLOT( slotUpdateStatus( TQString ) ) ); + connect( diskUsage, TQ_SIGNAL( newSearch() ), this, TQ_SLOT( slotNewSearch() ) ); + layout->addWidget( diskUsage, 0, 0 ); + this->show(); + diskUsage->show(); + + krConfig->setGroup( "DiskUsageViewer" ); + int view = krConfig->readNumEntry( "View", VIEW_FILELIGHT ); + if( view < VIEW_LINES || view > VIEW_FILELIGHT ) + view = VIEW_FILELIGHT; + diskUsage->setView( view ); + } + + url.setPath( url.path( -1 ) ); + + KURL baseURL = diskUsage->getBaseURL(); + if( !diskUsage->isLoading() && !baseURL.isEmpty() ) + { + if( url.protocol() == baseURL.protocol() && ( !url.hasHost() || url.host() == baseURL.host() ) ) + { + TQString baseStr = baseURL.path( 1 ), urlStr = url.path( 1 ); + + if( urlStr.startsWith( baseStr ) ) + { + TQString relURL = urlStr.mid( baseStr.length() ); + if( relURL.endsWith( "/" ) ) + relURL.truncate( relURL.length() -1 ); + + Directory *dir = diskUsage->getDirectory( relURL ); + if( dir ) + { + diskUsage->changeDirectory( dir ); + return; + } + } + } + } + diskUsage->load( url ); +} + +void DiskUsageViewer::closeURL() +{ + if( diskUsage ) + diskUsage->close(); +} + +void DiskUsageViewer::setStatusLabel( TQLabel *statLabel, TQString pref ) +{ + statusLabel = statLabel; + prefix = pref; +} + +void DiskUsageViewer::slotUpdateStatus( TQString status ) +{ + if( statusLabel ) { + if( status.isEmpty() ) { + Directory * dir = diskUsage->getCurrentDir(); + if( dir ) + status = prefix + dir->name() + " [" + TDEIO::convertSize( dir->size() ) + "]"; + } + statusLabel->setText( status ); + } +} + +void DiskUsageViewer::slotNewSearch() +{ + diskUsage->load( ACTIVE_PANEL->func->files()->vfs_getOrigin() ); +} + +#include "diskusageviewer.moc" diff --git a/src/app/KViewer/diskusageviewer.h b/src/app/KViewer/diskusageviewer.h new file mode 100644 index 0000000..a46e123 --- /dev/null +++ b/src/app/KViewer/diskusageviewer.h @@ -0,0 +1,69 @@ +/*************************************************************************** + diskusageviewer.h - description + ------------------- + copyright : (C) 2005 by Csaba Karai + e-mail : krusader@users.sourceforge.net + web site : http://krusader.sourceforge.net + --------------------------------------------------------------------------- + Description + *************************************************************************** + + A + + db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. + 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D + 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' + 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b + 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. + YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + H e a d e r F i l e + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef DISKUSAGEVIEWER_H +#define DISKUSAGEVIEWER_H + +#include "../DiskUsage/diskusage.h" +#include <kurl.h> +#include <tqlayout.h> +#include <tqlabel.h> + +class DiskUsageViewer : public TQWidget +{ + TQ_OBJECT + + +public: + DiskUsageViewer( TQWidget *parent = 0, char *name = 0 ); + ~DiskUsageViewer(); + + void openURL( KURL url ); + void closeURL(); + void setStatusLabel( TQLabel *statLabel, TQString pref ); + + inline DiskUsage * getWidget() { return diskUsage; } + +signals: + void openURLRequest(const KURL &); + +protected slots: + void slotUpdateStatus( TQString status = TQString() ); + void slotNewSearch(); + +protected: + DiskUsage *diskUsage; + TQGridLayout *layout; + + TQLabel *statusLabel; + TQString prefix; +}; + +#endif /* DISKUSAGEVIEWER_H */ diff --git a/src/app/KViewer/kimagefilepreview.cpp b/src/app/KViewer/kimagefilepreview.cpp new file mode 100644 index 0000000..f41e061 --- /dev/null +++ b/src/app/KViewer/kimagefilepreview.cpp @@ -0,0 +1,136 @@ +/* +* This file is part of the KDE project +* Copyright (C) 2001 Martin R. Jones <mjones@kde.org> +* 2001 Carsten Pfeiffer <pfeiffer@kde.org> +* +* You can Freely distribute this program under the GNU Library General Public +* License. See the file "COPYING" for the exact licensing terms. +*/ + +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqcombobox.h> +#include <tqcheckbox.h> +#include <tqwhatsthis.h> +#include <tqtimer.h> + +#include <tdeapplication.h> +#include <tdeglobal.h> +#include <kiconloader.h> +#include <kpushbutton.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <tdelocale.h> +#include <tdefiledialog.h> +#include <tdefileitem.h> +#include <tdeio/previewjob.h> + +#include "kimagefilepreview.h" + +/**** KrusaderImageFilePreview ****/ + +KrusaderImageFilePreview::KrusaderImageFilePreview( TQWidget *parent ) + : KPreviewWidgetBase( parent ), +m_job( 0L ) { + TQVBoxLayout *vb = new TQVBoxLayout( this, KDialog::marginHint() ); + + imageLabel = new TQLabel( this ); + imageLabel->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); + imageLabel->setAlignment( TQt::AlignHCenter | TQt::AlignVCenter ); + imageLabel->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored ) ); + vb->addWidget( imageLabel, 1 ); + + timer = new TQTimer( this ); + connect( timer, TQ_SIGNAL( timeout() ), TQ_SLOT( showPreview() ) ); + + setSupportedMimeTypes( TDEIO::PreviewJob::supportedMimeTypes() ); +} + +KrusaderImageFilePreview::~KrusaderImageFilePreview() { + if ( m_job ) + m_job->kill(); +} + +void KrusaderImageFilePreview::showPreview() { + // Pass a copy since clearPreview() will clear currentURL + KURL url = currentURL; + showPreview( url, true ); +} + +// called via KPreviewWidgetBase interface +void KrusaderImageFilePreview::showPreview( const KURL& url ) { + showPreview( url, false ); +} + +void KrusaderImageFilePreview::showPreview( const KURL &url, bool force ) { + if ( !url.isValid() ) { + clearPreview(); + return ; + } + + if ( url != currentURL || force ) { + clearPreview(); + currentURL = url; + + int w = imageLabel->contentsRect().width() - 4; + int h = imageLabel->contentsRect().height() - 4; + + m_job = createJob( url, w, h ); + connect( m_job, TQ_SIGNAL( result( TDEIO::Job * ) ), + this, TQ_SLOT( slotResult( TDEIO::Job * ) ) ); + connect( m_job, TQ_SIGNAL( gotPreview( const KFileItem*, + const TQPixmap& ) ), + TQ_SLOT( gotPreview( const KFileItem*, const TQPixmap& ) ) ); + + connect( m_job, TQ_SIGNAL( failed( const KFileItem* ) ), + this, TQ_SLOT( slotFailed( const KFileItem* ) ) ); + } +} + +void KrusaderImageFilePreview::resizeEvent( TQResizeEvent * ) { + timer->start( 100, true ); // forces a new preview +} + +TQSize KrusaderImageFilePreview::sizeHint() const { + return TQSize( 20, 200 ); // otherwise it ends up huge??? +} + +TDEIO::PreviewJob * KrusaderImageFilePreview::createJob( const KURL& url, int w, int h ) { + KURL::List urls; + urls.append( url ); + return TDEIO::filePreview( urls, w, h, 0, 0, true, false ); +} + +void KrusaderImageFilePreview::gotPreview( const KFileItem* item, const TQPixmap& pm ) { + if ( item->url() == currentURL ) // should always be the case + imageLabel->setPixmap( pm ); +} + +void KrusaderImageFilePreview::slotFailed( const KFileItem* item ) { + if ( item->isDir() ) + imageLabel->clear(); + else if ( item->url() == currentURL ) // should always be the case + imageLabel->setPixmap( SmallIcon( "file_broken", TDEIcon::SizeLarge, + TDEIcon::DisabledState ) ); +} + +void KrusaderImageFilePreview::slotResult( TDEIO::Job *job ) { + if ( job == m_job ) + m_job = 0L; +} + +void KrusaderImageFilePreview::clearPreview() { + if ( m_job ) { + m_job->kill(); + m_job = 0L; + } + + imageLabel->clear(); + currentURL = KURL(); +} + +void KrusaderImageFilePreview::virtual_hook( int id, void* data ) { + KPreviewWidgetBase::virtual_hook( id, data ); +} + +#include "kimagefilepreview.moc" diff --git a/src/app/KViewer/kimagefilepreview.h b/src/app/KViewer/kimagefilepreview.h new file mode 100644 index 0000000..ada0806 --- /dev/null +++ b/src/app/KViewer/kimagefilepreview.h @@ -0,0 +1,71 @@ +/* +* +* This file is part of the KDE project. +* Copyright (C) 2001 Martin R. Jones <mjones@kde.org> +* 2001 Carsten Pfeiffer <pfeiffer@kde.org> +* +* Modified for Krusader by Shie Erlich, October 2004 +* +* You can Freely distribute this program under the GNU Library General Public +* License. See the file "COPYING" for the exact licensing terms. +*/ + +#ifndef KrusaderImageFilePreview_H +#define KrusaderImageFilePreview_H + +#include <tqpixmap.h> + +#include <kurl.h> +#include <kpreviewwidgetbase.h> + +class TQCheckBox; +class TQPushButton; +class TQLabel; +class TQTimer; + +class KFileDialog; +class KFileItem; + +class KrusaderImageFilePreview : public KPreviewWidgetBase { + TQ_OBJECT + + + public: + KrusaderImageFilePreview( TQWidget *parent ); + ~KrusaderImageFilePreview(); + + virtual TQSize sizeHint() const; + + public slots: + virtual void showPreview( const KURL &url ); + virtual void clearPreview(); + + protected slots: + void showPreview(); + void showPreview( const KURL& url, bool force ); + + virtual void gotPreview( const KFileItem*, const TQPixmap& ); + + protected: + virtual void resizeEvent( TQResizeEvent *e ); + virtual TDEIO::PreviewJob * createJob( const KURL& url, + int w, int h ); + + private slots: + void slotResult( TDEIO::Job * ); + virtual void slotFailed( const KFileItem* ); + + private: + KURL currentURL; + TQTimer *timer; + TQLabel *imageLabel; + TQLabel *infoLabel; + TDEIO::PreviewJob *m_job; + protected: + virtual void virtual_hook( int id, void* data ); + private: + class KrusaderImageFilePreviewPrivate; + KrusaderImageFilePreviewPrivate *d; +}; + +#endif // KrusaderImageFilePreview_H diff --git a/src/app/KViewer/krviewer.cpp b/src/app/KViewer/krviewer.cpp new file mode 100644 index 0000000..f6e0357 --- /dev/null +++ b/src/app/KViewer/krviewer.cpp @@ -0,0 +1,702 @@ +/*************************************************************************** + krviewer.cpp - description + ------------------- + begin : Thu Apr 18 2002 + copyright : (C) 2002 by Shie Erlich & Rafi Yanai + email : +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +// TQt includes +#include <tqdatastream.h> +#include <tqfile.h> +#include <tqpopupmenu.h> +#include <tqtimer.h> +// TDE includes +#include <tdemenubar.h> +#include <kmimetype.h> +#include <tdelocale.h> +#include <tdeparts/part.h> +#include <tdeparts/componentfactory.h> +#include <tdemessagebox.h> +#include <klibloader.h> +#include <ktrader.h> +#include <tdeio/netaccess.h> +#include <tdeio/jobclasses.h> +#include <tdeio/job.h> +#include <kstatusbar.h> +#include <kdebug.h> +#include <klargefile.h> +#include <tdehtml_part.h> +#include <kprocess.h> +#include <tdefileitem.h> +// Krusader includes +#include "krviewer.h" +#include "../krusader.h" +#include "../defaults.h" +#include "../kicons.h" + +#include "panelviewer.h" + +#define VIEW_ICON "viewmag" +#define EDIT_ICON "edit" +#define MODIFIED_ICON "document-save-as" + + +TQPtrList<KrViewer> KrViewer::viewers; + +KrViewer::KrViewer( TQWidget *parent, const char *name ) : +KParts::MainWindow( parent, name ), manager( this, this ), tabBar( this ), returnFocusTo( 0 ), returnFocusTab( 0 ), + reservedKeys(), reservedKeyIDs() { + + //setWFlags(WType_TopLevel | WDestructiveClose); + setXMLFile( "krviewer.rc" ); // kpart-related xml file + setHelpMenuEnabled( false ); + + setAutoSaveSettings( "KrViewerWindow", true ); + tmpFile.setAutoDelete( true ); + + connect( &manager, TQ_SIGNAL( activePartChanged( KParts::Part* ) ), + this, TQ_SLOT( createGUI( KParts::Part* ) ) ); + connect( &tabBar, TQ_SIGNAL( currentChanged( TQWidget *) ), + this, TQ_SLOT( tabChanged(TQWidget*) ) ); + connect( &tabBar, TQ_SIGNAL( closeRequest( TQWidget *) ), + this, TQ_SLOT( tabCloseRequest(TQWidget*) ) ); + + tabBar.setTabReorderingEnabled(false); +#if KDE_IS_VERSION(3,4,0) + tabBar.setAutomaticResizeTabs(true); +#endif +// "edit" +// "document-save-as" + setCentralWidget( &tabBar ); + + printAction = KStdAction::print( this, TQ_SLOT( print() ), 0, 0 ); + copyAction = KStdAction::copy( this, TQ_SLOT( copy() ), 0, 0 ); + + viewerMenu = new TQPopupMenu( this ); + viewerMenu->insertItem( i18n( "&Generic viewer" ), this, TQ_SLOT( viewGeneric() ), CTRL + SHIFT + Key_G, 1 ); + viewerMenu->insertItem( i18n( "&Text viewer" ), this, TQ_SLOT( viewText() ), CTRL + SHIFT + Key_T, 2 ); + viewerMenu->insertItem( i18n( "&Hex viewer" ), this, TQ_SLOT( viewHex() ), CTRL + SHIFT + Key_H, 3 ); + viewerMenu->insertSeparator(); + viewerMenu->insertItem( i18n( "Text &editor" ), this, TQ_SLOT( editText() ), CTRL + SHIFT + Key_E, 4 ); + viewerMenu->insertSeparator(); + viewerMenu->insertItem( i18n( "&Next tab" ), this, TQ_SLOT( nextTab() ), ALT+Key_Right ); + viewerMenu->insertItem( i18n( "&Previous tab" ), this, TQ_SLOT( prevTab() ), ALT+Key_Left ); + + detachActionIndex = viewerMenu->insertItem( i18n( "&Detach tab" ), this, TQ_SLOT( detachTab() ), CTRL + SHIFT + Key_D ); + //no point in detaching only one tab.. + viewerMenu->setItemEnabled(detachActionIndex,false); + viewerMenu->insertSeparator(); + viewerMenu->insertItem( printAction->text(), this, TQ_SLOT( print() ), printAction->shortcut() ); + viewerMenu->insertItem( copyAction->text(), this, TQ_SLOT( copy() ), copyAction->shortcut() ); + viewerMenu->insertSeparator(); + tabCloseID = viewerMenu->insertItem( i18n( "&Close current tab" ), this, TQ_SLOT( tabCloseRequest() ), Key_Escape ); + closeID = viewerMenu->insertItem( i18n( "&Quit" ), this, TQ_SLOT( close() ), CTRL + Key_Q ); + + //toolBar() ->insertLined("Edit:",1,"",this,"",true ,i18n("Enter an URL to edit and press enter")); + + tabBar.setHoverCloseButton(true); + + checkModified(); +} + +KrViewer::~KrViewer() { + + disconnect( &manager, TQ_SIGNAL( activePartChanged( KParts::Part* ) ), + this, TQ_SLOT( createGUI( KParts::Part* ) ) ); + + viewers.remove( this ); + delete printAction; + delete copyAction; +} + +void KrViewer::createGUI( KParts::Part* part ) { + if ( part == 0 ) /* TDEHTMLPart calls this function with 0 at destruction. */ + return ; /* Can cause crash after JavaScript self.close() if removed */ + + + // and show the new part widget + connect( part, TQ_SIGNAL( setStatusBarText( const TQString& ) ), + this, TQ_SLOT( slotSetStatusBarText( const TQString& ) ) ); + + KParts::MainWindow::createGUI( part ); + toolBar() ->insertLineSeparator(0); + + PanelViewerBase *pvb = getPanelViewerBase( part ); + if( pvb ) + updateActions( pvb ); + + toolBar() ->show(); + statusBar() ->show(); + + // the KParts part may override the viewer shortcuts. We prevent it + // by installing an event filter on the menuBar() and the part + reservedKeys.clear(); + reservedKeyIDs.clear(); + + // getting the key sequences of the viewer menu + for( unsigned w=0; w != viewerMenu->count(); w++ ) + { + int id = viewerMenu->idAt( w ); + TQKeySequence sequence = viewerMenu->accel( id ); + if( sequence.count() > 0 ) + { + reservedKeys.push_back( sequence[ 0 ] ); + reservedKeyIDs.push_back( id ); + } + } + + // and "fix" the menubar + menuBar() ->removeItem( 70 ); + menuBar() ->insertItem( i18n( "&KrViewer" ), viewerMenu, 70 ); + menuBar() ->show(); + + // filtering out the key events + menuBar() ->installEventFilter( this ); + part->installEventFilter( this ); +} + +bool KrViewer::eventFilter ( TQObject * /* watched */, TQEvent * e ) +{ + if( e->type() == TQEvent::AccelOverride ) + { + TQKeyEvent* ke = (TQKeyEvent*) e; + if( reservedKeys.contains( ke->key() ) ) + { + ke->accept(); + + int id = reservedKeyIDs[ reservedKeys.findIndex( ke->key() ) ]; + if( id != -1 ) + { + // don't activate the close functions immediately! + // it can cause crash + if( id == tabCloseID ) + TQTimer::singleShot( 0, this, TQ_SLOT( tabCloseRequest() ) ); + else if( id == closeID ) + TQTimer::singleShot( 0, this, TQ_SLOT( close() ) ); + else { + int index = viewerMenu->indexOf( id ); + viewerMenu->activateItemAt( index ); + } + } + return true; + } + } + else if( e->type() == TQEvent::KeyPress ) + { + TQKeyEvent* ke = (TQKeyEvent*) e; + if( reservedKeys.contains( ke->key() ) ) + { + ke->accept(); + return true; + } + } + return false; +} +void KrViewer::keyPressEvent( TQKeyEvent *e ) { + switch ( e->key() ) { + case Key_F10: + close(); + break; + case Key_Escape: + tabCloseRequest(); + break; + default: + e->ignore(); + break; + } +} + +KrViewer* KrViewer::getViewer(bool new_window){ + if( !new_window ){ + if( !viewers.first() ){ + viewers.prepend( new KrViewer() ); // add to first (active) + } + else { + if( viewers.first()->isMinimized() ) // minimized? -> show it again + viewers.first()->showNormal(); + viewers.first()->raise(); + viewers.first()->setActiveWindow(); + } + return viewers.first(); + } + else { + KrViewer *newViewer = new KrViewer(); + viewers.prepend( newViewer ); + return newViewer; + } +} + +void KrViewer::view( KURL url, TQWidget * parent ) { + Mode defaultMode = Generic; + bool defaultWindow = false; + + krConfig->setGroup( "General" ); + defaultWindow = krConfig->readBoolEntry( "View In Separate Window",_ViewInSeparateWindow ); + + TQString modeString = krConfig->readEntry( "Default Viewer Mode","generic" ); + + if( modeString == "generic" ) defaultMode = Generic; + else if( modeString == "text" ) defaultMode = Text; + else if( modeString == "hex" ) defaultMode = Hex; + + view(url,defaultMode,defaultWindow, parent ); +} + +void KrViewer::view( KURL url, Mode mode, bool new_window, TQWidget * parent ) { + KrViewer* viewer = getViewer(new_window); + + PanelViewerBase* viewWidget = new PanelViewer(&viewer->tabBar); + KParts::Part* part = viewWidget->openURL(url,mode); + viewer->addTab(viewWidget,i18n( "Viewing" ),VIEW_ICON,part); + + viewer->returnFocusTo = parent; + viewer->returnFocusTab = viewWidget; +} + +void KrViewer::edit( KURL url, TQWidget * parent ) { + edit( url, Text, -1, parent ); +} + +void KrViewer::edit( KURL url, Mode mode, int new_window, TQWidget * parent ) { + krConfig->setGroup( "General" ); + TQString edit = krConfig->readEntry( "Editor", _Editor ); + + if( new_window == -1 ) + new_window = krConfig->readBoolEntry( "View In Separate Window",_ViewInSeparateWindow ); + + if ( edit != "internal editor" ) { + TDEProcess proc; + // if the file is local, pass a normal path and not a url. this solves + // the problem for editors that aren't url-aware + if ( url.isLocalFile() ) + proc << TQStringList::split( ' ', edit ) << url.path(); + else proc << TQStringList::split( ' ', edit ) << url.prettyURL(); + if ( !proc.start( TDEProcess::DontCare ) ) + KMessageBox::sorry( krApp, i18n( "Can't open " ) + "\"" + edit + "\"" ); + return ; + } + + KrViewer* viewer = getViewer(new_window); + + PanelViewerBase* editWidget = new PanelEditor(&viewer->tabBar); + KParts::Part* part = editWidget->openURL(url,mode); + viewer->addTab(editWidget,i18n("Editing"),EDIT_ICON,part); + + viewer->returnFocusTo = parent; + viewer->returnFocusTab = editWidget; +} + +void KrViewer::addTab(PanelViewerBase* pvb, TQString msg, TQString iconName ,KParts::Part* part){ + if( !part ) return; + + KURL url = pvb->url(); + setCaption( msg+": " + url.prettyURL() ); + + TQIconSet icon = TQIconSet(krLoader->loadIcon(iconName,TDEIcon::Small)); + + manager.addPart( part, this ); + manager.setActivePart( part ); + tabBar.insertTab(pvb,icon,url.fileName()+"("+msg+")"); + tabBar.setCurrentPage(tabBar.indexOf(pvb)); + tabBar.setTabToolTip(pvb,msg+": " + url.prettyURL()); + + updateActions( pvb ); + + // now we can offer the option to detach tabs (we have more than one) + if( tabBar.count() > 1 ){ + viewerMenu->setItemEnabled(detachActionIndex,true); + } + + show(); + tabBar.show(); + + connect( pvb, TQ_SIGNAL( urlChanged( PanelViewerBase *, const KURL & ) ), + this, TQ_SLOT( tabURLChanged(PanelViewerBase *, const KURL & ) ) ); +} + +void KrViewer::tabURLChanged( PanelViewerBase *pvb, const KURL & url ) { + TQString msg = pvb->isEditor() ? i18n( "Editing" ) : i18n( "Viewing" ); + tabBar.setTabLabel( pvb, url.fileName()+"("+msg+")" ); + tabBar.setTabToolTip(pvb,msg+": " + url.prettyURL()); +} + +void KrViewer::tabChanged(TQWidget* w){ + manager.setActivePart( static_cast<PanelViewerBase*>(w)->part() ); + + if( static_cast<PanelViewerBase*>(w) != returnFocusTab ) { + returnFocusTo = 0; + returnFocusTab = 0; + } + + // set this viewer to be the main viewer + if( viewers.remove( this ) ) viewers.prepend( this ); // move to first +} + +void KrViewer::tabCloseRequest(TQWidget *w){ + if( !w ) return; + + // important to save as returnFocusTo will be cleared at removePart + TQWidget * returnFocusToThisWidget = returnFocusTo; + + PanelViewerBase* pvb = static_cast<PanelViewerBase*>(w); + + if( !pvb->queryClose() ) + return; + + manager.removePart(pvb->part()); + + pvb->closeURL(); + + tabBar.removePage(w); + + if( tabBar.count() <= 0 ){ + if( returnFocusToThisWidget ){ + returnFocusToThisWidget->raise(); + returnFocusToThisWidget->setActiveWindow(); + } + else { + krApp->raise(); + krApp->setActiveWindow(); + } + delete this; + return; + } else if( tabBar.count() == 1 ){ + //no point in detaching only one tab.. + viewerMenu->setItemEnabled(detachActionIndex,false); + } + + if( returnFocusToThisWidget ){ + returnFocusToThisWidget->raise(); + returnFocusToThisWidget->setActiveWindow(); + } +} + +void KrViewer::tabCloseRequest(){ + tabCloseRequest( tabBar.currentPage() ); +} + +bool KrViewer::queryClose() { + for( int i=0; i != tabBar.count(); i++ ) { + PanelViewerBase* pvb = static_cast<PanelViewerBase*>( tabBar.page( i ) ); + if( !pvb ) + continue; + + tabBar.setCurrentPage( i ); + + if( !pvb->queryClose() ) + return false; + } + return true; +} + +bool KrViewer::queryExit() { + return true; // don't let the reference counter reach zero +} + +void KrViewer::viewGeneric(){ + PanelViewerBase* pvb = static_cast<PanelViewerBase*>( tabBar.currentPage() ); + if( !pvb ) return; + + PanelViewerBase* viewerWidget = new PanelViewer(&tabBar); + KParts::Part* part = viewerWidget->openURL(pvb->url(),Generic); + addTab(viewerWidget,i18n("Viewing"),VIEW_ICON,part); +} + +void KrViewer::viewText(){ + PanelViewerBase* pvb = static_cast<PanelViewerBase*>( tabBar.currentPage() ); + if( !pvb ) return; + + PanelViewerBase* viewerWidget = new PanelViewer(&tabBar); + KParts::Part* part = viewerWidget->openURL(pvb->url(),Text); + addTab(viewerWidget,i18n("Viewing"),VIEW_ICON,part); +} + +void KrViewer::viewHex(){ + PanelViewerBase* pvb = static_cast<PanelViewerBase*>( tabBar.currentPage() ); + if( !pvb ) return; + + PanelViewerBase* viewerWidget = new PanelViewer(&tabBar); + KParts::Part* part = viewerWidget->openURL(pvb->url(),Hex); + addTab(viewerWidget,i18n("Viewing"),VIEW_ICON,part); +} + +void KrViewer::editText(){ + PanelViewerBase* pvb = static_cast<PanelViewerBase*>( tabBar.currentPage() ); + if( !pvb ) return; + + PanelViewerBase* editWidget = new PanelEditor(&tabBar); + KParts::Part* part = editWidget->openURL(pvb->url(),Text); + addTab(editWidget,i18n("Editing"),EDIT_ICON,part); +} + +void KrViewer::checkModified(){ + TQTimer::singleShot( 1000, this, TQ_SLOT(checkModified()) ); + + PanelViewerBase* pvb = static_cast<PanelViewerBase*>( tabBar.currentPage() ); + if( !pvb ) return; + + if( !pvb->part()->url().equals( pvb->url(), true ) ) { + pvb->setUrl( pvb->part()->url() ); + } + + // add a * to modified files. + if( pvb->isModified() ){ + TQString label = tabBar.tabLabel(pvb); + if( !label.startsWith("*" + pvb->part()->url().fileName() ) ){ + label.prepend("*"); + TQIconSet icon = TQIconSet(krLoader->loadIcon(MODIFIED_ICON,TDEIcon::Small)); + + tabBar.changeTab(pvb,icon,label); + } + } + // remove the * from previously modified files. + else { + TQString label = tabBar.tabLabel(pvb); + if( label.startsWith("*" + pvb->part()->url().fileName() ) ){ + label = label.mid( 1 ); + TQIconSet icon = TQIconSet(krLoader->loadIcon(EDIT_ICON,TDEIcon::Small)); + + tabBar.changeTab(pvb,icon,label); + } + } +} + +void KrViewer::nextTab(){ + int index = (tabBar.currentPageIndex()+1)%tabBar.count(); + tabBar.setCurrentPage( index ); +} + +void KrViewer::prevTab(){ + int index = (tabBar.currentPageIndex()-1)%tabBar.count(); + while( index < 0 ) index+=tabBar.count(); + tabBar.setCurrentPage( index ); +} + +void KrViewer::detachTab(){ + PanelViewerBase* pvb = static_cast<PanelViewerBase*>( tabBar.currentPage() ); + if( !pvb ) return; + + KrViewer* viewer = getViewer(true); + + manager.removePart(pvb->part()); + tabBar.removePage(pvb); + + if( tabBar.count() == 1 ) { + //no point in detaching only one tab.. + viewerMenu->setItemEnabled(detachActionIndex,false); + } + + pvb->reparent(&viewer->tabBar,TQPoint(0,0)); + + if( pvb->isEditor() ) + viewer->addTab(pvb,i18n( "Editing" ),EDIT_ICON,pvb->part()); + else + viewer->addTab(pvb,i18n( "Viewing" ),VIEW_ICON,pvb->part()); +} + +void KrViewer::windowActivationChange ( bool /* oldActive */ ) { + if( isActiveWindow() ) + if( viewers.remove( this ) ) viewers.prepend( this ); // move to first +} + +void KrViewer::print() { + PanelViewerBase* pvb = static_cast<PanelViewerBase*>( tabBar.currentPage() ); + if( !pvb ) return; + + KParts::BrowserExtension * ext = KParts::BrowserExtension::childObject( pvb->part() ); + if( ext && ext->isActionEnabled( "print" ) ) + Invoker( ext, TQ_SLOT( print() ) ).invoke(); +} + +void KrViewer::copy() { + PanelViewerBase* pvb = static_cast<PanelViewerBase*>( tabBar.currentPage() ); + if( !pvb ) return; + + KParts::BrowserExtension * ext = KParts::BrowserExtension::childObject( pvb->part() ); + if( ext && ext->isActionEnabled( "copy" ) ) + Invoker( ext, TQ_SLOT( copy() ) ).invoke(); +} + +PanelViewerBase * KrViewer::getPanelViewerBase( KParts::Part * part ) { + for( int i=0; i != tabBar.count(); i++ ) { + PanelViewerBase *pvb = static_cast<PanelViewerBase*>( tabBar.page( i ) ); + if( pvb && pvb->part() == part ) + return pvb; + } + return 0; +} + +void KrViewer::updateActions( PanelViewerBase * pvb ) { + if( pvb->isEditor() ) { + printAction->unplugAll(); + copyAction->unplugAll(); + } + else { + if( !printAction->isPlugged( toolBar() ) ) + printAction->plug( toolBar(), 0 ); + if( !copyAction->isPlugged( toolBar() ) ) + copyAction->plug( toolBar(), 1 ); + } +} + +#if 0 +bool KrViewer::editGeneric( TQString mimetype, KURL _url ) { + KParts::ReadWritePart * kedit_part = 0L; + KLibFactory *factory = 0; + TDETrader::OfferList offers = TDETrader::self() ->query( mimetype ); + + // in theory, we only care about the first one.. but let's try all + // offers just in case the first can't be loaded for some reason + TDETrader::OfferList::Iterator it( offers.begin() ); + for ( ; it != offers.end(); ++it ) { + KService::Ptr ptr = ( *it ); + // we now know that our offer can handle mimetype and is a part. + // since it is a part, it must also have a library... let's try to + // load that now + factory = KLibLoader::self() ->factory( ptr->library().latin1() ); + if ( factory ) { + kedit_part = static_cast<KParts::ReadWritePart *>( factory->create( this, + ptr->name().latin1(), "KParts::ReadWritePart" ) ); + if ( kedit_part ) + if ( kedit_part->openURL( _url ) ) break; + else { + delete kedit_part; + kedit_part = 0L; + } + } + } + + if ( !kedit_part ) { + KMessageBox::error( this, i18n( "Sorry, can't find internal editor" ) ); + return false; + } + + setCentralWidget( kedit_part->widget() ); + createGUI( kedit_part ); + kedit_part->widget() ->show(); + return true; +} + +bool KrViewer::editText( bool create ) { + if ( !editor_part ) { + editor_part = static_cast<KParts::ReadWritePart*>( getPart( url, "text/plain", false, create ) ); + if ( !editor_part ) return false; + manager.addPart( editor_part, this ); + } + manager.setActivePart( editor_part ); + tabBar.addTab(editor_part->widget(),url.fileName()); + return true; +} + +bool KrViewer::viewGeneric() { + TQString mimetype = KMimeType::findByURL( url ) ->name(); + // ugly hack: don't try to get a part for an XML file, it usually don't work + if ( mimetype == "text/xml" ) return false; + if ( url.prettyURL().startsWith( "man:" ) ) mimetype = "text/html"; + if ( mimetype == "text/plain" ) + viewerMenu->setItemEnabled( 1, false ); + + if ( !generic_part ) { + if ( mimetype.contains( "html" ) ) { + TDEHTMLPart * p = new TDEHTMLPart( this, 0, 0, 0, TDEHTMLPart::BrowserViewGUI ); + connect( p->browserExtension(), TQ_SIGNAL( openURLRequest( const KURL &, const KParts::URLArgs & ) ), + this, TQ_SLOT( handleOpenURLRequest( const KURL &, const KParts::URLArgs & ) ) ); + /* At JavaScript self.close() the TDEHTMLPart destroys itself. */ + /* After destruction, just close the window */ + connect( p, TQ_SIGNAL( destroyed() ), this, TQ_SLOT( close() ) ); + + p-> openURL( url ); + generic_part = p; + } else { + generic_part = static_cast<KParts::ReadOnlyPart*>( getPart( url, mimetype, true ) ); + } + if ( generic_part ) manager.addPart( generic_part, this ); + + else return false; + } + + manager.setActivePart( generic_part ); + tabBar.addTab(generic_part->widget(),url.fileName()); + return true; +} + +bool KrViewer::viewText() { + if ( !text_part ) { + text_part = static_cast<KParts::ReadOnlyPart*>( getPart( url, "text/plain", true ) ); + if ( !text_part ) return false; + manager.addPart( text_part, this ); + } + manager.setActivePart( text_part ); + tabBar.addTab(text_part->widget(),url.fileName()); + return true; +} + +void KrViewer::viewHex() { + if ( !hex_part ) { + TQString file; + // files that are not local must first be downloaded + if ( !url.isLocalFile() ) { + if ( !TDEIO::NetAccess::download( url, file ) ) { + KMessageBox::sorry( this, i18n( "KrViewer is unable to download: " ) + url.url() ); + return ; + } + } else file = url.path(); + + + // create a hex file + TQFile f_in( file ); + f_in.open( IO_ReadOnly ); + TQDataStream in( &f_in ); + + FILE *out = KDE_fopen( tmpFile.name().local8Bit(), "w" ); + + TDEIO::filesize_t fileSize = f_in.size(); + TDEIO::filesize_t address = 0; + char buf[ 16 ]; + unsigned int* pBuff = ( unsigned int* ) buf; + + while ( address < fileSize ) { + memset( buf, 0, 16 ); + int bufSize = ( ( fileSize - address ) > 16 ) ? 16 : ( fileSize - address ); + in.readRawBytes( buf, bufSize ); + fprintf( out, "0x%8.8llx: ", address ); + for ( int i = 0; i < 4; ++i ) { + if ( i < ( bufSize / 4 ) ) fprintf( out, "%8.8x ", pBuff[ i ] ); + else fprintf( out, " " ); + } + fprintf( out, "| " ); + + for ( int i = 0; i < bufSize; ++i ) { + if ( buf[ i ] > ' ' && buf[ i ] < '~' ) fputc( buf[ i ], out ); + else fputc( '.', out ); + } + fputc( '\n', out ); + + address += 16; + } + // clean up + f_in.close(); + fclose( out ); + if ( !url.isLocalFile() ) + TDEIO::NetAccess::removeTempFile( file ); + + hex_part = static_cast<KParts::ReadOnlyPart*>( getPart( tmpFile.name(), "text/plain", true ) ); + if ( !hex_part ) return ; + manager.addPart( hex_part, this ); + } + manager.setActivePart( hex_part ); + tabBar.addTab(hex_part->widget(),url.fileName()); +} +#endif + + +#include "krviewer.moc" diff --git a/src/app/KViewer/krviewer.h b/src/app/KViewer/krviewer.h new file mode 100644 index 0000000..c4d12db --- /dev/null +++ b/src/app/KViewer/krviewer.h @@ -0,0 +1,130 @@ +/*************************************************************************** + krviewer.h - description + ------------------- + begin : Thu Apr 18 2002 + copyright : (C) 2002 by Shie Erlich & Rafi Yanai + email : +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KRVIEWER_H +#define KRVIEWER_H + +#include <tqwidget.h> +#include <tqptrlist.h> +#include <tdeparts/mainwindow.h> +#include <tdetempfile.h> +#include <tdeparts/partmanager.h> +#include <tdeparts/browserextension.h> +#include <tqguardedptr.h> +#include <ktabwidget.h> + +#include "../krusader.h" + + +/** + *@author Shie Erlich & Rafi Yanai + */ + +class TQPopupMenu; +class PanelViewerBase; + +class KrViewer : public KParts::MainWindow { + TQ_OBJECT + +public: + virtual ~KrViewer(); + + enum Mode{Generic,Text,Hex}; + + static void view( KURL url, TQWidget * parent = krApp ); + static void view( KURL url, Mode mode, bool new_window, TQWidget * parent = krApp ); + static void edit( KURL url, TQWidget * parent ); + static void edit( KURL url, Mode mode=Text, int new_window=-1, TQWidget * parent = krApp ); + + virtual bool eventFilter ( TQObject * watched, TQEvent * e ); + +public slots: + void keyPressEvent( TQKeyEvent *e ); + void createGUI( KParts::Part* ); + + void viewGeneric(); + void viewText(); + void viewHex(); + void editText(); + + void print(); + void copy(); + + void tabChanged(TQWidget* w); + void tabURLChanged( PanelViewerBase * pvb, const KURL &url ); + void tabCloseRequest(TQWidget *w); + void tabCloseRequest(); + + void nextTab(); + void prevTab(); + void detachTab(); + + void checkModified(); + +protected: + virtual bool queryClose(); + virtual bool queryExit(); + virtual void windowActivationChange ( bool oldActive ); + + virtual void focusInEvent( TQFocusEvent * ){ if( viewers.remove( this ) ) viewers.prepend( this ); } // move to first + +private: + KrViewer( TQWidget *parent = 0, const char *name = 0 ); + void addTab(PanelViewerBase* pvb, TQString msg,TQString iconName, KParts::Part* part); + PanelViewerBase * getPanelViewerBase( KParts::Part* part); + void updateActions( PanelViewerBase * base ); + + static KrViewer* getViewer(bool new_window); + + KParts::PartManager manager; + TQPopupMenu* viewerMenu; + KTempFile tmpFile; + KTabWidget tabBar; + TQGuardedPtr<TQWidget> returnFocusTo; + PanelViewerBase * returnFocusTab; + + int detachActionIndex; + + TDEAction *printAction; + TDEAction *copyAction; + + int tabCloseID; + int closeID; + + static TQPtrList<KrViewer> viewers; // the first viewer is the active one + TQValueList<int> reservedKeys; // the reserved key sequences + TQValueList<int> reservedKeyIDs; // the IDs of the reserved keys +}; + +class Invoker : public TQObject { + TQ_OBJECT + + +public: + Invoker( TQObject *recv, const char * slot ) { + connect( this, TQ_SIGNAL( invokeSignal() ), recv, slot ); + } + + void invoke() { + emit invokeSignal(); + } + +signals: + void invokeSignal(); +}; + +#endif diff --git a/src/app/KViewer/panelviewer.cpp b/src/app/KViewer/panelviewer.cpp new file mode 100644 index 0000000..32f6532 --- /dev/null +++ b/src/app/KViewer/panelviewer.cpp @@ -0,0 +1,307 @@ +#include <kurl.h> +#include <tqstring.h> +#include <tqwidgetstack.h> +#include <tqapplication.h> +#include <tdeparts/part.h> +#include <tdeparts/browserextension.h> +#include <tdemessagebox.h> +#include <tqdict.h> +#include <tqlabel.h> +#include <kmimetype.h> +#include <tdetempfile.h> +#include <tdelocale.h> +#include <klibloader.h> +#include <kuserprofile.h> +#include <kdebug.h> +#include <tdefileitem.h> +#include <tdeio/netaccess.h> +#include <tqfile.h> +#include <klargefile.h> +#include "panelviewer.h" + +#define DICTSIZE 211 + +/* ----==={ PanelViewerBase }===---- */ + +PanelViewerBase::PanelViewerBase( TQWidget *parent ) : +TQWidgetStack( parent ), mimes( 0 ), cpart( 0 ) { + setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored ) ); + + mimes = new TQDict<KParts::ReadOnlyPart>( DICTSIZE, false ); + mimes->setAutoDelete( true ); + cpart = 0; + fallback = new TQLabel( i18n( "No file selected or selected file can't be displayed." ), this ); + fallback->setAlignment( AlignCenter | ExpandTabs | WordBreak ); + addWidget( fallback ); + raiseWidget( fallback ); +} + +PanelViewerBase::~PanelViewerBase() { +// cpart->queryClose(); + closeURL(); + mimes->clear(); + delete mimes; + delete fallback; +} + +/* ----==={ PanelViewer }===---- */ + +PanelViewer::PanelViewer( TQWidget *parent ) : +PanelViewerBase( parent ) { +} + +PanelViewer::~PanelViewer() { +} + +KParts::ReadOnlyPart* PanelViewer::openURL( const KURL &url, KrViewer::Mode mode ) { + emit urlChanged( this, url ); + closeURL(); + curl = url; + + if( mode == KrViewer::Generic ){ + cmimetype = KMimeType::findByURL( curl ) ->name(); + cpart = ( *mimes ) [ cmimetype ]; + if ( !cpart ){ + cpart = getPart( cmimetype ); + mimes->insert( cmimetype, cpart ); + } + } + + KTempFile tmpFile; + + if( mode == KrViewer::Hex ){ + if ( !cpart ) cpart = getHexPart(); + if ( !cpart ) oldHexViewer(tmpFile); + } + + if ( !cpart ) cpart = getPart( "text/plain" ); + if ( !cpart ) cpart = getPart( "all/allfiles" ); + + if ( cpart ) { + addWidget( cpart->widget() ); + raiseWidget( cpart->widget() ); + } + if ( cpart && cpart->openURL( curl ) ){ + curl = url; /* needed because of the oldHexViewer */ + return cpart; + } + else { + raiseWidget( fallback ); + return 0; + } +} + +bool PanelViewer::closeURL() { + raiseWidget( fallback ); + if ( cpart && cpart->closeURL() ) { + cpart = 0; + return true; + } + return false; +} + +KParts::ReadOnlyPart* PanelViewer::getPart( TQString mimetype ) { + KParts::ReadOnlyPart * part = 0L; + KLibFactory *factory = 0; + KService::Ptr ptr = KServiceTypeProfile::preferredService( mimetype, "KParts/ReadOnlyPart" ); + if ( ptr ) { + TQStringList args; + TQVariant argsProp = ptr->property( "X-TDE-BrowserView-Args" ); + if ( argsProp.isValid() ) { + TQString argStr = argsProp.toString(); + args = TQStringList::split( " ", argStr ); + } + TQVariant prop = ptr->property( "X-TDE-BrowserView-AllowAsDefault" ); + if ( !prop.isValid() || prop.toBool() ) // defaults to true + { + factory = KLibLoader::self() ->factory( ptr->library().latin1() ); + if ( factory ) { + part = static_cast<KParts::ReadOnlyPart *>( factory->create( this, + ptr->name().latin1(), TQString( "KParts::ReadOnlyPart" ).latin1(), args ) ); + } + } + } + if ( part ) { + KParts::BrowserExtension * ext = KParts::BrowserExtension::childObject( part ); + if ( ext ) { + connect( ext, TQ_SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ), this, TQ_SLOT( openURL( const KURL & ) ) ); + connect( ext, TQ_SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ), this, TQ_SIGNAL( openURLRequest( const KURL & ) ) ); + } + } + return part; +} + +KParts::ReadOnlyPart* PanelViewer::getHexPart(){ + KParts::ReadOnlyPart * part = 0L; + + KLibFactory * factory = KLibLoader::self() ->factory( "libkhexedit2part" ); + if ( factory ) { + // Create the part + part = ( KParts::ReadOnlyPart * ) factory->create( this, "hexedit2part","KParts::ReadOnlyPart" ); + } + + return part; +} + +void PanelViewer::oldHexViewer(KTempFile& tmpFile) { + TQString file; + // files that are not local must first be downloaded + if ( !curl.isLocalFile() ) { + if ( !TDEIO::NetAccess::download( curl, file,this ) ) { + KMessageBox::sorry( this, i18n( "KrViewer is unable to download: " ) + curl.url() ); + return ; + } + } else file = curl.path(); + + + // create a hex file + TQFile f_in( file ); + f_in.open( IO_ReadOnly ); + TQDataStream in( &f_in ); + + FILE *out = KDE_fopen( tmpFile.name().local8Bit(), "w" ); + + TDEIO::filesize_t fileSize = f_in.size(); + TDEIO::filesize_t address = 0; + char buf[ 16 ]; + unsigned int* pBuff = ( unsigned int* ) buf; + + while ( address < fileSize ) { + memset( buf, 0, 16 ); + int bufSize = ( ( fileSize - address ) > 16 ) ? 16 : ( fileSize - address ); + in.readRawBytes( buf, bufSize ); + fprintf( out, "0x%8.8llx: ", address ); + for ( int i = 0; i < 4; ++i ) { + if ( i < ( bufSize / 4 ) ) fprintf( out, "%8.8x ", pBuff[ i ] ); + else fprintf( out, " " ); + } + fprintf( out, "| " ); + + for ( int i = 0; i < bufSize; ++i ) { + if ( buf[ i ] > ' ' && buf[ i ] < '~' ) fputc( buf[ i ], out ); + else fputc( '.', out ); + } + fputc( '\n', out ); + + address += 16; + } + // clean up + f_in.close(); + fclose( out ); + if ( !curl.isLocalFile() ) + TDEIO::NetAccess::removeTempFile( file ); + + curl = tmpFile.name(); +} + +/* ----==={ PanelEditor }===---- */ + +PanelEditor::PanelEditor( TQWidget *parent ) : +PanelViewerBase( parent ) { +} + +PanelEditor::~PanelEditor() { +} + +KParts::ReadOnlyPart* PanelEditor::openURL( const KURL &url, KrViewer::Mode mode ) { + emit urlChanged( this, url ); + closeURL(); + curl = url; + + if( mode == KrViewer::Generic ){ + cmimetype = KMimeType::findByURL( curl ) ->name(); + cpart = ( *mimes ) [ cmimetype ]; + if ( !cpart ){ + cpart = getPart( cmimetype ); + mimes->insert( cmimetype, cpart ); + } + } + + if ( !cpart ) cpart = getPart( "text/plain" ); + if ( !cpart ) cpart = getPart( "all/allfiles" ); + + if ( cpart ) { + addWidget( cpart->widget() ); + raiseWidget( cpart->widget() ); + } + else { + raiseWidget( fallback ); + return 0; + } + + bool create = true; + TDEIO::StatJob* statJob = TDEIO::stat( url, false ); + connect( statJob, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( slotStatResult( TDEIO::Job* ) ) ); + busy = true; + while ( busy ) tqApp->processEvents(); + if( !entry.isEmpty() ) { + KFileItem file( entry, url ); + if( file.isReadable() ) create = false; + } + + if( create ){ + if( static_cast<KParts::ReadWritePart *>(cpart)->saveAs( curl ) ) return cpart; + } + else { + if ( cpart->openURL( curl ) ) return cpart; + } + return 0; +} + +bool PanelEditor::queryClose() { + if ( !cpart ) return true; + return static_cast<KParts::ReadWritePart *>(cpart)->queryClose(); +} + +bool PanelEditor::closeURL() { + if ( !cpart ) return false; + + static_cast<KParts::ReadWritePart *>(cpart)->closeURL( false ); + + raiseWidget( fallback ); + cpart = 0; + return true; +} + +KParts::ReadWritePart* PanelEditor::getPart( TQString mimetype ) { + KParts::ReadWritePart * part = 0L; + KLibFactory *factory = 0; + KService::Ptr ptr = KServiceTypeProfile::preferredService( mimetype, "KParts/ReadWritePart" ); + if ( ptr ) { + TQStringList args; + TQVariant argsProp = ptr->property( "X-TDE-BrowserView-Args" ); + if ( argsProp.isValid() ) { + TQString argStr = argsProp.toString(); + args = TQStringList::split( " ", argStr ); + } + TQVariant prop = ptr->property( "X-TDE-BrowserView-AllowAsDefault" ); + if ( !prop.isValid() || prop.toBool() ) // defaults to true + { + factory = KLibLoader::self() ->factory( ptr->library().latin1() ); + if ( factory ) { + part = static_cast<KParts::ReadWritePart *>( factory->create( this, + ptr->name().latin1(), TQString( "KParts::ReadWritePart" ).latin1(), args ) ); + } + } + } + if ( part ) { + KParts::BrowserExtension * ext = KParts::BrowserExtension::childObject( part ); + if ( ext ) { + connect( ext, TQ_SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ), this, TQ_SLOT( openURL( const KURL & ) ) ); + connect( ext, TQ_SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ), this, TQ_SIGNAL( openURLRequest( const KURL & ) ) ); + } + } + return part; +} + +void PanelEditor::slotStatResult( TDEIO::Job* job ) { + if( !job || job->error() ) entry = TDEIO::UDSEntry(); + else entry = static_cast<TDEIO::StatJob*>(job)->statResult(); + busy = false; +} + +bool PanelEditor::isModified(){ + return static_cast<KParts::ReadWritePart *>(cpart)->isModified(); +} + +#include "panelviewer.moc" diff --git a/src/app/KViewer/panelviewer.h b/src/app/KViewer/panelviewer.h new file mode 100644 index 0000000..2875f92 --- /dev/null +++ b/src/app/KViewer/panelviewer.h @@ -0,0 +1,91 @@ +#ifndef _SUPERVIEW_H +#define _SUPERVIEW_H + +#include <kurl.h> +#include <tqstring.h> +#include <tqwidgetstack.h> +#include <tdeparts/part.h> +#include <tdeio/job.h> +#include <tdetempfile.h> +#include <tqdict.h> +#include <tqlabel.h> + +#include "krviewer.h" + + +class PanelViewerBase: public TQWidgetStack { + TQ_OBJECT + + +public: + PanelViewerBase( TQWidget *parent = 0 ); + virtual ~PanelViewerBase(); + inline KURL url() const { return curl; } + inline void setUrl( KURL url ) { emit urlChanged( this, url ); curl = url; } + inline KParts::ReadOnlyPart* part() const { return cpart; } + virtual bool isModified() { return false; } + virtual bool isEditor() = 0; + +public slots: + virtual KParts::ReadOnlyPart* openURL( const KURL&, KrViewer::Mode=KrViewer::Generic ){ return 0;} + virtual bool closeURL(){ return false; } + virtual bool queryClose() { return true; } + +signals: + void openURLRequest( const KURL &url ); + void urlChanged( PanelViewerBase *, const KURL & ); + +protected: + TQDict<KParts::ReadOnlyPart> *mimes; + KParts::ReadOnlyPart *cpart; + + TQString cmimetype; + KURL curl; + TQLabel *fallback; + +}; + +class PanelViewer: public PanelViewerBase { + TQ_OBJECT + +public slots: + KParts::ReadOnlyPart* openURL( const KURL &url, KrViewer::Mode mode=KrViewer::Generic ); + bool closeURL(); + +public: + PanelViewer( TQWidget *parent = 0 ); + ~PanelViewer(); + + virtual bool isEditor() { return false; } + +protected: + KParts::ReadOnlyPart *getPart( TQString mimetype ); + KParts::ReadOnlyPart* getHexPart(); + void oldHexViewer(KTempFile& tmpFile); +}; + +class PanelEditor: public PanelViewerBase { + TQ_OBJECT + +public: + virtual bool isModified(); + virtual bool isEditor() { return true; } + +public slots: + KParts::ReadOnlyPart* openURL( const KURL &url, KrViewer::Mode mode=KrViewer::Generic ); + bool closeURL(); + bool queryClose(); + void slotStatResult( TDEIO::Job* job ); + +public: + PanelEditor( TQWidget *parent = 0 ); + ~PanelEditor(); + +protected: + KParts::ReadWritePart* getPart( TQString mimetype ); + + bool busy; + TDEIO::UDSEntry entry; +}; + +#endif |