summaryrefslogtreecommitdiffstats
path: root/ark/arkapp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ark/arkapp.cpp')
-rw-r--r--ark/arkapp.cpp294
1 files changed, 294 insertions, 0 deletions
diff --git a/ark/arkapp.cpp b/ark/arkapp.cpp
new file mode 100644
index 0000000..c117d0b
--- /dev/null
+++ b/ark/arkapp.cpp
@@ -0,0 +1,294 @@
+/*
+
+ ark -- archiver for the KDE project
+
+ Copyright (C)
+
+ 2002-2003: Helio Chissini de Castro <helio@conectiva.com.br>
+ 2003: Georg Robbers <Georg.Robbers@urz.uni-hd.de>
+ 1999-2000: Corel Corporation (author: Emily Ezust emilye@corel.com)
+ 1999: Francois-Xavier Duranceau duranceau@kde.org
+
+ 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.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <dcopclient.h>
+#include <kdebug.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <unistd.h>
+#include <qfile.h>
+#include <errno.h>
+
+
+#include "arkapp.h"
+
+ArkApplication *ArkApplication::mInstance = NULL;
+
+// a helper function to follow a symlink and obtain the real filename
+// Used in the ArkApplication functions that use the archive filename
+// to make sure an archive isn't opened twice in different windows
+// Now, readlink only gives one level so this function recurses.
+
+static QString resolveFilename(const QString & _arkname)
+{
+ char *buff;
+ int nread;
+ int iter = 1;
+
+ while ( true )
+ {
+ buff = new char[BUFSIZ*iter];
+ nread = readlink( QFile::encodeName(_arkname), buff, BUFSIZ);
+ if (-1 == nread)
+ {
+ if ( EINVAL == errno ) // not a symbolic link. Stopping condition.
+ {
+ delete [] buff;
+ return _arkname;
+ }
+ else if ( ENAMETOOLONG == errno )
+ {
+ kdDebug(1601) << "resolveFilename: have to reallocate - name too long!" << endl;
+ iter++;
+ delete [] buff;
+ continue;
+ }
+ else
+ {
+ delete [] buff;
+ // the other errors will be taken care of already in simply
+ // // opening the archive (i.e., the user will be notified)
+ return "";
+ }
+ }
+ else
+ {
+ buff[nread] = '\0'; // readlink doesn't null terminate
+ QString name = QFile::decodeName( buff );
+ delete [] buff;
+
+ // watch out for relative pathnames
+ if (name.at(0) != '/')
+ {
+ // copy the path from _arkname
+ int index = _arkname.findRev('/');
+ name = _arkname.left(index + 1) + name;
+ }
+ kdDebug(1601) << "Now resolve " << name << endl;
+
+ return resolveFilename( name );
+ }
+ }
+}
+
+
+ArkApplication * ArkApplication::getInstance()
+{
+ if (mInstance == NULL)
+ {
+ mInstance = new ArkApplication();
+ }
+ return mInstance;
+}
+
+ArkApplication::ArkApplication()
+ : KUniqueApplication(), m_windowCount(0)
+{
+ m_mainwidget = new QWidget;
+ setMainWidget(m_mainwidget);
+}
+
+int
+ArkApplication::newInstance()
+{
+
+ // If we are restored by session management, we don't need to open
+ // another window on startup.
+ if (restoringSession()) return 0;
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ if ( args->isSet( "extract-to" ) )
+ {
+ if ( args->count() == 2 )
+ {
+ MainWindow *arkWin = new MainWindow();
+
+ arkWin->extractTo( args->url( 0 ), args->url( 1 ), args->isSet( "guess-name" ) );
+ return 0;
+ }
+ else
+ {
+ KCmdLineArgs::usage( i18n( "Wrong number of arguments specified" ) );
+ return 0;
+ }
+ }
+
+ if ( args->isSet( "add-to" ) && ( !args->isSet( "add" ) ) )
+ {
+ if ( args->count() < 2 )
+ {
+ KCmdLineArgs::usage( i18n( "You need to specify at least one file to be added to the archive." ) );
+ return 0;
+ }
+ else
+ {
+ KURL::List URLList;
+ for ( int c = 0; c < args->count()-1 ; c++ )
+ URLList.append( args->url( c ) );
+
+ MainWindow *arkWin = new MainWindow();
+
+ arkWin->addToArchive( URLList, args->cwd(), args->url( args->count()-1 ) );
+ return 0;
+ }
+ }
+
+ if ( args->isSet( "add" ) && args->isSet( "add-to" ) ) // HACK
+ {
+ bool oneFile = (args->count() == 2 ) ;
+
+ QString extension = args->arg( 0 );
+ KURL archiveName = args->url( 1 ); // the filename
+
+ // if more than one file -> use directory name
+ if ( !oneFile )
+ archiveName.setPath( archiveName.directory() );
+
+ archiveName.setFileName( archiveName.fileName() + extension );
+ KURL::List URLList;
+ for ( int c = 1; c < args->count(); c++ )
+ URLList.append( args->url( c ) );
+
+ MainWindow *arkWin = new MainWindow();
+
+ arkWin->addToArchive( URLList, args->cwd(), archiveName, !oneFile );
+ return 0;
+ }
+
+
+ if ( args->isSet( "add" ) && ( !args->isSet( "add-to" ) ) )
+ {
+ if ( args->count() < 1 )
+ {
+ KCmdLineArgs::usage( i18n( "You need to specify at least one file to be added to the archive." ) );
+ return 0;
+ }
+ else
+ {
+ KURL::List URLList;
+ for ( int c = 0; c < args->count() ; c++ )
+ URLList.append( args->url( c ) );
+
+ MainWindow *arkWin = new MainWindow();
+
+ arkWin->addToArchive( URLList, args->cwd() );
+ return 0;
+ }
+ }
+
+
+ int i = 0;
+ KURL url;
+ bool doAutoExtract = args->isSet("extract");
+ bool tempFile = KCmdLineArgs::isTempFileSet();
+ do
+ {
+ if (args->count() > 0)
+ {
+ url = args->url(i);
+ }
+ MainWindow *arkWin = new MainWindow();
+ arkWin->show();
+ if(doAutoExtract)
+ {
+ arkWin->setExtractOnly(true);
+ }
+ if (!url.isEmpty())
+ {
+ arkWin->openURL(url, tempFile);
+ }
+
+ ++i;
+ } while (i < args->count());
+
+ args->clear();
+ return 0;
+}
+
+
+void
+ArkApplication::addOpenArk(const KURL & _arkname, MainWindow *_ptr)
+{
+ QString realName;
+ if( _arkname.isLocalFile() )
+ {
+ realName = resolveFilename( _arkname.path() ); // follow symlink
+ kdDebug(1601) << " Real name of " << _arkname.prettyURL() << " is " << realName << endl;
+ }
+ else
+ realName = _arkname.prettyURL();
+ openArksList.append(realName);
+ m_windowsHash.replace(realName, _ptr);
+ kdDebug(1601) << "Saved ptr " << _ptr << " added open ark: " << realName << endl;
+}
+
+void
+ArkApplication::removeOpenArk(const KURL & _arkname)
+{
+ QString realName;
+ if ( _arkname.isLocalFile() )
+ realName = resolveFilename( _arkname.path() ); // follow symlink
+ else
+ realName = _arkname.prettyURL();
+ kdDebug(1601) << "Removing name " << _arkname.prettyURL() << endl;
+ openArksList.remove(realName);
+ m_windowsHash.remove(realName);
+}
+
+void
+ArkApplication::raiseArk(const KURL & _arkname)
+{
+ kdDebug( 1601 ) << "ArkApplication::raiseArk " << endl;
+ MainWindow *window;
+ QString realName;
+ if( _arkname.isLocalFile() )
+ realName = resolveFilename(_arkname.path()); // follow symlink
+ else
+ realName = _arkname.prettyURL();
+ window = m_windowsHash[realName];
+ kdDebug(1601) << "ArkApplication::raiseArk " << window << endl;
+ // raise didn't seem to be enough. Not sure why!
+ // This might be annoying though.
+ //window->hide();
+ //window->show();
+ window->raise();
+}
+
+bool
+ArkApplication::isArkOpenAlready(const KURL & _arkname)
+{
+ QString realName;
+ if ( _arkname.isLocalFile() )
+ realName = resolveFilename(_arkname.path()); // follow symlink
+ else
+ realName = _arkname.prettyURL();
+ return ( openArksList.findIndex(realName) != -1 );
+}
+
+#include "arkapp.moc"
+