summaryrefslogtreecommitdiffstats
path: root/src/app/KViewer
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/KViewer')
-rw-r--r--src/app/KViewer/Makefile.am11
-rw-r--r--src/app/KViewer/diskusageviewer.cpp129
-rw-r--r--src/app/KViewer/diskusageviewer.h69
-rw-r--r--src/app/KViewer/kimagefilepreview.cpp136
-rw-r--r--src/app/KViewer/kimagefilepreview.h71
-rw-r--r--src/app/KViewer/krviewer.cpp702
-rw-r--r--src/app/KViewer/krviewer.h130
-rw-r--r--src/app/KViewer/panelviewer.cpp307
-rw-r--r--src/app/KViewer/panelviewer.h91
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