diff --git a/shell/shell.cpp b/shell/shell.cpp index df96208c11c90fb822411c2cd5829a1f5a8937a2..351f7a7d7a85615da2245be782eb6c0ddbf3ee3e 100644 --- a/shell/shell.cpp +++ b/shell/shell.cpp @@ -10,6 +10,7 @@ * Copyright (C) 2003 by Malcolm Hunter * * Copyright (C) 2004 by Dominique Devriese * * Copyright (C) 2004 by Dirk Mueller * + * Copyright (C) 2005 by Piotr Szymanski * * * * 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 * @@ -34,6 +35,10 @@ #include #include #include +#include +#include +#include +#include // local includes #include "shell.h" @@ -57,7 +62,7 @@ void Shell::init() { // set the shell's ui resource file setXMLFile("shell.rc"); - + m_fileformats=0; // this routine will find and load our Part. it finds the Part by // name which is a bad idea usually.. but it's alright in this // case since our Part is made for this Shell @@ -109,6 +114,7 @@ void Shell::delayedOpen() Shell::~Shell() { if(m_part) writeSettings(); + if (m_fileformats) delete m_fileformats; } void Shell::openURL( const KURL & url ) @@ -205,16 +211,183 @@ void Shell::readProperties(KConfig* config) } } - void -Shell::fileOpen() +// this comes from kviewpart/kviewpart.cpp, fileformats function + +QStringList* Shell::fileFormats() +{ + QString constraint("([X-KDE-Priority] > 0) and (exist Library) ") ; + KTrader::OfferList offers=KTrader::self()->query("oKular/Generator",QString::null,constraint, QString::null); + QStringList supportedMimeTypes; + QStringList * supportedPattern; + + if (offers.isEmpty()) + { + return 0; + } + + bool bzip2Available = (KFilterBase::findFilterByMimeType( "application/x-bzip2" ) != 0L); + supportedPattern = new QStringList; + KTrader::OfferList::ConstIterator iterator = offers.begin(); + KTrader::OfferList::ConstIterator end = offers.end(); + QStringList::Iterator mimeType; + QString tmp; + QStringList mimeTypes,pattern,extensions; + QString allExt,comment; + for (; iterator != end; ++iterator) + { + KService::Ptr service = *iterator; + mimeTypes = service->serviceTypes(); + + for (mimeType=mimeTypes.begin();mimeType!=mimeTypes.end();++mimeType) + { + if (! (*mimeType).contains("oKular")) + { + supportedMimeTypes << *mimeType; + + pattern = KMimeType::mimeType(*mimeType)->patterns(); + extensions.clear(); + while(!pattern.isEmpty()) + { + tmp=pattern.front().stripWhiteSpace(); + extensions.append(tmp); + if (tmp.find(".gz", -3) == -1) + extensions.append(tmp+".gz"); + if ((bzip2Available) && (tmp.find(".bz2", -4) == -1)) + extensions.append(tmp+".bz2"); + pattern.pop_front(); + } + comment=KMimeType::mimeType(*mimeType)->comment(); + if (! comment.contains("Unknown")) + supportedPattern->append(extensions.join(" ") + "|" + comment); + allExt+=extensions.join(" "); + } + } + } + + supportedPattern->prepend(allExt + "|All Files"); + + + return supportedPattern; + + +} +bool Shell::handleCompressed(KURL & url, const QString &path, const KMimeType::Ptr mimetype) +{ + + // we are working with a compressed file, decompressing + // temporary file for decompressing + KTempFile* tmpUnzipped = new KTempFile; + if ( !tmpUnzipped ) + { + KMessageBox::error(this, + i18n("File Error! Could not create " + "temporary file.")); + return false; + } + + tmpUnzipped->setAutoDelete(true); + + // something failed while creating the tempfile + if ( tmpUnzipped->status() != 0 ) + { + KMessageBox::error( this, + i18n("File Error! Could not create temporary file " + "%1.").arg( + strerror(tmpUnzipped->status()))); + delete tmpUnzipped; + return false; + } + + // decompression filer + QIODevice* filterDev; + if (( mimetype->parentMimeType() == "application/x-gzip" ) || + ( mimetype->parentMimeType() == "application/x-bzip2" )) + filterDev = KFilterDev::deviceForFile(path, mimetype->parentMimeType()); + else + filterDev = KFilterDev::deviceForFile(path); + + if (!filterDev) + { + delete tmpUnzipped; + return false; + } + + if ( !filterDev->open(IO_ReadOnly) ) + { + KMessageBox::detailedError( this, + i18n("File Error! Could not open the file " + "%1 for uncompression. " + "The file will not be loaded.").arg(path), + i18n("This error typically occurs if you do " + "not have enough permissions to read the file. " + "You can check ownership and permissions if you " + "right-click on the file in the Konqueror " + "file manager and then choose the 'Properties' menu.")); + + delete filterDev; + delete tmpUnzipped; + return false; + } + + QByteArray buf(1024); + int read = 0, wrtn = 0; + + while ((read = filterDev->readBlock(buf.data(), buf.size())) > 0) + { + wrtn = tmpUnzipped->file()->writeBlock(buf.data(), read); + if ( read != wrtn ) + break; + } + delete filterDev; + if ((read != 0) || (tmpUnzipped->file()->size() == 0)) + { + KMessageBox::detailedError(this, + i18n("File Error! Could not uncompress " + "the file %1. " + "The file will not be loaded.").arg( path ), + i18n("This error typically occurs if the file is corrupt. " + "If you want to be sure, try to decompress the file manually " + "using command-line tools.")); + delete tmpUnzipped; + return false; + } + tmpUnzipped->close(); + url=tmpUnzipped->name(); +} + +void Shell::fileOpen() { - // this slot is called whenever the File->Open menu is selected, - // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar - // button is clicked - KURL url = KFileDialog::getOpenURL( QString::null, "application/pdf" );//getOpenFileName(); + // this slot is called whenever the File->Open menu is selected, + // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar + // button is clicked + if (!m_fileformats) + m_fileformats = fileFormats(); - if (!url.isEmpty()) - openURL(url); + if (m_fileformats) + { + KURL url = KFileDialog::getOpenURL( QString::null, m_fileformats->join("\n") );//getOpenFileName(); + bool reallyOpen=!url.isEmpty(); + if (reallyOpen) + { + QString path = url.path(); + KMimeType::Ptr mimetype = KMimeType::findByPath( path ); + if (( mimetype->name() == "application/x-gzip" ) + || ( mimetype->name() == "application/x-bzip2" ) + || ( mimetype->parentMimeType() == "application/x-gzip" ) + || ( mimetype->parentMimeType() == "application/x-bzip2" ) + ) + { + reallyOpen=handleCompressed(url,path,mimetype); + } + } + if (reallyOpen) + openURL(url); + } + else + { + KMessageBox::error(this, i18n("No oKular plugins were found.")); + slotQuit(); + } } void diff --git a/shell/shell.h b/shell/shell.h index 9ca9eb826245c79c33aad7b92791fc4559c15379..27983b668f2cc1815f4126e3f96391a0a0cd9c0c 100644 --- a/shell/shell.h +++ b/shell/shell.h @@ -6,6 +6,7 @@ * Copyright (C) 2004 by Christophe Devriese * * * * Copyright (C) 2004 by Albert Astals Cid * + * Copyright (C) 2005 by Piotr Szymanski * * * * 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 * @@ -21,9 +22,11 @@ #endif #include +#include namespace KPDF { +class Part; /** * This is the application "Shell". It has a menubar and a toolbar * but relies on the "Part" to do all the real work. @@ -68,7 +71,7 @@ namespace KPDF void readSettings(); void writeSettings(); void setFullScreen( bool ); - + private slots: void fileOpen(); void slotQuit(); @@ -89,10 +92,13 @@ namespace KPDF void setupAccel(); void setupActions(); void init(); + bool handleCompressed(KURL & url, const QString &path, const KMimeType::Ptr mimetype); + QStringList* fileFormats(); private: KParts::ReadOnlyPart* m_part; KRecentFilesAction* m_recent; + QStringList* m_fileformats; KAction* m_printAction; KToggleAction* m_fullScreenAction; KToggleAction* m_showMenuBarAction;