/* ark -- archiver for the KDE project Copyright (C) 2002-2003: Helio Chissini de Castro 2003: Georg Robbers 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 #include #include #include #include #include #include #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 TQString resolveFilename(const TQString & _arkname) { char *buff; int nread; int iter = 1; while ( true ) { buff = new char[BUFSIZ*iter]; nread = readlink( TQFile::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 TQString name = TQFile::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() : TDEUniqueApplication(), m_windowCount(0) { m_mainwidget = new TQWidget; 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; TDECmdLineArgs *args = TDECmdLineArgs::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 { TDECmdLineArgs::usage( i18n( "Wrong number of arguments specified" ) ); return 0; } } if ( args->isSet( "add-to" ) && ( !args->isSet( "add" ) ) ) { if ( args->count() < 2 ) { TDECmdLineArgs::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 ) ; TQString 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 ) { TDECmdLineArgs::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 = TDECmdLineArgs::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) { TQString 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) { TQString 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; TQString 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) { TQString realName; if ( _arkname.isLocalFile() ) realName = resolveFilename(_arkname.path()); // follow symlink else realName = _arkname.prettyURL(); return ( openArksList.findIndex(realName) != -1 ); } #include "arkapp.moc"