diff options
Diffstat (limited to 'kio/kio')
172 files changed, 0 insertions, 73590 deletions
diff --git a/kio/kio/CMakeLists.txt b/kio/kio/CMakeLists.txt deleted file mode 100644 index 1a2c3a263..000000000 --- a/kio/kio/CMakeLists.txt +++ /dev/null @@ -1,138 +0,0 @@ -################################################# -# -# (C) 2010 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${TQT_INCLUDE_DIRS} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_BINARY_DIR}/kio/kssl - ${CMAKE_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_BINARY_DIR}/tdecore - ${CMAKE_SOURCE_DIR} - ${CMAKE_SOURCE_DIR}/dcop - ${CMAKE_SOURCE_DIR}/tdecore - ${CMAKE_SOURCE_DIR}/tdecore/network - ${CMAKE_SOURCE_DIR}/tdeui - ${CMAKE_SOURCE_DIR}/kio - ${CMAKE_SOURCE_DIR}/kio/kssl - ${CMAKE_SOURCE_DIR}/interfaces - ${LIBR_INCLUDEDIR} - ${GAMIN_INCLUDEDIR} -) - -link_directories( - ${GAMIN_LIBDIR} -) - -##### headers ################################### - -install( FILES - kservicetype.h kmimetype.h kmimemagic.h kservice.h - krun.h kdirwatch.h kautomount.h kuserprofile.h - kshred.h kar.h ktar.h kzip.h ktrader.h kurifilter.h - kurlcompletion.h kshellcompletion.h kfileitem.h - kfileshare.h ksambashare.h knfsshare.h kdirlister.h - kservicegroup.h kimageio.h kdirnotify.h kdirnotify_stub.h - kurlpixmapprovider.h kprotocolinfo.h kprotocolmanager.h - kfilterbase.h kfilterdev.h kemailsettings.h kscan.h - kdatatool.h karchive.h kfilefilter.h kfilemetainfo.h - renamedlgplugin.h kmimetyperesolver.h kdcopservicestarter.h - kremoteencoding.h kmimetypechooser.h - DESTINATION ${INCLUDE_INSTALL_DIR} ) - -# FIXME seems that ACL is no longer optional -#if( USE_POSIX_ACL ) - install( FILES kacl.h DESTINATION ${INCLUDE_INSTALL_DIR} ) -#endif( USE_POSIX_ACL ) - -install( FILES - connection.h slaveinterface.h slave.h slaveconfig.h - sessiondata.h global.h passdlg.h netaccess.h job.h - scheduler.h jobclasses.h paste.h slavebase.h - progressbase.h defaultprogress.h statusbarprogress.h - tcpslavebase.h forwardingslavebase.h observer.h - chmodjob.h kmdbase.h authinfo.h ioslave_defaults.h - http_slave_defaults.h previewjob.h thumbcreator.h - metainfojob.h davjob.h renamedlg.h skipdlg.h - ${CMAKE_CURRENT_BINARY_DIR}/uiserver_stub.h - DESTINATION ${INCLUDE_INSTALL_DIR}/kio ) - - -##### kiocore ################################### - -set( target kiocore ) - -set( ${target}_SRCS - authinfo.cpp kshred.cpp kprotocolmanager.cpp slave.cpp - slaveinterface.cpp observer.stub sessiondata.cpp - scheduler.cpp connection.cpp job.cpp global.cpp - slaveconfig.cpp kurlpixmapprovider.cpp netaccess.cpp - paste.cpp pastedialog.cpp kmimemagic.cpp tcpslavebase.cpp - slavebase.cpp passdlg.cpp forwardingslavebase.cpp - progressbase.cpp defaultprogress.cpp statusbarprogress.cpp - kdirnotify.cpp kdirnotify.skel kdirnotify_stub.cpp - observer.cpp ../misc/uiserver.stub observer.skel kemailsettings.cpp - kprotocolinfo.cpp renamedlg.cpp skipdlg.cpp kremoteencoding.cpp - kmimetypechooser.cpp -) - -tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES ${${target}_SRCS} - DEPENDENCIES dcopidl -) - - -##### tdesycoca ################################### - -set( target tdesycoca ) - -set( ${target}_SRCS - kdirwatch.cpp kfileshare.cpp ksambashare.cpp - knfsshare.cpp ktrader.cpp ktraderparse.cpp - ktraderparsetree.cpp kservicetypefactory.cpp - kservicetype.cpp kmimetype.cpp kservicegroup.cpp - kservice.cpp kservicefactory.cpp kuserprofile.cpp - kservicegroupfactory.cpp kurifilter.cpp kfilterbase.cpp - kfilterdev.cpp kshellcompletion.cpp kurlcompletion.cpp - kautomount.cpp krun.cpp kfileitem.cpp kdirlister.cpp - kimageio.cpp yacc.c lex.c chmodjob.cpp kscan.cpp - kar.cpp ktar.cpp kzip.cpp previewjob.cpp metainfojob.cpp - davjob.cpp kdatatool.cpp karchive.cpp kfilefilter.cpp - kfilemetainfo.cpp kdcopservicestarter.cpp dataslave.cpp - dataprotocol.cpp -) - -# FIXME seems that ACL is no longer optional -#if( USE_POSIX_ACL ) - set( ${target}_SRCS ${${target}_SRCS} kacl.cpp posixacladdons.cpp ) -#endif( USE_POSIX_ACL ) - -tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES ${${target}_SRCS} - LINK ${GAMIN_LIBRARIES} -) - - -##### tdelficon ################################### - -if( HAVE_ELFICON ) - - set( target tdelficon ) - - set( ${target}_SRCS - tdelficon.cpp - ) - - tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES ${${target}_SRCS} - ) - -endif( HAVE_ELFICON ) diff --git a/kio/kio/KFILEMETAINFO_ISSUES b/kio/kio/KFILEMETAINFO_ISSUES deleted file mode 100644 index a4486f85f..000000000 --- a/kio/kio/KFILEMETAINFO_ISSUES +++ /dev/null @@ -1,4 +0,0 @@ -Bugs: -===== - -currently none known diff --git a/kio/kio/Makefile.am b/kio/kio/Makefile.am deleted file mode 100644 index 63d5fc5d8..000000000 --- a/kio/kio/Makefile.am +++ /dev/null @@ -1,129 +0,0 @@ -# This file is part of the KDE libraries -# Copyright (C) 1997 Torben Weis (weis@kde.org) - -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. - -# This library 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 -# Library General Public License for more details. - -# You should have received a copy of the GNU Library General Public License -# along with this library; see the file COPYING.LIB. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301, USA. - -AM_CPPFLAGS = -D_LARGEFILE64_SOURCE - -INCLUDES= -I$(top_srcdir) -I$(srcdir)/.. -I$(top_srcdir)/tdecore/network -I$(srcdir)/../kssl -I../kssl -I$(srcdir)/../../interfaces $(all_includes) $(SSL_INCLUDES) - -noinst_LTLIBRARIES = libkiocore.la libtdesycoca.la - -# convenience lib - no LDFLAGS or LIBADD ! - -libtdesycoca_la_SOURCES = \ - kdirwatch.cpp \ - kfileshare.cpp ksambashare.cpp knfsshare.cpp \ - ktrader.cpp ktraderparse.cpp ktraderparsetree.cpp \ - kservicetypefactory.cpp kservicetype.cpp \ - kmimetype.cpp kservicegroup.cpp \ - kservice.cpp kservicefactory.cpp \ - kuserprofile.cpp kservicegroupfactory.cpp \ - kurifilter.cpp \ - kfilterbase.cpp kfilterdev.cpp \ - kshellcompletion.cpp kurlcompletion.cpp \ - kautomount.cpp krun.cpp \ - kfileitem.cpp kdirlister.cpp kimageio.cpp \ - yacc.c lex.c \ - chmodjob.cpp kscan.cpp kar.cpp ktar.cpp kzip.cpp previewjob.cpp metainfojob.cpp davjob.cpp \ - kdatatool.cpp karchive.cpp kfilefilter.cpp \ - kfilemetainfo.cpp kdcopservicestarter.cpp \ - dataslave.cpp dataprotocol.cpp -#if USE_POSIX_ACL - libtdesycoca_la_SOURCES += kacl.cpp posixacladdons.cpp -#endif - -include_HEADERS = \ - kservicetype.h kmimetype.h kmimemagic.h kservice.h \ - krun.h kdirwatch.h kautomount.h kuserprofile.h \ - kshred.h kar.h ktar.h kzip.h ktrader.h kurifilter.h kurlcompletion.h \ - kshellcompletion.h kfileitem.h kfileshare.h ksambashare.h knfsshare.h \ - kdirlister.h kservicegroup.h \ - kimageio.h kdirnotify.h kdirnotify_stub.h \ - kurlpixmapprovider.h kprotocolinfo.h kprotocolmanager.h \ - kfilterbase.h kfilterdev.h kemailsettings.h kscan.h kdatatool.h \ - karchive.h kfilefilter.h kfilemetainfo.h renamedlgplugin.h \ - kmimetyperesolver.h kdcopservicestarter.h kremoteencoding.h \ - kmimetypechooser.h -#if USE_POSIX_ACL -include_HEADERS += kacl.h -#endif - -#libkiocore_la_LDFLAGS = $(all_libraries) -#libkiocore_la_LIBADD = ../../tdeui/libtdeui.la ../../tdesu/libtdesu.la $(LIBZ) $(LIBFAM) $(LIBVOLMGT) - -libkiocore_la_SOURCES = authinfo.cpp \ - kshred.cpp \ - kprotocolmanager.cpp \ - slave.cpp slaveinterface.cpp observer.stub \ - sessiondata.cpp scheduler.cpp \ - connection.cpp \ - job.cpp global.cpp \ - slaveconfig.cpp kurlpixmapprovider.cpp \ - netaccess.cpp paste.cpp pastedialog.cpp \ - kmimemagic.cpp \ - tcpslavebase.cpp slavebase.cpp passdlg.cpp \ - forwardingslavebase.cpp \ - progressbase.cpp defaultprogress.cpp \ - statusbarprogress.cpp \ - kdirnotify.cpp kdirnotify.skel kdirnotify_stub.cpp \ - observer.cpp uiserver.stub observer.skel \ - kemailsettings.cpp \ - kprotocolinfo.cpp \ - renamedlg.cpp skipdlg.cpp kremoteencoding.cpp \ - kmimetypechooser.cpp - -uiserver_DIR = $(top_srcdir)/kio/misc - -METASOURCES = AUTO - -kioincludedir = $(includedir)/kio -kioinclude_HEADERS = connection.h \ - slaveinterface.h slave.h slaveconfig.h \ - sessiondata.h global.h passdlg.h \ - netaccess.h job.h scheduler.h \ - jobclasses.h paste.h slavebase.h \ - progressbase.h defaultprogress.h \ - statusbarprogress.h tcpslavebase.h \ - forwardingslavebase.h \ - observer.h chmodjob.h uiserver_stub.h \ - kmdbase.h authinfo.h \ - ioslave_defaults.h http_slave_defaults.h previewjob.h thumbcreator.h \ - metainfojob.h davjob.h renamedlg.h skipdlg.h - -# Internal -noinst_HEADERS = kservicetypefactory.h kservicefactory.h \ - kmessageboxwrapper.h \ - ktraderparse.h ktraderparsetree.h yacc.h \ - kimageiofactory.h kdirwatch_p.h kdirlister_p.h \ - renamedlg.h skipdlg.h dataslave.h dataprotocol.h \ - kservice_p.h -#if USE_POSIX_ACL -noinst_HEADERS += posixacladdons.h -#endif - -parserfiles = yacc.y lex.l - -EXTRA_DIST = $(parserfiles) - -parser: $(parserfiles) - cd $(srcdir) ;\ - flex -olex.c -Pkiotrader lex.l ;\ - bison -d -p kiotrader yacc.y && mv yacc.tab.c yacc.c; mv yacc.tab.h yacc.h - -.PHONY: parser - -include ../../admin/Doxyfile.am diff --git a/kio/kio/authinfo.cpp b/kio/kio/authinfo.cpp deleted file mode 100644 index 483bc682f..000000000 --- a/kio/kio/authinfo.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include <config.h> - -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <tqdir.h> -#include <tqfile.h> - -#include <kdebug.h> -#include <kstandarddirs.h> -#include <ksavefile.h> -#include <kstaticdeleter.h> -#include <kde_file.h> - -#include "kio/authinfo.h" - -#define NETRC_READ_BUF_SIZE 4096 - -using namespace TDEIO; - -AuthInfo::AuthInfo() -{ - modified = false; - readOnly = false; - verifyPath = false; - keepPassword = false; -} - -AuthInfo::AuthInfo( const AuthInfo& info ) -{ - (*this) = info; -} - -AuthInfo& AuthInfo::operator= ( const AuthInfo& info ) -{ - url = info.url; - username = info.username; - password = info.password; - prompt = info.prompt; - caption = info.caption; - comment = info.comment; - commentLabel = info.commentLabel; - realmValue = info.realmValue; - digestInfo = info.digestInfo; - verifyPath = info.verifyPath; - readOnly = info.readOnly; - keepPassword = info.keepPassword; - modified = info.modified; - return *this; -} - -TQDataStream& TDEIO::operator<< (TQDataStream& s, const AuthInfo& a) -{ - s << a.url << a.username << a.password << a.prompt << a.caption - << a.comment << a.commentLabel << a.realmValue << a.digestInfo - << TQ_UINT8(a.verifyPath ? 1:0) << TQ_UINT8(a.readOnly ? 1:0) - << TQ_UINT8(a.keepPassword ? 1:0) << TQ_UINT8(a.modified ? 1:0); - return s; -} - -TQDataStream& TDEIO::operator>> (TQDataStream& s, AuthInfo& a) -{ - TQ_UINT8 verify = 0; - TQ_UINT8 ro = 0; - TQ_UINT8 keep = 0; - TQ_UINT8 mod = 0; - - s >> a.url >> a.username >> a.password >> a.prompt >> a.caption - >> a.comment >> a.commentLabel >> a.realmValue >> a.digestInfo - >> verify >> ro >> keep >> mod; - a.verifyPath = (verify != 0); - a.readOnly = (ro != 0); - a.keepPassword = (keep != 0); - a.modified = (mod != 0); - return s; -} - - -NetRC* NetRC::instance = 0L; - -NetRC::NetRC() -{ - isDirty = false; -} - -NetRC::~NetRC() -{ - delete instance; - instance = 0L; -} - -NetRC* NetRC::self() -{ - if ( !instance ) - instance = new NetRC(); - return instance; -} - -bool NetRC::lookup( const KURL& url, AutoLogin& login, bool userealnetrc, - TQString type, int mode ) -{ - // kdDebug() << "AutoLogin lookup for: " << url.host() << endl; - if ( !url.isValid() ) - return false; - - if ( type.isEmpty() ) - type = url.protocol(); - - if ( loginMap.isEmpty() || isDirty ) - { - loginMap.clear(); - - TQString filename = locateLocal("config", "kionetrc"); - bool status = parse (openf (filename)); - - if ( userealnetrc ) - { - filename = TQDir::homeDirPath()+ TQDir::separator() + ".netrc"; - status |= parse (openf(filename)); - } - - if ( !status ) - return false; - } - - if ( !loginMap.contains( type ) ) - return false; - - LoginList l = loginMap[type]; - if ( l.isEmpty() ) - return false; - - for (LoginList::Iterator it = l.begin(); it != l.end(); ++it) - { - AutoLogin &log = *it; - - if ( (mode & defaultOnly) == defaultOnly && - log.machine == TQString::fromLatin1("default") && - (login.login.isEmpty() || login.login == log.login) ) - { - login.type = log.type; - login.machine = log.machine; - login.login = log.login; - login.password = log.password; - login.macdef = log.macdef; - } - - if ( (mode & presetOnly) == presetOnly && - log.machine == TQString::fromLatin1("preset") && - (login.login.isEmpty() || login.login == log.login) ) - { - login.type = log.type; - login.machine = log.machine; - login.login = log.login; - login.password = log.password; - login.macdef = log.macdef; - } - - if ( (mode & exactOnly) == exactOnly && - log.machine == url.host() && - (login.login.isEmpty() || login.login == log.login) ) - { - login.type = log.type; - login.machine = log.machine; - login.login = log.login; - login.password = log.password; - login.macdef = log.macdef; - break; - } - } - - return true; -} - -int NetRC::openf( const TQString& f ) -{ - KDE_struct_stat sbuff; - TQCString ef = TQFile::encodeName(f); - if ( KDE_stat(ef, &sbuff) != 0 ) - return -1; - - // Security check!! - if ( sbuff.st_mode != (S_IFREG|S_IRUSR|S_IWUSR) || - sbuff.st_uid != geteuid() ) - return -1; - - return KDE_open( ef, O_RDONLY ); -} - -TQString NetRC::extract( const char* buf, const char* key, int& pos ) -{ - int idx = pos; - int m_len = strlen(key); - int b_len = strlen(buf); - - while( idx < b_len ) - { - while( buf[idx] == ' ' || buf[idx] == '\t' ) - idx++; - - if ( strncasecmp( buf+idx, key, m_len ) != 0 ) - idx++; - else - { - idx += m_len; - while( buf[idx] == ' ' || buf[idx] == '\t' ) - idx++; - - int start = idx; - while( buf[idx] != ' ' && buf[idx] != '\t' && - buf[idx] != '\n' && buf[idx] != '\r' ) - idx++; - - if ( idx > start ) - { - pos = idx; - return TQString::fromLatin1( buf+start, idx-start); - } - } - } - - return TQString::null; -} - -bool NetRC::parse( int fd ) -{ - if (fd == -1) - return false; - - TQString type; - TQString macro; - - uint index = 0; - bool isMacro = false; - char* buf = new char[NETRC_READ_BUF_SIZE]; - FILE* fstream = KDE_fdopen( fd,"rb" ); - - while ( fgets (buf, NETRC_READ_BUF_SIZE, fstream) != 0L ) - { - int pos = 0; - - while ( buf[pos] == ' ' || buf[pos] == '\t' ) - pos++; - - if ( buf[pos] == '#' || buf[pos] == '\n' || - buf[pos] == '\r' || buf[pos] == '\0' ) - { - if ( buf[pos] != '#' && isMacro ) - isMacro = false; - - continue; - } - - if ( isMacro ) - { - int tail = strlen(buf); - while( buf[tail-1] == '\n' || buf[tail-1] =='\r' ) - tail--; - - TQString mac = TQString::fromLatin1(buf, tail).stripWhiteSpace(); - if ( !mac.isEmpty() ) - loginMap[type][index].macdef[macro].append( mac ); - - continue; - } - - AutoLogin l; - l.machine = extract( buf, "machine", pos ); - if ( l.machine.isEmpty() ) - { - if (strncasecmp(buf+pos, "default", 7) == 0 ) - { - pos += 7; - l.machine = TQString::fromLatin1("default"); - } - else if (strncasecmp(buf+pos, "preset", 6) == 0 ) - { - pos += 6; - l.machine = TQString::fromLatin1("preset"); - } - } - // kdDebug() << "Machine: " << l.machine << endl; - - l.login = extract( buf, "login", pos ); - // kdDebug() << "Login: " << l.login << endl; - - l.password = extract( buf, "password", pos ); - if ( l.password.isEmpty() ) - l.password = extract( buf, "account", pos ); - // kdDebug() << "Password: " << l.password << endl; - - type = l.type = extract( buf, "type", pos ); - if ( l.type.isEmpty() && !l.machine.isEmpty() ) - type = l.type = TQString::fromLatin1("ftp"); - // kdDebug() << "Type: " << l.type << endl; - - macro = extract( buf, "macdef", pos ); - isMacro = !macro.isEmpty(); - // kdDebug() << "Macro: " << macro << endl; - - loginMap[l.type].append(l); - index = loginMap[l.type].count()-1; - } - - delete [] buf; - fclose (fstream); - close (fd); - return true; -} diff --git a/kio/kio/authinfo.h b/kio/kio/authinfo.h deleted file mode 100644 index 019311ef8..000000000 --- a/kio/kio/authinfo.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __KIO_AUTHINFO_H -#define __KIO_AUTHINFO_H - -#include <tqmap.h> -#include <tqvaluelist.h> -#include <kurl.h> - - -namespace TDEIO { - -/** - * This class is intended to make it easier to prompt for, cache - * and retrieve authorization information. - * - * When using this class to cache, retrieve or prompt authentication - * information, you only need to set the necessary attributes. For - * example, to check whether a password is already cached, the only - * required information is the URL of the resource and optionally - * whether or not a path match should be performed. Similarly, to - * prompt for password you only need to optionally set the prompt, - * username (if already supplied), comment and commentLabel fields. - * - * <em>SPECIAL NOTE:</em> If you extend this class to add additional - * parameters do not forget to overload the stream insertion and - * extraction operators ("<<" and ">>") so that the added data can - * be correctly serialzed. - * - * @short A two way messaging class for passing authentication information. - * @author Dawit Alemayehu <adawit@kde.org> - */ -class TDEIO_EXPORT AuthInfo -{ - TDEIO_EXPORT friend TQDataStream& operator<< (TQDataStream& s, const AuthInfo& a); - TDEIO_EXPORT friend TQDataStream& operator>> (TQDataStream& s, AuthInfo& a); - -public: - /** - * Default constructor. - */ - AuthInfo(); - - /** - * Copy constructor. - */ - AuthInfo( const AuthInfo& info ); - - /** - * Overloaded equal to operator. - */ - AuthInfo& operator=( const AuthInfo& info ); - - /** - * Use this method to check if the object was modified. - * @return true if the object has been modified - */ - bool isModified() const { return modified; } - - /** - * Use this method to indicate that this object has been modified. - * @param flag true to mark the object as modified, false to clear - */ - void setModified( bool flag ) { modified = flag; } - - /** - * The URL for which authentication is to be stored. - * - * This field is required when attempting to cache authorization - * and retrieve it. However, it is not needed when prompting - * the user for authorization info. - * - * This setting is @em required except when prompting the - * user for password. - */ - KURL url; - - /** - * This is @em required for caching. - */ - TQString username; - - /** - * This is @em required for caching. - */ - TQString password; - - /** - * Information to be displayed when prompting - * the user for authentication information. - * - * @note If this field is not set, the authentication - * dialog simply displays the preset default prompt. - * - * This setting is @em optional and empty by default. - */ - TQString prompt; - - /** - * The text to displayed in the title bar of - * the password prompting dialog. - * - * @note If this field is not set, the authentication - * dialog simply displays the preset default caption. - * - * This setting is @em optional and empty by default. - */ - TQString caption; - - /** - * Additional comment to be displayed when prompting - * the user for authentication information. - * - * This field allows you to display a short (no more than - * 80 characters) extra description in the password prompt - * dialog. For example, this field along with the - * commentLabel can be used to describe the server that - * requested the authentication: - * - * \code - * Server: Squid Proxy @ foo.com - * \endcode - * - * where "Server:" is the commentLabel and the rest is the - * actual comment. Note that it is always better to use - * the @p commentLabel field as it will be placed properly - * in the dialog rather than to include it within the actual - * comment. - * - * This setting is @em optional and empty by default. - */ - TQString comment; - - /** - * Descriptive label to be displayed in front of the - * comment when prompting the user for password. - * - * This setting is @em optional and only applicable when - * the comment field is also set. - */ - TQString commentLabel; - - /** - * A unique identifier that allows caching of multiple - * passwords for different resources in the same server. - * - * Mostly this setting is applicable to the HTTP protocol - * whose authentication scheme explicitly defines the use - * of such a unique key. However, any protocol that can - * generate or supply a unique id can effectively use it - * to distinguish passwords. - * - * (If you are instead interested in caching the authentication - * info for multiple users to the same server, refer to - * multipleUserCaching below) - * - * This setting is @em optional and not set by default. - */ - TQString realmValue; - - /** - * Field to store any extra authentication information for - * protocols that need it (ex: http). - * - * This setting is @em optional and mostly applicable for HTTP - * protocol. However, any protocol can make use of it to - * store extra info. - */ - TQString digestInfo; - - /** - * Flag that, if set, indicates whether a path match should be - * performed when requesting for cached authorization. - * - * A path is deemed to be a match if it is equal to or is a subset - * of the cached path. For example, if stored path is "/foo/bar" - * and the request's path set to "/foo/bar/acme", then it is a match - * whereas it would not if the request's path was set to "/foo". - * - * This setting is @em optional and false by default. - */ - bool verifyPath; - - /** - * Flag which if set forces the username field to be read-only. - * - * This setting is @em optional and false by default. - */ - bool readOnly; - - /** - * Flag to indicate the persistence of the given password. - * - * This is a two-way flag, when set before calling openPassDlg - * it makes the "keep Password" check box visible to the user. - * In return the flag will indicate the state of the check box. - * By default if the flag is checked the password will be cached - * for the entire life of the current KDE session otherwise the - * cached password is deleted right after the application using - * it has been closed. - */ - bool keepPassword; - -protected: - bool modified; -private: - class AuthInfoPrivate* d; -}; - -TDEIO_EXPORT TQDataStream& operator<< (TQDataStream& s, const AuthInfo& a); -TDEIO_EXPORT TQDataStream& operator>> (TQDataStream& s, AuthInfo& a); - -/** - * A Singleton class that provides access to passwords - * stored in .netrc files for automatic login purposes. - * This is only meant to address backward compatability - * with old automated ftp client style logins... - * - * @short An interface to the ftp .netrc files - * @author Dawit Alemayehu <adawit@kde.org> - */ -class TDEIO_EXPORT NetRC -{ -public: - - /** - * Specifies the mode to be used when searching for a - * matching automatic login info for a given site : - * - * @li exactOnly search entries with exact host name matches. - * @li defaultOnly search entries that are specified as "default". - * @li presetOnly search entries that are specified as "preset". - * - * @see lookup - */ - enum LookUpMode - { - exactOnly = 0x0002, - defaultOnly = 0x0004, - presetOnly = 0x0008 - }; - - /** - * Contains auto login information. - * @see lookup() - */ - struct AutoLogin - { - TQString type; - TQString machine; - TQString login; - TQString password; - TQMap<TQString, TQStringList> macdef; - }; - - /** - * A reference to the instance of the class. - * @return the class - */ - static NetRC* self(); - - /** - * Looks up the @p login information for the given @p url. - * - * @param url the url whose login information will be checked - * @param login the login information will be writte here - * @param userealnetrc if true, use $HOME/.netrc fle - * @param type the type of the login. If null, the @p url's protocol - * will be taken - * @param mode the LookUpMode flags (ORed) for the query - */ - bool lookup( const KURL& url, AutoLogin& login, - bool userealnetrc = false, - TQString type = TQString::null, - int mode = (exactOnly|defaultOnly) ); - /** - * Reloads the auto login information. - */ - void reload() { isDirty = true; } - -protected: - TQString extract( const char*, const char*, int& ); - int openf( const TQString& ); - bool parse( int ); - -private: - NetRC(); - ~NetRC(); - -private: - bool isDirty; - - typedef TQValueList<AutoLogin> LoginList; - typedef TQMap<TQString, LoginList> LoginMap; - LoginMap loginMap; - - static NetRC* instance; - class NetRCPrivate; - NetRCPrivate* d; -}; -} -#endif diff --git a/kio/kio/chmodjob.cpp b/kio/kio/chmodjob.cpp deleted file mode 100644 index f589da957..000000000 --- a/kio/kio/chmodjob.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Stephan Kulow <coolo@kde.org> - David Faure <faure@kde.org> - Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <config.h> - -#include <pwd.h> -#include <grp.h> -#include <sys/types.h> -#include <unistd.h> -#include <assert.h> - -#include <tqtimer.h> -#include <tqfile.h> -#include <klocale.h> -#include <kdebug.h> -#include <kmessagebox.h> - -#include "kio/job.h" -#include "kio/chmodjob.h" - -#include <kdirnotify_stub.h> - -using namespace TDEIO; - -ChmodJob::ChmodJob( const KFileItemList& lstItems, int permissions, int mask, - int newOwner, int newGroup, - bool recursive, bool showProgressInfo ) - : TDEIO::Job( showProgressInfo ), state( STATE_LISTING ), - m_permissions( permissions ), m_mask( mask ), - m_newOwner( newOwner ), m_newGroup( newGroup ), - m_recursive( recursive ), m_lstItems( lstItems ) -{ - TQTimer::singleShot( 0, this, TQT_SLOT(processList()) ); -} - -void ChmodJob::processList() -{ - while ( !m_lstItems.isEmpty() ) - { - KFileItem * item = m_lstItems.first(); - if ( !item->isLink() ) // don't do anything with symlinks - { - // File or directory -> remember to chmod - ChmodInfo info; - info.url = item->url(); - // This is a toplevel file, we apply changes directly (no +X emulation here) - info.permissions = ( m_permissions & m_mask ) | ( item->permissions() & ~m_mask ); - /*kdDebug(7007) << "\n current permissions=" << TQString::number(item->permissions(),8) - << "\n wanted permission=" << TQString::number(m_permissions,8) - << "\n with mask=" << TQString::number(m_mask,8) - << "\n with ~mask (mask bits we keep) =" << TQString::number((uint)~m_mask,8) - << "\n bits we keep =" << TQString::number(item->permissions() & ~m_mask,8) - << "\n new permissions = " << TQString::number(info.permissions,8) - << endl;*/ - m_infos.prepend( info ); - //kdDebug(7007) << "processList : Adding info for " << info.url.prettyURL() << endl; - // Directory and recursive -> list - if ( item->isDir() && m_recursive ) - { - //kdDebug(7007) << "ChmodJob::processList dir -> listing" << endl; - TDEIO::ListJob * listJob = TDEIO::listRecursive( item->url(), false /* no GUI */ ); - connect( listJob, TQT_SIGNAL(entries( TDEIO::Job *, - const TDEIO::UDSEntryList& )), - TQT_SLOT( slotEntries( TDEIO::Job*, - const TDEIO::UDSEntryList& ))); - addSubjob( listJob ); - return; // we'll come back later, when this one's finished - } - } - m_lstItems.removeFirst(); - } - kdDebug(7007) << "ChmodJob::processList -> going to STATE_CHMODING" << endl; - // We have finished, move on - state = STATE_CHMODING; - chmodNextFile(); -} - -void ChmodJob::slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList & list ) -{ - TDEIO::UDSEntryListConstIterator it = list.begin(); - TDEIO::UDSEntryListConstIterator end = list.end(); - for (; it != end; ++it) { - TDEIO::UDSEntry::ConstIterator it2 = (*it).begin(); - mode_t permissions = 0; - bool isDir = false; - bool isLink = false; - TQString relativePath; - for( ; it2 != (*it).end(); it2++ ) { - switch( (*it2).m_uds ) { - case TDEIO::UDS_NAME: - relativePath = (*it2).m_str; - break; - case TDEIO::UDS_FILE_TYPE: - isDir = S_ISDIR((*it2).m_long); - break; - case TDEIO::UDS_LINK_DEST: - isLink = !(*it2).m_str.isEmpty(); - break; - case TDEIO::UDS_ACCESS: - permissions = (mode_t)((*it2).m_long); - break; - default: - break; - } - } - if ( !isLink && relativePath != TQString::fromLatin1("..") ) - { - ChmodInfo info; - info.url = m_lstItems.first()->url(); // base directory - info.url.addPath( relativePath ); - int mask = m_mask; - // Emulate -X: only give +x to files that had a +x bit already - // So the check is the opposite : if the file had no x bit, don't touch x bits - // For dirs this doesn't apply - if ( !isDir ) - { - int newPerms = m_permissions & mask; - if ( (newPerms & 0111) && !(permissions & 0111) ) - { - // don't interfere with mandatory file locking - if ( newPerms & 02000 ) - mask = mask & ~0101; - else - mask = mask & ~0111; - } - } - info.permissions = ( m_permissions & mask ) | ( permissions & ~mask ); - /*kdDebug(7007) << "\n current permissions=" << TQString::number(permissions,8) - << "\n wanted permission=" << TQString::number(m_permissions,8) - << "\n with mask=" << TQString::number(mask,8) - << "\n with ~mask (mask bits we keep) =" << TQString::number((uint)~mask,8) - << "\n bits we keep =" << TQString::number(permissions & ~mask,8) - << "\n new permissions = " << TQString::number(info.permissions,8) - << endl;*/ - // Prepend this info in our todo list. - // This way, the toplevel dirs are done last. - m_infos.prepend( info ); - } - } -} - -void ChmodJob::chmodNextFile() -{ - if ( !m_infos.isEmpty() ) - { - ChmodInfo info = m_infos.first(); - m_infos.remove( m_infos.begin() ); - // First update group / owner (if local file) - // (permissions have to set after, in case of suid and sgid) - if ( info.url.isLocalFile() && ( m_newOwner != -1 || m_newGroup != -1 ) ) - { - TQString path = info.url.path(); - if ( chown( TQFile::encodeName(path), m_newOwner, m_newGroup ) != 0 ) - { - int answer = KMessageBox::warningContinueCancel( 0, i18n( "<qt>Could not modify the ownership of file <b>%1</b>. You have insufficient access to the file to perform the change.</qt>" ).arg(path), TQString::null, i18n("&Skip File") ); - if (answer == KMessageBox::Cancel) - { - m_error = ERR_USER_CANCELED; - emitResult(); - return; - } - } - } - - kdDebug(7007) << "ChmodJob::chmodNextFile chmod'ing " << info.url.prettyURL() - << " to " << TQString::number(info.permissions,8) << endl; - TDEIO::SimpleJob * job = TDEIO::chmod( info.url, info.permissions ); - // copy the metadata for acl and default acl - const TQString aclString = queryMetaData( "ACL_STRING" ); - const TQString defaultAclString = queryMetaData( "DEFAULT_ACL_STRING" ); - if ( !aclString.isEmpty() ) - job->addMetaData( "ACL_STRING", aclString ); - if ( !defaultAclString.isEmpty() ) - job->addMetaData( "DEFAULT_ACL_STRING", defaultAclString ); - addSubjob(job); - } - else - // We have finished - emitResult(); -} - -void ChmodJob::slotResult( TDEIO::Job * job ) -{ - if ( job->error() ) - { - m_error = job->error(); - m_errorText = job->errorText(); - emitResult(); - return; - } - //kdDebug(7007) << " ChmodJob::slotResult( TDEIO::Job * job ) m_lstItems:" << m_lstItems.count() << endl; - switch ( state ) - { - case STATE_LISTING: - subjobs.remove(job); - m_lstItems.removeFirst(); - kdDebug(7007) << "ChmodJob::slotResult -> processList" << endl; - processList(); - return; - case STATE_CHMODING: - subjobs.remove(job); - kdDebug(7007) << "ChmodJob::slotResult -> chmodNextFile" << endl; - chmodNextFile(); - return; - default: - assert(0); - return; - } -} - -// antlarr: KDE 4: Make owner and group be const TQString & -TDEIO_EXPORT ChmodJob *TDEIO::chmod( const KFileItemList& lstItems, int permissions, int mask, - TQString owner, TQString group, - bool recursive, bool showProgressInfo ) -{ - uid_t newOwnerID = (uid_t)-1; // chown(2) : -1 means no change - if ( !owner.isEmpty() ) - { - struct passwd* pw = getpwnam(TQFile::encodeName(owner)); - if ( pw == 0L ) - kdError(250) << " ERROR: No user " << owner << endl; - else - newOwnerID = pw->pw_uid; - } - gid_t newGroupID = (gid_t)-1; // chown(2) : -1 means no change - if ( !group.isEmpty() ) - { - struct group* g = getgrnam(TQFile::encodeName(group)); - if ( g == 0L ) - kdError(250) << " ERROR: No group " << group << endl; - else - newGroupID = g->gr_gid; - } - return new ChmodJob( lstItems, permissions, mask, newOwnerID, newGroupID, recursive, showProgressInfo ); -} - -void ChmodJob::virtual_hook( int id, void* data ) -{ TDEIO::Job::virtual_hook( id, data ); } - -#include "chmodjob.moc" diff --git a/kio/kio/chmodjob.h b/kio/kio/chmodjob.h deleted file mode 100644 index 81b614562..000000000 --- a/kio/kio/chmodjob.h +++ /dev/null @@ -1,109 +0,0 @@ -// -*- c++ -*- -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_chmodjob_h__ -#define __kio_chmodjob_h__ - -#include <kurl.h> -#include <tqstring.h> - -#include <kio/global.h> -#include <kio/job.h> -#include <kfileitem.h> - -namespace TDEIO { - - /** - * This job changes permissions on a list of files or directories, - * optionally in a recursive manner. - * @see TDEIO::chmod() - */ - class TDEIO_EXPORT ChmodJob : public TDEIO::Job - { - Q_OBJECT - public: - /** - * Create new ChmodJobs using the TDEIO::chmod() function. - */ - ChmodJob( const KFileItemList & lstItems, int permissions, int mask, - int newOwner, int newGroup, - bool recursive, bool showProgressInfo ); - - protected: - void chmodNextFile(); - - protected slots: - - virtual void slotResult( TDEIO::Job *job ); - void slotEntries( TDEIO::Job * , const TDEIO::UDSEntryList & ); - void processList(); - - private: - struct ChmodInfo - { - KURL url; - int permissions; - }; - enum { STATE_LISTING, STATE_CHMODING } state; - int m_permissions; - int m_mask; - int m_newOwner; - int m_newGroup; - bool m_recursive; - KFileItemList m_lstItems; - TQValueList<ChmodInfo> m_infos; - protected: - virtual void virtual_hook( int id, void* data ); - private: - class ChmodJobPrivate* d; - }; - - - /** - * Creates a job that changes permissions/ownership on several files or directories, - * optionally recursively. - * This version of chmod uses a KFileItemList so that it directly knows - * what to do with the items. TODO: a version that takes a KURL::List, - * and a general job that stats each url and returns a KFileItemList. - * - * Note that change of ownership is only supported for local files. - * - * Inside directories, the "x" bits will only be changed for files that had - * at least one "x" bit before, and for directories. - * This emulates the behavior of chmod +X. - * - * @param lstItems The file items representing several files or directories. - * @param permissions the permissions we want to set - * @param mask the bits we are allowed to change. - * For instance, if mask is 0077, we don't change - * the "user" bits, only "group" and "others". - * @param newOwner If non-empty, the new owner for the files - * @param newGroup If non-empty, the new group for the files - * @param recursive whether to open directories recursively - * @param showProgressInfo true to show progess information - * @return The job handling the operation. - */ - TDEIO_EXPORT ChmodJob * chmod( const KFileItemList& lstItems, int permissions, int mask, - TQString newOwner, TQString newGroup, - bool recursive, bool showProgressInfo = true ); - -} - -#endif diff --git a/kio/kio/configure.in.in b/kio/kio/configure.in.in deleted file mode 100644 index 8683dfec1..000000000 --- a/kio/kio/configure.in.in +++ /dev/null @@ -1,167 +0,0 @@ -dnl ------------------------------------------------------------------------ -dnl Try to find if FAM is installed -dnl ------------------------------------------------------------------------ -dnl -kde_have_fam=yes -AC_ARG_ENABLE(libfam, - AC_HELP_STRING([--disable-libfam],[don't search for libfam and do not use it]), -[ kde_have_fam=$enableval ], [])dnl - -dnl Bloody libfam is C++ and certainly compiled by GNU C++. This means, -dnl we can't use it, when compiling with another C++ compiler, as the -dnl runtime systems would conflict (e.g. in KAI C++) (matz) -test "$GXX" = yes || kde_have_fam=no - -if test "$kde_have_fam" = "yes" ; then - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - KDE_CHECK_LIB(fam, FAMOpen, [LIBFAM="-lfam"; kde_have_fam=yes],kde_have_fam=no) - if test $kde_have_fam = yes; then - AC_DEFINE_UNQUOTED(HAVE_FAM, 1, [Define if your system has libfam]) - fi - AC_LANG_RESTORE -fi -AC_SUBST(LIBFAM) -dnl ------------------------------------------------------------------------ -dnl Try to find if LIBZ is installed -dnl ------------------------------------------------------------------------ -dnl - -AC_FIND_ZLIB - -AC_CHECK_HEADERS(sys/mnttab.h sys/mntent.h mntent.h fstab.h sys/ucred.h sys/mount.h) -AC_CHECK_FUNCS(setmntent getmntinfo) - -AH_VERBATIM(_GETMNTINFO, [ -#ifdef __osf__ -#ifdef __cplusplus -extern "C" { -#endif -#include <sys/mount.h> -int getmntinfo(struct statfs **mntbufp, int flags); -#include <sys/fs_types.h> /* for mnt_names[] */ -#ifdef __cplusplus -} -#endif -#endif -]) - -dnl ------------------------------------------------------------------------ -dnl Try to find if libvolmgt is installed (Solaris) -dnl ------------------------------------------------------------------------ -kde_have_volmgt=yes -AC_CHECK_LIB(volmgt, volmgt_running, [LIBVOLMGT=-lvolmgt], kde_have_volmgt=no) -AC_SUBST(LIBVOLMGT) -if test "$kde_have_volmgt" = "yes"; then - AC_DEFINE_UNQUOTED(HAVE_VOLMGT, 1, [Define, to enable volume management (Solaris 2.x), if you have -lvolmgt]) -fi - -dnl ------------------------------------------------------------------------ -dnl Try to find if we have Linux Dir Notification -dnl ------------------------------------------------------------------------ - -AC_ARG_ENABLE(dnotify, -AC_HELP_STRING([--enable-dnotify],[enable use of Linux directory notifications]), -[ kde_enable_dnotify=$enableval ], [])dnl - -AC_CHECK_GNU_EXTENSIONS - -if test "x$kde_enable_dnotify" = "xyes"; then - AC_MSG_CHECKING([for Linux Directory Notification]) - AC_CACHE_VAL(kde_cv_have_dnotify, - [ - kde_cv_have_dnotify=no - AC_LANG_SAVE - AC_LANG_C - - AC_TRY_COMPILE( - [ -#include <fcntl.h> -#include <signal.h> - ], - [ -#ifndef F_NOTIFY -#error no dir notification -#endif - int fd; - siginfo_t *t = 0; - - fcntl(fd, F_SETSIG, SIGRTMIN); - fcntl(fd, F_NOTIFY, DN_DELETE|DN_CREATE|DN_MULTISHOT); - - ],kde_cv_have_dnotify=yes) - - AC_LANG_RESTORE - ]) - - if test "$kde_cv_have_dnotify" = "yes" ; then - AC_DEFINE_UNQUOTED(HAVE_DNOTIFY, 1, [Define if your system has Linux Directory Notification]) - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi -fi - -dnl ------------------------------------------------------------------------ -dnl Try to find if we have Linux Inode based Dir Notification -dnl ------------------------------------------------------------------------ - -AC_ARG_ENABLE(inotify, -AC_HELP_STRING([--disable-inotify],[enable use of Linux inode notifications]), -[ kde_enable_inotify=$enableval ], [kde_enable_inotify=yes])dnl - -AC_CHECK_GNU_EXTENSIONS - -if test "x$kde_enable_inotify" = "xyes"; then - AC_MSG_CHECKING([for Linux Inotify Notification]) - AC_CACHE_VAL(kde_cv_have_inotify, - [ - kde_cv_have_inotify=no - AC_LANG_SAVE - AC_LANG_C - - AC_TRY_COMPILE( - [ -#include <asm/unistd.h> -#define _S390_BITOPS_H -#include <linux/inotify.h> - ], - [ -#ifndef IN_ALL_EVENTS -#error no inotify notification -#endif - - ],kde_cv_have_inotify=yes,kde_cv_have_inotify=no) - - AC_LANG_RESTORE - ]) - - AC_CACHE_VAL(kde_cv_have_sys_inotify, - [ - kde_cv_have_sys_inotify=no - AC_LANG_SAVE - AC_LANG_C - - AC_TRY_COMPILE( - [ -#include <sys/inotify.h> - ], - [ -#ifndef IN_ALL_EVENTS -#error no inotify notification -#endif - ],kde_cv_have_sys_inotify=yes,kde_cv_have_sys_inotify=no) - - AC_LANG_RESTORE - ]) - - if test "$kde_cv_have_inotify" = "yes" -o "$kde_cv_have_sys_inotify" = "yes"; then - AC_DEFINE_UNQUOTED(HAVE_INOTIFY, 1, [Define if your system has Linux Inode Notification]) - if test "$kde_cv_have_sys_inotify" = "yes"; then - AC_DEFINE_UNQUOTED(HAVE_SYS_INOTIFY, 1, [Define if your system has glibc support for inotify]) - fi - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi -fi diff --git a/kio/kio/connection.cpp b/kio/kio/connection.cpp deleted file mode 100644 index d85f4921c..000000000 --- a/kio/kio/connection.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Stephan Kulow <coolo@kde.org> - David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -// $Id$ - -#include <config.h> - -#include <kde_file.h> -#include <ksock.h> -#include <tqtimer.h> - -#include <sys/types.h> -#include <sys/signal.h> -#include <sys/time.h> - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <unistd.h> - -#include "kio/connection.h" - -#include <kdebug.h> -#include <tqsocketnotifier.h> - -using namespace TDEIO; - -Connection::Connection() -{ - f_out = 0; - fd_in = -1; - socket = 0; - notifier = 0; - receiver = 0; - member = 0; - m_suspended = false; - tasks.setAutoDelete(true); -} - -Connection::~Connection() -{ - close(); -} - -void Connection::suspend() -{ - m_suspended = true; - if (notifier) - notifier->setEnabled(false); -} - -void Connection::resume() -{ - m_suspended = false; - if (notifier) - notifier->setEnabled(true); -} - -void Connection::close() -{ - delete notifier; - notifier = 0; - delete socket; - socket = 0; - - // TDESocket has already closed the file descriptor, but we need to - // close the file-stream as well otherwise we leak memory. - // As a result we close the file descriptor twice, but that should - // be harmless - // KDE4: fix this - if (f_out) - fclose(f_out); - f_out = 0; - fd_in = -1; - tasks.clear(); -} - -void Connection::send(int cmd, const TQByteArray& data) -{ - if (!inited() || tasks.count() > 0) { - Task *task = new Task(); - task->cmd = cmd; - task->data = data; - tasks.append(task); - } else { - sendnow( cmd, data ); - } -} - -void Connection::dequeue() -{ - if (!inited()) - return; - - while (tasks.count()) - { - tasks.first(); - Task *task = tasks.take(); - sendnow( task->cmd, task->data ); - delete task; - } -} - -void Connection::init(TDESocket *sock) -{ - delete notifier; - notifier = 0; -#ifdef Q_OS_UNIX //TODO: not yet available on WIN32 - delete socket; - socket = sock; - fd_in = socket->socket(); - f_out = KDE_fdopen( socket->socket(), "wb" ); -#endif - if (receiver && ( fd_in != -1 )) { - notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read); - if ( m_suspended ) { - suspend(); - } - TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member); - } - dequeue(); -} - -void Connection::init(int _fd_in, int fd_out) -{ - delete notifier; - notifier = 0; - fd_in = _fd_in; - f_out = KDE_fdopen( fd_out, "wb" ); - if (receiver && ( fd_in != -1 )) { - notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read); - if ( m_suspended ) { - suspend(); - } - TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member); - } - dequeue(); -} - - -void Connection::connect(TQObject *_receiver, const char *_member) -{ - receiver = _receiver; - member = _member; - delete notifier; - notifier = 0; - if (receiver && (fd_in != -1 )) { - notifier = new TQSocketNotifier(fd_in, TQSocketNotifier::Read); - if ( m_suspended ) - suspend(); - TQObject::connect(notifier, TQT_SIGNAL(activated(int)), receiver, member); - } -} - -bool Connection::sendnow( int _cmd, const TQByteArray &data ) -{ - if (f_out == 0) { - return false; - } - - if (data.size() > 0xffffff) - return false; - - static char buffer[ 64 ]; - sprintf( buffer, "%6x_%2x_", data.size(), _cmd ); - - size_t n = fwrite( buffer, 1, 10, f_out ); - - if ( n != 10 ) { - kdError(7017) << "Could not send header" << endl; - return false; - } - - n = fwrite( data.data(), 1, data.size(), f_out ); - - if ( n != data.size() ) { - kdError(7017) << "Could not write data" << endl; - return false; - } - - if (fflush( f_out )) { - kdError(7017) << "Could not write data" << endl; - return false; - } - - return true; -} - -int Connection::read( int* _cmd, TQByteArray &data ) -{ - if (fd_in == -1 ) { - kdError(7017) << "read: not yet inited" << endl; - return -1; - } - - static char buffer[ 10 ]; - - again1: - ssize_t n = ::read( fd_in, buffer, 10); - if ( n == -1 && errno == EINTR ) - goto again1; - - if ( n == -1) { - kdError(7017) << "Header read failed, errno=" << errno << endl; - } - - if ( n != 10 ) { - if ( n ) // 0 indicates end of file - kdError(7017) << "Header has invalid size (" << n << ")" << endl; - return -1; - } - - buffer[ 6 ] = 0; - buffer[ 9 ] = 0; - - char *p = buffer; - while( *p == ' ' ) p++; - long int len = strtol( p, 0L, 16 ); - - p = buffer + 7; - while( *p == ' ' ) p++; - long int cmd = strtol( p, 0L, 16 ); - - data.resize( len ); - - if ( len > 0L ) { - size_t bytesToGo = len; - size_t bytesRead = 0; - do { - n = ::read(fd_in, data.data()+bytesRead, bytesToGo); - if (n == -1) { - if (errno == EINTR) - continue; - - kdError(7017) << "Data read failed, errno=" << errno << endl; - return -1; - } - if ( !n ) { // 0 indicates end of file - kdError(7017) << "Connection ended unexpectedly (" << n << "/" << bytesToGo << ")" << endl; - return -1; - } - - bytesRead += n; - bytesToGo -= n; - } - while(bytesToGo); - } - - *_cmd = cmd; - return len; -} - -#include "connection.moc" diff --git a/kio/kio/connection.h b/kio/kio/connection.h deleted file mode 100644 index fb0b50e15..000000000 --- a/kio/kio/connection.h +++ /dev/null @@ -1,158 +0,0 @@ -// -*- c++ -*- -/* This file is part of the KDE libraries - Copyright (C) 2000 Stephan Kulow <coolo@kde.org> - David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __connection_h__ -#define __connection_h__ - -#include <tdelibs_export.h> - -#include <sys/types.h> - -#include <stdio.h> -#include <tqptrlist.h> -#include <tqobject.h> - -class TDESocket; -class TQSocketNotifier; - -namespace TDEIO { - - struct TDEIO_EXPORT Task { - int cmd; - TQByteArray data; - }; - - /** - * This class provides a simple means for IPC between two applications - * via a pipe. - * It handles a queue of commands to be sent which makes it possible to - * queue data before an actual connection has been established. - */ - class TDEIO_EXPORT Connection : public TQObject - { - Q_OBJECT - public: - /** - * Creates a new connection. - * @see init() - */ - Connection(); - virtual ~Connection(); - - /** - * Initialize this connection to use the given socket. - * @param sock the socket to use - * @see inited() - */ - void init(TDESocket *sock); - /** - * Initialize the connection to use the given file - * descriptors. - * @param fd_in the input file descriptor to use - * @param fd_out the output file descriptor to use - * @see inited() - */ - void init(int fd_in, int fd_out); // Used by KDENOX - void connect(TQObject *receiver = 0, const char *member = 0); - /// Closes the connection. - void close(); - - /** - * Returns the input file descriptor. - * @return the input file descriptor - */ - int fd_from() const { return fd_in; } - /** - * Returns the output file descriptor. - * @return the output file descriptor - */ - int fd_to() const { return fileno( f_out ); } - - /** - * Checks whether the connection has been initialized. - * @return true if the initialized - * @see init() - */ - bool inited() const { return (fd_in != -1) && (f_out != 0); } - - /** - * Sends/queues the given command to be sent. - * @param cmd the command to set - * @param arr the bytes to send - */ - void send(int cmd, const TQByteArray &arr = TQByteArray()); - - /** - * Sends the given command immediately. - * @param _cmd the command to set - * @param data the bytes to send - * @return true if successful, false otherwise - */ - bool sendnow( int _cmd, const TQByteArray &data ); - - /** - * Receive data. - * - * @param _cmd the received command will be written here - * @param data the received data will be written here - * @return >=0 indicates the received data size upon success - * -1 indicates error - */ - int read( int* _cmd, TQByteArray &data ); - - /** - * Don't handle incoming data until resumed. - */ - void suspend(); - - /** - * Resume handling of incoming data. - */ - void resume(); - - /** - * Returns status of connection. - * @return true if suspended, false otherwise - */ - bool suspended() const { return m_suspended; } - - protected slots: - void dequeue(); - - protected: - - - private: - int fd_in; - FILE *f_out; - TDESocket *socket; - TQSocketNotifier *notifier; - TQObject *receiver; - const char *member; - TQPtrList<Task> tasks; - bool m_suspended; - private: - class ConnectionPrivate* d; - }; - -} - -#endif diff --git a/kio/kio/dataprotocol.cpp b/kio/kio/dataprotocol.cpp deleted file mode 100644 index 1e3db04d7..000000000 --- a/kio/kio/dataprotocol.cpp +++ /dev/null @@ -1,339 +0,0 @@ -// dataprotocol.cpp -// ================== -// -// Implementation of the data protocol (rfc 2397) -// -// Author: Leo Savernik -// Email: l.savernik@aon.at -// (C) 2002, 2003 by Leo Savernik -// Created: Sam Dez 28 14:11:18 CET 2002 - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation; version 2. * - * * - ***************************************************************************/ - -#include "dataprotocol.h" - -#include <kdebug.h> -#include <kmdcodec.h> -#include <kurl.h> -#include <kio/global.h> - -#include <tqcstring.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqtextcodec.h> - -#ifdef DATAKIOSLAVE -# include <kinstance.h> -# include <stdlib.h> -#endif -#ifdef TESTKIO -# include <iostream.h> -#endif - -#if !defined(DATAKIOSLAVE) && !defined(TESTKIO) -# define DISPATCH(f) dispatch_##f -#else -# define DISPATCH(f) f -#endif - -using namespace TDEIO; -#ifdef DATAKIOSLAVE -extern "C" { - - int kdemain( int argc, char **argv ) { - TDEInstance instance( "kio_data" ); - - kdDebug(7101) << "*** Starting kio_data " << endl; - - if (argc != 4) { - kdDebug(7101) << "Usage: kio_data protocol domain-socket1 domain-socket2" << endl; - exit(-1); - } - - DataProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - - kdDebug(7101) << "*** kio_data Done" << endl; - return 0; - } -} -#endif - -/** structure containing header information */ -struct DataHeader { - TQString mime_type; // mime type of content (lowercase) - MetaData attributes; // attribute/value pairs (attribute lowercase, - // value unchanged) - bool is_base64; // true if data is base64 encoded - TQString url; // reference to decoded url - int data_offset; // zero-indexed position within url - // where the real data begins. May point beyond - // the end to indicate that there is no data - TQString *charset; // shortcut to charset (it always exists) -}; - -// constant string data -const TQChar text_plain_str[] = { 't','e','x','t','/','p','l','a','i','n' }; -const TQChar charset_str[] = { 'c','h','a','r','s','e','t' }; -const TQChar us_ascii_str[] = { 'u','s','-','a','s','c','i','i' }; -const TQChar base64_str[] = { 'b','a','s','e','6','4' }; - -/** returns the position of the first occurrence of any of the given characters - * @p c1 to @p c3 or buf.length() if none is contained. - * @param buf buffer where to look for c - * @param begin zero-indexed starting position - * @param c1 character to find - * @param c2 alternative character to find or '\0' to ignore - * @param c3 alternative character to find or '\0' to ignore - */ -static int find(const TQString &buf, int begin, TQChar c1, TQChar c2 = '\0', - TQChar c3 = '\0') { - int pos = begin; - int size = (int)buf.length(); - while (pos < size) { - TQChar ch = buf[pos]; - if (ch == c1 - || (c2 != '\0' && ch == c2) - || (c3 != '\0' && ch == c3)) - break; - pos++; - }/*wend*/ - return pos; -} - -/** extracts the string between the current position @p pos and the first - * occurrence of either @p c1 to @p c3 exclusively and updates @p pos - * to point at the found delimiter or at the end of the buffer if - * neither character occurred. - * @param buf buffer where to look for - * @param pos zero-indexed position within buffer - * @param c1 character to find - * @param c2 alternative character to find or 0 to ignore - * @param c3 alternative character to find or 0 to ignore - */ -inline TQString extract(const TQString &buf, int &pos, TQChar c1, - TQChar c2 = '\0', TQChar c3 = '\0') { - int oldpos = pos; - pos = find(buf,oldpos,c1,c2,c3); - return TQString(buf.unicode() + oldpos, pos - oldpos); -} - -/** ignores all whitespaces - * @param buf buffer to operate on - * @param pos position to shift to first non-whitespace character - * Upon return @p pos will either point to the first non-whitespace - * character or to the end of the buffer. - */ -inline void ignoreWS(const TQString &buf, int &pos) { - int size = (int)buf.length(); - TQChar ch = buf[pos]; - while (pos < size && (ch == ' ' || ch == '\t' || ch == '\n' - || ch == '\r')) - ch = buf[++pos]; -} - -/** parses a quoted string as per rfc 822. - * - * If trailing quote is missing, the whole rest of the buffer is returned. - * @param buf buffer to operate on - * @param pos position pointing to the leading quote - * @return the extracted string. @p pos will be updated to point to the - * character following the trailing quote. - */ -static TQString parseQuotedString(const TQString &buf, int &pos) { - int size = (int)buf.length(); - TQString res; - pos++; // jump over leading quote - bool escaped = false; // if true means next character is literal - bool parsing = true; // true as long as end quote not found - while (parsing && pos < size) { - TQChar ch = buf[pos++]; - if (escaped) { - res += ch; - escaped = false; - } else { - switch (ch) { - case '"': parsing = false; break; - case '\\': escaped = true; break; - default: res += ch; break; - }/*end switch*/ - }/*end if*/ - }/*wend*/ - return res; -} - -/** parses the header of a data url - * @param url the data url - * @param header_info fills the given DataHeader structure with the header - * information - */ -static void parseDataHeader(const KURL &url, DataHeader &header_info) { - TQConstString text_plain(text_plain_str,sizeof text_plain_str/sizeof text_plain_str[0]); - TQConstString charset(charset_str,sizeof charset_str/sizeof charset_str[0]); - TQConstString us_ascii(us_ascii_str,sizeof us_ascii_str/sizeof us_ascii_str[0]); - TQConstString base64(base64_str,sizeof base64_str/sizeof base64_str[0]); - // initialize header info members - header_info.mime_type = text_plain.string(); - header_info.charset = &header_info.attributes.insert( - charset.string(),us_ascii.string()) - .data(); - header_info.is_base64 = false; - - // decode url and save it - TQString &raw_url = header_info.url = TQString::fromLatin1("data:") + url.path(); - int raw_url_len = (int)raw_url.length(); - - // jump over scheme part (must be "data:", we don't even check that) - header_info.data_offset = raw_url.find(':'); - header_info.data_offset++; // jump over colon or to begin if scheme was missing - - // read mime type - if (header_info.data_offset >= raw_url_len) return; - TQString mime_type = extract(raw_url,header_info.data_offset,';',',') - .stripWhiteSpace(); - if (!mime_type.isEmpty()) header_info.mime_type = mime_type; - - if (header_info.data_offset >= raw_url_len) return; - // jump over delimiter token and return if data reached - if (raw_url[header_info.data_offset++] == ',') return; - - // read all attributes and store them - bool data_begin_reached = false; - while (!data_begin_reached && header_info.data_offset < raw_url_len) { - // read attribute - TQString attribute = extract(raw_url,header_info.data_offset,'=',';',',') - .stripWhiteSpace(); - if (header_info.data_offset >= raw_url_len - || raw_url[header_info.data_offset] != '=') { - // no assigment, must be base64 option - if (attribute == base64.string()) - header_info.is_base64 = true; - } else { - header_info.data_offset++; // jump over '=' token - - // read value - ignoreWS(raw_url,header_info.data_offset); - if (header_info.data_offset >= raw_url_len) return; - - TQString value; - if (raw_url[header_info.data_offset] == '"') { - value = parseQuotedString(raw_url,header_info.data_offset); - ignoreWS(raw_url,header_info.data_offset); - } else - value = extract(raw_url,header_info.data_offset,';',',') - .stripWhiteSpace(); - - // add attribute to map - header_info.attributes[attribute.lower()] = value; - - }/*end if*/ - if (header_info.data_offset < raw_url_len - && raw_url[header_info.data_offset] == ',') - data_begin_reached = true; - header_info.data_offset++; // jump over separator token - }/*wend*/ -} - -#ifdef DATAKIOSLAVE -DataProtocol::DataProtocol(const TQCString &pool_socket, const TQCString &app_socket) - : SlaveBase("kio_data", pool_socket, app_socket) { -#else -DataProtocol::DataProtocol() { -#endif - kdDebug() << "DataProtocol::DataProtocol()" << endl; -} - -/* --------------------------------------------------------------------- */ - -DataProtocol::~DataProtocol() { - kdDebug() << "DataProtocol::~DataProtocol()" << endl; -} - -/* --------------------------------------------------------------------- */ - -void DataProtocol::get(const KURL& url) { - ref(); - //kdDebug() << "===============================================================================================================================================================================" << endl; - kdDebug() << "kio_data@"<<this<<"::get(const KURL& url)" << endl ; - - DataHeader hdr; - parseDataHeader(url,hdr); - - int size = (int)hdr.url.length(); - int data_ofs = QMIN(hdr.data_offset,size); - // FIXME: string is copied, would be nice if we could have a reference only - TQString url_data = hdr.url.mid(data_ofs); - TQCString outData; - -#ifdef TESTKIO -// cout << "current charset: \"" << *hdr.charset << "\"" << endl; -#endif - if (hdr.is_base64) { - // base64 stuff is expected to contain the correct charset, so we just - // decode it and pass it to the receiver - KCodecs::base64Decode(url_data.local8Bit(),outData); - } else { - // FIXME: This is all flawed, must be reworked thoroughly - // non encoded data must be converted to the given charset - TQTextCodec *codec = TQTextCodec::codecForName(hdr.charset->latin1()); - if (codec != 0) { - outData = codec->fromUnicode(url_data); - } else { - // if there is no approprate codec, just use local encoding. This - // should work for >90% of all cases. - outData = url_data.local8Bit(); - }/*end if*/ - }/*end if*/ - - //kdDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl; - //kdDebug() << "emit mimeType@"<<this << endl ; - mimeType(hdr.mime_type); - //kdDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl; - //kdDebug() << "emit totalSize@"<<this << endl ; - totalSize(outData.size()); - - //kdDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl; - //kdDebug() << "emit setMetaData@"<<this << endl ; -#if defined(TESTKIO) || defined(DATAKIOSLAVE) - MetaData::ConstIterator it; - for (it = hdr.attributes.begin(); it != hdr.attributes.end(); ++it) { - setMetaData(it.key(),it.data()); - }/*next it*/ -#else - setAllMetaData(hdr.attributes); -#endif - - //kdDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl; - //kdDebug() << "emit sendMetaData@"<<this << endl ; - sendMetaData(); - //kdDebug() << "^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C^[[C" << endl; -// kdDebug() << "(1) queue size " << dispatchQueue.size() << endl; - // empiric studies have shown that this shouldn't be queued & dispatched - /*DISPATCH*/(data(outData)); -// kdDebug() << "(2) queue size " << dispatchQueue.size() << endl; - DISPATCH(data(TQByteArray())); -// kdDebug() << "(3) queue size " << dispatchQueue.size() << endl; - DISPATCH(finished()); -// kdDebug() << "(4) queue size " << dispatchQueue.size() << endl; - deref(); -} - -/* --------------------------------------------------------------------- */ - -void DataProtocol::mimetype(const KURL &url) { - ref(); - DataHeader hdr; - parseDataHeader(url,hdr); - mimeType(hdr.mime_type); - finished(); - deref(); -} - -/* --------------------------------------------------------------------- */ - diff --git a/kio/kio/dataprotocol.h b/kio/kio/dataprotocol.h deleted file mode 100644 index 472b42886..000000000 --- a/kio/kio/dataprotocol.h +++ /dev/null @@ -1,71 +0,0 @@ -// dataprotocol.h -// ================ -// -// Interface of the KDE data protocol core operations -// -// Author: Leo Savernik -// Email: l.savernik@aon.at -// (C) 2002 by Leo Savernik -// Created: Sam Dez 28 14:11:18 CET 2002 - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation; version 2. * - * * - ***************************************************************************/ - -#ifndef __dataprotocol_h__ -#define __dataprotocol_h__ - -// dataprotocol.* interprets the following defines -// DATAKIOSLAVE: define if you want to compile this into a stand-alone -// kioslave -// TESTKIO: define for test-driving -// Both defines are mutually exclusive. Defining none of them compiles -// DataProtocol for internal usage within libkiocore. - -class TQString; -class TQCString; - -class KURL; - -#if defined(DATAKIOSLAVE) -# include <kio/slavebase.h> -#elif !defined(TESTKIO) -# include "kio/dataslave.h" -#endif - -namespace TDEIO { - -/** This kioslave provides support of data urls as specified by rfc 2397 - * @see http://www.ietf.org/rfc/rfc2397.txt - * @author Leo Savernik - */ -#if defined(DATAKIOSLAVE) -class DataProtocol : public TDEIO::SlaveBase { -#elif defined(TESTKIO) -class DataProtocol : public TestSlave { -#else -class DataProtocol : public DataSlave { -#endif - -public: -#if defined(DATAKIOSLAVE) - DataProtocol(const TQCString &pool_socket, const TQCString &app_socket); -#else - DataProtocol(); -#endif - virtual ~DataProtocol(); - virtual void mimetype(const KURL &url); - virtual void get(const KURL &url); -#if defined(TESTKIO) - void ref() {} - void deref() {} -#endif -}; - -}/*end namespace*/ - -#endif diff --git a/kio/kio/dataslave.cpp b/kio/kio/dataslave.cpp deleted file mode 100644 index 528368ba5..000000000 --- a/kio/kio/dataslave.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (c) 2003 Leo Savernik <l.savernik@aon.at> - * Derived from slave.cpp - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include <config.h> - -#include "dataslave.h" -#include "dataprotocol.h" - -#include <klocale.h> -#include <kdebug.h> - -#include <tqtimer.h> - -using namespace TDEIO; - -#define KIO_DATA_POLL_INTERVAL 0 - -// don't forget to sync DISPATCH_DECL in dataslave.h -#define DISPATCH_IMPL(type) \ - void DataSlave::dispatch_##type() { \ - if (_suspended) { \ - QueueStruct q(Queue_##type); \ - dispatchQueue.push_back(q); \ - if (!timer->isActive()) timer->start(KIO_DATA_POLL_INTERVAL); \ - } else \ - type(); \ - } - -// don't forget to sync DISPATCH_DECL1 in dataslave.h -#define DISPATCH_IMPL1(type, paramtype, paramname) \ - void DataSlave::dispatch_##type(paramtype paramname) { \ - if (_suspended) { \ - QueueStruct q(Queue_##type); \ - q.paramname = paramname; \ - dispatchQueue.push_back(q); \ - if (!timer->isActive()) timer->start(KIO_DATA_POLL_INTERVAL); \ - } else \ - type(paramname); \ - } - - -DataSlave::DataSlave() : - Slave(true, 0, "data", TQString::null) -{ - //kdDebug() << this << k_funcinfo << endl; - _suspended = false; - timer = new TQTimer(this); - connect(timer, TQT_SIGNAL(timeout()), TQT_SLOT(dispatchNext())); -} - -DataSlave::~DataSlave() { - //kdDebug() << this << k_funcinfo << endl; -} - -void DataSlave::hold(const KURL &/*url*/) { - // ignored -} - -void DataSlave::suspend() { - _suspended = true; - //kdDebug() << this << k_funcinfo << endl; - timer->stop(); -} - -void DataSlave::resume() { - _suspended = false; - //kdDebug() << this << k_funcinfo << endl; - // aarrrgh! This makes the once hyper fast and efficient data protocol - // implementation slow as molasses. But it wouldn't work otherwise, - // and I don't want to start messing around with threads - timer->start(KIO_DATA_POLL_INTERVAL); -} - -// finished is a special case. If we emit it right away, then -// TransferJob::start can delete the job even before the end of the method -void DataSlave::dispatch_finished() { - QueueStruct q(Queue_finished); - dispatchQueue.push_back(q); - if (!timer->isActive()) timer->start(KIO_DATA_POLL_INTERVAL); -} - -void DataSlave::dispatchNext() { - if (dispatchQueue.empty()) { - timer->stop(); - return; - } - - const QueueStruct &q = dispatchQueue.front(); - //kdDebug() << this << k_funcinfo << "dispatching " << q.type << " " << dispatchQueue.size() << " left" << endl; - switch (q.type) { - case Queue_mimeType: mimeType(q.s); break; - case Queue_totalSize: totalSize(q.size); break; - case Queue_sendMetaData: sendMetaData(); break; - case Queue_data: data(q.ba); break; - case Queue_finished: finished(); break; - }/*end switch*/ - - dispatchQueue.pop_front(); -} - -void DataSlave::send(int cmd, const TQByteArray &arr) { - TQDataStream stream(arr, IO_ReadOnly); - - KURL url; - - switch (cmd) { - case CMD_GET: { - stream >> url; - get(url); - break; - } - case CMD_MIMETYPE: { - stream >> url; - mimetype(url); - break; - } - // ignore these (must not emit error, otherwise SIGSEGV occurs) - case CMD_META_DATA: - case CMD_SUBURL: - break; - default: - error(ERR_UNSUPPORTED_ACTION, - unsupportedActionErrorString(TQString::fromLatin1("data"),cmd)); - }/*end switch*/ -} - -bool DataSlave::suspended() { - return _suspended; -} - -void DataSlave::setHost(const TQString &/*host*/, int /*port*/, - const TQString &/*user*/, const TQString &/*passwd*/) { - // irrelevant -> will be ignored -} - -void DataSlave::setConfig(const MetaData &/*config*/) { - // FIXME: decide to handle this directly or not at all -#if 0 - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - stream << config; - slaveconn.send( CMD_CONFIG, data ); -#endif -} - -void DataSlave::setAllMetaData(const MetaData &md) { - meta_data = md; -} - -void DataSlave::sendMetaData() { - emit metaData(meta_data); -} - -void DataSlave::virtual_hook( int id, void* data ) { - switch (id) { - case VIRTUAL_SUSPEND: suspend(); return; - case VIRTUAL_RESUME: resume(); return; - case VIRTUAL_SEND: { - SendParams *params = reinterpret_cast<SendParams *>(data); - send(params->cmd, *params->arr); - return; - } - case VIRTUAL_HOLD: { - HoldParams *params = reinterpret_cast<HoldParams *>(data); - hold(*params->url); - return; - } - case VIRTUAL_SUSPENDED: { - SuspendedParams *params = reinterpret_cast<SuspendedParams *>(data); - params->retval = suspended(); - return; - } - case VIRTUAL_SET_HOST: { - SetHostParams *params = reinterpret_cast<SetHostParams *>(data); - setHost(*params->host,params->port,*params->user,*params->passwd); - return; - } - case VIRTUAL_SET_CONFIG: { - SetConfigParams *params = reinterpret_cast<SetConfigParams *>(data); - setConfig(*params->config); - return; - } - default: - TDEIO::Slave::virtual_hook( id, data ); - } -} - -DISPATCH_IMPL1(mimeType, const TQString &, s) -DISPATCH_IMPL1(totalSize, TDEIO::filesize_t, size) -DISPATCH_IMPL(sendMetaData) -DISPATCH_IMPL1(data, const TQByteArray &, ba) - -#undef DISPATCH_IMPL -#undef DISPATCH_IMPL1 - -#include "dataslave.moc" diff --git a/kio/kio/dataslave.h b/kio/kio/dataslave.h deleted file mode 100644 index 3567f3faf..000000000 --- a/kio/kio/dataslave.h +++ /dev/null @@ -1,126 +0,0 @@ -// -*- c++ -*- -/* - * This file is part of the KDE libraries - * Copyright (c) 2003 Leo Savernik <l.savernik@aon.at> - * Derived from slave.h - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#ifndef __KIO_DATASLAVE_H__ -#define __KIO_DATASLAVE_H__ - -#include <kio/global.h> -#include <kio/slave.h> - -class TQTimer; - -// don't forget to sync DISPATCH_IMPL in dataslave.h -#define DISPATCH_DECL(type) \ - void dispatch_##type(); - -// don't forget to sync DISPATCH_IMPL1 in dataslave.h -#define DISPATCH_DECL1(type, paramtype, param) \ - void dispatch_##type(paramtype param); - -namespace TDEIO { - - /** - * This class provides a high performance implementation for the data - * url scheme (rfc2397). - * - * @internal - * Do not use this class in external applications. It is an implementation - * detail of KIO and subject to change without notice. - * @author Leo Savernik - */ - class DataSlave : public TDEIO::Slave { - Q_OBJECT - public: - DataSlave(); - - virtual ~DataSlave(); - - virtual void setHost(const TQString &host, int port, - const TQString &user, const TQString &passwd); - virtual void setConfig(const MetaData &config); - - virtual void suspend(); - virtual void resume(); - virtual bool suspended(); - virtual void send(int cmd, const TQByteArray &data = TQByteArray()); - - virtual void hold(const KURL &url); - - // pure virtual methods that are defined by the actual protocol - virtual void get(const KURL &url) = 0; - virtual void mimetype(const KURL &url) = 0; - - protected: - /** - * Sets metadata - * @internal - */ - void setAllMetaData(const MetaData &); - /** - * Sends metadata set with setAllMetaData - * @internal - */ - void sendMetaData(); - - // queueing methods - /** identifiers of functions to be queued */ - enum QueueType { Queue_mimeType = 1, Queue_totalSize, - Queue_sendMetaData, Queue_data, Queue_finished }; - /** structure for queueing. It is very primitive, it doesn't - * even try to conserve memory. - */ - struct QueueStruct { - QueueType type; - TQString s; - TDEIO::filesize_t size; - TQByteArray ba; - - QueueStruct() {} - QueueStruct(QueueType type) : type(type) {} - }; - typedef TQValueList<QueueStruct> DispatchQueue; - DispatchQueue dispatchQueue; - - DISPATCH_DECL1(mimeType, const TQString &, s) - DISPATCH_DECL1(totalSize, TDEIO::filesize_t, size) - DISPATCH_DECL(sendMetaData) - DISPATCH_DECL1(data, const TQByteArray &, ba) - DISPATCH_DECL(finished) - - protected slots: - /** dispatches next queued method. Does nothing if there are no - * queued methods. - */ - void dispatchNext(); - protected: - virtual void virtual_hook( int id, void* data ); - private: - MetaData meta_data; - bool _suspended; - TQTimer *timer; - }; - -} - -#undef DISPATCH_DECL -#undef DISPATCH_DECL1 - -#endif /*__KIO_DATASLAVE_H__*/ diff --git a/kio/kio/davjob.cpp b/kio/kio/davjob.cpp deleted file mode 100644 index f1ba2d2d4..000000000 --- a/kio/kio/davjob.cpp +++ /dev/null @@ -1,142 +0,0 @@ -// -*- c++ -*- -/* This file is part of the KDE libraries - Copyright (C) 2002 Jan-Pascal van Best <janpascal@vanbest.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <kurl.h> - -#include <tqobject.h> -#include <tqptrlist.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqguardedptr.h> -#include <tqdom.h> - -#include <sys/types.h> -#include <sys/stat.h> - -#include <kdebug.h> -#include <kio/jobclasses.h> -#include <kio/global.h> -#include <kio/http.h> -#include <kio/davjob.h> -#include <kio/job.h> -#include <kio/slaveinterface.h> - -#define KIO_ARGS TQByteArray packedArgs; TQDataStream stream( packedArgs, IO_WriteOnly ); stream - -using namespace TDEIO; - -class DavJob::DavJobPrivate -{ -public: - TQByteArray savedStaticData; - TQByteArray str_response; // replaces the TQString previously used in DavJob itself -}; - -DavJob::DavJob( const KURL& url, int method, const TQString& request, bool showProgressInfo ) - : TransferJob( url, TDEIO::CMD_SPECIAL, TQByteArray(), TQByteArray(), showProgressInfo ) -{ - d = new DavJobPrivate; - // We couldn't set the args when calling the parent constructor, - // so do it now. - TQDataStream stream( m_packedArgs, IO_WriteOnly ); - stream << (int) 7 << url << method; - // Same for static data - if ( ! request.isEmpty() && ! request.isNull() ) { - staticData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" + request.utf8(); - staticData.truncate( staticData.size() - 1 ); - d->savedStaticData = staticData.copy(); - } -} - -void DavJob::slotData( const TQByteArray& data ) -{ - if(m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error) { - unsigned int oldSize = d->str_response.size(); - d->str_response.resize( oldSize + data.size() ); - memcpy( d->str_response.data() + oldSize, data.data(), data.size() ); - } -} - -void DavJob::slotFinished() -{ - // kdDebug(7113) << "DavJob::slotFinished()" << endl; - // kdDebug(7113) << d->str_response << endl; - if (!m_redirectionURL.isEmpty() && m_redirectionURL.isValid() && (m_command == CMD_SPECIAL)) { - TQDataStream istream( m_packedArgs, IO_ReadOnly ); - int s_cmd, s_method; - KURL s_url; - istream >> s_cmd; - istream >> s_url; - istream >> s_method; - // PROPFIND - if ( (s_cmd == 7) && (s_method == (int)TDEIO::DAV_PROPFIND) ) { - m_packedArgs.truncate(0); - TQDataStream stream( m_packedArgs, IO_WriteOnly ); - stream << (int)7 << m_redirectionURL << (int)TDEIO::DAV_PROPFIND; - } - } else if ( ! m_response.setContent( d->str_response, true ) ) { - // An error occurred parsing the XML response - TQDomElement root = m_response.createElementNS( "DAV:", "error-report" ); - m_response.appendChild( root ); - - TQDomElement el = m_response.createElementNS( "DAV:", "offending-response" ); - TQDomText textnode = m_response.createTextNode( d->str_response ); - el.appendChild( textnode ); - root.appendChild( el ); - delete d; // Should be in virtual destructor - d = 0; - } else { - delete d; // Should be in virtual destructor - d = 0; - } - // kdDebug(7113) << m_response.toString() << endl; - TransferJob::slotFinished(); - if( d ) staticData = d->savedStaticData.copy(); // Need to send DAV request to this host too -} - -/* Convenience methods */ - -// KDE 4: Make it const TQString & -DavJob* TDEIO::davPropFind( const KURL& url, const TQDomDocument& properties, TQString depth, bool showProgressInfo ) -{ - DavJob *job = new DavJob( url, (int) TDEIO::DAV_PROPFIND, properties.toString(), showProgressInfo ); - job->addMetaData( "davDepth", depth ); - return job; -} - - -DavJob* TDEIO::davPropPatch( const KURL& url, const TQDomDocument& properties, bool showProgressInfo ) -{ - return new DavJob( url, (int) TDEIO::DAV_PROPPATCH, properties.toString(), showProgressInfo ); -} - -DavJob* TDEIO::davSearch( const KURL& url, const TQString& nsURI, const TQString& qName, const TQString& query, bool showProgressInfo ) -{ - TQDomDocument doc; - TQDomElement searchrequest = doc.createElementNS( "DAV:", "searchrequest" ); - TQDomElement searchelement = doc.createElementNS( nsURI, qName ); - TQDomText text = doc.createTextNode( query ); - searchelement.appendChild( text ); - searchrequest.appendChild( searchelement ); - doc.appendChild( searchrequest ); - return new DavJob( url, TDEIO::DAV_SEARCH, doc.toString(), showProgressInfo ); -} - -#include "davjob.moc" diff --git a/kio/kio/davjob.h b/kio/kio/davjob.h deleted file mode 100644 index 02eaa6a78..000000000 --- a/kio/kio/davjob.h +++ /dev/null @@ -1,127 +0,0 @@ -// -*- c++ -*- -/* This file is part of the KDE libraries - Copyright (C) 2002 Jan-Pascal van Best <janpascal@vanbest.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_davjob_h__ -#define __kio_davjob_h__ - -#include <kurl.h> - -#include <tqobject.h> -#include <tqptrlist.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqguardedptr.h> -#include <tqdom.h> - -#include <sys/types.h> -#include <sys/stat.h> - -#include <kio/jobclasses.h> -#include <kio/global.h> - -class Observer; -class TQTimer; - -namespace TDEIO { - - class Slave; - class SlaveInterface; - - /** - * The transfer job pumps data into and/or out of a Slave. - * Data is sent to the slave on request of the slave ( dataReq). - * If data coming from the slave can not be handled, the - * reading of data from the slave should be suspended. - * @see TDEIO::davPropFind() - * @see TDEIO::davPropPatch() - * @see TDEIO::davSearch() - * @since 3.1 - */ - class TDEIO_EXPORT DavJob : public TransferJob { - Q_OBJECT - - public: - /** - * Use TDEIO::davPropFind(), TDEIO::davPropPatch() and - * TDEIO::davSearch() to create a new DavJob. - */ - DavJob(const KURL& url, int method, - const TQString& request, bool showProgressInfo); - /** - * Returns the response as a TQDomDocument. - * @return the response document - */ - TQDomDocument& response() { return m_response; } - - protected slots: - virtual void slotFinished(); - virtual void slotData( const TQByteArray &data); - - protected: - bool m_suspended; - TransferJob *m_subJob; - private: - class DavJobPrivate; - DavJobPrivate *d; - TQString dummy; // kept around for BC reasons - TQDomDocument m_response; - }; - - /** - * Creates a new DavJob that issues a PROPFIND command. PROPFIND retrieves - * the properties of the resource identified by the given @p url. - * - * @param url the URL of the resource - * @param properties a propfind document that describes the properties that - * should be retrieved - * @param depth the depth of the request. Can be "0", "1" or "infinity" - * @param showProgressInfo true to show progress information - * @return the new DavJob - */ - TDEIO_EXPORT DavJob* davPropFind( const KURL& url, const TQDomDocument& properties, TQString depth, bool showProgressInfo=true ); - - /** - * Creates a new DavJob that issues a PROPPATCH command. PROPPATCH sets - * the properties of the resource identified by the given @p url. - * - * @param url the URL of the resource - * @param properties a PROPPACTCH document that describes the properties that - * should be modified and its new values - * @param showProgressInfo true to show progress information - * @return the new DavJob - */ - TDEIO_EXPORT DavJob* davPropPatch( const KURL& url, const TQDomDocument& properties, bool showProgressInfo=true ); - - /** - * Creates a new DavJob that issues a SEARCH command. - * - * @param url the URL of the resource - * @param nsURI the URI of the search method's qualified name - * @param qName the local part of the search method's qualified name - * @param query the search string - * @param showProgressInfo true to show progress information - * @return the new DavJob - */ - TDEIO_EXPORT DavJob* davSearch( const KURL &url, const TQString& nsURI, const TQString& qName, const TQString& query, bool showProgressInfo=true ); - -} - -#endif - diff --git a/kio/kio/defaultprogress.cpp b/kio/kio/defaultprogress.cpp deleted file mode 100644 index 72bec0cfc..000000000 --- a/kio/kio/defaultprogress.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Matej Koss <koss@miesto.sk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqtimer.h> -#include <tqlayout.h> -#include <tqtooltip.h> -#include <tqdatetime.h> -#include <tqcheckbox.h> - -#include <kapplication.h> -#include <kdebug.h> -#include <kdialog.h> -#include <kstringhandler.h> -#include <kglobal.h> -#include <klocale.h> -#include <kiconloader.h> -#include <kprocess.h> -#include <kpushbutton.h> -#include <kstandarddirs.h> -#include <kstdguiitem.h> -#include <klineedit.h> - -#ifdef Q_WS_X11 -#include <twin.h> -#endif - -#include "jobclasses.h" -#include "defaultprogress.h" - -namespace TDEIO { - -class DefaultProgress::DefaultProgressPrivate -{ -public: - bool keepOpenChecked; - bool noCaptionYet; - KPushButton *cancelClose; - KPushButton *openFile; - KPushButton *openLocation; - TQCheckBox *keepOpen; - KURL location; - TQTime startTime; -}; - -DefaultProgress::DefaultProgress( bool showNow ) - : ProgressBase( 0 ), - m_iTotalSize(0), m_iTotalFiles(0), m_iTotalDirs(0), - m_iProcessedSize(0), m_iProcessedDirs(0), m_iProcessedFiles(0) -{ - init(); - - if ( showNow ) { - show(); - } -} - -DefaultProgress::DefaultProgress( TQWidget* parent, const char* /*name*/ ) - : ProgressBase( parent ), - m_iTotalSize(0), m_iTotalFiles(0), m_iTotalDirs(0), - m_iProcessedSize(0), m_iProcessedDirs(0), m_iProcessedFiles(0) -{ - init(); -} - -bool DefaultProgress::keepOpen() const -{ - return d->keepOpenChecked; -} - -void DefaultProgress::init() -{ - d = new DefaultProgressPrivate; - -#ifdef Q_WS_X11 //FIXME(E): Remove once all the KWin::foo calls have been ported to QWS - // Set a useful icon for this window! - KWin::setIcons( winId(), - TDEGlobal::iconLoader()->loadIcon( "filesave", KIcon::NoGroup, 32 ), - TDEGlobal::iconLoader()->loadIcon( "filesave", KIcon::NoGroup, 16 ) ); -#endif - - TQVBoxLayout *topLayout = new TQVBoxLayout( this, KDialog::marginHint(), - KDialog::spacingHint() ); - topLayout->addStrut( 360 ); // makes dlg at least that wide - - TQGridLayout *grid = new TQGridLayout( 2, 3 ); - topLayout->addLayout(TQT_TQLAYOUT(grid)); - grid->addColSpacing(1, KDialog::spacingHint()); - // filenames or action name - grid->addWidget(new TQLabel(i18n("Source:"), this), 0, 0); - - sourceEdit = new KLineEdit(this); - sourceEdit->setReadOnly(true); - sourceEdit->setEnableSqueezedText(true); - grid->addWidget(sourceEdit, 0, 2); - - destInvite = new TQLabel(i18n("Destination:"), this); - grid->addWidget(destInvite, 1, 0); - - destEdit = new KLineEdit(this); - destEdit->setReadOnly (true); - destEdit->setEnableSqueezedText(true); - grid->addWidget(destEdit, 1, 2); - - m_pProgressBar = new KProgress(this); - topLayout->addWidget( m_pProgressBar ); - - // processed info - TQHBoxLayout *hBox = new TQHBoxLayout(); - topLayout->addLayout(hBox); - - sizeLabel = new TQLabel(this); - hBox->addWidget(sizeLabel); - - resumeLabel = new TQLabel(this); - hBox->addWidget(resumeLabel); - - progressLabel = new TQLabel( this ); -/* progressLabel->setSizePolicy( TQSizePolicy( TQSizePolicy::MinimumExpanding, - TQSizePolicy::Preferred ) );*/ - progressLabel->setAlignment( TQLabel::AlignRight ); - hBox->addWidget( progressLabel ); - - hBox = new TQHBoxLayout(); - topLayout->addLayout(hBox); - - speedLabel = new TQLabel(this); - hBox->addWidget(speedLabel, 1); - - TQFrame *line = new TQFrame( this ); - line->setFrameShape( TQFrame::HLine ); - line->setFrameShadow( TQFrame::Sunken ); - topLayout->addWidget( line ); - - d->keepOpen = new TQCheckBox( i18n("&Keep this window open after transfer is complete"), this); - connect( d->keepOpen, TQT_SIGNAL( toggled(bool) ), TQT_SLOT( slotKeepOpenToggled(bool) ) ); - topLayout->addWidget(d->keepOpen); - d->keepOpen->hide(); - - hBox = new TQHBoxLayout(); - topLayout->addLayout(hBox); - - d->openFile = new KPushButton( i18n("Open &File"), this ); - connect( d->openFile, TQT_SIGNAL( clicked() ), TQT_SLOT( slotOpenFile() ) ); - hBox->addWidget( d->openFile ); - d->openFile->setEnabled(false); - d->openFile->hide(); - - d->openLocation = new KPushButton( i18n("Open &Destination"), this ); - connect( d->openLocation, TQT_SIGNAL( clicked() ), TQT_SLOT( slotOpenLocation() ) ); - hBox->addWidget( d->openLocation ); - d->openLocation->hide(); - - hBox->addStretch(1); - - d->cancelClose = new KPushButton( KStdGuiItem::cancel(), this ); - connect( d->cancelClose, TQT_SIGNAL( clicked() ), TQT_SLOT( slotStop() ) ); - hBox->addWidget( d->cancelClose ); - - resize( sizeHint() ); - setMaximumHeight(sizeHint().height()); - - d->keepOpenChecked = false; - d->noCaptionYet = true; - setCaption(i18n("Progress Dialog")); // show something better than kio_uiserver -} - -DefaultProgress::~DefaultProgress() -{ - delete d; -} - -void DefaultProgress::slotTotalSize( TDEIO::Job*, TDEIO::filesize_t size ) -{ - // size is measured in bytes - if ( m_iTotalSize == size ) - return; - m_iTotalSize = size; - if (d->startTime.isNull()) - d->startTime.start(); -} - - -void DefaultProgress::slotTotalFiles( TDEIO::Job*, unsigned long files ) -{ - if ( m_iTotalFiles == files ) - return; - m_iTotalFiles = files; - showTotals(); -} - - -void DefaultProgress::slotTotalDirs( TDEIO::Job*, unsigned long dirs ) -{ - if ( m_iTotalDirs == dirs ) - return; - m_iTotalDirs = dirs; - showTotals(); -} - -void DefaultProgress::showTotals() -{ - // Show the totals in the progress label, if we still haven't - // processed anything. This is useful when the stat'ing phase - // of CopyJob takes a long time (e.g. over networks). - if ( m_iProcessedFiles == 0 && m_iProcessedDirs == 0 ) - { - TQString tmps; - if ( m_iTotalDirs > 1 ) - // that we have a singular to translate looks weired but is only logical - // xgettext: no-c-format - tmps = i18n("%n folder", "%n folders", m_iTotalDirs) + " "; - // xgettext: no-c-format - tmps += i18n("%n file", "%n files", m_iTotalFiles); - progressLabel->setText( tmps ); - } -} - -//static -TQString DefaultProgress::makePercentString( unsigned long percent, - TDEIO::filesize_t totalSize, - unsigned long totalFiles ) -{ - if ( totalSize ) - return i18n( "%1 % of %2 " ).arg( TQString::number(percent) , TDEIO::convertSize( totalSize ) ); - else if ( totalFiles ) - return i18n( "%1 % of 1 file", "%1 % of %n files", totalFiles ).arg( percent ); - else - return i18n( "%1 %" ).arg( percent ); -} - -void DefaultProgress::slotPercent( TDEIO::Job*, unsigned long percent ) -{ - TQString caption = makePercentString( percent, m_iTotalSize, m_iTotalFiles ); - m_pProgressBar->setValue( percent ); - switch(mode) { - case Copy: - caption.append(i18n(" (Copying)")); - break; - case Move: - caption.append(i18n(" (Moving)")); - break; - case Delete: - caption.append(i18n(" (Deleting)")); - break; - case Create: - caption.append(i18n(" (Creating)")); - break; - case Done: - caption.append(i18n(" (Done)")); - break; - } - - setCaption( caption ); - d->noCaptionYet = false; -} - - -void DefaultProgress::slotInfoMessage( TDEIO::Job*, const TQString & msg ) -{ - speedLabel->setText( msg ); - speedLabel->setAlignment( speedLabel->alignment() & ~TQt::WordBreak ); -} - - -void DefaultProgress::slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t bytes ) { - if ( m_iProcessedSize == bytes ) - return; - m_iProcessedSize = bytes; - - TQString tmp = i18n( "%1 of %2 complete") - .arg( TDEIO::convertSize(bytes) ) - .arg( TDEIO::convertSize(m_iTotalSize)); - sizeLabel->setText( tmp ); -} - - -void DefaultProgress::slotProcessedDirs( TDEIO::Job*, unsigned long dirs ) -{ - if ( m_iProcessedDirs == dirs ) - return; - m_iProcessedDirs = dirs; - - TQString tmps; - tmps = i18n("%1 / %n folder", "%1 / %n folders", m_iTotalDirs).arg( m_iProcessedDirs ); - tmps += " "; - tmps += i18n("%1 / %n file", "%1 / %n files", m_iTotalFiles).arg( m_iProcessedFiles ); - progressLabel->setText( tmps ); -} - - -void DefaultProgress::slotProcessedFiles( TDEIO::Job*, unsigned long files ) -{ - if ( m_iProcessedFiles == files ) - return; - m_iProcessedFiles = files; - - TQString tmps; - if ( m_iTotalDirs > 1 ) { - tmps = i18n("%1 / %n folder", "%1 / %n folders", m_iTotalDirs).arg( m_iProcessedDirs ); - tmps += " "; - } - tmps += i18n("%1 / %n file", "%1 / %n files", m_iTotalFiles).arg( m_iProcessedFiles ); - progressLabel->setText( tmps ); -} - - -void DefaultProgress::slotSpeed( TDEIO::Job*, unsigned long speed ) -{ - if ( speed == 0 ) { - speedLabel->setText( i18n( "Stalled") ); - } else { - speedLabel->setText( i18n( "%1/s ( %2 remaining )").arg( TDEIO::convertSize( speed )) - .arg( TDEIO::convertSeconds( TDEIO::calculateRemainingSeconds( m_iTotalSize, m_iProcessedSize, speed ))) ); - } -} - - -void DefaultProgress::slotCopying( TDEIO::Job*, const KURL& from, const KURL& to ) -{ - if ( d->noCaptionYet ) { - setCaption(i18n("Copy File(s) Progress")); - d->noCaptionYet = false; - } - mode = Copy; - sourceEdit->setText(from.prettyURL()); - setDestVisible( true ); - checkDestination( to ); - destEdit->setText(to.prettyURL()); -} - - -void DefaultProgress::slotMoving( TDEIO::Job*, const KURL& from, const KURL& to ) -{ - if ( d->noCaptionYet ) { - setCaption(i18n("Move File(s) Progress")); - d->noCaptionYet = false; - } - mode = Move; - sourceEdit->setText(from.prettyURL()); - setDestVisible( true ); - checkDestination( to ); - destEdit->setText(to.prettyURL()); -} - - -void DefaultProgress::slotCreatingDir( TDEIO::Job*, const KURL& dir ) -{ - if ( d->noCaptionYet ) { - setCaption(i18n("Creating Folder")); - d->noCaptionYet = false; - } - mode = Create; - sourceEdit->setText(dir.prettyURL()); - setDestVisible( false ); -} - - -void DefaultProgress::slotDeleting( TDEIO::Job*, const KURL& url ) -{ - if ( d->noCaptionYet ) { - setCaption(i18n("Delete File(s) Progress")); - d->noCaptionYet = false; - } - mode = Delete; - sourceEdit->setText(url.prettyURL()); - setDestVisible( false ); -} - -void DefaultProgress::slotTransferring( TDEIO::Job*, const KURL& url ) -{ - if ( d->noCaptionYet ) { - setCaption(i18n("Loading Progress")); - d->noCaptionYet = false; - } - sourceEdit->setText(url.prettyURL()); - setDestVisible( false ); -} - -void DefaultProgress::slotStating( TDEIO::Job*, const KURL& url ) -{ - setCaption(i18n("Examining File Progress")); - sourceEdit->setText(url.prettyURL()); - setDestVisible( false ); -} - -void DefaultProgress::slotMounting( TDEIO::Job*, const TQString & dev, const TQString & point ) -{ - setCaption(i18n("Mounting %1").arg(dev)); - sourceEdit->setText(point); - setDestVisible( false ); -} - -void DefaultProgress::slotUnmounting( TDEIO::Job*, const TQString & point ) -{ - setCaption(i18n("Unmounting")); - sourceEdit->setText(point); - setDestVisible( false ); -} - -void DefaultProgress::slotCanResume( TDEIO::Job*, TDEIO::filesize_t resume ) -{ - if ( resume ) { - resumeLabel->setText( i18n("Resuming from %1").arg(TDEIO::number(resume)) ); - } else { - resumeLabel->setText( i18n("Not resumable") ); - } -} - -void DefaultProgress::setDestVisible( bool visible ) -{ - // We can't hide the destInvite/destEdit labels, - // because it screws up the TQGridLayout. - if (visible) - { - destInvite->show(); - destEdit->show(); - - destInvite->setText( i18n("Destination:") ); - } - else - { - destInvite->hide(); - destEdit->hide(); - destInvite->setText( TQString::null ); - destEdit->setText( TQString::null ); - } -} - -void DefaultProgress::slotClean() { - if (d->keepOpenChecked) { - mode = Done; - slotPercent(0, 100); - d->cancelClose->setGuiItem( KStdGuiItem::close() ); - d->openFile->setEnabled(true); - slotProcessedSize(0, m_iTotalSize); - d->keepOpen->setEnabled(false); - if (!d->startTime.isNull()) { - int s = d->startTime.elapsed(); - if (!s) - s = 1; - speedLabel->setText(i18n("%1/s (done)").arg(TDEIO::convertSize(1000 * m_iTotalSize / s))); - } - setOnlyClean(false); - } - else - hide(); -} - -void DefaultProgress::slotKeepOpenToggled(bool keepopen) -{ - d->keepOpenChecked=keepopen; -} - -void DefaultProgress::checkDestination(const KURL& dest) { - bool ok = true; - if ( dest.isLocalFile() ) { - TQString path = dest.path( -1 ); - TQStringList tmpDirs = TDEGlobal::dirs()->resourceDirs( "tmp" ); - for ( TQStringList::Iterator it = tmpDirs.begin() ; ok && it != tmpDirs.end() ; ++it ) - if ( path.contains( *it ) ) - ok = false; // it's in the tmp resource - } - - if ( ok ) { - d->openFile->show(); - d->openLocation->show(); - d->keepOpen->show(); - d->location=dest; - } -} - -void DefaultProgress::slotOpenFile() -{ - TDEProcess proc; - proc << "konqueror" << d->location.prettyURL(); - proc.start(TDEProcess::DontCare); -} - -void DefaultProgress::slotOpenLocation() -{ - TDEProcess proc; - d->location.setFileName(""); - proc << "konqueror" << d->location.prettyURL(); - proc.start(TDEProcess::DontCare); -} - -void DefaultProgress::virtual_hook( int id, void* data ) -{ ProgressBase::virtual_hook( id, data ); } - -} /* namespace */ - -#include "defaultprogress.moc" diff --git a/kio/kio/defaultprogress.h b/kio/kio/defaultprogress.h deleted file mode 100644 index 44ffff6c4..000000000 --- a/kio/kio/defaultprogress.h +++ /dev/null @@ -1,164 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Matej Koss <koss@miesto.sk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __defaultprogress_h__ -#define __defaultprogress_h__ - -#include <tqlabel.h> - -#include <kio/global.h> - -#include <kprogress.h> - -#include "progressbase.h" - -class KLineEdit; - -namespace TDEIO { - -/* - * A default implementation of the progress dialog ProgressBase. - * ProgressBase - */ -class TDEIO_EXPORT DefaultProgress : public ProgressBase { - - Q_OBJECT - -public: - /** - * Creates a new default progress dialog. - * @param showNow true to show immediately, false to show when - * needed - */ - DefaultProgress( bool showNow = true ); - /** - * Creates a new default progress dialog. - * @param parent the parent of the dialog (or 0 for top-level) - * @param name the name of the dialog, can be 0 - * @since 3.1 - */ - DefaultProgress( TQWidget* parent, const char* name = 0 ); - ~DefaultProgress(); - - bool keepOpen() const; - - /// Shared with uiserver.cpp - static TQString makePercentString( unsigned long percent, - TDEIO::filesize_t totalSize, - unsigned long totalFiles ); - -public slots: - virtual void slotTotalSize( TDEIO::Job *job, TDEIO::filesize_t size ); - virtual void slotTotalFiles( TDEIO::Job *job, unsigned long files ); - virtual void slotTotalDirs( TDEIO::Job *job, unsigned long dirs ); - - virtual void slotProcessedSize( TDEIO::Job *job, TDEIO::filesize_t bytes ); - virtual void slotProcessedFiles( TDEIO::Job *job, unsigned long files ); - virtual void slotProcessedDirs( TDEIO::Job *job, unsigned long dirs ); - - virtual void slotSpeed( TDEIO::Job *job, unsigned long speed ); - virtual void slotPercent( TDEIO::Job *job, unsigned long percent ); - /** - * Called to set an information message. - * @param job the TDEIO::Job - * @param msg the message to set - */ - virtual void slotInfoMessage( TDEIO::Job *job, const TQString & msg ); - - virtual void slotCopying( TDEIO::Job* job, const KURL& src, const KURL& dest ); - virtual void slotMoving( TDEIO::Job* job, const KURL& src, const KURL& dest ); - virtual void slotDeleting( TDEIO::Job* job, const KURL& url ); - /** - * Called when the job is transferring. - * @param job the TDEIO::Job - * @param url the url to transfer - * @since 3.1 - */ - void slotTransferring( TDEIO::Job* job, const KURL& url ); - virtual void slotCreatingDir( TDEIO::Job* job, const KURL& dir ); - /** - * Called when the job is requesting a stat. - * @param job the TDEIO::Job - * @param dir the dir to stat - * @since 3.1 - */ - virtual void slotStating( TDEIO::Job* job, const KURL& dir ); - /** - * Called when the job is mounting. - * @param job the TDEIO::Job - * @param dev the device to mount - * @param point the mount point - */ - virtual void slotMounting( TDEIO::Job* job, const TQString & dev, const TQString & point ); - /** - * Called when the job is unmounting. - * @param job the TDEIO::Job - * @param point the mount point - */ - virtual void slotUnmounting( TDEIO::Job* job, const TQString & point ); - virtual void slotCanResume( TDEIO::Job* job, TDEIO::filesize_t from); - - /** - * Called when the job is cleaned. - * @since 3.1 - */ - void slotClean(); - -protected: - /// @since 3.1 - void init(); - void showTotals(); - void setDestVisible( bool visible ); - /// @since 3.1 - void checkDestination( const KURL& dest); - - KLineEdit* sourceEdit; - KLineEdit* destEdit; - TQLabel* progressLabel; - TQLabel* destInvite; - TQLabel* speedLabel; - TQLabel* sizeLabel; - TQLabel* resumeLabel; - - KProgress* m_pProgressBar; - - TDEIO::filesize_t m_iTotalSize; - unsigned long m_iTotalFiles; - unsigned long m_iTotalDirs; - - TDEIO::filesize_t m_iProcessedSize; - unsigned long m_iProcessedDirs; - unsigned long m_iProcessedFiles; - - enum ModeType { Copy, Move, Delete, Create, Done }; - ModeType mode; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class DefaultProgressPrivate; - DefaultProgressPrivate* d; -private slots: - void slotKeepOpenToggled(bool); - void slotOpenFile(); - void slotOpenLocation(); -}; - -} /* namespace */ - -#endif // __defaultprogress_h__ - diff --git a/kio/kio/forwardingslavebase.cpp b/kio/kio/forwardingslavebase.cpp deleted file mode 100644 index 53121986d..000000000 --- a/kio/kio/forwardingslavebase.cpp +++ /dev/null @@ -1,475 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Kevin Ottens <ervin ipsquad net> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <kdebug.h> -#include <kio/job.h> -#include <kmimetype.h> -#include <kprotocolinfo.h> - -#include <tqapplication.h> -#include <tqeventloop.h> - -#include "forwardingslavebase.h" - -namespace TDEIO -{ - -class ForwardingSlaveBasePrivate -{ -}; - -ForwardingSlaveBase::ForwardingSlaveBase(const TQCString &protocol, - const TQCString &poolSocket, - const TQCString &appSocket) - : TQObject(), SlaveBase(protocol, poolSocket, appSocket) -{ -} - -ForwardingSlaveBase::~ForwardingSlaveBase() -{ -} - -bool ForwardingSlaveBase::internalRewriteURL(const KURL &url, KURL &newURL) -{ - bool result = true; - - if ( url.protocol().ascii()==mProtocol ) - { - result = rewriteURL(url, newURL); - } - else - { - newURL = url; - } - - m_processedURL = newURL; - m_requestedURL = url; - return result; -} - -void ForwardingSlaveBase::prepareUDSEntry(TDEIO::UDSEntry &entry, - bool listing) const -{ - kdDebug() << "ForwardingSlaveBase::prepareUDSEntry: listing==" - << listing << endl; - - bool url_found = false; - TQString name; - KURL url; - - TDEIO::UDSEntry::iterator it = entry.begin(); - TDEIO::UDSEntry::iterator end = entry.end(); - - for(; it!=end; ++it) - { - KURL new_url = m_requestedURL; - - switch( (*it).m_uds ) - { - case TDEIO::UDS_NAME: - name = (*it).m_str; - kdDebug() << "Name = " << name << endl; - break; - case TDEIO::UDS_URL: - url_found = true; - url = (*it).m_str; - if (listing) - { - new_url.addPath(url.fileName()); - } - (*it).m_str = new_url.url(); - kdDebug() << "URL = " << url << endl; - kdDebug() << "New URL = " << (*it).m_str << endl; - break; - } - } - - if ( m_processedURL.isLocalFile() ) - { - KURL new_url = m_processedURL; - if (listing) - { - new_url.addPath( name ); - } - - TDEIO::UDSAtom atom; - atom.m_uds = TDEIO::UDS_LOCAL_PATH; - atom.m_long = 0; - atom.m_str = new_url.path(); - entry.append(atom); - } -} - -void ForwardingSlaveBase::get(const KURL &url) -{ - kdDebug() << "ForwardingSlaveBase::get: " << url << endl; - - KURL new_url; - if ( internalRewriteURL(url, new_url) ) - { - TDEIO::TransferJob *job = TDEIO::get(new_url, false, false); - connectTransferJob(job); - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::put(const KURL &url, int permissions, - bool overwrite, bool resume ) -{ - kdDebug() << "ForwardingSlaveBase::put: " << url << endl; - - KURL new_url; - if ( internalRewriteURL(url, new_url) ) - { - TDEIO::TransferJob *job = TDEIO::put(new_url, permissions, overwrite, - resume, false); - connectTransferJob(job); - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::stat(const KURL &url) -{ - kdDebug() << "ForwardingSlaveBase::stat: " << url << endl; - - KURL new_url; - if ( internalRewriteURL(url, new_url) ) - { - TDEIO::SimpleJob *job = TDEIO::stat(new_url, false); - connectSimpleJob(job); - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::mimetype(const KURL &url) -{ - kdDebug() << "ForwardingSlaveBase::mimetype: " << url << endl; - - KURL new_url; - if ( internalRewriteURL(url, new_url) ) - { - TDEIO::TransferJob *job = TDEIO::mimetype(new_url, false); - connectTransferJob(job); - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::listDir(const KURL &url) -{ - kdDebug() << "ForwardingSlaveBase::listDir: " << url << endl; - - KURL new_url; - if ( internalRewriteURL(url, new_url) ) - { - TDEIO::ListJob *job = TDEIO::listDir(new_url, false); - connectListJob(job); - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::mkdir(const KURL &url, int permissions) -{ - kdDebug() << "ForwardingSlaveBase::mkdir: " << url << endl; - - KURL new_url; - if ( internalRewriteURL(url, new_url) ) - { - TDEIO::SimpleJob *job = TDEIO::mkdir(new_url, permissions); - connectSimpleJob(job); - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::rename(const KURL &src, const KURL &dest, - bool overwrite) -{ - kdDebug() << "ForwardingSlaveBase::rename: " << src << ", " << dest << endl; - - KURL new_src, new_dest; - if ( internalRewriteURL(src, new_src) && internalRewriteURL(dest, new_dest) ) - { - TDEIO::Job *job = TDEIO::rename(new_src, new_dest, overwrite); - connectJob(job); - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::symlink(const TQString &target, const KURL &dest, - bool overwrite) -{ - kdDebug() << "ForwardingSlaveBase::symlink: " << target << ", " << dest << endl; - - KURL new_dest; - if ( internalRewriteURL(dest, new_dest) ) - { - TDEIO::SimpleJob *job = TDEIO::symlink(target, new_dest, overwrite, false); - connectSimpleJob(job); - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::chmod(const KURL &url, int permissions) -{ - kdDebug() << "ForwardingSlaveBase::chmod: " << url << endl; - - KURL new_url; - if ( internalRewriteURL(url, new_url) ) - { - TDEIO::SimpleJob *job = TDEIO::chmod(new_url, permissions); - connectSimpleJob(job); - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::copy(const KURL &src, const KURL &dest, - int permissions, bool overwrite) -{ - kdDebug() << "ForwardingSlaveBase::copy: " << src << ", " << dest << endl; - - KURL new_src, new_dest; - if ( internalRewriteURL(src, new_src) && internalRewriteURL(dest, new_dest) ) - { - TDEIO::Job *job = TDEIO::file_copy(new_src, new_dest, permissions, - overwrite, false); - connectJob(job); - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::del(const KURL &url, bool isfile) -{ - kdDebug() << "ForwardingSlaveBase::del: " << url << endl; - - KURL new_url; - if ( internalRewriteURL(url, new_url) ) - { - if (isfile) - { - TDEIO::DeleteJob *job = TDEIO::del(new_url, false, false); - connectJob(job); - } - else - { - TDEIO::SimpleJob *job = TDEIO::rmdir(new_url); - connectSimpleJob(job); - } - - tqApp->eventLoop()->enterLoop(); - } -} - -void ForwardingSlaveBase::localURL(const KURL& remoteURL) -{ - kdDebug() << "ForwardingSlaveBase::localURL: " << remoteURL << endl; - - KURL new_url; - if ( internalRewriteURL(remoteURL, new_url) ) - { - TDEIO::LocalURLJob *job = TDEIO::localURL(new_url); - connectLocalURLJob(job); - - tqApp->eventLoop()->enterLoop(); - } - else - { - // Let the slave base emit the required signals - SlaveBase::localURL(remoteURL); - } -} - -////////////////////////////////////////////////////////////////////////////// - -void ForwardingSlaveBase::connectJob(TDEIO::Job *job) -{ - // We will forward the warning message, no need to let the job - // display it itself - job->setInteractive(false); - - // Forward metadata (e.g. modification time for put()) - job->setMetaData( allMetaData() ); -#if 0 // debug code - kdDebug() << k_funcinfo << "transferring metadata:" << endl; - const MetaData md = allMetaData(); - for ( MetaData::const_iterator it = md.begin(); it != md.end(); ++it ) - kdDebug() << it.key() << " = " << it.data() << endl; -#endif - - connect( job, TQT_SIGNAL( result(TDEIO::Job *) ), - this, TQT_SLOT( slotResult(TDEIO::Job *) ) ); - connect( job, TQT_SIGNAL( warning(TDEIO::Job *, const TQString &) ), - this, TQT_SLOT( slotWarning(TDEIO::Job *, const TQString &) ) ); - connect( job, TQT_SIGNAL( infoMessage(TDEIO::Job *, const TQString &) ), - this, TQT_SLOT( slotInfoMessage(TDEIO::Job *, const TQString &) ) ); - connect( job, TQT_SIGNAL( totalSize(TDEIO::Job *, TDEIO::filesize_t) ), - this, TQT_SLOT( slotTotalSize(TDEIO::Job *, TDEIO::filesize_t) ) ); - connect( job, TQT_SIGNAL( processedSize(TDEIO::Job *, TDEIO::filesize_t) ), - this, TQT_SLOT( slotProcessedSize(TDEIO::Job *, TDEIO::filesize_t) ) ); - connect( job, TQT_SIGNAL( speed(TDEIO::Job *, unsigned long) ), - this, TQT_SLOT( slotSpeed(TDEIO::Job *, unsigned long) ) ); -} - -void ForwardingSlaveBase::connectSimpleJob(TDEIO::SimpleJob *job) -{ - connectJob(job); - connect( job, TQT_SIGNAL( redirection(TDEIO::Job *, const KURL &) ), - this, TQT_SLOT( slotRedirection(TDEIO::Job *, const KURL &) ) ); -} - -void ForwardingSlaveBase::connectListJob(TDEIO::ListJob *job) -{ - connectSimpleJob(job); - connect( job, TQT_SIGNAL( entries(TDEIO::Job *, const TDEIO::UDSEntryList &) ), - this, TQT_SLOT( slotEntries(TDEIO::Job *, const TDEIO::UDSEntryList &) ) ); -} - -void ForwardingSlaveBase::connectTransferJob(TDEIO::TransferJob *job) -{ - connectSimpleJob(job); - connect( job, TQT_SIGNAL( data(TDEIO::Job *, const TQByteArray &) ), - this, TQT_SLOT( slotData(TDEIO::Job *, const TQByteArray &) ) ); - connect( job, TQT_SIGNAL( dataReq(TDEIO::Job *, TQByteArray &) ), - this, TQT_SLOT( slotDataReq(TDEIO::Job *, TQByteArray &) ) ); - connect( job, TQT_SIGNAL( mimetype(TDEIO::Job *, const TQString &) ), - this, TQT_SLOT( slotMimetype(TDEIO::Job *, const TQString &) ) ); - connect( job, TQT_SIGNAL( canResume(TDEIO::Job *, TDEIO::filesize_t) ), - this, TQT_SLOT( slotCanResume(TDEIO::Job *, TDEIO::filesize_t) ) ); -} - -void ForwardingSlaveBase::connectLocalURLJob(TDEIO::LocalURLJob *job) -{ - connectJob(job); - connect( job, TQT_SIGNAL( localURL(TDEIO::Job *, const KURL&, bool) ), - this, TQT_SLOT( slotLocalURL(TDEIO::Job *, const KURL&, bool) ) ); -} - -////////////////////////////////////////////////////////////////////////////// - -void ForwardingSlaveBase::slotResult(TDEIO::Job *job) -{ - if ( job->error() != 0) - { - error( job->error(), job->errorText() ); - } - else - { - TDEIO::StatJob *stat_job = dynamic_cast<TDEIO::StatJob *>(job); - if ( stat_job!=0L ) - { - TDEIO::UDSEntry entry = stat_job->statResult(); - prepareUDSEntry(entry); - statEntry( entry ); - } - finished(); - } - - tqApp->eventLoop()->exitLoop(); -} - -void ForwardingSlaveBase::slotWarning(TDEIO::Job* /*job*/, const TQString &msg) -{ - warning(msg); -} - -void ForwardingSlaveBase::slotInfoMessage(TDEIO::Job* /*job*/, const TQString &msg) -{ - infoMessage(msg); -} - -void ForwardingSlaveBase::slotTotalSize(TDEIO::Job* /*job*/, TDEIO::filesize_t size) -{ - totalSize(size); -} - -void ForwardingSlaveBase::slotProcessedSize(TDEIO::Job* /*job*/, TDEIO::filesize_t size) -{ - processedSize(size); -} - -void ForwardingSlaveBase::slotSpeed(TDEIO::Job* /*job*/, unsigned long bytesPerSecond) -{ - speed(bytesPerSecond); -} - -void ForwardingSlaveBase::slotRedirection(TDEIO::Job *job, const KURL &url) -{ - redirection(url); - - // We've been redirected stop everything. - job->kill( true ); - finished(); - - tqApp->eventLoop()->exitLoop(); -} - -void ForwardingSlaveBase::slotEntries(TDEIO::Job* /*job*/, - const TDEIO::UDSEntryList &entries) -{ - TDEIO::UDSEntryList final_entries = entries; - - TDEIO::UDSEntryList::iterator it = final_entries.begin(); - TDEIO::UDSEntryList::iterator end = final_entries.end(); - - for(; it!=end; ++it) - { - prepareUDSEntry(*it, true); - } - - listEntries( final_entries ); -} - -void ForwardingSlaveBase::slotData(TDEIO::Job* /*job*/, const TQByteArray &d) -{ - data(d); -} - -void ForwardingSlaveBase::slotDataReq(TDEIO::Job* /*job*/, TQByteArray &data) -{ - dataReq(); - readData(data); -} - -void ForwardingSlaveBase::slotMimetype (TDEIO::Job* /*job*/, const TQString &type) -{ - mimeType(type); -} - -void ForwardingSlaveBase::slotCanResume (TDEIO::Job* /*job*/, TDEIO::filesize_t offset) -{ - canResume(offset); -} - -void ForwardingSlaveBase::slotLocalURL(TDEIO::Job *, const KURL& url, bool) -{ - SlaveBase::localURL(url); -} - -} - -#include "forwardingslavebase.moc" - diff --git a/kio/kio/forwardingslavebase.h b/kio/kio/forwardingslavebase.h deleted file mode 100644 index f765e38a6..000000000 --- a/kio/kio/forwardingslavebase.h +++ /dev/null @@ -1,204 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Kevin Ottens <ervin ipsquad net> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef _FORWARDING_SLAVE_BASE_H_ -#define _FORWARDING_SLAVE_BASE_H_ - -#include <kio/slavebase.h> -#include <kio/jobclasses.h> - -#include <tqobject.h> - -namespace TDEIO -{ - -class ForwardingSlaveBasePrivate; - -/** - * This class should be used as a base for ioslaves acting as a - * forwarder to other ioslaves. It has been designed to support only - * local filesystem like ioslaves. - * - * If the resulting ioslave should be a simple proxy, you only need - * to implement the ForwardingSlaveBase::rewriteURL() method. - * - * For more advanced behavior, the classic ioslave methods should - * be reimplemented, because their default behavior in this class - * is to forward using the ForwardingSlaveBase::rewriteURL() method. - * - * A possible code snippet for an advanced stat() behavior would look - * like this in the child class: - * - * \code - * void ChildProtocol::stat(const KURL &url) - * { - * bool is_special = false; - * - * // Process the URL to see if it should have - * // a special treatment - * - * if ( is_special ) - * { - * // Handle the URL ourselves - * TDEIO::UDSEntry entry; - * // Fill entry with UDSAtom instances - * statEntry(entry); - * finished(); - * } - * else - * { - * // Setup the ioslave internal state if - * // required by ChildProtocol::rewriteURL() - * ForwardingSlaveBase::stat(url); - * } - * } - * \endcode - * - * Of course in this case, you surely need to reimplement listDir() - * and get() accordingly. - * - * If you want view on directories to be correctly refreshed when - * something changes on a forwarded URL, you'll need a companion kded - * module to emit the KDirNotify Files*() DCOP signals. - * - * This class was initially used for media:/ ioslave. This ioslave code - * and the MediaDirNotify class of its companion kded module can be a - * good source of inspiration. - * - * @see ForwardingSlaveBase::rewriteURL() - * @since 3.4 - * @author Kevin Ottens <ervin@ipsquad.net> - */ -class TDEIO_EXPORT ForwardingSlaveBase : public TQObject, public SlaveBase -{ -Q_OBJECT -public: - ForwardingSlaveBase(const TQCString &protocol, - const TQCString &poolSocket, - const TQCString &appSocket); - virtual ~ForwardingSlaveBase(); - - virtual void get(const KURL &url); - - virtual void put(const KURL &url, int permissions, - bool overwrite, bool resume); - - virtual void stat(const KURL &url); - - virtual void mimetype(const KURL &url); - - virtual void listDir(const KURL &url); - - virtual void mkdir(const KURL &url, int permissions); - - virtual void rename(const KURL &src, const KURL &dest, bool overwrite); - - virtual void symlink(const TQString &target, const KURL &dest, - bool overwrite); - - virtual void chmod(const KURL &url, int permissions); - - virtual void copy(const KURL &src, const KURL &dest, - int permissions, bool overwrite); - - virtual void del(const KURL &url, bool isfile); - - virtual void localURL(const KURL& remoteURL); - -protected: - /** - * Rewrite an url to it's forwarded counterpart. It should return - * true if everything was ok, and false otherwise. - * - * If a problem is detected it's up to this method to trigger error() - * before returning. Returning false silently cancel the current - * slave operation. - * - * @param url The URL as given during the slave call - * @param newURL The new URL to forward the slave call to - * @return true if the given url could be correctly rewritten - */ - virtual bool rewriteURL(const KURL &url, KURL &newURL)=0; - - /** - * Allow to modify a UDSEntry before it's sent to the ioslave enpoint. - * This is the default implementation working in most case, but sometimes - * you could make use of more forwarding black magic (for example - * dynamically transform any desktop file into a fake directory...) - * - * @param entry the UDSEntry to post-process - * @param listing indicate if this entry it created during a listDir - * operation - */ - virtual void prepareUDSEntry(TDEIO::UDSEntry &entry, - bool listing=false) const; - - /** - * Return the URL being processed by the ioslave - * Only access it inside prepareUDSEntry() - */ - KURL processedURL() const { return m_processedURL; } - - /** - * Return the URL asked to the ioslave - * Only access it inside prepareUDSEntry() - */ - KURL requestedURL() const { return m_requestedURL; } - -private: - KURL m_processedURL; - KURL m_requestedURL; - ForwardingSlaveBasePrivate *d; - - bool internalRewriteURL(const KURL &url, KURL &newURL); - - void connectJob(Job *job); - void connectSimpleJob(SimpleJob *job); - void connectListJob(ListJob *job); - void connectTransferJob(TransferJob *job); - void connectLocalURLJob(LocalURLJob *job); - -private slots: - // TDEIO::Job - void slotResult(TDEIO::Job *job); - void slotWarning(TDEIO::Job *job, const TQString &msg); - void slotInfoMessage(TDEIO::Job *job, const TQString &msg); - void slotTotalSize(TDEIO::Job *job, TDEIO::filesize_t size); - void slotProcessedSize(TDEIO::Job *job, TDEIO::filesize_t size); - void slotSpeed(TDEIO::Job *job, unsigned long bytesPerSecond); - - // TDEIO::SimpleJob subclasses - void slotRedirection(TDEIO::Job *job, const KURL &url); - - // TDEIO::ListJob - void slotEntries(TDEIO::Job *job, const TDEIO::UDSEntryList &entries); - - // TDEIO::TransferJob - void slotData(TDEIO::Job *job, const TQByteArray &data); - void slotDataReq(TDEIO::Job *job, TQByteArray &data); - void slotMimetype (TDEIO::Job *job, const TQString &type); - void slotCanResume (TDEIO::Job *job, TDEIO::filesize_t offset); - - // TDEIO::LocalURLJob - void slotLocalURL(TDEIO::Job *, const KURL&, bool); -}; - -} - -#endif diff --git a/kio/kio/global.cpp b/kio/kio/global.cpp deleted file mode 100644 index 3a7cadb8f..000000000 --- a/kio/kio/global.cpp +++ /dev/null @@ -1,2009 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <config.h> - -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/uio.h> - -#include <assert.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdio.h> - -#include "kio/global.h" -#include "kio/job.h" - -#include <kdebug.h> -#include <klocale.h> -#include <kglobal.h> -#include <kprotocolmanager.h> -#include <kde_file.h> - -#ifdef HAVE_VOLMGT -#include <volmgt.h> -#endif - -TDEIO_EXPORT TQString TDEIO::convertSizeWithBytes( TDEIO::filesize_t size ) -{ - if ( size >= 1024 ) - return convertSize( size ) + " (" + i18n( "%1 B" ).arg( TDEGlobal::locale()->formatNumber(size, 0) ) + ")"; - else - return convertSize( size ); -} - -TDEIO_EXPORT TQString TDEIO::convertSize( TDEIO::filesize_t size ) -{ - double fsize = size; - TQString s; - // Giga-byte - if ( size >= 1073741824 ) - { - fsize /= 1073741824.0; - if ( fsize > 1024 ) // Tera-byte - s = i18n( "%1 TB" ).arg( TDEGlobal::locale()->formatNumber(fsize / 1024.0, 1)); - else - s = i18n( "%1 GB" ).arg( TDEGlobal::locale()->formatNumber(fsize, 1)); - } - // Mega-byte - else if ( size >= 1048576 ) - { - fsize /= 1048576.0; - s = i18n( "%1 MB" ).arg( TDEGlobal::locale()->formatNumber(fsize, 1)); - } - // Kilo-byte - else if ( size >= 1024 ) - { - fsize /= 1024.0; - s = i18n( "%1 KB" ).arg( TDEGlobal::locale()->formatNumber(fsize, 1)); - } - // Just byte - else if ( size > 0 ) - { - s = i18n( "%1 B" ).arg( TDEGlobal::locale()->formatNumber(fsize, 0)); - } - // Nothing - else - { - s = i18n( "0 B" ); - } - return s; -} - -TDEIO_EXPORT TQString TDEIO::convertSizeFromKB( TDEIO::filesize_t kbSize ) -{ - return convertSize(kbSize * 1024); -} - -TDEIO_EXPORT TQString TDEIO::number( TDEIO::filesize_t size ) -{ - char charbuf[256]; - sprintf(charbuf, "%lld", size); - return TQString::fromLatin1(charbuf); -} - -TDEIO_EXPORT unsigned int TDEIO::calculateRemainingSeconds( TDEIO::filesize_t totalSize, - TDEIO::filesize_t processedSize, TDEIO::filesize_t speed ) -{ - if ( (speed != 0) && (totalSize != 0) ) - return ( totalSize - processedSize ) / speed; - else - return 0; -} - -TDEIO_EXPORT TQString TDEIO::convertSeconds( unsigned int seconds ) -{ - unsigned int days = seconds / 86400; - unsigned int hours = (seconds - (days * 86400)) / 3600; - unsigned int mins = (seconds - (days * 86400) - (hours * 3600)) / 60; - seconds = (seconds - (days * 86400) - (hours * 3600) - (mins * 60)); - - const TQTime time(hours, mins, seconds); - const TQString timeStr( TDEGlobal::locale()->formatTime(time, true /*with seconds*/, true /*duration*/) ); - if ( days > 0 ) - return i18n("1 day %1", "%n days %1", days).arg(timeStr); - else - return timeStr; -} - -TDEIO_EXPORT TQTime TDEIO::calculateRemaining( TDEIO::filesize_t totalSize, TDEIO::filesize_t processedSize, TDEIO::filesize_t speed ) -{ - TQTime remainingTime; - - if ( speed != 0 ) { - TDEIO::filesize_t secs; - if ( totalSize == 0 ) { - secs = 0; - } else { - secs = ( totalSize - processedSize ) / speed; - } - if (secs >= (24*60*60)) // Limit to 23:59:59 - secs = (24*60*60)-1; - int hr = secs / ( 60 * 60 ); - int mn = ( secs - hr * 60 * 60 ) / 60; - int sc = ( secs - hr * 60 * 60 - mn * 60 ); - - remainingTime.setHMS( hr, mn, sc ); - } - - return remainingTime; -} - -TDEIO_EXPORT TQString TDEIO::itemsSummaryString(uint items, uint files, uint dirs, TDEIO::filesize_t size, bool showSize) -{ - TQString text = items == 0 ? i18n( "No Items" ) : i18n( "One Item", "%n Items", items ); - text += " - "; - text += files == 0 ? i18n( "No Files" ) : i18n( "One File", "%n Files", files ); - if ( showSize && files > 0 ) - { - text += " "; - text += i18n("(%1 Total)").arg(TDEIO::convertSize( size ) ); - } - text += " - "; - text += dirs == 0 ? i18n( "No Folders" ) : i18n("One Folder", "%n Folders", dirs); - return text; -} - -TDEIO_EXPORT TQString TDEIO::encodeFileName( const TQString & _str ) -{ - TQString str( _str ); - - int i = 0; - while ( ( i = str.find( "%", i ) ) != -1 ) - { - str.replace( i, 1, "%%"); - i += 2; - } - while ( ( i = str.find( "/" ) ) != -1 ) - str.replace( i, 1, "%2f"); - return str; -} - -TDEIO_EXPORT TQString TDEIO::decodeFileName( const TQString & _str ) -{ - TQString str; - - unsigned int i = 0; - for ( ; i < _str.length() ; ++i ) - { - if ( _str[i]=='%' ) - { - if ( _str[i+1]=='%' ) // %% -> % - { - str.append('%'); - ++i; - } - else if ( _str[i+1]=='2' && (i+2<_str.length()) && _str[i+2].lower()=='f' ) // %2f -> / - { - str.append('/'); - i += 2; - } - else - str.append('%'); - } else - str.append(_str[i]); - } - - return str; -} - -TDEIO_EXPORT TQString TDEIO::Job::errorString() const -{ - return TDEIO::buildErrorString(m_error, m_errorText); -} - -TDEIO_EXPORT TQString TDEIO::buildErrorString(int errorCode, const TQString &errorText) -{ - TQString result; - - switch( errorCode ) - { - case TDEIO::ERR_CANNOT_OPEN_FOR_READING: - result = i18n( "Could not read %1." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_OPEN_FOR_WRITING: - result = i18n( "Could not write to %1." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_LAUNCH_PROCESS: - result = i18n( "Could not start process %1." ).arg( errorText ); - break; - case TDEIO::ERR_INTERNAL: - result = i18n( "Internal Error\nPlease send a full bug report at http://bugs.kde.org\n%1" ).arg( errorText ); - break; - case TDEIO::ERR_MALFORMED_URL: - result = i18n( "Malformed URL %1." ).arg( errorText ); - break; - case TDEIO::ERR_UNSUPPORTED_PROTOCOL: - result = i18n( "The protocol %1 is not supported." ).arg( errorText ); - break; - case TDEIO::ERR_NO_SOURCE_PROTOCOL: - result = i18n( "The protocol %1 is only a filter protocol.").arg( errorText ); - break; - case TDEIO::ERR_UNSUPPORTED_ACTION: - result = errorText; -// result = i18n( "Unsupported action %1" ).arg( errorText ); - break; - case TDEIO::ERR_IS_DIRECTORY: - result = i18n( "%1 is a folder, but a file was expected." ).arg( errorText ); - break; - case TDEIO::ERR_IS_FILE: - result = i18n( "%1 is a file, but a folder was expected." ).arg( errorText ); - break; - case TDEIO::ERR_DOES_NOT_EXIST: - result = i18n( "The file or folder %1 does not exist." ).arg( errorText ); - break; - case TDEIO::ERR_FILE_ALREADY_EXIST: - result = i18n( "A file named %1 already exists." ).arg( errorText ); - break; - case TDEIO::ERR_DIR_ALREADY_EXIST: - result = i18n( "A folder named %1 already exists." ).arg( errorText ); - break; - case TDEIO::ERR_UNKNOWN_HOST: - result = errorText.isEmpty() ? i18n( "No hostname specified." ) : i18n( "Unknown host %1" ).arg( errorText ); - break; - case TDEIO::ERR_ACCESS_DENIED: - result = i18n( "Access denied to %1." ).arg( errorText ); - break; - case TDEIO::ERR_WRITE_ACCESS_DENIED: - result = i18n( "Access denied.\nCould not write to %1." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_ENTER_DIRECTORY: - result = i18n( "Could not enter folder %1." ).arg( errorText ); - break; - case TDEIO::ERR_PROTOCOL_IS_NOT_A_FILESYSTEM: - result = i18n( "The protocol %1 does not implement a folder service." ).arg( errorText ); - break; - case TDEIO::ERR_CYCLIC_LINK: - result = i18n( "Found a cyclic link in %1." ).arg( errorText ); - break; - case TDEIO::ERR_USER_CANCELED: - // Do nothing in this case. The user doesn't need to be told what he just did. - break; - case TDEIO::ERR_CYCLIC_COPY: - result = i18n( "Found a cyclic link while copying %1." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_CREATE_SOCKET: - result = i18n( "Could not create socket for accessing %1." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_CONNECT: - result = i18n( "Could not connect to host %1." ).arg( errorText.isEmpty() ? TQString::fromLatin1("localhost") : errorText ); - break; - case TDEIO::ERR_CONNECTION_BROKEN: - result = i18n( "Connection to host %1 is broken." ).arg( errorText ); - break; - case TDEIO::ERR_NOT_FILTER_PROTOCOL: - result = i18n( "The protocol %1 is not a filter protocol." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_MOUNT: - result = i18n( "Could not mount device.\nThe reported error was:\n%1" ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_UNMOUNT: - result = i18n( "Could not unmount device.\nThe reported error was:\n%1" ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_READ: - result = i18n( "Could not read file %1." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_WRITE: - result = i18n( "Could not write to file %1." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_BIND: - result = i18n( "Could not bind %1." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_LISTEN: - result = i18n( "Could not listen %1." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_ACCEPT: - result = i18n( "Could not accept %1." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_LOGIN: - result = errorText; - break; - case TDEIO::ERR_COULD_NOT_STAT: - result = i18n( "Could not access %1." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_CLOSEDIR: - result = i18n( "Could not terminate listing %1." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_MKDIR: - result = i18n( "Could not make folder %1." ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_RMDIR: - result = i18n( "Could not remove folder %1." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_RESUME: - result = i18n( "Could not resume file %1." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_RENAME: - result = i18n( "Could not rename file %1." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_CHMOD: - result = i18n( "Could not change permissions for %1." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_DELETE: - result = i18n( "Could not delete file %1." ).arg( errorText ); - break; - case TDEIO::ERR_SLAVE_DIED: - result = i18n( "The process for the %1 protocol died unexpectedly." ).arg( errorText ); - break; - case TDEIO::ERR_OUT_OF_MEMORY: - result = i18n( "Error. Out of memory.\n%1" ).arg( errorText ); - break; - case TDEIO::ERR_UNKNOWN_PROXY_HOST: - result = i18n( "Unknown proxy host\n%1" ).arg( errorText ); - break; - case TDEIO::ERR_COULD_NOT_AUTHENTICATE: - result = i18n( "Authorization failed, %1 authentication not supported" ).arg( errorText ); - break; - case TDEIO::ERR_ABORTED: - result = i18n( "User canceled action\n%1" ).arg( errorText ); - break; - case TDEIO::ERR_INTERNAL_SERVER: - result = i18n( "Internal error in server\n%1" ).arg( errorText ); - break; - case TDEIO::ERR_SERVER_TIMEOUT: - result = i18n( "Timeout on server\n%1" ).arg( errorText ); - break; - case TDEIO::ERR_UNKNOWN: - result = i18n( "Unknown error\n%1" ).arg( errorText ); - break; - case TDEIO::ERR_UNKNOWN_INTERRUPT: - result = i18n( "Unknown interrupt\n%1" ).arg( errorText ); - break; -/* - case TDEIO::ERR_CHECKSUM_MISMATCH: - if (errorText) - result = i18n( "Warning: MD5 Checksum for %1 does not match checksum returned from server" ).arg(errorText); - else - result = i18n( "Warning: MD5 Checksum for %1 does not match checksum returned from server" ).arg("document"); - break; -*/ - case TDEIO::ERR_CANNOT_DELETE_ORIGINAL: - result = i18n( "Could not delete original file %1.\nPlease check permissions." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_DELETE_PARTIAL: - result = i18n( "Could not delete partial file %1.\nPlease check permissions." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_RENAME_ORIGINAL: - result = i18n( "Could not rename original file %1.\nPlease check permissions." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_RENAME_PARTIAL: - result = i18n( "Could not rename partial file %1.\nPlease check permissions." ).arg( errorText ); - break; - case TDEIO::ERR_CANNOT_SYMLINK: - result = i18n( "Could not create symlink %1.\nPlease check permissions." ).arg( errorText ); - break; - case TDEIO::ERR_NO_CONTENT: - result = errorText; - break; - case TDEIO::ERR_DISK_FULL: - result = i18n( "Could not write file %1.\nDisk full." ).arg( errorText ); - break; - case TDEIO::ERR_IDENTICAL_FILES: - result = i18n( "The source and destination are the same file.\n%1" ).arg( errorText ); - break; - case TDEIO::ERR_SLAVE_DEFINED: - result = errorText; - break; - case TDEIO::ERR_UPGRADE_REQUIRED: - result = i18n( "%1 is required by the server, but is not available." ).arg(errorText); - break; - case TDEIO::ERR_POST_DENIED: - result = i18n( "Access to restricted port in POST denied."); - break; - case TDEIO::ERR_OFFLINE_MODE: - result = i18n( "Could not access %1.\nOffline mode active.").arg( errorText ); - break; - default: - result = i18n( "Unknown error code %1\n%2\nPlease send a full bug report at http://bugs.kde.org." ).arg( errorCode ).arg( errorText ); - break; - } - - return result; -} - -TDEIO_EXPORT TQString TDEIO::unsupportedActionErrorString(const TQString &protocol, int cmd) { - switch (cmd) { - case CMD_CONNECT: - return i18n("Opening connections is not supported with the protocol %1." ).arg(protocol); - case CMD_DISCONNECT: - return i18n("Closing connections is not supported with the protocol %1." ).arg(protocol); - case CMD_STAT: - return i18n("Accessing files is not supported with the protocol %1.").arg(protocol); - case CMD_PUT: - return i18n("Writing to %1 is not supported.").arg(protocol); - case CMD_SPECIAL: - return i18n("There are no special actions available for protocol %1.").arg(protocol); - case CMD_LISTDIR: - return i18n("Listing folders is not supported for protocol %1.").arg(protocol); - case CMD_GET: - return i18n("Retrieving data from %1 is not supported.").arg(protocol); - case CMD_MIMETYPE: - return i18n("Retrieving mime type information from %1 is not supported.").arg(protocol); - case CMD_RENAME: - return i18n("Renaming or moving files within %1 is not supported.").arg(protocol); - case CMD_SYMLINK: - return i18n("Creating symlinks is not supported with protocol %1.").arg(protocol); - case CMD_COPY: - return i18n("Copying files within %1 is not supported.").arg(protocol); - case CMD_DEL: - return i18n("Deleting files from %1 is not supported.").arg(protocol); - case CMD_MKDIR: - return i18n("Creating folders is not supported with protocol %1.").arg(protocol); - case CMD_CHMOD: - return i18n("Changing the attributes of files is not supported with protocol %1.").arg(protocol); - case CMD_SUBURL: - return i18n("Using sub-URLs with %1 is not supported.").arg(protocol); - case CMD_MULTI_GET: - return i18n("Multiple get is not supported with protocol %1.").arg(protocol); - default: - return i18n("Protocol %1 does not support action %2.").arg(protocol).arg(cmd); - }/*end switch*/ -} - -TDEIO_EXPORT TQStringList TDEIO::Job::detailedErrorStrings( const KURL *reqUrl /*= 0L*/, - int method /*= -1*/ ) const -{ - TQString errorName, techName, description, ret2; - TQStringList causes, solutions, ret; - - TQByteArray raw = rawErrorDetail( m_error, m_errorText, reqUrl, method ); - TQDataStream stream(raw, IO_ReadOnly); - - stream >> errorName >> techName >> description >> causes >> solutions; - - TQString url, protocol, datetime; - if ( reqUrl ) { - url = reqUrl->htmlURL(); - protocol = reqUrl->protocol(); - } else { - url = i18n( "(unknown)" ); - } - - datetime = TDEGlobal::locale()->formatDateTime( TQDateTime::currentDateTime(), - false ); - - ret << errorName; - ret << TQString::fromLatin1( "<qt><p><b>" ) + errorName + - TQString::fromLatin1( "</b></p><p>" ) + description + - TQString::fromLatin1( "</p>" ); - ret2 = TQString::fromLatin1( "<qt><p>" ); - if ( !techName.isEmpty() ) - ret2 += i18n( "<b>Technical reason</b>: " ) + techName + TQString::fromLatin1( "</p>" ); - ret2 += i18n( "</p><p><b>Details of the request</b>:" ); - ret2 += i18n( "</p><ul><li>URL: %1</li>" ).arg( url ); - if ( !protocol.isEmpty() ) { - ret2 += i18n( "<li>Protocol: %1</li>" ).arg( protocol ); - } - ret2 += i18n( "<li>Date and time: %1</li>" ).arg( datetime ); - ret2 += i18n( "<li>Additional information: %1</li></ul>" ).arg( m_errorText ); - if ( !causes.isEmpty() ) { - ret2 += i18n( "<p><b>Possible causes</b>:</p><ul><li>" ); - ret2 += causes.join( "</li><li>" ); - ret2 += TQString::fromLatin1( "</li></ul>" ); - } - if ( !solutions.isEmpty() ) { - ret2 += i18n( "<p><b>Possible solutions</b>:</p><ul><li>" ); - ret2 += solutions.join( "</li><li>" ); - ret2 += TQString::fromLatin1( "</li></ul>" ); - } - ret << ret2; - return ret; -} - -TDEIO_EXPORT TQByteArray TDEIO::rawErrorDetail(int errorCode, const TQString &errorText, - const KURL *reqUrl /*= 0L*/, int /*method = -1*/ ) -{ - TQString url, host, protocol, datetime, domain, path, dir, filename; - bool isSlaveNetwork = false; - if ( reqUrl ) { - url = reqUrl->prettyURL(); - host = reqUrl->host(); - protocol = reqUrl->protocol(); - - if ( host.left(4) == "www." ) - domain = host.mid(4); - else - domain = host; - - path = reqUrl->path(1); - filename = reqUrl->fileName(); - dir = path + filename; - - // detect if protocol is a network protocol... - // add your hacks here... - if ( protocol == "http" || - protocol == "https" || - protocol == "ftp" || - protocol == "sftp" || - protocol == "webdav" || - protocol == "webdavs" || - protocol == "finger" || - protocol == "fish" || - protocol == "gopher" || - protocol == "imap" || - protocol == "imaps" || - protocol == "lan" || - protocol == "ldap" || - protocol == "mailto" || - protocol == "news" || - protocol == "nntp" || - protocol == "pop3" || - protocol == "pop3s" || - protocol == "smtp" || - protocol == "smtps" || - protocol == "telnet" - ) { - isSlaveNetwork = false; - } - } else { - // assume that the errorText has the location we are interested in - url = host = domain = path = filename = dir = errorText; - protocol = i18n( "(unknown)" ); - } - - datetime = TDEGlobal::locale()->formatDateTime( TQDateTime::currentDateTime(), - false ); - - TQString errorName, techName, description; - TQStringList causes, solutions; - - // c == cause, s == solution - TQString sSysadmin = i18n( "Contact your appropriate computer support system, " - "whether the system administrator, or technical support group for further " - "assistance." ); - TQString sServeradmin = i18n( "Contact the administrator of the server " - "for further assistance." ); - // FIXME active link to permissions dialog - TQString sAccess = i18n( "Check your access permissions on this resource." ); - TQString cAccess = i18n( "Your access permissions may be inadequate to " - "perform the requested operation on this resource." ); - TQString cLocked = i18n( "The file may be in use (and thus locked) by " - "another user or application." ); - TQString sQuerylock = i18n( "Check to make sure that no other " - "application or user is using the file or has locked the file." ); - TQString cHardware = i18n( "Although unlikely, a hardware error may have " - "occurred." ); - TQString cBug = i18n( "You may have encountered a bug in the program." ); - TQString cBuglikely = i18n( "This is most likely to be caused by a bug in the " - "program. Please consider submitting a full bug report as detailed below." ); - TQString sUpdate = i18n( "Update your software to the latest version. " - "Your distribution should provide tools to update your software." ); - TQString sBugreport = i18n( "When all else fails, please consider helping the " - "TDE team or the third party maintainer of this software by submitting a " - "high quality bug report. If the software is provided by a third party, " - "please contact them directly. Otherwise, first look to see if " - "the same bug has been submitted by someone else by searching at the " - "<a href=\"http://bugs.pearsoncomputing.net//\">TDE bug reporting website</a>. If not, take " - "note of the details given above, and include them in your bug report, along " - "with as many other details as you think might help." ); - TQString cNetwork = i18n( "There may have been a problem with your network " - "connection." ); - // FIXME netconf kcontrol link - TQString cNetconf = i18n( "There may have been a problem with your network " - "configuration. If you have been accessing the Internet with no problems " - "recently, this is unlikely." ); - TQString cNetpath = i18n( "There may have been a problem at some point along " - "the network path between the server and this computer." ); - TQString sTryagain = i18n( "Try again, either now or at a later time." ); - TQString cProtocol = i18n( "A protocol error or incompatibility may have occurred." ); - TQString sExists = i18n( "Ensure that the resource exists, and try again." ); - TQString cExists = i18n( "The specified resource may not exist." ); - TQString cTypo = i18n( "You may have incorrectly typed the location." ); - TQString sTypo = i18n( "Double-check that you have entered the correct location " - "and try again." ); - TQString sNetwork = i18n( "Check your network connection status." ); - - switch( errorCode ) { - case TDEIO::ERR_CANNOT_OPEN_FOR_READING: - errorName = i18n( "Cannot Open Resource For Reading" ); - description = i18n( "This means that the contents of the requested file " - "or folder <strong>%1</strong> could not be retrieved, as read " - "access could not be obtained." ).arg( dir ); - causes << i18n( "You may not have permissions to read the file or open " - "the folder.") << cLocked << cHardware; - solutions << sAccess << sQuerylock << sSysadmin; - break; - - case TDEIO::ERR_CANNOT_OPEN_FOR_WRITING: - errorName = i18n( "Cannot Open Resource For Writing" ); - description = i18n( "This means that the file, <strong>%1</strong>, could " - "not be written to as requested, because access with permission to " - "write could not be obtained." ).arg( filename ); - causes << cAccess << cLocked << cHardware; - solutions << sAccess << sQuerylock << sSysadmin; - break; - - case TDEIO::ERR_CANNOT_LAUNCH_PROCESS: - errorName = i18n( "Cannot Initiate the %1 Protocol" ).arg( protocol ); - techName = i18n( "Unable to Launch Process" ); - description = i18n( "The program on your computer which provides access " - "to the <strong>%1</strong> protocol could not be started. This is " - "usually due to technical reasons." ).arg( protocol ); - causes << i18n( "The program which provides compatibility with this " - "protocol may not have been updated with your last update of TDE. " - "This can cause the program to be incompatible with the current version " - "and thus not start." ) << cBug; - solutions << sUpdate << sSysadmin; - break; - - case TDEIO::ERR_INTERNAL: - errorName = i18n( "Internal Error" ); - description = i18n( "The program on your computer which provides access " - "to the <strong>%1</strong> protocol has reported an internal error." ) - .arg( protocol ); - causes << cBuglikely; - solutions << sUpdate << sBugreport; - break; - - case TDEIO::ERR_MALFORMED_URL: - errorName = i18n( "Improperly Formatted URL" ); - description = i18n( "The <strong>U</strong>niform <strong>R</strong>esource " - "<strong>L</strong>ocator (URL) that you entered was not properly " - "formatted. The format of a URL is generally as follows:" - "<blockquote><strong>protocol://user:password@www.example.org:port/folder/" - "filename.extension?query=value</strong></blockquote>" ); - solutions << sTypo; - break; - - case TDEIO::ERR_UNSUPPORTED_PROTOCOL: - errorName = i18n( "Unsupported Protocol %1" ).arg( protocol ); - description = i18n( "The protocol <strong>%1</strong> is not supported " - "by the TDE programs currently installed on this computer." ) - .arg( protocol ); - causes << i18n( "The requested protocol may not be supported." ) - << i18n( "The versions of the %1 protocol supported by this computer and " - "the server may be incompatible." ).arg( protocol ); - solutions << i18n( "You may perform a search on the Internet for a TDE " - "program (called a kioslave or ioslave) which supports this protocol. " - "Places to search include <a href=\"http://kde-apps.org/\">" - "http://kde-apps.org/</a> and <a href=\"http://freshmeat.net/\">" - "http://freshmeat.net/</a>." ) - << sUpdate << sSysadmin; - break; - - case TDEIO::ERR_NO_SOURCE_PROTOCOL: - errorName = i18n( "URL Does Not Refer to a Resource." ); - techName = i18n( "Protocol is a Filter Protocol" ); - description = i18n( "The <strong>U</strong>niform <strong>R</strong>esource " - "<strong>L</strong>ocator (URL) that you entered did not refer to a " - "specific resource." ); - causes << i18n( "TDE is able to communicate through a protocol within a " - "protocol; the protocol specified is only for use in such situations, " - "however this is not one of these situations. This is a rare event, and " - "is likely to indicate a programming error." ); - solutions << sTypo; - break; - - case TDEIO::ERR_UNSUPPORTED_ACTION: - errorName = i18n( "Unsupported Action: %1" ).arg( errorText ); - description = i18n( "The requested action is not supported by the TDE " - "program which is implementing the <strong>%1</strong> protocol." ) - .arg( protocol ); - causes << i18n( "This error is very much dependent on the TDE program. The " - "additional information should give you more information than is available " - "to the TDE input/output architecture." ); - solutions << i18n( "Attempt to find another way to accomplish the same " - "outcome." ); - break; - - case TDEIO::ERR_IS_DIRECTORY: - errorName = i18n( "File Expected" ); - description = i18n( "The request expected a file, however the " - "folder <strong>%1</strong> was found instead." ).arg( dir ); - causes << i18n( "This may be an error on the server side." ) << cBug; - solutions << sUpdate << sSysadmin; - break; - - case TDEIO::ERR_IS_FILE: - errorName = i18n( "Folder Expected" ); - description = i18n( "The request expected a folder, however " - "the file <strong>%1</strong> was found instead." ).arg( filename ); - causes << cBug; - solutions << sUpdate << sSysadmin; - break; - - case TDEIO::ERR_DOES_NOT_EXIST: - errorName = i18n( "File or Folder Does Not Exist" ); - description = i18n( "The specified file or folder <strong>%1</strong> " - "does not exist." ).arg( dir ); - causes << cBug; - solutions << sUpdate << sSysadmin; - break; - - case TDEIO::ERR_FILE_ALREADY_EXIST: - errorName = i18n( "File Already Exists" ); - description = i18n( "The requested file could not be created because a " - "file with the same name already exists." ); - solutions << i18n ( "Try moving the current file out of the way first, " - "and then try again." ) - << i18n ( "Delete the current file and try again." ) - << i18n( "Choose an alternate filename for the new file." ); - break; - - case TDEIO::ERR_DIR_ALREADY_EXIST: - errorName = i18n( "Folder Already Exists" ); - description = i18n( "The requested folder could not be created because " - "a folder with the same name already exists." ); - solutions << i18n( "Try moving the current folder out of the way first, " - "and then try again." ) - << i18n( "Delete the current folder and try again." ) - << i18n( "Choose an alternate name for the new folder." ); - break; - - case TDEIO::ERR_UNKNOWN_HOST: - errorName = i18n( "Unknown Host" ); - description = i18n( "An unknown host error indicates that the server with " - "the requested name, <strong>%1</strong>, could not be " - "located on the Internet." ).arg( host ); - causes << i18n( "The name that you typed, %1, may not exist: it may be " - "incorrectly typed." ).arg( host ) - << cNetwork << cNetconf; - solutions << sNetwork << sSysadmin; - break; - - case TDEIO::ERR_ACCESS_DENIED: - errorName = i18n( "Access Denied" ); - description = i18n( "Access was denied to the specified resource, " - "<strong>%1</strong>." ).arg( url ); - causes << i18n( "You may have supplied incorrect authentication details or " - "none at all." ) - << i18n( "Your account may not have permission to access the " - "specified resource." ); - solutions << i18n( "Retry the request and ensure your authentication details " - "are entered correctly." ) << sSysadmin; - if ( !isSlaveNetwork ) solutions << sServeradmin; - break; - - case TDEIO::ERR_WRITE_ACCESS_DENIED: - errorName = i18n( "Write Access Denied" ); - description = i18n( "This means that an attempt to write to the file " - "<strong>%1</strong> was rejected." ).arg( filename ); - causes << cAccess << cLocked << cHardware; - solutions << sAccess << sQuerylock << sSysadmin; - break; - - case TDEIO::ERR_CANNOT_ENTER_DIRECTORY: - errorName = i18n( "Unable to Enter Folder" ); - description = i18n( "This means that an attempt to enter (in other words, " - "to open) the requested folder <strong>%1</strong> was rejected." ) - .arg( dir ); - causes << cAccess << cLocked; - solutions << sAccess << sQuerylock << sSysadmin; - break; - - case TDEIO::ERR_PROTOCOL_IS_NOT_A_FILESYSTEM: - errorName = i18n( "Folder Listing Unavailable" ); - techName = i18n( "Protocol %1 is not a Filesystem" ).arg( protocol ); - description = i18n( "This means that a request was made which requires " - "determining the contents of the folder, and the TDE program supporting " - "this protocol is unable to do so." ); - causes << cBug; - solutions << sUpdate << sBugreport; - break; - - case TDEIO::ERR_CYCLIC_LINK: - errorName = i18n( "Cyclic Link Detected" ); - description = i18n( "UNIX environments are commonly able to link a file or " - "folder to a separate name and/or location. TDE detected a link or " - "series of links that results in an infinite loop - i.e. the file was " - "(perhaps in a roundabout way) linked to itself." ); - solutions << i18n( "Delete one part of the loop in order that it does not " - "cause an infinite loop, and try again." ) << sSysadmin; - break; - - case TDEIO::ERR_USER_CANCELED: - // Do nothing in this case. The user doesn't need to be told what he just did. - // rodda: However, if we have been called, an application is about to display - // this information anyway. If we don't return sensible information, the - // user sees a blank dialog (I have seen this myself) - errorName = i18n( "Request Aborted By User" ); - description = i18n( "The request was not completed because it was " - "aborted." ); - solutions << i18n( "Retry the request." ); - break; - - case TDEIO::ERR_CYCLIC_COPY: - errorName = i18n( "Cyclic Link Detected During Copy" ); - description = i18n( "UNIX environments are commonly able to link a file or " - "folder to a separate name and/or location. During the requested copy " - "operation, TDE detected a link or series of links that results in an " - "infinite loop - i.e. the file was (perhaps in a roundabout way) linked " - "to itself." ); - solutions << i18n( "Delete one part of the loop in order that it does not " - "cause an infinite loop, and try again." ) << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_CREATE_SOCKET: - errorName = i18n( "Could Not Create Network Connection" ); - techName = i18n( "Could Not Create Socket" ); - description = i18n( "This is a fairly technical error in which a required " - "device for network communications (a socket) could not be created." ); - causes << i18n( "The network connection may be incorrectly configured, or " - "the network interface may not be enabled." ); - solutions << sNetwork << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_CONNECT: - errorName = i18n( "Connection to Server Refused" ); - description = i18n( "The server <strong>%1</strong> refused to allow this " - "computer to make a connection." ).arg( host ); - causes << i18n( "The server, while currently connected to the Internet, " - "may not be configured to allow requests." ) - << i18n( "The server, while currently connected to the Internet, " - "may not be running the requested service (%1)." ).arg( protocol ) - << i18n( "A network firewall (a device which restricts Internet " - "requests), either protecting your network or the network of the server, " - "may have intervened, preventing this request." ); - solutions << sTryagain << sServeradmin << sSysadmin; - break; - - case TDEIO::ERR_CONNECTION_BROKEN: - errorName = i18n( "Connection to Server Closed Unexpectedly" ); - description = i18n( "Although a connection was established to " - "<strong>%1</strong>, the connection was closed at an unexpected point " - "in the communication." ).arg( host ); - causes << cNetwork << cNetpath << i18n( "A protocol error may have occurred, " - "causing the server to close the connection as a response to the error." ); - solutions << sTryagain << sServeradmin << sSysadmin; - break; - - case TDEIO::ERR_NOT_FILTER_PROTOCOL: - errorName = i18n( "URL Resource Invalid" ); - techName = i18n( "Protocol %1 is not a Filter Protocol" ).arg( protocol ); - description = i18n( "The <strong>U</strong>niform <strong>R</strong>esource " - "<strong>L</strong>ocator (URL) that you entered did not refer to " - "a valid mechanism of accessing the specific resource, " - "<strong>%1%2</strong>." ) - .arg( !host.isNull() ? host + '/' : TQString::null ).arg( dir ); - causes << i18n( "TDE is able to communicate through a protocol within a " - "protocol. This request specified a protocol be used as such, however " - "this protocol is not capable of such an action. This is a rare event, " - "and is likely to indicate a programming error." ); - solutions << sTypo << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_MOUNT: - errorName = i18n( "Unable to Initialize Input/Output Device" ); - techName = i18n( "Could Not Mount Device" ); - description = i18n( "The requested device could not be initialized " - "(\"mounted\"). The reported error was: <strong>%1</strong>" ) - .arg( errorText ); - causes << i18n( "The device may not be ready, for example there may be " - "no media in a removable media device (i.e. no CD-ROM in a CD drive), " - "or in the case of a peripheral/portable device, the device may not " - "be correctly connected." ) - << i18n( "You may not have permissions to initialize (\"mount\") the " - "device. On UNIX systems, often system administrator privileges are " - "required to initialize a device." ) - << cHardware; - solutions << i18n( "Check that the device is ready; removable drives " - "must contain media, and portable devices must be connected and powered " - "on.; and try again." ) << sAccess << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_UNMOUNT: - errorName = i18n( "Unable to Uninitialize Input/Output Device" ); - techName = i18n( "Could Not Unmount Device" ); - description = i18n( "The requested device could not be uninitialized " - "(\"unmounted\"). The reported error was: <strong>%1</strong>" ) - .arg( errorText ); - causes << i18n( "The device may be busy, that is, still in use by " - "another application or user. Even such things as having an open " - "browser window on a location on this device may cause the device to " - "remain in use." ) - << i18n( "You may not have permissions to uninitialize (\"unmount\") " - "the device. On UNIX systems, system administrator privileges are " - "often required to uninitialize a device." ) - << cHardware; - solutions << i18n( "Check that no applications are accessing the device, " - "and try again." ) << sAccess << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_READ: - errorName = i18n( "Cannot Read From Resource" ); - description = i18n( "This means that although the resource, " - "<strong>%1</strong>, was able to be opened, an error occurred while " - "reading the contents of the resource." ).arg( url ); - causes << i18n( "You may not have permissions to read from the resource." ); - if ( !isSlaveNetwork ) causes << cNetwork; - causes << cHardware; - solutions << sAccess; - if ( !isSlaveNetwork ) solutions << sNetwork; - solutions << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_WRITE: - errorName = i18n( "Cannot Write to Resource" ); - description = i18n( "This means that although the resource, <strong>%1</strong>" - ", was able to be opened, an error occurred while writing to the resource." ) - .arg( url ); - causes << i18n( "You may not have permissions to write to the resource." ); - if ( !isSlaveNetwork ) causes << cNetwork; - causes << cHardware; - solutions << sAccess; - if ( !isSlaveNetwork ) solutions << sNetwork; - solutions << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_BIND: - errorName = i18n( "Could Not Listen for Network Connections" ); - techName = i18n( "Could Not Bind" ); - description = i18n( "This is a fairly technical error in which a required " - "device for network communications (a socket) could not be established " - "to listen for incoming network connections." ); - causes << i18n( "The network connection may be incorrectly configured, or " - "the network interface may not be enabled." ); - solutions << sNetwork << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_LISTEN: - errorName = i18n( "Could Not Listen for Network Connections" ); - techName = i18n( "Could Not Listen" ); - description = i18n( "This is a fairly technical error in which a required " - "device for network communications (a socket) could not be established " - "to listen for incoming network connections." ); - causes << i18n( "The network connection may be incorrectly configured, or " - "the network interface may not be enabled." ); - solutions << sNetwork << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_ACCEPT: - errorName = i18n( "Could Not Accept Network Connection" ); - description = i18n( "This is a fairly technical error in which an error " - "occurred while attempting to accept an incoming network connection." ); - causes << i18n( "The network connection may be incorrectly configured, or " - "the network interface may not be enabled." ) - << i18n( "You may not have permissions to accept the connection." ); - solutions << sNetwork << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_LOGIN: - errorName = i18n( "Could Not Login: %1" ).arg( errorText ); - description = i18n( "An attempt to login to perform the requested " - "operation was unsuccessful." ); - causes << i18n( "You may have supplied incorrect authentication details or " - "none at all." ) - << i18n( "Your account may not have permission to access the " - "specified resource." ) << cProtocol; - solutions << i18n( "Retry the request and ensure your authentication details " - "are entered correctly." ) << sServeradmin << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_STAT: - errorName = i18n( "Could Not Determine Resource Status" ); - techName = i18n( "Could Not Stat Resource" ); - description = i18n( "An attempt to determine information about the status " - "of the resource <strong>%1</strong>, such as the resource name, type, " - "size, etc., was unsuccessful." ).arg( url ); - causes << i18n( "The specified resource may not have existed or may " - "not be accessible." ) << cProtocol << cHardware; - solutions << i18n( "Retry the request and ensure your authentication details " - "are entered correctly." ) << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_CLOSEDIR: - //result = i18n( "Could not terminate listing %1" ).arg( errorText ); - errorName = i18n( "Could Not Cancel Listing" ); - techName = i18n( "FIXME: Document this" ); - break; - - case TDEIO::ERR_COULD_NOT_MKDIR: - errorName = i18n( "Could Not Create Folder" ); - description = i18n( "An attempt to create the requested folder failed." ); - causes << cAccess << i18n( "The location where the folder was to be created " - "may not exist." ); - if ( !isSlaveNetwork ) causes << cProtocol; - solutions << i18n( "Retry the request." ) << sAccess; - break; - - case TDEIO::ERR_COULD_NOT_RMDIR: - errorName = i18n( "Could Not Remove Folder" ); - description = i18n( "An attempt to remove the specified folder, " - "<strong>%1</strong>, failed." ).arg( dir ); - causes << i18n( "The specified folder may not exist." ) - << i18n( "The specified folder may not be empty." ) - << cAccess; - if ( !isSlaveNetwork ) causes << cProtocol; - solutions << i18n( "Ensure that the folder exists and is empty, and try " - "again." ) << sAccess; - break; - - case TDEIO::ERR_CANNOT_RESUME: - errorName = i18n( "Could Not Resume File Transfer" ); - description = i18n( "The specified request asked that the transfer of " - "file <strong>%1</strong> be resumed at a certain point of the " - "transfer. This was not possible." ).arg( filename ); - causes << i18n( "The protocol, or the server, may not support file " - "resuming." ); - solutions << i18n( "Retry the request without attempting to resume " - "transfer." ); - break; - - case TDEIO::ERR_CANNOT_RENAME: - errorName = i18n( "Could Not Rename Resource" ); - description = i18n( "An attempt to rename the specified resource " - "<strong>%1</strong> failed." ).arg( url ); - causes << cAccess << cExists; - if ( !isSlaveNetwork ) causes << cProtocol; - solutions << sAccess << sExists; - break; - - case TDEIO::ERR_CANNOT_CHMOD: - errorName = i18n( "Could Not Alter Permissions of Resource" ); - description = i18n( "An attempt to alter the permissions on the specified " - "resource <strong>%1</strong> failed." ).arg( url ); - causes << cAccess << cExists; - solutions << sAccess << sExists; - break; - - case TDEIO::ERR_CANNOT_DELETE: - errorName = i18n( "Could Not Delete Resource" ); - description = i18n( "An attempt to delete the specified resource " - "<strong>%1</strong> failed." ).arg( url ); - causes << cAccess << cExists; - solutions << sAccess << sExists; - break; - - case TDEIO::ERR_SLAVE_DIED: - errorName = i18n( "Unexpected Program Termination" ); - description = i18n( "The program on your computer which provides access " - "to the <strong>%1</strong> protocol has unexpectedly terminated." ) - .arg( url ); - causes << cBuglikely; - solutions << sUpdate << sBugreport; - break; - - case TDEIO::ERR_OUT_OF_MEMORY: - errorName = i18n( "Out of Memory" ); - description = i18n( "The program on your computer which provides access " - "to the <strong>%1</strong> protocol could not obtain the memory " - "required to continue." ).arg( protocol ); - causes << cBuglikely; - solutions << sUpdate << sBugreport; - break; - - case TDEIO::ERR_UNKNOWN_PROXY_HOST: - errorName = i18n( "Unknown Proxy Host" ); - description = i18n( "While retrieving information about the specified " - "proxy host, <strong>%1</strong>, an Unknown Host error was encountered. " - "An unknown host error indicates that the requested name could not be " - "located on the Internet." ).arg( errorText ); - causes << i18n( "There may have been a problem with your network " - "configuration, specifically your proxy's hostname. If you have been " - "accessing the Internet with no problems recently, this is unlikely." ) - << cNetwork; - solutions << i18n( "Double-check your proxy settings and try again." ) - << sSysadmin; - break; - - case TDEIO::ERR_COULD_NOT_AUTHENTICATE: - errorName = i18n( "Authentication Failed: Method %1 Not Supported" ) - .arg( errorText ); - description = i18n( "Although you may have supplied the correct " - "authentication details, the authentication failed because the " - "method that the server is using is not supported by the TDE " - "program implementing the protocol %1." ).arg( protocol ); - solutions << i18n( "Please file a bug at <a href=\"http://bugs.kde.org/\">" - "http://bugs.pearsoncomputing.net/</a> to inform the TDE team of the unsupported " - "authentication method." ) << sSysadmin; - break; - - case TDEIO::ERR_ABORTED: - errorName = i18n( "Request Aborted" ); - description = i18n( "The request was not completed because it was " - "aborted." ); - solutions << i18n( "Retry the request." ); - break; - - case TDEIO::ERR_INTERNAL_SERVER: - errorName = i18n( "Internal Error in Server" ); - description = i18n( "The program on the server which provides access " - "to the <strong>%1</strong> protocol has reported an internal error: " - "%0." ).arg( protocol ); - causes << i18n( "This is most likely to be caused by a bug in the " - "server program. Please consider submitting a full bug report as " - "detailed below." ); - solutions << i18n( "Contact the administrator of the server " - "to advise them of the problem." ) - << i18n( "If you know who the authors of the server software are, " - "submit the bug report directly to them." ); - break; - - case TDEIO::ERR_SERVER_TIMEOUT: - errorName = i18n( "Timeout Error" ); - description = i18n( "Although contact was made with the server, a " - "response was not received within the amount of time allocated for " - "the request as follows:<ul>" - "<li>Timeout for establishing a connection: %1 seconds</li>" - "<li>Timeout for receiving a response: %2 seconds</li>" - "<li>Timeout for accessing proxy servers: %3 seconds</li></ul>" - "Please note that you can alter these timeout settings in the TDE " - "Control Center, by selecting Network -> Preferences." ) - .arg( KProtocolManager::connectTimeout() ) - .arg( KProtocolManager::responseTimeout() ) - .arg( KProtocolManager::proxyConnectTimeout() ); - causes << cNetpath << i18n( "The server was too busy responding to other " - "requests to respond." ); - solutions << sTryagain << sServeradmin; - break; - - case TDEIO::ERR_UNKNOWN: - errorName = i18n( "Unknown Error" ); - description = i18n( "The program on your computer which provides access " - "to the <strong>%1</strong> protocol has reported an unknown error: " - "%2." ).arg( protocol ).arg( errorText ); - causes << cBug; - solutions << sUpdate << sBugreport; - break; - - case TDEIO::ERR_UNKNOWN_INTERRUPT: - errorName = i18n( "Unknown Interruption" ); - description = i18n( "The program on your computer which provides access " - "to the <strong>%1</strong> protocol has reported an interruption of " - "an unknown type: %2." ).arg( protocol ).arg( errorText ); - causes << cBug; - solutions << sUpdate << sBugreport; - break; - - case TDEIO::ERR_CANNOT_DELETE_ORIGINAL: - errorName = i18n( "Could Not Delete Original File" ); - description = i18n( "The requested operation required the deleting of " - "the original file, most likely at the end of a file move operation. " - "The original file <strong>%1</strong> could not be deleted." ) - .arg( errorText ); - causes << cAccess; - solutions << sAccess; - break; - - case TDEIO::ERR_CANNOT_DELETE_PARTIAL: - errorName = i18n( "Could Not Delete Temporary File" ); - description = i18n( "The requested operation required the creation of " - "a temporary file in which to save the new file while being " - "downloaded. This temporary file <strong>%1</strong> could not be " - "deleted." ).arg( errorText ); - causes << cAccess; - solutions << sAccess; - break; - - case TDEIO::ERR_CANNOT_RENAME_ORIGINAL: - errorName = i18n( "Could Not Rename Original File" ); - description = i18n( "The requested operation required the renaming of " - "the original file <strong>%1</strong>, however it could not be " - "renamed." ).arg( errorText ); - causes << cAccess; - solutions << sAccess; - break; - - case TDEIO::ERR_CANNOT_RENAME_PARTIAL: - errorName = i18n( "Could Not Rename Temporary File" ); - description = i18n( "The requested operation required the creation of " - "a temporary file <strong>%1</strong>, however it could not be " - "created." ).arg( errorText ); - causes << cAccess; - solutions << sAccess; - break; - - case TDEIO::ERR_CANNOT_SYMLINK: - errorName = i18n( "Could Not Create Link" ); - techName = i18n( "Could Not Create Symbolic Link" ); - description = i18n( "The requested symbolic link %1 could not be created." ) - .arg( errorText ); - causes << cAccess; - solutions << sAccess; - break; - - case TDEIO::ERR_NO_CONTENT: - errorName = i18n( "No Content" ); - description = errorText; - break; - - case TDEIO::ERR_DISK_FULL: - errorName = i18n( "Disk Full" ); - description = i18n( "The requested file <strong>%1</strong> could not be " - "written to as there is inadequate disk space." ).arg( errorText ); - solutions << i18n( "Free up enough disk space by 1) deleting unwanted and " - "temporary files; 2) archiving files to removable media storage such as " - "CD-Recordable discs; or 3) obtain more storage capacity." ) - << sSysadmin; - break; - - case TDEIO::ERR_IDENTICAL_FILES: - errorName = i18n( "Source and Destination Files Identical" ); - description = i18n( "The operation could not be completed because the " - "source and destination files are the same file." ); - solutions << i18n( "Choose a different filename for the destination file." ); - break; - - // We assume that the slave has all the details - case TDEIO::ERR_SLAVE_DEFINED: - errorName = TQString::null; - description = errorText; - break; - - default: - // fall back to the plain error... - errorName = i18n( "Undocumented Error" ); - description = buildErrorString( errorCode, errorText ); - } - - TQByteArray ret; - TQDataStream stream(ret, IO_WriteOnly); - stream << errorName << techName << description << causes << solutions; - return ret; -} - -#ifdef Q_OS_UNIX - -#include <limits.h> -#include <stdlib.h> -#include <stdio.h> -#include <tqfile.h> - -#include <config.h> - -#ifdef HAVE_PATHS_H -#include <paths.h> -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#include <sys/param.h> -#ifdef HAVE_LIMITS_H -#include <limits.h> -#endif -#ifdef HAVE_SYS_MNTTAB_H -#include <sys/mnttab.h> -#endif -#ifdef HAVE_MNTENT_H -#include <mntent.h> -#elif defined(HAVE_SYS_MNTENT_H) -#include <sys/mntent.h> -#endif -#ifdef HAVE_SYS_UCRED_H -#include <sys/ucred.h> -#endif -#ifdef HAVE_SYS_MOUNT_H -#include <sys/mount.h> -#endif -#ifdef HAVE_FSTAB_H -#include <fstab.h> -#endif -#if defined(_AIX) -#include <sys/mntctl.h> -#include <sys/vmount.h> -#include <sys/vfs.h> - -/* AIX does not prototype mntctl anywhere that I can find */ -#ifndef mntctl -extern "C" { -int mntctl(int command, int size, void* buffer); -} -#endif -extern "C" struct vfs_ent *getvfsbytype(int vfsType); -extern "C" void endvfsent( ); -#endif - -/*************************************************************** - * - * Utility functions - * - ***************************************************************/ - -#ifndef HAVE_GETMNTINFO - -#ifdef _PATH_MOUNTED -// On some Linux, MNTTAB points to /etc/fstab ! -# undef MNTTAB -# define MNTTAB _PATH_MOUNTED -#else -# ifndef MNTTAB -# ifdef MTAB_FILE -# define MNTTAB MTAB_FILE -# else -# define MNTTAB "/etc/mnttab" -# endif -# endif -#endif - -#ifndef FSTAB -# ifdef _PATH_FSTAB -# define FSTAB _PATH_FSTAB -# else -# define FSTAB "/etc/fstab" -# endif -#endif - -#ifdef __CYGWIN__ -#define hasmntopt(var,opt) (0) -#endif - -// There are (at least) four kind of APIs: -// setmntent + getmntent + struct mntent (linux...) -// getmntent + struct mnttab -// mntctl + struct vmount (AIX) -// getmntinfo + struct statfs&flags (BSD 4.4 and friends) -// getfsent + char* (BSD 4.3 and friends) - -#ifdef HAVE_SETMNTENT -#define SETMNTENT setmntent -#define ENDMNTENT endmntent -#define STRUCT_MNTENT struct mntent * -#define STRUCT_SETMNTENT FILE * -#define GETMNTENT(file, var) ((var = getmntent(file)) != 0) -#define MOUNTPOINT(var) var->mnt_dir -#define MOUNTTYPE(var) var->mnt_type -#define HASMNTOPT(var, opt) hasmntopt(var, opt) -#define FSNAME(var) var->mnt_fsname -#elif defined(_AIX) -/* we don't need this stuff */ -#else -#define SETMNTENT fopen -#define ENDMNTENT fclose -#define STRUCT_MNTENT struct mnttab -#define STRUCT_SETMNTENT FILE * -#define GETMNTENT(file, var) (getmntent(file, &var) == 0) -#define MOUNTPOINT(var) var.mnt_mountp -#define MOUNTTYPE(var) var.mnt_fstype -#define HASMNTOPT(var, opt) hasmntopt(&var, opt) -#define FSNAME(var) var.mnt_special -#endif - -#endif /* HAVE_GETMNTINFO */ - -TQString TDEIO::findDeviceMountPoint( const TQString& filename ) -{ - TQString result; - -#ifdef HAVE_VOLMGT - /* - * support for Solaris volume management - */ - const char *volpath; - FILE *mnttab; - struct mnttab mnt; - int len; - TQCString devname; - - if( (volpath = volmgt_root()) == NULL ) { - kdDebug( 7007 ) << "findDeviceMountPoint: " - << "VOLMGT: can't find volmgt root dir" << endl; - return TQString::null; - } - - if( (mnttab = fopen( MNTTAB, "r" )) == NULL ) { - kdDebug( 7007 ) << "findDeviceMountPoint: " - << "VOLMGT: can't open mnttab" << endl; - return TQString::null; - } - - devname = volpath; - devname += TQFile::encodeName( filename ); - devname += '/'; - len = devname.length(); -// kdDebug( 7007 ) << "findDeviceMountPoint: " -// << "VOLMGT: searching mountpoint for \"" << devname << "\"" -// << endl; - - /* - * find the mountpoint - * floppies: - * /dev/disketteN => <volpath>/dev/disketteN - * CDROM, ZIP, and other media: - * /dev/dsk/cXtYdZs2 => <volpath>/dev/dsk/cXtYdZ (without slice#) - */ - rewind( mnttab ); - result = TQString::null; - while( getmntent( mnttab, &mnt ) == 0 ) { - /* - * either match the exact device name (floppies), - * or the device name without the slice# - */ - if( strncmp( devname.data(), mnt.mnt_special, len ) == 0 - || (strncmp( devname.data(), mnt.mnt_special, len - 3 ) == 0 - && mnt.mnt_special[len - 3] == '/' ) - || (strcmp(TQFile::encodeName(filename).data() - , mnt.mnt_special)==0)) { - result = mnt.mnt_mountp; - break; - } - } - fclose( mnttab ); -#else - - char realpath_buffer[MAXPATHLEN]; - TQCString realname; - - realname = TQFile::encodeName(filename); - /* If the path contains symlinks, get the real name */ - if (realpath(realname, realpath_buffer) != 0) - // succes, use result from realpath - realname = realpath_buffer; - - //kdDebug(7007) << "findDeviceMountPoint realname=" << realname << endl; - -#ifdef HAVE_GETMNTINFO - -#ifdef GETMNTINFO_USES_STATVFS - struct statvfs *mounted; -#else - struct statfs *mounted; -#endif - - int num_fs = getmntinfo(&mounted, MNT_NOWAIT); - - for (int i=0;i<num_fs;i++) { - - TQCString device_name = mounted[i].f_mntfromname; - - // If the path contains symlinks, get - // the real name - if (realpath(device_name, realpath_buffer) != 0) - // succes, use result from realpath - device_name = realpath_buffer; - - if (realname == device_name) { - result = mounted[i].f_mntonname; - break; - } - } - -#elif defined(_AIX) - - struct vmount *mntctl_buffer; - struct vmount *vm; - char *mountedfrom; - char *mountedto; - int fsname_len, num; - int buf_sz = 4096; - - /* mntctl can be used to query mounted file systems. - * mntctl takes only the command MCTL_QUERY so far. - * The buffer is filled with an array of vmount structures, but these - * vmount structures have variable size. - * mntctl return values: - * -1 error - * 0 look in first word of buffer for required bytes, 4096 may be - * a good starting size, but if tables grow too large, look here. - * >0 number of vmount structures - */ - mntctl_buffer = (struct vmount*)malloc(buf_sz); - num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer); - if (num == 0) - { - buf_sz = *(int*)mntctl_buffer; - free(mntctl_buffer); - mntctl_buffer = (struct vmount*)malloc(buf_sz); - num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer); - } - - if (num > 0) - { - /* iterate through items in the vmount structure: */ - vm = mntctl_buffer; - for ( ; num > 0; num-- ) - { - /* get the name of the mounted file systems: */ - fsname_len = vmt2datasize(vm, VMT_STUB); - mountedto = (char*)malloc(fsname_len + 1); - mountedto[fsname_len] = '\0'; - strncpy(mountedto, (char *)vmt2dataptr(vm, VMT_STUB), fsname_len); - - /* get the mount-from information: */ - fsname_len = vmt2datasize(vm, VMT_OBJECT); - mountedfrom = (char*)malloc(fsname_len + 1); - mountedfrom[fsname_len] = '\0'; - strncpy(mountedfrom, (char *)vmt2dataptr(vm, VMT_OBJECT), fsname_len); - - TQCString device_name = mountedfrom; - - if (realpath(device_name, realpath_buffer) != 0) - // success, use result from realpath - device_name = realpath_buffer; - - free(mountedfrom); - - if (realname == device_name) { - result = mountedto; - free(mountedto); - break; - } - - free(mountedto); - - /* goto the next vmount structure: */ - vm = (struct vmount *)((char *)vm + vm->vmt_length); - } - } - - free( mntctl_buffer ); - -#else - - STRUCT_SETMNTENT mtab; - - /* Get the list of mounted file systems */ - - if ((mtab = SETMNTENT(MNTTAB, "r")) == 0) { - perror("setmntent"); - return TQString::null; - } - - /* Loop over all file systems and see if we can find our - * mount point. - * Note that this is the mount point with the longest match. - * XXX: Fails if me->mnt_dir is not a realpath but goes - * through a symlink, e.g. /foo/bar where /foo is a symlink - * pointing to /local/foo. - * - * How kinky can you get with a filesystem? - */ - - STRUCT_MNTENT me; - - while (GETMNTENT(mtab, me)) - { - // There may be symbolic links into the /etc/mnttab - // So we have to find the real device name here as well! - TQCString device_name = FSNAME(me); - if (device_name.isEmpty() || (device_name == "none")) - continue; - - //kdDebug( 7007 ) << "device_name=" << device_name << endl; - - // If the path contains symlinks, get - // the real name - if (realpath(device_name, realpath_buffer) != 0) - // succes, use result from realpath - device_name = realpath_buffer; - - //kdDebug( 7007 ) << "device_name after realpath =" << device_name << endl; - - if (realname == device_name) - { - result = MOUNTPOINT(me); - break; - } - } - - ENDMNTENT(mtab); - -#endif /* GET_MNTINFO */ -#endif /* HAVE_VOLMGT */ - - //kdDebug( 7007 ) << "Returning result " << result << endl; - return result; -} - -// Don't just trust the return value, keep iterating to check for a better match (bigger max) -static bool is_my_mountpoint( const char *mountpoint, const char *realname, int &max ) -{ - int length = strlen(mountpoint); - - if (!strncmp(mountpoint, realname, length) - && length > max) { - max = length; - if (length == 1 || realname[length] == '/' || realname[length] == '\0') - return true; - } - return false; -} - -typedef enum { Unseen, Right, Wrong } MountState; - -/** - * Idea and code base by Olaf Kirch <okir@caldera.de> - **/ -static void check_mount_point(const char *mounttype, - const char *fsname, - MountState &isslow, MountState &isautofs) -{ - bool nfs = !strcmp(mounttype, "nfs"); - bool autofs = !strcmp(mounttype, "autofs") || !strcmp(mounttype,"subfs"); - bool pid = (strstr(fsname, ":(pid") != 0); - - if (nfs && !pid) - isslow = Right; - else if (isslow == Right) - isslow = Wrong; - - /* Does this look like automounted? */ - if (autofs || (nfs && pid)) { - isautofs = Right; - isslow = Right; - } -} - -// returns the mount point, checks the mount state. -// if ismanual == Wrong this function does not check the manual mount state -static TQString get_mount_info(const TQString& filename, - MountState& isautofs, MountState& isslow, MountState& ismanual, - TQString& fstype) -{ - static bool gotRoot = false; - static dev_t rootDevice; - - struct cachedDevice_t - { - dev_t device; - TQString mountPoint; - MountState isautofs; - MountState isslow; - MountState ismanual; - TQString fstype; - }; - static struct cachedDevice_t *cachedDevice = 0; - - if (!gotRoot) - { - KDE_struct_stat stat_buf; - KDE_stat("/", &stat_buf); - gotRoot = true; - rootDevice = stat_buf.st_dev; - } - - bool gotDevice = false; - KDE_struct_stat stat_buf; - if (KDE_stat(TQFile::encodeName(filename), &stat_buf) == 0) - { - gotDevice = true; - if (stat_buf.st_dev == rootDevice) - { - static const TQString &root = TDEGlobal::staticQString("/"); - isautofs = Wrong; - isslow = Wrong; - ismanual = Wrong; - fstype = TQString::null; // ### do we need it? - return root; - } - if (cachedDevice && (stat_buf.st_dev == cachedDevice->device)) - { - bool interestedInIsManual = ismanual != Wrong; - isautofs = cachedDevice->isautofs; - isslow = cachedDevice->isslow; - ismanual = cachedDevice->ismanual; - fstype = cachedDevice->fstype; - // Don't use the cache if it doesn't have the information we're looking for - if ( !interestedInIsManual || ismanual != Unseen ) - return cachedDevice->mountPoint; - } - } - - char realname[MAXPATHLEN]; - - memset(realname, 0, MAXPATHLEN); - - /* If the path contains symlinks, get the real name */ - if (realpath(TQFile::encodeName(filename), realname) == 0) { - if( strlcpy(realname, TQFile::encodeName(filename), MAXPATHLEN)>=MAXPATHLEN) - return TQString::null; - } - - int max = 0; - TQString mountPoint; - - /* Loop over all file systems and see if we can find our - * mount point. - * Note that this is the mount point with the longest match. - * XXX: Fails if me->mnt_dir is not a realpath but goes - * through a symlink, e.g. /foo/bar where /foo is a symlink - * pointing to /local/foo. - * - * How kinky can you get with a filesystem? - */ - -#ifdef HAVE_GETMNTINFO - -#ifdef GETMNTINFO_USES_STATVFS - struct statvfs *mounted; -#else - struct statfs *mounted; -#endif - - char realpath_buffer[MAXPATHLEN]; - - int num_fs = getmntinfo(&mounted, MNT_NOWAIT); - - for (int i=0;i<num_fs;i++) { - - TQCString device_name = mounted[i].f_mntfromname; - - // If the path contains symlinks, get - // the real name - if (realpath(device_name, realpath_buffer) != 0) - // succes, use result from realpath - device_name = realpath_buffer; -#ifdef __osf__ - char * mounttype = mnt_names[mounted[i].f_type]; -#else - char * mounttype = mounted[i].f_fstypename; -#endif - if ( is_my_mountpoint( mounted[i].f_mntonname, realname, max ) ) - { - mountPoint = TQFile::decodeName(mounted[i].f_mntonname); - fstype = TQString::fromLatin1(mounttype); - check_mount_point( mounttype, mounted[i].f_mntfromname, - isautofs, isslow ); - // keep going, looking for a potentially better one - - if (ismanual == Unseen) - { - struct fstab *ft = getfsfile(mounted[i].f_mntonname); - if (!ft || strstr(ft->fs_mntops, "noauto")) - ismanual = Right; - } - } - } - -#elif defined(_AIX) - - struct vmount *mntctl_buffer; - struct vmount *vm; - char *mountedfrom; - char *mountedto; - int fsname_len, num; - char realpath_buffer[MAXPATHLEN]; - int buf_sz = 4096; - - mntctl_buffer = (struct vmount*)malloc(buf_sz); - num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer); - if (num == 0) - { - buf_sz = *(int*)mntctl_buffer; - free(mntctl_buffer); - mntctl_buffer = (struct vmount*)malloc(buf_sz); - num = mntctl(MCTL_QUERY, buf_sz, mntctl_buffer); - } - - if (num > 0) - { - /* iterate through items in the vmount structure: */ - vm = (struct vmount *)mntctl_buffer; - for ( ; num > 0; num-- ) - { - /* get the name of the mounted file systems: */ - fsname_len = vmt2datasize(vm, VMT_STUB); - mountedto = (char*)malloc(fsname_len + 1); - mountedto[fsname_len] = '\0'; - strncpy(mountedto, (char *)vmt2dataptr(vm, VMT_STUB), fsname_len); - - fsname_len = vmt2datasize(vm, VMT_OBJECT); - mountedfrom = (char*)malloc(fsname_len + 1); - mountedfrom[fsname_len] = '\0'; - strncpy(mountedfrom, (char *)vmt2dataptr(vm, VMT_OBJECT), fsname_len); - - /* get the mount-from information: */ - TQCString device_name = mountedfrom; - - if (realpath(device_name, realpath_buffer) != 0) - // success, use result from realpath - device_name = realpath_buffer; - - /* Look up the string for the file system type, - * as listed in /etc/vfs. - * ex.: nfs,jfs,afs,cdrfs,sfs,cachefs,nfs3,autofs - */ - struct vfs_ent* ent = getvfsbytype(vm->vmt_gfstype); - - if ( is_my_mountpoint( mountedto, realname, max ) ) - { - mountPoint = TQFile::decodeName(mountedto); - fstype = TQString::fromLatin1(ent->vfsent_name); - check_mount_point(ent->vfsent_name, device_name, isautofs, isslow); - - if (ismanual == Unseen) - { - // TODO: add check for ismanual, I couldn't find any way - // how to get the mount attribute from /etc/filesystems - ismanual == Wrong; - } - } - - free(mountedfrom); - free(mountedto); - - /* goto the next vmount structure: */ - vm = (struct vmount *)((char *)vm + vm->vmt_length); - } - - endvfsent( ); - } - - free( mntctl_buffer ); - -#else - - STRUCT_SETMNTENT mtab; - /* Get the list of mounted file systems */ - - if ((mtab = SETMNTENT(MNTTAB, "r")) == 0) { - perror("setmntent"); - return TQString::null; - } - - STRUCT_MNTENT me; - - while (true) { - if (!GETMNTENT(mtab, me)) - break; - - if ( is_my_mountpoint( MOUNTPOINT(me), realname, max ) ) - { - mountPoint = TQFile::decodeName( MOUNTPOINT(me) ); - fstype = MOUNTTYPE(me); - check_mount_point(MOUNTTYPE(me), FSNAME(me), isautofs, isslow); - // we don't check if ismanual is Right, if /a/b is manually - // mounted /a/b/c can't be automounted. At least IMO. - if (ismanual == Unseen) - { - // The next GETMNTENT call may destroy 'me' - // Copy out the info that we need - TQCString fsname_me = FSNAME(me); - TQCString mounttype_me = MOUNTTYPE(me); - - STRUCT_SETMNTENT fstab; - if ((fstab = SETMNTENT(FSTAB, "r")) == 0) { - continue; - } - - bool found = false; - STRUCT_MNTENT fe; - while (GETMNTENT(fstab, fe)) - { - if (fsname_me == FSNAME(fe)) - { - found = true; - if (HASMNTOPT(fe, "noauto") || - !strcmp(MOUNTTYPE(fe), "supermount")) - ismanual = Right; - break; - } - } - if (!found || (mounttype_me == "supermount")) - ismanual = Right; - - ENDMNTENT(fstab); - } - } - } - - ENDMNTENT(mtab); - -#endif - - if (isautofs == Right && isslow == Unseen) - isslow = Right; - - if (gotDevice) - { - if (!cachedDevice) - cachedDevice = new cachedDevice_t; - - cachedDevice->device = stat_buf.st_dev; - cachedDevice->mountPoint = mountPoint; - cachedDevice->isautofs = isautofs; - cachedDevice->isslow = isslow; - cachedDevice->ismanual = ismanual; - cachedDevice->fstype = fstype; - } - - return mountPoint; -} - -#else //!Q_OS_UNIX -//dummy -TQString TDEIO::findDeviceMountPoint( const TQString& filename ) -{ - return TQString::null; -} -#endif - -TQString TDEIO::findPathMountPoint(const TQString& filename) -{ -#ifdef Q_OS_UNIX - MountState isautofs = Unseen, isslow = Unseen, ismanual = Wrong; - TQString fstype; - return get_mount_info(filename, isautofs, isslow, ismanual, fstype); -#else //!Q_OS_UNIX - return TQString::null; -#endif -} - -bool TDEIO::manually_mounted(const TQString& filename) -{ -#ifdef Q_OS_UNIX - MountState isautofs = Unseen, isslow = Unseen, ismanual = Unseen; - TQString fstype; - TQString mountPoint = get_mount_info(filename, isautofs, isslow, ismanual, fstype); - return !mountPoint.isNull() && (ismanual == Right); -#else //!Q_OS_UNIX - return false; -#endif -} - -bool TDEIO::probably_slow_mounted(const TQString& filename) -{ -#ifdef Q_OS_UNIX - MountState isautofs = Unseen, isslow = Unseen, ismanual = Wrong; - TQString fstype; - TQString mountPoint = get_mount_info(filename, isautofs, isslow, ismanual, fstype); - return !mountPoint.isNull() && (isslow == Right); -#else //!Q_OS_UNIX - return false; -#endif -} - -bool TDEIO::testFileSystemFlag(const TQString& filename, FileSystemFlag flag) -{ -#ifdef Q_OS_UNIX - MountState isautofs = Unseen, isslow = Unseen, ismanual = Wrong; - TQString fstype; - TQString mountPoint = get_mount_info(filename, isautofs, isslow, ismanual, fstype); - kdDebug() << "testFileSystemFlag: fstype=" << fstype << endl; - if (mountPoint.isNull()) - return false; - bool isMsDos = ( fstype == "msdos" || fstype == "fat" || fstype == "vfat" ); - switch (flag) { - case SupportsChmod: - case SupportsChown: - case SupportsUTime: - case SupportsSymlinks: - return !isMsDos; // it's amazing the number of things FAT doesn't support :) - case CaseInsensitive: - return isMsDos; - } -#endif - return false; -} - -TDEIO::CacheControl TDEIO::parseCacheControl(const TQString &cacheControl) -{ - TQString tmp = cacheControl.lower(); - - if (tmp == "cacheonly") - return TDEIO::CC_CacheOnly; - if (tmp == "cache") - return TDEIO::CC_Cache; - if (tmp == "verify") - return TDEIO::CC_Verify; - if (tmp == "refresh") - return TDEIO::CC_Refresh; - if (tmp == "reload") - return TDEIO::CC_Reload; - - kdDebug() << "unrecognized Cache control option:"<<cacheControl<<endl; - return TDEIO::CC_Verify; -} - -TQString TDEIO::getCacheControlString(TDEIO::CacheControl cacheControl) -{ - if (cacheControl == TDEIO::CC_CacheOnly) - return "CacheOnly"; - if (cacheControl == TDEIO::CC_Cache) - return "Cache"; - if (cacheControl == TDEIO::CC_Verify) - return "Verify"; - if (cacheControl == TDEIO::CC_Refresh) - return "Refresh"; - if (cacheControl == TDEIO::CC_Reload) - return "Reload"; - kdDebug() << "unrecognized Cache control enum value:"<<cacheControl<<endl; - return TQString::null; -} diff --git a/kio/kio/global.h b/kio/kio/global.h deleted file mode 100644 index 44b9df616..000000000 --- a/kio/kio/global.h +++ /dev/null @@ -1,547 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __kio_global_h__ -#define __kio_global_h__ - -#include <tqstring.h> -#include <tqvaluelist.h> -#include <tqptrlist.h> -#include <tqdatastream.h> -#include <tqdatetime.h> -#include <tqmap.h> - -#include <kurl.h> - -/** - * @short A namespace for KIO globals - * - */ -namespace TDEIO -{ - /// 64-bit file offset - typedef TQ_LLONG fileoffset_t; - /// 64-bit file size - typedef TQ_ULLONG filesize_t; - - /** - * Converts @p size from bytes to the string representation. - * - * @param size size in bytes - * @return converted size as a string - e.g. 123.4 kB , 12.0 MB - */ - TDEIO_EXPORT TQString convertSize( TDEIO::filesize_t size ); - - /** - * Converts @p size from bytes to a string representation with includes - * the size in bytes. - * e.g. 90 B, 240 B, 1.4 KB (1495 B), 2.6MB (2,734,344 B), 0 B - * @param size size in bytes - * @return converted size as a string - e.g. 1.4 KB (1495 B), 45 B - */ - TDEIO_EXPORT TQString convertSizeWithBytes( TDEIO::filesize_t size ); - /** - * Converts a size to a string representation - * Not unlike TQString::number(...) - * - * @param size size in bytes - * @return converted size as a string - e.g. 123456789 - */ - TDEIO_EXPORT TQString number( TDEIO::filesize_t size ); - - /** - * Converts size from kilo-bytes to the string representation. - * - * @param kbSize size in kilo-bytes - * @return converted size as a string - e.g. 123.4 kB , 12.0 MB - */ - TDEIO_EXPORT TQString convertSizeFromKB( TDEIO::filesize_t kbSize ); - - /** - * Calculates remaining time in seconds from total size, processed size and speed. - * - * @param totalSize total size in bytes - * @param processedSize processed size in bytes - * @param speed speed in bytes per second - * @return calculated remaining time in seconds - * - * @since 3.4 - */ - TDEIO_EXPORT unsigned int calculateRemainingSeconds( TDEIO::filesize_t totalSize, - TDEIO::filesize_t processedSize, TDEIO::filesize_t speed ); - - /** - * Convert @p seconds to a string representing number of days, hours, minutes and seconds - * - * @param seconds number of seconds to convert - * @return string representation in a locale depending format - * - * @since 3.4 - */ - TDEIO_EXPORT TQString convertSeconds( unsigned int seconds ); - - /** - * Calculates remaining time from total size, processed size and speed. - * Warning: As TQTime is limited to 23:59:59, use calculateRemainingSeconds() instead - * - * @param totalSize total size in bytes - * @param processedSize processed size in bytes - * @param speed speed in bytes per second - * @return calculated remaining time - */ - TDEIO_EXPORT TQTime calculateRemaining( TDEIO::filesize_t totalSize, TDEIO::filesize_t processedSize, TDEIO::filesize_t speed ) KDE_DEPRECATED; - - /** - * Helper for showing information about a set of files and directories - * @param items the number of items (= @p files + @p dirs + number of symlinks :) - * @param files the number of files - * @param dirs the number of dirs - * @param size the sum of the size of the @p files - * @param showSize whether to show the size in the result - * @return the summary string - */ - TDEIO_EXPORT TQString itemsSummaryString(uint items, uint files, uint dirs, TDEIO::filesize_t size, bool showSize); - - /** - * Encodes (from the text displayed to the real filename) - * This translates % into %% and / into %2f - * Used by TDEIO::link, for instance. - * @param str the file name to encode - * @return the encoded file name - */ - TDEIO_EXPORT TQString encodeFileName( const TQString & str ); - /** - * Decodes (from the filename to the text displayed) - * This translates %2[fF] into / and %% into % - * @param str the file name to decode - * @return the decoded file name - */ - TDEIO_EXPORT TQString decodeFileName( const TQString & str ); - - /** - * Commands that can be invoked by a job. - */ - enum Command { - CMD_HOST = '0', // 48 - CMD_CONNECT = '1', // 49 - CMD_DISCONNECT = '2', // 50 - CMD_SLAVE_STATUS = '3', // 51 - CMD_SLAVE_CONNECT = '4', // 52 - CMD_SLAVE_HOLD = '5', // 53 - CMD_NONE = 'A', // 65 - CMD_TESTDIR = 'B', // 66 - CMD_GET = 'C', // 67 - CMD_PUT = 'D', // 68 - CMD_STAT = 'E', // 69 - CMD_MIMETYPE = 'F', // 70 - CMD_LISTDIR = 'G', // 71 - CMD_MKDIR = 'H', // 72 - CMD_RENAME = 'I', // 73 - CMD_COPY = 'J', // 74 - CMD_DEL = 'K', // 75 - CMD_CHMOD = 'L', // 76 - CMD_SPECIAL = 'M', // 77 - CMD_USERPASS = 'N', // 78 - CMD_REPARSECONFIGURATION = 'O', // 79 - CMD_META_DATA = 'P', // 80 - CMD_SYMLINK = 'Q', // 81 - CMD_SUBURL = 'R', // 82 Inform the slave about the url it is streaming on. - CMD_MESSAGEBOXANSWER = 'S', // 83 - CMD_RESUMEANSWER = 'T', // 84 - CMD_CONFIG = 'U', // 85 - CMD_MULTI_GET = 'V', // 86 - CMD_LOCALURL = 'W' // 87 - // Add new ones here once a release is done, to avoid breaking binary compatibility. - // Note that protocol-specific commands shouldn't be added here, but should use special. - }; - - /** - * Error codes that can be emitted by KIO. - */ - enum Error { - ERR_CANNOT_OPEN_FOR_READING = 1, - ERR_CANNOT_OPEN_FOR_WRITING = 2, - ERR_CANNOT_LAUNCH_PROCESS = 3, - ERR_INTERNAL = 4, - ERR_MALFORMED_URL = 5, - ERR_UNSUPPORTED_PROTOCOL = 6, - ERR_NO_SOURCE_PROTOCOL = 7, - ERR_UNSUPPORTED_ACTION = 8, - ERR_IS_DIRECTORY = 9, // ... where a file was expected - ERR_IS_FILE = 10, // ... where a directory was expected (e.g. listing) - ERR_DOES_NOT_EXIST = 11, - ERR_FILE_ALREADY_EXIST = 12, - ERR_DIR_ALREADY_EXIST = 13, - ERR_UNKNOWN_HOST = 14, - ERR_ACCESS_DENIED = 15, - ERR_WRITE_ACCESS_DENIED = 16, - ERR_CANNOT_ENTER_DIRECTORY = 17, - ERR_PROTOCOL_IS_NOT_A_FILESYSTEM = 18, - ERR_CYCLIC_LINK = 19, - ERR_USER_CANCELED = 20, - ERR_CYCLIC_COPY = 21, - ERR_COULD_NOT_CREATE_SOCKET = 22, // KDE4: s/COULD_NOT/CANNOT/ or the other way round - ERR_COULD_NOT_CONNECT = 23, - ERR_CONNECTION_BROKEN = 24, - ERR_NOT_FILTER_PROTOCOL = 25, - ERR_COULD_NOT_MOUNT = 26, - ERR_COULD_NOT_UNMOUNT = 27, - ERR_COULD_NOT_READ = 28, - ERR_COULD_NOT_WRITE = 29, - ERR_COULD_NOT_BIND = 30, - ERR_COULD_NOT_LISTEN = 31, - ERR_COULD_NOT_ACCEPT = 32, - ERR_COULD_NOT_LOGIN = 33, - ERR_COULD_NOT_STAT = 34, - ERR_COULD_NOT_CLOSEDIR = 35, - ERR_COULD_NOT_MKDIR = 37, - ERR_COULD_NOT_RMDIR = 38, - ERR_CANNOT_RESUME = 39, - ERR_CANNOT_RENAME = 40, - ERR_CANNOT_CHMOD = 41, - ERR_CANNOT_DELETE = 42, - // The text argument is the protocol that the dead slave supported. - // This means for example: file, ftp, http, ... - ERR_SLAVE_DIED = 43, - ERR_OUT_OF_MEMORY = 44, - ERR_UNKNOWN_PROXY_HOST = 45, - ERR_COULD_NOT_AUTHENTICATE = 46, - ERR_ABORTED = 47, // Action got aborted from application side - ERR_INTERNAL_SERVER = 48, - ERR_SERVER_TIMEOUT = 49, - ERR_SERVICE_NOT_AVAILABLE = 50, - ERR_UNKNOWN = 51, - // (was a warning) ERR_CHECKSUM_MISMATCH = 52, - ERR_UNKNOWN_INTERRUPT = 53, - ERR_CANNOT_DELETE_ORIGINAL = 54, - ERR_CANNOT_DELETE_PARTIAL = 55, - ERR_CANNOT_RENAME_ORIGINAL = 56, - ERR_CANNOT_RENAME_PARTIAL = 57, - ERR_NEED_PASSWD = 58, - ERR_CANNOT_SYMLINK = 59, - ERR_NO_CONTENT = 60, // Action succeeded but no content will follow. - ERR_DISK_FULL = 61, - ERR_IDENTICAL_FILES = 62, // src==dest when moving/copying - ERR_SLAVE_DEFINED = 63, // for slave specified errors that can be - // rich text. Email links will be handled - // by the standard email app and all hrefs - // will be handled by the standard browser. - // <a href="exec:/khelpcenter ?" will be - // forked. - ERR_UPGRADE_REQUIRED = 64, // A transport upgrade is required to access this - // object. For instance, TLS is demanded by - // the server in order to continue. - ERR_POST_DENIED = 65, // Issued when trying to POST data to a certain Ports - // see job.cpp - ERR_OFFLINE_MODE = 66 // Used when an app is in offline mode and a - // requested document is unavailable. - }; - - /** - * Returns a translated error message for @p errorCode using the - * additional error information provided by @p errorText. - * @param errorCode the error code - * @param errorText the additional error text - * @return the created error string - */ - TDEIO_EXPORT TQString buildErrorString(int errorCode, const TQString &errorText); - - /** - * Returns a translated html error message for @p errorCode using the - * additional error information provided by @p errorText , @p reqUrl - * (the request URL), and the ioslave @p method . - * @param errorCode the error code - * @param errorText the additional error text - * @param reqUrl the request URL - * @param method the ioslave method - * @return the created error string - */ - TDEIO_EXPORT TQString buildHTMLErrorString(int errorCode, const TQString &errorText, - const KURL *reqUrl = 0L, int method = -1 ); - - /** - * Returns translated error details for @p errorCode using the - * additional error information provided by @p errorText , @p reqUrl - * (the request URL), and the ioslave @p method . - * - * @param errorCode the error code - * @param errorText the additional error text - * @param reqUrl the request URL - * @param method the ioslave method - * @return the following data: - * @li TQString errorName - the name of the error - * @li TQString techName - if not null, the more technical name of the error - * @li TQString description - a description of the error - * @li TQStringList causes - a list of possible causes of the error - * @li TQStringList solutions - a liso of solutions for the error - */ - TDEIO_EXPORT TQByteArray rawErrorDetail(int errorCode, const TQString &errorText, - const KURL *reqUrl = 0L, int method = -1 ); - - /** - * Returns an appropriate error message if the given command @p cmd - * is an unsupported action (ERR_UNSUPPORTED_ACTION). - * @param protocol name of the protocol - * @param cmd given command - * @see enum Command - * @since 3.2 - */ - TDEIO_EXPORT TQString unsupportedActionErrorString(const TQString &protocol, int cmd); - - /** - * Constants used to specify the type of a KUDSAtom. - */ - enum UDSAtomTypes { - /// First let's define the item types - UDS_STRING = 1, - UDS_LONG = 2, - UDS_TIME = 4 | UDS_LONG, - - // To add new UDS entries below, you can use a step of 8 - // (i.e. 8, 16, 24, 32, etc.) Only the last 3 bits are a bitfield, - // the rest isn't. - - /// Size of the file - UDS_SIZE = 8 | UDS_LONG, - UDS_SIZE_LARGE = 32768 | UDS_LONG, // For internal use only - /// User ID of the file owner - UDS_USER = 16 | UDS_STRING, - /// Name of the icon, that should be used for displaying. - /// It overrides all other detection mechanisms - /// @since 3.2 - UDS_ICON_NAME = 24 | UDS_STRING, - /// Group ID of the file owner - UDS_GROUP = 32 | UDS_STRING, - /// Extra data (used only if you specified Columns/ColumnsTypes) - /// This is the only UDS entry that can be repeated. - /// @since 3.2 - UDS_EXTRA = 48 | UDS_STRING, - /// Filename - as displayed in directory listings etc. - /// "." has the usual special meaning of "current directory" - UDS_NAME = 64 | UDS_STRING, - /// A local file path if the ioslave display files sitting - /// on the local filesystem (but in another hierarchy, e.g. media:/) - UDS_LOCAL_PATH = 72 | UDS_STRING, - /// Treat the file as a hidden file or as a normal file, - /// regardless of (the absence of) a leading dot in the filename. - UDS_HIDDEN = 80 | UDS_LONG, - /// Indicates that the entry has extended ACL entries - /// @since 3.5 - UDS_EXTENDED_ACL = 88 | UDS_LONG, - /// The access control list serialized into a single string. - /// @since 3.5 - UDS_ACL_STRING = 96 | UDS_STRING, - /// The default access control list serialized into a single string. - /// Only available for directories. - /// @since 3.5 - UDS_DEFAULT_ACL_STRING = 104 | UDS_STRING, - - // available: 112, 120 - - /// Access permissions (part of the mode returned by stat) - UDS_ACCESS = 128 | UDS_LONG, - /// The last time the file was modified - UDS_MODIFICATION_TIME = 256 | UDS_TIME, - /// The last time the file was opened - UDS_ACCESS_TIME = 512 | UDS_TIME, - /// The time the file was created - UDS_CREATION_TIME = 1024 | UDS_TIME, - /// File type, part of the mode returned by stat - /// (for a link, this returns the file type of the pointed item) - /// check UDS_LINK_DEST to know if this is a link - UDS_FILE_TYPE = 2048 | UDS_LONG, - /// Name of the file where the link points to - /// Allows to check for a symlink (don't use S_ISLNK !) - UDS_LINK_DEST = 4096 | UDS_STRING, - /// An alternative URL (If different from the caption) - UDS_URL = 8192 | UDS_STRING, - /// A mime type; prevents guessing - UDS_MIME_TYPE = 16384 | UDS_STRING, - /// A mime type to be used for displaying only. - /// But when 'running' the file, the mimetype is re-determined - UDS_GUESSED_MIME_TYPE = 16392 | UDS_STRING, - /// XML properties, e.g. for WebDAV - /// @since 3.1 - UDS_XML_PROPERTIES = 0x8000 | UDS_STRING - }; - - /** - * Specifies how to use the cache. - * @see parseCacheControl() - * @see getCacheControlString() - */ - enum CacheControl - { - CC_CacheOnly, ///< Fail request if not in cache - CC_Cache, ///< Use cached entry if available - CC_Verify, ///< Validate cached entry with remote site if expired - CC_Refresh, ///< Always validate cached entry with remote site - ///< @since 3.1 - CC_Reload ///< Always fetch from remote site. - }; - - /** - * Parses the string representation of the cache control option. - * - * @param cacheControl the string representation - * @return the cache control value - * @see getCacheControlString() - */ - TDEIO_EXPORT TDEIO::CacheControl parseCacheControl(const TQString &cacheControl); - - /** - * Returns a string representation of the given cache control method. - * - * @param cacheControl the cache control method - * @return the string representation - * @see parseCacheControl() - */ - TDEIO_EXPORT TQString getCacheControlString(TDEIO::CacheControl cacheControl); - - /** - * Returns the mount point where @p device is mounted - * right now. This means, it has to be mounted, not just - * defined in fstab. - */ - TDEIO_EXPORT TQString findDeviceMountPoint( const TQString& device ); - - /** - * Returns the mount point on which resides @p filename. - * For instance if /home is a separate partition, findPathMountPoint("/home/user/blah") - * will return /home - * @param filename the file name to check - * @return the mount point of the given @p filename - */ - TDEIO_EXPORT TQString findPathMountPoint( const TQString & filename ); - - /** - * Checks if the path belongs to a filesystem that is probably - * slow. It checks for NFS or for paths belonging to automounted - * paths not yet mounted - * @param filename the file name to check - * @return true if the filesystem is probably slow - */ - TDEIO_EXPORT bool probably_slow_mounted(const TQString& filename); - - /** - * Checks if the path belongs to a filesystem that is manually - * mounted. - * @param filename the file name to check - * @return true if the filesystem is manually mounted - */ - TDEIO_EXPORT bool manually_mounted(const TQString& filename); - - enum FileSystemFlag { SupportsChmod, SupportsChown, SupportsUTime, - SupportsSymlinks, CaseInsensitive }; - /** - * Checks the capabilities of the filesystem to which a given file belongs. - * given feature (e.g. chmod). - * @param filename the file name to check - * @param flag the flag to check - * @return true if the filesystem has that flag, false if not (or some error occurred) - * - * The availables flags are: - * @li SupportsChmod: returns true if the filesystem supports chmod - * (e.g. msdos filesystems return false) - * @li SupportsChown: returns true if the filesystem supports chown - * (e.g. msdos filesystems return false) - * @li SupportsUtime: returns true if the filesystems supports utime - * (e.g. msdos filesystems return false) - * @li SupportsSymlinks: returns true if the filesystems supports symlinks - * (e.g. msdos filesystems return false) - * @li CaseInsensitive: returns true if the filesystem treats - * "foo" and "FOO" as being the same file (true for msdos systems) - * - */ - TDEIO_EXPORT bool testFileSystemFlag(const TQString& filename, FileSystemFlag flag); - - -/************ - * - * Universal Directory Service - * - * Any file or URL can be represented by the UDSEntry type below - * A UDSEntry is a list of atoms - * Each atom contains a specific bit of information for the file - * - * The following UDS constants represent the different possible values - * for m_uds in the UDS atom structure below - * - * Each atom contains a specific bit of information for the file - */ -class TDEIO_EXPORT UDSAtom -{ -public: - /** - * Whether 'm_str' or 'm_long' is used depends on the value of 'm_uds'. - */ - TQString m_str; - /** - * Whether 'm_str' or 'm_long' is used depends on the value of 'm_uds'. - */ - long long m_long; - - /** - * Holds one of the UDS_XXX constants - */ - unsigned int m_uds; -}; - -/** - * An entry is the list of atoms containing all the informations for a file or URL - */ -typedef TQValueList<UDSAtom> UDSEntry; -typedef TQValueList<UDSEntry> UDSEntryList; -typedef TQValueListIterator<UDSEntry> UDSEntryListIterator; -typedef TQValueListConstIterator<UDSEntry> UDSEntryListConstIterator; - -/** - * MetaData is a simple map of key/value strings. - */ -class TDEIO_EXPORT MetaData : public TQMap<TQString, TQString> -{ -public: - /** - * Creates an empty meta data map. - */ - MetaData() : TQMap<TQString, TQString>() { }; - /** - * Copy constructor. - */ - MetaData(const TQMap<TQString, TQString>&metaData) : - TQMap<TQString, TQString>(metaData) { }; - - /** - * Adds the given meta data map to this map. - * @param metaData the map to add - * @return this map - */ - MetaData & operator+= ( const TQMap<TQString,TQString> &metaData ) - { - TQMap<TQString,TQString>::ConstIterator it; - for( it = metaData.begin(); - it != metaData.end(); - ++it) - { - replace(it.key(), it.data()); - } - return *this; - } -}; - -} -#endif diff --git a/kio/kio/http_slave_defaults.h b/kio/kio/http_slave_defaults.h deleted file mode 100644 index e3247e39b..000000000 --- a/kio/kio/http_slave_defaults.h +++ /dev/null @@ -1,49 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2001 Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef _KIO_HTTP_SLAVE_DEFAULTS_H -#define _KIO_HTTP_SLAVE_DEFAULTS_H - -// CONNECTION -#define DEFAULT_KEEP_ALIVE_TIMEOUT 60 // 60 seconds - -// CACHE SETTINGS -#define DEFAULT_MAX_CACHE_SIZE 5120 // 5 MB -#define DEFAULT_MAX_CACHE_AGE 60*60*24*14 // 14 DAYS -#define DEFAULT_CACHE_EXPIRE 3*60 // 3 MINS -#define DEFAULT_CLEAN_CACHE_INTERVAL 30*60 // 30 MINS -#define DEFAULT_CACHE_CONTROL TDEIO::CC_Refresh // Verify with remote -#define CACHE_REVISION "7\n" // Cache version - -// DEFAULT USER AGENT KEY - ENABLES OS NAME -#define DEFAULT_USER_AGENT_KEYS "o" // Show OS - -// MAXIMUM AMOUNT OF DATA THAT CAN BE SAFELY SENT OVER IPC -#define MAX_IPC_SIZE 1024*8 - -// AMOUNT OF DATA TO OBTAIN FROM THE SERVER BY DEFAULT -#define DEFAULT_BUF_SIZE 1024*4 - -// SOME DEFAULT HEADER VALUES -#define DEFAULT_LANGUAGE_HEADER "en" -#define DEFAULT_MIME_TYPE "text/html" -#define DEFAULT_PARTIAL_CHARSET_HEADER ", utf-8;q=0.5, *;q=0.5" - -#define DEFAULT_ACCEPT_HEADER "text/html, image/jpeg, image/png, text/*, image/*, */*" - -#endif diff --git a/kio/kio/ioslave_defaults.h b/kio/kio/ioslave_defaults.h deleted file mode 100644 index ddf5b6af5..000000000 --- a/kio/kio/ioslave_defaults.h +++ /dev/null @@ -1,53 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2001 Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef _KIO_IOSLAVE_DEFAULTS_H -#define _KIO_IOSLAVE_DEFAULTS_H - -// TIMEOUT VALUES -#define DEFAULT_RESPONSE_TIMEOUT 600 // 10 min. -#define DEFAULT_CONNECT_TIMEOUT 20 // 20 secs. -#define DEFAULT_READ_TIMEOUT 15 // 15 secs. -#define DEFAULT_PROXY_CONNECT_TIMEOUT 10 // 10 secs. -#define MIN_TIMEOUT_VALUE 2 // 2 secs. - -// MINMUM SIZE FOR ABORTED DOWNLOAD TO BE KEPT -#define DEFAULT_MINIMUM_KEEP_SIZE 5120 // 5 Kbs - -// NORMAL PORT DEFAULTS -#define DEFAULT_FTP_PORT 21 -#define DEFAULT_SMTP_PORT 25 -#define DEFAULT_HTTP_PORT 80 -#define DEFAULT_POP3_PORT 110 -#define DEFAULT_NNTP_PORT 119 -#define DEFAULT_IMAP_PORT 143 -#define DEFAULT_IMAP3_PORT 220 -#define DEFAULT_LDAP_PORT 389 - -// SECURE PORT DEFAULTS -#define DEFAULT_HTTPS_PORT 443 -#define DEFAULT_NNTPS_PORT 563 -#define DEFAULT_LDAPS_PORT 389 -#define DEFAULT_IMAPS_PORT 993 -#define DEFAULT_POP3S_PORT 995 - -// OTHER GENERIC PORT DEFAULTS -#define DEFAULT_PROXY_PORT 8080 -#define MAX_PORT_VALUE 65535 - -#endif diff --git a/kio/kio/job.cpp b/kio/kio/job.cpp deleted file mode 100644 index d72eae574..000000000 --- a/kio/kio/job.cpp +++ /dev/null @@ -1,4814 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Stephan Kulow <coolo@kde.org> - David Faure <faure@kde.org> - Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kio/job.h" - -#include <config.h> - -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/stat.h> - -#include <assert.h> - -#include <signal.h> -#include <stdlib.h> -#include <stdio.h> -#include <time.h> -#include <unistd.h> -extern "C" { -#include <pwd.h> -#include <grp.h> -} -#include <tqtimer.h> -#include <tqfile.h> - -#include <kapplication.h> -#include <kglobal.h> -#include <klocale.h> -#include <ksimpleconfig.h> -#include <kdebug.h> -#include <kdialog.h> -#include <kmessagebox.h> -#include <kdatastream.h> -#include <kmainwindow.h> -#include <kde_file.h> - -#include <errno.h> - -#include "kmimetype.h" -#include "slave.h" -#include "scheduler.h" -#include "kdirwatch.h" -#include "kmimemagic.h" -#include "kprotocolinfo.h" -#include "kprotocolmanager.h" - -#include "kio/observer.h" - -#include "kssl/ksslcsessioncache.h" - -#include <kdirnotify_stub.h> -#include <ktempfile.h> -#include <dcopclient.h> - -#ifdef Q_OS_UNIX -#include <utime.h> -#endif -#if defined Q_WS_X11 -#include <netwm.h> -#include <fixx11h.h> -#endif - -using namespace TDEIO; -template class TQPtrList<TDEIO::Job>; - -//this will update the report dialog with 5 Hz, I think this is fast enough, aleXXX -#define REPORT_TIMEOUT 200 - -#define KIO_ARGS TQByteArray packedArgs; TQDataStream stream( packedArgs, IO_WriteOnly ); stream - -class Job::JobPrivate -{ -public: - JobPrivate() : m_autoErrorHandling( false ), m_autoWarningHandling( true ), - m_interactive( true ), m_parentJob( 0L ), m_extraFlags(0), - m_processedSize(0), m_userTimestamp(0) - {} - - bool m_autoErrorHandling; - bool m_autoWarningHandling; - bool m_interactive; - TQGuardedPtr<TQWidget> m_errorParentWidget; - // Maybe we could use the TQObject parent/child mechanism instead - // (requires a new ctor, and moving the ctor code to some init()). - Job* m_parentJob; - int m_extraFlags; - TDEIO::filesize_t m_processedSize; - unsigned long m_userTimestamp; -}; - -Job::Job(bool showProgressInfo) : TQObject(0, "job"), m_error(0), m_percent(0) - , m_progressId(0), m_speedTimer(0), d( new JobPrivate ) -{ - // All jobs delete themselves after emiting 'result'. - - // Notify the UI Server and get a progress id - if ( showProgressInfo ) - { - m_progressId = Observer::self()->newJob( this, true ); - addMetaData("progress-id", TQString::number(m_progressId)); - //kdDebug(7007) << "Created job " << this << " with progress info -- m_progressId=" << m_progressId << endl; - // Connect global progress info signals - connect( this, TQT_SIGNAL( percent( TDEIO::Job*, unsigned long ) ), - Observer::self(), TQT_SLOT( slotPercent( TDEIO::Job*, unsigned long ) ) ); - connect( this, TQT_SIGNAL( infoMessage( TDEIO::Job*, const TQString & ) ), - Observer::self(), TQT_SLOT( slotInfoMessage( TDEIO::Job*, const TQString & ) ) ); - connect( this, TQT_SIGNAL( totalSize( TDEIO::Job*, TDEIO::filesize_t ) ), - Observer::self(), TQT_SLOT( slotTotalSize( TDEIO::Job*, TDEIO::filesize_t ) ) ); - connect( this, TQT_SIGNAL( processedSize( TDEIO::Job*, TDEIO::filesize_t ) ), - Observer::self(), TQT_SLOT( slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t ) ) ); - connect( this, TQT_SIGNAL( speed( TDEIO::Job*, unsigned long ) ), - Observer::self(), TQT_SLOT( slotSpeed( TDEIO::Job*, unsigned long ) ) ); - } - // Don't exit while this job is running - if (kapp) - kapp->ref(); - if (kapp) - updateUserTimestamp( kapp->userTimestamp()); -} - -Job::~Job() -{ - delete m_speedTimer; - delete d; - if (kapp) - kapp->deref(); -} - -int& Job::extraFlags() -{ - return d->m_extraFlags; -} - -void Job::setProcessedSize(TDEIO::filesize_t size) -{ - d->m_processedSize = size; -} - -TDEIO::filesize_t Job::getProcessedSize() -{ - return d->m_processedSize; -} - -void Job::addSubjob(Job *job, bool inheritMetaData) -{ - //kdDebug(7007) << "addSubjob(" << job << ") this = " << this << endl; - subjobs.append(job); - - connect( job, TQT_SIGNAL(result(TDEIO::Job*)), - TQT_SLOT(slotResult(TDEIO::Job*)) ); - - // Forward information from that subjob. - connect( job, TQT_SIGNAL(speed( TDEIO::Job*, unsigned long )), - TQT_SLOT(slotSpeed(TDEIO::Job*, unsigned long)) ); - - connect( job, TQT_SIGNAL(infoMessage( TDEIO::Job*, const TQString & )), - TQT_SLOT(slotInfoMessage(TDEIO::Job*, const TQString &)) ); - - if (inheritMetaData) - job->mergeMetaData(m_outgoingMetaData); - - job->setWindow( m_window ); - job->updateUserTimestamp( d->m_userTimestamp ); -} - -void Job::removeSubjob( Job *job ) -{ - removeSubjob( job, false, true ); -} - -void Job::removeSubjob( Job *job, bool mergeMetaData, bool emitResultIfLast ) -{ - //kdDebug(7007) << "removeSubjob(" << job << ") this = " << this << " subjobs = " << subjobs.count() << endl; - // Merge metadata from subjob - if ( mergeMetaData ) - m_incomingMetaData += job->metaData(); - subjobs.remove(job); - if ( subjobs.isEmpty() && emitResultIfLast ) - emitResult(); -} - -void Job::emitPercent( TDEIO::filesize_t processedSize, TDEIO::filesize_t totalSize ) -{ - // calculate percents - unsigned long ipercent = m_percent; - - if ( totalSize == 0 ) - m_percent = 100; - else - m_percent = (unsigned long)(( (float)(processedSize) / (float)(totalSize) ) * 100.0); - - if ( m_percent != ipercent || m_percent == 100 /* for those buggy total sizes that grow */ ) { - emit percent( this, m_percent ); - //kdDebug(7007) << "Job::emitPercent - percent = " << (unsigned int) m_percent << endl; - } -} - -void Job::emitSpeed( unsigned long bytes_per_second ) -{ - //kdDebug(7007) << "Job " << this << " emitSpeed " << bytes_per_second << endl; - if ( !m_speedTimer ) - { - m_speedTimer = new TQTimer(); - connect( m_speedTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotSpeedTimeout() ) ); - } - emit speed( this, bytes_per_second ); - m_speedTimer->start( 5000 ); // 5 seconds interval should be enough -} - -void Job::emitResult() -{ - // If we are displaying a progress dialog, remove it first. - if ( m_progressId ) // Did we get an ID from the observer ? - Observer::self()->jobFinished( m_progressId ); - if ( m_error && d->m_interactive && d->m_autoErrorHandling ) - showErrorDialog( d->m_errorParentWidget ); - emit result(this); - deleteLater(); -} - -void Job::kill( bool quietly ) -{ - kdDebug(7007) << "Job::kill this=" << this << " " << className() << " m_progressId=" << m_progressId << " quietly=" << quietly << endl; - // kill all subjobs, without triggering their result slot - TQPtrListIterator<Job> it( subjobs ); - for ( ; it.current() ; ++it ) - (*it)->kill( true ); - subjobs.clear(); - - if ( ! quietly ) { - m_error = ERR_USER_CANCELED; - emit canceled( this ); // Not very useful (deprecated) - emitResult(); - } else - { - if ( m_progressId ) // in both cases we want to hide the progress window - Observer::self()->jobFinished( m_progressId ); - deleteLater(); - } -} - -void Job::slotResult( Job *job ) -{ - // Did job have an error ? - if ( job->error() && !m_error ) - { - // Store it in the parent only if first error - m_error = job->error(); - m_errorText = job->errorText(); - } - removeSubjob(job); -} - -void Job::slotSpeed( TDEIO::Job*, unsigned long speed ) -{ - //kdDebug(7007) << "Job::slotSpeed " << speed << endl; - emitSpeed( speed ); -} - -void Job::slotInfoMessage( TDEIO::Job*, const TQString & msg ) -{ - emit infoMessage( this, msg ); -} - -void Job::slotSpeedTimeout() -{ - //kdDebug(7007) << "slotSpeedTimeout()" << endl; - // send 0 and stop the timer - // timer will be restarted only when we receive another speed event - emit speed( this, 0 ); - m_speedTimer->stop(); -} - -//Job::errorString is implemented in global.cpp - -void Job::showErrorDialog( TQWidget * parent ) -{ - //kdDebug(7007) << "Job::showErrorDialog parent=" << parent << endl; - kapp->enableStyles(); - // Show a message box, except for "user canceled" or "no content" - if ( (m_error != ERR_USER_CANCELED) && (m_error != ERR_NO_CONTENT) ) { - //old plain error message - //kdDebug(7007) << "Default language: " << TDEGlobal::locale()->defaultLanguage() << endl; - if ( 1 ) - KMessageBox::queuedMessageBox( parent, KMessageBox::Error, errorString() ); -#if 0 - } else { - TQStringList errors = detailedErrorStrings(); - TQString caption, err, detail; - TQStringList::const_iterator it = errors.begin(); - if ( it != errors.end() ) - caption = *(it++); - if ( it != errors.end() ) - err = *(it++); - if ( it != errors.end() ) - detail = *it; - KMessageBox::queuedDetailedError( parent, err, detail, caption ); - } -#endif - } -} - -void Job::setAutoErrorHandlingEnabled( bool enable, TQWidget *parentWidget ) -{ - d->m_autoErrorHandling = enable; - d->m_errorParentWidget = parentWidget; -} - -bool Job::isAutoErrorHandlingEnabled() const -{ - return d->m_autoErrorHandling; -} - -void Job::setAutoWarningHandlingEnabled( bool enable ) -{ - d->m_autoWarningHandling = enable; -} - -bool Job::isAutoWarningHandlingEnabled() const -{ - return d->m_autoWarningHandling; -} - -void Job::setInteractive(bool enable) -{ - d->m_interactive = enable; -} - -bool Job::isInteractive() const -{ - return d->m_interactive; -} - -void Job::setWindow(TQWidget *window) -{ - m_window = window; - TDEIO::Scheduler::registerWindow(window); -} - -TQWidget *Job::window() const -{ - return m_window; -} - -void Job::updateUserTimestamp( unsigned long time ) -{ -#if defined Q_WS_X11 - if( d->m_userTimestamp == 0 || NET::timestampCompare( time, d->m_userTimestamp ) > 0 ) - d->m_userTimestamp = time; -#endif -} - -unsigned long Job::userTimestamp() const -{ - return d->m_userTimestamp; -} - -void Job::setParentJob(Job* job) -{ - Q_ASSERT(d->m_parentJob == 0L); - Q_ASSERT(job); - d->m_parentJob = job; -} - -Job* Job::parentJob() const -{ - return d->m_parentJob; -} - -MetaData Job::metaData() const -{ - return m_incomingMetaData; -} - -TQString Job::queryMetaData(const TQString &key) -{ - if (!m_incomingMetaData.contains(key)) - return TQString::null; - return m_incomingMetaData[key]; -} - -void Job::setMetaData( const TDEIO::MetaData &_metaData) -{ - m_outgoingMetaData = _metaData; -} - -void Job::addMetaData( const TQString &key, const TQString &value) -{ - m_outgoingMetaData.insert(key, value); -} - -void Job::addMetaData( const TQMap<TQString,TQString> &values) -{ - TQMapConstIterator<TQString,TQString> it = values.begin(); - for(;it != values.end(); ++it) - m_outgoingMetaData.insert(it.key(), it.data()); -} - -void Job::mergeMetaData( const TQMap<TQString,TQString> &values) -{ - TQMapConstIterator<TQString,TQString> it = values.begin(); - for(;it != values.end(); ++it) - m_outgoingMetaData.insert(it.key(), it.data(), false); -} - -MetaData Job::outgoingMetaData() const -{ - return m_outgoingMetaData; -} - - -SimpleJob::SimpleJob(const KURL& url, int command, const TQByteArray &packedArgs, - bool showProgressInfo ) - : Job(showProgressInfo), m_slave(0), m_packedArgs(packedArgs), - m_url(url), m_command(command), m_totalSize(0) -{ - if (m_url.hasSubURL()) - { - KURL::List list = KURL::split(m_url); - KURL::List::Iterator it = list.fromLast(); - list.remove(it); - m_subUrl = KURL::join(list); - //kdDebug(7007) << "New URL = " << m_url.url() << endl; - //kdDebug(7007) << "Sub URL = " << m_subUrl.url() << endl; - } - - Scheduler::doJob(this); - - if (!m_url.isValid()) - { - kdDebug() << "ERR_MALFORMED_URL" << endl; - m_error = ERR_MALFORMED_URL; - m_errorText = m_url.url(); - TQTimer::singleShot(0, this, TQT_SLOT(slotFinished()) ); - return; - } -} - -void SimpleJob::kill( bool quietly ) -{ - Scheduler::cancelJob( this ); // deletes the slave if not 0 - m_slave = 0; // -> set to 0 - Job::kill( quietly ); -} - -void SimpleJob::putOnHold() -{ - Q_ASSERT( m_slave ); - if ( m_slave ) - { - Scheduler::putSlaveOnHold(this, m_url); - m_slave = 0; - } - kill(true); -} - -void SimpleJob::removeOnHold() -{ - Scheduler::removeSlaveOnHold(); -} - -SimpleJob::~SimpleJob() -{ - if (m_slave) // was running - { - kdDebug(7007) << "SimpleJob::~SimpleJob: Killing running job in destructor!" << endl; -#if 0 - m_slave->kill(); - Scheduler::jobFinished( this, m_slave ); // deletes the slave -#endif - Scheduler::cancelJob( this ); - m_slave = 0; // -> set to 0 - } -} - -void SimpleJob::start(Slave *slave) -{ - m_slave = slave; - - connect( m_slave, TQT_SIGNAL( error( int , const TQString & ) ), - TQT_SLOT( slotError( int , const TQString & ) ) ); - - connect( m_slave, TQT_SIGNAL( warning( const TQString & ) ), - TQT_SLOT( slotWarning( const TQString & ) ) ); - - connect( m_slave, TQT_SIGNAL( infoMessage( const TQString & ) ), - TQT_SLOT( slotInfoMessage( const TQString & ) ) ); - - connect( m_slave, TQT_SIGNAL( connected() ), - TQT_SLOT( slotConnected() ) ); - - connect( m_slave, TQT_SIGNAL( finished() ), - TQT_SLOT( slotFinished() ) ); - - if ((extraFlags() & EF_TransferJobDataSent) == 0) - { - connect( m_slave, TQT_SIGNAL( totalSize( TDEIO::filesize_t ) ), - TQT_SLOT( slotTotalSize( TDEIO::filesize_t ) ) ); - - connect( m_slave, TQT_SIGNAL( processedSize( TDEIO::filesize_t ) ), - TQT_SLOT( slotProcessedSize( TDEIO::filesize_t ) ) ); - - connect( m_slave, TQT_SIGNAL( speed( unsigned long ) ), - TQT_SLOT( slotSpeed( unsigned long ) ) ); - } - - connect( slave, TQT_SIGNAL( needProgressId() ), - TQT_SLOT( slotNeedProgressId() ) ); - - connect( slave, TQT_SIGNAL(metaData( const TDEIO::MetaData& ) ), - TQT_SLOT( slotMetaData( const TDEIO::MetaData& ) ) ); - - if (m_window) - { - TQString id; - addMetaData("window-id", id.setNum((ulong)m_window->winId())); - } - if (userTimestamp()) - { - TQString id; - addMetaData("user-timestamp", id.setNum(userTimestamp())); - } - - TQString sslSession = KSSLCSessionCache::getSessionForURL(m_url); - if ( !sslSession.isNull() ) - { - addMetaData("ssl_session_id", sslSession); - } - - if (!isInteractive()) - { - addMetaData("no-auth-prompt", "true"); - } - - if (!m_outgoingMetaData.isEmpty()) - { - KIO_ARGS << m_outgoingMetaData; - slave->send( CMD_META_DATA, packedArgs ); - } - - if (!m_subUrl.isEmpty()) - { - KIO_ARGS << m_subUrl; - m_slave->send( CMD_SUBURL, packedArgs ); - } - - m_slave->send( m_command, m_packedArgs ); -} - -void SimpleJob::slaveDone() -{ - if (!m_slave) return; - disconnect(m_slave); // Remove all signals between slave and job - Scheduler::jobFinished( this, m_slave ); - m_slave = 0; -} - -void SimpleJob::slotFinished( ) -{ - // Return slave to the scheduler - slaveDone(); - - if (subjobs.isEmpty()) - { - if ( !m_error && (m_command == CMD_MKDIR || m_command == CMD_RENAME ) ) - { - KDirNotify_stub allDirNotify( "*", "KDirNotify*" ); - if ( m_command == CMD_MKDIR ) - { - KURL urlDir( url() ); - urlDir.setPath( urlDir.directory() ); - allDirNotify.FilesAdded( urlDir ); - } - else /*if ( m_command == CMD_RENAME )*/ - { - KURL src, dst; - TQDataStream str( m_packedArgs, IO_ReadOnly ); - str >> src >> dst; - if ( src.directory() == dst.directory() ) // For the user, moving isn't renaming. Only renaming is. - allDirNotify.FileRenamed( src, dst ); - } - } - emitResult(); - } -} - -void SimpleJob::slotError( int error, const TQString & errorText ) -{ - m_error = error; - m_errorText = errorText; - if ((m_error == ERR_UNKNOWN_HOST) && m_url.host().isEmpty()) - m_errorText = TQString::null; - // error terminates the job - slotFinished(); -} - -void SimpleJob::slotWarning( const TQString & errorText ) -{ - TQGuardedPtr<SimpleJob> guard( this ); - if (isInteractive() && isAutoWarningHandlingEnabled()) - { - static uint msgBoxDisplayed = 0; - if ( msgBoxDisplayed == 0 ) // don't bomb the user with message boxes, only one at a time - { - msgBoxDisplayed++; - KMessageBox::information( 0L, errorText ); - msgBoxDisplayed--; - } - // otherwise just discard it. - } - - if ( !guard.isNull() ) - emit warning( this, errorText ); -} - -void SimpleJob::slotInfoMessage( const TQString & msg ) -{ - emit infoMessage( this, msg ); -} - -void SimpleJob::slotConnected() -{ - emit connected( this ); -} - -void SimpleJob::slotNeedProgressId() -{ - if ( !m_progressId ) - m_progressId = Observer::self()->newJob( this, false ); - m_slave->setProgressId( m_progressId ); -} - -void SimpleJob::slotTotalSize( TDEIO::filesize_t size ) -{ - if (size > m_totalSize) - { - m_totalSize = size; - emit totalSize( this, size ); - } -} - -void SimpleJob::slotProcessedSize( TDEIO::filesize_t size ) -{ - //kdDebug(7007) << "SimpleJob::slotProcessedSize " << TDEIO::number(size) << endl; - setProcessedSize(size); - emit processedSize( this, size ); - if ( size > m_totalSize ) { - slotTotalSize(size); // safety - } - emitPercent( size, m_totalSize ); -} - -void SimpleJob::slotSpeed( unsigned long speed ) -{ - //kdDebug(7007) << "SimpleJob::slotSpeed( " << speed << " )" << endl; - emitSpeed( speed ); -} - -void SimpleJob::slotMetaData( const TDEIO::MetaData &_metaData) -{ - m_incomingMetaData += _metaData; -} - -void SimpleJob::storeSSLSessionFromJob(const KURL &m_redirectionURL) { - TQString sslSession = queryMetaData("ssl_session_id"); - - if ( !sslSession.isNull() ) { - const KURL &queryURL = m_redirectionURL.isEmpty()?m_url:m_redirectionURL; - KSSLCSessionCache::putSessionForURL(queryURL, sslSession); - } -} - -////////// -MkdirJob::MkdirJob( const KURL& url, int command, - const TQByteArray &packedArgs, bool showProgressInfo ) - : SimpleJob(url, command, packedArgs, showProgressInfo) -{ -} - -void MkdirJob::start(Slave *slave) -{ - connect( slave, TQT_SIGNAL( redirection(const KURL &) ), - TQT_SLOT( slotRedirection(const KURL &) ) ); - - SimpleJob::start(slave); -} - -// Slave got a redirection request -void MkdirJob::slotRedirection( const KURL &url) -{ - kdDebug(7007) << "MkdirJob::slotRedirection(" << url << ")" << endl; - if (!kapp->authorizeURLAction("redirect", m_url, url)) - { - kdWarning(7007) << "MkdirJob: Redirection from " << m_url << " to " << url << " REJECTED!" << endl; - m_error = ERR_ACCESS_DENIED; - m_errorText = url.prettyURL(); - return; - } - m_redirectionURL = url; // We'll remember that when the job finishes - if (m_url.hasUser() && !url.hasUser() && (m_url.host().lower() == url.host().lower())) - m_redirectionURL.setUser(m_url.user()); // Preserve user - // Tell the user that we haven't finished yet - emit redirection(this, m_redirectionURL); -} - -void MkdirJob::slotFinished() -{ - if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid()) - { - // Return slave to the scheduler - SimpleJob::slotFinished(); - } else { - //kdDebug(7007) << "MkdirJob: Redirection to " << m_redirectionURL << endl; - if (queryMetaData("permanent-redirect")=="true") - emit permanentRedirection(this, m_url, m_redirectionURL); - KURL dummyUrl; - int permissions; - TQDataStream istream( m_packedArgs, IO_ReadOnly ); - istream >> dummyUrl >> permissions; - - m_url = m_redirectionURL; - m_redirectionURL = KURL(); - m_packedArgs.truncate(0); - TQDataStream stream( m_packedArgs, IO_WriteOnly ); - stream << m_url << permissions; - - // Return slave to the scheduler - slaveDone(); - Scheduler::doJob(this); - } -} - -SimpleJob *TDEIO::mkdir( const KURL& url, int permissions ) -{ - //kdDebug(7007) << "mkdir " << url << endl; - KIO_ARGS << url << permissions; - return new MkdirJob(url, CMD_MKDIR, packedArgs, false); -} - -SimpleJob *TDEIO::rmdir( const KURL& url ) -{ - //kdDebug(7007) << "rmdir " << url << endl; - KIO_ARGS << url << TQ_INT8(false); // isFile is false - return new SimpleJob(url, CMD_DEL, packedArgs, false); -} - -SimpleJob *TDEIO::chmod( const KURL& url, int permissions ) -{ - //kdDebug(7007) << "chmod " << url << endl; - KIO_ARGS << url << permissions; - return new SimpleJob(url, CMD_CHMOD, packedArgs, false); -} - -SimpleJob *TDEIO::rename( const KURL& src, const KURL & dest, bool overwrite ) -{ - //kdDebug(7007) << "rename " << src << " " << dest << endl; - KIO_ARGS << src << dest << (TQ_INT8) overwrite; - return new SimpleJob(src, CMD_RENAME, packedArgs, false); -} - -SimpleJob *TDEIO::symlink( const TQString& target, const KURL & dest, bool overwrite, bool showProgressInfo ) -{ - //kdDebug(7007) << "symlink target=" << target << " " << dest << endl; - KIO_ARGS << target << dest << (TQ_INT8) overwrite; - return new SimpleJob(dest, CMD_SYMLINK, packedArgs, showProgressInfo); -} - -SimpleJob *TDEIO::special(const KURL& url, const TQByteArray & data, bool showProgressInfo) -{ - //kdDebug(7007) << "special " << url << endl; - return new SimpleJob(url, CMD_SPECIAL, data, showProgressInfo); -} - -SimpleJob *TDEIO::mount( bool ro, const char *fstype, const TQString& dev, const TQString& point, bool showProgressInfo ) -{ - KIO_ARGS << int(1) << TQ_INT8( ro ? 1 : 0 ) - << TQString::fromLatin1(fstype) << dev << point; - SimpleJob *job = special( KURL("file:/"), packedArgs, showProgressInfo ); - if ( showProgressInfo ) - Observer::self()->mounting( job, dev, point ); - return job; -} - -SimpleJob *TDEIO::unmount( const TQString& point, bool showProgressInfo ) -{ - KIO_ARGS << int(2) << point; - SimpleJob *job = special( KURL("file:/"), packedArgs, showProgressInfo ); - if ( showProgressInfo ) - Observer::self()->unmounting( job, point ); - return job; -} - -////////// -LocalURLJob::LocalURLJob( const KURL& url, int command, - const TQByteArray &packedArgs, bool showProgressInfo ) - : SimpleJob(url, command, packedArgs, showProgressInfo) -{ - -} - -void LocalURLJob::start(Slave *slave) -{ - connect( slave, TQT_SIGNAL( localURL(const KURL &, bool) ), - TQT_SLOT( slotLocalURL(const KURL &, bool) ) ); - - SimpleJob::start(slave); -} - -// Slave sent a response! -void LocalURLJob::slotLocalURL(const KURL &url, bool isLocal) -{ - kdDebug(7007) << "LocalURLJob::slotLocalURL(" << url << ")" << endl; - emit localURL(this, url, isLocal); -} - -void LocalURLJob::slotFinished() -{ - // Return slave to the scheduler - SimpleJob::slotFinished(); -} - -LocalURLJob *TDEIO::localURL( const KURL& remoteUrl ) -{ - KIO_ARGS << remoteUrl; - return new LocalURLJob(remoteUrl, CMD_LOCALURL, packedArgs, false); -} - - -////////// - -StatJob::StatJob( const KURL& url, int command, - const TQByteArray &packedArgs, bool showProgressInfo ) - : SimpleJob(url, command, packedArgs, showProgressInfo), - m_bSource(true), m_details(2) -{ -} - -void StatJob::start(Slave *slave) -{ - m_outgoingMetaData.replace( "statSide", m_bSource ? "source" : "dest" ); - m_outgoingMetaData.replace( "details", TQString::number(m_details) ); - - connect( slave, TQT_SIGNAL( statEntry( const TDEIO::UDSEntry& ) ), - TQT_SLOT( slotStatEntry( const TDEIO::UDSEntry & ) ) ); - connect( slave, TQT_SIGNAL( redirection(const KURL &) ), - TQT_SLOT( slotRedirection(const KURL &) ) ); - - SimpleJob::start(slave); -} - -void StatJob::slotStatEntry( const TDEIO::UDSEntry & entry ) -{ - //kdDebug(7007) << "StatJob::slotStatEntry" << endl; - m_statResult = entry; -} - -// Slave got a redirection request -void StatJob::slotRedirection( const KURL &url) -{ - kdDebug(7007) << "StatJob::slotRedirection(" << url << ")" << endl; - if (!kapp->authorizeURLAction("redirect", m_url, url)) - { - kdWarning(7007) << "StatJob: Redirection from " << m_url << " to " << url << " REJECTED!" << endl; - m_error = ERR_ACCESS_DENIED; - m_errorText = url.prettyURL(); - return; - } - m_redirectionURL = url; // We'll remember that when the job finishes - if (m_url.hasUser() && !url.hasUser() && (m_url.host().lower() == url.host().lower())) - m_redirectionURL.setUser(m_url.user()); // Preserve user - // Tell the user that we haven't finished yet - emit redirection(this, m_redirectionURL); -} - -void StatJob::slotFinished() -{ - if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid()) - { - // Return slave to the scheduler - SimpleJob::slotFinished(); - } else { - //kdDebug(7007) << "StatJob: Redirection to " << m_redirectionURL << endl; - if (queryMetaData("permanent-redirect")=="true") - emit permanentRedirection(this, m_url, m_redirectionURL); - m_url = m_redirectionURL; - m_redirectionURL = KURL(); - m_packedArgs.truncate(0); - TQDataStream stream( m_packedArgs, IO_WriteOnly ); - stream << m_url; - - // Return slave to the scheduler - slaveDone(); - Scheduler::doJob(this); - } -} - -void StatJob::slotMetaData( const TDEIO::MetaData &_metaData) { - SimpleJob::slotMetaData(_metaData); - storeSSLSessionFromJob(m_redirectionURL); -} - -StatJob *TDEIO::stat(const KURL& url, bool showProgressInfo) -{ - // Assume sideIsSource. Gets are more common than puts. - return stat( url, true, 2, showProgressInfo ); -} - -StatJob *TDEIO::stat(const KURL& url, bool sideIsSource, short int details, bool showProgressInfo) -{ - kdDebug(7007) << "stat " << url << endl; - KIO_ARGS << url; - StatJob * job = new StatJob(url, CMD_STAT, packedArgs, showProgressInfo ); - job->setSide( sideIsSource ); - job->setDetails( details ); - if ( showProgressInfo ) - Observer::self()->stating( job, url ); - return job; -} - -SimpleJob *TDEIO::http_update_cache( const KURL& url, bool no_cache, time_t expireDate) -{ - assert( (url.protocol() == "http") || (url.protocol() == "https") ); - // Send http update_cache command (2) - KIO_ARGS << (int)2 << url << no_cache << expireDate; - SimpleJob * job = new SimpleJob( url, CMD_SPECIAL, packedArgs, false ); - Scheduler::scheduleJob(job); - return job; -} - -////////// - -TransferJob::TransferJob( const KURL& url, int command, - const TQByteArray &packedArgs, - const TQByteArray &_staticData, - bool showProgressInfo) - : SimpleJob(url, command, packedArgs, showProgressInfo), staticData( _staticData) -{ - m_suspended = false; - m_errorPage = false; - m_subJob = 0L; - if ( showProgressInfo ) - Observer::self()->slotTransferring( this, url ); -} - -// Slave sends data -void TransferJob::slotData( const TQByteArray &_data) -{ - if(m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error) - emit data( this, _data); -} - -// Slave got a redirection request -void TransferJob::slotRedirection( const KURL &url) -{ - kdDebug(7007) << "TransferJob::slotRedirection(" << url << ")" << endl; - if (!kapp->authorizeURLAction("redirect", m_url, url)) - { - kdWarning(7007) << "TransferJob: Redirection from " << m_url << " to " << url << " REJECTED!" << endl; - return; - } - - // Some websites keep redirecting to themselves where each redirection - // acts as the stage in a state-machine. We define "endless redirections" - // as 5 redirections to the same URL. - if (m_redirectionList.contains(url) > 5) - { - kdDebug(7007) << "TransferJob::slotRedirection: CYCLIC REDIRECTION!" << endl; - m_error = ERR_CYCLIC_LINK; - m_errorText = m_url.prettyURL(); - } - else - { - m_redirectionURL = url; // We'll remember that when the job finishes - if (m_url.hasUser() && !url.hasUser() && (m_url.host().lower() == url.host().lower())) - m_redirectionURL.setUser(m_url.user()); // Preserve user - m_redirectionList.append(url); - m_outgoingMetaData["ssl_was_in_use"] = m_incomingMetaData["ssl_in_use"]; - // Tell the user that we haven't finished yet - emit redirection(this, m_redirectionURL); - } -} - -void TransferJob::slotFinished() -{ - //kdDebug(7007) << "TransferJob::slotFinished(" << this << ", " << m_url << ")" << endl; - if (m_redirectionURL.isEmpty() || !m_redirectionURL.isValid()) - SimpleJob::slotFinished(); - else { - //kdDebug(7007) << "TransferJob: Redirection to " << m_redirectionURL << endl; - if (queryMetaData("permanent-redirect")=="true") - emit permanentRedirection(this, m_url, m_redirectionURL); - // Honour the redirection - // We take the approach of "redirecting this same job" - // Another solution would be to create a subjob, but the same problem - // happens (unpacking+repacking) - staticData.truncate(0); - m_incomingMetaData.clear(); - if (queryMetaData("cache") != "reload") - addMetaData("cache","refresh"); - m_suspended = false; - m_url = m_redirectionURL; - m_redirectionURL = KURL(); - // The very tricky part is the packed arguments business - TQString dummyStr; - KURL dummyUrl; - TQDataStream istream( m_packedArgs, IO_ReadOnly ); - switch( m_command ) { - case CMD_GET: { - m_packedArgs.truncate(0); - TQDataStream stream( m_packedArgs, IO_WriteOnly ); - stream << m_url; - break; - } - case CMD_PUT: { - int permissions; - TQ_INT8 iOverwrite, iResume; - istream >> dummyUrl >> iOverwrite >> iResume >> permissions; - m_packedArgs.truncate(0); - TQDataStream stream( m_packedArgs, IO_WriteOnly ); - stream << m_url << iOverwrite << iResume << permissions; - break; - } - case CMD_SPECIAL: { - int specialcmd; - istream >> specialcmd; - if (specialcmd == 1) // HTTP POST - { - addMetaData("cache","reload"); - m_packedArgs.truncate(0); - TQDataStream stream( m_packedArgs, IO_WriteOnly ); - stream << m_url; - m_command = CMD_GET; - } - break; - } - } - - // Return slave to the scheduler - slaveDone(); - Scheduler::doJob(this); - } -} - -void TransferJob::setAsyncDataEnabled(bool enabled) -{ - if (enabled) - extraFlags() |= EF_TransferJobAsync; - else - extraFlags() &= ~EF_TransferJobAsync; -} - -void TransferJob::sendAsyncData(const TQByteArray &dataForSlave) -{ - if (extraFlags() & EF_TransferJobNeedData) - { - m_slave->send( MSG_DATA, dataForSlave ); - if (extraFlags() & EF_TransferJobDataSent) - { - TDEIO::filesize_t size = getProcessedSize()+dataForSlave.size(); - setProcessedSize(size); - emit processedSize( this, size ); - if ( size > m_totalSize ) { - slotTotalSize(size); // safety - } - emitPercent( size, m_totalSize ); - } - } - - extraFlags() &= ~EF_TransferJobNeedData; -} - -void TransferJob::setReportDataSent(bool enabled) -{ - if (enabled) - extraFlags() |= EF_TransferJobDataSent; - else - extraFlags() &= ~EF_TransferJobDataSent; -} - -bool TransferJob::reportDataSent() -{ - return (extraFlags() & EF_TransferJobDataSent); -} - - -// Slave requests data -void TransferJob::slotDataReq() -{ - TQByteArray dataForSlave; - - extraFlags() |= EF_TransferJobNeedData; - - if (!staticData.isEmpty()) - { - dataForSlave = staticData; - staticData = TQByteArray(); - } - else - { - emit dataReq( this, dataForSlave); - - if (extraFlags() & EF_TransferJobAsync) - return; - } - - static const size_t max_size = 14 * 1024 * 1024; - if (dataForSlave.size() > max_size) - { - kdDebug(7007) << "send " << dataForSlave.size() / 1024 / 1024 << "MB of data in TransferJob::dataReq. This needs to be splitted, which requires a copy. Fix the application.\n"; - staticData.duplicate(dataForSlave.data() + max_size , dataForSlave.size() - max_size); - dataForSlave.truncate(max_size); - } - - sendAsyncData(dataForSlave); - - if (m_subJob) - { - // Bitburger protocol in action - suspend(); // Wait for more data from subJob. - m_subJob->resume(); // Ask for more! - } -} - -void TransferJob::slotMimetype( const TQString& type ) -{ - m_mimetype = type; - emit mimetype( this, m_mimetype); -} - - -void TransferJob::suspend() -{ - m_suspended = true; - if (m_slave) - m_slave->suspend(); -} - -void TransferJob::resume() -{ - m_suspended = false; - if (m_slave) - m_slave->resume(); -} - -void TransferJob::start(Slave *slave) -{ - assert(slave); - connect( slave, TQT_SIGNAL( data( const TQByteArray & ) ), - TQT_SLOT( slotData( const TQByteArray & ) ) ); - - connect( slave, TQT_SIGNAL( dataReq() ), - TQT_SLOT( slotDataReq() ) ); - - connect( slave, TQT_SIGNAL( redirection(const KURL &) ), - TQT_SLOT( slotRedirection(const KURL &) ) ); - - connect( slave, TQT_SIGNAL(mimeType( const TQString& ) ), - TQT_SLOT( slotMimetype( const TQString& ) ) ); - - connect( slave, TQT_SIGNAL(errorPage() ), - TQT_SLOT( slotErrorPage() ) ); - - connect( slave, TQT_SIGNAL( needSubURLData() ), - TQT_SLOT( slotNeedSubURLData() ) ); - - connect( slave, TQT_SIGNAL(canResume( TDEIO::filesize_t ) ), - TQT_SLOT( slotCanResume( TDEIO::filesize_t ) ) ); - - if (slave->suspended()) - { - m_mimetype = "unknown"; - // WABA: The slave was put on hold. Resume operation. - slave->resume(); - } - - SimpleJob::start(slave); - if (m_suspended) - slave->suspend(); -} - -void TransferJob::slotNeedSubURLData() -{ - // Job needs data from subURL. - m_subJob = TDEIO::get( m_subUrl, false, false); - suspend(); // Put job on hold until we have some data. - connect(m_subJob, TQT_SIGNAL( data(TDEIO::Job*,const TQByteArray &)), - TQT_SLOT( slotSubURLData(TDEIO::Job*,const TQByteArray &))); - addSubjob(m_subJob); -} - -void TransferJob::slotSubURLData(TDEIO::Job*, const TQByteArray &data) -{ - // The Alternating Bitburg protocol in action again. - staticData = data; - m_subJob->suspend(); // Put job on hold until we have delivered the data. - resume(); // Activate ourselves again. -} - -void TransferJob::slotMetaData( const TDEIO::MetaData &_metaData) { - SimpleJob::slotMetaData(_metaData); - storeSSLSessionFromJob(m_redirectionURL); -} - -void TransferJob::slotErrorPage() -{ - m_errorPage = true; -} - -void TransferJob::slotCanResume( TDEIO::filesize_t offset ) -{ - emit canResume(this, offset); -} - -void TransferJob::slotResult( TDEIO::Job *job) -{ - // This can only be our suburl. - assert(job == m_subJob); - // Did job have an error ? - if ( job->error() ) - { - m_error = job->error(); - m_errorText = job->errorText(); - - emitResult(); - return; - } - - if (job == m_subJob) - { - m_subJob = 0; // No action required - resume(); // Make sure we get the remaining data. - } - removeSubjob( job, false, false ); // Remove job, but don't kill this job. -} - -TransferJob *TDEIO::get( const KURL& url, bool reload, bool showProgressInfo ) -{ - // Send decoded path and encoded query - KIO_ARGS << url; - TransferJob * job = new TransferJob( url, CMD_GET, packedArgs, TQByteArray(), showProgressInfo ); - if (reload) - job->addMetaData("cache", "reload"); - return job; -} - -class PostErrorJob : public TransferJob -{ -public: - - PostErrorJob(int _error, const TQString& url, const TQByteArray &packedArgs, const TQByteArray &postData, bool showProgressInfo) - : TransferJob(KURL(), CMD_SPECIAL, packedArgs, postData, showProgressInfo) - { - m_error = _error; - m_errorText = url; - } - -}; - -TransferJob *TDEIO::http_post( const KURL& url, const TQByteArray &postData, bool showProgressInfo ) -{ - int _error = 0; - - // filter out some malicious ports - static const int bad_ports[] = { - 1, // tcpmux - 7, // echo - 9, // discard - 11, // systat - 13, // daytime - 15, // netstat - 17, // qotd - 19, // chargen - 20, // ftp-data - 21, // ftp-cntl - 22, // ssh - 23, // telnet - 25, // smtp - 37, // time - 42, // name - 43, // nicname - 53, // domain - 77, // priv-rjs - 79, // finger - 87, // ttylink - 95, // supdup - 101, // hostriame - 102, // iso-tsap - 103, // gppitnp - 104, // acr-nema - 109, // pop2 - 110, // pop3 - 111, // sunrpc - 113, // auth - 115, // sftp - 117, // uucp-path - 119, // nntp - 123, // NTP - 135, // loc-srv / epmap - 139, // netbios - 143, // imap2 - 179, // BGP - 389, // ldap - 512, // print / exec - 513, // login - 514, // shell - 515, // printer - 526, // tempo - 530, // courier - 531, // Chat - 532, // netnews - 540, // uucp - 556, // remotefs - 587, // sendmail - 601, // - 989, // ftps data - 990, // ftps - 992, // telnets - 993, // imap/SSL - 995, // pop3/SSL - 1080, // SOCKS - 2049, // nfs - 4045, // lockd - 6000, // x11 - 6667, // irc - 0}; - for (int cnt=0; bad_ports[cnt]; ++cnt) - if (url.port() == bad_ports[cnt]) - { - _error = TDEIO::ERR_POST_DENIED; - break; - } - - if( _error ) - { - static bool override_loaded = false; - static TQValueList< int >* overriden_ports = NULL; - if( !override_loaded ) - { - TDEConfig cfg( "kio_httprc", true ); - overriden_ports = new TQValueList< int >; - *overriden_ports = cfg.readIntListEntry( "OverriddenPorts" ); - override_loaded = true; - } - for( TQValueList< int >::ConstIterator it = overriden_ports->begin(); - it != overriden_ports->end(); - ++it ) - if( overriden_ports->contains( url.port())) - _error = 0; - } - - // filter out non https? protocols - if ((url.protocol() != "http") && (url.protocol() != "https" )) - _error = TDEIO::ERR_POST_DENIED; - - bool redirection = false; - KURL _url(url); - if (_url.path().isEmpty()) - { - redirection = true; - _url.setPath("/"); - } - - if (!_error && !kapp->authorizeURLAction("open", KURL(), _url)) - _error = TDEIO::ERR_ACCESS_DENIED; - - // if request is not valid, return an invalid transfer job - if (_error) - { - KIO_ARGS << (int)1 << url; - TransferJob * job = new PostErrorJob(_error, url.prettyURL(), packedArgs, postData, showProgressInfo); - return job; - } - - // Send http post command (1), decoded path and encoded query - KIO_ARGS << (int)1 << _url; - TransferJob * job = new TransferJob( _url, CMD_SPECIAL, - packedArgs, postData, showProgressInfo ); - - if (redirection) - TQTimer::singleShot(0, job, TQT_SLOT(slotPostRedirection()) ); - - return job; -} - -// http post got redirected from http://host to http://host/ by TransferJob -// We must do this redirection ourselves because redirections by the -// slave change post jobs into get jobs. -void TransferJob::slotPostRedirection() -{ - kdDebug(7007) << "TransferJob::slotPostRedirection(" << m_url << ")" << endl; - // Tell the user about the new url. - emit redirection(this, m_url); -} - - -TransferJob *TDEIO::put( const KURL& url, int permissions, - bool overwrite, bool resume, bool showProgressInfo ) -{ - KIO_ARGS << url << TQ_INT8( overwrite ? 1 : 0 ) << TQ_INT8( resume ? 1 : 0 ) << permissions; - TransferJob * job = new TransferJob( url, CMD_PUT, packedArgs, TQByteArray(), showProgressInfo ); - return job; -} - -////////// - -StoredTransferJob::StoredTransferJob(const KURL& url, int command, - const TQByteArray &packedArgs, - const TQByteArray &_staticData, - bool showProgressInfo) - : TransferJob( url, command, packedArgs, _staticData, showProgressInfo ), - m_uploadOffset( 0 ) -{ - connect( this, TQT_SIGNAL( data( TDEIO::Job *, const TQByteArray & ) ), - TQT_SLOT( slotStoredData( TDEIO::Job *, const TQByteArray & ) ) ); - connect( this, TQT_SIGNAL( dataReq( TDEIO::Job *, TQByteArray & ) ), - TQT_SLOT( slotStoredDataReq( TDEIO::Job *, TQByteArray & ) ) ); -} - -void StoredTransferJob::setData( const TQByteArray& arr ) -{ - Q_ASSERT( m_data.isNull() ); // check that we're only called once - Q_ASSERT( m_uploadOffset == 0 ); // no upload started yet - m_data = arr; -} - -void StoredTransferJob::slotStoredData( TDEIO::Job *, const TQByteArray &data ) -{ - // check for end-of-data marker: - if ( data.size() == 0 ) - return; - unsigned int oldSize = m_data.size(); - m_data.resize( oldSize + data.size(), TQGArray::SpeedOptim ); - memcpy( m_data.data() + oldSize, data.data(), data.size() ); -} - -void StoredTransferJob::slotStoredDataReq( TDEIO::Job *, TQByteArray &data ) -{ - // Inspired from kmail's KMKernel::byteArrayToRemoteFile - // send the data in 64 KB chunks - const int MAX_CHUNK_SIZE = 64*1024; - int remainingBytes = m_data.size() - m_uploadOffset; - if( remainingBytes > MAX_CHUNK_SIZE ) { - // send MAX_CHUNK_SIZE bytes to the receiver (deep copy) - data.duplicate( m_data.data() + m_uploadOffset, MAX_CHUNK_SIZE ); - m_uploadOffset += MAX_CHUNK_SIZE; - //kdDebug() << "Sending " << MAX_CHUNK_SIZE << " bytes (" - // << remainingBytes - MAX_CHUNK_SIZE << " bytes remain)\n"; - } else { - // send the remaining bytes to the receiver (deep copy) - data.duplicate( m_data.data() + m_uploadOffset, remainingBytes ); - m_data = TQByteArray(); - m_uploadOffset = 0; - //kdDebug() << "Sending " << remainingBytes << " bytes\n"; - } -} - -StoredTransferJob *TDEIO::storedGet( const KURL& url, bool reload, bool showProgressInfo ) -{ - // Send decoded path and encoded query - KIO_ARGS << url; - StoredTransferJob * job = new StoredTransferJob( url, CMD_GET, packedArgs, TQByteArray(), showProgressInfo ); - if (reload) - job->addMetaData("cache", "reload"); - return job; -} - -StoredTransferJob *TDEIO::storedPut( const TQByteArray& arr, const KURL& url, int permissions, - bool overwrite, bool resume, bool showProgressInfo ) -{ - KIO_ARGS << url << TQ_INT8( overwrite ? 1 : 0 ) << TQ_INT8( resume ? 1 : 0 ) << permissions; - StoredTransferJob * job = new StoredTransferJob( url, CMD_PUT, packedArgs, TQByteArray(), showProgressInfo ); - job->setData( arr ); - return job; -} - -////////// - -MimetypeJob::MimetypeJob( const KURL& url, int command, - const TQByteArray &packedArgs, bool showProgressInfo ) - : TransferJob(url, command, packedArgs, TQByteArray(), showProgressInfo) -{ -} - -void MimetypeJob::start(Slave *slave) -{ - TransferJob::start(slave); -} - - -void MimetypeJob::slotFinished( ) -{ - //kdDebug(7007) << "MimetypeJob::slotFinished()" << endl; - if ( m_error == TDEIO::ERR_IS_DIRECTORY ) - { - // It is in fact a directory. This happens when HTTP redirects to FTP. - // Due to the "protocol doesn't support listing" code in KRun, we - // assumed it was a file. - kdDebug(7007) << "It is in fact a directory!" << endl; - m_mimetype = TQString::fromLatin1("inode/directory"); - emit TransferJob::mimetype( this, m_mimetype ); - m_error = 0; - } - if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error ) - { - // Return slave to the scheduler - TransferJob::slotFinished(); - } else { - //kdDebug(7007) << "MimetypeJob: Redirection to " << m_redirectionURL << endl; - if (queryMetaData("permanent-redirect")=="true") - emit permanentRedirection(this, m_url, m_redirectionURL); - staticData.truncate(0); - m_suspended = false; - m_url = m_redirectionURL; - m_redirectionURL = KURL(); - m_packedArgs.truncate(0); - TQDataStream stream( m_packedArgs, IO_WriteOnly ); - stream << m_url; - - // Return slave to the scheduler - slaveDone(); - Scheduler::doJob(this); - } -} - -MimetypeJob *TDEIO::mimetype(const KURL& url, bool showProgressInfo ) -{ - KIO_ARGS << url; - MimetypeJob * job = new MimetypeJob(url, CMD_MIMETYPE, packedArgs, showProgressInfo); - if ( showProgressInfo ) - Observer::self()->stating( job, url ); - return job; -} - -////////////////////////// - -DirectCopyJob::DirectCopyJob( const KURL& url, int command, - const TQByteArray &packedArgs, bool showProgressInfo ) - : SimpleJob(url, command, packedArgs, showProgressInfo) -{ -} - -void DirectCopyJob::start( Slave* slave ) -{ - connect( slave, TQT_SIGNAL(canResume( TDEIO::filesize_t ) ), - TQT_SLOT( slotCanResume( TDEIO::filesize_t ) ) ); - SimpleJob::start(slave); -} - -void DirectCopyJob::slotCanResume( TDEIO::filesize_t offset ) -{ - emit canResume(this, offset); -} - -////////////////////////// - - -class FileCopyJob::FileCopyJobPrivate -{ -public: - TDEIO::filesize_t m_sourceSize; - time_t m_modificationTime; - SimpleJob *m_delJob; -}; - -/* - * The FileCopyJob works according to the famous Bayern - * 'Alternating Bitburger Protocol': we either drink a beer or we - * we order a beer, but never both at the same time. - * Tranlated to io-slaves: We alternate between receiving a block of data - * and sending it away. - */ -FileCopyJob::FileCopyJob( const KURL& src, const KURL& dest, int permissions, - bool move, bool overwrite, bool resume, bool showProgressInfo) - : Job(showProgressInfo), m_src(src), m_dest(dest), - m_permissions(permissions), m_move(move), m_overwrite(overwrite), m_resume(resume), - m_totalSize(0) -{ - if (showProgressInfo && !move) - Observer::self()->slotCopying( this, src, dest ); - else if (showProgressInfo && move) - Observer::self()->slotMoving( this, src, dest ); - - //kdDebug(7007) << "FileCopyJob::FileCopyJob()" << endl; - m_moveJob = 0; - m_copyJob = 0; - m_getJob = 0; - m_putJob = 0; - d = new FileCopyJobPrivate; - d->m_delJob = 0; - d->m_sourceSize = (TDEIO::filesize_t) -1; - d->m_modificationTime = static_cast<time_t>( -1 ); - TQTimer::singleShot(0, this, TQT_SLOT(slotStart())); -} - -void FileCopyJob::slotStart() -{ - if ( m_move ) - { - // The if() below must be the same as the one in startBestCopyMethod - if ((m_src.protocol() == m_dest.protocol()) && - (m_src.host() == m_dest.host()) && - (m_src.port() == m_dest.port()) && - (m_src.user() == m_dest.user()) && - (m_src.pass() == m_dest.pass()) && - !m_src.hasSubURL() && !m_dest.hasSubURL()) - { - startRenameJob(m_src); - return; - } - else if (m_src.isLocalFile() && KProtocolInfo::canRenameFromFile(m_dest)) - { - startRenameJob(m_dest); - return; - } - else if (m_dest.isLocalFile() && KProtocolInfo::canRenameToFile(m_src)) - { - startRenameJob(m_src); - return; - } - // No fast-move available, use copy + del. - } - startBestCopyMethod(); -} - -void FileCopyJob::startBestCopyMethod() -{ - if ((m_src.protocol() == m_dest.protocol()) && - (m_src.host() == m_dest.host()) && - (m_src.port() == m_dest.port()) && - (m_src.user() == m_dest.user()) && - (m_src.pass() == m_dest.pass()) && - !m_src.hasSubURL() && !m_dest.hasSubURL()) - { - startCopyJob(); - } - else if (m_src.isLocalFile() && KProtocolInfo::canCopyFromFile(m_dest)) - { - startCopyJob(m_dest); - } - else if (m_dest.isLocalFile() && KProtocolInfo::canCopyToFile(m_src)) - { - startCopyJob(m_src); - } - else - { - startDataPump(); - } -} - -FileCopyJob::~FileCopyJob() -{ - delete d; -} - -void FileCopyJob::setSourceSize( off_t size ) -{ - d->m_sourceSize = size; - if (size != (off_t) -1) - m_totalSize = size; -} - -void FileCopyJob::setSourceSize64( TDEIO::filesize_t size ) -{ - d->m_sourceSize = size; - if (size != (TDEIO::filesize_t) -1) - m_totalSize = size; -} - -void FileCopyJob::setModificationTime( time_t mtime ) -{ - d->m_modificationTime = mtime; -} - -void FileCopyJob::startCopyJob() -{ - startCopyJob(m_src); -} - -void FileCopyJob::startCopyJob(const KURL &slave_url) -{ - //kdDebug(7007) << "FileCopyJob::startCopyJob()" << endl; - KIO_ARGS << m_src << m_dest << m_permissions << (TQ_INT8) m_overwrite; - m_copyJob = new DirectCopyJob(slave_url, CMD_COPY, packedArgs, false); - addSubjob( m_copyJob ); - connectSubjob( m_copyJob ); - connect( m_copyJob, TQT_SIGNAL(canResume(TDEIO::Job *, TDEIO::filesize_t)), - TQT_SLOT( slotCanResume(TDEIO::Job *, TDEIO::filesize_t))); -} - -void FileCopyJob::startRenameJob(const KURL &slave_url) -{ - KIO_ARGS << m_src << m_dest << (TQ_INT8) m_overwrite; - m_moveJob = new SimpleJob(slave_url, CMD_RENAME, packedArgs, false); - addSubjob( m_moveJob ); - connectSubjob( m_moveJob ); -} - -void FileCopyJob::connectSubjob( SimpleJob * job ) -{ - connect( job, TQT_SIGNAL(totalSize( TDEIO::Job*, TDEIO::filesize_t )), - this, TQT_SLOT( slotTotalSize(TDEIO::Job*, TDEIO::filesize_t)) ); - - connect( job, TQT_SIGNAL(processedSize( TDEIO::Job*, TDEIO::filesize_t )), - this, TQT_SLOT( slotProcessedSize(TDEIO::Job*, TDEIO::filesize_t)) ); - - connect( job, TQT_SIGNAL(percent( TDEIO::Job*, unsigned long )), - this, TQT_SLOT( slotPercent(TDEIO::Job*, unsigned long)) ); - -} - -void FileCopyJob::slotProcessedSize( TDEIO::Job *, TDEIO::filesize_t size ) -{ - setProcessedSize(size); - emit processedSize( this, size ); - if ( size > m_totalSize ) { - slotTotalSize( this, size ); // safety - } - emitPercent( size, m_totalSize ); -} - -void FileCopyJob::slotTotalSize( TDEIO::Job*, TDEIO::filesize_t size ) -{ - if (size > m_totalSize) - { - m_totalSize = size; - emit totalSize( this, m_totalSize ); - } -} - -void FileCopyJob::slotPercent( TDEIO::Job*, unsigned long pct ) -{ - if ( pct > m_percent ) - { - m_percent = pct; - emit percent( this, m_percent ); - } -} - -void FileCopyJob::startDataPump() -{ - //kdDebug(7007) << "FileCopyJob::startDataPump()" << endl; - - m_canResume = false; - m_resumeAnswerSent = false; - m_getJob = 0L; // for now - m_putJob = put( m_dest, m_permissions, m_overwrite, m_resume, false /* no GUI */); - if ( d->m_modificationTime != static_cast<time_t>( -1 ) ) { - TQDateTime dt; dt.setTime_t( d->m_modificationTime ); - m_putJob->addMetaData( "modified", dt.toString( Qt::ISODate ) ); - } - //kdDebug(7007) << "FileCopyJob: m_putJob = " << m_putJob << " m_dest=" << m_dest << endl; - - // The first thing the put job will tell us is whether we can - // resume or not (this is always emitted) - connect( m_putJob, TQT_SIGNAL(canResume(TDEIO::Job *, TDEIO::filesize_t)), - TQT_SLOT( slotCanResume(TDEIO::Job *, TDEIO::filesize_t))); - connect( m_putJob, TQT_SIGNAL(dataReq(TDEIO::Job *, TQByteArray&)), - TQT_SLOT( slotDataReq(TDEIO::Job *, TQByteArray&))); - addSubjob( m_putJob ); -} - -void FileCopyJob::slotCanResume( TDEIO::Job* job, TDEIO::filesize_t offset ) -{ - if ( job == m_putJob || job == m_copyJob ) - { - //kdDebug(7007) << "FileCopyJob::slotCanResume from PUT job. offset=" << TDEIO::number(offset) << endl; - if (offset) - { - RenameDlg_Result res = R_RESUME; - - if (!KProtocolManager::autoResume() && !m_overwrite) - { - TQString newPath; - TDEIO::Job* job = ( !m_progressId && parentJob() ) ? parentJob() : this; - // Ask confirmation about resuming previous transfer - res = Observer::self()->open_RenameDlg( - job, i18n("File Already Exists"), - m_src.url(), - m_dest.url(), - (RenameDlg_Mode) (M_OVERWRITE | M_RESUME | M_NORENAME), newPath, - d->m_sourceSize, offset ); - } - - if ( res == R_OVERWRITE || m_overwrite ) - offset = 0; - else if ( res == R_CANCEL ) - { - if ( job == m_putJob ) - m_putJob->kill(true); - else - m_copyJob->kill(true); - m_error = ERR_USER_CANCELED; - emitResult(); - return; - } - } - else - m_resumeAnswerSent = true; // No need for an answer - - if ( job == m_putJob ) - { - m_getJob = get( m_src, false, false /* no GUI */ ); - //kdDebug(7007) << "FileCopyJob: m_getJob = " << m_getJob << endl; - m_getJob->addMetaData( "errorPage", "false" ); - m_getJob->addMetaData( "AllowCompressedPage", "false" ); - // Set size in subjob. This helps if the slave doesn't emit totalSize. - if ( d->m_sourceSize != (TDEIO::filesize_t)-1 ) - m_getJob->slotTotalSize( d->m_sourceSize ); - if (offset) - { - //kdDebug(7007) << "Setting metadata for resume to " << (unsigned long) offset << endl; - // TODO KDE4: rename to seek or offset and document it - // This isn't used only for resuming, but potentially also for extracting (#72302). - m_getJob->addMetaData( "resume", TDEIO::number(offset) ); - - // Might or might not get emitted - connect( m_getJob, TQT_SIGNAL(canResume(TDEIO::Job *, TDEIO::filesize_t)), - TQT_SLOT( slotCanResume(TDEIO::Job *, TDEIO::filesize_t))); - } - m_putJob->slave()->setOffset( offset ); - - m_putJob->suspend(); - addSubjob( m_getJob ); - connectSubjob( m_getJob ); // Progress info depends on get - m_getJob->resume(); // Order a beer - - connect( m_getJob, TQT_SIGNAL(data(TDEIO::Job*,const TQByteArray&)), - TQT_SLOT( slotData(TDEIO::Job*,const TQByteArray&)) ); - connect( m_getJob, TQT_SIGNAL(mimetype(TDEIO::Job*,const TQString&) ), - TQT_SLOT(slotMimetype(TDEIO::Job*,const TQString&)) ); - } - else // copyjob - { - m_copyJob->slave()->sendResumeAnswer( offset != 0 ); - } - } - else if ( job == m_getJob ) - { - // Cool, the get job said ok, we can resume - m_canResume = true; - //kdDebug(7007) << "FileCopyJob::slotCanResume from the GET job -> we can resume" << endl; - - m_getJob->slave()->setOffset( m_putJob->slave()->offset() ); - } - else - kdWarning(7007) << "FileCopyJob::slotCanResume from unknown job=" << job - << " m_getJob=" << m_getJob << " m_putJob=" << m_putJob << endl; -} - -void FileCopyJob::slotData( TDEIO::Job * , const TQByteArray &data) -{ - //kdDebug(7007) << "FileCopyJob::slotData" << endl; - //kdDebug(7007) << " data size : " << data.size() << endl; - assert(m_putJob); - if (!m_putJob) return; // Don't crash - m_getJob->suspend(); - m_putJob->resume(); // Drink the beer - m_buffer = data; - - // On the first set of data incoming, we tell the "put" slave about our - // decision about resuming - if (!m_resumeAnswerSent) - { - m_resumeAnswerSent = true; - //kdDebug(7007) << "FileCopyJob::slotData (first time) -> send resume answer " << m_canResume << endl; - m_putJob->slave()->sendResumeAnswer( m_canResume ); - } -} - -void FileCopyJob::slotDataReq( TDEIO::Job * , TQByteArray &data) -{ - //kdDebug(7007) << "FileCopyJob::slotDataReq" << endl; - if (!m_resumeAnswerSent && !m_getJob) - { - // This can't happen (except as a migration bug on 12/10/2000) - m_error = ERR_INTERNAL; - m_errorText = "'Put' job didn't send canResume or 'Get' job didn't send data!"; - m_putJob->kill(true); - emitResult(); - return; - } - if (m_getJob) - { - m_getJob->resume(); // Order more beer - m_putJob->suspend(); - } - data = m_buffer; - m_buffer = TQByteArray(); -} - -void FileCopyJob::slotMimetype( TDEIO::Job*, const TQString& type ) -{ - emit mimetype( this, type ); -} - -void FileCopyJob::slotResult( TDEIO::Job *job) -{ - //kdDebug(7007) << "FileCopyJob this=" << this << " ::slotResult(" << job << ")" << endl; - // Did job have an error ? - if ( job->error() ) - { - if ((job == m_moveJob) && (job->error() == ERR_UNSUPPORTED_ACTION)) - { - m_moveJob = 0; - startBestCopyMethod(); - removeSubjob(job); - return; - } - else if ((job == m_copyJob) && (job->error() == ERR_UNSUPPORTED_ACTION)) - { - m_copyJob = 0; - startDataPump(); - removeSubjob(job); - return; - } - else if (job == m_getJob) - { - m_getJob = 0L; - if (m_putJob) - m_putJob->kill(true); - } - else if (job == m_putJob) - { - m_putJob = 0L; - if (m_getJob) - m_getJob->kill(true); - } - m_error = job->error(); - m_errorText = job->errorText(); - emitResult(); - return; - } - - if (job == m_moveJob) - { - m_moveJob = 0; // Finished - } - - if (job == m_copyJob) - { - m_copyJob = 0; - if (m_move) - { - d->m_delJob = file_delete( m_src, false/*no GUI*/ ); // Delete source - addSubjob(d->m_delJob); - } - } - - if (job == m_getJob) - { - m_getJob = 0; // No action required - if (m_putJob) - m_putJob->resume(); - } - - if (job == m_putJob) - { - //kdDebug(7007) << "FileCopyJob: m_putJob finished " << endl; - m_putJob = 0; - if (m_getJob) - { - kdWarning(7007) << "WARNING ! Get still going on..." << endl; - m_getJob->resume(); - } - if (m_move) - { - d->m_delJob = file_delete( m_src, false/*no GUI*/ ); // Delete source - addSubjob(d->m_delJob); - } - } - - if (job == d->m_delJob) - { - d->m_delJob = 0; // Finished - } - removeSubjob(job); -} - -FileCopyJob *TDEIO::file_copy( const KURL& src, const KURL& dest, int permissions, - bool overwrite, bool resume, bool showProgressInfo) -{ - return new FileCopyJob( src, dest, permissions, false, overwrite, resume, showProgressInfo ); -} - -FileCopyJob *TDEIO::file_move( const KURL& src, const KURL& dest, int permissions, - bool overwrite, bool resume, bool showProgressInfo) -{ - return new FileCopyJob( src, dest, permissions, true, overwrite, resume, showProgressInfo ); -} - -SimpleJob *TDEIO::file_delete( const KURL& src, bool showProgressInfo) -{ - KIO_ARGS << src << TQ_INT8(true); // isFile - return new SimpleJob(src, CMD_DEL, packedArgs, showProgressInfo ); -} - -////////// - -// KDE 4: Make it const TQString & _prefix -ListJob::ListJob(const KURL& u, bool showProgressInfo, bool _recursive, TQString _prefix, bool _includeHidden) : - SimpleJob(u, CMD_LISTDIR, TQByteArray(), showProgressInfo), - recursive(_recursive), includeHidden(_includeHidden), prefix(_prefix), m_processedEntries(0) -{ - // We couldn't set the args when calling the parent constructor, - // so do it now. - TQDataStream stream( m_packedArgs, IO_WriteOnly ); - stream << u; -} - -void ListJob::slotListEntries( const TDEIO::UDSEntryList& list ) -{ - // Emit progress info (takes care of emit processedSize and percent) - m_processedEntries += list.count(); - slotProcessedSize( m_processedEntries ); - - if (recursive) { - UDSEntryListConstIterator it = list.begin(); - UDSEntryListConstIterator end = list.end(); - - for (; it != end; ++it) { - bool isDir = false; - bool isLink = false; - KURL itemURL; - - UDSEntry::ConstIterator it2 = (*it).begin(); - UDSEntry::ConstIterator end2 = (*it).end(); - for( ; it2 != end2; it2++ ) { - switch( (*it2).m_uds ) { - case UDS_FILE_TYPE: - isDir = S_ISDIR((*it2).m_long); - break; - case UDS_NAME: - if( itemURL.isEmpty() ) { - itemURL = url(); - itemURL.addPath( (*it2).m_str ); - } - break; - case UDS_URL: - itemURL = (*it2).m_str; - break; - case UDS_LINK_DEST: - // This is a link !!! Don't follow ! - isLink = !(*it2).m_str.isEmpty(); - break; - default: - break; - } - } - if (isDir && !isLink) { - const TQString filename = itemURL.fileName(); - // skip hidden dirs when listing if requested - if (filename != ".." && filename != "." && (includeHidden || filename[0] != '.')) { - ListJob *job = new ListJob(itemURL, - false /*no progress info!*/, - true /*recursive*/, - prefix + filename + "/", - includeHidden); - Scheduler::scheduleJob(job); - connect(job, TQT_SIGNAL(entries( TDEIO::Job *, - const TDEIO::UDSEntryList& )), - TQT_SLOT( gotEntries( TDEIO::Job*, - const TDEIO::UDSEntryList& ))); - addSubjob(job); - } - } - } - } - - // Not recursive, or top-level of recursive listing : return now (send . and .. as well) - // exclusion of hidden files also requires the full sweep, but the case for full-listing - // a single dir is probably common enough to justify the shortcut - if (prefix.isNull() && includeHidden) { - emit entries(this, list); - } else { - // cull the unwanted hidden dirs and/or parent dir references from the listing, then emit that - UDSEntryList newlist; - - UDSEntryListConstIterator it = list.begin(); - UDSEntryListConstIterator end = list.end(); - for (; it != end; ++it) { - - UDSEntry newone = *it; - UDSEntry::Iterator it2 = newone.begin(); - TQString filename; - for( ; it2 != newone.end(); it2++ ) { - if ((*it2).m_uds == UDS_NAME) { - filename = (*it2).m_str; - (*it2).m_str = prefix + filename; - } - } - // Avoid returning entries like subdir/. and subdir/.., but include . and .. for - // the toplevel dir, and skip hidden files/dirs if that was requested - if ( (prefix.isNull() || (filename != ".." && filename != ".") ) - && (includeHidden || (filename[0] != '.') ) ) - newlist.append(newone); - } - - emit entries(this, newlist); - } -} - -void ListJob::gotEntries(TDEIO::Job *, const TDEIO::UDSEntryList& list ) -{ - // Forward entries received by subjob - faking we received them ourselves - emit entries(this, list); -} - -void ListJob::slotResult( TDEIO::Job * job ) -{ - // If we can't list a subdir, the result is still ok - // This is why we override Job::slotResult() - to skip error checking - removeSubjob( job ); -} - -void ListJob::slotRedirection( const KURL & url ) -{ - if (!kapp->authorizeURLAction("redirect", m_url, url)) - { - kdWarning(7007) << "ListJob: Redirection from " << m_url << " to " << url << " REJECTED!" << endl; - return; - } - m_redirectionURL = url; // We'll remember that when the job finishes - if (m_url.hasUser() && !url.hasUser() && (m_url.host().lower() == url.host().lower())) - m_redirectionURL.setUser(m_url.user()); // Preserve user - emit redirection( this, m_redirectionURL ); -} - -void ListJob::slotFinished() -{ - // Support for listing archives as directories - if ( m_error == TDEIO::ERR_IS_FILE && m_url.isLocalFile() ) { - KMimeType::Ptr ptr = KMimeType::findByURL( m_url, 0, true, true ); - if ( ptr ) { - TQString proto = ptr->property("X-TDE-LocalProtocol").toString(); - if ( !proto.isEmpty() && KProtocolInfo::isKnownProtocol(proto) ) { - m_redirectionURL = m_url; - m_redirectionURL.setProtocol( proto ); - m_error = 0; - emit redirection(this,m_redirectionURL); - } - } - } - if ( m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error ) { - // Return slave to the scheduler - SimpleJob::slotFinished(); - } else { - - //kdDebug(7007) << "ListJob: Redirection to " << m_redirectionURL << endl; - if (queryMetaData("permanent-redirect")=="true") - emit permanentRedirection(this, m_url, m_redirectionURL); - m_url = m_redirectionURL; - m_redirectionURL = KURL(); - m_packedArgs.truncate(0); - TQDataStream stream( m_packedArgs, IO_WriteOnly ); - stream << m_url; - - // Return slave to the scheduler - slaveDone(); - Scheduler::doJob(this); - } -} - -void ListJob::slotMetaData( const TDEIO::MetaData &_metaData) { - SimpleJob::slotMetaData(_metaData); - storeSSLSessionFromJob(m_redirectionURL); -} - -ListJob *TDEIO::listDir( const KURL& url, bool showProgressInfo, bool includeHidden ) -{ - ListJob * job = new ListJob(url, showProgressInfo,false,TQString::null,includeHidden); - return job; -} - -ListJob *TDEIO::listRecursive( const KURL& url, bool showProgressInfo, bool includeHidden ) -{ - ListJob * job = new ListJob(url, showProgressInfo, true,TQString::null,includeHidden); - return job; -} - -void ListJob::setUnrestricted(bool unrestricted) -{ - if (unrestricted) - extraFlags() |= EF_ListJobUnrestricted; - else - extraFlags() &= ~EF_ListJobUnrestricted; -} - -void ListJob::start(Slave *slave) -{ - if (kapp && !kapp->authorizeURLAction("list", m_url, m_url) && !(extraFlags() & EF_ListJobUnrestricted)) - { - m_error = ERR_ACCESS_DENIED; - m_errorText = m_url.url(); - TQTimer::singleShot(0, this, TQT_SLOT(slotFinished()) ); - return; - } - connect( slave, TQT_SIGNAL( listEntries( const TDEIO::UDSEntryList& )), - TQT_SLOT( slotListEntries( const TDEIO::UDSEntryList& ))); - connect( slave, TQT_SIGNAL( totalSize( TDEIO::filesize_t ) ), - TQT_SLOT( slotTotalSize( TDEIO::filesize_t ) ) ); - connect( slave, TQT_SIGNAL( redirection(const KURL &) ), - TQT_SLOT( slotRedirection(const KURL &) ) ); - - SimpleJob::start(slave); -} - -class CopyJob::CopyJobPrivate -{ -public: - CopyJobPrivate() { - m_defaultPermissions = false; - m_bURLDirty = false; - } - // This is the dest URL that was initially given to CopyJob - // It is copied into m_dest, which can be changed for a given src URL - // (when using the RENAME dialog in slotResult), - // and which will be reset for the next src URL. - KURL m_globalDest; - // The state info about that global dest - CopyJob::DestinationState m_globalDestinationState; - // See setDefaultPermissions - bool m_defaultPermissions; - // Whether URLs changed (and need to be emitted by the next slotReport call) - bool m_bURLDirty; - // Used after copying all the files into the dirs, to set mtime (TODO: and permissions?) - // after the copy is done - TQValueList<CopyInfo> m_directoriesCopied; -}; - -CopyJob::CopyJob( const KURL::List& src, const KURL& dest, CopyMode mode, bool asMethod, bool showProgressInfo ) - : Job(showProgressInfo), m_mode(mode), m_asMethod(asMethod), - destinationState(DEST_NOT_STATED), state(STATE_STATING), - m_totalSize(0), m_processedSize(0), m_fileProcessedSize(0), - m_processedFiles(0), m_processedDirs(0), - m_srcList(src), m_currentStatSrc(m_srcList.begin()), - m_bCurrentOperationIsLink(false), m_bSingleFileCopy(false), m_bOnlyRenames(mode==Move), - m_dest(dest), m_bAutoSkip( false ), m_bOverwriteAll( false ), - m_conflictError(0), m_reportTimer(0) -{ - d = new CopyJobPrivate; - d->m_globalDest = dest; - d->m_globalDestinationState = destinationState; - - if ( showProgressInfo ) { - connect( this, TQT_SIGNAL( totalFiles( TDEIO::Job*, unsigned long ) ), - Observer::self(), TQT_SLOT( slotTotalFiles( TDEIO::Job*, unsigned long ) ) ); - - connect( this, TQT_SIGNAL( totalDirs( TDEIO::Job*, unsigned long ) ), - Observer::self(), TQT_SLOT( slotTotalDirs( TDEIO::Job*, unsigned long ) ) ); - } - TQTimer::singleShot(0, this, TQT_SLOT(slotStart())); - /** - States: - STATE_STATING for the dest - STATE_STATING for each src url (statNextSrc) - for each: if dir -> STATE_LISTING (filling 'dirs' and 'files') - but if direct rename possible: STATE_RENAMING instead. - STATE_CREATING_DIRS (createNextDir, iterating over 'dirs') - if conflict: STATE_CONFLICT_CREATING_DIRS - STATE_COPYING_FILES (copyNextFile, iterating over 'files') - if conflict: STATE_CONFLICT_COPYING_FILES - STATE_DELETING_DIRS (deleteNextDir) (if moving) - STATE_SETTING_DIR_ATTRIBUTES (setNextDirAttribute, iterating over d->m_directoriesCopied) - done. - */ -} - -CopyJob::~CopyJob() -{ - delete d; -} - -void CopyJob::slotStart() -{ - /** - We call the functions directly instead of using signals. - Calling a function via a signal takes approx. 65 times the time - compared to calling it directly (at least on my machine). aleXXX - */ - m_reportTimer = new TQTimer(this); - - connect(m_reportTimer,TQT_SIGNAL(timeout()),this,TQT_SLOT(slotReport())); - m_reportTimer->start(REPORT_TIMEOUT,false); - - // Stat the dest - TDEIO::Job * job = TDEIO::stat( m_dest, false, 2, false ); - //kdDebug(7007) << "CopyJob:stating the dest " << m_dest << endl; - addSubjob(job); -} - -// For unit test purposes -TDEIO_EXPORT bool kio_resolve_local_urls = true; - -void CopyJob::slotResultStating( Job *job ) -{ - //kdDebug(7007) << "CopyJob::slotResultStating" << endl; - // Was there an error while stating the src ? - if (job->error() && destinationState != DEST_NOT_STATED ) - { - KURL srcurl = ((SimpleJob*)job)->url(); - if ( !srcurl.isLocalFile() ) - { - // Probably : src doesn't exist. Well, over some protocols (e.g. FTP) - // this info isn't really reliable (thanks to MS FTP servers). - // We'll assume a file, and try to download anyway. - kdDebug(7007) << "Error while stating source. Activating hack" << endl; - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); // We should have only one job at a time ... - struct CopyInfo info; - info.permissions = (mode_t) -1; - info.mtime = (time_t) -1; - info.ctime = (time_t) -1; - info.size = (TDEIO::filesize_t)-1; - info.uSource = srcurl; - info.uDest = m_dest; - // Append filename or dirname to destination URL, if allowed - if ( destinationState == DEST_IS_DIR && !m_asMethod ) - info.uDest.addPath( srcurl.fileName() ); - - files.append( info ); - statNextSrc(); - return; - } - // Local file. If stat fails, the file definitely doesn't exist. - Job::slotResult( job ); // will set the error and emit result(this) - return; - } - - // Is it a file or a dir ? Does it have a local path? - UDSEntry entry = ((StatJob*)job)->statResult(); - bool bDir = false; - bool bLink = false; - TQString sName; - TQString sLocalPath; - UDSEntry::ConstIterator it2 = entry.begin(); - for( ; it2 != entry.end(); it2++ ) { - if ( ((*it2).m_uds) == UDS_FILE_TYPE ) - bDir = S_ISDIR( (mode_t)(*it2).m_long ); - else if ( ((*it2).m_uds) == UDS_LINK_DEST ) - bLink = !((*it2).m_str.isEmpty()); - else if ( ((*it2).m_uds) == UDS_NAME ) - sName = (*it2).m_str; - else if ( ((*it2).m_uds) == UDS_LOCAL_PATH ) - sLocalPath = (*it2).m_str; - } - - if ( destinationState == DEST_NOT_STATED ) - // we were stating the dest - { - if (job->error()) - destinationState = DEST_DOESNT_EXIST; - else { - // Treat symlinks to dirs as dirs here, so no test on bLink - destinationState = bDir ? DEST_IS_DIR : DEST_IS_FILE; - //kdDebug(7007) << "CopyJob::slotResultStating dest is dir:" << bDir << endl; - } - const bool isGlobalDest = m_dest == d->m_globalDest; - if ( isGlobalDest ) - d->m_globalDestinationState = destinationState; - - if ( !sLocalPath.isEmpty() && kio_resolve_local_urls ) { - m_dest = KURL(); - m_dest.setPath(sLocalPath); - if ( isGlobalDest ) - d->m_globalDest = m_dest; - } - - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); - - // After knowing what the dest is, we can start stat'ing the first src. - statCurrentSrc(); - return; - } - // We were stating the current source URL - m_currentDest = m_dest; // used by slotEntries - // Create a dummy list with it, for slotEntries - UDSEntryList lst; - lst.append(entry); - - // There 6 cases, and all end up calling slotEntries(job, lst) first : - // 1 - src is a dir, destination is a directory, - // slotEntries will append the source-dir-name to the destination - // 2 - src is a dir, destination is a file, ERROR (done later on) - // 3 - src is a dir, destination doesn't exist, then it's the destination dirname, - // so slotEntries will use it as destination. - - // 4 - src is a file, destination is a directory, - // slotEntries will append the filename to the destination. - // 5 - src is a file, destination is a file, m_dest is the exact destination name - // 6 - src is a file, destination doesn't exist, m_dest is the exact destination name - // Tell slotEntries not to alter the src url - m_bCurrentSrcIsDir = false; - slotEntries(job, lst); - - KURL srcurl; - if (!sLocalPath.isEmpty()) - srcurl.setPath(sLocalPath); - else - srcurl = ((SimpleJob*)job)->url(); - - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); // We should have only one job at a time ... - - if ( bDir - && !bLink // treat symlinks as files (no recursion) - && m_mode != Link ) // No recursion in Link mode either. - { - //kdDebug(7007) << " Source is a directory " << endl; - - m_bCurrentSrcIsDir = true; // used by slotEntries - if ( destinationState == DEST_IS_DIR ) // (case 1) - { - if ( !m_asMethod ) - { - // Use <desturl>/<directory_copied> as destination, from now on - TQString directory = srcurl.fileName(); - if ( !sName.isEmpty() && KProtocolInfo::fileNameUsedForCopying( srcurl ) == KProtocolInfo::Name ) - { - directory = sName; - } - m_currentDest.addPath( directory ); - } - } - else if ( destinationState == DEST_IS_FILE ) // (case 2) - { - m_error = ERR_IS_FILE; - m_errorText = m_dest.prettyURL(); - emitResult(); - return; - } - else // (case 3) - { - // otherwise dest is new name for toplevel dir - // so the destination exists, in fact, from now on. - // (This even works with other src urls in the list, since the - // dir has effectively been created) - destinationState = DEST_IS_DIR; - if ( m_dest == d->m_globalDest ) - d->m_globalDestinationState = destinationState; - } - - startListing( srcurl ); - } - else - { - //kdDebug(7007) << " Source is a file (or a symlink), or we are linking -> no recursive listing " << endl; - statNextSrc(); - } -} - -void CopyJob::slotReport() -{ - // If showProgressInfo was set, m_progressId is > 0. - Observer * observer = m_progressId ? Observer::self() : 0L; - switch (state) { - case STATE_COPYING_FILES: - emit processedFiles( this, m_processedFiles ); - if (observer) observer->slotProcessedFiles(this, m_processedFiles); - if (d->m_bURLDirty) - { - // Only emit urls when they changed. This saves time, and fixes #66281 - d->m_bURLDirty = false; - if (m_mode==Move) - { - if (observer) observer->slotMoving( this, m_currentSrcURL, m_currentDestURL); - emit moving( this, m_currentSrcURL, m_currentDestURL); - } - else if (m_mode==Link) - { - if (observer) observer->slotCopying( this, m_currentSrcURL, m_currentDestURL ); // we don't have a slotLinking - emit linking( this, m_currentSrcURL.path(), m_currentDestURL ); - } - else - { - if (observer) observer->slotCopying( this, m_currentSrcURL, m_currentDestURL ); - emit copying( this, m_currentSrcURL, m_currentDestURL ); - } - } - break; - - case STATE_CREATING_DIRS: - if (observer) observer->slotProcessedDirs( this, m_processedDirs ); - emit processedDirs( this, m_processedDirs ); - if (d->m_bURLDirty) - { - d->m_bURLDirty = false; - emit creatingDir( this, m_currentDestURL ); - if (observer) observer->slotCreatingDir( this, m_currentDestURL); - } - break; - - case STATE_STATING: - case STATE_LISTING: - if (d->m_bURLDirty) - { - d->m_bURLDirty = false; - if (observer) observer->slotCopying( this, m_currentSrcURL, m_currentDestURL ); - } - emit totalSize( this, m_totalSize ); - emit totalFiles( this, files.count() ); - emit totalDirs( this, dirs.count() ); - break; - - default: - break; - } -} - -void CopyJob::slotEntries(TDEIO::Job* job, const UDSEntryList& list) -{ - UDSEntryListConstIterator it = list.begin(); - UDSEntryListConstIterator end = list.end(); - for (; it != end; ++it) { - UDSEntry::ConstIterator it2 = (*it).begin(); - struct CopyInfo info; - info.permissions = -1; - info.mtime = (time_t) -1; - info.ctime = (time_t) -1; - info.size = (TDEIO::filesize_t)-1; - TQString displayName; - KURL url; - TQString localPath; - bool isDir = false; - for( ; it2 != (*it).end(); it2++ ) { - switch ((*it2).m_uds) { - case UDS_FILE_TYPE: - //info.type = (mode_t)((*it2).m_long); - isDir = S_ISDIR( (mode_t)((*it2).m_long) ); - break; - case UDS_NAME: // recursive listing, displayName can be a/b/c/d - displayName = (*it2).m_str; - break; - case UDS_URL: // optional - url = KURL((*it2).m_str); - break; - case UDS_LOCAL_PATH: - localPath = (*it2).m_str; - break; - case UDS_LINK_DEST: - info.linkDest = (*it2).m_str; - break; - case UDS_ACCESS: - info.permissions = ((*it2).m_long); - break; - case UDS_SIZE: - info.size = (TDEIO::filesize_t)((*it2).m_long); - m_totalSize += info.size; - break; - case UDS_MODIFICATION_TIME: - info.mtime = (time_t)((*it2).m_long); - break; - case UDS_CREATION_TIME: - info.ctime = (time_t)((*it2).m_long); - default: - break; - } - } - if (displayName != ".." && displayName != ".") - { - bool hasCustomURL = !url.isEmpty() || !localPath.isEmpty(); - if( !hasCustomURL ) { - // Make URL from displayName - url = ((SimpleJob *)job)->url(); - if ( m_bCurrentSrcIsDir ) { // Only if src is a directory. Otherwise uSource is fine as is - //kdDebug(7007) << "adding path " << displayName << endl; - url.addPath( displayName ); - } - } - //kdDebug(7007) << "displayName=" << displayName << " url=" << url << endl; - if (!localPath.isEmpty() && kio_resolve_local_urls) { - url = KURL(); - url.setPath(localPath); - } - - info.uSource = url; - info.uDest = m_currentDest; - //kdDebug(7007) << " uSource=" << info.uSource << " uDest(1)=" << info.uDest << endl; - // Append filename or dirname to destination URL, if allowed - if ( destinationState == DEST_IS_DIR && - // "copy/move as <foo>" means 'foo' is the dest for the base srcurl - // (passed here during stating) but not its children (during listing) - ( ! ( m_asMethod && state == STATE_STATING ) ) ) - { - TQString destFileName; - if ( hasCustomURL && - KProtocolInfo::fileNameUsedForCopying( url ) == KProtocolInfo::FromURL ) { - //destFileName = url.fileName(); // Doesn't work for recursive listing - // Count the number of prefixes used by the recursive listjob - int numberOfSlashes = displayName.contains( '/' ); // don't make this a find()! - TQString path = url.path(); - int pos = 0; - for ( int n = 0; n < numberOfSlashes + 1; ++n ) { - pos = path.findRev( '/', pos - 1 ); - if ( pos == -1 ) { // error - kdWarning(7007) << "kioslave bug: not enough slashes in UDS_URL " << path << " - looking for " << numberOfSlashes << " slashes" << endl; - break; - } - } - if ( pos >= 0 ) { - destFileName = path.mid( pos + 1 ); - } - - } else { // destination filename taken from UDS_NAME - destFileName = displayName; - } - - // Here we _really_ have to add some filename to the dest. - // Otherwise, we end up with e.g. dest=..../Desktop/ itself. - // (This can happen when dropping a link to a webpage with no path) - if ( destFileName.isEmpty() ) - destFileName = TDEIO::encodeFileName( info.uSource.prettyURL() ); - - //kdDebug(7007) << " adding destFileName=" << destFileName << endl; - info.uDest.addPath( destFileName ); - } - //kdDebug(7007) << " uDest(2)=" << info.uDest << endl; - //kdDebug(7007) << " " << info.uSource << " -> " << info.uDest << endl; - if ( info.linkDest.isEmpty() && isDir && m_mode != Link ) // Dir - { - dirs.append( info ); // Directories - if (m_mode == Move) - dirsToRemove.append( info.uSource ); - } - else { - files.append( info ); // Files and any symlinks - } - } - } -} - -void CopyJob::skipSrc() -{ - m_dest = d->m_globalDest; - destinationState = d->m_globalDestinationState; - ++m_currentStatSrc; - skip( m_currentSrcURL ); - statCurrentSrc(); -} - -void CopyJob::statNextSrc() -{ - /* Revert to the global destination, the one that applies to all source urls. - * Imagine you copy the items a b and c into /d, but /d/b exists so the user uses "Rename" to put it in /foo/b instead. - * m_dest is /foo/b for b, but we have to revert to /d for item c and following. - */ - m_dest = d->m_globalDest; - destinationState = d->m_globalDestinationState; - ++m_currentStatSrc; - statCurrentSrc(); -} - -void CopyJob::statCurrentSrc() -{ - if ( m_currentStatSrc != m_srcList.end() ) - { - m_currentSrcURL = (*m_currentStatSrc); - d->m_bURLDirty = true; - if ( m_mode == Link ) - { - // Skip the "stating the source" stage, we don't need it for linking - m_currentDest = m_dest; - struct CopyInfo info; - info.permissions = -1; - info.mtime = (time_t) -1; - info.ctime = (time_t) -1; - info.size = (TDEIO::filesize_t)-1; - info.uSource = m_currentSrcURL; - info.uDest = m_currentDest; - // Append filename or dirname to destination URL, if allowed - if ( destinationState == DEST_IS_DIR && !m_asMethod ) - { - if ( - (m_currentSrcURL.protocol() == info.uDest.protocol()) && - (m_currentSrcURL.host() == info.uDest.host()) && - (m_currentSrcURL.port() == info.uDest.port()) && - (m_currentSrcURL.user() == info.uDest.user()) && - (m_currentSrcURL.pass() == info.uDest.pass()) ) - { - // This is the case of creating a real symlink - info.uDest.addPath( m_currentSrcURL.fileName() ); - } - else - { - // Different protocols, we'll create a .desktop file - // We have to change the extension anyway, so while we're at it, - // name the file like the URL - info.uDest.addPath( TDEIO::encodeFileName( m_currentSrcURL.prettyURL() )+".desktop" ); - } - } - files.append( info ); // Files and any symlinks - statNextSrc(); // we could use a loop instead of a recursive call :) - return; - } - else if ( m_mode == Move && ( - // Don't go renaming right away if we need a stat() to find out the destination filename - KProtocolInfo::fileNameUsedForCopying( m_currentSrcURL ) == KProtocolInfo::FromURL || - destinationState != DEST_IS_DIR || m_asMethod ) - ) - { - // If moving, before going for the full stat+[list+]copy+del thing, try to rename - // The logic is pretty similar to FileCopyJob::slotStart() - if ( (m_currentSrcURL.protocol() == m_dest.protocol()) && - (m_currentSrcURL.host() == m_dest.host()) && - (m_currentSrcURL.port() == m_dest.port()) && - (m_currentSrcURL.user() == m_dest.user()) && - (m_currentSrcURL.pass() == m_dest.pass()) ) - { - startRenameJob( m_currentSrcURL ); - return; - } - else if ( m_currentSrcURL.isLocalFile() && KProtocolInfo::canRenameFromFile( m_dest ) ) - { - startRenameJob( m_dest ); - return; - } - else if ( m_dest.isLocalFile() && KProtocolInfo::canRenameToFile( m_currentSrcURL ) ) - { - startRenameJob( m_currentSrcURL ); - return; - } - } - - // if the file system doesn't support deleting, we do not even stat - if (m_mode == Move && !KProtocolInfo::supportsDeleting(m_currentSrcURL)) { - TQGuardedPtr<CopyJob> that = this; - if (isInteractive()) - KMessageBox::information( 0, buildErrorString(ERR_CANNOT_DELETE, m_currentSrcURL.prettyURL())); - if (that) - statNextSrc(); // we could use a loop instead of a recursive call :) - return; - } - - // Stat the next src url - Job * job = TDEIO::stat( m_currentSrcURL, true, 2, false ); - //kdDebug(7007) << "TDEIO::stat on " << m_currentSrcURL << endl; - state = STATE_STATING; - addSubjob(job); - m_currentDestURL=m_dest; - m_bOnlyRenames = false; - d->m_bURLDirty = true; - } - else - { - // Finished the stat'ing phase - // First make sure that the totals were correctly emitted - state = STATE_STATING; - d->m_bURLDirty = true; - slotReport(); - if (!dirs.isEmpty()) - emit aboutToCreate( this, dirs ); - if (!files.isEmpty()) - emit aboutToCreate( this, files ); - // Check if we are copying a single file - m_bSingleFileCopy = ( files.count() == 1 && dirs.isEmpty() ); - // Then start copying things - state = STATE_CREATING_DIRS; - createNextDir(); - } -} - -void CopyJob::startRenameJob( const KURL& slave_url ) -{ - KURL dest = m_dest; - // Append filename or dirname to destination URL, if allowed - if ( destinationState == DEST_IS_DIR && !m_asMethod ) - dest.addPath( m_currentSrcURL.fileName() ); - kdDebug(7007) << "This seems to be a suitable case for trying to rename before stat+[list+]copy+del" << endl; - state = STATE_RENAMING; - - struct CopyInfo info; - info.permissions = -1; - info.mtime = (time_t) -1; - info.ctime = (time_t) -1; - info.size = (TDEIO::filesize_t)-1; - info.uSource = m_currentSrcURL; - info.uDest = dest; - TQValueList<CopyInfo> files; - files.append(info); - emit aboutToCreate( this, files ); - - KIO_ARGS << m_currentSrcURL << dest << (TQ_INT8) false /*no overwrite*/; - SimpleJob * newJob = new SimpleJob(slave_url, CMD_RENAME, packedArgs, false); - Scheduler::scheduleJob(newJob); - addSubjob( newJob ); - if ( m_currentSrcURL.directory() != dest.directory() ) // For the user, moving isn't renaming. Only renaming is. - m_bOnlyRenames = false; -} - -void CopyJob::startListing( const KURL & src ) -{ - state = STATE_LISTING; - d->m_bURLDirty = true; - ListJob * newjob = listRecursive( src, false ); - newjob->setUnrestricted(true); - connect(newjob, TQT_SIGNAL(entries( TDEIO::Job *, - const TDEIO::UDSEntryList& )), - TQT_SLOT( slotEntries( TDEIO::Job*, - const TDEIO::UDSEntryList& ))); - addSubjob( newjob ); -} - -void CopyJob::skip( const KURL & sourceUrl ) -{ - // Check if this is one if toplevel sources - // If yes, remove it from m_srcList, for a correct FilesRemoved() signal - //kdDebug(7007) << "CopyJob::skip: looking for " << sourceUrl << endl; - KURL::List::Iterator sit = m_srcList.find( sourceUrl ); - if ( sit != m_srcList.end() ) - { - //kdDebug(7007) << "CopyJob::skip: removing " << sourceUrl << " from list" << endl; - m_srcList.remove( sit ); - } - dirsToRemove.remove( sourceUrl ); -} - -bool CopyJob::shouldOverwrite( const TQString& path ) const -{ - if ( m_bOverwriteAll ) - return true; - TQStringList::ConstIterator sit = m_overwriteList.begin(); - for( ; sit != m_overwriteList.end(); ++sit ) - if ( path.startsWith( *sit ) ) - return true; - return false; -} - -bool CopyJob::shouldSkip( const TQString& path ) const -{ - TQStringList::ConstIterator sit = m_skipList.begin(); - for( ; sit != m_skipList.end(); ++sit ) - if ( path.startsWith( *sit ) ) - return true; - return false; -} - -void CopyJob::slotResultCreatingDirs( Job * job ) -{ - // The dir we are trying to create: - TQValueList<CopyInfo>::Iterator it = dirs.begin(); - // Was there an error creating a dir ? - if ( job->error() ) - { - m_conflictError = job->error(); - if ( (m_conflictError == ERR_DIR_ALREADY_EXIST) - || (m_conflictError == ERR_FILE_ALREADY_EXIST) ) // can't happen? - { - KURL oldURL = ((SimpleJob*)job)->url(); - // Should we skip automatically ? - if ( m_bAutoSkip ) { - // We don't want to copy files in this directory, so we put it on the skip list - m_skipList.append( oldURL.path( 1 ) ); - skip( oldURL ); - dirs.remove( it ); // Move on to next dir - } else { - // Did the user choose to overwrite already? - const TQString destFile = (*it).uDest.path(); - if ( shouldOverwrite( destFile ) ) { // overwrite => just skip - emit copyingDone( this, ( *it ).uSource, ( *it ).uDest, true /* directory */, false /* renamed */ ); - dirs.remove( it ); // Move on to next dir - } else { - if ( !isInteractive() ) { - Job::slotResult( job ); // will set the error and emit result(this) - return; - } - - assert( ((SimpleJob*)job)->url().url() == (*it).uDest.url() ); - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); // We should have only one job at a time ... - - // We need to stat the existing dir, to get its last-modification time - KURL existingDest( (*it).uDest ); - SimpleJob * newJob = TDEIO::stat( existingDest, false, 2, false ); - Scheduler::scheduleJob(newJob); - kdDebug(7007) << "TDEIO::stat for resolving conflict on " << existingDest << endl; - state = STATE_CONFLICT_CREATING_DIRS; - addSubjob(newJob); - return; // Don't move to next dir yet ! - } - } - } - else - { - // Severe error, abort - Job::slotResult( job ); // will set the error and emit result(this) - return; - } - } - else // no error : remove from list, to move on to next dir - { - //this is required for the undo feature - emit copyingDone( this, (*it).uSource, (*it).uDest, true, false ); - d->m_directoriesCopied.append( *it ); - dirs.remove( it ); - } - - m_processedDirs++; - //emit processedDirs( this, m_processedDirs ); - subjobs.remove( job ); - assert( subjobs.isEmpty() ); // We should have only one job at a time ... - createNextDir(); -} - -void CopyJob::slotResultConflictCreatingDirs( TDEIO::Job * job ) -{ - // We come here after a conflict has been detected and we've stated the existing dir - - // The dir we were trying to create: - TQValueList<CopyInfo>::Iterator it = dirs.begin(); - // Its modification time: - time_t destmtime = (time_t)-1; - time_t destctime = (time_t)-1; - TDEIO::filesize_t destsize = 0; - TQString linkDest; - - UDSEntry entry = ((TDEIO::StatJob*)job)->statResult(); - TDEIO::UDSEntry::ConstIterator it2 = entry.begin(); - for( ; it2 != entry.end(); it2++ ) { - switch ((*it2).m_uds) { - case UDS_MODIFICATION_TIME: - destmtime = (time_t)((*it2).m_long); - break; - case UDS_CREATION_TIME: - destctime = (time_t)((*it2).m_long); - break; - case UDS_SIZE: - destsize = (*it2).m_long; - break; - case UDS_LINK_DEST: - linkDest = (*it2).m_str; - break; - } - } - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); // We should have only one job at a time ... - - // Always multi and skip (since there are files after that) - RenameDlg_Mode mode = (RenameDlg_Mode)( M_MULTI | M_SKIP ); - // Overwrite only if the existing thing is a dir (no chance with a file) - if ( m_conflictError == ERR_DIR_ALREADY_EXIST ) - { - if( (*it).uSource == (*it).uDest || - ((*it).uSource.protocol() == (*it).uDest.protocol() && - (*it).uSource.path(-1) == linkDest) ) - mode = (RenameDlg_Mode)( mode | M_OVERWRITE_ITSELF); - else - mode = (RenameDlg_Mode)( mode | M_OVERWRITE ); - } - - TQString existingDest = (*it).uDest.path(); - TQString newPath; - if (m_reportTimer) - m_reportTimer->stop(); - RenameDlg_Result r = Observer::self()->open_RenameDlg( this, i18n("Folder Already Exists"), - (*it).uSource.url(), - (*it).uDest.url(), - mode, newPath, - (*it).size, destsize, - (*it).ctime, destctime, - (*it).mtime, destmtime ); - if (m_reportTimer) - m_reportTimer->start(REPORT_TIMEOUT,false); - switch ( r ) { - case R_CANCEL: - m_error = ERR_USER_CANCELED; - emitResult(); - return; - case R_RENAME: - { - TQString oldPath = (*it).uDest.path( 1 ); - KURL newUrl( (*it).uDest ); - newUrl.setPath( newPath ); - emit renamed( this, (*it).uDest, newUrl ); // for e.g. kpropsdlg - - // Change the current one and strip the trailing '/' - (*it).uDest.setPath( newUrl.path( -1 ) ); - newPath = newUrl.path( 1 ); // With trailing slash - TQValueList<CopyInfo>::Iterator renamedirit = it; - ++renamedirit; - // Change the name of subdirectories inside the directory - for( ; renamedirit != dirs.end() ; ++renamedirit ) - { - TQString path = (*renamedirit).uDest.path(); - if ( path.left(oldPath.length()) == oldPath ) { - TQString n = path; - n.replace( 0, oldPath.length(), newPath ); - kdDebug(7007) << "dirs list: " << (*renamedirit).uSource.path() - << " was going to be " << path - << ", changed into " << n << endl; - (*renamedirit).uDest.setPath( n ); - } - } - // Change filenames inside the directory - TQValueList<CopyInfo>::Iterator renamefileit = files.begin(); - for( ; renamefileit != files.end() ; ++renamefileit ) - { - TQString path = (*renamefileit).uDest.path(); - if ( path.left(oldPath.length()) == oldPath ) { - TQString n = path; - n.replace( 0, oldPath.length(), newPath ); - kdDebug(7007) << "files list: " << (*renamefileit).uSource.path() - << " was going to be " << path - << ", changed into " << n << endl; - (*renamefileit).uDest.setPath( n ); - } - } - if (!dirs.isEmpty()) - emit aboutToCreate( this, dirs ); - if (!files.isEmpty()) - emit aboutToCreate( this, files ); - } - break; - case R_AUTO_SKIP: - m_bAutoSkip = true; - // fall through - case R_SKIP: - m_skipList.append( existingDest ); - skip( (*it).uSource ); - // Move on to next dir - dirs.remove( it ); - m_processedDirs++; - break; - case R_OVERWRITE: - m_overwriteList.append( existingDest ); - emit copyingDone( this, ( *it ).uSource, ( *it ).uDest, true /* directory */, false /* renamed */ ); - // Move on to next dir - dirs.remove( it ); - m_processedDirs++; - break; - case R_OVERWRITE_ALL: - m_bOverwriteAll = true; - emit copyingDone( this, ( *it ).uSource, ( *it ).uDest, true /* directory */, false /* renamed */ ); - // Move on to next dir - dirs.remove( it ); - m_processedDirs++; - break; - default: - assert( 0 ); - } - state = STATE_CREATING_DIRS; - //emit processedDirs( this, m_processedDirs ); - createNextDir(); -} - -void CopyJob::createNextDir() -{ - KURL udir; - if ( !dirs.isEmpty() ) - { - // Take first dir to create out of list - TQValueList<CopyInfo>::Iterator it = dirs.begin(); - // Is this URL on the skip list or the overwrite list ? - while( it != dirs.end() && udir.isEmpty() ) - { - const TQString dir = (*it).uDest.path(); - if ( shouldSkip( dir ) ) { - dirs.remove( it ); - it = dirs.begin(); - } else - udir = (*it).uDest; - } - } - if ( !udir.isEmpty() ) // any dir to create, finally ? - { - // Create the directory - with default permissions so that we can put files into it - // TODO : change permissions once all is finished; but for stuff coming from CDROM it sucks... - TDEIO::SimpleJob *newjob = TDEIO::mkdir( udir, -1 ); - Scheduler::scheduleJob(newjob); - - m_currentDestURL = udir; - d->m_bURLDirty = true; - - addSubjob(newjob); - return; - } - else // we have finished creating dirs - { - emit processedDirs( this, m_processedDirs ); // make sure final number appears - if (m_progressId) Observer::self()->slotProcessedDirs( this, m_processedDirs ); - - state = STATE_COPYING_FILES; - m_processedFiles++; // Ralf wants it to start at 1, not 0 - copyNextFile(); - } -} - -void CopyJob::slotResultCopyingFiles( Job * job ) -{ - // The file we were trying to copy: - TQValueList<CopyInfo>::Iterator it = files.begin(); - if ( job->error() ) - { - // Should we skip automatically ? - if ( m_bAutoSkip ) - { - skip( (*it).uSource ); - m_fileProcessedSize = (*it).size; - files.remove( it ); // Move on to next file - } - else - { - if ( !isInteractive() ) { - Job::slotResult( job ); // will set the error and emit result(this) - return; - } - - m_conflictError = job->error(); // save for later - // Existing dest ? - if ( ( m_conflictError == ERR_FILE_ALREADY_EXIST ) - || ( m_conflictError == ERR_DIR_ALREADY_EXIST ) - || ( m_conflictError == ERR_IDENTICAL_FILES ) ) - { - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); - // We need to stat the existing file, to get its last-modification time - KURL existingFile( (*it).uDest ); - SimpleJob * newJob = TDEIO::stat( existingFile, false, 2, false ); - Scheduler::scheduleJob(newJob); - kdDebug(7007) << "TDEIO::stat for resolving conflict on " << existingFile << endl; - state = STATE_CONFLICT_COPYING_FILES; - addSubjob(newJob); - return; // Don't move to next file yet ! - } - else - { - if ( m_bCurrentOperationIsLink && ::tqqt_cast<TDEIO::DeleteJob*>( job ) ) - { - // Very special case, see a few lines below - // We are deleting the source of a symlink we successfully moved... ignore error - m_fileProcessedSize = (*it).size; - files.remove( it ); - } else { - // Go directly to the conflict resolution, there is nothing to stat - slotResultConflictCopyingFiles( job ); - return; - } - } - } - } else // no error - { - // Special case for moving links. That operation needs two jobs, unlike others. - if ( m_bCurrentOperationIsLink && m_mode == Move - && !::tqqt_cast<TDEIO::DeleteJob *>( job ) // Deleting source not already done - ) - { - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); - // The only problem with this trick is that the error handling for this del operation - // is not going to be right... see 'Very special case' above. - TDEIO::Job * newjob = TDEIO::del( (*it).uSource, false /*don't shred*/, false /*no GUI*/ ); - addSubjob( newjob ); - return; // Don't move to next file yet ! - } - - if ( m_bCurrentOperationIsLink ) - { - TQString target = ( m_mode == Link ? (*it).uSource.path() : (*it).linkDest ); - //required for the undo feature - emit copyingLinkDone( this, (*it).uSource, target, (*it).uDest ); - } - else - //required for the undo feature - emit copyingDone( this, (*it).uSource, (*it).uDest, false, false ); - // remove from list, to move on to next file - files.remove( it ); - } - m_processedFiles++; - - // clear processed size for last file and add it to overall processed size - m_processedSize += m_fileProcessedSize; - m_fileProcessedSize = 0; - - //kdDebug(7007) << files.count() << " files remaining" << endl; - - removeSubjob( job, true, false ); // merge metadata - assert ( subjobs.isEmpty() ); // We should have only one job at a time ... - copyNextFile(); -} - -void CopyJob::slotResultConflictCopyingFiles( TDEIO::Job * job ) -{ - // We come here after a conflict has been detected and we've stated the existing file - // The file we were trying to create: - TQValueList<CopyInfo>::Iterator it = files.begin(); - - RenameDlg_Result res; - TQString newPath; - - if (m_reportTimer) - m_reportTimer->stop(); - - if ( ( m_conflictError == ERR_FILE_ALREADY_EXIST ) - || ( m_conflictError == ERR_DIR_ALREADY_EXIST ) - || ( m_conflictError == ERR_IDENTICAL_FILES ) ) - { - // Its modification time: - time_t destmtime = (time_t)-1; - time_t destctime = (time_t)-1; - TDEIO::filesize_t destsize = 0; - TQString linkDest; - UDSEntry entry = ((TDEIO::StatJob*)job)->statResult(); - TDEIO::UDSEntry::ConstIterator it2 = entry.begin(); - for( ; it2 != entry.end(); it2++ ) { - switch ((*it2).m_uds) { - case UDS_MODIFICATION_TIME: - destmtime = (time_t)((*it2).m_long); - break; - case UDS_CREATION_TIME: - destctime = (time_t)((*it2).m_long); - break; - case UDS_SIZE: - destsize = (*it2).m_long; - break; - case UDS_LINK_DEST: - linkDest = (*it2).m_str; - break; - } - } - - // Offer overwrite only if the existing thing is a file - // If src==dest, use "overwrite-itself" - RenameDlg_Mode mode; - bool isDir = true; - - if( m_conflictError == ERR_DIR_ALREADY_EXIST ) - mode = (RenameDlg_Mode) 0; - else - { - if ( (*it).uSource == (*it).uDest || - ((*it).uSource.protocol() == (*it).uDest.protocol() && - (*it).uSource.path(-1) == linkDest) ) - mode = M_OVERWRITE_ITSELF; - else - mode = M_OVERWRITE; - isDir = false; - } - - if ( m_bSingleFileCopy ) - mode = (RenameDlg_Mode) ( mode | M_SINGLE ); - else - mode = (RenameDlg_Mode) ( mode | M_MULTI | M_SKIP ); - - res = Observer::self()->open_RenameDlg( this, !isDir ? - i18n("File Already Exists") : i18n("Already Exists as Folder"), - (*it).uSource.url(), - (*it).uDest.url(), - mode, newPath, - (*it).size, destsize, - (*it).ctime, destctime, - (*it).mtime, destmtime ); - - } - else - { - if ( job->error() == ERR_USER_CANCELED ) - res = R_CANCEL; - else if ( !isInteractive() ) { - Job::slotResult( job ); // will set the error and emit result(this) - return; - } - else - { - SkipDlg_Result skipResult = Observer::self()->open_SkipDlg( this, files.count() > 1, - job->errorString() ); - - // Convert the return code from SkipDlg into a RenameDlg code - res = ( skipResult == S_SKIP ) ? R_SKIP : - ( skipResult == S_AUTO_SKIP ) ? R_AUTO_SKIP : - R_CANCEL; - } - } - - if (m_reportTimer) - m_reportTimer->start(REPORT_TIMEOUT,false); - - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); - switch ( res ) { - case R_CANCEL: - m_error = ERR_USER_CANCELED; - emitResult(); - return; - case R_RENAME: - { - KURL newUrl( (*it).uDest ); - newUrl.setPath( newPath ); - emit renamed( this, (*it).uDest, newUrl ); // for e.g. kpropsdlg - (*it).uDest = newUrl; - - TQValueList<CopyInfo> files; - files.append(*it); - emit aboutToCreate( this, files ); - } - break; - case R_AUTO_SKIP: - m_bAutoSkip = true; - // fall through - case R_SKIP: - // Move on to next file - skip( (*it).uSource ); - m_processedSize += (*it).size; - files.remove( it ); - m_processedFiles++; - break; - case R_OVERWRITE_ALL: - m_bOverwriteAll = true; - break; - case R_OVERWRITE: - // Add to overwrite list, so that copyNextFile knows to overwrite - m_overwriteList.append( (*it).uDest.path() ); - break; - default: - assert( 0 ); - } - state = STATE_COPYING_FILES; - //emit processedFiles( this, m_processedFiles ); - copyNextFile(); -} - -void CopyJob::copyNextFile() -{ - bool bCopyFile = false; - //kdDebug(7007) << "CopyJob::copyNextFile()" << endl; - // Take the first file in the list - TQValueList<CopyInfo>::Iterator it = files.begin(); - // Is this URL on the skip list ? - while (it != files.end() && !bCopyFile) - { - const TQString destFile = (*it).uDest.path(); - bCopyFile = !shouldSkip( destFile ); - if ( !bCopyFile ) { - files.remove( it ); - it = files.begin(); - } - } - - if (bCopyFile) // any file to create, finally ? - { - // Do we set overwrite ? - bool bOverwrite; - const TQString destFile = (*it).uDest.path(); - kdDebug(7007) << "copying " << destFile << endl; - if ( (*it).uDest == (*it).uSource ) - bOverwrite = false; - else - bOverwrite = shouldOverwrite( destFile ); - - m_bCurrentOperationIsLink = false; - TDEIO::Job * newjob = 0L; - if ( m_mode == Link ) - { - //kdDebug(7007) << "Linking" << endl; - if ( - ((*it).uSource.protocol() == (*it).uDest.protocol()) && - ((*it).uSource.host() == (*it).uDest.host()) && - ((*it).uSource.port() == (*it).uDest.port()) && - ((*it).uSource.user() == (*it).uDest.user()) && - ((*it).uSource.pass() == (*it).uDest.pass()) ) - { - // This is the case of creating a real symlink - TDEIO::SimpleJob *newJob = TDEIO::symlink( (*it).uSource.path(), (*it).uDest, bOverwrite, false /*no GUI*/ ); - newjob = newJob; - Scheduler::scheduleJob(newJob); - //kdDebug(7007) << "CopyJob::copyNextFile : Linking target=" << (*it).uSource.path() << " link=" << (*it).uDest << endl; - //emit linking( this, (*it).uSource.path(), (*it).uDest ); - m_bCurrentOperationIsLink = true; - m_currentSrcURL=(*it).uSource; - m_currentDestURL=(*it).uDest; - d->m_bURLDirty = true; - //Observer::self()->slotCopying( this, (*it).uSource, (*it).uDest ); // should be slotLinking perhaps - } else { - //kdDebug(7007) << "CopyJob::copyNextFile : Linking URL=" << (*it).uSource << " link=" << (*it).uDest << endl; - if ( (*it).uDest.isLocalFile() ) - { - bool devicesOk=false; - - // if the source is a devices url, handle it a littlebit special - if ((*it).uSource.protocol()==TQString::fromLatin1("devices")) - { - TQByteArray data; - TQByteArray param; - TQCString retType; - TQDataStream streamout(param,IO_WriteOnly); - streamout<<(*it).uSource; - streamout<<(*it).uDest; - if ( kapp && kapp->dcopClient()->call( "kded", - "mountwatcher", "createLink(KURL, KURL)", param,retType,data,false ) ) - { - TQDataStream streamin(data,IO_ReadOnly); - streamin>>devicesOk; - } - if (devicesOk) - { - files.remove( it ); - m_processedFiles++; - //emit processedFiles( this, m_processedFiles ); - copyNextFile(); - return; - } - } - - if (!devicesOk) - { - TQString path = (*it).uDest.path(); - //kdDebug(7007) << "CopyJob::copyNextFile path=" << path << endl; - TQFile f( path ); - if ( f.open( IO_ReadWrite ) ) - { - f.close(); - KSimpleConfig config( path ); - config.setDesktopGroup(); - KURL url = (*it).uSource; - url.setPass( "" ); - config.writePathEntry( TQString::fromLatin1("URL"), url.url() ); - config.writeEntry( TQString::fromLatin1("Name"), url.url() ); - config.writeEntry( TQString::fromLatin1("Type"), TQString::fromLatin1("Link") ); - TQString protocol = (*it).uSource.protocol(); - if ( protocol == TQString::fromLatin1("ftp") ) - config.writeEntry( TQString::fromLatin1("Icon"), TQString::fromLatin1("ftp") ); - else if ( protocol == TQString::fromLatin1("http") ) - config.writeEntry( TQString::fromLatin1("Icon"), TQString::fromLatin1("www") ); - else if ( protocol == TQString::fromLatin1("info") ) - config.writeEntry( TQString::fromLatin1("Icon"), TQString::fromLatin1("info") ); - else if ( protocol == TQString::fromLatin1("mailto") ) // sven: - config.writeEntry( TQString::fromLatin1("Icon"), TQString::fromLatin1("kmail") ); // added mailto: support - else - config.writeEntry( TQString::fromLatin1("Icon"), TQString::fromLatin1("unknown") ); - config.sync(); - files.remove( it ); - m_processedFiles++; - //emit processedFiles( this, m_processedFiles ); - copyNextFile(); - return; - } - else - { - kdDebug(7007) << "CopyJob::copyNextFile ERR_CANNOT_OPEN_FOR_WRITING" << endl; - m_error = ERR_CANNOT_OPEN_FOR_WRITING; - m_errorText = (*it).uDest.path(); - emitResult(); - return; - } - } - } else { - // Todo: not show "link" on remote dirs if the src urls are not from the same protocol+host+... - m_error = ERR_CANNOT_SYMLINK; - m_errorText = (*it).uDest.prettyURL(); - emitResult(); - return; - } - } - } - else if ( !(*it).linkDest.isEmpty() && - ((*it).uSource.protocol() == (*it).uDest.protocol()) && - ((*it).uSource.host() == (*it).uDest.host()) && - ((*it).uSource.port() == (*it).uDest.port()) && - ((*it).uSource.user() == (*it).uDest.user()) && - ((*it).uSource.pass() == (*it).uDest.pass())) - // Copying a symlink - only on the same protocol/host/etc. (#5601, downloading an FTP file through its link), - { - TDEIO::SimpleJob *newJob = TDEIO::symlink( (*it).linkDest, (*it).uDest, bOverwrite, false /*no GUI*/ ); - Scheduler::scheduleJob(newJob); - newjob = newJob; - //kdDebug(7007) << "CopyJob::copyNextFile : Linking target=" << (*it).linkDest << " link=" << (*it).uDest << endl; - //emit linking( this, (*it).linkDest, (*it).uDest ); - m_currentSrcURL=(*it).linkDest; - m_currentDestURL=(*it).uDest; - d->m_bURLDirty = true; - //Observer::self()->slotCopying( this, (*it).linkDest, (*it).uDest ); // should be slotLinking perhaps - m_bCurrentOperationIsLink = true; - // NOTE: if we are moving stuff, the deletion of the source will be done in slotResultCopyingFiles - } else if (m_mode == Move) // Moving a file - { - TDEIO::FileCopyJob * moveJob = TDEIO::file_move( (*it).uSource, (*it).uDest, (*it).permissions, bOverwrite, false, false/*no GUI*/ ); - moveJob->setSourceSize64( (*it).size ); - newjob = moveJob; - //kdDebug(7007) << "CopyJob::copyNextFile : Moving " << (*it).uSource << " to " << (*it).uDest << endl; - //emit moving( this, (*it).uSource, (*it).uDest ); - m_currentSrcURL=(*it).uSource; - m_currentDestURL=(*it).uDest; - d->m_bURLDirty = true; - //Observer::self()->slotMoving( this, (*it).uSource, (*it).uDest ); - } - else // Copying a file - { - // If source isn't local and target is local, we ignore the original permissions - // Otherwise, files downloaded from HTTP end up with -r--r--r-- - bool remoteSource = !KProtocolInfo::supportsListing((*it).uSource); - int permissions = (*it).permissions; - if ( d->m_defaultPermissions || ( remoteSource && (*it).uDest.isLocalFile() ) ) - permissions = -1; - TDEIO::FileCopyJob * copyJob = TDEIO::file_copy( (*it).uSource, (*it).uDest, permissions, bOverwrite, false, false/*no GUI*/ ); - copyJob->setParentJob( this ); // in case of rename dialog - copyJob->setSourceSize64( (*it).size ); - copyJob->setModificationTime( (*it).mtime ); - newjob = copyJob; - //kdDebug(7007) << "CopyJob::copyNextFile : Copying " << (*it).uSource << " to " << (*it).uDest << endl; - m_currentSrcURL=(*it).uSource; - m_currentDestURL=(*it).uDest; - d->m_bURLDirty = true; - } - addSubjob(newjob); - connect( newjob, TQT_SIGNAL( processedSize( TDEIO::Job*, TDEIO::filesize_t ) ), - this, TQT_SLOT( slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t ) ) ); - connect( newjob, TQT_SIGNAL( totalSize( TDEIO::Job*, TDEIO::filesize_t ) ), - this, TQT_SLOT( slotTotalSize( TDEIO::Job*, TDEIO::filesize_t ) ) ); - } - else - { - // We're done - //kdDebug(7007) << "copyNextFile finished" << endl; - deleteNextDir(); - } -} - -void CopyJob::deleteNextDir() -{ - if ( m_mode == Move && !dirsToRemove.isEmpty() ) // some dirs to delete ? - { - state = STATE_DELETING_DIRS; - d->m_bURLDirty = true; - // Take first dir to delete out of list - last ones first ! - KURL::List::Iterator it = dirsToRemove.fromLast(); - SimpleJob *job = TDEIO::rmdir( *it ); - Scheduler::scheduleJob(job); - dirsToRemove.remove(it); - addSubjob( job ); - } - else - { - // This step is done, move on - setNextDirAttribute(); - } -} - -void CopyJob::setNextDirAttribute() -{ - if ( !d->m_directoriesCopied.isEmpty() ) - { - state = STATE_SETTING_DIR_ATTRIBUTES; -#ifdef Q_OS_UNIX - // TODO KDE4: this should use a SlaveBase method, but we have none yet in KDE3. - TQValueList<CopyInfo>::Iterator it = d->m_directoriesCopied.begin(); - for ( ; it != d->m_directoriesCopied.end() ; ++it ) { - const KURL& url = (*it).uDest; - if ( url.isLocalFile() && (*it).mtime != (time_t)-1 ) { - const TQCString path = TQFile::encodeName( url.path() ); - KDE_struct_stat statbuf; - if (KDE_lstat(path, &statbuf) == 0) { - struct utimbuf utbuf; - utbuf.actime = statbuf.st_atime; // access time, unchanged - utbuf.modtime = (*it).mtime; // modification time - utime( path, &utbuf ); - } - - } - } -#endif - d->m_directoriesCopied.clear(); - } - - // No "else" here, since the above is a simple sync loop - - { - // Finished - tell the world - if ( !m_bOnlyRenames ) - { - KDirNotify_stub allDirNotify("*", "KDirNotify*"); - KURL url( d->m_globalDest ); - if ( d->m_globalDestinationState != DEST_IS_DIR || m_asMethod ) - url.setPath( url.directory() ); - //kdDebug(7007) << "KDirNotify'ing FilesAdded " << url << endl; - allDirNotify.FilesAdded( url ); - - if ( m_mode == Move && !m_srcList.isEmpty() ) { - //kdDebug(7007) << "KDirNotify'ing FilesRemoved " << m_srcList.toStringList() << endl; - allDirNotify.FilesRemoved( m_srcList ); - } - } - if (m_reportTimer) - m_reportTimer->stop(); - --m_processedFiles; // undo the "start at 1" hack - slotReport(); // display final numbers, important if progress dialog stays up - - emitResult(); - } -} - -void CopyJob::slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t data_size ) -{ - //kdDebug(7007) << "CopyJob::slotProcessedSize " << data_size << endl; - m_fileProcessedSize = data_size; - setProcessedSize(m_processedSize + m_fileProcessedSize); - - if ( m_processedSize + m_fileProcessedSize > m_totalSize ) - { - m_totalSize = m_processedSize + m_fileProcessedSize; - //kdDebug(7007) << "Adjusting m_totalSize to " << m_totalSize << endl; - emit totalSize( this, m_totalSize ); // safety - } - //kdDebug(7007) << "emit processedSize " << (unsigned long) (m_processedSize + m_fileProcessedSize) << endl; - emit processedSize( this, m_processedSize + m_fileProcessedSize ); - emitPercent( m_processedSize + m_fileProcessedSize, m_totalSize ); -} - -void CopyJob::slotTotalSize( TDEIO::Job*, TDEIO::filesize_t size ) -{ - //kdDebug(7007) << "slotTotalSize: " << size << endl; - // Special case for copying a single file - // This is because some protocols don't implement stat properly - // (e.g. HTTP), and don't give us a size in some cases (redirection) - // so we'd rather rely on the size given for the transfer - if ( m_bSingleFileCopy && size > m_totalSize) - { - //kdDebug(7007) << "slotTotalSize: updating totalsize to " << size << endl; - m_totalSize = size; - emit totalSize( this, size ); - } -} - -void CopyJob::slotResultDeletingDirs( Job * job ) -{ - if (job->error()) - { - // Couldn't remove directory. Well, perhaps it's not empty - // because the user pressed Skip for a given file in it. - // Let's not display "Could not remove dir ..." for each of those dir ! - } - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); - deleteNextDir(); -} - -#if 0 // TODO KDE4 -void CopyJob::slotResultSettingDirAttributes( Job * job ) -{ - if (job->error()) - { - // Couldn't set directory attributes. Ignore the error, it can happen - // with inferior file systems like VFAT. - // Let's not display warnings for each dir like "cp -a" does. - } - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); - setNextDirAttribute(); -} -#endif - -void CopyJob::slotResultRenaming( Job* job ) -{ - int err = job->error(); - const TQString errText = job->errorText(); - removeSubjob( job, true, false ); // merge metadata - assert ( subjobs.isEmpty() ); - // Determine dest again - KURL dest = m_dest; - if ( destinationState == DEST_IS_DIR && !m_asMethod ) - dest.addPath( m_currentSrcURL.fileName() ); - if ( err ) - { - // Direct renaming didn't work. Try renaming to a temp name, - // this can help e.g. when renaming 'a' to 'A' on a VFAT partition. - // In that case it's the _same_ dir, we don't want to copy+del (data loss!) - if ( m_currentSrcURL.isLocalFile() && m_currentSrcURL.url(-1) != dest.url(-1) && - m_currentSrcURL.url(-1).lower() == dest.url(-1).lower() && - ( err == ERR_FILE_ALREADY_EXIST || - err == ERR_DIR_ALREADY_EXIST || - err == ERR_IDENTICAL_FILES ) ) - { - kdDebug(7007) << "Couldn't rename directly, dest already exists. Detected special case of lower/uppercase renaming in same dir, try with 2 rename calls" << endl; - TQCString _src( TQFile::encodeName(m_currentSrcURL.path()) ); - TQCString _dest( TQFile::encodeName(dest.path()) ); - KTempFile tmpFile( m_currentSrcURL.directory(false) ); - TQCString _tmp( TQFile::encodeName(tmpFile.name()) ); - kdDebug(7007) << "CopyJob::slotResult KTempFile status:" << tmpFile.status() << " using " << _tmp << " as intermediary" << endl; - tmpFile.unlink(); - if ( ::rename( _src, _tmp ) == 0 ) - { - if ( !TQFile::exists( _dest ) && ::rename( _tmp, _dest ) == 0 ) - { - kdDebug(7007) << "Success." << endl; - err = 0; - } - else - { - // Revert back to original name! - if ( ::rename( _tmp, _src ) != 0 ) { - kdError(7007) << "Couldn't rename " << tmpFile.name() << " back to " << _src << " !" << endl; - // Severe error, abort - Job::slotResult( job ); // will set the error and emit result(this) - return; - } - } - } - } - } - if ( err ) - { - // This code is similar to CopyJob::slotResultConflictCopyingFiles - // but here it's about the base src url being moved/renamed - // (*m_currentStatSrc) and its dest (m_dest), not about a single file. - // It also means we already stated the dest, here. - // On the other hand we haven't stated the src yet (we skipped doing it - // to save time, since it's not necessary to rename directly!)... - - Q_ASSERT( m_currentSrcURL == *m_currentStatSrc ); - - // Existing dest? - if ( ( err == ERR_DIR_ALREADY_EXIST || - err == ERR_FILE_ALREADY_EXIST || - err == ERR_IDENTICAL_FILES ) - && isInteractive() ) - { - if (m_reportTimer) - m_reportTimer->stop(); - - // Should we skip automatically ? - if ( m_bAutoSkip ) { - // Move on to next file - skipSrc(); - return; - } else if ( m_bOverwriteAll ) { - ; // nothing to do, stat+copy+del will overwrite - } else { - TQString newPath; - // If src==dest, use "overwrite-itself" - RenameDlg_Mode mode = (RenameDlg_Mode) - ( ( m_currentSrcURL == dest ) ? M_OVERWRITE_ITSELF : M_OVERWRITE ); - - if ( m_srcList.count() > 1 ) - mode = (RenameDlg_Mode) ( mode | M_MULTI | M_SKIP ); - else - mode = (RenameDlg_Mode) ( mode | M_SINGLE ); - - // we lack mtime info for both the src (not stated) - // and the dest (stated but this info wasn't stored) - // Let's do it for local files, at least - TDEIO::filesize_t sizeSrc = (TDEIO::filesize_t) -1; - TDEIO::filesize_t sizeDest = (TDEIO::filesize_t) -1; - time_t ctimeSrc = (time_t) -1; - time_t ctimeDest = (time_t) -1; - time_t mtimeSrc = (time_t) -1; - time_t mtimeDest = (time_t) -1; - - KDE_struct_stat stat_buf; - if ( m_currentSrcURL.isLocalFile() && - KDE_stat(TQFile::encodeName(m_currentSrcURL.path()), &stat_buf) == 0 ) { - sizeSrc = stat_buf.st_size; - ctimeSrc = stat_buf.st_ctime; - mtimeSrc = stat_buf.st_mtime; - } - if ( dest.isLocalFile() && - KDE_stat(TQFile::encodeName(dest.path()), &stat_buf) == 0 ) { - sizeDest = stat_buf.st_size; - ctimeDest = stat_buf.st_ctime; - mtimeDest = stat_buf.st_mtime; - } - - RenameDlg_Result r = Observer::self()->open_RenameDlg( - this, - err != ERR_DIR_ALREADY_EXIST ? i18n("File Already Exists") : i18n("Already Exists as Folder"), - m_currentSrcURL.url(), - dest.url(), - mode, newPath, - sizeSrc, sizeDest, - ctimeSrc, ctimeDest, - mtimeSrc, mtimeDest ); - if (m_reportTimer) - m_reportTimer->start(REPORT_TIMEOUT,false); - - switch ( r ) - { - case R_CANCEL: - { - m_error = ERR_USER_CANCELED; - emitResult(); - return; - } - case R_RENAME: - { - // Set m_dest to the chosen destination - // This is only for this src url; the next one will revert to d->m_globalDest - m_dest.setPath( newPath ); - TDEIO::Job* job = TDEIO::stat( m_dest, false, 2, false ); - state = STATE_STATING; - destinationState = DEST_NOT_STATED; - addSubjob(job); - return; - } - case R_AUTO_SKIP: - m_bAutoSkip = true; - // fall through - case R_SKIP: - // Move on to next file - skipSrc(); - return; - case R_OVERWRITE_ALL: - m_bOverwriteAll = true; - break; - case R_OVERWRITE: - // Add to overwrite list - // Note that we add dest, not m_dest. - // This ensures that when moving several urls into a dir (m_dest), - // we only overwrite for the current one, not for all. - // When renaming a single file (m_asMethod), it makes no difference. - kdDebug(7007) << "adding to overwrite list: " << dest.path() << endl; - m_overwriteList.append( dest.path() ); - break; - default: - //assert( 0 ); - break; - } - } - } else if ( err != TDEIO::ERR_UNSUPPORTED_ACTION ) { - kdDebug(7007) << "Couldn't rename " << m_currentSrcURL << " to " << dest << ", aborting" << endl; - m_error = err; - m_errorText = errText; - emitResult(); - return; - } - kdDebug(7007) << "Couldn't rename " << m_currentSrcURL << " to " << dest << ", reverting to normal way, starting with stat" << endl; - //kdDebug(7007) << "TDEIO::stat on " << m_currentSrcURL << endl; - TDEIO::Job* job = TDEIO::stat( m_currentSrcURL, true, 2, false ); - state = STATE_STATING; - addSubjob(job); - m_bOnlyRenames = false; - } - else - { - //kdDebug(7007) << "Renaming succeeded, move on" << endl; - emit copyingDone( this, *m_currentStatSrc, dest, true, true ); - statNextSrc(); - } -} - -void CopyJob::slotResult( Job *job ) -{ - //kdDebug(7007) << "CopyJob::slotResult() state=" << (int) state << endl; - // In each case, what we have to do is : - // 1 - check for errors and treat them - // 2 - subjobs.remove(job); - // 3 - decide what to do next - - switch ( state ) { - case STATE_STATING: // We were trying to stat a src url or the dest - slotResultStating( job ); - break; - case STATE_RENAMING: // We were trying to do a direct renaming, before even stat'ing - { - slotResultRenaming( job ); - break; - } - case STATE_LISTING: // recursive listing finished - //kdDebug(7007) << "totalSize: " << (unsigned int) m_totalSize << " files: " << files.count() << " dirs: " << dirs.count() << endl; - // Was there an error ? - if (job->error()) - { - Job::slotResult( job ); // will set the error and emit result(this) - return; - } - - subjobs.remove( job ); - assert ( subjobs.isEmpty() ); - - statNextSrc(); - break; - case STATE_CREATING_DIRS: - slotResultCreatingDirs( job ); - break; - case STATE_CONFLICT_CREATING_DIRS: - slotResultConflictCreatingDirs( job ); - break; - case STATE_COPYING_FILES: - slotResultCopyingFiles( job ); - break; - case STATE_CONFLICT_COPYING_FILES: - slotResultConflictCopyingFiles( job ); - break; - case STATE_DELETING_DIRS: - slotResultDeletingDirs( job ); - break; - case STATE_SETTING_DIR_ATTRIBUTES: // TODO KDE4 - assert( 0 ); - //slotResultSettingDirAttributes( job ); - break; - default: - assert( 0 ); - } -} - -void TDEIO::CopyJob::setDefaultPermissions( bool b ) -{ - d->m_defaultPermissions = b; -} - -// KDE4: remove -void TDEIO::CopyJob::setInteractive( bool b ) -{ - Job::setInteractive( b ); -} - -CopyJob *TDEIO::copy(const KURL& src, const KURL& dest, bool showProgressInfo ) -{ - //kdDebug(7007) << "TDEIO::copy src=" << src << " dest=" << dest << endl; - KURL::List srcList; - srcList.append( src ); - return new CopyJob( srcList, dest, CopyJob::Copy, false, showProgressInfo ); -} - -CopyJob *TDEIO::copyAs(const KURL& src, const KURL& dest, bool showProgressInfo ) -{ - //kdDebug(7007) << "TDEIO::copyAs src=" << src << " dest=" << dest << endl; - KURL::List srcList; - srcList.append( src ); - return new CopyJob( srcList, dest, CopyJob::Copy, true, showProgressInfo ); -} - -CopyJob *TDEIO::copy( const KURL::List& src, const KURL& dest, bool showProgressInfo ) -{ - //kdDebug(7007) << src << " " << dest << endl; - return new CopyJob( src, dest, CopyJob::Copy, false, showProgressInfo ); -} - -CopyJob *TDEIO::move(const KURL& src, const KURL& dest, bool showProgressInfo ) -{ - //kdDebug(7007) << src << " " << dest << endl; - KURL::List srcList; - srcList.append( src ); - return new CopyJob( srcList, dest, CopyJob::Move, false, showProgressInfo ); -} - -CopyJob *TDEIO::moveAs(const KURL& src, const KURL& dest, bool showProgressInfo ) -{ - //kdDebug(7007) << src << " " << dest << endl; - KURL::List srcList; - srcList.append( src ); - return new CopyJob( srcList, dest, CopyJob::Move, true, showProgressInfo ); -} - -CopyJob *TDEIO::move( const KURL::List& src, const KURL& dest, bool showProgressInfo ) -{ - //kdDebug(7007) << src << " " << dest << endl; - return new CopyJob( src, dest, CopyJob::Move, false, showProgressInfo ); -} - -CopyJob *TDEIO::link(const KURL& src, const KURL& destDir, bool showProgressInfo ) -{ - KURL::List srcList; - srcList.append( src ); - return new CopyJob( srcList, destDir, CopyJob::Link, false, showProgressInfo ); -} - -CopyJob *TDEIO::link(const KURL::List& srcList, const KURL& destDir, bool showProgressInfo ) -{ - return new CopyJob( srcList, destDir, CopyJob::Link, false, showProgressInfo ); -} - -CopyJob *TDEIO::linkAs(const KURL& src, const KURL& destDir, bool showProgressInfo ) -{ - KURL::List srcList; - srcList.append( src ); - return new CopyJob( srcList, destDir, CopyJob::Link, false, showProgressInfo ); -} - -CopyJob *TDEIO::trash(const KURL& src, bool showProgressInfo ) -{ - KURL::List srcList; - srcList.append( src ); - return new CopyJob( srcList, KURL( "trash:/" ), CopyJob::Move, false, showProgressInfo ); -} - -CopyJob *TDEIO::trash(const KURL::List& srcList, bool showProgressInfo ) -{ - return new CopyJob( srcList, KURL( "trash:/" ), CopyJob::Move, false, showProgressInfo ); -} - -////////// - -DeleteJob::DeleteJob( const KURL::List& src, bool /*shred*/, bool showProgressInfo ) -: Job(showProgressInfo), m_totalSize( 0 ), m_processedSize( 0 ), m_fileProcessedSize( 0 ), - m_processedFiles( 0 ), m_processedDirs( 0 ), m_totalFilesDirs( 0 ), - m_srcList(src), m_currentStat(m_srcList.begin()), m_reportTimer(0) -{ - if ( showProgressInfo ) { - - connect( this, TQT_SIGNAL( totalFiles( TDEIO::Job*, unsigned long ) ), - Observer::self(), TQT_SLOT( slotTotalFiles( TDEIO::Job*, unsigned long ) ) ); - - connect( this, TQT_SIGNAL( totalDirs( TDEIO::Job*, unsigned long ) ), - Observer::self(), TQT_SLOT( slotTotalDirs( TDEIO::Job*, unsigned long ) ) ); - - // See slotReport - /*connect( this, TQT_SIGNAL( processedFiles( TDEIO::Job*, unsigned long ) ), - m_observer, TQT_SLOT( slotProcessedFiles( TDEIO::Job*, unsigned long ) ) ); - - connect( this, TQT_SIGNAL( processedDirs( TDEIO::Job*, unsigned long ) ), - m_observer, TQT_SLOT( slotProcessedDirs( TDEIO::Job*, unsigned long ) ) ); - - connect( this, TQT_SIGNAL( deleting( TDEIO::Job*, const KURL& ) ), - m_observer, TQT_SLOT( slotDeleting( TDEIO::Job*, const KURL& ) ) );*/ - - m_reportTimer=new TQTimer(this); - connect(m_reportTimer,TQT_SIGNAL(timeout()),this,TQT_SLOT(slotReport())); - //this will update the report dialog with 5 Hz, I think this is fast enough, aleXXX - m_reportTimer->start(REPORT_TIMEOUT,false); - } - - TQTimer::singleShot(0, this, TQT_SLOT(slotStart())); -} - -void DeleteJob::slotStart() -{ - statNextSrc(); -} - -//this is called often, so calling the functions -//from Observer here directly might improve the performance a little bit -//aleXXX -void DeleteJob::slotReport() -{ - if (m_progressId==0) - return; - - Observer * observer = Observer::self(); - - emit deleting( this, m_currentURL ); - observer->slotDeleting(this,m_currentURL); - - switch( state ) { - case STATE_STATING: - case STATE_LISTING: - emit totalSize( this, m_totalSize ); - emit totalFiles( this, files.count() ); - emit totalDirs( this, dirs.count() ); - break; - case STATE_DELETING_DIRS: - emit processedDirs( this, m_processedDirs ); - observer->slotProcessedDirs(this,m_processedDirs); - emitPercent( m_processedFiles + m_processedDirs, m_totalFilesDirs ); - break; - case STATE_DELETING_FILES: - observer->slotProcessedFiles(this,m_processedFiles); - emit processedFiles( this, m_processedFiles ); - emitPercent( m_processedFiles, m_totalFilesDirs ); - break; - } -} - - -void DeleteJob::slotEntries(TDEIO::Job* job, const UDSEntryList& list) -{ - UDSEntryListConstIterator it = list.begin(); - UDSEntryListConstIterator end = list.end(); - for (; it != end; ++it) - { - UDSEntry::ConstIterator it2 = (*it).begin(); - bool bDir = false; - bool bLink = false; - TQString displayName; - KURL url; - int atomsFound(0); - for( ; it2 != (*it).end(); it2++ ) - { - switch ((*it2).m_uds) - { - case UDS_FILE_TYPE: - bDir = S_ISDIR((*it2).m_long); - atomsFound++; - break; - case UDS_NAME: - displayName = (*it2).m_str; - atomsFound++; - break; - case UDS_URL: - url = KURL((*it2).m_str); - atomsFound++; - break; - case UDS_LINK_DEST: - bLink = !(*it2).m_str.isEmpty(); - atomsFound++; - break; - case UDS_SIZE: - m_totalSize += (TDEIO::filesize_t)((*it2).m_long); - atomsFound++; - break; - default: - break; - } - if (atomsFound==5) break; - } - assert(!displayName.isEmpty()); - if (displayName != ".." && displayName != ".") - { - if( url.isEmpty() ) { - url = ((SimpleJob *)job)->url(); // assumed to be a dir - url.addPath( displayName ); - } - //kdDebug(7007) << "DeleteJob::slotEntries " << displayName << " (" << url << ")" << endl; - if ( bLink ) - symlinks.append( url ); - else if ( bDir ) - dirs.append( url ); - else - files.append( url ); - } - } -} - - -void DeleteJob::statNextSrc() -{ - //kdDebug(7007) << "statNextSrc" << endl; - if ( m_currentStat != m_srcList.end() ) - { - m_currentURL = (*m_currentStat); - - // if the file system doesn't support deleting, we do not even stat - if (!KProtocolInfo::supportsDeleting(m_currentURL)) { - TQGuardedPtr<DeleteJob> that = this; - ++m_currentStat; - if (isInteractive()) - KMessageBox::information( 0, buildErrorString(ERR_CANNOT_DELETE, m_currentURL.prettyURL())); - if (that) - statNextSrc(); - return; - } - // Stat it - state = STATE_STATING; - TDEIO::SimpleJob * job = TDEIO::stat( m_currentURL, true, 1, false ); - Scheduler::scheduleJob(job); - //kdDebug(7007) << "TDEIO::stat (DeleteJob) " << m_currentURL << endl; - addSubjob(job); - //if ( m_progressId ) // Did we get an ID from the observer ? - // Observer::self()->slotDeleting( this, *it ); // show asap - } else - { - m_totalFilesDirs = files.count()+symlinks.count() + dirs.count(); - slotReport(); - // Now we know which dirs hold the files we're going to delete. - // To speed things up and prevent double-notification, we disable KDirWatch - // on those dirs temporarily (using KDirWatch::self, that's the instanced - // used by e.g. kdirlister). - for ( TQStringList::Iterator it = m_parentDirs.begin() ; it != m_parentDirs.end() ; ++it ) - KDirWatch::self()->stopDirScan( *it ); - state = STATE_DELETING_FILES; - deleteNextFile(); - } -} - -void DeleteJob::deleteNextFile() -{ - //kdDebug(7007) << "deleteNextFile" << endl; - if ( !files.isEmpty() || !symlinks.isEmpty() ) - { - SimpleJob *job; - do { - // Take first file to delete out of list - KURL::List::Iterator it = files.begin(); - bool isLink = false; - if ( it == files.end() ) // No more files - { - it = symlinks.begin(); // Pick up a symlink to delete - isLink = true; - } - // Normal deletion - // If local file, try do it directly - if ( (*it).isLocalFile() && unlink( TQFile::encodeName((*it).path()) ) == 0 ) { - //kdDebug(7007) << "DeleteJob deleted " << (*it).path() << endl; - job = 0; - m_processedFiles++; - if ( m_processedFiles % 300 == 0 || m_totalFilesDirs < 300) { // update progress info every 300 files - m_currentURL = *it; - slotReport(); - } - } else - { // if remote - or if unlink() failed (we'll use the job's error handling in that case) - job = TDEIO::file_delete( *it, false /*no GUI*/); - Scheduler::scheduleJob(job); - m_currentURL=(*it); - } - if ( isLink ) - symlinks.remove(it); - else - files.remove(it); - if ( job ) { - addSubjob(job); - return; - } - // loop only if direct deletion worked (job=0) and there is something else to delete - } while (!job && (!files.isEmpty() || !symlinks.isEmpty())); - } - state = STATE_DELETING_DIRS; - deleteNextDir(); -} - -void DeleteJob::deleteNextDir() -{ - if ( !dirs.isEmpty() ) // some dirs to delete ? - { - do { - // Take first dir to delete out of list - last ones first ! - KURL::List::Iterator it = dirs.fromLast(); - // If local dir, try to rmdir it directly - if ( (*it).isLocalFile() && ::rmdir( TQFile::encodeName((*it).path()) ) == 0 ) { - - m_processedDirs++; - if ( m_processedDirs % 100 == 0 ) { // update progress info every 100 dirs - m_currentURL = *it; - slotReport(); - } - } else { - SimpleJob* job; - if ( KProtocolInfo::canDeleteRecursive( *it ) ) { - // If the ioslave supports recursive deletion of a directory, then - // we only need to send a single CMD_DEL command, so we use file_delete :) - job = TDEIO::file_delete( *it, false /*no gui*/ ); - } else { - job = TDEIO::rmdir( *it ); - } - Scheduler::scheduleJob(job); - dirs.remove(it); - addSubjob( job ); - return; - } - dirs.remove(it); - } while ( !dirs.isEmpty() ); - } - - // Re-enable watching on the dirs that held the deleted files - for ( TQStringList::Iterator it = m_parentDirs.begin() ; it != m_parentDirs.end() ; ++it ) - KDirWatch::self()->restartDirScan( *it ); - - // Finished - tell the world - if ( !m_srcList.isEmpty() ) - { - KDirNotify_stub allDirNotify("*", "KDirNotify*"); - //kdDebug(7007) << "KDirNotify'ing FilesRemoved " << m_srcList.toStringList() << endl; - allDirNotify.FilesRemoved( m_srcList ); - } - if (m_reportTimer!=0) - m_reportTimer->stop(); - emitResult(); -} - -void DeleteJob::slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t data_size ) -{ - // Note: this is the same implementation as CopyJob::slotProcessedSize but - // it's different from FileCopyJob::slotProcessedSize - which is why this - // is not in Job. - - m_fileProcessedSize = data_size; - setProcessedSize(m_processedSize + m_fileProcessedSize); - - //kdDebug(7007) << "DeleteJob::slotProcessedSize " << (unsigned int) (m_processedSize + m_fileProcessedSize) << endl; - - emit processedSize( this, m_processedSize + m_fileProcessedSize ); - - // calculate percents - unsigned long ipercent = m_percent; - - if ( m_totalSize == 0 ) - m_percent = 100; - else - m_percent = (unsigned long)(( (float)(m_processedSize + m_fileProcessedSize) / (float)m_totalSize ) * 100.0); - - if ( m_percent > ipercent ) - { - emit percent( this, m_percent ); - //kdDebug(7007) << "DeleteJob::slotProcessedSize - percent = " << (unsigned int) m_percent << endl; - } - -} - -void DeleteJob::slotResult( Job *job ) -{ - switch ( state ) - { - case STATE_STATING: - { - // Was there an error while stating ? - if (job->error() ) - { - // Probably : doesn't exist - Job::slotResult( job ); // will set the error and emit result(this) - return; - } - - // Is it a file or a dir ? - UDSEntry entry = ((StatJob*)job)->statResult(); - bool bDir = false; - bool bLink = false; - TDEIO::filesize_t size = (TDEIO::filesize_t)-1; - UDSEntry::ConstIterator it2 = entry.begin(); - int atomsFound(0); - for( ; it2 != entry.end(); it2++ ) - { - if ( ((*it2).m_uds) == UDS_FILE_TYPE ) - { - bDir = S_ISDIR( (mode_t)(*it2).m_long ); - atomsFound++; - } - else if ( ((*it2).m_uds) == UDS_LINK_DEST ) - { - bLink = !((*it2).m_str.isEmpty()); - atomsFound++; - } - else if ( ((*it2).m_uds) == UDS_SIZE ) - { - size = (*it2).m_long; - atomsFound++; - } - if (atomsFound==3) break; - } - - KURL url = ((SimpleJob*)job)->url(); - - subjobs.remove( job ); - assert( subjobs.isEmpty() ); - - if (bDir && !bLink) - { - // Add toplevel dir in list of dirs - dirs.append( url ); - if ( url.isLocalFile() && !m_parentDirs.contains( url.path(-1) ) ) - m_parentDirs.append( url.path(-1) ); - - if ( !KProtocolInfo::canDeleteRecursive( url ) ) { - //kdDebug(7007) << " Target is a directory " << endl; - // List it - state = STATE_LISTING; - ListJob *newjob = listRecursive( url, false ); - newjob->setUnrestricted(true); // No KIOSK restrictions - Scheduler::scheduleJob(newjob); - connect(newjob, TQT_SIGNAL(entries( TDEIO::Job *, - const TDEIO::UDSEntryList& )), - TQT_SLOT( slotEntries( TDEIO::Job*, - const TDEIO::UDSEntryList& ))); - addSubjob(newjob); - } else { - ++m_currentStat; - statNextSrc(); - } - } - else - { - if ( bLink ) { - //kdDebug(7007) << " Target is a symlink" << endl; - symlinks.append( url ); - } else { - //kdDebug(7007) << " Target is a file" << endl; - files.append( url ); - } - if ( url.isLocalFile() && !m_parentDirs.contains( url.directory(false) ) ) - m_parentDirs.append( url.directory(false) ); - ++m_currentStat; - statNextSrc(); - } - } - break; - case STATE_LISTING: - if ( job->error() ) - { - // Try deleting nonetheless, it may be empty (and non-listable) - } - subjobs.remove( job ); - assert( subjobs.isEmpty() ); - ++m_currentStat; - statNextSrc(); - break; - case STATE_DELETING_FILES: - if ( job->error() ) - { - Job::slotResult( job ); // will set the error and emit result(this) - return; - } - subjobs.remove( job ); - assert( subjobs.isEmpty() ); - m_processedFiles++; - - deleteNextFile(); - break; - case STATE_DELETING_DIRS: - if ( job->error() ) - { - Job::slotResult( job ); // will set the error and emit result(this) - return; - } - subjobs.remove( job ); - assert( subjobs.isEmpty() ); - m_processedDirs++; - //emit processedDirs( this, m_processedDirs ); - //if (!m_shred) - //emitPercent( m_processedFiles + m_processedDirs, m_totalFilesDirs ); - - deleteNextDir(); - break; - default: - assert(0); - } -} - -DeleteJob *TDEIO::del( const KURL& src, bool shred, bool showProgressInfo ) -{ - KURL::List srcList; - srcList.append( src ); - DeleteJob *job = new DeleteJob( srcList, shred, showProgressInfo ); - return job; -} - -DeleteJob *TDEIO::del( const KURL::List& src, bool shred, bool showProgressInfo ) -{ - DeleteJob *job = new DeleteJob( src, shred, showProgressInfo ); - return job; -} - -MultiGetJob::MultiGetJob(const KURL& url, - bool showProgressInfo) - : TransferJob(url, 0, TQByteArray(), TQByteArray(), showProgressInfo) -{ - m_waitQueue.setAutoDelete(true); - m_activeQueue.setAutoDelete(true); - m_currentEntry = 0; -} - -void MultiGetJob::get(long id, const KURL &url, const MetaData &metaData) -{ - GetRequest *entry = new GetRequest(id, url, metaData); - entry->metaData["request-id"] = TQString("%1").arg(id); - m_waitQueue.append(entry); -} - -void MultiGetJob::flushQueue(TQPtrList<GetRequest> &queue) -{ - GetRequest *entry; - // Use multi-get - // Scan all jobs in m_waitQueue - for(entry = m_waitQueue.first(); entry; ) - { - if ((m_url.protocol() == entry->url.protocol()) && - (m_url.host() == entry->url.host()) && - (m_url.port() == entry->url.port()) && - (m_url.user() == entry->url.user())) - { - m_waitQueue.take(); - queue.append(entry); - entry = m_waitQueue.current(); - } - else - { - entry = m_waitQueue.next(); - } - } - // Send number of URLs, (URL, metadata)* - KIO_ARGS << (TQ_INT32) queue.count(); - for(entry = queue.first(); entry; entry = queue.next()) - { - stream << entry->url << entry->metaData; - } - m_packedArgs = packedArgs; - m_command = CMD_MULTI_GET; - m_outgoingMetaData.clear(); -} - -void MultiGetJob::start(Slave *slave) -{ - // Add first job from m_waitQueue and add it to m_activeQueue - GetRequest *entry = m_waitQueue.take(0); - m_activeQueue.append(entry); - - m_url = entry->url; - - if (!entry->url.protocol().startsWith("http")) - { - // Use normal get - KIO_ARGS << entry->url; - m_packedArgs = packedArgs; - m_outgoingMetaData = entry->metaData; - m_command = CMD_GET; - b_multiGetActive = false; - } - else - { - flushQueue(m_activeQueue); - b_multiGetActive = true; - } - - TransferJob::start(slave); // Anything else to do?? -} - -bool MultiGetJob::findCurrentEntry() -{ - if (b_multiGetActive) - { - long id = m_incomingMetaData["request-id"].toLong(); - for(GetRequest *entry = m_activeQueue.first(); entry; entry = m_activeQueue.next()) - { - if (entry->id == id) - { - m_currentEntry = entry; - return true; - } - } - m_currentEntry = 0; - return false; - } - else - { - m_currentEntry = m_activeQueue.first(); - return (m_currentEntry != 0); - } -} - -void MultiGetJob::slotRedirection( const KURL &url) -{ - if (!findCurrentEntry()) return; // Error - if (kapp && !kapp->authorizeURLAction("redirect", m_url, url)) - { - kdWarning(7007) << "MultiGetJob: Redirection from " << m_currentEntry->url << " to " << url << " REJECTED!" << endl; - return; - } - m_redirectionURL = url; - if (m_currentEntry->url.hasUser() && !url.hasUser() && (m_currentEntry->url.host().lower() == url.host().lower())) - m_redirectionURL.setUser(m_currentEntry->url.user()); // Preserve user - get(m_currentEntry->id, m_redirectionURL, m_currentEntry->metaData); // Try again -} - - -void MultiGetJob::slotFinished() -{ - if (!findCurrentEntry()) return; - if (m_redirectionURL.isEmpty()) - { - // No redirection, tell the world that we are finished. - emit result(m_currentEntry->id); - } - m_redirectionURL = KURL(); - m_error = 0; - m_incomingMetaData.clear(); - m_activeQueue.removeRef(m_currentEntry); - if (m_activeQueue.count() == 0) - { - if (m_waitQueue.count() == 0) - { - // All done - TransferJob::slotFinished(); - } - else - { - // return slave to pool - // fetch new slave for first entry in m_waitQueue and call start - // again. - GetRequest *entry = m_waitQueue.at(0); - m_url = entry->url; - slaveDone(); - Scheduler::doJob(this); - } - } -} - -void MultiGetJob::slotData( const TQByteArray &_data) -{ - if(!m_currentEntry) return;// Error, unknown request! - if(m_redirectionURL.isEmpty() || !m_redirectionURL.isValid() || m_error) - emit data(m_currentEntry->id, _data); -} - -void MultiGetJob::slotMimetype( const TQString &_mimetype ) -{ - if (b_multiGetActive) - { - TQPtrList<GetRequest> newQueue; - flushQueue(newQueue); - if (!newQueue.isEmpty()) - { - while(!newQueue.isEmpty()) - m_activeQueue.append(newQueue.take(0)); - m_slave->send( m_command, m_packedArgs ); - } - } - if (!findCurrentEntry()) return; // Error, unknown request! - emit mimetype(m_currentEntry->id, _mimetype); -} - -MultiGetJob *TDEIO::multi_get(long id, const KURL &url, const MetaData &metaData) -{ - MultiGetJob * job = new MultiGetJob( url, false ); - job->get(id, url, metaData); - return job; -} - - -#ifdef CACHE_INFO -CacheInfo::CacheInfo(const KURL &url) -{ - m_url = url; -} - -TQString CacheInfo::cachedFileName() -{ - const TQChar separator = '_'; - - TQString CEF = m_url.path(); - - int p = CEF.find('/'); - - while(p != -1) - { - CEF[p] = separator; - p = CEF.find('/', p); - } - - TQString host = m_url.host().lower(); - CEF = host + CEF + '_'; - - TQString dir = KProtocolManager::cacheDir(); - if (dir[dir.length()-1] != '/') - dir += "/"; - - int l = m_url.host().length(); - for(int i = 0; i < l; i++) - { - if (host[i].isLetter() && (host[i] != 'w')) - { - dir += host[i]; - break; - } - } - if (dir[dir.length()-1] == '/') - dir += "0"; - - unsigned long hash = 0x00000000; - TQCString u = m_url.url().latin1(); - for(int i = u.length(); i--;) - { - hash = (hash * 12211 + u[i]) % 2147483563; - } - - TQString hashString; - hashString.sprintf("%08lx", hash); - - CEF = CEF + hashString; - - CEF = dir + "/" + CEF; - - return CEF; -} - -TQFile *CacheInfo::cachedFile() -{ -#ifdef Q_WS_WIN - const char *mode = (readWrite ? "rb+" : "rb"); -#else - const char *mode = (readWrite ? "r+" : "r"); -#endif - - FILE *fs = fopen(TQFile::encodeName(CEF), mode); // Open for reading and writing - if (!fs) - return 0; - - char buffer[401]; - bool ok = true; - - // CacheRevision - if (ok && (!fgets(buffer, 400, fs))) - ok = false; - if (ok && (strcmp(buffer, CACHE_REVISION) != 0)) - ok = false; - - time_t date; - time_t currentDate = time(0); - - // URL - if (ok && (!fgets(buffer, 400, fs))) - ok = false; - if (ok) - { - int l = strlen(buffer); - if (l>0) - buffer[l-1] = 0; // Strip newline - if (m_.url.url() != buffer) - { - ok = false; // Hash collision - } - } - - // Creation Date - if (ok && (!fgets(buffer, 400, fs))) - ok = false; - if (ok) - { - date = (time_t) strtoul(buffer, 0, 10); - if (m_maxCacheAge && (difftime(currentDate, date) > m_maxCacheAge)) - { - m_bMustRevalidate = true; - m_expireDate = currentDate; - } - } - - // Expiration Date - m_cacheExpireDateOffset = ftell(fs); - if (ok && (!fgets(buffer, 400, fs))) - ok = false; - if (ok) - { - if (m_request.cache == CC_Verify) - { - date = (time_t) strtoul(buffer, 0, 10); - // After the expire date we need to revalidate. - if (!date || difftime(currentDate, date) >= 0) - m_bMustRevalidate = true; - m_expireDate = date; - } - } - - // ETag - if (ok && (!fgets(buffer, 400, fs))) - ok = false; - if (ok) - { - m_etag = TQString(buffer).stripWhiteSpace(); - } - - // Last-Modified - if (ok && (!fgets(buffer, 400, fs))) - ok = false; - if (ok) - { - m_lastModified = TQString(buffer).stripWhiteSpace(); - } - - fclose(fs); - - if (ok) - return fs; - - unlink( TQFile::encodeName(CEF) ); - return 0; - -} - -void CacheInfo::flush() -{ - cachedFile().remove(); -} - -void CacheInfo::touch() -{ - -} -void CacheInfo::setExpireDate(int); -void CacheInfo::setExpireTimeout(int); - - -int CacheInfo::creationDate(); -int CacheInfo::expireDate(); -int CacheInfo::expireTimeout(); -#endif - -void Job::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -void SimpleJob::virtual_hook( int id, void* data ) -{ TDEIO::Job::virtual_hook( id, data ); } - -void MkdirJob::virtual_hook( int id, void* data ) -{ SimpleJob::virtual_hook( id, data ); } - -void StatJob::virtual_hook( int id, void* data ) -{ SimpleJob::virtual_hook( id, data ); } - -void TransferJob::virtual_hook( int id, void* data ) -{ SimpleJob::virtual_hook( id, data ); } - -void MultiGetJob::virtual_hook( int id, void* data ) -{ TransferJob::virtual_hook( id, data ); } - -void MimetypeJob::virtual_hook( int id, void* data ) -{ TransferJob::virtual_hook( id, data ); } - -void FileCopyJob::virtual_hook( int id, void* data ) -{ Job::virtual_hook( id, data ); } - -void ListJob::virtual_hook( int id, void* data ) -{ SimpleJob::virtual_hook( id, data ); } - -void CopyJob::virtual_hook( int id, void* data ) -{ Job::virtual_hook( id, data ); } - -void DeleteJob::virtual_hook( int id, void* data ) -{ Job::virtual_hook( id, data ); } - -void LocalURLJob::virtual_hook( int id, void* data ) -{ Job::virtual_hook( id, data ); } - - -#include "jobclasses.moc" diff --git a/kio/kio/job.h b/kio/kio/job.h deleted file mode 100644 index f5254df39..000000000 --- a/kio/kio/job.h +++ /dev/null @@ -1,532 +0,0 @@ -// -*- c++ -*- -/* This file is part of the KDE libraries - Copyright (C) 2000 Stephan Kulow <coolo@kde.org> - David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_job_h__ -#define __kio_job_h__ - -#include <kio/jobclasses.h> - -namespace TDEIO { - - - /** - * Creates a single directory. - * - * - * - * - * @param url The URL of the directory to create. - * @param permissions The permissions to set after creating the - * directory (unix-style), -1 for default permissions. - * @return A pointer to the job handling the operation. - */ - TDEIO_EXPORT SimpleJob * mkdir( const KURL& url, int permissions = -1 ); - - /** - * Removes a single directory. - * - * The directory is assumed to be empty. - * - * - * - * @param url The URL of the directory to remove. - * @return A pointer to the job handling the operation. - */ - TDEIO_EXPORT SimpleJob * rmdir( const KURL& url ); - - /** - * Changes permissions on a file or directory. - * See the other chmod below for changing many files - * or directories. - * - * @param url The URL of file or directory. - * @param permissions The permissions to set. - * @return the job handling the operation. - */ - TDEIO_EXPORT SimpleJob * chmod( const KURL& url, int permissions ); - - /** - * Rename a file or directory. - * Warning: this operation fails if a direct renaming is not - * possible (like with files or dirs on separate partitions) - * Use move or file_move in this case. - * - * @param src The original URL - * @param dest The final URL - * @param overwrite whether to automatically overwrite if the dest exists - * @return the job handling the operation. - */ - TDEIO_EXPORT SimpleJob * rename( const KURL& src, const KURL & dest, bool overwrite ); - - /** - * Create or move a symlink. - * This is the lowlevel operation, similar to file_copy and file_move. - * It doesn't do any check (other than those the slave does) - * and it doesn't show rename and skip dialogs - use TDEIO::link for that. - * @param target The string that will become the "target" of the link (can be relative) - * @param dest The symlink to create. - * @param overwrite whether to automatically overwrite if the dest exists - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT SimpleJob * symlink( const TQString & target, const KURL& dest, bool overwrite, bool showProgressInfo = true ); - - /** - * Execute any command that is specific to one slave (protocol). - * - * Examples are : HTTP POST, mount and unmount (kio_file) - * - * @param url The URL isn't passed to the slave, but is used to know - * which slave to send it to :-) - * @param data Packed data. The meaning is completely dependent on the - * slave, but usually starts with an int for the command number. - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT SimpleJob * special( const KURL& url, const TQByteArray & data, bool showProgressInfo = true ); - - /** - * Mount filesystem. - * - * Special job for @p kio_file. - * - * @param ro Mount read-only if @p true. - * @param fstype File system type (e.g. "ext2", can be 0L). - * @param dev Device (e.g. /dev/sda0). - * @param point Mount point, can be @p null. - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT SimpleJob *mount( bool ro, const char *fstype, const TQString& dev, const TQString& point, bool showProgressInfo = true ); - - /** - * Unmount filesystem. - * - * Special job for @p kio_file. - * - * @param point Point to unmount. - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT SimpleJob *unmount( const TQString & point, bool showProgressInfo = true ); - - /** - * Retrieve local URL if available - * - * @param remoteURL the remote URL to get the local URL for - * @return the job handling the operation. - */ - TDEIO_EXPORT LocalURLJob *localURL( const KURL& remoteUrl ); - - /** - * HTTP cache update - * - * @param url Url to update, protocol must be "http". - * @param no_cache If true, cache entry for @p url is deleted. - * @param expireDate Local machine time indicating when the entry is - * supposed to expire. - * @return the job handling the operation. - */ - TDEIO_EXPORT SimpleJob *http_update_cache( const KURL& url, bool no_cache, time_t expireDate); - - /** - * Find all details for one file or directory. - * - * @param url the URL of the file - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT StatJob * stat( const KURL& url, bool showProgressInfo = true ); - /** - * Find all details for one file or directory. - * This version of the call includes two additional booleans, @p sideIsSource and @p details. - * - * @param url the URL of the file - * @param sideIsSource is true when stating a source file (we will do a get on it if - * the stat works) and false when stating a destination file (target of a copy). - * The reason for this parameter is that in some cases the kioslave might not - * be able to determine a file's existence (e.g. HTTP doesn't allow it, FTP - * has issues with case-sensitivity on some systems). - * When the slave can't reliably determine the existence of a file, it will: - * @li be optimistic if sideIsSource=true, i.e. it will assume the file exists, - * and if it doesn't this will appear when actually trying to download it - * @li be pessimistic if sideIsSource=false, i.e. it will assume the file - * doesn't exist, to prevent showing "about to overwrite" errors to the user. - * If you simply want to check for existence without downloading/uploading afterwards, - * then you should use sideIsSource=false. - * - * @param details selects the level of details we want. - * By default this is 2 (all details wanted, including modification time, size, etc.), - * setDetails(1) is used when deleting: we don't need all the information if it takes - * too much time, no need to follow symlinks etc. - * setDetails(0) is used for very simple probing: we'll only get the answer - * "it's a file or a directory, or it doesn't exist". This is used by KRun. - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT StatJob * stat( const KURL& url, bool sideIsSource, short int details, bool showProgressInfo = true ); - - /** - * Get (a.k.a. read). - * - * The slave emits the data through data(). - * @param url the URL of the file - * @param reload true to reload the file, false if it can be taken from the cache - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT TransferJob *get( const KURL& url, bool reload=false, bool showProgressInfo = true ); - - /** - * Put (a.k.a. write) - * - * @param url Where to write data. - * @param permissions May be -1. In this case no special permission mode is set. - * @param overwrite If true, any existing file will be overwritten. - * @param resume true to resume an operation. Warning, setting this to true means - * that the data will be appended to @p dest if @p dest exists. - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - * @see multi_get() - */ - TDEIO_EXPORT TransferJob *put( const KURL& url, int permissions, - bool overwrite, bool resume, bool showProgressInfo = true ); - - /** - * HTTP POST (for form data). - * - * Example: - * \code - * job = TDEIO::http_post( url, postData, false ); - * job->addMetaData("content-type", contentType ); - * job->addMetaData("referrer", referrerURL); - * \endcode - * - * @p postData is the data that you want to send and - * @p contentType is the complete HTTP header line that - * specifies the content's MIME type, for example - * "Content-Type: text/xml". - * - * You MUST specify content-type! - * - * Often @p contentType is - * "Content-Type: application/x-www-form-urlencoded" and - * the @p postData is then an ASCII string (without null-termination!) - * with characters like space, linefeed and percent escaped like %20, - * %0A and %25. - * - * @param url Where to write the data. - * @param postData Encoded data to post. - * @param showProgressInfo true to display - * @return the job handling the operation. - */ - TDEIO_EXPORT TransferJob *http_post( const KURL& url, const TQByteArray &postData, - bool showProgressInfo = true ); - - /** - * Get (a.k.a. read), into a single TQByteArray. - * @see StoredTransferJob - * - * @param url the URL of the file - * @param reload true to reload the file, false if it can be taken from the cache - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - * @since 3.3 - */ - TDEIO_EXPORT StoredTransferJob *storedGet( const KURL& url, bool reload=false, bool showProgressInfo = true ); - - /** - * Put (a.k.a. write) data from a single TQByteArray. - * @see StoredTransferJob - * - * @param arr The data to write - * @param url Where to write data. - * @param permissions May be -1. In this case no special permission mode is set. - * @param overwrite If true, any existing file will be overwritten. - * @param resume true to resume an operation. Warning, setting this to true means - * that the data will be appended to @p dest if @p dest exists. - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - * @since 3.3 - */ - TDEIO_EXPORT StoredTransferJob *storedPut( const TQByteArray& arr, const KURL& url, int permissions, - bool overwrite, bool resume, bool showProgressInfo = true ); - - /** - * Creates a new multiple get job. - * - * @param id the id of the get operation - * @param url the URL of the file - * @param metaData the MetaData associated with the file - * - * @return the job handling the operation. - * @see get() - */ - TDEIO_EXPORT MultiGetJob *multi_get( long id, const KURL &url, const MetaData &metaData); - - /** - * Find mimetype for one file or directory. - * - * @param url the URL of the file - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT MimetypeJob * mimetype( const KURL& url, - bool showProgressInfo = true ); - - /** - * Copy a single file. - * - * Uses either SlaveBase::copy() if the slave supports that - * or get() and put() otherwise. - * @param src Where to get the file. - * @param dest Where to put the file. - * @param permissions May be -1. In this case no special permission mode is set. - * @param overwrite If true, any existing file will be overwritten. - * @param resume true to resume an operation. Warning, setting this to true means - * that @p src will be appended to @p dest if @p dest exists. - * You probably don't want that, so leave it to false :) - * - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT FileCopyJob *file_copy( const KURL& src, const KURL& dest, int permissions=-1, - bool overwrite=false, bool resume=false, - bool showProgressInfo = true); - - /** - * Move a single file. - * - * Use either SlaveBase::rename() if the slave supports that, - * or copy() and del() otherwise, or eventually get() & put() & del() - * @param src Where to get the file. - * @param dest Where to put the file. - * @param permissions May be -1. In this case no special permission mode is set. - * @param overwrite If @p true, any existing file will be overwritten. - * @param resume true to resume an operation. Warning, setting this to true means - * that @p src will be appended to @p dest if @p dest exists. - * You probably don't want that, so leave it to false :) - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT FileCopyJob *file_move( const KURL& src, const KURL& dest, int permissions=-1, - bool overwrite=false, bool resume=false, - bool showProgressInfo = true); - - /** - * Delete a single file. - * - * @param src File to delete. - * @param showProgressInfo true to show progress information - * @return the job handling the operation. - */ - TDEIO_EXPORT SimpleJob *file_delete( const KURL& src, bool showProgressInfo = true); - - /** - * List the contents of @p url, which is assumed to be a directory. - * - * "." and ".." are returned, filter them out if you don't want them. - * - * - * @param url the url of the directory - * @param showProgressInfo true to show progress information - * @param includeHidden true for all files, false to cull out UNIX hidden - * files/dirs (whose names start with dot) - * @return the job handling the operation. - */ - TDEIO_EXPORT ListJob *listDir( const KURL& url, bool showProgressInfo = true, - bool includeHidden = true ); - - /** - * The same as the previous method, but recurses subdirectories. - * Directory links are not followed. - * - * "." and ".." are returned but only for the toplevel directory. - * Filter them out if you don't want them. - * - * @param url the url of the directory - * @param showProgressInfo true to show progress information - * @param includeHidden true for all files, false to cull out UNIX hidden - * files/dirs (whose names start with dot) - * @return the job handling the operation. - */ - TDEIO_EXPORT ListJob *listRecursive( const KURL& url, bool showProgressInfo = true, - bool includeHidden = true ); - - /** - * Copy a file or directory @p src into the destination @p dest, - * which can be a file (including the final filename) or a directory - * (into which @p src will be copied). - * - * This emulates the cp command completely. - * - * @param src the file or directory to copy - * @param dest the destination - * @param showProgressInfo true to show progress information - * @return the job handling the operation - * @see copyAs() - */ - TDEIO_EXPORT CopyJob *copy( const KURL& src, const KURL& dest, bool showProgressInfo = true ); - - /** - * Copy a file or directory @p src into the destination @p dest, - * which is the destination name in any case, even for a directory. - * - * As opposed to copy(), this doesn't emulate cp, but is the only - * way to copy a directory, giving it a new name and getting an error - * box if a directory already exists with the same name. - * - * @param src the file or directory to copy - * @param dest the destination - * @param showProgressInfo true to show progress information - * @return the job handling the operation - */ - TDEIO_EXPORT CopyJob *copyAs( const KURL& src, const KURL& dest, bool showProgressInfo = true ); - - /** - * Copy a list of file/dirs @p src into a destination directory @p dest. - * - * @param src the list of files and/or directories - * @param dest the destination - * @param showProgressInfo true to show progress information - * @return the job handling the operation - */ - TDEIO_EXPORT CopyJob *copy( const KURL::List& src, const KURL& dest, bool showProgressInfo = true ); - - /** - * Moves a file or directory @p src to the given destination @p dest. - * - * @param src the file or directory to copy - * @param dest the destination - * @param showProgressInfo true to show progress information - * @return the job handling the operation - * @see copy() - * @see moveAs() - */ - TDEIO_EXPORT CopyJob *move( const KURL& src, const KURL& dest, bool showProgressInfo = true ); - /** - * Moves a file or directory @p src to the given destination @p dest. Unlike move() - * this operation will fail when the directory already exists. - * - * @param src the file or directory to copy - * @param dest the destination - * @param showProgressInfo true to show progress information - * @return the job handling the operation - * @see copyAs() - */ - TDEIO_EXPORT CopyJob *moveAs( const KURL& src, const KURL& dest, bool showProgressInfo = true ); - /** - * Moves a list of files or directories @p src to the given destination @p dest. - * - * @param src the list of files or directories to copy - * @param dest the destination - * @param showProgressInfo true to show progress information - * @return the job handling the operation - * @see copy() - */ - TDEIO_EXPORT CopyJob *move( const KURL::List& src, const KURL& dest, bool showProgressInfo = true ); - - /** - * Create a link. - * If the protocols and hosts are the same, a Unix symlink will be created. - * Otherwise, a .desktop file of Type Link and pointing to the src URL will be created. - * - * @param src The existing file or directory, 'target' of the link. - * @param destDir Destination directory where the link will be created. - * @param showProgressInfo true to show progress information - * @return the job handling the operation - */ - TDEIO_EXPORT CopyJob *link( const KURL& src, const KURL& destDir, bool showProgressInfo = true ); - - /** - * Create several links - * If the protocols and hosts are the same, a Unix symlink will be created. - * Otherwise, a .desktop file of Type Link and pointing to the src URL will be created. - * - * @param src The existing files or directories, 'targets' of the link. - * @param destDir Destination directory where the links will be created. - * @param showProgressInfo true to show progress information - * @return the job handling the operation - * @see link() - */ - TDEIO_EXPORT CopyJob *link( const KURL::List& src, const KURL& destDir, bool showProgressInfo = true ); - - /** - * Create a link. Unlike link() this operation will fail when the directory already - * exists. - * If the protocols and hosts are the same, a Unix symlink will be created. - * Otherwise, a .desktop file of Type Link and pointing to the src URL will be created. - * - * @param src The existing file or directory, 'target' of the link. - * @param dest Destination directory where the link will be created. - * @param showProgressInfo true to show progress information - * @return the job handling the operation - * @see link () - * @see copyAs() - */ - TDEIO_EXPORT CopyJob *linkAs( const KURL& src, const KURL& dest, bool showProgressInfo = true ); - - /** - * Trash a file or directory. - * This is currently only supported for local files and directories. - * Use "KURL src; src.setPath( path );" to create a URL from a path. - * - * @param src file to delete - * @param showProgressInfo true to show progress information - * @return the job handling the operation - * @since 3.4 - */ - TDEIO_EXPORT CopyJob *trash( const KURL& src, bool showProgressInfo = true ); - - /** - * Trash a list of files or directories. - * This is currently only supported for local files and directories. - * - * @param src the files to delete - * @param showProgressInfo true to show progress information - * @return the job handling the operation - * @since 3.4 - */ - TDEIO_EXPORT CopyJob *trash( const KURL::List& src, bool showProgressInfo = true ); - - /** - * Delete a file or directory. - * - * @param src file to delete - * @param shred obsolete (TODO remove in KDE4) - * @param showProgressInfo true to show progress information - * @return the job handling the operation - */ - TDEIO_EXPORT DeleteJob *del( const KURL& src, bool shred = false, bool showProgressInfo = true ); - - /** - * Deletes a list of files or directories. - * - * @param src the files to delete - * @param shred obsolete (TODO remove in KDE4) - * @param showProgressInfo true to show progress information - * @return the job handling the operation - */ - TDEIO_EXPORT DeleteJob *del( const KURL::List& src, bool shred = false, bool showProgressInfo = true ); -} - -#endif - diff --git a/kio/kio/jobclasses.h b/kio/kio/jobclasses.h deleted file mode 100644 index 3438406fa..000000000 --- a/kio/kio/jobclasses.h +++ /dev/null @@ -1,1909 +0,0 @@ -// -*- c++ -*- -/* This file is part of the KDE libraries - Copyright (C) 2000 Stephan Kulow <coolo@kde.org> - David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_jobclasses_h__ -#define __kio_jobclasses_h__ - -#include <tqobject.h> -#include <tqptrlist.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqguardedptr.h> - -#include <sys/types.h> -#include <sys/stat.h> - -#include <kurl.h> -#include <kio/global.h> - -class Observer; -class TQTimer; - -#define KIO_COPYJOB_HAS_SETINTERACTIVE // new in 3.4. Used by kio_trash. - -namespace TDEIO { - - class Slave; - class SlaveInterface; - - - /** - * The base class for all jobs. - * For all jobs created in an application, the code looks like - * - * \code - * TDEIO::Job * job = TDEIO::someoperation( some parameters ); - * connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), - * this, TQT_SLOT( slotResult( TDEIO::Job * ) ) ); - * \endcode - * (other connects, specific to the job) - * - * And slotResult is usually at least: - * - * \code - * if ( job->error() ) - * job->showErrorDialog( this or 0L ); - * \endcode - * @see TDEIO::Scheduler - * @see TDEIO::Slave - */ - class TDEIO_EXPORT Job : public TQObject { - Q_OBJECT - - protected: - Job( bool showProgressInfo ); - - public: - virtual ~Job(); - - /** - * Abort this job. - * This kills all subjobs and deletes the job. - * - * @param quietly if false, Job will emit signal result - * and ask kio_uiserver to close the progress window. - * @p quietly is set to true for subjobs. Whether applications - * should call with true or false depends on whether they rely - * on result being emitted or not. - */ - virtual void kill( bool quietly = true ); - - /** - * Returns the error code, if there has been an error. - * Only call this method from the slot connected to result(). - * @return the error code for this job, 0 if no error. - * Error codes are defined in TDEIO::Error. - */ - int error() const { return m_error; } - - /** - * Returns the progress id for this job. - * @return the progress id for this job, as returned by uiserver - */ - int progressId() const { return m_progressId; } - - /** - * Returns the error text if there has been an error. - * Only call if error is not 0. - * This is really internal, better use errorString() or errorDialog(). - * - * @return a string to help understand the error, usually the url - * related to the error. Only valid if error() is not 0. - */ - const TQString & errorText() const { return m_errorText; } - - /** - * Converts an error code and a non-i18n error message into an - * error message in the current language. The low level (non-i18n) - * error message (usually a url) is put into the translated error - * message using %1. - * - * Example for errid == ERR_CANNOT_OPEN_FOR_READING: - * \code - * i18n( "Could not read\n%1" ).arg( errortext ); - * \endcode - * Use this to display the error yourself, but for a dialog box - * use Job::showErrorDialog. Do not call it if error() - * is not 0. - * @return the error message and if there is no error, a message - * telling the user that the app is broken, so check with - * error() whether there is an error - */ - TQString errorString() const; - - /** - * Converts an error code and a non-i18n error message into i18n - * strings suitable for presentation in a detailed error message box. - * - * @param reqUrl the request URL that generated this error message - * @param method the method that generated this error message - * (unimplemented) - * @return the following strings: caption, error + description, - * causes+solutions - */ - TQStringList detailedErrorStrings(const KURL *reqUrl = 0L, - int method = -1) const; - - /** - * Display a dialog box to inform the user of the error given by - * this job. - * Only call if error is not 0, and only in the slot connected - * to result. - * @param parent the parent widget for the dialog box, can be 0 for - * top-level - */ - void showErrorDialog( TQWidget * parent = 0L ); - - /** - * Enable or disable the automatic error handling. When automatic - * error handling is enabled and an error occurs, then showErrorDialog() - * is called with the specified @p parentWidget (if supplied) , right before - * the emission of the result signal. - * - * The default is false. - * - * @param enable enable or disable automatic error handling - * @param parentWidget the parent widget, passed to showErrorDialog. - * Can be 0 for top-level - * @see isAutoErrorHandlingEnabled(), showErrorDialog() - */ - void setAutoErrorHandlingEnabled( bool enable, TQWidget *parentWidget = 0 ); - - /** - * Returns whether automatic error handling is enabled or disabled. - * @return true if automatic error handling is enabled - * @see setAutoErrorHandlingEnabled() - */ - bool isAutoErrorHandlingEnabled() const; - - /** - * Enable or disable the automatic warning handling. When automatic - * warning handling is enabled and an error occurs, then a message box - * is displayed with the warning message - * - * The default is true. - * - * See also isAutoWarningHandlingEnabled , showErrorDialog - * - * @param enable enable or disable automatic warning handling - * @see isAutoWarningHandlingEnabled() - * @since 3.5 - */ - void setAutoWarningHandlingEnabled( bool enable ); - - /** - * Returns whether automatic warning handling is enabled or disabled. - * See also setAutoWarningHandlingEnabled . - * @return true if automatic warning handling is enabled - * @see setAutoWarningHandlingEnabled() - * @since 3.5 - */ - bool isAutoWarningHandlingEnabled() const; - - /** - * Enable or disable the message display from the job. - * - * The default is true. - * @param enable enable or disable message display - * @since 3.4.1 - */ - void setInteractive(bool enable); - - /** - * Returns whether message display is enabled or disabled. - * @return true if message display is enabled - * @see setInteractive() - * @since 3.4.1 - */ - bool isInteractive() const; - /** - * Associate this job with a window given by @p window. - * @param window the window to associate to - * @see window() - */ - void setWindow(TQWidget *window); - - /** - * Returns the window this job is associated with. - * @return the associated window - * @see setWindow() - */ - TQWidget *window() const; - - /** - * Updates the last user action timestamp to the given time. - * See TDEApplication::updateUserTimestamp() . - * @since 3.5.6 - */ - void updateUserTimestamp( unsigned long time ); - - /** - * Set the parent Job. - * One example use of this is when FileCopyJob calls open_RenameDlg, - * it must pass the correct progress ID of the parent CopyJob - * (to hide the progress dialog). - * You can set the parent job only once. By default a job does not - * have a parent job. - * @param parentJob the new parent job - * @since 3.1 - */ - void setParentJob( Job* parentJob ); - - /** - * Returns the parent job, if there is one. - * @return the parent job, or 0 if there is none - * @see setParentJob - * @since 3.1 - */ - Job* parentJob() const; - - /** - * Set meta data to be sent to the slave, replacing existing - * meta data. - * @param metaData the meta data to set - * @see addMetaData() - * @see mergeMetaData() - */ - void setMetaData( const TDEIO::MetaData &metaData); - - /** - * Add key/value pair to the meta data that is sent to the slave. - * @param key the key of the meta data - * @param value the value of the meta data - * @see setMetaData() - * @see mergeMetaData() - */ - void addMetaData(const TQString &key, const TQString &value); - - /** - * Add key/value pairs to the meta data that is sent to the slave. - * If a certain key already existed, it will be overridden. - * @param values the meta data to add - * @see setMetaData() - * @see mergeMetaData() - */ - void addMetaData(const TQMap<TQString,TQString> &values); - - /** - * Add key/value pairs to the meta data that is sent to the slave. - * If a certain key already existed, it will remain unchanged. - * @param values the meta data to merge - * @see setMetaData() - * @see addMetaData() - */ - void mergeMetaData(const TQMap<TQString,TQString> &values); - - /** - * @internal. For the scheduler. Do not use. - */ - MetaData outgoingMetaData() const; - - /** - * Get meta data received from the slave. - * (Valid when first data is received and/or slave is finished) - * @return the job's meta data - */ - MetaData metaData() const; - - /** - * Query meta data received from the slave. - * (Valid when first data is received and/or slave is finished) - * @param key the key of the meta data to retrieve - * @return the value of the meta data, or TQString::null if the - * @p key does not exist - */ - TQString queryMetaData(const TQString &key); - - /** - * Returns the processed size for this job. - * @see processedSize - * @since 3.2 - */ - TDEIO::filesize_t getProcessedSize(); - - signals: - /** - * Emitted when the job is finished, in any case (completed, canceled, - * failed...). Use error to know the result. - * @param job the job that emitted this signal - */ - void result( TDEIO::Job *job ); - - /** - * @deprecated. Don't use ! - * Emitted when the job is canceled. - * Signal result() is emitted as well, and error() is, - * in this case, ERR_USER_CANCELED. - * @param job the job that emitted this signal - */ - void canceled( TDEIO::Job *job ); - - /** - * Emitted to display information about this job, as sent by the slave. - * Examples of message are "Resolving host", "Connecting to host...", etc. - * @param job the job that emitted this signal - * @param msg the info message - */ - void infoMessage( TDEIO::Job *job, const TQString & msg ); - // KDE4: Separate rich-text string from plain-text string, for different widgets. - - /** - * Emitted to display a warning about this job, as sent by the slave. - * @param job the job that emitted this signal - * @param msg the info message - * @since 3.5 - */ - void warning( TDEIO::Job *job, const TQString & msg ); - // KDE4: Separate rich-text string from plain-text string, for different widgets. - - /** - * Emitted when the slave successfully connected to the host. - * There is no guarantee the slave will send this, and this is - * currently unused (in the applications). - * @param job the job that emitted this signal - */ - void connected( TDEIO::Job *job ); - - /** - * Progress signal showing the overall progress of the job - * This is valid for any kind of job, and allows using a - * a progress bar very easily. (see KProgress). - * Note that this signal is not emitted for finished jobs. - * @param job the job that emitted this signal - * @param percent the percentage - */ - void percent( TDEIO::Job *job, unsigned long percent ); - - /** - * Emitted when we know the size of this job (data size for transfers, - * number of entries for listings). - * @param job the job that emitted this signal - * @param size the total size in bytes - */ - void totalSize( TDEIO::Job *job, TDEIO::filesize_t size ); - - /** - * Regularly emitted to show the progress of this job - * (current data size for transfers, entries listed). - * @param job the job that emitted this signal - * @param size the processed size in bytes - */ - void processedSize( TDEIO::Job *job, TDEIO::filesize_t size ); - - /** - * Emitted to display information about the speed of this job. - * @param job the job that emitted this signal - * @param speed the speed in bytes/s - */ - void speed( TDEIO::Job *job, unsigned long speed ); - - protected slots: - /** - * Called whenever a subjob finishes. - * Default implementation checks for errors and propagates - * to parent job, then calls removeSubjob. - * Override if you don't want subjobs errors to be propagated. - * @param job the subjob - * @see result() - */ - virtual void slotResult( TDEIO::Job *job ); - - /** - * Forward signal from subjob. - * @param job the subjob - * @param speed the speed in bytes/s - * @see speed() - */ - void slotSpeed( TDEIO::Job *job, unsigned long speed ); - /** - * Forward signal from subjob. - * @param job the subjob - * @param msg the info message - * @see infoMessage() - */ - void slotInfoMessage( TDEIO::Job *job, const TQString &msg ); - - /** - * Remove speed information. - */ - void slotSpeedTimeout(); - - protected: - /** - * Add a job that has to be finished before a result - * is emitted. This has obviously to be called before - * the finish signal is emitted by the slave. - * - * @param job the subjob to add - * @param inheritMetaData if true, the subjob will - * inherit the meta data from this job. - */ - virtual void addSubjob( Job *job, bool inheritMetaData=true ); - - /** - * Mark a sub job as being done. If it's the last to - * wait on the job will emit a result - jobs with - * two steps might want to override slotResult - * in order to avoid calling this method. - * - * @param job the subjob to add - */ - virtual void removeSubjob( Job *job ); - /** - * Overloaded version of removeSubjob - * @param job the subjob to remove - * @param mergeMetaData if set, the metadata received by the subjob is - * merged into this job. - * @param emitResultIfLast if this was the last subjob, emit result, - * i.e. terminate this job. - */ - void removeSubjob( Job *job, bool mergeMetaData, bool emitResultIfLast ); // KDE4: merge with above, with =true to both - - /** - * Utility function for inherited jobs. - * Emits the percent signal if bigger than m_percent, - * after calculating it from the parameters. - * - * @param processedSize the processed size in bytes - * @param totalSize the total size in bytes - */ - void emitPercent( TDEIO::filesize_t processedSize, TDEIO::filesize_t totalSize ); - - /** - * Utility function for inherited jobs. - * Emits the speed signal and starts the timer for removing that info - * - * @param speed the speed in bytes/s - */ - void emitSpeed( unsigned long speed ); - - /** - * Utility function to emit the result signal, and suicide this job. - * It first tells the observer to hide the progress dialog for this job. - */ - void emitResult(); - - /** - * Set the processed size, does not emit processedSize - * @since 3.2 - */ - void setProcessedSize(TDEIO::filesize_t size); - - /** - * @internal - */ - unsigned long userTimestamp() const; - - /** - * @internal - * Some extra storage space for jobs that don't have their own - * private d pointer. - */ - enum { EF_TransferJobAsync = (1 << 0), - EF_TransferJobNeedData = (1 << 1), - EF_TransferJobDataSent = (1 << 2), - EF_ListJobUnrestricted = (1 << 3) }; - int &extraFlags(); - - TQPtrList<Job> subjobs; - int m_error; - TQString m_errorText; - unsigned long m_percent; - int m_progressId; // for uiserver - TQTimer *m_speedTimer; - TQGuardedPtr<TQWidget> m_window; - MetaData m_outgoingMetaData; - MetaData m_incomingMetaData; - protected: - virtual void virtual_hook( int id, void* data ); - private: - class JobPrivate; - JobPrivate *d; - }; - - /** - * A simple job (one url and one command). - * This is the base class for all jobs that are scheduled. - * Other jobs are high-level jobs (CopyJob, DeleteJob, FileCopyJob...) - * that manage subjobs but aren't scheduled directly. - */ - class TDEIO_EXPORT SimpleJob : public TDEIO::Job { - Q_OBJECT - - public: - /** - * Creates a new simple job. You don't need to use this constructor, - * unless you create a new job that inherits from SimpleJob. - * @param url the url of the job - * @param command the command of the job - * @param packedArgs the arguments - * @param showProgressInfo true to show progress information to the user - */ - SimpleJob(const KURL& url, int command, const TQByteArray &packedArgs, - bool showProgressInfo); - - ~SimpleJob(); - - /** - * Returns the SimpleJob's URL - * @return the url - */ - const KURL& url() const { return m_url; } - - /** - * Abort job. - * This kills all subjobs and deletes the job. - * @param quietly if true, Job will emit signal result - * Should only be set to false when the user kills the job - * (from kio_uiserver), not when you want to abort a job. - */ - virtual void kill( bool quietly = true ); - - /** - * Abort job. - * Suspends slave to be reused by another job for the same request. - */ - virtual void putOnHold(); - - /** - * Discard suspended slave. - */ - static void removeOnHold(); - - /** - * @internal - * Called by the scheduler when a slave gets to - * work on this job. - **/ - virtual void start( Slave *slave ); - - /** - * @internal - * Called to detach a slave from a job. - **/ - void slaveDone(); - - /** - * @internal - * Slave in use by this job. - */ - Slave *slave() const { return m_slave; } - - /** - * @internal - */ - int command() const { return m_command; } - - public slots: - /** - * Forward signal from the slave - * Can also be called by the parent job, when it knows the size. - * @param data_size the total size - */ - void slotTotalSize( TDEIO::filesize_t data_size ); - - protected slots: - /** - * Called when the slave marks the job - * as finished. - */ - virtual void slotFinished( ); - - /** - * @internal - * Called on a slave's warning. - */ - void slotWarning( const TQString & ); // KDE4: make virtual - - /** - * Called on a slave's info message. - * @param s the info message - * @see infoMessage() - */ - void slotInfoMessage( const TQString &s ); // KDE4: make virtual - - /** - * Called on a slave's connected signal. - * @see connected() - */ - void slotConnected(); - - /** - * Forward signal from the slave. - * @param data_size the processed size in bytes - * @see processedSize() - */ - void slotProcessedSize( TDEIO::filesize_t data_size ); - /** - * Forward signal from the slave. - * @param speed the speed in bytes/s - * @see speed() - */ - void slotSpeed( unsigned long speed ); - - /** - * MetaData from the slave is received. - * @param _metaData the meta data - * @see metaData() - */ - virtual void slotMetaData( const TDEIO::MetaData &_metaData); - - public slots: - /** - * @internal - * Called on a slave's error. - * Made public for the scheduler. - */ - virtual void slotError( int , const TQString & ); - - protected slots: - /** - * @internal - */ - void slotNeedProgressId(); - - protected: - Slave * m_slave; - TQByteArray m_packedArgs; - KURL m_url; - KURL m_subUrl; - int m_command; - TDEIO::filesize_t m_totalSize; - protected: - virtual void virtual_hook( int id, void* data ); - /* - * Allow jobs that inherit SimpleJob and are aware - * of redirections to store the SSL session used. - * Retrieval is handled by SimpleJob::start - * @param m_redirectionURL Reference to redirection URL, - * used instead of m_url if not empty - */ - void storeSSLSessionFromJob(const KURL &m_redirectionURL); - private: - class SimpleJobPrivate* d; - }; - - /** - * A KIO job that retrieves information about a file or directory. - * @see TDEIO::stat() - */ - class TDEIO_EXPORT StatJob : public SimpleJob { - - Q_OBJECT - - public: - /** - * Do not use this constructor to create a StatJob, use TDEIO::stat() instead. - * @param url the url of the file or directory to check - * @param command the command to issue - * @param packedArgs the arguments - * @param showProgressInfo true to show progress information to the user - */ - StatJob(const KURL& url, int command, const TQByteArray &packedArgs, bool showProgressInfo); - - /** - * A stat() can have two meanings. Either we want to read from this URL, - * or to check if we can write to it. First case is "source", second is "dest". - * It is necessary to know what the StatJob is for, to tune the kioslave's behavior - * (e.g. with FTP). - * @param source true for "source" mode, false for "dest" mode - */ - void setSide( bool source ) { m_bSource = source; } - - /** - * Selects the level of @p details we want. - * By default this is 2 (all details wanted, including modification time, size, etc.), - * setDetails(1) is used when deleting: we don't need all the information if it takes - * too much time, no need to follow symlinks etc. - * setDetails(0) is used for very simple probing: we'll only get the answer - * "it's a file or a directory, or it doesn't exist". This is used by KRun. - * @param details 2 for all details, 1 for simple, 0 for very simple - */ - void setDetails( short int details ) { m_details = details; } - - /** - * Call this in the slot connected to result, - * and only after making sure no error happened. - * @return the result of the stat - */ - const UDSEntry & statResult() const { return m_statResult; } - - /** - * @internal - * Called by the scheduler when a @p slave gets to - * work on this job. - * @param slave the slave that starts working on this job - */ - virtual void start( Slave *slave ); - - signals: - /** - * Signals a redirection. - * Use to update the URL shown to the user. - * The redirection itself is handled internally. - * @param job the job that is redirected - * @param url the new url - */ - void redirection( TDEIO::Job *job, const KURL &url ); - - /** - * Signals a permanent redirection. - * The redirection itself is handled internally. - * @param job the job that is redirected - * @param fromUrl the original URL - * @param toUrl the new URL - * @since 3.1 - */ - void permanentRedirection( TDEIO::Job *job, const KURL &fromUrl, const KURL &toUrl ); - - protected slots: - void slotStatEntry( const TDEIO::UDSEntry & entry ); - void slotRedirection( const KURL &url); - virtual void slotFinished(); - virtual void slotMetaData( const TDEIO::MetaData &_metaData); - - protected: - UDSEntry m_statResult; - KURL m_redirectionURL; - bool m_bSource; - short int m_details; - protected: - virtual void virtual_hook( int id, void* data ); - private: - class StatJobPrivate; - StatJobPrivate *d; - }; - - /** - * A KIO job that creates a directory - * @see TDEIO::mkdir() - * @since 3.3 - */ - class TDEIO_EXPORT MkdirJob : public SimpleJob { - - Q_OBJECT - - public: - /** - * Do not use this constructor to create a MkdirJob, use TDEIO::mkdir() instead. - * @param url the url of the file or directory to check - * @param command the command to issue - * @param packedArgs the arguments - * @param showProgressInfo true to show progress information to the user - */ - MkdirJob(const KURL& url, int command, const TQByteArray &packedArgs, bool showProgressInfo); - - /** - * @internal - * Called by the scheduler when a @p slave gets to - * work on this job. - * @param slave the slave that starts working on this job - */ - virtual void start( Slave *slave ); - - signals: - /** - * Signals a redirection. - * Use to update the URL shown to the user. - * The redirection itself is handled internally. - * @param job the job that is redirected - * @param url the new url - */ - void redirection( TDEIO::Job *job, const KURL &url ); - - /** - * Signals a permanent redirection. - * The redirection itself is handled internally. - * @param job the job that is redirected - * @param fromUrl the original URL - * @param toUrl the new URL - */ - void permanentRedirection( TDEIO::Job *job, const KURL &fromUrl, const KURL &toUrl ); - - protected slots: - void slotRedirection( const KURL &url); - virtual void slotFinished(); - - protected: - KURL m_redirectionURL; - - protected: - virtual void virtual_hook( int id, void* data ); - private: - class MkdirJobPrivate; - MkdirJobPrivate *d; - }; - - /** - * @internal - * Used for direct copy from or to the local filesystem (i.e. SlaveBase::copy()) - */ - class TDEIO_EXPORT DirectCopyJob : public SimpleJob { - Q_OBJECT - - public: - /** - * Do not create a DirectCopyJob. Use TDEIO::copy() or TDEIO::file_copy() instead. - */ - DirectCopyJob(const KURL& url, int command, const TQByteArray &packedArgs, - bool showProgressInfo); - /** - * @internal - * Called by the scheduler when a @p slave gets to - * work on this job. - * @param slave the slave that starts working on this job - */ - virtual void start(Slave *slave); - - signals: - /** - * @internal - * Emitted if the job found an existing partial file - * and supports resuming. Used by FileCopyJob. - */ - void canResume( TDEIO::Job *job, TDEIO::filesize_t offset ); - - private slots: - void slotCanResume( TDEIO::filesize_t offset ); - }; - - - /** - * The transfer job pumps data into and/or out of a Slave. - * Data is sent to the slave on request of the slave ( dataReq). - * If data coming from the slave can not be handled, the - * reading of data from the slave should be suspended. - */ - class TDEIO_EXPORT TransferJob : public SimpleJob { - Q_OBJECT - - public: - /** - * Do not create a TransferJob. Use TDEIO::get() or TDEIO::put() - * instead. - * @param url the url to get or put - * @param command the command to issue - * @param packedArgs the arguments - * @param _staticData additional data to transmit (e.g. in a HTTP Post) - * @param showProgressInfo true to show progress information to the user - */ - TransferJob(const KURL& url, int command, - const TQByteArray &packedArgs, - const TQByteArray &_staticData, - bool showProgressInfo); - - /** - * @internal - * Called by the scheduler when a @p slave gets to - * work on this job. - * @param slave the slave that starts working on this job - */ - virtual void start(Slave *slave); - - /** - * Called when m_subJob finishes. - * @param job the job that finished - */ - virtual void slotResult( TDEIO::Job *job ); - - /** - * Flow control. Suspend data processing from the slave. - */ - void suspend(); - - /** - * Flow control. Resume data processing from the slave. - */ - void resume(); - - /** - * Flow control. - * @return true if the job is suspended - */ - bool isSuspended() const { return m_suspended; } - - - /** - * Checks whether we got an error page. This currently only happens - * with HTTP urls. Call this from your slot connected to result(). - * - * @return true if we got an (HTML) error page from the server - * instead of what we asked for. - */ - bool isErrorPage() const { return m_errorPage; } - - /** - * Enable the async data mode. - * When async data is enabled, data should be provided to the job by - * calling sendAsyncData() instead of returning data in the - * dataReq() signal. - * @since 3.2 - */ - void setAsyncDataEnabled(bool enabled); - - /** - * Provide data to the job when async data is enabled. - * Should be called exactly once after receiving a dataReq signal - * Sending an empty block indicates end of data. - * @since 3.2 - */ - void sendAsyncData(const TQByteArray &data); - - /** - * When enabled, the job reports the amount of data that has been sent, - * instead of the amount of data that that has been received. - * @see slotProcessedSize - * @see slotSpeed - * @since 3.2 - */ - void setReportDataSent(bool enabled); - - /** - * Returns whether the job reports the amount of data that has been - * sent (true), or whether the job reports the amount of data that - * has been received (false) - * @since 3.2 - */ - bool reportDataSent(); - - signals: - /** - * Data from the slave has arrived. - * @param job the job that emitted this signal - * @param data data received from the slave. - * - * End of data (EOD) has been reached if data.size() == 0, however, you - * should not be certain of data.size() == 0 ever happening (e.g. in case - * of an error), so you should rely on result() instead. - */ - void data( TDEIO::Job *job, const TQByteArray &data ); - - /** - * Request for data. - * Please note, that you shouldn't put too large chunks - * of data in it as this requires copies within the frame - * work, so you should rather split the data you want - * to pass here in reasonable chunks (about 1MB maximum) - * - * @param job the job that emitted this signal - * @param data buffer to fill with data to send to the - * slave. An empty buffer indicates end of data. (EOD) - */ - void dataReq( TDEIO::Job *job, TQByteArray &data ); - - /** - * Signals a redirection. - * Use to update the URL shown to the user. - * The redirection itself is handled internally. - * @param job the job that emitted this signal - * @param url the new URL - */ - void redirection( TDEIO::Job *job, const KURL &url ); - - /** - * Signals a permanent redirection. - * The redirection itself is handled internally. - * @param job the job that emitted this signal - * @param fromUrl the original URL - * @param toUrl the new URL - * @since 3.1 - */ - void permanentRedirection( TDEIO::Job *job, const KURL &fromUrl, const KURL &toUrl ); - - /** - * Mimetype determined. - * @param job the job that emitted this signal - * @param type the mime type - */ - void mimetype( TDEIO::Job *job, const TQString &type ); - - /** - * @internal - * Emitted if the "put" job found an existing partial file - * (in which case offset is the size of that file) - * and emitted by the "get" job if it supports resuming to - * the given offset - in this case @p offset is unused) - */ - void canResume( TDEIO::Job *job, TDEIO::filesize_t offset ); - - - protected slots: - virtual void slotRedirection( const KURL &url); - virtual void slotFinished(); - virtual void slotData( const TQByteArray &data); - virtual void slotDataReq(); - virtual void slotMimetype( const TQString &mimetype ); - virtual void slotNeedSubURLData(); - virtual void slotSubURLData(TDEIO::Job*, const TQByteArray &); - virtual void slotMetaData( const TDEIO::MetaData &_metaData); - void slotErrorPage(); - void slotCanResume( TDEIO::filesize_t offset ); - void slotPostRedirection(); - - protected: - bool m_suspended; - bool m_errorPage; - TQByteArray staticData; - KURL m_redirectionURL; - KURL::List m_redirectionList; - TQString m_mimetype; - TransferJob *m_subJob; - protected: - virtual void virtual_hook( int id, void* data ); - private: - class TransferJobPrivate *d; - }; - - /** - * StoredTransferJob is a TransferJob (for downloading or uploading data) that - * also stores a TQByteArray with the data, making it simpler to use than the - * standard TransferJob. - * - * For TDEIO::storedGet it puts the data into the member TQByteArray, so the user - * of this class can get hold of the whole data at once by calling data() - * when the result signal is emitted. - * You should only use StoredTransferJob to download data if you cannot - * process the data by chunks while it's being downloaded, since storing - * everything in a TQByteArray can potentially require a lot of memory. - * - * For TDEIO::storedPut the user of this class simply provides the bytearray from - * the start, and the job takes care of uploading it. - * You should only use StoredTransferJob to upload data if you cannot - * provide the in chunks while it's being uploaded, since storing - * everything in a TQByteArray can potentially require a lot of memory. - * - * @since 3.3 - */ - class TDEIO_EXPORT StoredTransferJob : public TDEIO::TransferJob { - Q_OBJECT - - public: - /** - * Do not create a StoredTransferJob. Use storedGet() or storedPut() - * instead. - * @param url the url to get or put - * @param command the command to issue - * @param packedArgs the arguments - * @param _staticData additional data to transmit (e.g. in a HTTP Post) - * @param showProgressInfo true to show progress information to the user - */ - StoredTransferJob(const KURL& url, int command, - const TQByteArray &packedArgs, - const TQByteArray &_staticData, - bool showProgressInfo); - - /** - * Set data to be uploaded. This is for put jobs. - * Automatically called by TDEIO::storedPut(const TQByteArray &, ...), - * do not call this yourself. - */ - void setData( const TQByteArray& arr ); - - /** - * Get hold of the downloaded data. This is for get jobs. - * You're supposed to call this only from the slot connected to the result() signal. - */ - TQByteArray data() const { return m_data; } - - private slots: - void slotStoredData( TDEIO::Job *job, const TQByteArray &data ); - void slotStoredDataReq( TDEIO::Job *job, TQByteArray &data ); - private: - TQByteArray m_data; - int m_uploadOffset; - }; - - /** - * The MultiGetJob is a TransferJob that allows you to get - * several files from a single server. Don't create directly, - * but use TDEIO::multi_get() instead. - * @see TDEIO::multi_get() - */ - class TDEIO_EXPORT MultiGetJob : public TransferJob { - Q_OBJECT - - public: - /** - * Do not create a MultiGetJob directly, use TDEIO::multi_get() - * instead. - * - * @param url the first url to get - * @param showProgressInfo true to show progress information to the user - */ - MultiGetJob(const KURL& url, bool showProgressInfo); - - /** - * @internal - * Called by the scheduler when a @p slave gets to - * work on this job. - * @param slave the slave that starts working on this job - */ - virtual void start(Slave *slave); - - /** - * Get an additional file. - * - * @param id the id of the file - * @param url the url of the file to get - * @param metaData the meta data for this request - */ - void get(long id, const KURL &url, const MetaData &metaData); - - signals: - /** - * Data from the slave has arrived. - * @param id the id of the request - * @param data data received from the slave. - * End of data (EOD) has been reached if data.size() == 0 - */ - void data( long id, const TQByteArray &data); - - /** - * Mimetype determined - * @param id the id of the request - * @param type the mime type - */ - void mimetype( long id, const TQString &type ); - - /** - * File transfer completed. - * - * When all files have been processed, result(TDEIO::Job *) gets - * emitted. - * @param id the id of the request - */ - void result( long id); - - protected slots: - virtual void slotRedirection( const KURL &url); - virtual void slotFinished(); - virtual void slotData( const TQByteArray &data); - virtual void slotMimetype( const TQString &mimetype ); - private: - struct GetRequest { - public: - GetRequest(long _id, const KURL &_url, const MetaData &_metaData) - : id(_id), url(_url), metaData(_metaData) { } - long id; - KURL url; - MetaData metaData; - }; - bool findCurrentEntry(); - void flushQueue(TQPtrList<GetRequest> &queue); - - TQPtrList<GetRequest> m_waitQueue; - TQPtrList<GetRequest> m_activeQueue; - bool b_multiGetActive; - GetRequest *m_currentEntry; - protected: - virtual void virtual_hook( int id, void* data ); - private: - class MultiGetJobPrivate* d; - }; - - /** - * A MimetypeJob is a TransferJob that allows you to get - * the mime type of an URL. Don't create directly, - * but use TDEIO::mimetype() instead. - * @see TDEIO::mimetype() - */ - class TDEIO_EXPORT MimetypeJob : public TransferJob { - Q_OBJECT - - public: - /** - * Do not create a MimetypeJob directly. Use TDEIO::mimetype() - * instead. - * @param url the url to get - * @param command the command to issue - * @param packedArgs the arguments - * @param showProgressInfo true to show progress information to the user - */ - MimetypeJob(const KURL& url, int command, const TQByteArray &packedArgs, bool showProgressInfo); - - /** - * Call this in the slot connected to result, - * and only after making sure no error happened. - * @return the mimetype of the URL - */ - TQString mimetype() const { return m_mimetype; } - - /** - * @internal - * Called by the scheduler when a slave gets to - * work on this job. - * @param slave the slave that works on the job - */ - virtual void start( Slave *slave ); - - protected slots: - virtual void slotFinished( ); - protected: - virtual void virtual_hook( int id, void* data ); - private: - class MimetypeJobPrivate* d; - }; - - /** - * The FileCopyJob copies data from one place to another. - * @see TDEIO::file_copy() - * @see TDEIO::file_move() - */ - class TDEIO_EXPORT FileCopyJob : public Job { - Q_OBJECT - - public: - /** - * Do not create a FileCopyJob directly. Use TDEIO::file_move() - * or TDEIO::file_copy() instead. - * @param src the source URL - * @param dest the destination URL - * @param permissions the permissions of the resulting resource - * @param move true to move, false to copy - * @param overwrite true to allow overwriting, false otherwise - * @param resume true to resume an operation, false otherwise - * @param showProgressInfo true to show progress information to the user - */ - FileCopyJob( const KURL& src, const KURL& dest, int permissions, - bool move, bool overwrite, bool resume, bool showProgressInfo); - - ~FileCopyJob(); - /** - * If you know the size of the source file, call this method - * to inform this job. It will be displayed in the "resume" dialog. - * @param size the size of the source file - * @since 3.2 - */ - void setSourceSize64(TDEIO::filesize_t size); - - /** - * Sets the modification time of the file - * - * Note that this is ignored if a direct copy (SlaveBase::copy) can be done, - * in which case the mtime of the source is applied to the destination (if the protocol - * supports the concept). - */ - void setModificationTime( time_t mtime ); - - /** - * @deprecated - */ - void setSourceSize( off_t size ) KDE_DEPRECATED; - - /** - * Returns the source URL. - * @return the source URL - */ - KURL srcURL() const { return m_src; } - - /** - * Returns the destination URL. - * @return the destination URL - */ - KURL destURL() const { return m_dest; } - - signals: - /** - * Mimetype determined during a file copy. - * This is never emitted during a move, and might not be emitted during - * a copy, depending on the slave. - * @param job the job that emitted this signal - * @param type the mime type - * - * @since 3.5.7 - */ - void mimetype( TDEIO::Job *job, const TQString &type ); - - public slots: - void slotStart(); - void slotData( TDEIO::Job *, const TQByteArray &data); - void slotDataReq( TDEIO::Job *, TQByteArray &data); - void slotMimetype( TDEIO::Job *, const TQString& type ); - - protected slots: - /** - * Called whenever a subjob finishes. - * @param job the job that emitted this signal - */ - virtual void slotResult( TDEIO::Job *job ); - - /** - * Forward signal from subjob - * @param job the job that emitted this signal - * @param size the processed size in bytes - */ - void slotProcessedSize( TDEIO::Job *job, TDEIO::filesize_t size ); - /** - * Forward signal from subjob - * @param job the job that emitted this signal - * @param size the total size - */ - void slotTotalSize( TDEIO::Job *job, TDEIO::filesize_t size ); - /** - * Forward signal from subjob - * @param job the job that emitted this signal - * @param pct the percentage - */ - void slotPercent( TDEIO::Job *job, unsigned long pct ); - /** - * Forward signal from subjob - * @param job the job that emitted this signal - * @param offset the offset to resume from - */ - void slotCanResume( TDEIO::Job *job, TDEIO::filesize_t offset ); - - protected: - void startCopyJob(); - void startCopyJob(const KURL &slave_url); - void startRenameJob(const KURL &slave_url); - void startDataPump(); - void connectSubjob( SimpleJob * job ); - - private: - void startBestCopyMethod(); - - protected: - KURL m_src; - KURL m_dest; - int m_permissions; - bool m_move:1; - bool m_overwrite:1; - bool m_resume:1; - bool m_canResume:1; - bool m_resumeAnswerSent:1; - TQByteArray m_buffer; - SimpleJob *m_moveJob; - SimpleJob *m_copyJob; - TransferJob *m_getJob; - TransferJob *m_putJob; - TDEIO::filesize_t m_totalSize; - protected: - virtual void virtual_hook( int id, void* data ); - private: - class FileCopyJobPrivate; - FileCopyJobPrivate* d; - }; - - /** - * A ListJob is allows you to get the get the content of a directory. - * Don't create the job directly, but use TDEIO::listRecursive() or - * TDEIO::listDir() instead. - * @see TDEIO::listRecursive() - * @see TDEIO::listDir() - */ - class TDEIO_EXPORT ListJob : public SimpleJob { - Q_OBJECT - - public: - /** - * Do not create a ListJob directly. Use TDEIO::listDir() or - * TDEIO::listRecursive() instead. - * @param url the url of the directory - * @param showProgressInfo true to show progress information to the user - * @param recursive true to get the data recursively from child directories, - * false to get only the content of the specified dir - * @param prefix the prefix of the files, or TQString::null for no prefix - * @param includeHidden true to include hidden files (those starting with '.') - */ - ListJob(const KURL& url, bool showProgressInfo, - bool recursive = false, TQString prefix = TQString::null, - bool includeHidden = true); - - /** - * @internal - * Called by the scheduler when a @p slave gets to - * work on this job. - * @param slave the slave that starts working on this job - */ - virtual void start( Slave *slave ); - - /** - * Returns the ListJob's redirection URL. This will be invalid if there - * was no redirection. - * @return the redirection url - * @since 3.4.1 - */ - const KURL& redirectionURL() const { return m_redirectionURL; } - - /** - * Do not apply any KIOSK restrictions to this job. - * @since 3.2 - */ - void setUnrestricted(bool unrestricted); - - signals: - /** - * This signal emits the entry found by the job while listing. - * The progress signals aren't specific to ListJob. It simply - * uses SimpleJob's processedSize (number of entries listed) and - * totalSize (total number of entries, if known), - * as well as percent. - * @param job the job that emitted this signal - * @param list the list of UDSEntries - */ - void entries( TDEIO::Job *job, const TDEIO::UDSEntryList& list); - - /** - * Signals a redirection. - * Use to update the URL shown to the user. - * The redirection itself is handled internally. - * @param job the job that is redirected - * @param url the new url - */ - void redirection( TDEIO::Job *job, const KURL &url ); - - /** - * Signals a permanent redirection. - * The redirection itself is handled internally. - * @param job the job that emitted this signal - * @param fromUrl the original URL - * @param toUrl the new URL - * @since 3.1 - */ - void permanentRedirection( TDEIO::Job *job, const KURL &fromUrl, const KURL &toUrl ); - - protected slots: - virtual void slotFinished( ); - virtual void slotMetaData( const TDEIO::MetaData &_metaData); - virtual void slotResult( TDEIO::Job *job ); - void slotListEntries( const TDEIO::UDSEntryList& list ); - void slotRedirection( const KURL &url ); - void gotEntries( TDEIO::Job * subjob, const TDEIO::UDSEntryList& list ); - - private: - bool recursive; - bool includeHidden; - TQString prefix; - unsigned long m_processedEntries; - KURL m_redirectionURL; - protected: - virtual void virtual_hook( int id, void* data ); - private: - class ListJobPrivate* d; - }; - - /// @internal - struct TDEIO_EXPORT CopyInfo - { - KURL uSource; - KURL uDest; - TQString linkDest; // for symlinks only - int permissions; - //mode_t type; - time_t ctime; - time_t mtime; - TDEIO::filesize_t size; // 0 for dirs - }; - - /** - * CopyJob is used to move, copy or symlink files and directories. - * Don't create the job directly, but use TDEIO::copy(), - * TDEIO::move(), TDEIO::link() and friends. - * - * @see TDEIO::copy() - * @see TDEIO::copyAs() - * @see TDEIO::move() - * @see TDEIO::moveAs() - * @see TDEIO::link() - * @see TDEIO::linkAs() - */ - class TDEIO_EXPORT CopyJob : public Job { - Q_OBJECT - - public: - /** - * Defines the mode of the operation - */ - enum CopyMode{ Copy, Move, Link }; - - /** - * Do not create a CopyJob directly. Use TDEIO::copy(), - * TDEIO::move(), TDEIO::link() and friends instead. - * - * @param src the list of source URLs - * @param dest the destination URL - * @param mode specifies whether the job should copy, move or link - * @param asMethod if true, behaves like TDEIO::copyAs(), - * TDEIO::moveAs() or TDEIO::linkAs() - * @param showProgressInfo true to show progress information to the user - * @see TDEIO::copy() - * @see TDEIO::copyAs() - * @see TDEIO::move() - * @see TDEIO::moveAs() - * @see TDEIO::link() - * @see TDEIO::linkAs() - */ - CopyJob( const KURL::List& src, const KURL& dest, CopyMode mode, bool asMethod, bool showProgressInfo ); - - virtual ~CopyJob(); - - /** - * Returns the list of source URLs. - * @return the list of source URLs. - */ - KURL::List srcURLs() const { return m_srcList; } - - /** - * Returns the destination URL. - * @return the destination URL - */ - KURL destURL() const { return m_dest; } - - /** - * By default the permissions of the copied files will be those of the source files. - * - * But when copying "template" files to "new" files, people prefer the umask - * to apply, rather than the template's permissions. - * For that case, call setDefaultPermissions(true) - * - * TODO KDE4: consider adding this as bool to copy/copyAs? - * @since 3.2.3 - */ - void setDefaultPermissions( bool b ); - - /** - * When an error happens while copying/moving a file, the user will be presented with - * a dialog for skipping the file that can't be copied/moved. - * Or if the error is that the destination file already exists, the standard - * rename dialog is shown. - * If the program doesn't want CopyJob to show dialogs, but to simply fail on error, - * call setInteractive( false ). - * - * KDE4: remove, already in Job - * @since 3.4 - */ - void setInteractive( bool b ); - - signals: - - /** - * Emitted when the total number of files is known. - * @param job the job that emitted this signal - * @param files the total number of files - */ - void totalFiles( TDEIO::Job *job, unsigned long files ); - /** - * Emitted when the toal number of direcotries is known. - * @param job the job that emitted this signal - * @param dirs the total number of directories - */ - void totalDirs( TDEIO::Job *job, unsigned long dirs ); - - /** - * Emitted when it is known which files / directories are going - * to be created. Note that this may still change e.g. when - * existing files with the same name are discovered. - * @param job the job that emitted this signal - * @param files a list of items that are about to be created. - */ - void aboutToCreate( TDEIO::Job *job, const TQValueList<TDEIO::CopyInfo> &files); - - /** - * Sends the number of processed files. - * @param job the job that emitted this signal - * @param files the number of processed files - */ - void processedFiles( TDEIO::Job *job, unsigned long files ); - /** - * Sends the number of processed directories. - * @param job the job that emitted this signal - * @param dirs the number of processed dirs - */ - void processedDirs( TDEIO::Job *job, unsigned long dirs ); - - /** - * The job is copying a file or directory. - * @param job the job that emitted this signal - * @param from the URl of the file or directory that is currently - * being copied - * @param to the destination of the current operation - */ - void copying( TDEIO::Job *job, const KURL& from, const KURL& to ); - /** - * The job is creating a symbolic link. - * @param job the job that emitted this signal - * @param target the URl of the file or directory that is currently - * being linked - * @param to the destination of the current operation - */ - void linking( TDEIO::Job *job, const TQString& target, const KURL& to ); - /** - * The job is moving a file or directory. - * @param job the job that emitted this signal - * @param from the URl of the file or directory that is currently - * being moved - * @param to the destination of the current operation - */ - void moving( TDEIO::Job *job, const KURL& from, const KURL& to ); - /** - * The job is creating the directory @p dir. - * @param job the job that emitted this signal - * @param dir the directory that is currently being created - */ - void creatingDir( TDEIO::Job *job, const KURL& dir ); - /** - * The user chose to rename @p from to @p to. - * @param job the job that emitted this signal - * @param from the original name - * @param to the new name - */ - void renamed( TDEIO::Job *job, const KURL& from, const KURL& to ); - - /** - * The job emits this signal when copying or moving a file or directory successfully finished. - * This signal is mainly for the Undo feature. - * - * @param job the job that emitted this signal - * @param from the source URL - * @param to the destination URL - * @param directory indicates whether a file or directory was successfully copied/moved. - * true for a directoy, false for file - * @param renamed indicates that the destination URL was created using a - * rename operation (i.e. fast directory moving). true if is has been renamed - */ - void copyingDone( TDEIO::Job *job, const KURL &from, const KURL &to, bool directory, bool renamed ); - /** - * The job is copying or moving a symbolic link, that points to target. - * The new link is created in @p to. The existing one is/was in @p from. - * This signal is mainly for the Undo feature. - * @param job the job that emitted this signal - * @param from the source URL - * @param target the target - * @param to the destination URL - */ - void copyingLinkDone( TDEIO::Job *job, const KURL &from, const TQString& target, const KURL& to ); - - protected: - void statCurrentSrc(); - void statNextSrc(); - - // Those aren't slots but submethods for slotResult. - void slotResultStating( TDEIO::Job * job ); - void startListing( const KURL & src ); - void slotResultCreatingDirs( TDEIO::Job * job ); - void slotResultConflictCreatingDirs( TDEIO::Job * job ); - void createNextDir(); - void slotResultCopyingFiles( TDEIO::Job * job ); - void slotResultConflictCopyingFiles( TDEIO::Job * job ); - void copyNextFile(); - void slotResultDeletingDirs( TDEIO::Job * job ); - void deleteNextDir(); - void skip( const KURL & sourceURL ); - void slotResultRenaming( TDEIO::Job * job ); - //void slotResultSettingDirAttributes( TDEIO::Job * job ); - void setNextDirAttribute(); - private: - void startRenameJob(const KURL &slave_url); - bool shouldOverwrite( const TQString& path ) const; - bool shouldSkip( const TQString& path ) const; - void skipSrc(); - - protected slots: - void slotStart(); - void slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& list ); - virtual void slotResult( TDEIO::Job *job ); - /** - * Forward signal from subjob - */ - void slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t data_size ); - /** - * Forward signal from subjob - * @param size the total size - */ - void slotTotalSize( TDEIO::Job*, TDEIO::filesize_t size ); - - void slotReport(); - private: - CopyMode m_mode; - bool m_asMethod; - enum DestinationState { DEST_NOT_STATED, DEST_IS_DIR, DEST_IS_FILE, DEST_DOESNT_EXIST }; - DestinationState destinationState; - enum { STATE_STATING, STATE_RENAMING, STATE_LISTING, STATE_CREATING_DIRS, - STATE_CONFLICT_CREATING_DIRS, STATE_COPYING_FILES, STATE_CONFLICT_COPYING_FILES, - STATE_DELETING_DIRS, STATE_SETTING_DIR_ATTRIBUTES } state; - TDEIO::filesize_t m_totalSize; - TDEIO::filesize_t m_processedSize; - TDEIO::filesize_t m_fileProcessedSize; - int m_processedFiles; - int m_processedDirs; - TQValueList<CopyInfo> files; - TQValueList<CopyInfo> dirs; - KURL::List dirsToRemove; - KURL::List m_srcList; - KURL::List::Iterator m_currentStatSrc; - bool m_bCurrentSrcIsDir; - bool m_bCurrentOperationIsLink; - bool m_bSingleFileCopy; - bool m_bOnlyRenames; - KURL m_dest; - KURL m_currentDest; - // - TQStringList m_skipList; - TQStringList m_overwriteList; - bool m_bAutoSkip; - bool m_bOverwriteAll; - int m_conflictError; - - TQTimer *m_reportTimer; - //these both are used for progress dialog reporting - KURL m_currentSrcURL; - KURL m_currentDestURL; - protected: - virtual void virtual_hook( int id, void* data ); - private: - class CopyJobPrivate; - CopyJobPrivate* d; - friend class CopyJobPrivate; // for DestinationState - }; - - /** - * A more complex Job to delete files and directories. - * Don't create the job directly, but use TDEIO::del() instead. - * - * @see TDEIO::del() - */ - class TDEIO_EXPORT DeleteJob : public Job { - Q_OBJECT - - public: - /** - * Do not create a DeleteJob directly. Use TDEIO::del() - * instead. - * - * @param src the list of URLs to delete - * @param shred true to shred (make sure that data is not recoverable)a - * @param showProgressInfo true to show progress information to the user - * @see TDEIO::del() - */ - DeleteJob( const KURL::List& src, bool shred, bool showProgressInfo ); - - /** - * Returns the list of URLs. - * @return the list of URLs. - */ - KURL::List urls() const { return m_srcList; } - - signals: - - /** - * Emitted when the total number of files is known. - * @param job the job that emitted this signal - * @param files the total number of files - */ - void totalFiles( TDEIO::Job *job, unsigned long files ); - /** - * Emitted when the toal number of direcotries is known. - * @param job the job that emitted this signal - * @param dirs the total number of directories - */ - void totalDirs( TDEIO::Job *job, unsigned long dirs ); - - /** - * Sends the number of processed files. - * @param job the job that emitted this signal - * @param files the number of processed files - */ - void processedFiles( TDEIO::Job *job, unsigned long files ); - /** - * Sends the number of processed directories. - * @param job the job that emitted this signal - * @param dirs the number of processed dirs - */ - void processedDirs( TDEIO::Job *job, unsigned long dirs ); - - /** - * Sends the URL of the file that is currently being deleted. - * @param job the job that emitted this signal - * @param file the URL of the file or directory that is being - * deleted - */ - void deleting( TDEIO::Job *job, const KURL& file ); - - protected slots: - void slotStart(); - void slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList& list ); - virtual void slotResult( TDEIO::Job *job ); - - /** - * Forward signal from subjob - */ - void slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t data_size ); - void slotReport(); - - private: - void statNextSrc(); - void deleteNextFile(); - void deleteNextDir(); - - private: - enum { STATE_STATING, STATE_LISTING, - STATE_DELETING_FILES, STATE_DELETING_DIRS } state; - TDEIO::filesize_t m_totalSize; - TDEIO::filesize_t m_processedSize; - TDEIO::filesize_t m_fileProcessedSize; - int m_processedFiles; - int m_processedDirs; - int m_totalFilesDirs; - KURL m_currentURL; - KURL::List files; - KURL::List symlinks; - KURL::List dirs; - KURL::List m_srcList; - KURL::List::Iterator m_currentStat; - TQStringList m_parentDirs; - bool m_shred; // BIC: remove in KDE4 - TQTimer *m_reportTimer; - protected: - /** \internal */ - virtual void virtual_hook( int id, void* data ); - private: - class DeleteJobPrivate* d; - }; - - /** - * A KIO job that finds a local URL - * @see TDEIO::localURL() - * @since R14.0.0 - */ - class TDEIO_EXPORT LocalURLJob : public SimpleJob { - - Q_OBJECT - - public: - /** - * Do not use this constructor to create a LocalURLJob, use TDEIO::localURL() instead. - * @param url the url of the file or directory to check - * @param command the command to issue - * @param packedArgs the arguments - * @param showProgressInfo true to show progress information to the user - */ - LocalURLJob(const KURL& url, int command, const TQByteArray &packedArgs, bool showProgressInfo); - - /** - * @internal - * Called by the scheduler when a @p slave gets to - * work on this job. - * @param slave the slave that starts working on this job - */ - virtual void start( Slave *slave ); - - signals: - /** - * @param job the job that emitted this signal - * @param url the local url - * @param isLocal true if the returned URL is local, false if not - */ - void localURL( TDEIO::Job *job, const KURL &url, bool isLocal ); - - protected slots: - void slotLocalURL( const KURL &url, bool isLocal ); - virtual void slotFinished(); - - protected: - virtual void virtual_hook( int id, void* data ); - private: - class LocalURLJobPrivate; - LocalURLJobPrivate *d; - }; - -} - -#endif diff --git a/kio/kio/kacl.cpp b/kio/kio/kacl.cpp deleted file mode 100644 index 432a50d31..000000000 --- a/kio/kio/kacl.cpp +++ /dev/null @@ -1,682 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2005 Till Adam <adam@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -// $Id: kacl.cpp 424977 2005-06-13 15:13:22Z tilladam $ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <pwd.h> -#include <grp.h> -#include <sys/stat.h> -#ifdef USE_POSIX_ACL -#ifdef HAVE_NON_POSIX_ACL_EXTENSIONS -#include <acl/libacl.h> -#else -#include <posixacladdons.h> -#endif -#endif -#include <tqintdict.h> - -#include <kdebug.h> - -#include "kacl.h" - - -#ifdef USE_POSIX_ACL -static void printACL( acl_t acl, const TQString &comment ); -static TQString aclAsString(const acl_t acl); -#endif - -class KACL::KACLPrivate { -public: - KACLPrivate() : m_acl( 0 ) { init(); } -#ifdef USE_POSIX_ACL - KACLPrivate( acl_t acl ) - : m_acl( acl ) { init(); } - ~KACLPrivate() { if ( m_acl ) acl_free( m_acl ); } -#endif - void init() { - m_usercache.setAutoDelete( true ); - m_groupcache.setAutoDelete( true ); - } - // helpers -#ifdef USE_POSIX_ACL - bool setMaskPermissions( unsigned short v ); - TQString getUserName( uid_t uid ) const; - TQString getGroupName( gid_t gid ) const; - bool setAllUsersOrGroups( const TQValueList< QPair<TQString, unsigned short> > &list, acl_tag_t type ); - bool setNamedUserOrGroupPermissions( const TQString& name, unsigned short permissions, acl_tag_t type ); - - acl_t m_acl; -#else - int m_acl; -#endif - mutable TQIntDict<TQString> m_usercache; - mutable TQIntDict<TQString> m_groupcache; -}; - -KACL::KACL( const TQString &aclString ) - : d( new KACLPrivate ) -{ - setACL( aclString ); -} - -KACL::KACL( mode_t basePermissions ) -#ifdef USE_POSIX_ACL - : d( new KACLPrivate( acl_from_mode( basePermissions ) ) ) -#else - : d( new KACLPrivate ) -#endif -{ -#ifndef USE_POSIX_ACL - Q_UNUSED( basePermissions ); -#endif -} - -KACL::KACL() - : d( new KACLPrivate ) -{ -} - -KACL::KACL( const KACL& rhs ) - : d( new KACLPrivate ) -{ - setACL( rhs.asString() ); -} - -KACL::~KACL() -{ - delete d; -} - -bool KACL::operator==( const KACL& rhs ) const { -#ifdef USE_POSIX_ACL - return ( acl_cmp( d->m_acl, rhs.d->m_acl ) == 0 ); -#else - Q_UNUSED( rhs ); - return true; -#endif -} - -bool KACL::isValid() const -{ - bool valid = false; -#ifdef USE_POSIX_ACL - if ( d->m_acl ) { - valid = ( acl_valid( d->m_acl ) == 0 ); - } -#endif - return valid; -} - -bool KACL::isExtended() const -{ -#ifdef USE_POSIX_ACL - return ( acl_equiv_mode( d->m_acl, NULL ) != 0 ); -#else - return false; -#endif -} - -#ifdef USE_POSIX_ACL -static acl_entry_t entryForTag( acl_t acl, acl_tag_t tag ) -{ - acl_entry_t entry; - int ret = acl_get_entry( acl, ACL_FIRST_ENTRY, &entry ); - while ( ret == 1 ) { - acl_tag_t currentTag; - acl_get_tag_type( entry, ¤tTag ); - if ( currentTag == tag ) - return entry; - ret = acl_get_entry( acl, ACL_NEXT_ENTRY, &entry ); - } - return 0; -} - -static unsigned short entryToPermissions( acl_entry_t entry ) -{ - if ( entry == 0 ) return 0; - acl_permset_t permset; - if ( acl_get_permset( entry, &permset ) != 0 ) return 0; - return( acl_get_perm( permset, ACL_READ ) << 2 | - acl_get_perm( permset, ACL_WRITE ) << 1 | - acl_get_perm( permset, ACL_EXECUTE ) ); -} - -static void permissionsToEntry( acl_entry_t entry, unsigned short v ) -{ - if ( entry == 0 ) return; - acl_permset_t permset; - if ( acl_get_permset( entry, &permset ) != 0 ) return; - acl_clear_perms( permset ); - if ( v & 4 ) acl_add_perm( permset, ACL_READ ); - if ( v & 2 ) acl_add_perm( permset, ACL_WRITE ); - if ( v & 1 ) acl_add_perm( permset, ACL_EXECUTE ); -} - -static void printACL( acl_t acl, const TQString &comment ) -{ - kdDebug() << comment << aclAsString( acl ) << endl; -} - -static int getUidForName( const TQString& name ) -{ - struct passwd *user = getpwnam( name.latin1() ); - if ( user ) - return user->pw_uid; - else - return -1; -} - -static int getGidForName( const TQString& name ) -{ - struct group *group = getgrnam( name.latin1() ); - if ( group ) - return group->gr_gid; - else - return -1; -} -#endif -// ------------------ begin API implementation ------------ - -unsigned short KACL::ownerPermissions() const -{ -#ifdef USE_POSIX_ACL - return entryToPermissions( entryForTag( d->m_acl, ACL_USER_OBJ ) ); -#else - return 0; -#endif -} - -bool KACL::setOwnerPermissions( unsigned short v ) -{ -#ifdef USE_POSIX_ACL - permissionsToEntry( entryForTag( d->m_acl, ACL_USER_OBJ ), v ); -#else - Q_UNUSED( v ); -#endif - return true; -} - -unsigned short KACL::owningGroupPermissions() const -{ -#ifdef USE_POSIX_ACL - return entryToPermissions( entryForTag( d->m_acl, ACL_GROUP_OBJ ) ); -#else - return 0; -#endif -} - -bool KACL::setOwningGroupPermissions( unsigned short v ) -{ -#ifdef USE_POSIX_ACL - permissionsToEntry( entryForTag( d->m_acl, ACL_GROUP_OBJ ), v ); -#else - Q_UNUSED( v ); -#endif - return true; -} - -unsigned short KACL::othersPermissions() const -{ -#ifdef USE_POSIX_ACL - return entryToPermissions( entryForTag( d->m_acl, ACL_OTHER ) ); -#else - return 0; -#endif -} - -bool KACL::setOthersPermissions( unsigned short v ) -{ -#ifdef USE_POSIX_ACL - permissionsToEntry( entryForTag( d->m_acl, ACL_OTHER ), v ); -#else - Q_UNUSED( v ); -#endif - return true; -} - -mode_t KACL::basePermissions() const -{ - mode_t perms( 0 ); -#ifdef USE_POSIX_ACL - if ( ownerPermissions() & ACL_READ ) perms |= S_IRUSR; - if ( ownerPermissions() & ACL_WRITE ) perms |= S_IWUSR; - if ( ownerPermissions() & ACL_EXECUTE ) perms |= S_IXUSR; - if ( owningGroupPermissions() & ACL_READ ) perms |= S_IRGRP; - if ( owningGroupPermissions() & ACL_WRITE ) perms |= S_IWGRP; - if ( owningGroupPermissions() & ACL_EXECUTE ) perms |= S_IXGRP; - if ( othersPermissions() & ACL_READ ) perms |= S_IROTH; - if ( othersPermissions() & ACL_WRITE ) perms |= S_IWOTH; - if ( othersPermissions() & ACL_EXECUTE ) perms |= S_IXOTH; -#endif - return perms; -} - -unsigned short KACL::maskPermissions( bool &exists ) const -{ - exists = true; -#ifdef USE_POSIX_ACL - acl_entry_t entry = entryForTag( d->m_acl, ACL_MASK ); - if ( entry == 0 ) { - exists = false; - return 0; - } - return entryToPermissions( entry ); -#else - return 0; -#endif -} - -#ifdef USE_POSIX_ACL -bool KACL::KACLPrivate::setMaskPermissions( unsigned short v ) -{ - acl_entry_t entry = entryForTag( m_acl, ACL_MASK ); - if ( entry == 0 ) { - acl_create_entry( &m_acl, &entry ); - acl_set_tag_type( entry, ACL_MASK ); - } - permissionsToEntry( entry, v ); - return true; -} -#endif - -bool KACL::setMaskPermissions( unsigned short v ) -{ -#ifdef USE_POSIX_ACL - return d->setMaskPermissions( v ); -#else - Q_UNUSED( v ); - return true; -#endif -} - -/************************** - * Deal with named users * - **************************/ -unsigned short KACL::namedUserPermissions( const TQString& name, bool *exists ) const -{ -#ifdef USE_POSIX_ACL - acl_entry_t entry; - uid_t id; - *exists = false; - int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry ); - while ( ret == 1 ) { - acl_tag_t currentTag; - acl_get_tag_type( entry, ¤tTag ); - if ( currentTag == ACL_USER ) { - id = *( (uid_t*) acl_get_qualifier( entry ) ); - if ( d->getUserName( id ) == name ) { - *exists = true; - return entryToPermissions( entry ); - } - } - ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry ); - } -#else - Q_UNUSED( name ); - Q_UNUSED( exists ); -#endif - return 0; -} - -#ifdef USE_POSIX_ACL -bool KACL::KACLPrivate::setNamedUserOrGroupPermissions( const TQString& name, unsigned short permissions, acl_tag_t type ) -{ - bool allIsWell = true; - acl_t newACL = acl_dup( m_acl ); - acl_entry_t entry; - bool createdNewEntry = false; - bool found = false; - int ret = acl_get_entry( newACL, ACL_FIRST_ENTRY, &entry ); - while ( ret == 1 ) { - acl_tag_t currentTag; - acl_get_tag_type( entry, ¤tTag ); - if ( currentTag == type ) { - int id = * (int*)acl_get_qualifier( entry ); - const TQString entryName = type == ACL_USER? getUserName( id ): getGroupName( id ); - if ( entryName == name ) { - // found him, update - permissionsToEntry( entry, permissions ); - found = true; - break; - } - } - ret = acl_get_entry( newACL, ACL_NEXT_ENTRY, &entry ); - } - if ( !found ) { - acl_create_entry( &newACL, &entry ); - acl_set_tag_type( entry, type ); - int id = type == ACL_USER? getUidForName( name ): getGidForName( name ); - if ( id == -1 || acl_set_qualifier( entry, &id ) != 0 ) { - acl_delete_entry( newACL, entry ); - allIsWell = false; - } else { - permissionsToEntry( entry, permissions ); - createdNewEntry = true; - } - } - if ( allIsWell && createdNewEntry ) { - // 23.1.1 of 1003.1e states that as soon as there is a named user or - // named group entry, there needs to be a mask entry as well, so add - // one, if the user hasn't explicitely set one. - if ( entryForTag( newACL, ACL_MASK ) == 0 ) { - acl_calc_mask( &newACL ); - } - } - - if ( !allIsWell || acl_valid( newACL ) != 0 ) { - acl_free( newACL ); - allIsWell = false; - } else { - acl_free( m_acl ); - m_acl = newACL; - } - return allIsWell; -} -#endif - -bool KACL::setNamedUserPermissions( const TQString& name, unsigned short permissions ) -{ -#ifdef USE_POSIX_ACL - return d->setNamedUserOrGroupPermissions( name, permissions, ACL_USER ); -#else - Q_UNUSED( name ); - Q_UNUSED( permissions ); - return true; -#endif -} - -ACLUserPermissionsList KACL::allUserPermissions() const -{ - ACLUserPermissionsList list; -#ifdef USE_POSIX_ACL - acl_entry_t entry; - uid_t id; - int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry ); - while ( ret == 1 ) { - acl_tag_t currentTag; - acl_get_tag_type( entry, ¤tTag ); - if ( currentTag == ACL_USER ) { - id = *( (uid_t*) acl_get_qualifier( entry ) ); - TQString name = d->getUserName( id ); - unsigned short permissions = entryToPermissions( entry ); - ACLUserPermissions pair = qMakePair( name, permissions ); - list.append( pair ); - } - ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry ); - } -#endif - return list; -} - -#ifdef USE_POSIX_ACL -bool KACL::KACLPrivate::setAllUsersOrGroups( const TQValueList< QPair<TQString, unsigned short> > &list, acl_tag_t type ) -{ - bool allIsWell = true; - bool atLeastOneUserOrGroup = false; - - // make working copy, in case something goes wrong - acl_t newACL = acl_dup( m_acl ); - acl_entry_t entry; - -//printACL( newACL, "Before cleaning: " ); - // clear user entries - int ret = acl_get_entry( newACL, ACL_FIRST_ENTRY, &entry ); - while ( ret == 1 ) { - acl_tag_t currentTag; - acl_get_tag_type( entry, ¤tTag ); - if ( currentTag == type ) { - acl_delete_entry( newACL, entry ); - // we have to start from the beginning, the iterator is - // invalidated, on deletion - ret = acl_get_entry( newACL, ACL_FIRST_ENTRY, &entry ); - } else { - ret = acl_get_entry( newACL, ACL_NEXT_ENTRY, &entry ); - } - } -//printACL( newACL, "After cleaning out entries: " ); - - // now add the entries from the list - TQValueList< QPair<TQString, unsigned short> >::const_iterator it = list.constBegin(); - while ( it != list.constEnd() ) { - acl_create_entry( &newACL, &entry ); - acl_set_tag_type( entry, type ); - int id = type == ACL_USER? getUidForName( (*it).first):getGidForName( (*it).first ); - if ( id == -1 || acl_set_qualifier( entry, &id ) != 0 ) { - // user or group doesn't exist => error - acl_delete_entry( newACL, entry ); - allIsWell = false; - break; - } else { - permissionsToEntry( entry, (*it).second ); - atLeastOneUserOrGroup = true; - } - ++it; - } -//printACL( newACL, "After adding entries: " ); - if ( allIsWell && atLeastOneUserOrGroup ) { - // 23.1.1 of 1003.1e states that as soon as there is a named user or - // named group entry, there needs to be a mask entry as well, so add - // one, if the user hasn't explicitely set one. - if ( entryForTag( newACL, ACL_MASK ) == 0 ) { - acl_calc_mask( &newACL ); - } - } - if ( allIsWell && ( acl_valid( newACL ) == 0 ) ) { - acl_free( m_acl ); - m_acl = newACL; - } else { - acl_free( newACL ); - } - return allIsWell; -} -#endif - -bool KACL::setAllUserPermissions( const ACLUserPermissionsList &users ) -{ -#ifdef USE_POSIX_ACL - return d->setAllUsersOrGroups( users, ACL_USER ); -#else - Q_UNUSED( users ); - return true; -#endif -} - - -/************************** - * Deal with named groups * - **************************/ - -unsigned short KACL::namedGroupPermissions( const TQString& name, bool *exists ) const -{ - *exists = false; -#ifdef USE_POSIX_ACL - acl_entry_t entry; - gid_t id; - int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry ); - while ( ret == 1 ) { - acl_tag_t currentTag; - acl_get_tag_type( entry, ¤tTag ); - if ( currentTag == ACL_GROUP ) { - id = *( (gid_t*) acl_get_qualifier( entry ) ); - if ( d->getGroupName( id ) == name ) { - *exists = true; - return entryToPermissions( entry ); - } - } - ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry ); - } -#else - Q_UNUSED( name ); -#endif - return 0; -} - -bool KACL::setNamedGroupPermissions( const TQString& name, unsigned short permissions ) -{ -#ifdef USE_POSIX_ACL - return d->setNamedUserOrGroupPermissions( name, permissions, ACL_GROUP ); -#else - Q_UNUSED( name ); - Q_UNUSED( permissions ); - return true; -#endif -} - - -ACLGroupPermissionsList KACL::allGroupPermissions() const -{ - ACLGroupPermissionsList list; -#ifdef USE_POSIX_ACL - acl_entry_t entry; - gid_t id; - int ret = acl_get_entry( d->m_acl, ACL_FIRST_ENTRY, &entry ); - while ( ret == 1 ) { - acl_tag_t currentTag; - acl_get_tag_type( entry, ¤tTag ); - if ( currentTag == ACL_GROUP ) { - id = *( (gid_t*) acl_get_qualifier( entry ) ); - TQString name = d->getGroupName( id ); - unsigned short permissions = entryToPermissions( entry ); - ACLGroupPermissions pair = qMakePair( name, permissions ); - list.append( pair ); - } - ret = acl_get_entry( d->m_acl, ACL_NEXT_ENTRY, &entry ); - } -#endif - return list; -} - -bool KACL::setAllGroupPermissions( const ACLGroupPermissionsList &groups ) -{ -#ifdef USE_POSIX_ACL - return d->setAllUsersOrGroups( groups, ACL_GROUP ); -#else - Q_UNUSED( groups ); - return true; -#endif -} - -/************************** - * from and to string * - **************************/ - -bool KACL::setACL( const TQString &aclStr ) -{ - bool ret = false; -#ifdef USE_POSIX_ACL - if ( aclStr.isEmpty() ) - return false; - - acl_t temp = acl_from_text( aclStr.latin1() ); - if ( acl_valid( temp ) != 0 ) { - // TODO errno is set, what to do with it here? - acl_free( temp ); - } else { - if ( d->m_acl ) - acl_free( d->m_acl ); - d->m_acl = temp; - ret = true; - } -#else - Q_UNUSED( aclStr ); -#endif - return ret; -} - -TQString KACL::asString() const -{ -#ifdef USE_POSIX_ACL - return aclAsString( d->m_acl ); -#else - return TQString::null; -#endif -} - - -// helpers - -#ifdef USE_POSIX_ACL -TQString KACL::KACLPrivate::getUserName( uid_t uid ) const -{ - TQString *temp; - temp = m_usercache.find( uid ); - if ( !temp ) { - struct passwd *user = getpwuid( uid ); - if ( user ) { - m_usercache.insert( uid, new TQString(TQString::fromLatin1(user->pw_name)) ); - return TQString::fromLatin1( user->pw_name ); - } - else - return TQString::number( uid ); - } - else - return *temp; -} - - -TQString KACL::KACLPrivate::getGroupName( gid_t gid ) const -{ - TQString *temp; - temp = m_groupcache.find( gid ); - if ( !temp ) { - struct group *grp = getgrgid( gid ); - if ( grp ) { - m_groupcache.insert( gid, new TQString(TQString::fromLatin1(grp->gr_name)) ); - return TQString::fromLatin1( grp->gr_name ); - } - else - return TQString::number( gid ); - } - else - return *temp; -} - -static TQString aclAsString(const acl_t acl) -{ - char *aclString = acl_to_text( acl, 0 ); - TQString ret = TQString::fromLatin1( aclString ); - acl_free( (void*)aclString ); - return ret; -} - - -#endif - -void KACL::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -TQDataStream & operator<< ( TQDataStream & s, const KACL & a ) -{ - s << a.asString(); - return s; -} - -TQDataStream & operator>> ( TQDataStream & s, KACL & a ) -{ - TQString str; - s >> str; - a.setACL( str ); - return s; -} - -// vim:set ts=8 sw=4: diff --git a/kio/kio/kacl.h b/kio/kio/kacl.h deleted file mode 100644 index 1f60fde60..000000000 --- a/kio/kio/kacl.h +++ /dev/null @@ -1,207 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2005 Till Adam <adam@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kacl_h__ -#define __kacl_h__ - -#include <sys/types.h> -#include <kio/global.h> - -typedef QPair<TQString, unsigned short> ACLUserPermissions; -typedef TQValueList<ACLUserPermissions> ACLUserPermissionsList; -typedef TQValueListIterator<ACLUserPermissions> ACLUserPermissionsIterator; -typedef TQValueListConstIterator<ACLUserPermissions> ACLUserPermissionsConstIterator; - -typedef QPair<TQString, unsigned short> ACLGroupPermissions; -typedef TQValueList<ACLGroupPermissions> ACLGroupPermissionsList; -typedef TQValueListIterator<ACLGroupPermissions> ACLGroupPermissionsIterator; -typedef TQValueListConstIterator<ACLGroupPermissions> ACLGroupPermissionsConstIterator; - -/** - * The KCAL class encapsulates a POSIX Access Control List. It follows the - * little standard that couldn't, 1003.1e/1003.2c, which died in draft status. - * @short a POSIX ACL encapsulation - * @author Till Adam <adam@kde.org> - */ -class TDEIO_EXPORT KACL -{ -public: - /** - * Creates a new KACL from @p aclString. If the string is a valid acl - * string, isValid() will afterwards return true. - */ - KACL( const TQString & aclString ); - - /** Copy ctor */ - KACL( const KACL& rhs ); - - /** - * Creates a new KACL from the basic permissions passed in @p basicPermissions. - * isValid() will return true, afterwards. - */ - KACL( mode_t basicPermissions ); - - /** - * Creates an empty KACL. Until a valid acl string is set via setACL, - * isValid() will return false. - */ - KACL(); - - virtual ~KACL(); - - KACL& operator=( const KACL& rhs ) { - if ( this != &rhs ) - setACL( rhs.asString() ); - return *this; - } - - bool operator==( const KACL& rhs ) const; - - bool operator!=( const KACL& rhs ) const { - return !operator==( rhs ); - } - - /** - * Returns whether the KACL object represents a valid acl. - * @return whether the KACL object represents a valid acl. - */ - bool isValid() const; - - /** The standard (non-extended) part of an ACL. These map directly to - * standard unix file permissions. Setting them will never make a valid - * ACL invalid. */ - - /** @return the owner's premissions entry */ - unsigned short ownerPermissions() const; - - /** Set the owner's permissions entry. - * @return success or failure */ - bool setOwnerPermissions( unsigned short ); - - /** @return the owning group's premissions entry */ - unsigned short owningGroupPermissions() const; - - /** Set the owning group's permissions entry. - * @return success or failure */ - bool setOwningGroupPermissions( unsigned short ); - - /** @return the premissions entry for others */ - unsigned short othersPermissions() const; - - /** Set the permissions entry for others. - * @return success or failure */ - bool setOthersPermissions( unsigned short ); - - /** @return the basic (owner/group/others) part of the ACL as a mode_t */ - mode_t basePermissions() const; - - /** The interface to the extended ACL. This is a mask, permissions for - * n named users and permissions for m named groups. */ - - /** - * Return whether the ACL contains extended entries or can be expressed - * using only basic file permissions. - * @return whether the ACL contains extended entries */ - bool isExtended() const; - - /** - * Return the entry for the permissions mask if there is one and sets - * @p exists to true. If there is no such entry, @p exists is set to false. - * @return the permissions mask entry */ - unsigned short maskPermissions( bool &exists ) const; - - /** Set the permissions mask for the ACL. Permissions set for individual - * entries will be masked with this, such that their effective permissions - * are the result of the logical and of their entry and the mask. - * @return success or failure */ - bool setMaskPermissions( unsigned short ); - - /** - * Access to the permissions entry for a named user, if such an entry - * exists. @p exists is set to true if a matching entry exists and - * to false otherwise. - * @return the permissions for a user entry with the name in @p name */ - unsigned short namedUserPermissions( const TQString& name, bool *exists ) const; - - - /** Set the permissions for a user with the name @p name. Will fail - * if the user doesn't exist, in which case the ACL will be unchanged. - * @return success or failure. */ - bool setNamedUserPermissions( const TQString& name, unsigned short ); - - /** Returns the list of all group permission entries. Each entry consists - * of a name/permissions pair. This is a QPair, therefore access is provided - * via the .first and .next members. - * @return the list of all group permission entries. */ - ACLUserPermissionsList allUserPermissions() const; - - /** Replace the list of all user permissions with @p list. If one - * of the entries in the list does not exists, or setting of the ACL - * entry fails for any reason, the ACL will be left unchanged. - * @return success or failure */ - bool setAllUserPermissions( const ACLUserPermissionsList &list ); - - /** - * Access to the permissions entry for a named group, if such an entry - * exists. @p exists is set to true if a matching entry exists and - * to false otherwise. - * @return the permissions for a group with the name in @p name */ - unsigned short namedGroupPermissions( const TQString& name, bool *exists ) const; - - /** Set the permissions for a group with the name @p name. Will fail - * if the group doesn't exist, in which case the ACL be unchanged. - * @return success or failure. */ - bool setNamedGroupPermissions( const TQString& name, unsigned short ); - - /** Returns the list of all group permission entries. Each entry consists - * of a name/permissions pair. This is a QPair, therefor access is provided - * via the .first and .next members. - * @return the list of all group permission entries. */ - - ACLGroupPermissionsList allGroupPermissions() const; - /** Replace the list of all user permissions with @p list. If one - * of the entries in the list does not exists, or setting of the ACL - * entry fails for any reason, the ACL will be left unchanged. - * @return success or failure */ - bool setAllGroupPermissions( const ACLGroupPermissionsList & ); - - /** Sets the whole list from a string. If the string in @p aclStr represents - * a valid ACL, it will be set, otherwise the ACL remains unchanged. - * @return whether setting the ACL was successful. */ - bool setACL( const TQString &aclStr ); - - /** Return a string representation of the ACL. - * @return a string version of the ACL in the format compatible with libacl and - * POSIX 1003.1e. Implementations conforming to that standard should be able - * to take such strings as input. */ - TQString asString() const; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KACLPrivate; - KACLPrivate * d; - TDEIO_EXPORT friend TQDataStream & operator<< ( TQDataStream & s, const KACL & a ); - TDEIO_EXPORT friend TQDataStream & operator>> ( TQDataStream & s, KACL & a ); -}; - -TDEIO_EXPORT TQDataStream & operator<< ( TQDataStream & s, const KACL & a ); -TDEIO_EXPORT TQDataStream & operator>> ( TQDataStream & s, KACL & a ); - -#endif diff --git a/kio/kio/kar.cpp b/kio/kio/kar.cpp deleted file mode 100644 index 07072d0c6..000000000 --- a/kio/kio/kar.cpp +++ /dev/null @@ -1,170 +0,0 @@ - -/* This file is part of the KDE libraries - Copyright (C) 2002 Laurence Anderson <l.d.anderson@warwick.ac.uk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqfile.h> -#include <tqdir.h> -#include <time.h> -#include <kdebug.h> -#include <tqptrlist.h> -#include <kmimetype.h> -#include <tqregexp.h> - -#include "kfilterdev.h" -#include "kar.h" -//#include "klimitediodevice.h" - -//////////////////////////////////////////////////////////////////////// -/////////////////////////// KAr /////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -class KAr::KArPrivate -{ -public: - KArPrivate() {} -}; - -KAr::KAr( const TQString& filename ) - : KArchive( 0L ) -{ - //kdDebug(7042) << "KAr(filename) reached." << endl; - m_filename = filename; - d = new KArPrivate; - setDevice( TQT_TQIODEVICE(new TQFile( filename )) ); -} - -KAr::KAr( TQIODevice * dev ) - : KArchive( dev ) -{ - //kdDebug(7042) << "KAr::KAr( TQIODevice * dev) reached." << endl; - d = new KArPrivate; -} - -KAr::~KAr() -{ - // mjarrett: Closes to prevent ~KArchive from aborting w/o device - //kdDebug(7042) << "~KAr reached." << endl; - if( isOpened() ) - close(); - if ( !m_filename.isEmpty() ) - delete device(); // we created it ourselves - delete d; -} - -bool KAr::openArchive( int mode ) -{ - // Open archive - - //kdDebug(7042) << "openarchive reached." << endl; - - if ( mode == IO_WriteOnly ) - return true; - if ( mode != IO_ReadOnly && mode != IO_ReadWrite ) - { - kdWarning(7042) << "Unsupported mode " << mode << endl; - return false; - } - - TQIODevice* dev = device(); - if ( !dev ) - return false; - - char magic[8]; - dev->readBlock (magic, 8); - if (tqstrncmp(magic, "!<arch>", 7) != 0) { - kdWarning(7042) << "Invalid main magic" << endl; - return false; - } - - char *ar_longnames = 0; - while (! dev->atEnd()) { - TQCString ar_header; - ar_header.resize(61); - TQCString name; - int date, uid, gid, mode, size; - - dev->at( dev->at() + (2 - (dev->at() % 2)) % 2 ); // Ar headers are padded to byte boundary - - if ( dev->readBlock (ar_header.data(), 60) != 60 ) { // Read ar header - kdWarning(7042) << "Couldn't read header" << endl; - delete[] ar_longnames; - //return false; - return true; // Probably EOF / trailing junk - } - - if (ar_header.right(2) != "`\n") { // Check header magic - kdWarning(7042) << "Invalid magic" << endl; - delete[] ar_longnames; - return false; - } - - name = ar_header.mid( 0, 16 ); // Process header - date = ar_header.mid( 16, 12 ).toInt(); - uid = ar_header.mid( 28, 6 ).toInt(); - gid = ar_header.mid( 34, 6 ).toInt(); - mode = ar_header.mid( 40, 8 ).toInt(); - size = ar_header.mid( 48, 10 ).toInt(); - - bool skip_entry = false; // Deal with special entries - if (name.mid(0, 1) == "/") { - if (name.mid(1, 1) == "/") { // Longfilename table entry - delete[] ar_longnames; - ar_longnames = new char[size + 1]; - ar_longnames[size] = '\0'; - dev->readBlock (ar_longnames, size); - skip_entry = true; - kdDebug(7042) << "Read in longnames entry" << endl; - } else if (name.mid(1, 1) == " ") { // Symbol table entry - kdDebug(7042) << "Skipped symbol entry" << endl; - dev->at( dev->at() + size ); - skip_entry = true; - } else { // Longfilename - kdDebug(7042) << "Longfilename #" << name.mid(1, 15).toInt() << endl; - if (! ar_longnames) { - kdWarning(7042) << "Invalid longfilename reference" << endl; - return false; - } - name = &ar_longnames[name.mid(1, 15).toInt()]; - name = name.left(name.find("/")); - } - } - if (skip_entry) continue; - - name = name.stripWhiteSpace(); // Process filename - name.replace( "/", "" ); - kdDebug(7042) << "Filename: " << name << " Size: " << size << endl; - - KArchiveEntry* entry; - entry = new KArchiveFile(this, name, mode, date, /*uid*/ 0, /*gid*/ 0, 0, dev->at(), size); - rootDir()->addEntry(entry); // Ar files don't support directorys, so everything in root - - dev->at( dev->at() + size ); // Skip contents - } - delete[] ar_longnames; - - return true; -} - -bool KAr::closeArchive() -{ - // Close the archive - return true; -} - -void KAr::virtual_hook( int id, void* data ) -{ KArchive::virtual_hook( id, data ); } diff --git a/kio/kio/kar.h b/kio/kio/kar.h deleted file mode 100644 index 83d94e75c..000000000 --- a/kio/kio/kar.h +++ /dev/null @@ -1,103 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2002 Laurence Anderson <l.d.anderson@warwick.ac.uk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __kar_h -#define __kar_h - -#include <sys/stat.h> -#include <sys/types.h> - -#include <tqdatetime.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqdict.h> - -#include <karchive.h> - -/** - * KAr is a class for reading archives in ar format. Writing - * is not supported. - * @short A class for reading ar archives. - * @author Laurence Anderson <l.d.anderson@warwick.ac.uk> - * @since 3.1 - */ -class TDEIO_EXPORT KAr : public KArchive -{ -public: - /** - * Creates an instance that operates on the given filename. - * - * @param filename is a local path (e.g. "/home/holger/myfile.ar") - */ - KAr( const TQString& filename ); - - /** - * Creates an instance that operates on the given device. - * The device can be compressed (KFilterDev) or not (TQFile, etc.). - * @param dev the device to read from - */ - KAr( TQIODevice * dev ); - - /** - * If the ar file is still opened, then it will be - * closed automatically by the destructor. - */ - virtual ~KAr(); - - /** - * The name of the ar file, as passed to the constructor. - * @return the filename. Null if you used the TQIODevice constructor - */ - TQString fileName() { return m_filename; } - - /* - * Writing not supported by this class, will always fail. - * @return always false - */ - virtual bool prepareWriting( const TQString& name, const TQString& user, const TQString& group, uint size ) { Q_UNUSED(name); Q_UNUSED(user); Q_UNUSED(group); Q_UNUSED(size); return false; } - - /* - * Writing not supported by this class, will always fail. - * @return always false - */ - virtual bool doneWriting( uint size ) { Q_UNUSED(size); return false; } - - /* - * Writing not supported by this class, will always fail. - * @return always false - */ - virtual bool writeDir( const TQString& name, const TQString& user, const TQString& group ) { Q_UNUSED(name); Q_UNUSED(user); Q_UNUSED(group); return false; } - -protected: - /** - * Opens the archive for reading. - * Parses the directory listing of the archive - * and creates the KArchiveDirectory/KArchiveFile entries. - * - */ - virtual bool openArchive( int mode ); - virtual bool closeArchive(); - -protected: - virtual void virtual_hook( int id, void* data ); -private: - TQString m_filename; - class KArPrivate; - KArPrivate * d; -}; - -#endif diff --git a/kio/kio/karchive.cpp b/kio/kio/karchive.cpp deleted file mode 100644 index 0e8d6789d..000000000 --- a/kio/kio/karchive.cpp +++ /dev/null @@ -1,717 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - Copyright (C) 2003 Leo Savernik <l.savernik@aon.at> - - Moved from ktar.cpp by Roberto Teixeira <maragato@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <unistd.h> -#include <errno.h> -#include <grp.h> -#include <pwd.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <tqptrlist.h> -#include <tqptrstack.h> -#include <tqvaluestack.h> -#include <tqmap.h> -#include <tqcstring.h> -#include <tqdir.h> -#include <tqfile.h> - -#include <kdebug.h> -#include <kfilterdev.h> -#include <kfilterbase.h> -#include <kde_file.h> - -#include "karchive.h" -#include "klimitediodevice.h" - -template class TQDict<KArchiveEntry>; - - -class KArchive::KArchivePrivate -{ -public: - KArchiveDirectory* rootDir; - bool closeSucceeded; -}; - -class PosSortedPtrList : public TQPtrList<KArchiveFile> { -protected: - int compareItems( TQPtrCollection::Item i1, - TQPtrCollection::Item i2 ) - { - int pos1 = static_cast<KArchiveFile*>( i1 )->position(); - int pos2 = static_cast<KArchiveFile*>( i2 )->position(); - return ( pos1 - pos2 ); - } -}; - - -//////////////////////////////////////////////////////////////////////// -/////////////////////////// KArchive /////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -KArchive::KArchive( TQIODevice * dev ) -{ - d = new KArchivePrivate; - d->rootDir = 0; - m_dev = dev; - m_open = false; -} - -KArchive::~KArchive() -{ - if ( m_open ) - close(); - delete d->rootDir; - delete d; -} - -bool KArchive::open( int mode ) -{ - if ( m_dev && !m_dev->open( mode ) ) - return false; - - if ( m_open ) - close(); - - m_mode = mode; - m_open = true; - - Q_ASSERT( d->rootDir == 0L ); - d->rootDir = 0L; - - return openArchive( mode ); -} - -void KArchive::close() -{ - if ( !m_open ) - return; - // moved by holger to allow kzip to write the zip central dir - // to the file in closeArchive() - d->closeSucceeded = closeArchive(); - - if ( m_dev ) - m_dev->close(); - - delete d->rootDir; - d->rootDir = 0; - m_open = false; -} - -bool KArchive::closeSucceeded() const -{ - return d->closeSucceeded; -} - -const KArchiveDirectory* KArchive::directory() const -{ - // rootDir isn't const so that parsing-on-demand is possible - return const_cast<KArchive *>(this)->rootDir(); -} - - -bool KArchive::addLocalFile( const TQString& fileName, const TQString& destName ) -{ - TQFileInfo fileInfo( fileName ); - if ( !fileInfo.isFile() && !fileInfo.isSymLink() ) - { - kdWarning() << "KArchive::addLocalFile " << fileName << " doesn't exist or is not a regular file." << endl; - return false; - } - - KDE_struct_stat fi; - if (KDE_lstat(TQFile::encodeName(fileName),&fi) == -1) { - kdWarning() << "KArchive::addLocalFile stating " << fileName - << " failed: " << strerror(errno) << endl; - return false; - } - - if (fileInfo.isSymLink()) { - return writeSymLink(destName, fileInfo.readLink(), fileInfo.owner(), - fileInfo.group(), fi.st_mode, fi.st_atime, fi.st_mtime, - fi.st_ctime); - }/*end if*/ - - uint size = fileInfo.size(); - - // the file must be opened before prepareWriting is called, otherwise - // if the opening fails, no content will follow the already written - // header and the tar file is effectively f*cked up - TQFile file( fileName ); - if ( !file.open( IO_ReadOnly ) ) - { - kdWarning() << "KArchive::addLocalFile couldn't open file " << fileName << endl; - return false; - } - - if ( !prepareWriting( destName, fileInfo.owner(), fileInfo.group(), size, - fi.st_mode, fi.st_atime, fi.st_mtime, fi.st_ctime ) ) - { - kdWarning() << "KArchive::addLocalFile prepareWriting " << destName << " failed" << endl; - return false; - } - - // Read and write data in chunks to minimize memory usage - TQByteArray array(8*1024); - int n; - uint total = 0; - while ( ( n = file.readBlock( array.data(), array.size() ) ) > 0 ) - { - if ( !writeData( array.data(), n ) ) - { - kdWarning() << "KArchive::addLocalFile writeData failed" << endl; - return false; - } - total += n; - } - Q_ASSERT( total == size ); - - if ( !doneWriting( size ) ) - { - kdWarning() << "KArchive::addLocalFile doneWriting failed" << endl; - return false; - } - return true; -} - -bool KArchive::addLocalDirectory( const TQString& path, const TQString& destName ) -{ - TQString dot = "."; - TQString dotdot = ".."; - TQDir dir( path ); - if ( !dir.exists() ) - return false; - dir.setFilter(dir.filter() | TQDir::Hidden); - TQStringList files = dir.entryList(); - for ( TQStringList::Iterator it = files.begin(); it != files.end(); ++it ) - { - if ( *it != dot && *it != dotdot ) - { - TQString fileName = path + "/" + *it; -// kdDebug() << "storing " << fileName << endl; - TQString dest = destName.isEmpty() ? *it : (destName + "/" + *it); - TQFileInfo fileInfo( fileName ); - - if ( fileInfo.isFile() || fileInfo.isSymLink() ) - addLocalFile( fileName, dest ); - else if ( fileInfo.isDir() ) - addLocalDirectory( fileName, dest ); - // We omit sockets - } - } - return true; -} - -bool KArchive::writeFile( const TQString& name, const TQString& user, const TQString& group, uint size, const char* data ) -{ - mode_t perm = 0100644; - time_t the_time = time(0); - return writeFile(name,user,group,size,perm,the_time,the_time,the_time,data); -} - -bool KArchive::prepareWriting( const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime ) { - PrepareWritingParams params; - params.name = &name; - params.user = &user; - params.group = &group; - params.size = size; - params.perm = perm; - params.atime = atime; - params.mtime = mtime; - params.ctime = ctime; - virtual_hook(VIRTUAL_PREPARE_WRITING,¶ms); - return params.retval; -} - -bool KArchive::prepareWriting_impl(const TQString &name, const TQString &user, - const TQString &group, uint size, mode_t /*perm*/, - time_t /*atime*/, time_t /*mtime*/, time_t /*ctime*/ ) { - kdWarning(7040) << "New prepareWriting API not implemented in this class." << endl - << "Falling back to old API (metadata information will be lost)" << endl; - return prepareWriting(name,user,group,size); -} - -bool KArchive::writeFile( const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime, - const char* data ) { - WriteFileParams params; - params.name = &name; - params.user = &user; - params.group = &group; - params.size = size; - params.perm = perm; - params.atime = atime; - params.mtime = mtime; - params.ctime = ctime; - params.data = data; - virtual_hook(VIRTUAL_WRITE_FILE,¶ms); - return params.retval; -} - -bool KArchive::writeFile_impl( const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime, - const char* data ) { - - if ( !prepareWriting( name, user, group, size, perm, atime, mtime, ctime ) ) - { - kdWarning() << "KArchive::writeFile prepareWriting failed" << endl; - return false; - } - - // Write data - // Note: if data is 0L, don't call writeBlock, it would terminate the KFilterDev - if ( data && size && !writeData( data, size ) ) - { - kdWarning() << "KArchive::writeFile writeData failed" << endl; - return false; - } - - if ( !doneWriting( size ) ) - { - kdWarning() << "KArchive::writeFile doneWriting failed" << endl; - return false; - } - return true; -} - -bool KArchive::writeDir(const TQString& name, const TQString& user, - const TQString& group, mode_t perm, - time_t atime, time_t mtime, time_t ctime) { - WriteDirParams params; - params.name = &name; - params.user = &user; - params.group = &group; - params.perm = perm; - params.atime = atime; - params.mtime = mtime; - params.ctime = ctime; - virtual_hook(VIRTUAL_WRITE_DIR,¶ms); - return params.retval; -} - -bool KArchive::writeDir_impl(const TQString &name, const TQString &user, - const TQString &group, mode_t /*perm*/, - time_t /*atime*/, time_t /*mtime*/, time_t /*ctime*/ ) { - kdWarning(7040) << "New writeDir API not implemented in this class." << endl - << "Falling back to old API (metadata information will be lost)" << endl; - return writeDir(name,user,group); -} - -bool KArchive::writeSymLink(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t atime, time_t mtime, time_t ctime) { - WriteSymlinkParams params; - params.name = &name; - params.target = ⌖ - params.user = &user; - params.group = &group; - params.perm = perm; - params.atime = atime; - params.mtime = mtime; - params.ctime = ctime; - virtual_hook(VIRTUAL_WRITE_SYMLINK,¶ms); - return params.retval; -} - -bool KArchive::writeSymLink_impl(const TQString &/*name*/,const TQString &/*target*/, - const TQString &/*user*/, const TQString &/*group*/, - mode_t /*perm*/, time_t /*atime*/, time_t /*mtime*/, - time_t /*ctime*/) { - kdWarning(7040) << "writeSymLink not implemented in this class." << endl - << "No fallback available." << endl; - // FIXME: better return true here for compatibility with KDE < 3.2 - return false; -} - -bool KArchive::writeData( const char* data, uint size ) -{ - WriteDataParams params; - params.data = data; - params.size = size; - virtual_hook( VIRTUAL_WRITE_DATA, ¶ms ); - return params.retval; -} - -bool KArchive::writeData_impl( const char* data, uint size ) -{ - Q_ASSERT( device() ); - return device()->writeBlock( data, size ) == (TQ_LONG)size; -} - -KArchiveDirectory * KArchive::rootDir() -{ - if ( !d->rootDir ) - { - //kdDebug() << "Making root dir " << endl; - struct passwd* pw = getpwuid( getuid() ); - struct group* grp = getgrgid( getgid() ); - TQString username = pw ? TQFile::decodeName(pw->pw_name) : TQString::number( getuid() ); - TQString groupname = grp ? TQFile::decodeName(grp->gr_name) : TQString::number( getgid() ); - - d->rootDir = new KArchiveDirectory( this, TQString::fromLatin1("/"), (int)(0777 + S_IFDIR), 0, username, groupname, TQString::null ); - } - return d->rootDir; -} - -KArchiveDirectory * KArchive::findOrCreate( const TQString & path ) -{ - //kdDebug() << "KArchive::findOrCreate " << path << endl; - if ( path.isEmpty() || path == "/" || path == "." ) // root dir => found - { - //kdDebug() << "KArchive::findOrCreate returning rootdir" << endl; - return rootDir(); - } - // Important note : for tar files containing absolute paths - // (i.e. beginning with "/"), this means the leading "/" will - // be removed (no KDirectory for it), which is exactly the way - // the "tar" program works (though it displays a warning about it) - // See also KArchiveDirectory::entry(). - - // Already created ? => found - KArchiveEntry* ent = rootDir()->entry( path ); - if ( ent ) - { - if ( ent->isDirectory() ) - //kdDebug() << "KArchive::findOrCreate found it" << endl; - return (KArchiveDirectory *) ent; - else - kdWarning() << "Found " << path << " but it's not a directory" << endl; - } - - // Otherwise go up and try again - int pos = path.findRev( '/' ); - KArchiveDirectory * parent; - TQString dirname; - if ( pos == -1 ) // no more slash => create in root dir - { - parent = rootDir(); - dirname = path; - } - else - { - TQString left = path.left( pos ); - dirname = path.mid( pos + 1 ); - parent = findOrCreate( left ); // recursive call... until we find an existing dir. - } - - //kdDebug() << "KTar : found parent " << parent->name() << " adding " << dirname << " to ensure " << path << endl; - // Found -> add the missing piece - KArchiveDirectory * e = new KArchiveDirectory( this, dirname, d->rootDir->permissions(), - d->rootDir->date(), d->rootDir->user(), - d->rootDir->group(), TQString::null ); - parent->addEntry( e ); - return e; // now a directory to <path> exists -} - -void KArchive::setDevice( TQIODevice * dev ) -{ - m_dev = dev; -} - -void KArchive::setRootDir( KArchiveDirectory *rootDir ) -{ - Q_ASSERT( !d->rootDir ); // Call setRootDir only once during parsing please ;) - d->rootDir = rootDir; -} - -//////////////////////////////////////////////////////////////////////// -/////////////////////// KArchiveEntry ////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -KArchiveEntry::KArchiveEntry( KArchive* t, const TQString& name, int access, int date, - const TQString& user, const TQString& group, const - TQString& symlink) -{ - m_name = name; - m_access = access; - m_date = date; - m_user = user; - m_group = group; - m_symlink = symlink; - m_archive = t; - -} - -TQDateTime KArchiveEntry::datetime() const -{ - TQDateTime d; - d.setTime_t( m_date ); - return d; -} - -//////////////////////////////////////////////////////////////////////// -/////////////////////// KArchiveFile /////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -KArchiveFile::KArchiveFile( KArchive* t, const TQString& name, int access, int date, - const TQString& user, const TQString& group, - const TQString & symlink, - int pos, int size ) - : KArchiveEntry( t, name, access, date, user, group, symlink ) -{ - m_pos = pos; - m_size = size; -} - -int KArchiveFile::position() const -{ - return m_pos; -} - -int KArchiveFile::size() const -{ - return m_size; -} - -TQByteArray KArchiveFile::data() const -{ - archive()->device()->at( m_pos ); - - // Read content - TQByteArray arr( m_size ); - if ( m_size ) - { - assert( arr.data() ); - int n = archive()->device()->readBlock( arr.data(), m_size ); - if ( n != m_size ) - arr.resize( n ); - } - return arr; -} - -// ** This should be a virtual method, and this code should be in ktar.cpp -TQIODevice *KArchiveFile::device() const -{ - return new KLimitedIODevice( archive()->device(), m_pos, m_size ); -} - -void KArchiveFile::copyTo(const TQString& dest) const -{ - TQFile f( dest + "/" + name() ); - f.open( IO_ReadWrite | IO_Truncate ); - f.writeBlock( data() ); - f.close(); -} - -//////////////////////////////////////////////////////////////////////// -//////////////////////// KArchiveDirectory ///////////////////////////////// -//////////////////////////////////////////////////////////////////////// - - -KArchiveDirectory::KArchiveDirectory( KArchive* t, const TQString& name, int access, - int date, - const TQString& user, const TQString& group, - const TQString &symlink) - : KArchiveEntry( t, name, access, date, user, group, symlink ) -{ - m_entries.setAutoDelete( true ); -} - -TQStringList KArchiveDirectory::entries() const -{ - TQStringList l; - - TQDictIterator<KArchiveEntry> it( m_entries ); - for( ; it.current(); ++it ) - l.append( it.currentKey() ); - - return l; -} - -KArchiveEntry* KArchiveDirectory::entry( TQString name ) - // not "const TQString & name" since we want a local copy - // (to remove leading slash if any) -{ - int pos = name.find( '/' ); - if ( pos == 0 ) // ouch absolute path (see also KArchive::findOrCreate) - { - if (name.length()>1) - { - name = name.mid( 1 ); // remove leading slash - pos = name.find( '/' ); // look again - } - else // "/" - return this; - } - // trailing slash ? -> remove - if ( pos != -1 && pos == (int)name.length()-1 ) - { - name = name.left( pos ); - pos = name.find( '/' ); // look again - } - if ( pos != -1 ) - { - TQString left = name.left( pos ); - TQString right = name.mid( pos + 1 ); - - //kdDebug() << "KArchiveDirectory::entry left=" << left << " right=" << right << endl; - - KArchiveEntry* e = m_entries[ left ]; - if ( !e || !e->isDirectory() ) - return 0; - return ((KArchiveDirectory*)e)->entry( right ); - } - - return m_entries[ name ]; -} - -const KArchiveEntry* KArchiveDirectory::entry( TQString name ) const -{ - return ((KArchiveDirectory*)this)->entry( name ); -} - -void KArchiveDirectory::addEntry( KArchiveEntry* entry ) -{ - Q_ASSERT( !entry->name().isEmpty() ); - if( m_entries[ entry->name() ] ) { - kdWarning() << "KArchiveDirectory::addEntry: directory " << name() - << " has entry " << entry->name() << " already" << endl; - } - m_entries.insert( entry->name(), entry ); -} - -void KArchiveDirectory::copyTo(const TQString& dest, bool recursiveCopy ) const -{ - TQDir root; - - PosSortedPtrList fileList; - TQMap<int, TQString> fileToDir; - - TQStringList::Iterator it; - - // placeholders for iterated items - KArchiveDirectory* curDir; - TQString curDirName; - - TQStringList dirEntries; - KArchiveEntry* curEntry; - KArchiveFile* curFile; - - - TQPtrStack<KArchiveDirectory> dirStack; - TQValueStack<TQString> dirNameStack; - - dirStack.push( this ); // init stack at current directory - dirNameStack.push( dest ); // ... with given path - do { - curDir = dirStack.pop(); - curDirName = dirNameStack.pop(); - root.mkdir(curDirName); - - dirEntries = curDir->entries(); - for ( it = dirEntries.begin(); it != dirEntries.end(); ++it ) { - curEntry = curDir->entry(*it); - if (!curEntry->symlink().isEmpty()) { - const TQString linkName = curDirName+'/'+curEntry->name(); - kdDebug() << "symlink(" << curEntry->symlink() << ',' << linkName << ')'; -#ifdef Q_OS_UNIX - if (!::symlink(curEntry->symlink().local8Bit(), linkName.local8Bit())) { - kdDebug() << "symlink(" << curEntry->symlink() << ',' << linkName << ") failed:" << strerror(errno); - } -#endif - } else { - if ( curEntry->isFile() ) { - curFile = dynamic_cast<KArchiveFile*>( curEntry ); - if (curFile) { - fileList.append( curFile ); - fileToDir.insert( curFile->position(), curDirName ); - } - } - - if ( curEntry->isDirectory() ) - if ( recursiveCopy ) { - KArchiveDirectory *ad = dynamic_cast<KArchiveDirectory*>( curEntry ); - if (ad) { - dirStack.push( ad ); - dirNameStack.push( curDirName + "/" + curEntry->name() ); - } - } - } - } - } while (!dirStack.isEmpty()); - - fileList.sort(); // sort on m_pos, so we have a linear access - - KArchiveFile* f; - for ( f = fileList.first(); f; f = fileList.next() ) { - int pos = f->position(); - f->copyTo( fileToDir[pos] ); - } -} - -void KArchive::virtual_hook( int id, void* data ) -{ - switch (id) { - case VIRTUAL_WRITE_DATA: { - WriteDataParams* params = reinterpret_cast<WriteDataParams *>(data); - params->retval = writeData_impl( params->data, params->size ); - break; - } - case VIRTUAL_WRITE_SYMLINK: { - WriteSymlinkParams *params = reinterpret_cast<WriteSymlinkParams *>(data); - params->retval = writeSymLink_impl(*params->name,*params->target, - *params->user,*params->group,params->perm, - params->atime,params->mtime,params->ctime); - break; - } - case VIRTUAL_WRITE_DIR: { - WriteDirParams *params = reinterpret_cast<WriteDirParams *>(data); - params->retval = writeDir_impl(*params->name,*params->user, - *params->group,params->perm, - params->atime,params->mtime,params->ctime); - break; - } - case VIRTUAL_WRITE_FILE: { - WriteFileParams *params = reinterpret_cast<WriteFileParams *>(data); - params->retval = writeFile_impl(*params->name,*params->user, - *params->group,params->size,params->perm, - params->atime,params->mtime,params->ctime, - params->data); - break; - } - case VIRTUAL_PREPARE_WRITING: { - PrepareWritingParams *params = reinterpret_cast<PrepareWritingParams *>(data); - params->retval = prepareWriting_impl(*params->name,*params->user, - *params->group,params->size,params->perm, - params->atime,params->mtime,params->ctime); - break; - } - default: - /*BASE::virtual_hook( id, data )*/; - }/*end switch*/ -} - -void KArchiveEntry::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -void KArchiveFile::virtual_hook( int id, void* data ) -{ KArchiveEntry::virtual_hook( id, data ); } - -void KArchiveDirectory::virtual_hook( int id, void* data ) -{ KArchiveEntry::virtual_hook( id, data ); } diff --git a/kio/kio/karchive.h b/kio/kio/karchive.h deleted file mode 100644 index 840c560b7..000000000 --- a/kio/kio/karchive.h +++ /dev/null @@ -1,639 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - Copyright (C) 2003 Leo Savernik <l.savernik@aon.at> - - Moved from ktar.h by Roberto Teixeira <maragato@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __karchive_h -#define __karchive_h - -#include <sys/stat.h> -#include <sys/types.h> - -#include <tqdatetime.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqdict.h> - -#include <tdelibs_export.h> - -class KArchiveDirectory; -class KArchiveFile; - -/** - * KArchive is a base class for reading and writing archives. - * @short generic class for reading/writing archives - * @author David Faure <faure@kde.org> - */ -class TDEIO_EXPORT KArchive -{ -protected: - /** - * Base constructor (protected since this is a pure virtual class). - * @param dev the I/O device where the archive reads its data - * Note that this can be a file, but also a data buffer, a compression filter, etc. - */ - KArchive( TQIODevice * dev ); - -public: - virtual ~KArchive(); - - /** - * Opens the archive for reading or writing. - * Inherited classes might want to reimplement openArchive instead. - * @param mode may be IO_ReadOnly or IO_WriteOnly - * @see close - */ - virtual bool open( int mode ); - - /** - * Closes the archive. - * Inherited classes might want to reimplement closeArchive instead. - * - * @see open - */ - virtual void close(); - - /** - * Use to check if close had any problem - * @return true if close succeded without problems - * @since 3.5 - */ - // TODO KDE4 merge with above - bool closeSucceeded() const; - - /** - * Checks whether the archive is open. - * @return true if the archive is opened - */ - bool isOpened() const { return m_open; } - - /** - * Returns the mode in which the archive was opened - * @return the mode in which the archive was opened (IO_ReadOnly or IO_WriteOnly) - * @see open() - */ - int mode() const { return m_mode; } - - /** - * The underlying device. - * @return the underlying device. - */ - TQIODevice * device() const { return m_dev; } - - /** - * If an archive is opened for reading, then the contents - * of the archive can be accessed via this function. - * @return the directory of the archive - */ - const KArchiveDirectory* directory() const; - - /** - * Writes a local file into the archive. The main difference with writeFile, - * is that this method minimizes memory usage, by not loading the whole file - * into memory in one go. - * - * If @p fileName is a symbolic link, it will be written as is, i. e. - * it will not be resolved before. - * @param fileName full path to an existing local file, to be added to the archive. - * @param destName the resulting name (or relative path) of the file in the archive. - */ - bool addLocalFile( const TQString& fileName, const TQString& destName ); - - /** - * Writes a local directory into the archive, including all its contents, recursively. - * Calls addLocalFile for each file to be added. - * - * Since KDE 3.2 it will also add a @p path that is a symbolic link to a - * directory. The symbolic link will be dereferenced and the content of the - * directory it is pointing to added recursively. However, symbolic links - * *under* @p path will be stored as is. - * @param path full path to an existing local directory, to be added to the archive. - * @param destName the resulting name (or relative path) of the file in the archive. - */ - bool addLocalDirectory( const TQString& path, const TQString& destName ); - - /** - * If an archive is opened for writing then you can add new directories - * using this function. KArchive won't write one directory twice. - * - * @param name the name of the directory - * @param user the user that owns the directory - * @param group the group that owns the directory - * - * @todo TODO(BIC): make this a thin wrapper around - * writeDir(name,user,group,perm,atime,mtime,ctime) - * or eliminate it - */ - virtual bool writeDir( const TQString& name, const TQString& user, const TQString& group ) = 0; - - /** - * If an archive is opened for writing then you can add new directories - * using this function. KArchive won't write one directory twice. - * - * This method also allows some file metadata to be - * set. However, depending on the archive type not all metadata might be - * regarded. - * @param name the name of the directory - * @param user the user that owns the directory - * @param group the group that owns the directory - * @param perm permissions of the directory - * @param atime time the file was last accessed - * @param mtime modification time of the file - * @param ctime creation time of the file - * @since 3.2 - * @todo TODO(BIC): make this virtual. For now use virtual hook - */ - bool writeDir( const TQString& name, const TQString& user, const TQString& group, - mode_t perm, time_t atime, time_t mtime, time_t ctime ); - - /** - * Writes a symbolic link to the archive if the archive must be opened for - * writing. - * @param name name of symbolic link - * @param target target of symbolic link - * @param user the user that owns the directory - * @param group the group that owns the directory - * @param perm permissions of the directory - * @param atime time the file was last accessed - * @param mtime modification time of the file - * @param ctime creation time of the file - * @since 3.2 - * @todo TODO(BIC) make virtual. For now it must be implemented by virtual_hook. - */ - bool writeSymLink(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t atime, time_t mtime, time_t ctime); - - /** - * If an archive is opened for writing then you can add a new file - * using this function. If the file name is for example "mydir/test1" then - * the directory "mydir" is automatically appended first if that did not - * happen yet. - * @param name the name of the file - * @param user the user that owns the file - * @param group the group that owns the file - * @param size the size of the file - * @param data the data to write (@p size bytes) - * @todo TODO(BIC): make this a thin non-virtual wrapper around - * writeFile(name,user,group,size,perm,atime,mtime,ctime,data) - */ - virtual bool writeFile( const TQString& name, const TQString& user, const TQString& group, uint size, const char* data ); - - /** - * If an archive is opened for writing then you can add a new file - * using this function. If the file name is for example "mydir/test1" then - * the directory "mydir" is automatically appended first if that did not - * happen yet. - * - * This method also allows some file metadata to be - * set. However, depending on the archive type not all metadata might be - * regarded. - * @param name the name of the file - * @param user the user that owns the file - * @param group the group that owns the file - * @param size the size of the file - * @param perm permissions of the file - * @param atime time the file was last accessed - * @param mtime modification time of the file - * @param ctime creation time of the file - * @param data the data to write (@p size bytes) - * @since 3.2 - * @todo TODO(BIC): make virtual. For now use virtual hook - */ - bool writeFile( const TQString& name, const TQString& user, const TQString& group, - uint size, mode_t perm, time_t atime, time_t mtime, - time_t ctime, const char* data ); - - /** - * Here's another way of writing a file into an archive: - * Call prepareWriting, then call writeData() - * as many times as wanted then call doneWriting( totalSize ). - * For tar.gz files, you need to know the size before hand, since it is needed in the header. - * For zip files, size isn't used. - * - * @param name the name of the file - * @param user the user that owns the file - * @param group the group that owns the file - * @param size the size of the file - * - * @todo TODO(BIC): make this a thin non-virtual wrapper around - * prepareWriting(name,user,group,size,perm,atime,mtime,ctime) - * or eliminate it. - */ - virtual bool prepareWriting( const TQString& name, const TQString& user, const TQString& group, uint size ) = 0; - - /** - * Here's another way of writing a file into an archive: - * Call prepareWriting, then call writeData() - * as many times as wanted then call doneWriting( totalSize ). - * For tar.gz files, you need to know the size before hand, it is needed in the header! - * For zip files, size isn't used. - * - * This method also allows some file metadata to be - * set. However, depending on the archive type not all metadata might be - * regarded. - * @param name the name of the file - * @param user the user that owns the file - * @param group the group that owns the file - * @param size the size of the file - * @param perm permissions of the file - * @param atime time the file was last accessed - * @param mtime modification time of the file - * @param ctime creation time of the file - * @since 3.2 - * @todo TODO(BIC): make this virtual. For now use virtual hook. - */ - bool prepareWriting( const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime ); - - /** - * Write data into the current file - to be called after calling prepareWriting - * @todo TODO(BIC) make virtual. For now virtual_hook allows reimplementing it. - */ - bool writeData( const char* data, uint size ); - - /** - * Call doneWriting after writing the data. - * @param size the size of the file - * @see prepareWriting() - */ - virtual bool doneWriting( uint size ) = 0; - -protected: - /** - * Opens an archive for reading or writing. - * Called by open. - * @param mode may be IO_ReadOnly or IO_WriteOnly - */ - virtual bool openArchive( int mode ) = 0; - - /** - * Closes the archive. - * Called by close. - */ - virtual bool closeArchive() = 0; - - /** - * Retrieves or create the root directory. - * The default implementation assumes that openArchive() did the parsing, - * so it creates a dummy rootdir if none was set (write mode, or no '/' in the archive). - * Reimplement this to provide parsing/listing on demand. - * @return the root directory - */ - virtual KArchiveDirectory* rootDir(); - - /** - * Ensures that @p path exists, create otherwise. - * This handles e.g. tar files missing directory entries, like mico-2.3.0.tar.gz :) - * @param path the path of the directory - * @return the directory with the given @p path - */ - KArchiveDirectory * findOrCreate( const TQString & path ); - - /** - * @internal for inherited constructors - */ - void setDevice( TQIODevice *dev ); - - /** - * @internal for inherited classes - */ - void setRootDir( KArchiveDirectory *rootDir ); - -private: - TQIODevice * m_dev; - bool m_open; - char m_mode; -protected: - virtual void virtual_hook( int id, void* data ); - /* @internal for virtual_hook */ - enum { VIRTUAL_WRITE_DATA = 1, VIRTUAL_WRITE_SYMLINK, VIRTUAL_WRITE_DIR, - VIRTUAL_WRITE_FILE, VIRTUAL_PREPARE_WRITING }; - bool prepareWriting_impl( const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime ); - struct PrepareWritingParams { - const TQString *name; - const TQString *user; - const TQString *group; - uint size; - mode_t perm; - time_t atime, mtime, ctime; - bool retval; - }; - bool writeFile_impl( const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime, - const char* data ); - struct WriteFileParams { - const TQString *name; - const TQString *user; - const TQString *group; - uint size; - mode_t perm; - time_t atime, mtime, ctime; - const char *data; - bool retval; - }; - bool writeDir_impl(const TQString& name, const TQString& user, - const TQString& group, mode_t perm, - time_t atime, time_t mtime, time_t ctime); - struct WriteDirParams { - const TQString *name; - const TQString *user; - const TQString *group; - mode_t perm; - time_t atime, mtime, ctime; - bool retval; - }; - bool writeSymLink_impl(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t atime, time_t mtime, time_t ctime); - struct WriteSymlinkParams { - const TQString *name; - const TQString *target; - const TQString *user; - const TQString *group; - mode_t perm; - time_t atime, mtime, ctime; - bool retval; - }; - bool writeData_impl( const char* data, uint size ); - struct WriteDataParams { - const char* data; - uint size; - bool retval; - }; -private: - class KArchivePrivate; - KArchivePrivate * d; -}; - -/** - * A base class for entries in an KArchive. - * @short Base class for the archive-file's directory structure. - * - * @see KArchiveFile - * @see KArchiveDirectory - */ -class TDEIO_EXPORT KArchiveEntry -{ -public: - /** - * Creates a new entry. - * @param archive the entries archive - * @param name the name of the entry - * @param access the permissions in unix format - * @param date the date (in seconds since 1970) - * @param user the user that owns the entry - * @param group the group that owns the entry - * @param symlink the symlink, or TQString::null - */ - KArchiveEntry( KArchive* archive, const TQString& name, int access, int date, - const TQString& user, const TQString& group, - const TQString &symlink ); - - virtual ~KArchiveEntry() { } - - /** - * Creation date of the file. - * @return the creation date - */ - TQDateTime datetime() const; - - /** - * Creation date of the file. - * @return the creation date in seconds since 1970 - */ - int date() const { return m_date; } - - /** - * Name of the file without path. - * @return the file name without path - */ - TQString name() const { return m_name; } - /** - * The permissions and mode flags as returned by the stat() function - * in st_mode. - * @return the permissions - */ - mode_t permissions() const { return m_access; } - /** - * User who created the file. - * @return the owner of the file - */ - TQString user() const { return m_user; } - /** - * Group of the user who created the file. - * @return the group of the file - */ - TQString group() const { return m_group; } - - /** - * Symlink if there is one. - * @return the symlink, or TQString::null - */ - TQString symlink() const { return m_symlink; } - - /** - * Checks whether the entry is a file. - * @return true if this entry is a file - */ - virtual bool isFile() const { return false; } - - /** - * Checks whether the entry is a directory. - * @return true if this entry is a directory - */ - virtual bool isDirectory() const { return false; } - -protected: - KArchive* archive() const { return m_archive; } - -private: - TQString m_name; - int m_date; - mode_t m_access; - TQString m_user; - TQString m_group; - TQString m_symlink; - KArchive* m_archive; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KArchiveEntryPrivate* d; -}; - -/** - * Represents a file entry in a KArchive. - * @short A file in an archive. - * - * @see KArchive - * @see KArchiveDirectory - */ -class TDEIO_EXPORT KArchiveFile : public KArchiveEntry -{ -public: - /** - * Creates a new file entry. - * @param archive the entries archive - * @param name the name of the entry - * @param access the permissions in unix format - * @param date the date (in seconds since 1970) - * @param user the user that owns the entry - * @param group the group that owns the entry - * @param symlink the symlink, or TQString::null - * @param pos the position of the file in the directory - * @param size the size of the file - */ - KArchiveFile( KArchive* archive, const TQString& name, int access, int date, - const TQString& user, const TQString& group, const TQString &symlink, - int pos, int size ); - - virtual ~KArchiveFile() { } - - /** - * Position of the data in the [uncompressed] archive. - * @return the position of the file - */ - int position() const; // TODO use TQ_LONG in KDE-4.0 - /** - * Size of the data. - * @return the size of the file - */ - int size() const; // TODO use TQ_LONG in KDE-4.0 - /** - * Set size of data, usually after writing the file. - * @param s the new size of the file - */ - void setSize( int s ) { m_size = s; } - - /** - * Returns the data of the file. - * Call data() with care (only once per file), this data isn't cached. - * @return the content of this file. - */ - virtual TQByteArray data() const; - - /** - * This method returns TQIODevice (internal class: KLimitedIODevice) - * on top of the underlying TQIODevice. This is obviously for reading only. - * Note that the ownership of the device is being transferred to the caller, - * who will have to delete it. - * The returned device auto-opens (in readonly mode), no need to open it. - * @return the TQIODevice of the file - */ - TQIODevice *device() const; // TODO make virtual - - /** - * Checks whether this entry is a file. - * @return true, since this entry is a file - */ - virtual bool isFile() const { return true; } - - /** - * Extracts the file to the directory @p dest - * @param dest the directory to extract to - * @since 3.1 - */ - void copyTo(const TQString& dest) const; - -private: - int m_pos; // TODO use TQ_LONG in KDE-4.0 - int m_size; // TODO use TQ_LONG in KDE-4.0 -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KArchiveFilePrivate* d; -}; - -/** - * Represents a directory entry in a KArchive. - * @short A directory in an archive. - * - * @see KArchive - * @see KArchiveFile - */ -class TDEIO_EXPORT KArchiveDirectory : public KArchiveEntry -{ -public: - /** - * Creates a new directory entry. - * @param archive the entries archive - * @param name the name of the entry - * @param access the permissions in unix format - * @param date the date (in seconds since 1970) - * @param user the user that owns the entry - * @param group the group that owns the entry - * @param symlink the symlink, or TQString::null - */ - KArchiveDirectory( KArchive* archive, const TQString& name, int access, int date, - const TQString& user, const TQString& group, - const TQString& symlink); - - virtual ~KArchiveDirectory() { } - - /** - * Returns a list of sub-entries. - * @return the names of all entries in this directory (filenames, no path). - */ - TQStringList entries() const; - /** - * Returns the entry with the given name. - * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc. - * @return a pointer to the entry in the directory. - */ - KArchiveEntry* entry( TQString name ); - /** - * Returns the entry with the given name. - * @param name may be "test1", "mydir/test3", "mydir/mysubdir/test3", etc. - * @return a pointer to the entry in the directory. - */ - const KArchiveEntry* entry( TQString name ) const; - - /** - * @internal - * Adds a new entry to the directory. - */ - void addEntry( KArchiveEntry* ); - - /** - * Checks whether this entry is a directory. - * @return true, since this entry is a directory - */ - virtual bool isDirectory() const { return true; } - - /** - * Extracts all entries in this archive directory to the directory - * @p dest. - * @param dest the directory to extract to - * @param recursive if set to true, subdirectories are extracted as well - * @since 3.1 - */ - void copyTo(const TQString& dest, bool recursive = true) const; - -private: - TQDict<KArchiveEntry> m_entries; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KArchiveDirectoryPrivate* d; -}; - -#endif diff --git a/kio/kio/kautomount.cpp b/kio/kio/kautomount.cpp deleted file mode 100644 index e8b1d2af0..000000000 --- a/kio/kio/kautomount.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kautomount.h" -#include "krun.h" -#include "kdirwatch.h" -#include "kio/job.h" -#include <kdirnotify_stub.h> -#include <kdebug.h> - -/*********************************************************************** - * - * Utility classes - * - ***********************************************************************/ - -KAutoMount::KAutoMount( bool _readonly, const TQString& _format, const TQString& _device, - const TQString& _mountpoint, const TQString & _desktopFile, - bool _show_filemanager_window ) - : m_strDevice( _device ), - m_desktopFile( _desktopFile ) -{ - //kdDebug(7015) << "KAutoMount device=" << _device << " mountpoint=" << _mountpoint << endl; - m_bShowFilemanagerWindow = _show_filemanager_window; - - TDEIO::Job* job = TDEIO::mount( _readonly, _format.ascii(), _device, _mountpoint ); - connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) ); -} - -void KAutoMount::slotResult( TDEIO::Job * job ) -{ - if ( job->error() ) { - emit error(); - job->showErrorDialog(); - } - else - { - KURL mountpoint; - mountpoint.setPath( TDEIO::findDeviceMountPoint( m_strDevice ) ); - //kdDebug(7015) << "KAutoMount: m_strDevice=" << m_strDevice << " -> mountpoint=" << mountpoint << endl; - Q_ASSERT( mountpoint.isValid() ); - - if ( mountpoint.path().isEmpty() ) - kdWarning(7015) << m_strDevice << " was correctly mounted, but TDEIO::findDeviceMountPoint didn't find it. " - << "This looks like a bug, please report it on http://bugs.kde.org, together with your /etc/fstab line" << endl; - else if ( m_bShowFilemanagerWindow ) - KRun::runURL( mountpoint, "inode/directory" ); - - // Notify about the new stuff in that dir, in case of opened windows showing it - KDirNotify_stub allDirNotify("*", "KDirNotify*"); - allDirNotify.FilesAdded( mountpoint ); - - // Update the desktop file which is used for mount/unmount (icon change) - kdDebug(7015) << " mount finished : updating " << m_desktopFile << endl; - KURL dfURL; - dfURL.setPath( m_desktopFile ); - allDirNotify.FilesChanged( dfURL ); - //KDirWatch::self()->setFileDirty( m_desktopFile ); - - emit finished(); - } - delete this; -} - -KAutoUnmount::KAutoUnmount( const TQString & _mountpoint, const TQString & _desktopFile ) - : m_desktopFile( _desktopFile ), m_mountpoint( _mountpoint ) -{ - TDEIO::Job * job = TDEIO::unmount( m_mountpoint ); - connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), this, TQT_SLOT( slotResult( TDEIO::Job * ) ) ); -} - -void KAutoUnmount::slotResult( TDEIO::Job * job ) -{ - if ( job->error() ) { - emit error(); - job->showErrorDialog(); - } - else - { - KDirNotify_stub allDirNotify("*", "KDirNotify*"); - // Update the desktop file which is used for mount/unmount (icon change) - kdDebug(7015) << "unmount finished : updating " << m_desktopFile << endl; - KURL dfURL; - dfURL.setPath( m_desktopFile ); - allDirNotify.FilesChanged( dfURL ); - //KDirWatch::self()->setFileDirty( m_desktopFile ); - - // Notify about the new stuff in that dir, in case of opened windows showing it - // You may think we removed files, but this may have also readded some - // (if the mountpoint wasn't empty). The only possible behavior on FilesAdded - // is to relist the directory anyway. - KURL mp; - mp.setPath( m_mountpoint ); - allDirNotify.FilesAdded( mp ); - - emit finished(); - } - - delete this; -} - -#include "kautomount.moc" diff --git a/kio/kio/kautomount.h b/kio/kio/kautomount.h deleted file mode 100644 index 203c037d9..000000000 --- a/kio/kio/kautomount.h +++ /dev/null @@ -1,122 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __auto_mount_h__ -#define __auto_mount_h__ - -#include <tqobject.h> -#include <tqstring.h> - -#include <tdelibs_export.h> - -#ifdef Q_MOC_RUN -#define Q_OS_UNIX -#endif // Q_MOC_RUN - -#ifdef Q_OS_UNIX - -namespace TDEIO { -class Job; -} - -/** - * This class implements synchronous mounting of devices, - * as well as showing a file-manager window after mounting a device, optionally. - * It is a wrapper around the asychronous TDEIO::special() call for mount, - * used by KMimeType. - * - * @short This class implements synchronous mounting of devices. - */ -class TDEIO_EXPORT KAutoMount : public TQObject -{ - Q_OBJECT - friend class gcc_gives_a_warning_without_this; -public: - /** - * Mounts a device. - * @param readonly if true, the device is mounted read-only - * @param format the file system (e.g. vfat, ext2...) [optional, fstab is used otherwise] - * @param device the path to the device (e.g. /dev/fd0) - * @param mountpoint the directory where to mount the device [optional, fstab is used otherwise] - * @param desktopFile the file the user clicked on - to notify KDirWatch of the fact that - * it should emit fileDirty for it (to have the icon change) - * @param show_filemanager_window if true, a file-manager window for that mountpoint is shown after - * the mount, if successful. - */ - KAutoMount( bool readonly, const TQString& format, const TQString& device, const TQString& mountpoint, - const TQString & desktopFile, bool show_filemanager_window = true ); - -signals: - /** Emitted when the directory has been mounted */ - void finished(); - /** Emitted in case the directory could not been mounted */ - void error(); - -protected slots: - void slotResult( TDEIO::Job * ); - -protected: - TQString m_strDevice; - bool m_bShowFilemanagerWindow; - TQString m_desktopFile; -private: - /** KAutoMount deletes itself. Don't delete it manually. */ - ~KAutoMount() {} - class KAutoMountPrivate* d; -}; - -/** - * This class implements synchronous unmounting of devices, - * It is a wrapper around the asychronous TDEIO::special() call for unmount, - * used by KMimeType. - * - * @short This class implements synchronous unmounting of devices, - */ -class TDEIO_EXPORT KAutoUnmount : public TQObject -{ - Q_OBJECT - friend class gcc_gives_a_warning_without_this; -public: - /** - * Unmounts a device. - * @param mountpoint the mount point - KAutoUnmount finds the device from that - * @param desktopFile the file the user clicked on - to notify KDirWatch of the fact that - * it should emit fileDirty for it (to have the icon change) - */ - KAutoUnmount( const TQString & mountpoint, const TQString & desktopFile ); - -signals: - /** Emitted when the directory has been unmounted */ - void finished(); - /** Emitted in case the directory could not been unmounted */ - void error(); - -protected slots: - void slotResult( TDEIO::Job * ); -private: - TQString m_desktopFile; - TQString m_mountpoint; -private: - /** KAutoUnmount deletes itself. Don't delete it manually. */ - ~KAutoUnmount() {} - class KAutoUnmountPrivate* d; -}; - -#endif //Q_OS_UNIX - -#endif diff --git a/kio/kio/kdatatool.cpp b/kio/kio/kdatatool.cpp deleted file mode 100644 index 08630d110..000000000 --- a/kio/kio/kdatatool.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org> - Copyright (C) 2001 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kdatatool.h" - -#include <kstandarddirs.h> -#include <klibloader.h> -#include <kdebug.h> -#include <kinstance.h> - -#include <ktrader.h> -#include <tdeparts/componentfactory.h> - -#include <tqpixmap.h> -#include <tqfile.h> - -/************************************************* - * - * KDataToolInfo - * - *************************************************/ - -KDataToolInfo::KDataToolInfo() -{ - m_service = 0; -} - -KDataToolInfo::KDataToolInfo( const KService::Ptr& service, TDEInstance* instance ) -{ - m_service = service; - m_instance = instance; - - if ( !!m_service && !m_service->serviceTypes().contains( "KDataTool" ) ) - { - kdDebug(30003) << "The service " << m_service->name().latin1() - << " does not feature the service type KDataTool" << endl; - m_service = 0; - } -} - -KDataToolInfo::KDataToolInfo( const KDataToolInfo& info ) -{ - m_service = info.service(); - m_instance = info.instance(); -} - -KDataToolInfo& KDataToolInfo::operator= ( const KDataToolInfo& info ) -{ - m_service = info.service(); - m_instance = info.instance(); - return *this; -} - -TQString KDataToolInfo::dataType() const -{ - if ( !m_service ) - return TQString::null; - - return m_service->property( "DataType" ).toString(); -} - -TQStringList KDataToolInfo::mimeTypes() const -{ - if ( !m_service ) - return TQStringList(); - - return m_service->property( "DataMimeTypes" ).toStringList(); -} - -bool KDataToolInfo::isReadOnly() const -{ - if ( !m_service ) - return true; - - return m_service->property( "ReadOnly" ).toBool(); -} - -TQPixmap KDataToolInfo::icon() const -{ - if ( !m_service ) - return TQPixmap(); - - TQPixmap pix; - TQStringList lst = TDEGlobal::dirs()->resourceDirs("icon"); - TQStringList::ConstIterator it = lst.begin(); - while (!pix.load( *it + "/" + m_service->icon() ) && it != lst.end() ) - it++; - - return pix; -} - -TQPixmap KDataToolInfo::miniIcon() const -{ - if ( !m_service ) - return TQPixmap(); - - TQPixmap pix; - TQStringList lst = TDEGlobal::dirs()->resourceDirs("mini"); - TQStringList::ConstIterator it = lst.begin(); - while (!pix.load( *it + "/" + m_service->icon() ) && it != lst.end() ) - it++; - - return pix; -} - -TQString KDataToolInfo::iconName() const -{ - if ( !m_service ) - return TQString::null; - return m_service->icon(); -} - -TQStringList KDataToolInfo::commands() const -{ - if ( !m_service ) - return TQString(); - - return m_service->property( "Commands" ).toStringList(); -} - -TQStringList KDataToolInfo::userCommands() const -{ - if ( !m_service ) - return TQString(); - - return TQStringList::split( ',', m_service->comment() ); -} - -KDataTool* KDataToolInfo::createTool( TQObject* parent, const char* name ) const -{ - if ( !m_service ) - return 0; - - KDataTool* tool = KParts::ComponentFactory::createInstanceFromService<KDataTool>( m_service, parent, name ); - if ( tool ) - tool->setInstance( m_instance ); - return tool; -} - -KService::Ptr KDataToolInfo::service() const -{ - return m_service; -} - -TQValueList<KDataToolInfo> KDataToolInfo::query( const TQString& datatype, const TQString& mimetype, TDEInstance* instance ) -{ - TQValueList<KDataToolInfo> lst; - - TQString constr; - - if ( !datatype.isEmpty() ) - { - constr = TQString::fromLatin1( "DataType == '%1'" ).arg( datatype ); - } - if ( !mimetype.isEmpty() ) - { - TQString tmp = TQString::fromLatin1( "'%1' in DataMimeTypes" ).arg( mimetype ); - if ( constr.isEmpty() ) - constr = tmp; - else - constr = constr + " and " + tmp; - } -/* Bug in KTrader ? Test with HEAD-tdelibs! - if ( instance ) - { - TQString tmp = TQString::fromLatin1( "not ('%1' in ExcludeFrom)" ).arg( instance->instanceName() ); - if ( constr.isEmpty() ) - constr = tmp; - else - constr = constr + " and " + tmp; - } */ - - // Query the trader - //kdDebug() << "KDataToolInfo::query " << constr << endl; - KTrader::OfferList offers = KTrader::self()->query( "KDataTool", constr ); - - KTrader::OfferList::ConstIterator it = offers.begin(); - for( ; it != offers.end(); ++it ) - { - // Temporary replacement for the non-working trader query above - if ( !instance || !(*it)->property("ExcludeFrom").toStringList() - .contains( instance->instanceName() ) ) - lst.append( KDataToolInfo( *it, instance ) ); - else - kdDebug() << (*it)->entryPath() << " excluded." << endl; - } - - return lst; -} - -bool KDataToolInfo::isValid() const -{ - return( m_service ); -} - -/************************************************* - * - * KDataToolAction - * - *************************************************/ -KDataToolAction::KDataToolAction( const TQString & text, const KDataToolInfo & info, const TQString & command, - TQObject * parent, const char * name ) - : KAction( text, info.iconName(), 0, parent, name ), - m_command( command ), - m_info( info ) -{ -} - -void KDataToolAction::slotActivated() -{ - emit toolActivated( m_info, m_command ); -} - -TQPtrList<KAction> KDataToolAction::dataToolActionList( const TQValueList<KDataToolInfo> & tools, const TQObject *receiver, const char* slot ) -{ - TQPtrList<KAction> actionList; - if ( tools.isEmpty() ) - return actionList; - - actionList.append( new KActionSeparator() ); - TQValueList<KDataToolInfo>::ConstIterator entry = tools.begin(); - for( ; entry != tools.end(); ++entry ) - { - TQStringList userCommands = (*entry).userCommands(); - TQStringList commands = (*entry).commands(); - Q_ASSERT(!commands.isEmpty()); - if ( commands.count() != userCommands.count() ) - kdWarning() << "KDataTool desktop file error (" << (*entry).service()->entryPath() - << "). " << commands.count() << " commands and " - << userCommands.count() << " descriptions." << endl; - TQStringList::ConstIterator uit = userCommands.begin(); - TQStringList::ConstIterator cit = commands.begin(); - for (; uit != userCommands.end() && cit != commands.end(); ++uit, ++cit ) - { - //kdDebug() << "creating action " << *uit << " " << *cit << endl; - KDataToolAction * action = new KDataToolAction( *uit, *entry, *cit ); - connect( action, TQT_SIGNAL( toolActivated( const KDataToolInfo &, const TQString & ) ), - receiver, slot ); - actionList.append( action ); - } - } - - return actionList; -} - -/************************************************* - * - * KDataTool - * - *************************************************/ - -KDataTool::KDataTool( TQObject* parent, const char* name ) - : TQObject( parent, name ), m_instance( 0L ) -{ -} - -TDEInstance* KDataTool::instance() const -{ - return m_instance; -} - -void KDataToolAction::virtual_hook( int id, void* data ) -{ KAction::virtual_hook( id, data ); } - -void KDataTool::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -#include "kdatatool.moc" diff --git a/kio/kio/kdatatool.h b/kio/kio/kdatatool.h deleted file mode 100644 index 1258767fc..000000000 --- a/kio/kio/kdatatool.h +++ /dev/null @@ -1,303 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999, 2000 Torben Weis <weis@kde.org> - Copyright (C) 2001 David Faure <david@mandrakesoft.com> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KDATATOOL_H -#define KDATATOOL_H - -#include <tqobject.h> -#include <tqvaluelist.h> - -#include <kaction.h> -#include <kservice.h> - -class KDataTool; -class TQPixmap; -class TQStringList; -class TDEInstance; - -// If you're only looking at implementing a data-tool, skip directly to the last -// class definition, KDataTool. - -/** - * This is a convenience class for KService. You can use it if you have - * a KService describing a KDataTool. In this case the KDataToolInfo class - * is more convenient to work with. - * - * Especially useful is the method createTool which creates the datatool - * described by the service. - * @see KDataTool - */ -class TDEIO_EXPORT KDataToolInfo -{ -public: - /** - * Create an invalid KDataToolInfo. - */ - KDataToolInfo(); - /** - * Create a valid KDataToolInfo. - * @param service the corresponding service - * @param instance the instance to use - */ - KDataToolInfo( const KService::Ptr& service, TDEInstance* instance ); - /** - * Copy constructor. - */ - KDataToolInfo( const KDataToolInfo& info ); - /** - * Assignment operator. - */ - KDataToolInfo& operator= ( const KDataToolInfo& info ); - - /** - * Returns the data type that the DataTool can accept. - * @return the C++ data type that this DataTool accepts. - * For example "TQString" or "TQImage" or something more - * complicated. - */ - TQString dataType() const; - /** - * Returns a list of mime type that will be accepted by the DataTool. - * The mimetypes are only used if the dataType can be used to store - * different mimetypes. For example in a "TQString" you could save "text/plain" - * or "text/html" or "text/xml". - * - * @return the mime types accepted by this DataTool. For example - * "image/gif" or "text/plain". In some cases the dataType - * determines the accepted type of data perfectly. In this cases - * this list may be empty. - */ - TQStringList mimeTypes() const; - - /** - * Checks whether the DataTool is read-only. - * @return true if the DataTool does not modify the data passed to it by KDataTool::run. - */ - bool isReadOnly() const; - - /** - * Returns the icon of this data tool. - * @return a large pixmap for the DataTool. - * @deprecated, use iconName() - */ - TQPixmap icon() const KDE_DEPRECATED; - /** - * Returns the mini icon of this data tool. - * @return a mini pixmap for the DataTool. - * @deprecated, use iconName() - */ - TQPixmap miniIcon() const KDE_DEPRECATED; - /** - * Returns the icon name for this DataTool. - * @return the name of the icon for the DataTool - */ - TQString iconName() const; - /** - * Returns a list of strings that you can put in a TQPopupMenu item, for example to - * offer the DataTools services to the user. The returned value - * is usually something like "Spell checking", "Shrink Image", "Rotate Image" - * or something like that. - * This list comes from the Comment field of the tool's desktop file - * (so that it can be translated). - * - * Each of the strings returned corresponds to a string in the list returned by - * commands. - * - * @return a list of strings that you can put in a TQPopupMenu item - */ - TQStringList userCommands() const; - /** - * Returns the list of commands the DataTool can execute. The application - * passes the command to the KDataTool::run method. - * - * This list comes from the Commands field of the tool's desktop file. - * - * Each of the strings returned corresponds to a string in the list returned by - * userCommands. - * @return the list of commands the DataTool can execute, suitable for - * the KDataTool::run method. - */ - TQStringList commands() const; - - /** - * Creates the data tool described by this KDataToolInfo. - * @param parent the parent of the TQObject (or 0 for parent-less KDataTools) - * @param name the name of the TQObject, can be 0 - * @return a pointer to the created data tool or 0 on error. - */ - KDataTool* createTool( TQObject* parent = 0, const char* name = 0 ) const; - - /** - * The KDataToolInfo's service that is represented by this class. - * @return the service - */ - KService::Ptr service() const; - - /** - * The instance of the service. - * @return the instance - */ - TDEInstance* instance() const { return m_instance; } - - /** - * A DataToolInfo may be invalid if the KService passed to its constructor does - * not feature the service type "KDataTool". - * @return true if valid, false otherwise - */ - bool isValid() const; - - /** - * Queries the KTrader about installed KDataTool implementations. - * @param datatype a type that the application can 'export' to the tools (e.g. TQString) - * @param mimetype the mimetype of the data (e.g. text/plain) - * @param instance the application (or the part)'s instance (to check if a tool is excluded from this part, - * and also used if the tool wants to read its configuration in the app's config file). - * @return the list of results - */ - static TQValueList<KDataToolInfo> query( const TQString& datatype, const TQString& mimetype, TDEInstance * instance ); - -private: - KService::Ptr m_service; - TDEInstance* m_instance; -private: - class KDataToolInfoPrivate* d; -}; - - -/** - * This class helps applications implement support for KDataTool. - * The steps to follow are simple: - * @li query for the available tools using KDataToolInfo::query - * @li pass the result to KDataToolAction::dataToolActionList (with a slot) - * @li plug the resulting actions, either using KXMLGUIClient::plugActionList, or by hand. - * - * The slot defined for step 2 is called when the action is activated, and - * that's where the tool should be created and run. - */ -class TDEIO_EXPORT KDataToolAction : public KAction -{ - Q_OBJECT - -public: - /** - * Constructs a new KDataToolAction. - * - * @param text The text that will be displayed. - * @param info the corresponding KDataToolInfo - * @param command the command of the action - * @param parent This action's parent. - * @param name An internal name for this action. - */ - KDataToolAction( const TQString & text, const KDataToolInfo & info, const TQString & command, TQObject * parent = 0, const char * name = 0); - - /** - * Creates a list of actions from a list of information about data-tools. - * The slot must have a signature corresponding to the toolActivated signal. - * - * Note that it's the caller's responsibility to delete the actions when they're not needed anymore. - * @param tools the list of data tool descriptions - * @param receiver the receiver for toolActivated() signals - * @param slot the slot that will receive the toolActivated() signals - * @return the KActions - */ - static TQPtrList<KAction> dataToolActionList( const TQValueList<KDataToolInfo> & tools, const TQObject *receiver, const char* slot ); - -signals: - /** - * Emitted when a tool has been activated. - * @param info a description of the activated tools - * @param command the command for the tool - */ - void toolActivated( const KDataToolInfo & info, const TQString & command ); - -protected: - virtual void slotActivated(); - -private: - TQString m_command; - KDataToolInfo m_info; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KDataToolActionPrivate* d; - -}; - -/** - * A generic tool that processes data. - * - * A data-tool is a "plugin" for an application, that acts (reads/modifies) - * on a portion of the data present in the document (e.g. a text document, - * a single word or paragraph, a KSpread cell, an image, etc.) - * - * The application has some generic code for presenting the tools in a popupmenu - * @see KDataToolAction, and for activating a tool, passing it the data - * (and possibly getting modified data from it). - */ -class TDEIO_EXPORT KDataTool : public TQObject -{ - Q_OBJECT - -public: - /** - * Constructor - * The data-tool is only created when a menu-item, that relates to it, is activated. - * @param parent the parent of the TQObject (or 0 for parent-less KDataTools) - * @param name the name of the TQObject, can be 0 - */ - KDataTool( TQObject* parent = 0, const char* name = 0 ); - - /** - * @internal. Do not use under any circumstance (including bad weather). - */ - void setInstance( TDEInstance* instance ) { m_instance = instance; } - - /** - * Returns the instance of the part that created this tool. - * Usually used if the tool wants to read its configuration in the app's config file. - * @return the instance of the part that created this tool. - */ - TDEInstance* instance() const; - - /** - * Interface for 'running' this tool. - * This is the method that the data-tool must implement. - * - * @param command is the command that was selected (see KDataToolInfo::commands()) - * @param data the data provided by the application, on which to run the tool. - * The application is responsible for setting that data before running the tool, - * and for getting it back and updating itself with it, after the tool ran. - * @param datatype defines the type of @p data. - * @param mimetype defines the mimetype of the data (for instance datatype may be - * TQString, but the mimetype can be text/plain, text/html etc.) - * @return true if successful, false otherwise - */ - virtual bool run( const TQString& command, void* data, const TQString& datatype, const TQString& mimetype) = 0; - -private: - TDEInstance * m_instance; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KDataToolPrivate; - KDataToolPrivate * d; -}; - -#endif diff --git a/kio/kio/kdcopservicestarter.cpp b/kio/kio/kdcopservicestarter.cpp deleted file mode 100644 index 3c9b55501..000000000 --- a/kio/kio/kdcopservicestarter.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2003 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kdcopservicestarter.h" -#include "ktrader.h" -#include <kapplication.h> -#include "kservice.h" -#include <kstaticdeleter.h> -#include <kdebug.h> -#include <klocale.h> -#include <dcopclient.h> - -static KStaticDeleter<KDCOPServiceStarter> dss_sd; -KDCOPServiceStarter* KDCOPServiceStarter::s_self; - -KDCOPServiceStarter* KDCOPServiceStarter::self() -{ - if ( !s_self ) - dss_sd.setObject( s_self, new KDCOPServiceStarter ); - return s_self; -} - -KDCOPServiceStarter::KDCOPServiceStarter() -{ - // Set the singleton instance - useful when a derived KDCOPServiceStarter - // was created (before self() was called) - s_self = this; -} - -KDCOPServiceStarter::~KDCOPServiceStarter() -{ -} - -int KDCOPServiceStarter::findServiceFor( const TQString& serviceType, - const TQString& _constraint, - const TQString& preferences, - TQString *error, TQCString* pDcopService, - int flags ) -{ - // Ask the trader which service is preferred for this servicetype - // We want one that provides a DCOP interface - TQString constraint = _constraint; - if ( !constraint.isEmpty() ) - constraint += " and "; - constraint += "exist [X-DCOP-ServiceName]"; - KTrader::OfferList offers = KTrader::self()->query(serviceType, "Application", constraint, preferences); - if ( offers.isEmpty() ) { - if ( error ) - *error = i18n("No service implementing %1").arg( serviceType ); - kdWarning() << "KDCOPServiceStarter: No service implementing " << serviceType << endl; - return -1; - } - KService::Ptr ptr = offers.first(); - TQCString dcopService = ptr->property("X-DCOP-ServiceName").toString().latin1(); - - if ( !kapp->dcopClient()->isApplicationRegistered( dcopService ) ) - { - TQString error; - if ( startServiceFor( serviceType, constraint, preferences, &error, &dcopService, flags ) != 0 ) - { - kdDebug() << "KDCOPServiceStarter: Couldn't start service: " << error << endl; - return -2; - } - } - kdDebug() << "KDCOPServiceStarter: DCOP service is available now, as " << dcopService << endl; - if ( pDcopService ) - *pDcopService = dcopService; - return 0; -} - -int KDCOPServiceStarter::startServiceFor( const TQString& serviceType, - const TQString& constraint, - const TQString& preferences, - TQString *error, TQCString* dcopService, int /*flags*/ ) -{ - KTrader::OfferList offers = KTrader::self()->query(serviceType, "Application", constraint, preferences); - if ( offers.isEmpty() ) - return -1; - KService::Ptr ptr = offers.first(); - kdDebug() << "KDCOPServiceStarter: starting " << ptr->desktopEntryPath() << endl; - return kapp->startServiceByDesktopPath( ptr->desktopEntryPath(), TQStringList(), error, dcopService ); -} diff --git a/kio/kio/kdcopservicestarter.h b/kio/kio/kdcopservicestarter.h deleted file mode 100644 index f70f0173e..000000000 --- a/kio/kio/kdcopservicestarter.h +++ /dev/null @@ -1,103 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2003 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KDCOPSERVICESTARTER_H -#define KDCOPSERVICESTARTER_H - -#include <tqstring.h> -#include <kstaticdeleter.h> - -class KDCOPServiceStarter; -class TQCString; - -/** - * A generic DCOP service starter, using KTrader. - * The default implementation starts new processes, but this interface can - * also be reimplemented by specific applications to provide dlopened in-process DCOP objects. - * @author David Faure <faure@kde.org> - */ -class TDEIO_EXPORT KDCOPServiceStarter { - friend class KStaticDeleter<KDCOPServiceStarter>; -public: - - static KDCOPServiceStarter* self(); - - /** - * Check if a given DCOP interface is available - from the serviceType it's supposed to implement. - * - * The trader is queried to find the preferred application for this serviceType, - * with the constraint that its X-DCOP-ServiceName property must be defined. - * Then the DCOP server is checked. If the service is not available, - * this method will call startServiceFor to start it. - * - * @param serviceType the type of service we're looking for - * @param constraint see KTrader - * @param preferences see KTrader - * @param error On failure, @p error contains a description of the error - * that occurred. If the pointer is 0, the argument will be - * ignored - * @param dcopService On success, @p dcopService contains the DCOP name - * under which this service is available. If the pointer is 0 the argument - * will be ignored - * @param flags for future extensions (currently unused) - * - * @return an error code indicating success (== 0) or failure (> 0). - */ - int findServiceFor( const TQString& serviceType, - const TQString& constraint = TQString::null, - const TQString& preferences = TQString::null, - TQString *error=0, TQCString* dcopService=0, - int flags=0 ); - - /** - * Find an implementation of the given @p serviceType, - * and start it, to use its DCOP interface. - * The default implementation uses KTrader to find the preferred Application, - * and then starts it using kapp->startService... - * - * However applications (like kontact) can reimplement this method, to provide - * an in-process way of loading the implementation for this service type. - * - * @param serviceType the type of service we're looking for - * @param constraint see KTrader - * @param preferences see KTrader - * @param error On failure, @p error contains a description of the error - * that occurred. If the pointer is 0, the argument will be - * ignored - * @param dcopService On success, @p dcopService contains the DCOP name - * under which this service is available. If the pointer is 0 the argument - * will be ignored - * @param flags for future extensions (currently unused) - * - * @return an error code indicating success (== 0) or failure (> 0). - */ - virtual int startServiceFor( const TQString& serviceType, - const TQString& constraint = TQString::null, - const TQString& preferences = TQString::null, - TQString *error=0, TQCString* dcopService=0, - int flags=0 ); -protected: - KDCOPServiceStarter(); - virtual ~KDCOPServiceStarter(); - -private: - static KDCOPServiceStarter* s_self; -}; - -#endif - diff --git a/kio/kio/kdirlister.cpp b/kio/kio/kdirlister.cpp deleted file mode 100644 index 90cfca041..000000000 --- a/kio/kio/kdirlister.cpp +++ /dev/null @@ -1,2538 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - 2000 Carsten Pfeiffer <pfeiffer@kde.org> - 2001-2005 Michael Brade <brade@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kdirlister.h" - -#include <tqregexp.h> -#include <tqptrlist.h> -#include <tqtimer.h> -#include <tqeventloop.h> - -#include <kapplication.h> -#include <kdebug.h> -#include <klocale.h> -#include <kio/job.h> -#include <kmessagebox.h> -#include <kglobal.h> -#include <kglobalsettings.h> -#include <kstaticdeleter.h> -#include <kprotocolinfo.h> - -#include "kdirlister_p.h" - -#include <assert.h> -#include <unistd.h> - -KDirListerCache* KDirListerCache::s_pSelf = 0; -static KStaticDeleter<KDirListerCache> sd_KDirListerCache; - -// Enable this to get printDebug() called often, to see the contents of the cache -//#define DEBUG_CACHE - -// Make really sure it doesn't get activated in the final build -#ifdef NDEBUG -#undef DEBUG_CACHE -#endif - -KDirListerCache::KDirListerCache( int maxCount ) - : itemsCached( maxCount ) -{ - kdDebug(7004) << "+KDirListerCache" << endl; - - itemsInUse.setAutoDelete( false ); - itemsCached.setAutoDelete( true ); - urlsCurrentlyListed.setAutoDelete( true ); - urlsCurrentlyHeld.setAutoDelete( true ); - pendingUpdates.setAutoDelete( true ); - - connect( kdirwatch, TQT_SIGNAL( dirty( const TQString& ) ), - this, TQT_SLOT( slotFileDirty( const TQString& ) ) ); - connect( kdirwatch, TQT_SIGNAL( created( const TQString& ) ), - this, TQT_SLOT( slotFileCreated( const TQString& ) ) ); - connect( kdirwatch, TQT_SIGNAL( deleted( const TQString& ) ), - this, TQT_SLOT( slotFileDeleted( const TQString& ) ) ); -} - -KDirListerCache::~KDirListerCache() -{ - kdDebug(7004) << "-KDirListerCache" << endl; - - itemsInUse.setAutoDelete( true ); - itemsInUse.clear(); - itemsCached.clear(); - urlsCurrentlyListed.clear(); - urlsCurrentlyHeld.clear(); - - if ( KDirWatch::exists() ) - kdirwatch->disconnect( this ); -} - -// setting _reload to true will emit the old files and -// call updateDirectory -bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u, - bool _keep, bool _reload ) -{ - // like this we don't have to worry about trailing slashes any further - KURL _url = _u; - _url.cleanPath(); // kill consecutive slashes - _url.adjustPath(-1); - TQString urlStr = _url.url(); - - if ( !lister->validURL( _url ) ) - return false; - -#ifdef DEBUG_CACHE - printDebug(); -#endif - kdDebug(7004) << k_funcinfo << lister << " url=" << _url - << " keep=" << _keep << " reload=" << _reload << endl; - - if ( !_keep ) - { - // stop any running jobs for lister - stop( lister ); - - // clear our internal list for lister - forgetDirs( lister ); - - lister->d->rootFileItem = 0; - } - else if ( lister->d->lstDirs.find( _url ) != lister->d->lstDirs.end() ) - { - // stop the job listing _url for this lister - stop( lister, _url ); - - // clear _url for lister - forgetDirs( lister, _url, true ); - - if ( lister->d->url == _url ) - lister->d->rootFileItem = 0; - } - - lister->d->lstDirs.append( _url ); - - if ( lister->d->url.isEmpty() || !_keep ) // set toplevel URL only if not set yet - lister->d->url = _url; - - DirItem *itemU = itemsInUse[urlStr]; - DirItem *itemC; - - if ( !urlsCurrentlyListed[urlStr] ) - { - // if there is an update running for _url already we get into - // the following case - it will just be restarted by updateDirectory(). - - if ( itemU ) - { - kdDebug(7004) << "listDir: Entry already in use: " << _url << endl; - - bool oldState = lister->d->complete; - lister->d->complete = false; - - emit lister->started( _url ); - - if ( !lister->d->rootFileItem && lister->d->url == _url ) - lister->d->rootFileItem = itemU->rootItem; - - lister->addNewItems( *(itemU->lstItems) ); - lister->emitItems(); - - // _url is already in use, so there is already an entry in urlsCurrentlyHeld - assert( urlsCurrentlyHeld[urlStr] ); - urlsCurrentlyHeld[urlStr]->append( lister ); - - lister->d->complete = oldState; - - emit lister->completed( _url ); - if ( lister->d->complete ) - emit lister->completed(); - - if ( _reload || !itemU->complete ) - updateDirectory( _url ); - } - else if ( !_reload && (itemC = itemsCached.take( urlStr )) ) - { - kdDebug(7004) << "listDir: Entry in cache: " << _url << endl; - - itemC->decAutoUpdate(); - itemsInUse.insert( urlStr, itemC ); - itemU = itemC; - - bool oldState = lister->d->complete; - lister->d->complete = false; - - emit lister->started( _url ); - - if ( !lister->d->rootFileItem && lister->d->url == _url ) - lister->d->rootFileItem = itemC->rootItem; - - lister->addNewItems( *(itemC->lstItems) ); - lister->emitItems(); - - Q_ASSERT( !urlsCurrentlyHeld[urlStr] ); - TQPtrList<KDirLister> *list = new TQPtrList<KDirLister>; - list->append( lister ); - urlsCurrentlyHeld.insert( urlStr, list ); - - lister->d->complete = oldState; - - emit lister->completed( _url ); - if ( lister->d->complete ) - emit lister->completed(); - - if ( !itemC->complete ) - updateDirectory( _url ); - } - else // dir not in cache or _reload is true - { - kdDebug(7004) << "listDir: Entry not in cache or reloaded: " << _url << endl; - - TQPtrList<KDirLister> *list = new TQPtrList<KDirLister>; - list->append( lister ); - urlsCurrentlyListed.insert( urlStr, list ); - - itemsCached.remove( urlStr ); - itemU = new DirItem( _url ); - itemsInUse.insert( urlStr, itemU ); - -// // we have a limit of MAX_JOBS_PER_LISTER concurrently running jobs -// if ( lister->numJobs() >= MAX_JOBS_PER_LISTER ) -// { -// lstPendingUpdates.append( _url ); -// } -// else -// { - - if ( lister->d->url == _url ) - lister->d->rootFileItem = 0; - - TDEIO::ListJob* job = TDEIO::listDir( _url, false /* no default GUI */ ); - jobs.insert( job, TQValueList<TDEIO::UDSEntry>() ); - - lister->jobStarted( job ); - lister->connectJob( job ); - - if ( lister->d->window ) - job->setWindow( lister->d->window ); - - connect( job, TQT_SIGNAL( entries( TDEIO::Job *, const TDEIO::UDSEntryList & ) ), - this, TQT_SLOT( slotEntries( TDEIO::Job *, const TDEIO::UDSEntryList & ) ) ); - connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), - this, TQT_SLOT( slotResult( TDEIO::Job * ) ) ); - connect( job, TQT_SIGNAL( redirection( TDEIO::Job *, const KURL & ) ), - this, TQT_SLOT( slotRedirection( TDEIO::Job *, const KURL & ) ) ); - - emit lister->started( _url ); - -// } - } - } - else - { - kdDebug(7004) << "listDir: Entry currently being listed: " << _url << endl; - - emit lister->started( _url ); - - urlsCurrentlyListed[urlStr]->append( lister ); - - TDEIO::ListJob *job = jobForUrl( urlStr ); - Q_ASSERT( job ); - - lister->jobStarted( job ); - lister->connectJob( job ); - - Q_ASSERT( itemU ); - - if ( !lister->d->rootFileItem && lister->d->url == _url ) - lister->d->rootFileItem = itemU->rootItem; - - lister->addNewItems( *(itemU->lstItems) ); - lister->emitItems(); - } - - // automatic updating of directories - if ( lister->d->autoUpdate ) - itemU->incAutoUpdate(); - - return true; -} - -bool KDirListerCache::validURL( const KDirLister *lister, const KURL& url ) const -{ - if ( !url.isValid() ) - { - if ( lister->d->autoErrorHandling ) - { - TQString tmp = i18n("Malformed URL\n%1").arg( url.prettyURL() ); - KMessageBox::error( lister->d->errorParent, tmp ); - } - return false; - } - - if ( !KProtocolInfo::supportsListing( url ) ) - { - if ( lister->d->autoErrorHandling ) - { - // TODO: this message should be changed during next string unfreeze! - TQString tmp = i18n("Malformed URL\n%1").arg( url.prettyURL() ); - KMessageBox::error( lister->d->errorParent, tmp ); - } - return false; - } - - return true; -} - -void KDirListerCache::stop( KDirLister *lister ) -{ -#ifdef DEBUG_CACHE - printDebug(); -#endif - kdDebug(7004) << k_funcinfo << "lister: " << lister << endl; - bool stopped = false; - - TQDictIterator< TQPtrList<KDirLister> > it( urlsCurrentlyListed ); - TQPtrList<KDirLister> *listers; - while ( (listers = it.current()) ) - { - if ( listers->findRef( lister ) > -1 ) - { - // lister is listing url - TQString url = it.currentKey(); - - //kdDebug(7004) << k_funcinfo << " found lister in list - for " << url << endl; - bool ret = listers->removeRef( lister ); - Q_ASSERT( ret ); - - TDEIO::ListJob *job = jobForUrl( url ); - if ( job ) - lister->jobDone( job ); - - // move lister to urlsCurrentlyHeld - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[url]; - if ( !holders ) - { - holders = new TQPtrList<KDirLister>; - urlsCurrentlyHeld.insert( url, holders ); - } - - holders->append( lister ); - - emit lister->canceled( KURL( url ) ); - - //kdDebug(7004) << k_funcinfo << "remaining list: " << listers->count() << " listers" << endl; - - if ( listers->isEmpty() ) - { - // kill the job since it isn't used any more - if ( job ) - killJob( job ); - - urlsCurrentlyListed.remove( url ); - } - - stopped = true; - } - else - ++it; - } - - if ( stopped ) - { - emit lister->canceled(); - lister->d->complete = true; - } - - // this is wrong if there is still an update running! - //Q_ASSERT( lister->d->complete ); -} - -void KDirListerCache::stop( KDirLister *lister, const KURL& _u ) -{ - TQString urlStr( _u.url(-1) ); - KURL _url( urlStr ); - - // TODO: consider to stop all the "child jobs" of _url as well - kdDebug(7004) << k_funcinfo << lister << " url=" << _url << endl; - - TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr]; - if ( !listers || !listers->removeRef( lister ) ) - return; - - // move lister to urlsCurrentlyHeld - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr]; - if ( !holders ) - { - holders = new TQPtrList<KDirLister>; - urlsCurrentlyHeld.insert( urlStr, holders ); - } - - holders->append( lister ); - - - TDEIO::ListJob *job = jobForUrl( urlStr ); - if ( job ) - lister->jobDone( job ); - - emit lister->canceled( _url ); - - if ( listers->isEmpty() ) - { - // kill the job since it isn't used any more - if ( job ) - killJob( job ); - - urlsCurrentlyListed.remove( urlStr ); - } - - if ( lister->numJobs() == 0 ) - { - lister->d->complete = true; - - // we killed the last job for lister - emit lister->canceled(); - } -} - -void KDirListerCache::setAutoUpdate( KDirLister *lister, bool enable ) -{ - // IMPORTANT: this method does not check for the current autoUpdate state! - - for ( KURL::List::Iterator it = lister->d->lstDirs.begin(); - it != lister->d->lstDirs.end(); ++it ) - { - if ( enable ) - itemsInUse[(*it).url()]->incAutoUpdate(); - else - itemsInUse[(*it).url()]->decAutoUpdate(); - } -} - -void KDirListerCache::forgetDirs( KDirLister *lister ) -{ - kdDebug(7004) << k_funcinfo << lister << endl; - - emit lister->clear(); - - // forgetDirs() will modify lstDirs, make a copy first - KURL::List lstDirsCopy = lister->d->lstDirs; - for ( KURL::List::Iterator it = lstDirsCopy.begin(); - it != lstDirsCopy.end(); ++it ) - { - forgetDirs( lister, *it, false ); - } -} - -void KDirListerCache::forgetDirs( KDirLister *lister, const KURL& _url, bool notify ) -{ - kdDebug(7004) << k_funcinfo << lister << " _url: " << _url << endl; - - KURL url( _url ); - url.adjustPath( -1 ); - TQString urlStr = url.url(); - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr]; - //Q_ASSERT( holders ); - if ( holders ) - { - holders->removeRef( lister ); - } - - // remove the dir from lister->d->lstDirs so that it doesn't contain things - // that itemsInUse doesn't. When emitting the canceled signals lstDirs must - // not contain anything that itemsInUse does not contain. (otherwise it - // might crash in findByName()). - lister->d->lstDirs.remove( lister->d->lstDirs.find( url ) ); - - DirItem *item = itemsInUse[urlStr]; - - if ( holders && holders->isEmpty() ) - { - urlsCurrentlyHeld.remove( urlStr ); // this deletes the (empty) holders list - if ( !urlsCurrentlyListed[urlStr] ) - { - // item not in use anymore -> move into cache if complete - itemsInUse.remove( urlStr ); - - // this job is a running update - TDEIO::ListJob *job = jobForUrl( urlStr ); - if ( job ) - { - lister->jobDone( job ); - killJob( job ); - kdDebug(7004) << k_funcinfo << "Killing update job for " << urlStr << endl; - - emit lister->canceled( url ); - if ( lister->numJobs() == 0 ) - { - lister->d->complete = true; - emit lister->canceled(); - } - } - - if ( notify ) - emit lister->clear( url ); - - if ( item && item->complete ) - { - kdDebug(7004) << k_funcinfo << lister << " item moved into cache: " << url << endl; - itemsCached.insert( urlStr, item ); // TODO: may return false!! - - // Should we forget the dir for good, or keep a watch on it? - // Generally keep a watch, except when it would prevent - // unmounting a removable device (#37780) - const bool isLocal = item->url.isLocalFile(); - const bool isManuallyMounted = isLocal && TDEIO::manually_mounted( item->url.path() ); - bool containsManuallyMounted = false; - if ( !isManuallyMounted && item->lstItems && isLocal ) - { - // Look for a manually-mounted directory inside - // If there's one, we can't keep a watch either, FAM would prevent unmounting the CDROM - // I hope this isn't too slow (manually_mounted caches the last device so most - // of the time this is just a stat per subdir) - KFileItemListIterator kit( *item->lstItems ); - for ( ; kit.current() && !containsManuallyMounted; ++kit ) - if ( (*kit)->isDir() && TDEIO::manually_mounted( (*kit)->url().path() ) ) - containsManuallyMounted = true; - } - - if ( isManuallyMounted || containsManuallyMounted ) - { - kdDebug(7004) << "Not adding a watch on " << item->url << " because it " << - ( isManuallyMounted ? "is manually mounted" : "contains a manually mounted subdir" ) << endl; - item->complete = false; // set to "dirty" - } - else - item->incAutoUpdate(); // keep watch - } - else - { - delete item; - item = 0; - } - } - } - - if ( item && lister->d->autoUpdate ) - item->decAutoUpdate(); -} - -void KDirListerCache::updateDirectory( const KURL& _dir ) -{ - kdDebug(7004) << k_funcinfo << _dir << endl; - - TQString urlStr = _dir.url(-1); - if ( !checkUpdate( urlStr ) ) - return; - - // A job can be running to - // - only list a new directory: the listers are in urlsCurrentlyListed - // - only update a directory: the listers are in urlsCurrentlyHeld - // - update a currently running listing: the listers are in urlsCurrentlyListed - // and urlsCurrentlyHeld - - TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr]; - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr]; - - // restart the job for _dir if it is running already - bool killed = false; - TQWidget *window = 0; - TDEIO::ListJob *job = jobForUrl( urlStr ); - if ( job ) - { - window = job->window(); - - killJob( job ); - killed = true; - - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->jobDone( job ); - - if ( holders ) - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - kdl->jobDone( job ); - } - kdDebug(7004) << k_funcinfo << "Killed = " << killed << endl; - - // we don't need to emit canceled signals since we only replaced the job, - // the listing is continuing. - - Q_ASSERT( !listers || (listers && killed) ); - - job = TDEIO::listDir( _dir, false /* no default GUI */ ); - jobs.insert( job, TQValueList<TDEIO::UDSEntry>() ); - - connect( job, TQT_SIGNAL(entries( TDEIO::Job *, const TDEIO::UDSEntryList & )), - this, TQT_SLOT(slotUpdateEntries( TDEIO::Job *, const TDEIO::UDSEntryList & )) ); - connect( job, TQT_SIGNAL(result( TDEIO::Job * )), - this, TQT_SLOT(slotUpdateResult( TDEIO::Job * )) ); - - kdDebug(7004) << k_funcinfo << "update started in " << _dir << endl; - - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->jobStarted( job ); - - if ( holders ) - { - if ( !killed ) - { - bool first = true; - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - { - kdl->jobStarted( job ); - if ( first && kdl->d->window ) - { - first = false; - job->setWindow( kdl->d->window ); - } - emit kdl->started( _dir ); - } - } - else - { - job->setWindow( window ); - - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - kdl->jobStarted( job ); - } - } -} - -bool KDirListerCache::checkUpdate( const TQString& _dir ) -{ - if ( !itemsInUse[_dir] ) - { - DirItem *item = itemsCached[_dir]; - if ( item && item->complete ) - { - item->complete = false; - item->decAutoUpdate(); - // Hmm, this debug output might include login/password from the _dir URL. - //kdDebug(7004) << k_funcinfo << "directory " << _dir << " not in use, marked dirty." << endl; - } - //else - //kdDebug(7004) << k_funcinfo << "aborted, directory " << _dir << " not in cache." << endl; - - return false; - } - else - return true; -} - -KFileItemList *KDirListerCache::itemsForDir( const KURL &_dir ) const -{ - TQString urlStr = _dir.url(-1); - DirItem *item = itemsInUse[ urlStr ]; - if ( !item ) - item = itemsCached[ urlStr ]; - return item ? item->lstItems : 0; -} - -KFileItem *KDirListerCache::findByName( const KDirLister *lister, const TQString& _name ) const -{ - Q_ASSERT( lister ); - - for ( KURL::List::Iterator it = lister->d->lstDirs.begin(); - it != lister->d->lstDirs.end(); ++it ) - { - KFileItemListIterator kit( *itemsInUse[(*it).url()]->lstItems ); - for ( ; kit.current(); ++kit ) - if ( (*kit)->name() == _name ) - return (*kit); - } - - return 0L; -} - -KFileItem *KDirListerCache::findByURL( const KDirLister *lister, const KURL& _u ) const -{ - KURL _url = _u; - _url.adjustPath(-1); - - KURL parentDir( _url ); - parentDir.setPath( parentDir.directory() ); - - // If lister is set, check that it contains this dir - if ( lister && !lister->d->lstDirs.contains( parentDir ) ) - return 0L; - - KFileItemList *itemList = itemsForDir( parentDir ); - if ( itemList ) - { - KFileItemListIterator kit( *itemList ); - for ( ; kit.current(); ++kit ) - if ( (*kit)->url() == _url ) - return (*kit); - } - return 0L; -} - -void KDirListerCache::FilesAdded( const KURL &dir ) -{ - kdDebug(7004) << k_funcinfo << dir << endl; - updateDirectory( dir ); -} - -void KDirListerCache::FilesRemoved( const KURL::List &fileList ) -{ - kdDebug(7004) << k_funcinfo << endl; - KURL::List::ConstIterator it = fileList.begin(); - for ( ; it != fileList.end() ; ++it ) - { - // emit the deleteItem signal if this file was shown in any view - KFileItem *fileitem = 0L; - KURL parentDir( *it ); - parentDir.setPath( parentDir.directory() ); - KFileItemList *lstItems = itemsForDir( parentDir ); - if ( lstItems ) - { - KFileItem *fit = lstItems->first(); - for ( ; fit; fit = lstItems->next() ) - if ( fit->url() == *it ) { - fileitem = fit; - lstItems->take(); // remove fileitem from list - break; - } - } - - // Tell the views about it before deleting the KFileItems. They might need the subdirs' - // file items (see the dirtree). - if ( fileitem ) - { - TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDir.url()]; - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->emitDeleteItem( fileitem ); - } - - // If we found a fileitem, we can test if it's a dir. If not, we'll go to deleteDir just in case. - if ( !fileitem || fileitem->isDir() ) - { - // in case of a dir, check if we have any known children, there's much to do in that case - // (stopping jobs, removing dirs from cache etc.) - deleteDir( *it ); - } - - // now remove the item itself - delete fileitem; - } -} - -void KDirListerCache::FilesChanged( const KURL::List &fileList ) -{ - KURL::List dirsToUpdate; - kdDebug(7004) << k_funcinfo << "only half implemented" << endl; - KURL::List::ConstIterator it = fileList.begin(); - for ( ; it != fileList.end() ; ++it ) - { - if ( ( *it ).isLocalFile() ) - { - kdDebug(7004) << "KDirListerCache::FilesChanged " << *it << endl; - KFileItem *fileitem = findByURL( 0, *it ); - if ( fileitem ) - { - // we need to refresh the item, because e.g. the permissions can have changed. - aboutToRefreshItem( fileitem ); - fileitem->refresh(); - emitRefreshItem( fileitem ); - } - else - kdDebug(7004) << "item not found" << endl; - } else { - // For remote files, refresh() won't be able to figure out the new information. - // Let's update the dir. - KURL dir( *it ); - dir.setPath( dir.directory( true ) ); - if ( dirsToUpdate.find( dir ) == dirsToUpdate.end() ) - dirsToUpdate.prepend( dir ); - } - } - - KURL::List::ConstIterator itdir = dirsToUpdate.begin(); - for ( ; itdir != dirsToUpdate.end() ; ++itdir ) - updateDirectory( *itdir ); - // ## TODO problems with current jobs listing/updating that dir - // ( see kde-2.2.2's kdirlister ) -} - -void KDirListerCache::FileRenamed( const KURL &src, const KURL &dst ) -{ - kdDebug(7004) << k_funcinfo << src.prettyURL() << " -> " << dst.prettyURL() << endl; -#ifdef DEBUG_CACHE - printDebug(); -#endif - - // Somehow this should only be called if src is a dir. But how could we know if it is? - // (Note that looking into itemsInUse isn't good enough. One could rename a subdir in a view.) - renameDir( src, dst ); - - // Now update the KFileItem representing that file or dir (not exclusive with the above!) - KURL oldurl( src ); - oldurl.adjustPath( -1 ); - KFileItem *fileitem = findByURL( 0, oldurl ); - if ( fileitem ) - { - if ( !fileitem->isLocalFile() && !fileitem->localPath().isEmpty() ) // it uses UDS_LOCAL_PATH? ouch, needs an update then - FilesChanged( src ); - else - { - aboutToRefreshItem( fileitem ); - fileitem->setURL( dst ); - fileitem->refreshMimeType(); - emitRefreshItem( fileitem ); - } - } -#ifdef DEBUG_CACHE - printDebug(); -#endif -} - -void KDirListerCache::aboutToRefreshItem( KFileItem *fileitem ) -{ - // Look whether this item was shown in any view, i.e. held by any dirlister - KURL parentDir( fileitem->url() ); - parentDir.setPath( parentDir.directory() ); - TQString parentDirURL = parentDir.url(); - TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL]; - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->aboutToRefreshItem( fileitem ); - - // Also look in urlsCurrentlyListed, in case the user manages to rename during a listing - listers = urlsCurrentlyListed[parentDirURL]; - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->aboutToRefreshItem( fileitem ); -} - -void KDirListerCache::emitRefreshItem( KFileItem *fileitem ) -{ - // Look whether this item was shown in any view, i.e. held by any dirlister - KURL parentDir( fileitem->url() ); - parentDir.setPath( parentDir.directory() ); - TQString parentDirURL = parentDir.url(); - TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL]; - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->addRefreshItem( fileitem ); - kdl->emitItems(); - } - - // Also look in urlsCurrentlyListed, in case the user manages to rename during a listing - listers = urlsCurrentlyListed[parentDirURL]; - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->addRefreshItem( fileitem ); - kdl->emitItems(); - } -} - -KDirListerCache* KDirListerCache::self() -{ - if ( !s_pSelf ) - s_pSelf = sd_KDirListerCache.setObject( s_pSelf, new KDirListerCache ); - - return s_pSelf; -} - -bool KDirListerCache::exists() -{ - return s_pSelf != 0; -} - - -// private slots - -// _file can also be a directory being currently held! -void KDirListerCache::slotFileDirty( const TQString& _file ) -{ - kdDebug(7004) << k_funcinfo << _file << endl; - - if ( !pendingUpdates[_file] ) - { - KURL dir; - dir.setPath( _file ); - if ( checkUpdate( dir.url(-1) ) ) - updateDirectory( dir ); - - // the parent directory of _file - dir.setPath( dir.directory() ); - if ( checkUpdate( dir.url() ) ) - { - // Nice hack to save memory: use the qt object name to store the filename - TQTimer *timer = new TQTimer( this, _file.utf8() ); - connect( timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotFileDirtyDelayed()) ); - pendingUpdates.insert( _file, timer ); - timer->start( 500, true ); - } - } -} - -// delayed updating of files, FAM is flooding us with events -void KDirListerCache::slotFileDirtyDelayed() -{ - TQString file = TQString::fromUtf8( TQT_TQOBJECT_CONST(sender())->name() ); - - kdDebug(7004) << k_funcinfo << file << endl; - - // TODO: do it better: don't always create/delete the TQTimer but reuse it. - // Delete the timer after the parent directory is removed from the cache. - pendingUpdates.remove( file ); - - KURL u; - u.setPath( file ); - KFileItem *item = findByURL( 0, u ); // search all items - if ( item ) - { - // we need to refresh the item, because e.g. the permissions can have changed. - aboutToRefreshItem( item ); - item->refresh(); - emitRefreshItem( item ); - } -} - -void KDirListerCache::slotFileCreated( const TQString& _file ) -{ - kdDebug(7004) << k_funcinfo << _file << endl; - // XXX: how to avoid a complete rescan here? - KURL u; - u.setPath( _file ); - u.setPath( u.directory() ); - FilesAdded( u ); -} - -void KDirListerCache::slotFileDeleted( const TQString& _file ) -{ - kdDebug(7004) << k_funcinfo << _file << endl; - KURL u; - u.setPath( _file ); - FilesRemoved( u ); -} - -void KDirListerCache::slotEntries( TDEIO::Job *job, const TDEIO::UDSEntryList &entries ) -{ - KURL url = joburl( static_cast<TDEIO::ListJob *>(job) ); - url.adjustPath(-1); - TQString urlStr = url.url(); - - kdDebug(7004) << k_funcinfo << "new entries for " << url << endl; - - DirItem *dir = itemsInUse[urlStr]; - Q_ASSERT( dir ); - - TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr]; - Q_ASSERT( listers ); - Q_ASSERT( !listers->isEmpty() ); - - // check if anyone wants the mimetypes immediately - bool delayedMimeTypes = true; - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - delayedMimeTypes = delayedMimeTypes && kdl->d->delayedMimeTypes; - - // avoid creating these QStrings again and again - static const TQString& dot = TDEGlobal::staticQString("."); - static const TQString& dotdot = TDEGlobal::staticQString(".."); - - TDEIO::UDSEntryListConstIterator it = entries.begin(); - TDEIO::UDSEntryListConstIterator end = entries.end(); - - for ( ; it != end; ++it ) - { - TQString name; - - // find out about the name - TDEIO::UDSEntry::ConstIterator entit = (*it).begin(); - for( ; entit != (*it).end(); ++entit ) - if ( (*entit).m_uds == TDEIO::UDS_NAME ) - { - name = (*entit).m_str; - break; - } - - Q_ASSERT( !name.isEmpty() ); - if ( name.isEmpty() ) - continue; - - if ( name == dot ) - { - Q_ASSERT( !dir->rootItem ); - dir->rootItem = new KFileItem( *it, url, delayedMimeTypes, true ); - - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - if ( !kdl->d->rootFileItem && kdl->d->url == url ) - kdl->d->rootFileItem = dir->rootItem; - } - else if ( name != dotdot ) - { - KFileItem* item = new KFileItem( *it, url, delayedMimeTypes, true ); - Q_ASSERT( item ); - - //kdDebug(7004)<< "Adding item: " << item->url() << endl; - dir->lstItems->append( item ); - - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->addNewItem( item ); - } - } - - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->emitItems(); -} - -void KDirListerCache::slotResult( TDEIO::Job *j ) -{ - Q_ASSERT( j ); - TDEIO::ListJob *job = static_cast<TDEIO::ListJob *>( j ); - jobs.remove( job ); - - KURL jobUrl = joburl( job ); - jobUrl.adjustPath(-1); // need remove trailing slashes again, in case of redirections - TQString jobUrlStr = jobUrl.url(); - - kdDebug(7004) << k_funcinfo << "finished listing " << jobUrl << endl; -#ifdef DEBUG_CACHE - printDebug(); -#endif - - TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( jobUrlStr ); - Q_ASSERT( listers ); - - // move the directory to the held directories, do it before emitting - // the signals to make sure it exists in KDirListerCache in case someone - // calls listDir during the signal emission - Q_ASSERT( !urlsCurrentlyHeld[jobUrlStr] ); - urlsCurrentlyHeld.insert( jobUrlStr, listers ); - - KDirLister *kdl; - - if ( job->error() ) - { - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->jobDone( job ); - kdl->handleError( job ); - emit kdl->canceled( jobUrl ); - if ( kdl->numJobs() == 0 ) - { - kdl->d->complete = true; - emit kdl->canceled(); - } - } - } - else - { - DirItem *dir = itemsInUse[jobUrlStr]; - Q_ASSERT( dir ); - dir->complete = true; - - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->jobDone( job ); - emit kdl->completed( jobUrl ); - if ( kdl->numJobs() == 0 ) - { - kdl->d->complete = true; - emit kdl->completed(); - } - } - } - - // TODO: hmm, if there was an error and job is a parent of one or more - // of the pending urls we should cancel it/them as well - processPendingUpdates(); - -#ifdef DEBUG_CACHE - printDebug(); -#endif -} - -void KDirListerCache::slotRedirection( TDEIO::Job *j, const KURL& url ) -{ - Q_ASSERT( j ); - TDEIO::ListJob *job = static_cast<TDEIO::ListJob *>( j ); - - KURL oldUrl = job->url(); // here we really need the old url! - KURL newUrl = url; - - // strip trailing slashes - oldUrl.adjustPath(-1); - newUrl.adjustPath(-1); - - if ( oldUrl == newUrl ) - { - kdDebug(7004) << k_funcinfo << "New redirection url same as old, giving up." << endl; - return; - } - - kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << newUrl.prettyURL() << endl; - -#ifdef DEBUG_CACHE - printDebug(); -#endif - - // I don't think there can be dirItems that are childs of oldUrl. - // Am I wrong here? And even if so, we don't need to delete them, right? - // DF: redirection happens before listDir emits any item. Makes little sense otherwise. - - // oldUrl cannot be in itemsCached because only completed items are moved there - DirItem *dir = itemsInUse.take( oldUrl.url() ); - Q_ASSERT( dir ); - - TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrl.url() ); - Q_ASSERT( listers ); - Q_ASSERT( !listers->isEmpty() ); - - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - // TODO: put in own method? - if ( kdl->d->url.equals( oldUrl, true ) ) - { - kdl->d->rootFileItem = 0; - kdl->d->url = newUrl; - } - - *kdl->d->lstDirs.find( oldUrl ) = newUrl; - - if ( kdl->d->lstDirs.count() == 1 ) - { - emit kdl->clear(); - emit kdl->redirection( newUrl ); - emit kdl->redirection( oldUrl, newUrl ); - } - else - { - emit kdl->clear( oldUrl ); - emit kdl->redirection( oldUrl, newUrl ); - } - } - - // when a lister was stopped before the job emits the redirection signal, the old url will - // also be in urlsCurrentlyHeld - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrl.url() ); - if ( holders ) - { - Q_ASSERT( !holders->isEmpty() ); - - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - { - kdl->jobStarted( job ); - - // do it like when starting a new list-job that will redirect later - emit kdl->started( oldUrl ); - - // TODO: maybe don't emit started if there's an update running for newUrl already? - - if ( kdl->d->url.equals( oldUrl, true ) ) - { - kdl->d->rootFileItem = 0; - kdl->d->url = newUrl; - } - - *kdl->d->lstDirs.find( oldUrl ) = newUrl; - - if ( kdl->d->lstDirs.count() == 1 ) - { - emit kdl->clear(); - emit kdl->redirection( newUrl ); - emit kdl->redirection( oldUrl, newUrl ); - } - else - { - emit kdl->clear( oldUrl ); - emit kdl->redirection( oldUrl, newUrl ); - } - } - } - - DirItem *newDir = itemsInUse[newUrl.url()]; - if ( newDir ) - { - kdDebug(7004) << "slotRedirection: " << newUrl.url() << " already in use" << endl; - - // only in this case there can newUrl already be in urlsCurrentlyListed or urlsCurrentlyHeld - delete dir; - - // get the job if one's running for newUrl already (can be a list-job or an update-job), but - // do not return this 'job', which would happen because of the use of redirectionURL() - TDEIO::ListJob *oldJob = jobForUrl( newUrl.url(), job ); - - // listers of newUrl with oldJob: forget about the oldJob and use the already running one - // which will be converted to an updateJob - TQPtrList<KDirLister> *curListers = urlsCurrentlyListed[newUrl.url()]; - if ( curListers ) - { - kdDebug(7004) << "slotRedirection: and it is currently listed" << endl; - - Q_ASSERT( oldJob ); // ?! - - for ( KDirLister *kdl = curListers->first(); kdl; kdl = curListers->next() ) // listers of newUrl - { - kdl->jobDone( oldJob ); - - kdl->jobStarted( job ); - kdl->connectJob( job ); - } - - // append listers of oldUrl with newJob to listers of newUrl with oldJob - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - curListers->append( kdl ); - } - else - urlsCurrentlyListed.insert( newUrl.url(), listers ); - - if ( oldJob ) // kill the old job, be it a list-job or an update-job - killJob( oldJob ); - - // holders of newUrl: use the already running job which will be converted to an updateJob - TQPtrList<KDirLister> *curHolders = urlsCurrentlyHeld[newUrl.url()]; - if ( curHolders ) - { - kdDebug(7004) << "slotRedirection: and it is currently held." << endl; - - for ( KDirLister *kdl = curHolders->first(); kdl; kdl = curHolders->next() ) // holders of newUrl - { - kdl->jobStarted( job ); - emit kdl->started( newUrl ); - } - - // append holders of oldUrl to holders of newUrl - if ( holders ) - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - curHolders->append( kdl ); - } - else if ( holders ) - urlsCurrentlyHeld.insert( newUrl.url(), holders ); - - - // emit old items: listers, holders. NOT: newUrlListers/newUrlHolders, they already have them listed - // TODO: make this a separate method? - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - if ( !kdl->d->rootFileItem && kdl->d->url == newUrl ) - kdl->d->rootFileItem = newDir->rootItem; - - kdl->addNewItems( *(newDir->lstItems) ); - kdl->emitItems(); - } - - if ( holders ) - { - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - { - if ( !kdl->d->rootFileItem && kdl->d->url == newUrl ) - kdl->d->rootFileItem = newDir->rootItem; - - kdl->addNewItems( *(newDir->lstItems) ); - kdl->emitItems(); - } - } - } - else if ( (newDir = itemsCached.take( newUrl.url() )) ) - { - kdDebug(7004) << "slotRedirection: " << newUrl.url() << " is unused, but already in the cache." << endl; - - delete dir; - itemsInUse.insert( newUrl.url(), newDir ); - urlsCurrentlyListed.insert( newUrl.url(), listers ); - if ( holders ) - urlsCurrentlyHeld.insert( newUrl.url(), holders ); - - // emit old items: listers, holders - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - if ( !kdl->d->rootFileItem && kdl->d->url == newUrl ) - kdl->d->rootFileItem = newDir->rootItem; - - kdl->addNewItems( *(newDir->lstItems) ); - kdl->emitItems(); - } - - if ( holders ) - { - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - { - if ( !kdl->d->rootFileItem && kdl->d->url == newUrl ) - kdl->d->rootFileItem = newDir->rootItem; - - kdl->addNewItems( *(newDir->lstItems) ); - kdl->emitItems(); - } - } - } - else - { - kdDebug(7004) << "slotRedirection: " << newUrl.url() << " has not been listed yet." << endl; - - delete dir->rootItem; - dir->rootItem = 0; - dir->lstItems->clear(); - dir->redirect( newUrl ); - itemsInUse.insert( newUrl.url(), dir ); - urlsCurrentlyListed.insert( newUrl.url(), listers ); - - if ( holders ) - urlsCurrentlyHeld.insert( newUrl.url(), holders ); - else - { -#ifdef DEBUG_CACHE - printDebug(); -#endif - return; // only in this case the job doesn't need to be converted, - } - } - - // make the job an update job - job->disconnect( this ); - - connect( job, TQT_SIGNAL(entries( TDEIO::Job *, const TDEIO::UDSEntryList & )), - this, TQT_SLOT(slotUpdateEntries( TDEIO::Job *, const TDEIO::UDSEntryList & )) ); - connect( job, TQT_SIGNAL(result( TDEIO::Job * )), - this, TQT_SLOT(slotUpdateResult( TDEIO::Job * )) ); - - // FIXME: autoUpdate-Counts!! - -#ifdef DEBUG_CACHE - printDebug(); -#endif -} - -void KDirListerCache::renameDir( const KURL &oldUrl, const KURL &newUrl ) -{ - kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << newUrl.prettyURL() << endl; - TQString oldUrlStr = oldUrl.url(-1); - TQString newUrlStr = newUrl.url(-1); - - // Not enough. Also need to look at any child dir, even sub-sub-sub-dir. - //DirItem *dir = itemsInUse.take( oldUrlStr ); - //emitRedirections( oldUrl, url ); - - // Look at all dirs being listed/shown - TQDictIterator<DirItem> itu( itemsInUse ); - bool goNext; - while ( itu.current() ) - { - goNext = true; - DirItem *dir = itu.current(); - KURL oldDirUrl ( itu.currentKey() ); - //kdDebug(7004) << "itemInUse: " << oldDirUrl.prettyURL() << endl; - // Check if this dir is oldUrl, or a subfolder of it - if ( oldUrl.isParentOf( oldDirUrl ) ) - { - // TODO should use KURL::cleanpath like isParentOf does - TQString relPath = oldDirUrl.path().mid( oldUrl.path().length() ); - - KURL newDirUrl( newUrl ); // take new base - if ( !relPath.isEmpty() ) - newDirUrl.addPath( relPath ); // add unchanged relative path - //kdDebug(7004) << "KDirListerCache::renameDir new url=" << newDirUrl.prettyURL() << endl; - - // Update URL in dir item and in itemsInUse - dir->redirect( newDirUrl ); - itemsInUse.remove( itu.currentKey() ); // implies ++itu - itemsInUse.insert( newDirUrl.url(-1), dir ); - goNext = false; // because of the implied ++itu above - if ( dir->lstItems ) - { - // Rename all items under that dir - KFileItemListIterator kit( *dir->lstItems ); - for ( ; kit.current(); ++kit ) - { - KURL oldItemUrl = (*kit)->url(); - TQString oldItemUrlStr( oldItemUrl.url(-1) ); - KURL newItemUrl( oldItemUrl ); - newItemUrl.setPath( newDirUrl.path() ); - newItemUrl.addPath( oldItemUrl.fileName() ); - kdDebug(7004) << "KDirListerCache::renameDir renaming " << oldItemUrlStr << " to " << newItemUrl.url() << endl; - (*kit)->setURL( newItemUrl ); - } - } - emitRedirections( oldDirUrl, newDirUrl ); - } - if ( goNext ) - ++itu; - } - - // Is oldUrl a directory in the cache? - // Remove any child of oldUrl from the cache - even if the renamed dir itself isn't in it! - removeDirFromCache( oldUrl ); - // TODO rename, instead. -} - -void KDirListerCache::emitRedirections( const KURL &oldUrl, const KURL &url ) -{ - kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << url.prettyURL() << endl; - TQString oldUrlStr = oldUrl.url(-1); - TQString urlStr = url.url(-1); - - TDEIO::ListJob *job = jobForUrl( oldUrlStr ); - if ( job ) - killJob( job ); - - // Check if we were listing this dir. Need to abort and restart with new name in that case. - TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrlStr ); - if ( listers ) - { - // Tell the world that the job listing the old url is dead. - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - if ( job ) - kdl->jobDone( job ); - - emit kdl->canceled( oldUrl ); - } - - urlsCurrentlyListed.insert( urlStr, listers ); - } - - // Check if we are currently displaying this directory (odds opposite wrt above) - // Update urlsCurrentlyHeld dict with new URL - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrlStr ); - if ( holders ) - { - if ( job ) - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - kdl->jobDone( job ); - - urlsCurrentlyHeld.insert( urlStr, holders ); - } - - if ( listers ) - { - updateDirectory( url ); - - // Tell the world about the new url - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - emit kdl->started( url ); - } - - if ( holders ) - { - // And notify the dirlisters of the redirection - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - { - *kdl->d->lstDirs.find( oldUrl ) = url; - - if ( kdl->d->lstDirs.count() == 1 ) - emit kdl->redirection( url ); - - emit kdl->redirection( oldUrl, url ); - } - } -} - -void KDirListerCache::removeDirFromCache( const KURL& dir ) -{ - kdDebug(7004) << "KDirListerCache::removeDirFromCache " << dir.prettyURL() << endl; - TQCacheIterator<DirItem> itc( itemsCached ); - while ( itc.current() ) - { - if ( dir.isParentOf( KURL( itc.currentKey() ) ) ) - itemsCached.remove( itc.currentKey() ); - else - ++itc; - } -} - -void KDirListerCache::slotUpdateEntries( TDEIO::Job* job, const TDEIO::UDSEntryList& list ) -{ - jobs[static_cast<TDEIO::ListJob*>(job)] += list; -} - -void KDirListerCache::slotUpdateResult( TDEIO::Job * j ) -{ - Q_ASSERT( j ); - TDEIO::ListJob *job = static_cast<TDEIO::ListJob *>( j ); - - KURL jobUrl = joburl( job ); - jobUrl.adjustPath(-1); // need remove trailing slashes again, in case of redirections - TQString jobUrlStr = jobUrl.url(); - - kdDebug(7004) << k_funcinfo << "finished update " << jobUrl << endl; - - KDirLister *kdl; - - TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[jobUrlStr]; - TQPtrList<KDirLister> *tmpLst = urlsCurrentlyListed.take( jobUrlStr ); - - if ( tmpLst ) - { - if ( listers ) - for ( kdl = tmpLst->first(); kdl; kdl = tmpLst->next() ) - { - Q_ASSERT( listers->containsRef( kdl ) == 0 ); - listers->append( kdl ); - } - else - { - listers = tmpLst; - urlsCurrentlyHeld.insert( jobUrlStr, listers ); - } - } - - // once we are updating dirs that are only in the cache this will fail! - Q_ASSERT( listers ); - - if ( job->error() ) - { - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->jobDone( job ); - - //don't bother the user - //kdl->handleError( job ); - - emit kdl->canceled( jobUrl ); - if ( kdl->numJobs() == 0 ) - { - kdl->d->complete = true; - emit kdl->canceled(); - } - } - - jobs.remove( job ); - - // TODO: if job is a parent of one or more - // of the pending urls we should cancel them - processPendingUpdates(); - return; - } - - DirItem *dir = itemsInUse[jobUrlStr]; - dir->complete = true; - - - // check if anyone wants the mimetypes immediately - bool delayedMimeTypes = true; - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - delayedMimeTypes = delayedMimeTypes && kdl->d->delayedMimeTypes; - - // should be enough to get reasonable speed in most cases - TQDict<KFileItem> fileItems( 9973 ); - - KFileItemListIterator kit ( *(dir->lstItems) ); - - // Unmark all items in url - for ( ; kit.current(); ++kit ) - { - (*kit)->unmark(); - fileItems.insert( (*kit)->url().url(), *kit ); - } - - static const TQString& dot = TDEGlobal::staticQString("."); - static const TQString& dotdot = TDEGlobal::staticQString(".."); - - KFileItem *item = 0, *tmp; - - TQValueList<TDEIO::UDSEntry> buf = jobs[job]; - TQValueListIterator<TDEIO::UDSEntry> it = buf.begin(); - for ( ; it != buf.end(); ++it ) - { - // Form the complete url - if ( !item ) - item = new KFileItem( *it, jobUrl, delayedMimeTypes, true ); - else - item->setUDSEntry( *it, jobUrl, delayedMimeTypes, true ); - - // Find out about the name - TQString name = item->name(); - Q_ASSERT( !name.isEmpty() ); - - // we duplicate the check for dotdot here, to avoid iterating over - // all items again and checking in matchesFilter() that way. - if ( name.isEmpty() || name == dotdot ) - continue; - - if ( name == dot ) - { - // if the update was started before finishing the original listing - // there is no root item yet - if ( !dir->rootItem ) - { - dir->rootItem = item; - item = 0; - - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - if ( !kdl->d->rootFileItem && kdl->d->url == jobUrl ) - kdl->d->rootFileItem = dir->rootItem; - } - - continue; - } - - // Find this item - if ( (tmp = fileItems[item->url().url()]) ) - { - tmp->mark(); - - // check if something changed for this file - if ( !tmp->cmp( *item ) ) - { - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->aboutToRefreshItem( tmp ); - - //kdDebug(7004) << "slotUpdateResult: file changed: " << tmp->name() << endl; - tmp->assign( *item ); - - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->addRefreshItem( tmp ); - } - } - else // this is a new file - { - //kdDebug(7004) << "slotUpdateResult: new file: " << name << endl; - - item->mark(); - dir->lstItems->append( item ); - - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->addNewItem( item ); - - // item used, we need a new one for the next iteration - item = 0; - } - } - - if ( item ) - delete item; - - jobs.remove( job ); - - deleteUnmarkedItems( listers, dir->lstItems ); - - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->emitItems(); - - kdl->jobDone( job ); - - emit kdl->completed( jobUrl ); - if ( kdl->numJobs() == 0 ) - { - kdl->d->complete = true; - emit kdl->completed(); - } - } - - // TODO: hmm, if there was an error and job is a parent of one or more - // of the pending urls we should cancel it/them as well - processPendingUpdates(); -} - -// private - -TDEIO::ListJob *KDirListerCache::jobForUrl( const TQString& url, TDEIO::ListJob *not_job ) -{ - TDEIO::ListJob *job; - TQMap< TDEIO::ListJob *, TQValueList<TDEIO::UDSEntry> >::Iterator it = jobs.begin(); - while ( it != jobs.end() ) - { - job = it.key(); - if ( joburl( job ).url(-1) == url && job != not_job ) - return job; - ++it; - } - return 0; -} - -const KURL& KDirListerCache::joburl( TDEIO::ListJob *job ) -{ - if ( job->redirectionURL().isValid() ) - return job->redirectionURL(); - else - return job->url(); -} - -void KDirListerCache::killJob( TDEIO::ListJob *job ) -{ - jobs.remove( job ); - job->disconnect( this ); - job->kill(); -} - -void KDirListerCache::deleteUnmarkedItems( TQPtrList<KDirLister> *listers, KFileItemList *lstItems ) -{ - // Find all unmarked items and delete them - KFileItem* item; - lstItems->first(); - while ( (item = lstItems->current()) ) - if ( !item->isMarked() ) - { - //kdDebug() << k_funcinfo << item->name() << endl; - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->emitDeleteItem( item ); - - if ( item->isDir() ) - deleteDir( item->url() ); - - // finally actually delete the item - lstItems->take(); - delete item; - } - else - lstItems->next(); -} - -void KDirListerCache::deleteDir( const KURL& dirUrl ) -{ - //kdDebug() << k_funcinfo << dirUrl.prettyURL() << endl; - // unregister and remove the childs of the deleted item. - // Idea: tell all the KDirListers that they should forget the dir - // and then remove it from the cache. - - TQDictIterator<DirItem> itu( itemsInUse ); - while ( itu.current() ) - { - KURL deletedUrl( itu.currentKey() ); - if ( dirUrl.isParentOf( deletedUrl ) ) - { - // stop all jobs for deletedUrl - - TQPtrList<KDirLister> *kdls = urlsCurrentlyListed[deletedUrl.url()]; - if ( kdls ) // yeah, I lack good names - { - // we need a copy because stop modifies the list - kdls = new TQPtrList<KDirLister>( *kdls ); - for ( KDirLister *kdl = kdls->first(); kdl; kdl = kdls->next() ) - stop( kdl, deletedUrl ); - - delete kdls; - } - - // tell listers holding deletedUrl to forget about it - // this will stop running updates for deletedUrl as well - - kdls = urlsCurrentlyHeld[deletedUrl.url()]; - if ( kdls ) - { - // we need a copy because forgetDirs modifies the list - kdls = new TQPtrList<KDirLister>( *kdls ); - - for ( KDirLister *kdl = kdls->first(); kdl; kdl = kdls->next() ) - { - // lister's root is the deleted item - if ( kdl->d->url == deletedUrl ) - { - // tell the view first. It might need the subdirs' items (which forgetDirs will delete) - if ( kdl->d->rootFileItem ) - emit kdl->deleteItem( kdl->d->rootFileItem ); - forgetDirs( kdl ); - kdl->d->rootFileItem = 0; - } - else - { - bool treeview = kdl->d->lstDirs.count() > 1; - if ( !treeview ) - emit kdl->clear(); - - forgetDirs( kdl, deletedUrl, treeview ); - } - } - - delete kdls; - } - - // delete the entry for deletedUrl - should not be needed, it's in - // items cached now - - DirItem *dir = itemsInUse.take( deletedUrl.url() ); - Q_ASSERT( !dir ); - if ( !dir ) // take didn't find it - move on - ++itu; - } - else - ++itu; - } - - // remove the children from the cache - removeDirFromCache( dirUrl ); -} - -void KDirListerCache::processPendingUpdates() -{ - // TODO -} - -#ifndef NDEBUG -void KDirListerCache::printDebug() -{ - kdDebug(7004) << "Items in use: " << endl; - TQDictIterator<DirItem> itu( itemsInUse ); - for ( ; itu.current() ; ++itu ) { - kdDebug(7004) << " " << itu.currentKey() << " URL: " << itu.current()->url - << " rootItem: " << ( itu.current()->rootItem ? itu.current()->rootItem->url() : KURL() ) - << " autoUpdates refcount: " << itu.current()->autoUpdates - << " complete: " << itu.current()->complete - << ( itu.current()->lstItems ? TQString(" with %1 items.").arg(itu.current()->lstItems->count()) : TQString(" lstItems=NULL") ) << endl; - } - - kdDebug(7004) << "urlsCurrentlyHeld: " << endl; - TQDictIterator< TQPtrList<KDirLister> > it( urlsCurrentlyHeld ); - for ( ; it.current() ; ++it ) - { - TQString list; - for ( TQPtrListIterator<KDirLister> listit( *it.current() ); listit.current(); ++listit ) - list += " 0x" + TQString::number( (long)listit.current(), 16 ); - kdDebug(7004) << " " << it.currentKey() << " " << it.current()->count() << " listers: " << list << endl; - } - - kdDebug(7004) << "urlsCurrentlyListed: " << endl; - TQDictIterator< TQPtrList<KDirLister> > it2( urlsCurrentlyListed ); - for ( ; it2.current() ; ++it2 ) - { - TQString list; - for ( TQPtrListIterator<KDirLister> listit( *it2.current() ); listit.current(); ++listit ) - list += " 0x" + TQString::number( (long)listit.current(), 16 ); - kdDebug(7004) << " " << it2.currentKey() << " " << it2.current()->count() << " listers: " << list << endl; - } - - TQMap< TDEIO::ListJob *, TQValueList<TDEIO::UDSEntry> >::Iterator jit = jobs.begin(); - kdDebug(7004) << "Jobs: " << endl; - for ( ; jit != jobs.end() ; ++jit ) - kdDebug(7004) << " " << jit.key() << " listing " << joburl( jit.key() ).prettyURL() << ": " << (*jit).count() << " entries." << endl; - - kdDebug(7004) << "Items in cache: " << endl; - TQCacheIterator<DirItem> itc( itemsCached ); - for ( ; itc.current() ; ++itc ) - kdDebug(7004) << " " << itc.currentKey() << " rootItem: " - << ( itc.current()->rootItem ? itc.current()->rootItem->url().prettyURL() : TQString("NULL") ) - << ( itc.current()->lstItems ? TQString(" with %1 items.").arg(itc.current()->lstItems->count()) : TQString(" lstItems=NULL") ) << endl; -} -#endif - -/*********************** -- The new KDirLister -- ************************/ - - -KDirLister::KDirLister( bool _delayedMimeTypes ) -{ - kdDebug(7003) << "+KDirLister" << endl; - - d = new KDirListerPrivate; - - d->complete = true; - d->delayedMimeTypes = _delayedMimeTypes; - - setAutoUpdate( true ); - setDirOnlyMode( false ); - setShowingDotFiles( false ); - - setAutoErrorHandlingEnabled( true, 0 ); -} - -KDirLister::~KDirLister() -{ - kdDebug(7003) << "-KDirLister" << endl; - - if ( KDirListerCache::exists() ) - { - // Stop all running jobs - stop(); - s_pCache->forgetDirs( this ); - } - - delete d; -} - -bool KDirLister::openURL( const KURL& _url, bool _keep, bool _reload ) -{ - kdDebug(7003) << k_funcinfo << _url.prettyURL() - << " keep=" << _keep << " reload=" << _reload << endl; - - // emit the current changes made to avoid an inconsistent treeview - if ( d->changes != NONE && _keep ) - emitChanges(); - - d->changes = NONE; - - // If a local path is available, monitor that instead of the given remote URL... - KURL realURL = _url; - if (!realURL.isLocalFile()) { - TDEIO::LocalURLJob* localURLJob = TDEIO::localURL(_url); - if (localURLJob) { - connect(localURLJob, TQT_SIGNAL(localURL(TDEIO::Job*, const KURL&, bool)), this, TQT_SLOT(slotLocalURL(TDEIO::Job*, const KURL&, bool))); - connect(localURLJob, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotLocalURLKIODestroyed())); - d->localURLSlotFired = false; - while (!d->localURLSlotFired) { - tqApp->eventLoop()->processEvents(TQEventLoop::ExcludeUserInput); - usleep(1000); - } - if (d->localURLResultIsLocal) { - realURL = d->localURLResultURL; - } - } - } - - return s_pCache->listDir( this, realURL, _keep, _reload ); -} - -void KDirLister::slotLocalURL(TDEIO::Job *job, const KURL& url, bool isLocal) { - d->localURLSlotFired = true; - d->localURLResultURL = url; - d->localURLResultIsLocal = isLocal; -} - -void KDirLister::slotLocalURLKIODestroyed() { - if (!d->localURLSlotFired) { - d->localURLSlotFired = true; - d->localURLResultURL = KURL(); - d->localURLResultIsLocal = false; - } -} - -void KDirLister::stop() -{ - kdDebug(7003) << k_funcinfo << endl; - s_pCache->stop( this ); -} - -void KDirLister::stop( const KURL& _url ) -{ - kdDebug(7003) << k_funcinfo << _url.prettyURL() << endl; - s_pCache->stop( this, _url ); -} - -bool KDirLister::autoUpdate() const -{ - return d->autoUpdate; -} - -void KDirLister::setAutoUpdate( bool _enable ) -{ - if ( d->autoUpdate == _enable ) - return; - - d->autoUpdate = _enable; - s_pCache->setAutoUpdate( this, _enable ); -} - -bool KDirLister::showingDotFiles() const -{ - return d->isShowingDotFiles; -} - -void KDirLister::setShowingDotFiles( bool _showDotFiles ) -{ - if ( d->isShowingDotFiles == _showDotFiles ) - return; - - d->isShowingDotFiles = _showDotFiles; - d->changes ^= DOT_FILES; -} - -bool KDirLister::dirOnlyMode() const -{ - return d->dirOnlyMode; -} - -void KDirLister::setDirOnlyMode( bool _dirsOnly ) -{ - if ( d->dirOnlyMode == _dirsOnly ) - return; - - d->dirOnlyMode = _dirsOnly; - d->changes ^= DIR_ONLY_MODE; -} - -bool KDirLister::autoErrorHandlingEnabled() const -{ - return d->autoErrorHandling; -} - -void KDirLister::setAutoErrorHandlingEnabled( bool enable, TQWidget* parent ) -{ - d->autoErrorHandling = enable; - d->errorParent = parent; -} - -const KURL& KDirLister::url() const -{ - return d->url; -} - -const KURL::List& KDirLister::directories() const -{ - return d->lstDirs; -} - -void KDirLister::emitChanges() -{ - if ( d->changes == NONE ) - return; - - static const TQString& dot = TDEGlobal::staticQString("."); - static const TQString& dotdot = TDEGlobal::staticQString(".."); - - for ( KURL::List::Iterator it = d->lstDirs.begin(); - it != d->lstDirs.end(); ++it ) - { - KFileItemListIterator kit( *s_pCache->itemsForDir( *it ) ); - for ( ; kit.current(); ++kit ) - { - if ( (*kit)->text() == dot || (*kit)->text() == dotdot ) - continue; - - bool oldMime = true, newMime = true; - - if ( d->changes & MIME_FILTER ) - { - oldMime = doMimeFilter( (*kit)->mimetype(), d->oldMimeFilter ) - && doMimeExcludeFilter( (*kit)->mimetype(), d->oldMimeExcludeFilter ); - newMime = doMimeFilter( (*kit)->mimetype(), d->mimeFilter ) - && doMimeExcludeFilter( (*kit)->mimetype(), d->mimeExcludeFilter ); - - if ( oldMime && !newMime ) - { - emit deleteItem( *kit ); - continue; - } - } - - if ( d->changes & DIR_ONLY_MODE ) - { - // the lister switched to dirOnlyMode - if ( d->dirOnlyMode ) - { - if ( !(*kit)->isDir() ) - emit deleteItem( *kit ); - } - else if ( !(*kit)->isDir() ) - addNewItem( *kit ); - - continue; - } - - if ( (*kit)->isHidden() ) - { - if ( d->changes & DOT_FILES ) - { - // the lister switched to dot files mode - if ( d->isShowingDotFiles ) - addNewItem( *kit ); - else - emit deleteItem( *kit ); - - continue; - } - } - else if ( d->changes & NAME_FILTER ) - { - bool oldName = (*kit)->isDir() || - d->oldFilters.isEmpty() || - doNameFilter( (*kit)->text(), d->oldFilters ); - - bool newName = (*kit)->isDir() || - d->lstFilters.isEmpty() || - doNameFilter( (*kit)->text(), d->lstFilters ); - - if ( oldName && !newName ) - { - emit deleteItem( *kit ); - continue; - } - else if ( !oldName && newName ) - addNewItem( *kit ); - } - - if ( (d->changes & MIME_FILTER) && !oldMime && newMime ) - addNewItem( *kit ); - } - - emitItems(); - } - - d->changes = NONE; -} - -void KDirLister::updateDirectory( const KURL& _u ) -{ - s_pCache->updateDirectory( _u ); -} - -bool KDirLister::isFinished() const -{ - return d->complete; -} - -KFileItem *KDirLister::rootItem() const -{ - return d->rootFileItem; -} - -KFileItem *KDirLister::findByURL( const KURL& _url ) const -{ - return s_pCache->findByURL( this, _url ); -} - -KFileItem *KDirLister::findByName( const TQString& _name ) const -{ - return s_pCache->findByName( this, _name ); -} - -#ifndef KDE_NO_COMPAT -KFileItem *KDirLister::find( const KURL& _url ) const -{ - return findByURL( _url ); -} -#endif - - -// ================ public filter methods ================ // - -void KDirLister::setNameFilter( const TQString& nameFilter ) -{ - if ( !(d->changes & NAME_FILTER) ) - { - d->oldFilters = d->lstFilters; - d->lstFilters.setAutoDelete( false ); - } - - d->lstFilters.clear(); - d->lstFilters.setAutoDelete( true ); - - d->nameFilter = nameFilter; - - // Split on white space - TQStringList list = TQStringList::split( ' ', nameFilter ); - for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) - d->lstFilters.append( new TQRegExp(*it, false, true ) ); - - d->changes |= NAME_FILTER; -} - -const TQString& KDirLister::nameFilter() const -{ - return d->nameFilter; -} - -void KDirLister::setMimeFilter( const TQStringList& mimeFilter ) -{ - if ( !(d->changes & MIME_FILTER) ) - d->oldMimeFilter = d->mimeFilter; - - if ( mimeFilter.find("all/allfiles") != mimeFilter.end() || - mimeFilter.find("all/all") != mimeFilter.end() ) - d->mimeFilter.clear(); - else - d->mimeFilter = mimeFilter; - - d->changes |= MIME_FILTER; -} - -void KDirLister::setMimeExcludeFilter( const TQStringList& mimeExcludeFilter ) -{ - if ( !(d->changes & MIME_FILTER) ) - d->oldMimeExcludeFilter = d->mimeExcludeFilter; - - d->mimeExcludeFilter = mimeExcludeFilter; - d->changes |= MIME_FILTER; -} - - -void KDirLister::clearMimeFilter() -{ - if ( !(d->changes & MIME_FILTER) ) - { - d->oldMimeFilter = d->mimeFilter; - d->oldMimeExcludeFilter = d->mimeExcludeFilter; - } - d->mimeFilter.clear(); - d->mimeExcludeFilter.clear(); - d->changes |= MIME_FILTER; -} - -const TQStringList& KDirLister::mimeFilters() const -{ - return d->mimeFilter; -} - -bool KDirLister::matchesFilter( const TQString& name ) const -{ - return doNameFilter( name, d->lstFilters ); -} - -bool KDirLister::matchesMimeFilter( const TQString& mime ) const -{ - return doMimeFilter( mime, d->mimeFilter ) && doMimeExcludeFilter(mime,d->mimeExcludeFilter); -} - -// ================ protected methods ================ // - -bool KDirLister::matchesFilter( const KFileItem *item ) const -{ - Q_ASSERT( item ); - static const TQString& dotdot = TDEGlobal::staticQString(".."); - - if ( item->text() == dotdot ) - return false; - - if ( !d->isShowingDotFiles && item->isHidden() ) - return false; - - if ( item->isDir() || d->lstFilters.isEmpty() ) - return true; - - return matchesFilter( item->text() ); -} - -bool KDirLister::matchesMimeFilter( const KFileItem *item ) const -{ - Q_ASSERT( item ); - // Don't lose time determining the mimetype if there is no filter - if ( d->mimeFilter.isEmpty() && d->mimeExcludeFilter.isEmpty() ) - return true; - return matchesMimeFilter( item->mimetype() ); -} - -bool KDirLister::doNameFilter( const TQString& name, const TQPtrList<TQRegExp>& filters ) const -{ - for ( TQPtrListIterator<TQRegExp> it( filters ); it.current(); ++it ) - if ( it.current()->exactMatch( name ) ) - return true; - - return false; -} - -bool KDirLister::doMimeFilter( const TQString& mime, const TQStringList& filters ) const -{ - if ( filters.isEmpty() ) - return true; - - KMimeType::Ptr mimeptr = KMimeType::mimeType(mime); - //kdDebug(7004) << "doMimeFilter: investigating: "<<mimeptr->name()<<endl; - TQStringList::ConstIterator it = filters.begin(); - for ( ; it != filters.end(); ++it ) - if ( mimeptr->is(*it) ) - return true; - //else kdDebug(7004) << "doMimeFilter: compared without result to "<<*it<<endl; - - - return false; -} - -bool KDirLister::doMimeExcludeFilter( const TQString& mime, const TQStringList& filters ) const -{ - if ( filters.isEmpty() ) - return true; - - TQStringList::ConstIterator it = filters.begin(); - for ( ; it != filters.end(); ++it ) - if ( (*it) == mime ) - return false; - - return true; -} - - -bool KDirLister::validURL( const KURL& _url ) const -{ - return s_pCache->validURL( this, _url ); -} - -void KDirLister::handleError( TDEIO::Job *job ) -{ - if ( d->autoErrorHandling ) - job->showErrorDialog( d->errorParent ); -} - - -// ================= private methods ================= // - -void KDirLister::addNewItem( const KFileItem *item ) -{ - if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) ) - return; // No reason to continue... bailing out here prevents a mimetype scan. - - if ( matchesMimeFilter( item ) ) - { - if ( !d->lstNewItems ) - d->lstNewItems = new KFileItemList; - - d->lstNewItems->append( item ); // items not filtered - } - else - { - if ( !d->lstMimeFilteredItems ) - d->lstMimeFilteredItems = new KFileItemList; - - d->lstMimeFilteredItems->append( item ); // only filtered by mime - } -} - -void KDirLister::addNewItems( const KFileItemList& items ) -{ - // TODO: make this faster - test if we have a filter at all first - // DF: was this profiled? The matchesFoo() functions should be fast, w/o filters... - // Of course if there is no filter and we can do a range-insertion instead of a loop, that might be good. - // But that's for Qt4, not possible with TQPtrList. - for ( KFileItemListIterator kit( items ); kit.current(); ++kit ) - addNewItem( *kit ); -} - -void KDirLister::aboutToRefreshItem( const KFileItem *item ) -{ - // The code here follows the logic in addNewItem - if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) ) - d->refreshItemWasFiltered = true; - else if ( !matchesMimeFilter( item ) ) - d->refreshItemWasFiltered = true; - else - d->refreshItemWasFiltered = false; -} - -void KDirLister::addRefreshItem( const KFileItem *item ) -{ - bool isExcluded = (d->dirOnlyMode && !item->isDir()) || !matchesFilter( item ); - - if ( !isExcluded && matchesMimeFilter( item ) ) - { - if ( d->refreshItemWasFiltered ) - { - if ( !d->lstNewItems ) - d->lstNewItems = new KFileItemList; - - d->lstNewItems->append( item ); - } - else - { - if ( !d->lstRefreshItems ) - d->lstRefreshItems = new KFileItemList; - - d->lstRefreshItems->append( item ); - } - } - else if ( !d->refreshItemWasFiltered ) - { - if ( !d->lstRemoveItems ) - d->lstRemoveItems = new KFileItemList; - - // notify the user that the mimetype of a file changed that doesn't match - // a filter or does match an exclude filter - d->lstRemoveItems->append( item ); - } -} - -void KDirLister::emitItems() -{ - KFileItemList *tmpNew = d->lstNewItems; - d->lstNewItems = 0; - - KFileItemList *tmpMime = d->lstMimeFilteredItems; - d->lstMimeFilteredItems = 0; - - KFileItemList *tmpRefresh = d->lstRefreshItems; - d->lstRefreshItems = 0; - - KFileItemList *tmpRemove = d->lstRemoveItems; - d->lstRemoveItems = 0; - - if ( tmpNew ) - { - emit newItems( *tmpNew ); - delete tmpNew; - } - - if ( tmpMime ) - { - emit itemsFilteredByMime( *tmpMime ); - delete tmpMime; - } - - if ( tmpRefresh ) - { - emit refreshItems( *tmpRefresh ); - delete tmpRefresh; - } - - if ( tmpRemove ) - { - for ( KFileItem *tmp = tmpRemove->first(); tmp; tmp = tmpRemove->next() ) - emit deleteItem( tmp ); - delete tmpRemove; - } -} - -void KDirLister::emitDeleteItem( KFileItem *item ) -{ - if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) ) - return; // No reason to continue... bailing out here prevents a mimetype scan. - if ( matchesMimeFilter( item ) ) - emit deleteItem( item ); -} - - -// ================ private slots ================ // - -void KDirLister::slotInfoMessage( TDEIO::Job *, const TQString& message ) -{ - emit infoMessage( message ); -} - -void KDirLister::slotPercent( TDEIO::Job *job, unsigned long pcnt ) -{ - d->jobData[static_cast<TDEIO::ListJob *>(job)].percent = pcnt; - - int result = 0; - - TDEIO::filesize_t size = 0; - - TQMap< TDEIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin(); - while ( dataIt != d->jobData.end() ) - { - result += (*dataIt).percent * (*dataIt).totalSize; - size += (*dataIt).totalSize; - ++dataIt; - } - - if ( size != 0 ) - result /= size; - else - result = 100; - emit percent( result ); -} - -void KDirLister::slotTotalSize( TDEIO::Job *job, TDEIO::filesize_t size ) -{ - d->jobData[static_cast<TDEIO::ListJob *>(job)].totalSize = size; - - TDEIO::filesize_t result = 0; - TQMap< TDEIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin(); - while ( dataIt != d->jobData.end() ) - { - result += (*dataIt).totalSize; - ++dataIt; - } - - emit totalSize( result ); -} - -void KDirLister::slotProcessedSize( TDEIO::Job *job, TDEIO::filesize_t size ) -{ - d->jobData[static_cast<TDEIO::ListJob *>(job)].processedSize = size; - - TDEIO::filesize_t result = 0; - TQMap< TDEIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin(); - while ( dataIt != d->jobData.end() ) - { - result += (*dataIt).processedSize; - ++dataIt; - } - - emit processedSize( result ); -} - -void KDirLister::slotSpeed( TDEIO::Job *job, unsigned long spd ) -{ - d->jobData[static_cast<TDEIO::ListJob *>(job)].speed = spd; - - int result = 0; - TQMap< TDEIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin(); - while ( dataIt != d->jobData.end() ) - { - result += (*dataIt).speed; - ++dataIt; - } - - emit speed( result ); -} - -uint KDirLister::numJobs() -{ - return d->jobData.count(); -} - -void KDirLister::jobDone( TDEIO::ListJob *job ) -{ - d->jobData.remove( job ); -} - -void KDirLister::jobStarted( TDEIO::ListJob *job ) -{ - KDirListerPrivate::JobData jobData; - jobData.speed = 0; - jobData.percent = 0; - jobData.processedSize = 0; - jobData.totalSize = 0; - - d->jobData.insert( job, jobData ); - d->complete = false; -} - -void KDirLister::connectJob( TDEIO::ListJob *job ) -{ - connect( job, TQT_SIGNAL(infoMessage( TDEIO::Job *, const TQString& )), - this, TQT_SLOT(slotInfoMessage( TDEIO::Job *, const TQString& )) ); - connect( job, TQT_SIGNAL(percent( TDEIO::Job *, unsigned long )), - this, TQT_SLOT(slotPercent( TDEIO::Job *, unsigned long )) ); - connect( job, TQT_SIGNAL(totalSize( TDEIO::Job *, TDEIO::filesize_t )), - this, TQT_SLOT(slotTotalSize( TDEIO::Job *, TDEIO::filesize_t )) ); - connect( job, TQT_SIGNAL(processedSize( TDEIO::Job *, TDEIO::filesize_t )), - this, TQT_SLOT(slotProcessedSize( TDEIO::Job *, TDEIO::filesize_t )) ); - connect( job, TQT_SIGNAL(speed( TDEIO::Job *, unsigned long )), - this, TQT_SLOT(slotSpeed( TDEIO::Job *, unsigned long )) ); -} - -void KDirLister::setMainWindow( TQWidget *window ) -{ - d->window = window; -} - -TQWidget *KDirLister::mainWindow() -{ - return d->window; -} - -KFileItemList KDirLister::items( WhichItems which ) const -{ - return itemsForDir( url(), which ); -} - -KFileItemList KDirLister::itemsForDir( const KURL& dir, WhichItems which ) const -{ - KFileItemList result; - KFileItemList *allItems = s_pCache->itemsForDir( dir ); - if ( !allItems ) - return result; - - if ( which == AllItems ) - result = *allItems; // shallow copy - else // only items passing the filters - { - for ( KFileItemListIterator kit( *allItems ); kit.current(); ++kit ) - { - KFileItem *item = *kit; - bool isExcluded = (d->dirOnlyMode && !item->isDir()) || !matchesFilter( item ); - if ( !isExcluded && matchesMimeFilter( item ) ) - result.append( item ); - } - } - - return result; -} - -// to keep BC changes - -void KDirLister::virtual_hook( int, void * ) -{ /*BASE::virtual_hook( id, data );*/ } - -#include "kdirlister.moc" -#include "kdirlister_p.moc" diff --git a/kio/kio/kdirlister.h b/kio/kio/kdirlister.h deleted file mode 100644 index 2688fcd9c..000000000 --- a/kio/kio/kdirlister.h +++ /dev/null @@ -1,634 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1999 David Faure <faure@kde.org> - 2001, 2002, 2004, 2005 Michael Brade <brade@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef kdirlister_h -#define kdirlister_h - -#include "kfileitem.h" -#include "kdirnotify.h" - -#include <tqstring.h> -#include <tqstringlist.h> - -#include <kurl.h> - -namespace TDEIO { class Job; class ListJob; } - -/** - * The dir lister deals with the kiojob used to list and update a directory - * and has signals for the user of this class (e.g. konqueror view or - * kdesktop) to create/destroy its items when asked. - * - * This class is independent from the graphical representation of the dir - * (icon container, tree view, ...) and it stores the items (as KFileItems). - * - * Typical usage : - * @li Create an instance. - * @li Connect to at least update, clear, newItem, and deleteItem. - * @li Call openURL - the signals will be called. - * @li Reuse the instance when opening a new url (openURL). - * @li Destroy the instance when not needed anymore (usually destructor). - * - * Advanced usage : call openURL with _keep = true to list directories - * without forgetting the ones previously read (e.g. for a tree view) - * - * @short Helper class for the kiojob used to list and update a directory. - * @author Michael Brade <brade@kde.org> - */ -class TDEIO_EXPORT KDirLister : public TQObject -{ - class KDirListerPrivate; - friend class KDirListerPrivate; - friend class KDirListerCache; - - Q_OBJECT - TQ_PROPERTY( bool autoUpdate READ autoUpdate WRITE setAutoUpdate ) - TQ_PROPERTY( bool showingDotFiles READ showingDotFiles WRITE setShowingDotFiles ) - TQ_PROPERTY( bool dirOnlyMode READ dirOnlyMode WRITE setDirOnlyMode ) - TQ_PROPERTY( bool autoErrorHandlingEnabled READ autoErrorHandlingEnabled ) - TQ_PROPERTY( TQString nameFilter READ nameFilter WRITE setNameFilter ) - TQ_PROPERTY( TQStringList mimeFilter READ mimeFilters WRITE setMimeFilter RESET clearMimeFilter ) - -public: - /** - * Create a directory lister. - * @param _delayedMimeTypes if true, mime types will be fetched on demand. If false, - * they will always be fetched immediately - */ - KDirLister( bool _delayedMimeTypes = false ); - - /** - * Destroy the directory lister. - */ - virtual ~KDirLister(); - - /** - * Run the directory lister on the given url. - * - * This method causes KDirLister to emit _all_ the items of @p _url, in any case. - * Depending on @p _keep either clear() or clear(const KURL &) will be - * emitted first. - * - * The newItems() signal may be emitted more than once to supply you - * with KFileItems, up until the signal completed() is emitted - * (and isFinished() returns true). - * - * @param _url the directory URL. - * @param _keep if true the previous directories aren't forgotten - * (they are still watched by kdirwatch and their items - * are kept for this KDirLister). This is useful for e.g. - * a treeview. - * @param _reload indicates wether to use the cache (false) or to reread the - * directory from the disk. - * Use only when opening a dir not yet listed by this lister - * without using the cache. Otherwise use updateDirectory. - * @return true if successful, - * false otherwise (e.g. invalid @p _url) - */ - virtual bool openURL( const KURL& _url, bool _keep = false, bool _reload = false ); - - /** - * Stop listing all directories currently being listed. - * - * Emits canceled() if there was at least one job running. - * Emits canceled( const KURL& ) for each stopped job if - * there are at least two dirctories being watched by KDirLister. - */ - virtual void stop(); - - /** - * Stop listing the given directory. - * - * Emits canceled() if the killed job was the last running one. - * Emits canceled( const KURL& ) for the killed job if - * there are at least two directories being watched by KDirLister. - * No signal is emitted if there was no job running for @p _url. - * @param _url the directory URL - */ - virtual void stop( const KURL& _url ); - - /** - * Checks whether KDirWatch will automatically update directories. This is - * enabled by default. - * @return true if KDirWatch is used to automatically update directories. - */ - bool autoUpdate() const; - - /** - * Enable/disable automatic directory updating, when a directory changes - * (using KDirWatch). - * @param enable true to enable, false to disable - */ - virtual void setAutoUpdate( bool enable ); - - /** - * Check whether auto error handling is enabled. - * If enabled, it will show an error dialog to the user when an - * error occurs. It is turned on by default. - * @return true if auto error handling is enabled, false otherwise - * @see setAutoErrorHandlingEnabled() - */ - bool autoErrorHandlingEnabled() const; - - /** - * Enable or disable auto error handling is enabled. - * If enabled, it will show an error dialog to the user when an - * error occurs. It is turned on by default. - * @param enable true to enable auto error handling, false to disable - * @param parent the parent widget for the error dialogs, can be 0 for - * top-level - * @see autoErrorHandlingEnabled() - */ - void setAutoErrorHandlingEnabled( bool enable, TQWidget *parent ); - - /** - * Checks whether hidden files (files beginning with a dot) will be - * shown. - * By default this option is disabled (hidden files will be not shown). - * @return true if dot files are shown, false otherwise - * @see setShowingDotFiles() - */ - bool showingDotFiles() const; - - /** - * Changes the "is viewing dot files" setting. - * Calls updateDirectory() if setting changed. - * By default this option is disabled (hidden files will not be shown). - * @param _showDotFiles true to enable showing hidden files, false to - * disable - * @see showingDotFiles() - */ - virtual void setShowingDotFiles( bool _showDotFiles ); - - /** - * Checks whether the KDirLister only lists directories or all - * files. - * By default this option is disabled (all files will be shown). - * @return true if setDirOnlyMode(true) was called - */ - bool dirOnlyMode() const; - - /** - * Call this to list only directories. - * By default this option is disabled (all files will be shown). - * @param dirsOnly true to list only directories - */ - virtual void setDirOnlyMode( bool dirsOnly ); - - /** - * Returns the top level URL that is listed by this KDirLister. - * It might be different from the one given with openURL() if there was a - * redirection. If you called openURL() with @p _keep == true this is the - * first url opened (e.g. in a treeview this is the root). - * - * @return the url used by this instance to list the files. - */ - const KURL& url() const; - - /** - * Returns all URLs that are listed by this KDirLister. This is only - * useful if you called openURL() with @p _keep == true, as it happens in a - * treeview, for example. (Note that the base url is included in the list - * as well, of course.) - * - * @return the list of all listed URLs - * @since 3.4 - */ - const KURL::List& directories() const; - - /** - * Actually emit the changes made with setShowingDotFiles, setDirOnlyMode, - * setNameFilter and setMimeFilter. - */ - virtual void emitChanges(); - - /** - * Update the directory @p _dir. This method causes KDirLister to _only_ emit - * the items of @p _dir that actually changed compared to the current state in the - * cache and updates the cache. - * - * The current implementation calls updateDirectory automatically for - * local files, using KDirWatch (if autoUpdate() is true), but it might be - * useful to force an update manually. - * - * @param _dir the directory URL - */ - virtual void updateDirectory( const KURL& _dir ); - - /** - * Returns true if no io operation is currently in progress. - * @return true if finished, false otherwise - */ - bool isFinished() const; - - /** - * Returns the file item of the URL. - * @return the file item for url() itself (".") - */ - KFileItem *rootItem() const; - - /** - * Find an item by its URL. - * @param _url the item URL - * @return the pointer to the KFileItem - */ - virtual KFileItem *findByURL( const KURL& _url ) const; -#ifndef KDE_NO_COMPAT - KFileItem *find( const KURL& _url ) const; -#endif - - /** - * Find an item by its name. - * @param name the item name - * @return the pointer to the KFileItem - */ - virtual KFileItem *findByName( const TQString& name ) const; - - /** - * Set a name filter to only list items matching this name, e.g. "*.cpp". - * - * You can set more than one filter by separating them with whitespace, e.g - * "*.cpp *.h". - * Note: the direcory is not automatically reloaded. - * - * @param filter the new filter, TQString::null to disable filtering - * @see matchesFilter - */ - virtual void setNameFilter( const TQString &filter ); - - /** - * Returns the current name filter, as set via setNameFilter() - * @return the current name filter, can be TQString::null if filtering - * is turned off - */ - const TQString& nameFilter() const; - - /** - * Set mime-based filter to only list items matching the given mimetypes. - * - * NOTE: setting the filter does not automatically reload direcory. - * Also calling this function will not affect any named filter already set. - * - * @param mimeList a list of mime-types. - * - * @see clearMimeFilter - * @see matchesMimeFilter - */ - virtual void setMimeFilter( const TQStringList &mimeList ); - - /** - * Filtering should be done with KFileFilter. This will be implemented in a later - * revision of KDirLister. This method may be removed then. - * - * Set mime-based exclude filter to only list items not matching the given mimetypes - * - * NOTE: setting the filter does not automatically reload direcory. - * Also calling this function will not affect any named filter already set. - * - * @param mimeList a list of mime-types. - * @see clearMimeFilter - * @see matchesMimeFilter - * @since 3.1 - * @internal - */ - void setMimeExcludeFilter(const TQStringList &mimeList ); - - - /** - * Clears the mime based filter. - * - * @see setMimeFilter - */ - virtual void clearMimeFilter(); - - /** - * Returns the list of mime based filters, as set via setMimeFilter(). - * @return the list of mime based filters. Empty, when no mime filter is set. - */ - const TQStringList& mimeFilters() const; - - /** - * Checks whether @p name matches a filter in the list of name filters. - * @return true if @p name matches a filter in the list, - * otherwise false. - * @see setNameFilter - */ - bool matchesFilter( const TQString& name ) const; - - /** - * Checks whether @p mime matches a filter in the list of mime types - * @param mime the mimetype to find in the filter list. - * @return true if @p name matches a filter in the list, - * otherwise false. - * @see setMimeFilter. - */ - bool matchesMimeFilter( const TQString& mime ) const; - - /** - * Pass the main window this object is associated with - * this is used for caching authentication data - * @param window the window to associate with, 0 to disassociate - * @since 3.1 - */ - void setMainWindow( TQWidget *window ); - - /** - * Returns the main window associated with this object. - * @return the associated main window, or 0 if there is none - * @since 3.1 - */ - TQWidget *mainWindow(); - - /** - * Used by items() and itemsForDir() to specify whether you want - * all items for a directory or just the filtered ones. - */ - enum WhichItems - { - AllItems = 0, - FilteredItems = 1 - }; - - /** - * Returns the items listed for the current url(). - * This method will NOT start listing a directory, you should only call - * this when receiving the finished() signal. - * - * The items in the KFileItemList are references to the items used - * by KDirLister, so e.g. an item gets destroyed when the deleteItem() - * signal is emitted. - * - * @param which specifies whether the returned list will contain all entries - * or only the ones that passed the nameFilter(), mimeFilter(), - * etc. Note that the latter causes iteration over all the - * items, filtering them. If this is too slow for you, use the - * newItems() signal, sending out filtered items in chunks. - * @return the items listed for the current url(). - * @since 3.1 - */ - KFileItemList items( WhichItems which = FilteredItems ) const; - - /** - * Returns the items listed for the given @p dir. - * This method will NOT start listing @p dir, you should only call - * this when receiving the finished() signal. - * - * The items in the KFileItemList are references to the items used - * by KDirLister, so e.g. an item gets destroyed when the deleteItem() - * signal is emitted. - * - * @param dir specifies the url for which the items should be returned. This - * is only useful if you use KDirLister with multiple URLs - * i.e. using bool keep = true in openURL(). - * @param which specifies whether the returned list will contain all entries - * or only the ones that passed the nameFilter, mimeFilter, etc. - * Note that the latter causes iteration over all the items, - * filtering them. If this is too slow for you, use the - * newItems() signal, sending out filtered items in chunks. - * @return the items listed for @p dir. - * @since 3.1 - */ - KFileItemList itemsForDir( const KURL& dir, - WhichItems which = FilteredItems ) const; - -signals: - /** - * Tell the view that we started to list @p _url. NOTE: this does _not_ imply that there - * is really a job running! I.e. KDirLister::jobs() may return an empty list. In this case - * the items are taken from the cache. - * - * The view knows that openURL should start it, so it might seem useless, - * but the view also needs to know when an automatic update happens. - * @param _url the URL to list - */ - void started( const KURL& _url ); - - /** - * Tell the view that listing is finished. There are no jobs running anymore. - */ - void completed(); - - /** - * Tell the view that the listing of the directory @p _url is finished. - * There might be other running jobs left. - * @param _url the directory URL - */ - void completed( const KURL& _url ); - - /** - * Tell the view that the user canceled the listing. No running jobs are left. - */ - void canceled(); - - /** - * Tell the view that the listing of the directory @p _url was canceled. - * There might be other running jobs left. - * @param _url the directory URL - */ - void canceled( const KURL& _url ); - - /** - * Signal a redirection. - * Only emitted if there's just one directory to list, i.e. most - * probably openURL() has been called with @p _keep == @p false. - * @param _url the new URL - */ - void redirection( const KURL& _url ); - - /** - * Signal a redirection. - * @param oldUrl the original URL - * @param newUrl the new URL - */ - void redirection( const KURL& oldUrl, const KURL& newUrl ); - - /** - * Signal to clear all items. - * It must always be connected to this signal to avoid doubled items! - */ - void clear(); - - /** - * Signal to empty the directory @p _url. - * It is only emitted if the lister is holding more than one directory. - * @param _url the directory that will be emptied - */ - void clear( const KURL& _url ); - - /** - * Signal new items. - * @param items a list of new items - */ - void newItems( const KFileItemList& items ); - - /** - * Send a list of items filtered-out by mime-type. - * @param items the list of filtered items - */ - void itemsFilteredByMime( const KFileItemList& items ); - - /** - * Signal an item to remove. - * - * ATTENTION: if @p _fileItem == rootItem() the directory this lister - * is holding was deleted and you HAVE to release especially the - * rootItem() of this lister, otherwise your app will CRASH!! - * The clear() signals have been emitted already. - * @param _fileItem the fileItem to delete - */ - void deleteItem( KFileItem *_fileItem ); - - /** - * Signal an item to refresh (its mimetype/icon/name has changed). - * Note: KFileItem::refresh has already been called on those items. - * @param items the items to refresh - */ - void refreshItems( const KFileItemList& items ); - - /** - * Emitted to display information about running jobs. - * Examples of message are "Resolving host", "Connecting to host...", etc. - * @param msg the info message - */ - void infoMessage( const TQString& msg ); - - /** - * Progress signal showing the overall progress of the KDirLister. - * This allows using a progress bar very easily. (see KProgress) - * @param percent the progress in percent - */ - void percent( int percent ); - - /** - * Emitted when we know the size of the jobs. - * @param size the total size in bytes - */ - void totalSize( TDEIO::filesize_t size ); - - /** - * Regularly emitted to show the progress of this KDirLister. - * @param size the processed size in bytes - */ - void processedSize( TDEIO::filesize_t size ); - - /** - * Emitted to display information about the speed of the jobs. - * @param bytes_per_second the speed in bytes/s - */ - void speed( int bytes_per_second ); - -protected: - enum Changes { - NONE=0, NAME_FILTER=1, MIME_FILTER=2, DOT_FILES=4, DIR_ONLY_MODE=8 - }; - - /** - * Called for every new item before emitting newItems(). - * You may reimplement this method in a subclass to implement your own - * filtering. - * The default implementation filters out ".." and everything not matching - * the name filter(s) - * @return true if the item is "ok". - * false if the item shall not be shown in a view, e.g. - * files not matching a pattern *.cpp ( KFileItem::isHidden()) - * @see matchesFilter - * @see setNameFilter - */ - virtual bool matchesFilter( const KFileItem * ) const; - - /** - * Called for every new item before emitting newItems(). - * You may reimplement this method in a subclass to implement your own - * filtering. - * The default implementation filters out ".." and everything not matching - * the name filter(s) - * @return true if the item is "ok". - * false if the item shall not be shown in a view, e.g. - * files not matching a pattern *.cpp ( KFileItem::isHidden()) - * @see matchesMimeFilter - * @see setMimeFilter - */ - virtual bool matchesMimeFilter( const KFileItem * ) const; - - /** - * Called by the public matchesFilter() to do the - * actual filtering. Those methods may be reimplemented to customize - * filtering. - * @param name the name to filter - * @param filters a list of regular expressions for filtering - */ - virtual bool doNameFilter( const TQString& name, const TQPtrList<TQRegExp>& filters ) const; - - /** - * Called by the public matchesMimeFilter() to do the - * actual filtering. Those methods may be reimplemented to customize - * filtering. - * @param mime the mime type to filter - * @param filters the list of mime types to filter - */ - virtual bool doMimeFilter( const TQString& mime, const TQStringList& filters ) const; - - /** - * @internal - */ - bool doMimeExcludeFilter( const TQString& mimeExclude, const TQStringList& filters ) const; - - /** - * Checks if an url is malformed or not and displays an error message - * if it is and autoErrorHandling is set to true. - * @return true if url is valid, otherwise false. - */ - virtual bool validURL( const KURL& ) const; - - /** Reimplement to customize error handling */ - virtual void handleError( TDEIO::Job * ); - -protected: - virtual void virtual_hook( int id, void *data ); - -private slots: - void slotInfoMessage( TDEIO::Job *, const TQString& ); - void slotPercent( TDEIO::Job *, unsigned long ); - void slotTotalSize( TDEIO::Job *, TDEIO::filesize_t ); - void slotProcessedSize( TDEIO::Job *, TDEIO::filesize_t ); - void slotSpeed( TDEIO::Job *, unsigned long ); - void slotLocalURL( TDEIO::Job *, const KURL&, bool ); - void slotLocalURLKIODestroyed( ); - -private: - void jobStarted( TDEIO::ListJob * ); - void connectJob( TDEIO::ListJob * ); - void jobDone( TDEIO::ListJob * ); - - uint numJobs(); - -private: - virtual void addNewItem( const KFileItem *item ); - virtual void addNewItems( const KFileItemList& items ); - /*virtual*/ void aboutToRefreshItem( const KFileItem *item ); // TODO: KDE 4.0 make virtual - virtual void addRefreshItem( const KFileItem *item ); - virtual void emitItems(); - virtual void emitDeleteItem( KFileItem *item ); - - KDirListerPrivate *d; -}; - -#endif - diff --git a/kio/kio/kdirlister_p.h b/kio/kio/kdirlister_p.h deleted file mode 100644 index 47bd4d452..000000000 --- a/kio/kio/kdirlister_p.h +++ /dev/null @@ -1,358 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2002 Michael Brade <brade@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef kdirlister_p_h -#define kdirlister_p_h - -#include "kfileitem.h" - -#include <tqmap.h> -#include <tqdict.h> -#include <tqcache.h> -#include <tqwidget.h> - -#include <kurl.h> -#include <kio/global.h> -#include <kdirwatch.h> -#include <dcopclient.h> - -class TQTimer; -class KDirLister; -namespace TDEIO { class Job; class ListJob; } - - -class KDirLister::KDirListerPrivate -{ -public: - KDirListerPrivate() - { - complete = false; - - autoUpdate = false; - isShowingDotFiles = false; - dirOnlyMode = false; - - autoErrorHandling = false; - errorParent = 0; - - delayedMimeTypes = false; - - rootFileItem = 0; - lstNewItems = 0; - lstRefreshItems = 0; - lstMimeFilteredItems = 0; - lstRemoveItems = 0; - refreshItemWasFiltered = false; - - changes = NONE; - - window = 0; - - lstFilters.setAutoDelete( true ); - oldFilters.setAutoDelete( true ); - } - - /** - * List of dirs handled by this dirlister. The first entry is the base URL. - * For a tree view, it contains all the dirs shown. - */ - KURL::List lstDirs; - - // toplevel URL - KURL url; - - bool complete; - - bool autoUpdate; - bool isShowingDotFiles; - bool dirOnlyMode; - - bool autoErrorHandling; - TQWidget *errorParent; - - bool delayedMimeTypes; - - struct JobData { - long unsigned int percent, speed; - TDEIO::filesize_t processedSize, totalSize; - }; - - TQMap<TDEIO::ListJob *, JobData> jobData; - - // file item for the root itself (".") - KFileItem *rootFileItem; - - KFileItemList *lstNewItems, *lstRefreshItems; - KFileItemList *lstMimeFilteredItems, *lstRemoveItems; - - bool refreshItemWasFiltered; - - int changes; - - TQWidget *window; // Main window ths lister is associated with - - TQString nameFilter; - TQPtrList<TQRegExp> lstFilters, oldFilters; - TQStringList mimeFilter, oldMimeFilter; - TQStringList mimeExcludeFilter, oldMimeExcludeFilter; - - bool localURLSlotFired; - KURL localURLResultURL; - bool localURLResultIsLocal; -}; - -/** - * Design of the cache: - * There is a single KDirListerCache for the whole process. - * It holds all the items used by the dir listers (itemsInUse) - * as well as a cache of the recently used items (itemsCached). - * Those items are grouped by directory (a DirItem represents a whole directory). - * - * KDirListerCache also runs all the jobs for listing directories, whether they are for - * normal listing or for updates. - * For faster lookups, it also stores two dicts: - * a URL -> dirlister holding that URL (urlsCurrentlyHeld) - * a URL -> dirlister currently listing that URL (urlsCurrentlyListed) - */ -class KDirListerCache : public TQObject, KDirNotify -{ - Q_OBJECT -public: - KDirListerCache( int maxCount = 10 ); - ~KDirListerCache(); - - bool listDir( KDirLister *lister, const KURL& _url, bool _keep, bool _reload ); - bool validURL( const KDirLister *lister, const KURL& _url ) const; - - // stop all running jobs for lister - void stop( KDirLister *lister ); - // stop just the job listing url for lister - void stop( KDirLister *lister, const KURL &_url ); - - void setAutoUpdate( KDirLister *lister, bool enable ); - - void forgetDirs( KDirLister *lister ); - void forgetDirs( KDirLister *lister, const KURL &_url, bool notify ); - - void updateDirectory( const KURL &_dir ); - - KFileItemList *itemsForDir( const KURL &_dir ) const; - - KFileItem *findByName( const KDirLister *lister, const TQString &_name ) const; - // if lister is set, it is checked that the url is held by the lister - KFileItem *findByURL( const KDirLister *lister, const KURL &_url ) const; - - /** - * Notify that files have been added in @p directory - * The receiver will list that directory again to find - * the new items (since it needs more than just the names anyway). - * Reimplemented from KDirNotify. - */ - virtual void FilesAdded( const KURL &directory ); - - /** - * Notify that files have been deleted. - * This call passes the exact urls of the deleted files - * so that any view showing them can simply remove them - * or be closed (if its current dir was deleted) - * Reimplemented from KDirNotify. - */ - virtual void FilesRemoved( const KURL::List &fileList ); - - /** - * Notify that files have been changed. - * At the moment, this is only used for new icon, but it could be - * used for size etc. as well. - * Note: this is ASYNC so that it can be used with a broadcast - */ - virtual void FilesChanged( const KURL::List &fileList ); - virtual void FileRenamed( const KURL &src, const KURL &dst ); - - static KDirListerCache *self(); - - static bool exists(); - -private slots: - void slotFileDirty( const TQString &_file ); - void slotFileCreated( const TQString &_file ); - void slotFileDeleted( const TQString &_file ); - - void slotFileDirtyDelayed(); - - void slotEntries( TDEIO::Job *job, const TDEIO::UDSEntryList &entries ); - void slotResult( TDEIO::Job *j ); - void slotRedirection( TDEIO::Job *job, const KURL &url ); - - void slotUpdateEntries( TDEIO::Job *job, const TDEIO::UDSEntryList &entries ); - void slotUpdateResult( TDEIO::Job *job ); - -private: - TDEIO::ListJob *jobForUrl( const TQString& url, TDEIO::ListJob *not_job = 0 ); - const KURL& joburl( TDEIO::ListJob *job ); - - void killJob( TDEIO::ListJob *job ); - - // check if _url is held by some lister and return true, - // otherwise schedule a delayed update and return false - bool checkUpdate( const TQString& _url ); - // when there were items deleted from the filesystem all the listers holding - // the parent directory need to be notified, the unmarked items have to be deleted - // and removed from the cache including all the childs. - void deleteUnmarkedItems( TQPtrList<KDirLister> *, KFileItemList * ); - void processPendingUpdates(); - // common for slotRedirection and FileRenamed - void renameDir( const KURL &oldUrl, const KURL &url ); - // common for deleteUnmarkedItems and FilesRemoved - void deleteDir( const KURL& dirUrl ); - // remove directory from cache (itemsCached), including all child dirs - void removeDirFromCache( const KURL& dir ); - // helper for renameDir - void emitRedirections( const KURL &oldUrl, const KURL &url ); - - void aboutToRefreshItem( KFileItem *fileitem ); - void emitRefreshItem( KFileItem *fileitem ); - -#ifndef NDEBUG - void printDebug(); -#endif - - struct DirItem - { - DirItem( const KURL &dir ) - : url(dir), rootItem(0), lstItems(new KFileItemList) - { - autoUpdates = 0; - complete = false; - lstItems->setAutoDelete( true ); - } - - ~DirItem() - { - if ( autoUpdates ) - { - if ( KDirWatch::exists() && url.isLocalFile() ) - kdirwatch->removeDir( url.path() ); - sendSignal( false, url ); - } - delete rootItem; - delete lstItems; - } - - void sendSignal( bool entering, const KURL& url ) - { - DCOPClient *client = DCOPClient::mainClient(); - if ( !client ) - return; - TQByteArray data; - TQDataStream arg( data, IO_WriteOnly ); - arg << url; - client->emitDCOPSignal( "KDirNotify", entering ? "enteredDirectory(KURL)" : "leftDirectory(KURL)", data ); - } - - void redirect( const KURL& newUrl ) - { - if ( autoUpdates ) - { - if ( url.isLocalFile() ) - kdirwatch->removeDir( url.path() ); - sendSignal( false, url ); - - if ( newUrl.isLocalFile() ) - kdirwatch->addDir( newUrl.path() ); - sendSignal( true, newUrl ); - } - - url = newUrl; - - if ( rootItem ) - rootItem->setURL( newUrl ); - } - - void incAutoUpdate() - { - if ( autoUpdates++ == 0 ) - { - if ( url.isLocalFile() ) - kdirwatch->addDir( url.path() ); - sendSignal( true, url ); - } - } - - void decAutoUpdate() - { - if ( --autoUpdates == 0 ) - { - if ( url.isLocalFile() ) - kdirwatch->removeDir( url.path() ); - sendSignal( false, url ); - } - - else if ( autoUpdates < 0 ) - autoUpdates = 0; - } - - // number of KDirListers using autoUpdate for this dir - short autoUpdates; - - // this directory is up-to-date - bool complete; - - // the complete url of this directory - KURL url; - - // KFileItem representing the root of this directory. - // Remember that this is optional. FTP sites don't return '.' in - // the list, so they give no root item - KFileItem *rootItem; - KFileItemList *lstItems; - }; - - static const unsigned short MAX_JOBS_PER_LISTER; - TQMap<TDEIO::ListJob *, TDEIO::UDSEntryList> jobs; - - // an item is a complete directory - TQDict<DirItem> itemsInUse; - TQCache<DirItem> itemsCached; - - // A lister can be EITHER in urlsCurrentlyListed OR urlsCurrentlyHeld but NOT - // in both at the same time. - // On the other hand there can be some listers in urlsCurrentlyHeld - // and some in urlsCurrentlyListed for the same url! - // Or differently said, there can be an entry for url in urlsCurrentlyListed - // and urlsCurrentlyHeld. This happens if more listers are requesting url at - // the same time and one lister was stopped during the listing of files. - - // saves all urls that are currently being listed and maps them - // to their KDirListers - TQDict< TQPtrList<KDirLister> > urlsCurrentlyListed; - - // saves all KDirListers that are just holding url - TQDict< TQPtrList<KDirLister> > urlsCurrentlyHeld; - - // running timers for the delayed update - TQDict<TQTimer> pendingUpdates; - - static KDirListerCache *s_pSelf; -}; - -const unsigned short KDirListerCache::MAX_JOBS_PER_LISTER = 5; - -#define s_pCache KDirListerCache::self() - -#endif diff --git a/kio/kio/kdirnotify.cpp b/kio/kio/kdirnotify.cpp deleted file mode 100644 index fb98196f5..000000000 --- a/kio/kio/kdirnotify.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kdirnotify.h" - -// Needed since DCOP enforces object id uniqueness. -int KDirNotify::s_serial = 0; - -KDirNotify::KDirNotify() - : DCOPObject( TQCString().sprintf("KDirNotify-%d", ++s_serial) ) -{ - connectDCOPSignal(0, "KDirNotify", "FilesAdded(KURL)", "FilesAdded(KURL)", false); - connectDCOPSignal(0, "KDirNotify", "FilesRemoved(KURL::List)", "FilesRemoved(KURL::List)", false); - connectDCOPSignal(0, "KDirNotify", "FilesChanged(KURL::List)", "FilesChanged(KURL::List)", false); - connectDCOPSignal(0, "KDirNotify", "FileRenamed(KURL,KURL)", "FileRenamed(KURL,KURL)", false); -} - -void KDirNotify::FileRenamed( const KURL &, const KURL & ) -{ -} - -void KDirNotify::virtual_hook( int id, void* data ) -{ DCOPObject::virtual_hook( id, data ); } - diff --git a/kio/kio/kdirnotify.h b/kio/kio/kdirnotify.h deleted file mode 100644 index 14d864609..000000000 --- a/kio/kio/kdirnotify.h +++ /dev/null @@ -1,84 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kdirnotify_h__ -#define __kdirnotify_h__ - -#include <dcopobject.h> -#include <kurl.h> - -/** - * An abstract class that receives notifications of added and removed files - * in any directory, local or remote. - * The information comes from the konqueror/kdesktop instance where the - * operation was done, and can interest KDirListers, bookmark handlers, etc. - */ -class TDEIO_EXPORT KDirNotify : public DCOPObject -{ - K_DCOP -protected: - KDirNotify(); - virtual ~KDirNotify() {} - -public: -k_dcop: - /** - * Notify that files have been added in @p directory - * Note: this is ASYNC so that it can be used with a broadcast. - * @param directory the directory that contains the new files - */ - virtual ASYNC FilesAdded( const KURL & directory ) = 0; - - /** - * Notify that files have been deleted. - * Note: this is ASYNC so that it can be used with a broadcast - * @param fileList the files that have been deleted - */ - virtual ASYNC FilesRemoved( const KURL::List & fileList ) = 0; - - /** - * Notify that files have been changed. - * At the moment, this is only used for new icon, but it could be - * used for size etc. as well. - * Note: this is ASYNC so that it can be used with a broadcast. - * @param fileList the list of changed files - */ - virtual ASYNC FilesChanged( const KURL::List & fileList ) = 0; - - /** - * Notify that a file has been renamed. - * Note: this is ASYNC so that it can be used with a broadcast - * @param src a list containing original names of the renamed files - * @param dst a list of original names of the renamed files - */ - virtual ASYNC FileRenamed( const KURL &src, const KURL &dst ); - - // WARNING: When adding new methods, make sure to update - // kdirnotify_stub.cpp and kdirnotify_stub.h manually. - // They are not automatically generated since they contain - // handcoded changes. - -private: - // @internal - static int s_serial; -protected: - virtual void virtual_hook( int id, void* data ); -}; - -#endif diff --git a/kio/kio/kdirnotify_stub.cpp b/kio/kio/kdirnotify_stub.cpp deleted file mode 100644 index 66988d6c9..000000000 --- a/kio/kio/kdirnotify_stub.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** DCOP Stub Implementation based on output of dcopidl2cpp from kdirnotify.kidl -** but with hand coded changes!! -** -*****************************************************************************/ -/* This file is part of the KDE project - Copyright (C) 2000 David Faure <faure@kde.org> - Copyright (C) 2003 Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kdirnotify_stub.h" -#include <dcopclient.h> - -#include <kdatastream.h> - - -KDirNotify_stub::KDirNotify_stub( const TQCString& app, const TQCString& obj ) - : DCOPStub( app, obj ) -{ -} - -KDirNotify_stub::KDirNotify_stub( DCOPClient* client, const TQCString& app, const TQCString& obj ) - : DCOPStub( client, app, obj ) -{ -} - -KDirNotify_stub::KDirNotify_stub( const DCOPRef& ref ) - : DCOPStub( ref ) -{ -} - -void KDirNotify_stub::FilesAdded( const KURL& arg0 ) -{ - if ( !dcopClient() ) { - setStatus( CallFailed ); - return; - } - TQByteArray data; - TQDataStream arg( data, IO_WriteOnly ); - arg << arg0; - dcopClient()->emitDCOPSignal( "KDirNotify", "FilesAdded(KURL)", data ); - setStatus( CallSucceeded ); -} - -void KDirNotify_stub::FilesRemoved( const KURL::List& arg0 ) -{ - if ( !dcopClient() ) { - setStatus( CallFailed ); - return; - } - TQByteArray data; - TQDataStream arg( data, IO_WriteOnly ); - arg << arg0; - dcopClient()->emitDCOPSignal( "KDirNotify", "FilesRemoved(KURL::List)", data ); - setStatus( CallSucceeded ); -} - -void KDirNotify_stub::FilesChanged( const KURL::List& arg0 ) -{ - if ( !dcopClient() ) { - setStatus( CallFailed ); - return; - } - TQByteArray data; - TQDataStream arg( data, IO_WriteOnly ); - arg << arg0; - dcopClient()->emitDCOPSignal( "KDirNotify", "FilesChanged(KURL::List)", data ); - setStatus( CallSucceeded ); -} - -void KDirNotify_stub::FileRenamed( const KURL& arg0, const KURL& arg1 ) -{ - if ( !dcopClient() ) { - setStatus( CallFailed ); - return; - } - TQByteArray data; - TQDataStream arg( data, IO_WriteOnly ); - arg << arg0; - arg << arg1; - dcopClient()->emitDCOPSignal( "KDirNotify", "FileRenamed(KURL,KURL)", data ); - setStatus( CallSucceeded ); -} - - diff --git a/kio/kio/kdirnotify_stub.h b/kio/kio/kdirnotify_stub.h deleted file mode 100644 index 56ab168c4..000000000 --- a/kio/kio/kdirnotify_stub.h +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** DCOP Stub Definition created by dcopidl2cpp from kdirnotify.kidl -** -** WARNING! All changes made in this file will be lost! -** -*****************************************************************************/ - -#ifndef __KDIRNOTIFY_STUB__ -#define __KDIRNOTIFY_STUB__ - -#include <dcopstub.h> -#include <dcopobject.h> -#include <kurl.h> - - -class TDEIO_EXPORT KDirNotify_stub : virtual public DCOPStub -{ -public: - KDirNotify_stub( const TQCString& app, const TQCString& id ); - KDirNotify_stub( DCOPClient* client, const TQCString& app, const TQCString& id ); - explicit KDirNotify_stub( const DCOPRef& ref ); - virtual ASYNC FilesAdded( const KURL& directory ); - virtual ASYNC FilesRemoved( const KURL::List& fileList ); - virtual ASYNC FilesChanged( const KURL::List& fileList ); - virtual ASYNC FileRenamed( const KURL& src, const KURL& dst ); -protected: - KDirNotify_stub() : DCOPStub( never_use ) {}; -}; - - -#endif diff --git a/kio/kio/kdirwatch.cpp b/kio/kio/kdirwatch.cpp deleted file mode 100644 index 1ea5805f3..000000000 --- a/kio/kio/kdirwatch.cpp +++ /dev/null @@ -1,1774 +0,0 @@ -// -*- c-basic-offset: 2 -*- -/* This file is part of the KDE libraries - Copyright (C) 1998 Sven Radej <sven@lisa.exp.univie.ac.at> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - - -// CHANGES: -// Oct 4, 2005 - Inotify support (Dirk Mueller) -// Februar 2002 - Add file watching and remote mount check for STAT -// Mar 30, 2001 - Native support for Linux dir change notification. -// Jan 28, 2000 - Usage of FAM service on IRIX (Josef.Weidendorfer@in.tum.de) -// May 24. 1998 - List of times introduced, and some bugs are fixed. (sven)1 -// May 23. 1998 - Removed static pointer - you can have more instances. -// It was Needed for KRegistry. KDirWatch now emits signals and doesn't -// call (or need) KFM. No more URL's - just plain paths. (sven) -// Mar 29. 1998 - added docs, stop/restart for particular Dirs and -// deep copies for list of dirs. (sven) -// Mar 28. 1998 - Created. (sven) - - -#include <config.h> -#include <errno.h> - -#ifdef HAVE_DNOTIFY -#include <unistd.h> -#include <time.h> -#include <fcntl.h> -#include <signal.h> -#include <errno.h> -#endif - - -#include <sys/stat.h> -#include <assert.h> -#include <tqdir.h> -#include <tqfile.h> -#include <tqintdict.h> -#include <tqptrlist.h> -#include <tqsocketnotifier.h> -#include <tqstringlist.h> -#include <tqtimer.h> - -#include <kapplication.h> -#include <kdebug.h> -#include <kconfig.h> -#include <kglobal.h> -#include <kstaticdeleter.h> -#include <kde_file.h> - -// debug -#include <sys/ioctl.h> - -#ifdef HAVE_INOTIFY -#include <unistd.h> -#include <fcntl.h> -#include <sys/syscall.h> -#include <linux/types.h> -// Linux kernel headers are documented to not compile -#define _S390_BITOPS_H -#include <sys/inotify.h> - -#ifndef __NR_inotify_init -#if defined(__i386__) -#define __NR_inotify_init 291 -#define __NR_inotify_add_watch 292 -#define __NR_inotify_rm_watch 293 -#endif -#if defined(__PPC__) -#define __NR_inotify_init 275 -#define __NR_inotify_add_watch 276 -#define __NR_inotify_rm_watch 277 -#endif -#if defined(__x86_64__) -#define __NR_inotify_init 253 -#define __NR_inotify_add_watch 254 -#define __NR_inotify_rm_watch 255 -#endif -#endif - -#ifndef IN_ONLYDIR -#define IN_ONLYDIR 0x01000000 -#endif - -#ifndef IN_DONT_FOLLOW -#define IN_DONT_FOLLOW 0x02000000 -#endif - -#ifndef IN_MOVE_SELF -#define IN_MOVE_SELF 0x00000800 -#endif - -#endif - -#include <sys/utsname.h> - -#include "kdirwatch.h" -#include "kdirwatch_p.h" -#include "global.h" // TDEIO::probably_slow_mounted - -#define NO_NOTIFY (time_t) 0 - -static KDirWatchPrivate* dwp_self = 0; - -#ifdef HAVE_DNOTIFY - -static int dnotify_signal = 0; - -/* DNOTIFY signal handler - * - * As this is called asynchronously, only a flag is set and - * a rescan is requested. - * This is done by writing into a pipe to trigger a TQSocketNotifier - * watching on this pipe: a timer is started and after a timeout, - * the rescan is done. - */ -void KDirWatchPrivate::dnotify_handler(int, siginfo_t *si, void *) -{ - if (!dwp_self) return; - - // write might change errno, we have to save it and restore it - // (Richard Stevens, Advanced programming in the Unix Environment) - int saved_errno = errno; - - Entry* e = dwp_self->fd_Entry.find(si->si_fd); - -// kdDebug(7001) << "DNOTIFY Handler: fd " << si->si_fd << " path " -// << TQString(e ? e->path:"unknown") << endl; - - if(e && e->dn_fd == si->si_fd) - e->dirty = true; - - char c = 0; - write(dwp_self->mPipe[1], &c, 1); - errno = saved_errno; -} - -static struct sigaction old_sigio_act; -/* DNOTIFY SIGIO signal handler - * - * When the kernel queue for the dnotify_signal overflows, a SIGIO is send. - */ -void KDirWatchPrivate::dnotify_sigio_handler(int sig, siginfo_t *si, void *p) -{ - if (dwp_self) - { - // write might change errno, we have to save it and restore it - // (Richard Stevens, Advanced programming in the Unix Environment) - int saved_errno = errno; - - dwp_self->rescan_all = true; - char c = 0; - write(dwp_self->mPipe[1], &c, 1); - - errno = saved_errno; - } - - // Call previous signal handler - if (old_sigio_act.sa_flags & SA_SIGINFO) - { - if (old_sigio_act.sa_sigaction) - (*old_sigio_act.sa_sigaction)(sig, si, p); - } - else - { - if ((old_sigio_act.sa_handler != SIG_DFL) && - (old_sigio_act.sa_handler != SIG_IGN)) - (*old_sigio_act.sa_handler)(sig); - } -} -#endif - - -// -// Class KDirWatchPrivate (singleton) -// - -/* All entries (files/directories) to be watched in the - * application (coming from multiple KDirWatch instances) - * are registered in a single KDirWatchPrivate instance. - * - * At the moment, the following methods for file watching - * are supported: - * - Polling: All files to be watched are polled regularly - * using stat (more precise: TQFileInfo.lastModified()). - * The polling frequency is determined from global kconfig - * settings, defaulting to 500 ms for local directories - * and 5000 ms for remote mounts - * - FAM (File Alternation Monitor): first used on IRIX, SGI - * has ported this method to LINUX. It uses a kernel part - * (IMON, sending change events to /dev/imon) and a user - * level damon (fam), to which applications connect for - * notification of file changes. For NFS, the fam damon - * on the NFS server machine is used; if IMON is not built - * into the kernel, fam uses polling for local files. - * - DNOTIFY: In late LINUX 2.3.x, directory notification was - * introduced. By opening a directory, you can request for - * UNIX signals to be sent to the process when a directory - * is changed. - * - INOTIFY: In LINUX 2.6.13, inode change notification was - * introduced. You're now able to watch arbitrary inode's - * for changes, and even get notification when they're - * unmounted. - */ - -KDirWatchPrivate::KDirWatchPrivate() - : rescan_timer(0, "KDirWatchPrivate::rescan_timer") -{ - timer = new TQTimer(this, "KDirWatchPrivate::timer"); - connect (timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotRescan())); - freq = 3600000; // 1 hour as upper bound - statEntries = 0; - delayRemove = false; - m_ref = 0; - - TDEConfigGroup config(TDEGlobal::config(), TQCString("DirWatch")); - m_nfsPollInterval = config.readNumEntry("NFSPollInterval", 5000); - m_PollInterval = config.readNumEntry("PollInterval", 500); - - TQString available("Stat"); - - // used for FAM and DNOTIFY - rescan_all = false; - connect(&rescan_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotRescan())); - -#ifdef HAVE_FAM - // It's possible that FAM server can't be started - if (FAMOpen(&fc) ==0) { - available += ", FAM"; - use_fam=true; - sn = new TQSocketNotifier( FAMCONNECTION_GETFD(&fc), - TQSocketNotifier::Read, this); - connect( sn, TQT_SIGNAL(activated(int)), - this, TQT_SLOT(famEventReceived()) ); - } - else { - kdDebug(7001) << "Can't use FAM (fam daemon not running?)" << endl; - use_fam=false; - } -#endif - -#ifdef HAVE_INOTIFY - supports_inotify = true; - - m_inotify_fd = inotify_init(); - - if ( m_inotify_fd <= 0 ) { - kdDebug(7001) << "Can't use Inotify, kernel doesn't support it" << endl; - supports_inotify = false; - } - - { - struct utsname uts; - int major, minor, patch; - if (uname(&uts) < 0) - supports_inotify = false; // *shrug* - else if (sscanf(uts.release, "%d.%d.%d", &major, &minor, &patch) != 3) - supports_inotify = false; // *shrug* - else if( major * 1000000 + minor * 1000 + patch < 2006014 ) { // <2.6.14 - kdDebug(7001) << "Can't use INotify, Linux kernel too old" << endl; - supports_inotify = false; - } - } - - if ( supports_inotify ) { - available += ", Inotify"; - fcntl(m_inotify_fd, F_SETFD, FD_CLOEXEC); - - mSn = new TQSocketNotifier( m_inotify_fd, TQSocketNotifier::Read, this ); - connect( mSn, TQT_SIGNAL(activated( int )), this, TQT_SLOT( slotActivated() ) ); - } -#endif - -#ifdef HAVE_DNOTIFY - - // if we have inotify, disable dnotify. -#ifdef HAVE_INOTIFY - supports_dnotify = !supports_inotify; -#else - // otherwise, not guilty until proven guilty. - supports_dnotify = true; -#endif - - struct utsname uts; - int major, minor, patch; - if (uname(&uts) < 0) - supports_dnotify = false; // *shrug* - else if (sscanf(uts.release, "%d.%d.%d", &major, &minor, &patch) != 3) - supports_dnotify = false; // *shrug* - else if( major * 1000000 + minor * 1000 + patch < 2004019 ) { // <2.4.19 - kdDebug(7001) << "Can't use DNotify, Linux kernel too old" << endl; - supports_dnotify = false; - } - - if( supports_dnotify ) { - available += ", DNotify"; - - pipe(mPipe); - fcntl(mPipe[0], F_SETFD, FD_CLOEXEC); - fcntl(mPipe[1], F_SETFD, FD_CLOEXEC); - fcntl(mPipe[0], F_SETFL, O_NONBLOCK | fcntl(mPipe[0], F_GETFL)); - fcntl(mPipe[1], F_SETFL, O_NONBLOCK | fcntl(mPipe[1], F_GETFL)); - mSn = new TQSocketNotifier( mPipe[0], TQSocketNotifier::Read, this); - connect(mSn, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotActivated())); - // Install the signal handler only once - if ( dnotify_signal == 0 ) - { - dnotify_signal = SIGRTMIN + 8; - - struct sigaction act; - act.sa_sigaction = KDirWatchPrivate::dnotify_handler; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO; -#ifdef SA_RESTART - act.sa_flags |= SA_RESTART; -#endif - sigaction(dnotify_signal, &act, NULL); - - act.sa_sigaction = KDirWatchPrivate::dnotify_sigio_handler; - sigaction(SIGIO, &act, &old_sigio_act); - } - } - else - { - mPipe[0] = -1; - mPipe[1] = -1; - } -#endif - - kdDebug(7001) << "Available methods: " << available << endl; -} - -/* This is called on app exit (KStaticDeleter) */ -KDirWatchPrivate::~KDirWatchPrivate() -{ - timer->stop(); - - /* remove all entries being watched */ - removeEntries(0); - -#ifdef HAVE_FAM - if (use_fam) { - FAMClose(&fc); - kdDebug(7001) << "KDirWatch deleted (FAM closed)" << endl; - } -#endif -#ifdef HAVE_INOTIFY - if ( supports_inotify ) - ::close( m_inotify_fd ); -#endif -#ifdef HAVE_DNOTIFY - close(mPipe[0]); - close(mPipe[1]); -#endif -} - -#include <stdlib.h> - -void KDirWatchPrivate::slotActivated() -{ -#ifdef HAVE_DNOTIFY - if ( supports_dnotify ) - { - char dummy_buf[4096]; - read(mPipe[0], &dummy_buf, 4096); - - if (!rescan_timer.isActive()) - rescan_timer.start(m_PollInterval, true /* singleshot */); - - return; - } -#endif - -#ifdef HAVE_INOTIFY - if ( !supports_inotify ) - return; - - int pending = -1; - int offset = 0; - char buf[4096]; - assert( m_inotify_fd > -1 ); - ioctl( m_inotify_fd, FIONREAD, &pending ); - - while ( pending > 0 ) { - - if ( pending > (int)sizeof( buf ) ) - pending = sizeof( buf ); - - pending = read( m_inotify_fd, buf, pending); - - while ( pending > 0 ) { - struct inotify_event *event = (struct inotify_event *) &buf[offset]; - pending -= sizeof( struct inotify_event ) + event->len; - offset += sizeof( struct inotify_event ) + event->len; - - TQString path; - if ( event->len ) - path = TQFile::decodeName( TQCString( event->name, event->len ) ); - - if ( path.length() && isNoisyFile( path.latin1() ) ) - continue; - - kdDebug(7001) << "ev wd: " << event->wd << " mask " << event->mask << " path: " << path << endl; - - // now we're in deep trouble of finding the - // associated entries - // for now, we suck and iterate - for ( EntryMap::Iterator it = m_mapEntries.begin(); - it != m_mapEntries.end(); ++it ) { - Entry* e = &( *it ); - if ( e->wd == event->wd ) { - e->dirty = true; - - if ( 1 || e->isDir) { - if( event->mask & IN_DELETE_SELF) { - kdDebug(7001) << "-->got deleteself signal for " << e->path << endl; - e->m_status = NonExistent; - if (e->isDir) - addEntry(0, TQDir::cleanDirPath(e->path+"/.."), e, true); - else - addEntry(0, TQFileInfo(e->path).dirPath(true), e, true); - } - if ( event->mask & IN_IGNORED ) { - e->wd = 0; - } - if ( event->mask & (IN_CREATE|IN_MOVED_TO) ) { - Entry *sub_entry = e->m_entries.first(); - for(;sub_entry; sub_entry = e->m_entries.next()) - if (sub_entry->path == e->path + "/" + path) break; - - if (sub_entry /*&& sub_entry->isDir*/) { - removeEntry(0,e->path, sub_entry); - KDE_struct_stat stat_buf; - TQCString tpath = TQFile::encodeName(path); - KDE_stat(tpath, &stat_buf); - - //sub_entry->isDir = S_ISDIR(stat_buf.st_mode); - //sub_entry->m_ctime = stat_buf.st_ctime; - //sub_entry->m_status = Normal; - //sub_entry->m_nlink = stat_buf.st_nlink; - - if(!useINotify(sub_entry)) - useStat(sub_entry); - sub_entry->dirty = true; - } - } - } - - if (!rescan_timer.isActive()) - rescan_timer.start(m_PollInterval, true /* singleshot */); - - break; // there really should be only one matching wd - } - } - - } - } -#endif -} - -/* In DNOTIFY/FAM mode, only entries which are marked dirty are scanned. - * We first need to mark all yet nonexistent, but possible created - * entries as dirty... - */ -void KDirWatchPrivate::Entry::propagate_dirty() -{ - for (TQPtrListIterator<Entry> sub_entry (m_entries); - sub_entry.current(); ++sub_entry) - { - if (!sub_entry.current()->dirty) - { - sub_entry.current()->dirty = true; - sub_entry.current()->propagate_dirty(); - } - } -} - - -/* A KDirWatch instance is interested in getting events for - * this file/Dir entry. - */ -void KDirWatchPrivate::Entry::addClient(KDirWatch* instance) -{ - Client* client = m_clients.first(); - for(;client; client = m_clients.next()) - if (client->instance == instance) break; - - if (client) { - client->count++; - return; - } - - client = new Client; - client->instance = instance; - client->count = 1; - client->watchingStopped = instance->isStopped(); - client->pending = NoChange; - - m_clients.append(client); -} - -void KDirWatchPrivate::Entry::removeClient(KDirWatch* instance) -{ - Client* client = m_clients.first(); - for(;client; client = m_clients.next()) - if (client->instance == instance) break; - - if (client) { - client->count--; - if (client->count == 0) { - m_clients.removeRef(client); - delete client; - } - } -} - -/* get number of clients */ -int KDirWatchPrivate::Entry::clients() -{ - int clients = 0; - Client* client = m_clients.first(); - for(;client; client = m_clients.next()) - clients += client->count; - - return clients; -} - - -KDirWatchPrivate::Entry* KDirWatchPrivate::entry(const TQString& _path) -{ -// we only support absolute paths - if (TQDir::isRelativePath(_path)) { - return 0; - } - - TQString path = _path; - - if ( path.length() > 1 && path.right(1) == "/" ) - path.truncate( path.length() - 1 ); - - EntryMap::Iterator it = m_mapEntries.find( path ); - if ( it == m_mapEntries.end() ) - return 0; - else - return &(*it); -} - -// set polling frequency for a entry and adjust global freq if needed -void KDirWatchPrivate::useFreq(Entry* e, int newFreq) -{ - e->freq = newFreq; - - // a reasonable frequency for the global polling timer - if (e->freq < freq) { - freq = e->freq; - if (timer->isActive()) timer->changeInterval(freq); - kdDebug(7001) << "Global Poll Freq is now " << freq << " msec" << endl; - } -} - - -#ifdef HAVE_FAM -// setup FAM notification, returns false if not possible -bool KDirWatchPrivate::useFAM(Entry* e) -{ - if (!use_fam) return false; - - // handle FAM events to avoid deadlock - // (FAM sends back all files in a directory when monitoring) - famEventReceived(); - - e->m_mode = FAMMode; - e->dirty = false; - - if (e->isDir) { - if (e->m_status == NonExistent) { - // If the directory does not exist we watch the parent directory - addEntry(0, TQDir::cleanDirPath(e->path+"/.."), e, true); - } - else { - int res =FAMMonitorDirectory(&fc, TQFile::encodeName(e->path), - &(e->fr), e); - if (res<0) { - e->m_mode = UnknownMode; - use_fam=false; - return false; - } - kdDebug(7001) << " Setup FAM (Req " - << FAMREQUEST_GETREQNUM(&(e->fr)) - << ") for " << e->path << endl; - } - } - else { - if (e->m_status == NonExistent) { - // If the file does not exist we watch the directory - addEntry(0, TQFileInfo(e->path).dirPath(true), e, true); - } - else { - int res = FAMMonitorFile(&fc, TQFile::encodeName(e->path), - &(e->fr), e); - if (res<0) { - e->m_mode = UnknownMode; - use_fam=false; - return false; - } - - kdDebug(7001) << " Setup FAM (Req " - << FAMREQUEST_GETREQNUM(&(e->fr)) - << ") for " << e->path << endl; - } - } - - // handle FAM events to avoid deadlock - // (FAM sends back all files in a directory when monitoring) - famEventReceived(); - - return true; -} -#endif - - -#ifdef HAVE_DNOTIFY -// setup DNotify notification, returns false if not possible -bool KDirWatchPrivate::useDNotify(Entry* e) -{ - e->dn_fd = 0; - e->dirty = false; - if (!supports_dnotify) return false; - - e->m_mode = DNotifyMode; - - if (e->isDir) { - if (e->m_status == Normal) { - int fd = KDE_open(TQFile::encodeName(e->path).data(), O_RDONLY); - // Migrate fd to somewhere above 128. Some libraries have - // constructs like: - // fd = socket(...) - // if (fd > ARBITRARY_LIMIT) - // return error; - // - // Since programs might end up using a lot of KDirWatch objects - // for a rather long time the above braindamage could get - // triggered. - // - // By moving the kdirwatch fd's to > 128, calls like socket() will keep - // returning fd's < ARBITRARY_LIMIT for a bit longer. - int fd2 = fcntl(fd, F_DUPFD, 128); - if (fd2 >= 0) - { - close(fd); - fd = fd2; - } - if (fd<0) { - e->m_mode = UnknownMode; - return false; - } - - int mask = DN_DELETE|DN_CREATE|DN_RENAME|DN_MULTISHOT; - // if dependant is a file watch, we check for MODIFY & ATTRIB too - for(Entry* dep=e->m_entries.first();dep;dep=e->m_entries.next()) - if (!dep->isDir) { mask |= DN_MODIFY|DN_ATTRIB; break; } - - if(fcntl(fd, F_SETSIG, dnotify_signal) < 0 || - fcntl(fd, F_NOTIFY, mask) < 0) { - - kdDebug(7001) << "Not using Linux Directory Notifications." - << endl; - supports_dnotify = false; - ::close(fd); - e->m_mode = UnknownMode; - return false; - } - - fd_Entry.replace(fd, e); - e->dn_fd = fd; - - kdDebug(7001) << " Setup DNotify (fd " << fd - << ") for " << e->path << endl; - } - else { // NotExisting - addEntry(0, TQDir::cleanDirPath(e->path+"/.."), e, true); - } - } - else { // File - // we always watch the directory (DNOTIFY can't watch files alone) - // this notifies us about changes of files therein - addEntry(0, TQFileInfo(e->path).dirPath(true), e, true); - } - - return true; -} -#endif - -#ifdef HAVE_INOTIFY -// setup INotify notification, returns false if not possible -bool KDirWatchPrivate::useINotify( Entry* e ) -{ - e->wd = 0; - e->dirty = false; - if (!supports_inotify) return false; - - e->m_mode = INotifyMode; - - int mask = IN_DELETE|IN_DELETE_SELF|IN_CREATE|IN_MOVE|IN_MOVE_SELF|IN_DONT_FOLLOW; - if(!e->isDir) - mask |= IN_MODIFY|IN_ATTRIB; - else - mask |= IN_ONLYDIR; - - // if dependant is a file watch, we check for MODIFY & ATTRIB too - for(Entry* dep=e->m_entries.first();dep;dep=e->m_entries.next()) { - if (!dep->isDir) { mask |= IN_MODIFY|IN_ATTRIB; break; } - } - - if ( ( e->wd = inotify_add_watch( m_inotify_fd, - TQFile::encodeName( e->path ), mask) ) > 0 ) - return true; - - if ( e->m_status == NonExistent ) { - if (e->isDir) - addEntry(0, TQDir::cleanDirPath(e->path+"/.."), e, true); - else - addEntry(0, TQFileInfo(e->path).dirPath(true), e, true); - return true; - } - - return false; -} -#endif - -bool KDirWatchPrivate::useStat(Entry* e) -{ - if ( e->path.startsWith("/media/") || (e->path == "/media") - || (TDEIO::probably_slow_mounted(e->path)) ) - useFreq(e, m_nfsPollInterval); - else - useFreq(e, m_PollInterval); - - if (e->m_mode != StatMode) { - e->m_mode = StatMode; - statEntries++; - - if ( statEntries == 1 ) { - // if this was first STAT entry (=timer was stopped) - timer->start(freq); // then start the timer - kdDebug(7001) << " Started Polling Timer, freq " << freq << endl; - } - } - - kdDebug(7001) << " Setup Stat (freq " << e->freq - << ") for " << e->path << endl; - - return true; -} - - -/* If <instance> !=0, this KDirWatch instance wants to watch at <_path>, - * providing in <isDir> the type of the entry to be watched. - * Sometimes, entries are dependant on each other: if <sub_entry> !=0, - * this entry needs another entry to watch himself (when notExistent). - */ -void KDirWatchPrivate::addEntry(KDirWatch* instance, const TQString& _path, - Entry* sub_entry, bool isDir) -{ - TQString path = _path; - if (path.startsWith("/dev/") || (path == "/dev")) - return; // Don't even go there. - - if ( path.length() > 1 && path.right(1) == "/" ) - path.truncate( path.length() - 1 ); - - EntryMap::Iterator it = m_mapEntries.find( path ); - if ( it != m_mapEntries.end() ) - { - if (sub_entry) { - (*it).m_entries.append(sub_entry); - kdDebug(7001) << "Added already watched Entry " << path - << " (for " << sub_entry->path << ")" << endl; - -#ifdef HAVE_DNOTIFY - { - Entry* e = &(*it); - if( (e->m_mode == DNotifyMode) && (e->dn_fd > 0) ) { - int mask = DN_DELETE|DN_CREATE|DN_RENAME|DN_MULTISHOT; - // if dependant is a file watch, we check for MODIFY & ATTRIB too - for(Entry* dep=e->m_entries.first();dep;dep=e->m_entries.next()) - if (!dep->isDir) { mask |= DN_MODIFY|DN_ATTRIB; break; } - if( fcntl(e->dn_fd, F_NOTIFY, mask) < 0) { // shouldn't happen - ::close(e->dn_fd); - e->m_mode = UnknownMode; - fd_Entry.remove(e->dn_fd); - e->dn_fd = 0; - useStat( e ); - } - } - } -#endif - -#ifdef HAVE_INOTIFY - { - Entry* e = &(*it); - if( (e->m_mode == INotifyMode) && (e->wd > 0) ) { - int mask = IN_DELETE|IN_DELETE_SELF|IN_CREATE|IN_MOVE|IN_MOVE_SELF|IN_DONT_FOLLOW; - if(!e->isDir) - mask |= IN_MODIFY|IN_ATTRIB; - else - mask |= IN_ONLYDIR; - - inotify_rm_watch (m_inotify_fd, e->wd); - e->wd = inotify_add_watch( m_inotify_fd, TQFile::encodeName( e->path ), mask); - } - } -#endif - - } - else { - (*it).addClient(instance); - kdDebug(7001) << "Added already watched Entry " << path - << " (now " << (*it).clients() << " clients)" - << TQString(TQString(" [%1]").arg(instance->name())) << endl; - } - return; - } - - // we have a new path to watch - - KDE_struct_stat stat_buf; - TQCString tpath = TQFile::encodeName(path); - bool exists = (KDE_stat(tpath, &stat_buf) == 0); - - Entry newEntry; - m_mapEntries.insert( path, newEntry ); - // the insert does a copy, so we have to use <e> now - Entry* e = &(m_mapEntries[path]); - - if (exists) { - e->isDir = S_ISDIR(stat_buf.st_mode); - - if (e->isDir && !isDir) - kdWarning() << "KDirWatch: " << path << " is a directory. Use addDir!" << endl; - else if (!e->isDir && isDir) - kdWarning() << "KDirWatch: " << path << " is a file. Use addFile!" << endl; - - e->m_ctime = stat_buf.st_ctime; - e->m_status = Normal; - e->m_nlink = stat_buf.st_nlink; - } - else { - e->isDir = isDir; - e->m_ctime = invalid_ctime; - e->m_status = NonExistent; - e->m_nlink = 0; - } - - e->path = path; - if (sub_entry) - e->m_entries.append(sub_entry); - else - e->addClient(instance); - - kdDebug(7001) << "Added " << (e->isDir ? "Dir ":"File ") << path - << (e->m_status == NonExistent ? " NotExisting" : "") - << (sub_entry ? TQString(TQString(" for %1").arg(sub_entry->path)) : TQString("")) - << (instance ? TQString(TQString(" [%1]").arg(instance->name())) : TQString("")) - << endl; - - - // now setup the notification method - e->m_mode = UnknownMode; - e->msecLeft = 0; - - if ( isNoisyFile( tpath ) ) - return; - -#ifdef HAVE_FAM - if (useFAM(e)) return; -#endif - -#ifdef HAVE_INOTIFY - if (useINotify(e)) return; -#endif - -#ifdef HAVE_DNOTIFY - if (useDNotify(e)) return; -#endif - - useStat(e); -} - - -void KDirWatchPrivate::removeEntry( KDirWatch* instance, - const TQString& _path, Entry* sub_entry ) -{ - kdDebug(7001) << "KDirWatchPrivate::removeEntry for '" << _path << "' sub_entry: " << sub_entry << endl; - Entry* e = entry(_path); - if (!e) { - kdDebug(7001) << "KDirWatchPrivate::removeEntry can't handle '" << _path << "'" << endl; - return; - } - - if (sub_entry) - e->m_entries.removeRef(sub_entry); - else - e->removeClient(instance); - - if (e->m_clients.count() || e->m_entries.count()) { - kdDebug(7001) << "removeEntry: unwatched " << e->path << " " << _path << endl; - return; - } - - if (delayRemove) { - // removeList is allowed to contain any entry at most once - if (removeList.findRef(e)==-1) - removeList.append(e); - // now e->isValid() is false - return; - } - -#ifdef HAVE_FAM - if (e->m_mode == FAMMode) { - if ( e->m_status == Normal) { - FAMCancelMonitor(&fc, &(e->fr) ); - kdDebug(7001) << "Cancelled FAM (Req " - << FAMREQUEST_GETREQNUM(&(e->fr)) - << ") for " << e->path << endl; - } - else { - if (e->isDir) - removeEntry(0, TQDir::cleanDirPath(e->path+"/.."), e); - else - removeEntry(0, TQFileInfo(e->path).dirPath(true), e); - } - } -#endif - -#ifdef HAVE_INOTIFY - kdDebug(7001) << "inotify remove " << ( e->m_mode == INotifyMode ) << " " << ( e->m_status == Normal ) << endl; - if (e->m_mode == INotifyMode) { - if ( e->m_status == Normal ) { - (void) inotify_rm_watch( m_inotify_fd, e->wd ); - kdDebug(7001) << "Cancelled INotify (fd " << - m_inotify_fd << ", " << e->wd << - ") for " << e->path << endl; - } - else { - if (e->isDir) - removeEntry(0, TQDir::cleanDirPath(e->path+"/.."), e); - else - removeEntry(0, TQFileInfo(e->path).dirPath(true), e); - } - } -#endif - -#ifdef HAVE_DNOTIFY - if (e->m_mode == DNotifyMode) { - if (!e->isDir) { - removeEntry(0, TQFileInfo(e->path).dirPath(true), e); - } - else { // isDir - // must close the FD. - if ( e->m_status == Normal) { - if (e->dn_fd) { - ::close(e->dn_fd); - fd_Entry.remove(e->dn_fd); - - kdDebug(7001) << "Cancelled DNotify (fd " << e->dn_fd - << ") for " << e->path << endl; - e->dn_fd = 0; - - } - } - else { - removeEntry(0, TQDir::cleanDirPath(e->path+"/.."), e); - } - } - } -#endif - - if (e->m_mode == StatMode) { - statEntries--; - if ( statEntries == 0 ) { - timer->stop(); // stop timer if lists are empty - kdDebug(7001) << " Stopped Polling Timer" << endl; - } - } - - kdDebug(7001) << "Removed " << (e->isDir ? "Dir ":"File ") << e->path - << (sub_entry ? TQString(TQString(" for %1").arg(sub_entry->path)) : TQString("")) - << (instance ? TQString(TQString(" [%1]").arg(instance->name())) : TQString("")) - << endl; - m_mapEntries.remove( e->path ); // <e> not valid any more -} - - -/* Called from KDirWatch destructor: - * remove <instance> as client from all entries - */ -void KDirWatchPrivate::removeEntries( KDirWatch* instance ) -{ - TQPtrList<Entry> list; - int minfreq = 3600000; - - // put all entries where instance is a client in list - EntryMap::Iterator it = m_mapEntries.begin(); - for( ; it != m_mapEntries.end(); ++it ) { - Client* c = (*it).m_clients.first(); - for(;c;c=(*it).m_clients.next()) - if (c->instance == instance) break; - if (c) { - c->count = 1; // forces deletion of instance as client - list.append(&(*it)); - } - else if ( (*it).m_mode == StatMode && (*it).freq < minfreq ) - minfreq = (*it).freq; - } - - for(Entry* e=list.first();e;e=list.next()) - removeEntry(instance, e->path, 0); - - if (minfreq > freq) { - // we can decrease the global polling frequency - freq = minfreq; - if (timer->isActive()) timer->changeInterval(freq); - kdDebug(7001) << "Poll Freq now " << freq << " msec" << endl; - } -} - -// instance ==0: stop scanning for all instances -bool KDirWatchPrivate::stopEntryScan( KDirWatch* instance, Entry* e) -{ - int stillWatching = 0; - Client* c = e->m_clients.first(); - for(;c;c=e->m_clients.next()) { - if (!instance || instance == c->instance) - c->watchingStopped = true; - else if (!c->watchingStopped) - stillWatching += c->count; - } - - kdDebug(7001) << instance->name() << " stopped scanning " << e->path - << " (now " << stillWatching << " watchers)" << endl; - - if (stillWatching == 0) { - // if nobody is interested, we don't watch - e->m_ctime = invalid_ctime; // invalid - e->m_status = NonExistent; - // e->m_status = Normal; - } - return true; -} - -// instance ==0: start scanning for all instances -bool KDirWatchPrivate::restartEntryScan( KDirWatch* instance, Entry* e, - bool notify) -{ - int wasWatching = 0, newWatching = 0; - Client* c = e->m_clients.first(); - for(;c;c=e->m_clients.next()) { - if (!c->watchingStopped) - wasWatching += c->count; - else if (!instance || instance == c->instance) { - c->watchingStopped = false; - newWatching += c->count; - } - } - if (newWatching == 0) - return false; - - kdDebug(7001) << (instance ? instance->name() : "all") << " restarted scanning " << e->path - << " (now " << wasWatching+newWatching << " watchers)" << endl; - - // restart watching and emit pending events - - int ev = NoChange; - if (wasWatching == 0) { - if (!notify) { - KDE_struct_stat stat_buf; - bool exists = (KDE_stat(TQFile::encodeName(e->path), &stat_buf) == 0); - if (exists) { - e->m_ctime = stat_buf.st_ctime; - e->m_status = Normal; - e->m_nlink = stat_buf.st_nlink; - } - else { - e->m_ctime = invalid_ctime; - e->m_status = NonExistent; - e->m_nlink = 0; - } - } - e->msecLeft = 0; - ev = scanEntry(e); - } - emitEvent(e,ev); - - return true; -} - -// instance ==0: stop scanning for all instances -void KDirWatchPrivate::stopScan(KDirWatch* instance) -{ - EntryMap::Iterator it = m_mapEntries.begin(); - for( ; it != m_mapEntries.end(); ++it ) - stopEntryScan(instance, &(*it)); -} - - -void KDirWatchPrivate::startScan(KDirWatch* instance, - bool notify, bool skippedToo ) -{ - if (!notify) - resetList(instance,skippedToo); - - EntryMap::Iterator it = m_mapEntries.begin(); - for( ; it != m_mapEntries.end(); ++it ) - restartEntryScan(instance, &(*it), notify); - - // timer should still be running when in polling mode -} - - -// clear all pending events, also from stopped -void KDirWatchPrivate::resetList( KDirWatch* /*instance*/, - bool skippedToo ) -{ - EntryMap::Iterator it = m_mapEntries.begin(); - for( ; it != m_mapEntries.end(); ++it ) { - - Client* c = (*it).m_clients.first(); - for(;c;c=(*it).m_clients.next()) - if (!c->watchingStopped || skippedToo) - c->pending = NoChange; - } -} - -// Return event happened on <e> -// -int KDirWatchPrivate::scanEntry(Entry* e) -{ -#ifdef HAVE_FAM - if (e->m_mode == FAMMode) { - // we know nothing has changed, no need to stat - if(!e->dirty) return NoChange; - e->dirty = false; - } - if (e->isDir) return Changed; -#endif - - // Shouldn't happen: Ignore "unknown" notification method - if (e->m_mode == UnknownMode) return NoChange; - -#if defined ( HAVE_DNOTIFY ) || defined( HAVE_INOTIFY ) - if (e->m_mode == DNotifyMode || e->m_mode == INotifyMode ) { - // we know nothing has changed, no need to stat - if(!e->dirty) return NoChange; - kdDebug(7001) << "scanning " << e->path << " " << e->m_status << " " << e->m_ctime << endl; - e->dirty = false; - } -#endif - - if (e->m_mode == StatMode) { - // only scan if timeout on entry timer happens; - // e.g. when using 500msec global timer, a entry - // with freq=5000 is only watched every 10th time - - e->msecLeft -= freq; - if (e->msecLeft>0) return NoChange; - e->msecLeft += e->freq; - } - - KDE_struct_stat stat_buf; - bool exists = (KDE_stat(TQFile::encodeName(e->path), &stat_buf) == 0); - if (exists) { - - if (e->m_status == NonExistent) { - // ctime is the 'creation time' on windows, but with qMax - // we get the latest change of any kind, on any platform. - e->m_ctime = stat_buf.st_ctime; - e->m_status = Normal; - e->m_nlink = stat_buf.st_nlink; - return Created; - } - - if ( (e->m_ctime != invalid_ctime) && - ((stat_buf.st_ctime != e->m_ctime) || - (stat_buf.st_nlink != (nlink_t) e->m_nlink)) ) { - e->m_ctime = stat_buf.st_ctime; - e->m_nlink = stat_buf.st_nlink; - return Changed; - } - - return NoChange; - } - - // dir/file doesn't exist - - if (e->m_ctime == invalid_ctime && e->m_status == NonExistent) { - e->m_nlink = 0; - e->m_status = NonExistent; - return NoChange; - } - - e->m_ctime = invalid_ctime; - e->m_nlink = 0; - e->m_status = NonExistent; - - return Deleted; -} - -/* Notify all interested KDirWatch instances about a given event on an entry - * and stored pending events. When watching is stopped, the event is - * added to the pending events. - */ -void KDirWatchPrivate::emitEvent(Entry* e, int event, const TQString &fileName) -{ - TQString path = e->path; - if (!fileName.isEmpty()) { - if (!TQDir::isRelativePath(fileName)) - path = fileName; - else -#ifdef Q_OS_UNIX - path += "/" + fileName; -#elif defined(Q_WS_WIN) - //current drive is passed instead of / - path += TQDir::currentDirPath().left(2) + "/" + fileName; -#endif - } - - TQPtrListIterator<Client> cit( e->m_clients ); - for ( ; cit.current(); ++cit ) - { - Client* c = cit.current(); - - if (c->instance==0 || c->count==0) continue; - - if (c->watchingStopped) { - // add event to pending... - if (event == Changed) - c->pending |= event; - else if (event == Created || event == Deleted) - c->pending = event; - continue; - } - // not stopped - if (event == NoChange || event == Changed) - event |= c->pending; - c->pending = NoChange; - if (event == NoChange) continue; - - if (event & Deleted) { - c->instance->setDeleted(path); - // emit only Deleted event... - continue; - } - - if (event & Created) { - c->instance->setCreated(path); - // possible emit Change event after creation - } - - if (event & Changed) - c->instance->setDirty(path); - } -} - -// Remove entries which were marked to be removed -void KDirWatchPrivate::slotRemoveDelayed() -{ - Entry* e; - delayRemove = false; - for(e=removeList.first();e;e=removeList.next()) - removeEntry(0, e->path, 0); - removeList.clear(); -} - -/* Scan all entries to be watched for changes. This is done regularly - * when polling and once after a DNOTIFY signal. This is NOT used by FAM. - */ -void KDirWatchPrivate::slotRescan() -{ - EntryMap::Iterator it; - - // People can do very long things in the slot connected to dirty(), - // like showing a message box. We don't want to keep polling during - // that time, otherwise the value of 'delayRemove' will be reset. - bool timerRunning = timer->isActive(); - if ( timerRunning ) - timer->stop(); - - // We delay deletions of entries this way. - // removeDir(), when called in slotDirty(), can cause a crash otherwise - delayRemove = true; - -#if defined(HAVE_DNOTIFY) || defined(HAVE_INOTIFY) - TQPtrList<Entry> dList, cList; -#endif - - if (rescan_all) - { - // mark all as dirty - it = m_mapEntries.begin(); - for( ; it != m_mapEntries.end(); ++it ) - (*it).dirty = true; - rescan_all = false; - } - else - { - // progate dirty flag to dependant entries (e.g. file watches) - it = m_mapEntries.begin(); - for( ; it != m_mapEntries.end(); ++it ) - if (((*it).m_mode == INotifyMode || (*it).m_mode == DNotifyMode) && (*it).dirty ) - (*it).propagate_dirty(); - } - - it = m_mapEntries.begin(); - for( ; it != m_mapEntries.end(); ++it ) { - // we don't check invalid entries (i.e. remove delayed) - if (!(*it).isValid()) continue; - - int ev = scanEntry( &(*it) ); - - -#ifdef HAVE_INOTIFY - if ((*it).m_mode == INotifyMode && ev == Created && (*it).wd == 0) { - cList.append( &(*it) ); - if (! useINotify( &(*it) )) { - useStat( &(*it) ); - } - } -#endif - -#ifdef HAVE_DNOTIFY - if ((*it).m_mode == DNotifyMode) { - if ((*it).isDir && (ev == Deleted)) { - dList.append( &(*it) ); - - // must close the FD. - if ((*it).dn_fd) { - ::close((*it).dn_fd); - fd_Entry.remove((*it).dn_fd); - (*it).dn_fd = 0; - } - } - - else if ((*it).isDir && (ev == Created)) { - // For created, but yet without DNOTIFYing ... - if ( (*it).dn_fd == 0) { - cList.append( &(*it) ); - if (! useDNotify( &(*it) )) { - // if DNotify setup fails... - useStat( &(*it) ); - } - } - } - } -#endif - - if ( ev != NoChange ) - emitEvent( &(*it), ev); - } - - -#if defined(HAVE_DNOTIFY) || defined(HAVE_INOTIFY) - // Scan parent of deleted directories for new creation - Entry* e; - for(e=dList.first();e;e=dList.next()) - addEntry(0, TQDir::cleanDirPath( e->path+"/.."), e, true); - - // Remove watch of parent of new created directories - for(e=cList.first();e;e=cList.next()) - removeEntry(0, TQDir::cleanDirPath( e->path+"/.."), e); -#endif - - if ( timerRunning ) - timer->start(freq); - - TQTimer::singleShot(0, this, TQT_SLOT(slotRemoveDelayed())); -} - -bool KDirWatchPrivate::isNoisyFile( const char * filename ) -{ - // $HOME/.X.err grows with debug output, so don't notify change - if ( *filename == '.') { - if (strncmp(filename, ".X.err", 6) == 0) return true; - if (strncmp(filename, ".xsession-errors", 16) == 0) return true; - // fontconfig updates the cache on every KDE app start - // (inclusive kio_thumbnail slaves) - if (strncmp(filename, ".fonts.cache", 12) == 0) return true; - } - - return false; -} - -#ifdef HAVE_FAM -void KDirWatchPrivate::famEventReceived() -{ - static FAMEvent fe; - - delayRemove = true; - - while(use_fam && FAMPending(&fc)) { - if (FAMNextEvent(&fc, &fe) == -1) { - kdWarning(7001) << "FAM connection problem, switching to polling." - << endl; - use_fam = false; - delete sn; sn = 0; - - // Replace all FAMMode entries with DNotify/Stat - EntryMap::Iterator it; - it = m_mapEntries.begin(); - for( ; it != m_mapEntries.end(); ++it ) - if ((*it).m_mode == FAMMode && (*it).m_clients.count()>0) { -#ifdef HAVE_INOTIFY - if (useINotify( &(*it) )) continue; -#endif -#ifdef HAVE_DNOTIFY - if (useDNotify( &(*it) )) continue; -#endif - useStat( &(*it) ); - } - } - else - checkFAMEvent(&fe); - } - - TQTimer::singleShot(0, this, TQT_SLOT(slotRemoveDelayed())); -} - -void KDirWatchPrivate::checkFAMEvent(FAMEvent* fe) -{ - // Don't be too verbose ;-) - if ((fe->code == FAMExists) || - (fe->code == FAMEndExist) || - (fe->code == FAMAcknowledge)) return; - - if ( isNoisyFile( fe->filename ) ) - return; - - Entry* e = 0; - EntryMap::Iterator it = m_mapEntries.begin(); - for( ; it != m_mapEntries.end(); ++it ) - if (FAMREQUEST_GETREQNUM(&( (*it).fr )) == - FAMREQUEST_GETREQNUM(&(fe->fr)) ) { - e = &(*it); - break; - } - - // Entry* e = static_cast<Entry*>(fe->userdata); - -#if 0 // #88538 - kdDebug(7001) << "Processing FAM event (" - << ((fe->code == FAMChanged) ? "FAMChanged" : - (fe->code == FAMDeleted) ? "FAMDeleted" : - (fe->code == FAMStartExecuting) ? "FAMStartExecuting" : - (fe->code == FAMStopExecuting) ? "FAMStopExecuting" : - (fe->code == FAMCreated) ? "FAMCreated" : - (fe->code == FAMMoved) ? "FAMMoved" : - (fe->code == FAMAcknowledge) ? "FAMAcknowledge" : - (fe->code == FAMExists) ? "FAMExists" : - (fe->code == FAMEndExist) ? "FAMEndExist" : "Unknown Code") - << ", " << fe->filename - << ", Req " << FAMREQUEST_GETREQNUM(&(fe->fr)) - << ")" << endl; -#endif - - if (!e) { - // this happens e.g. for FAMAcknowledge after deleting a dir... - // kdDebug(7001) << "No entry for FAM event ?!" << endl; - return; - } - - if (e->m_status == NonExistent) { - kdDebug(7001) << "FAM event for nonExistent entry " << e->path << endl; - return; - } - - // Delayed handling. This rechecks changes with own stat calls. - e->dirty = true; - if (!rescan_timer.isActive()) - rescan_timer.start(m_PollInterval, true); - - // needed FAM control actions on FAM events - if (e->isDir) - switch (fe->code) - { - case FAMDeleted: - // file absolute: watched dir - if (!TQDir::isRelativePath(fe->filename)) - { - // a watched directory was deleted - - e->m_status = NonExistent; - FAMCancelMonitor(&fc, &(e->fr) ); // needed ? - kdDebug(7001) << "Cancelled FAMReq " - << FAMREQUEST_GETREQNUM(&(e->fr)) - << " for " << e->path << endl; - // Scan parent for a new creation - addEntry(0, TQDir::cleanDirPath( e->path+"/.."), e, true); - } - break; - - case FAMCreated: { - // check for creation of a directory we have to watch - Entry *sub_entry = e->m_entries.first(); - for(;sub_entry; sub_entry = e->m_entries.next()) - if (sub_entry->path == e->path + "/" + fe->filename) break; - if (sub_entry && sub_entry->isDir) { - TQString path = e->path; - removeEntry(0,e->path,sub_entry); // <e> can be invalid here!! - sub_entry->m_status = Normal; - if (!useFAM(sub_entry)) -#ifdef HAVE_INOTIFY - if (!useINotify(sub_entry )) -#endif - useStat(sub_entry); - } - break; - } - - default: - break; - } -} -#else -void KDirWatchPrivate::famEventReceived() {} -#endif - - -void KDirWatchPrivate::statistics() -{ - EntryMap::Iterator it; - - kdDebug(7001) << "Entries watched:" << endl; - if (m_mapEntries.count()==0) { - kdDebug(7001) << " None." << endl; - } - else { - it = m_mapEntries.begin(); - for( ; it != m_mapEntries.end(); ++it ) { - Entry* e = &(*it); - kdDebug(7001) << " " << e->path << " (" - << ((e->m_status==Normal)?"":"Nonexistent ") - << (e->isDir ? "Dir":"File") << ", using " - << ((e->m_mode == FAMMode) ? "FAM" : - (e->m_mode == INotifyMode) ? "INotify" : - (e->m_mode == DNotifyMode) ? "DNotify" : - (e->m_mode == StatMode) ? "Stat" : "Unknown Method") - << ")" << endl; - - Client* c = e->m_clients.first(); - for(;c; c = e->m_clients.next()) { - TQString pending; - if (c->watchingStopped) { - if (c->pending & Deleted) pending += "deleted "; - if (c->pending & Created) pending += "created "; - if (c->pending & Changed) pending += "changed "; - if (!pending.isEmpty()) pending = " (pending: " + pending + ")"; - pending = ", stopped" + pending; - } - kdDebug(7001) << " by " << c->instance->name() - << " (" << c->count << " times)" - << pending << endl; - } - if (e->m_entries.count()>0) { - kdDebug(7001) << " dependent entries:" << endl; - Entry* d = e->m_entries.first(); - for(;d; d = e->m_entries.next()) { - kdDebug(7001) << " " << d << endl; - kdDebug(7001) << " " << d->path << " (" << d << ") " << endl; - } - } - } - } -} - - -// -// Class KDirWatch -// - -static KStaticDeleter<KDirWatch> sd_dw; -KDirWatch* KDirWatch::s_pSelf = 0L; - -KDirWatch* KDirWatch::self() -{ - if ( !s_pSelf ) { - sd_dw.setObject( s_pSelf, new KDirWatch ); - } - - return s_pSelf; -} - -bool KDirWatch::exists() -{ - return s_pSelf != 0; -} - -KDirWatch::KDirWatch (TQObject* parent, const char* name) - : TQObject(parent,name) -{ - if (!name) { - static int nameCounter = 0; - - nameCounter++; - setName(TQString(TQString("KDirWatch-%1").arg(nameCounter)).ascii()); - } - - if (!dwp_self) - dwp_self = new KDirWatchPrivate; - d = dwp_self; - d->ref(); - - _isStopped = false; -} - -KDirWatch::~KDirWatch() -{ - d->removeEntries(this); - if ( d->deref() ) - { - // delete it if it's the last one - delete d; - dwp_self = 0L; - } -} - - -// TODO: add watchFiles/recursive support -void KDirWatch::addDir( const TQString& _path, - bool watchFiles, bool recursive) -{ - if (watchFiles || recursive) { - kdDebug(7001) << "addDir - recursive/watchFiles not supported yet in KDE 3.x" << endl; - } - if (d) d->addEntry(this, _path, 0, true); -} - -void KDirWatch::addFile( const TQString& _path ) -{ - if (d) d->addEntry(this, _path, 0, false); -} - -TQDateTime KDirWatch::ctime( const TQString &_path ) -{ - KDirWatchPrivate::Entry* e = d->entry(_path); - - if (!e) - return TQDateTime(); - - TQDateTime result; - result.setTime_t(e->m_ctime); - return result; -} - -void KDirWatch::removeDir( const TQString& _path ) -{ - if (d) d->removeEntry(this, _path, 0); -} - -void KDirWatch::removeFile( const TQString& _path ) -{ - if (d) d->removeEntry(this, _path, 0); -} - -bool KDirWatch::stopDirScan( const TQString& _path ) -{ - if (d) { - KDirWatchPrivate::Entry *e = d->entry(_path); - if (e && e->isDir) return d->stopEntryScan(this, e); - } - return false; -} - -bool KDirWatch::restartDirScan( const TQString& _path ) -{ - if (d) { - KDirWatchPrivate::Entry *e = d->entry(_path); - if (e && e->isDir) - // restart without notifying pending events - return d->restartEntryScan(this, e, false); - } - return false; -} - -void KDirWatch::stopScan() -{ - if (d) d->stopScan(this); - _isStopped = true; -} - -void KDirWatch::startScan( bool notify, bool skippedToo ) -{ - _isStopped = false; - if (d) d->startScan(this, notify, skippedToo); -} - - -bool KDirWatch::contains( const TQString& _path ) const -{ - KDirWatchPrivate::Entry* e = d->entry(_path); - if (!e) - return false; - - KDirWatchPrivate::Client* c = e->m_clients.first(); - for(;c;c=e->m_clients.next()) - if (c->instance == this) return true; - - return false; -} - -void KDirWatch::statistics() -{ - if (!dwp_self) { - kdDebug(7001) << "KDirWatch not used" << endl; - return; - } - dwp_self->statistics(); -} - - -void KDirWatch::setCreated( const TQString & _file ) -{ - kdDebug(7001) << name() << " emitting created " << _file << endl; - emit created( _file ); -} - -void KDirWatch::setDirty( const TQString & _file ) -{ - kdDebug(7001) << name() << " emitting dirty " << _file << endl; - emit dirty( _file ); -} - -void KDirWatch::setDeleted( const TQString & _file ) -{ - kdDebug(7001) << name() << " emitting deleted " << _file << endl; - emit deleted( _file ); -} - -KDirWatch::Method KDirWatch::internalMethod() -{ -#ifdef HAVE_FAM - if (d->use_fam) - return KDirWatch::FAM; -#endif -#ifdef HAVE_INOTIFY - if (d->supports_inotify) - return KDirWatch::INotify; -#endif -#ifdef HAVE_DNOTIFY - if (d->supports_dnotify) - return KDirWatch::DNotify; -#endif - return KDirWatch::Stat; -} - - -#include "kdirwatch.moc" -#include "kdirwatch_p.moc" - -//sven - -// vim: sw=2 ts=8 et diff --git a/kio/kio/kdirwatch.h b/kio/kio/kdirwatch.h deleted file mode 100644 index 4abaa302e..000000000 --- a/kio/kio/kdirwatch.h +++ /dev/null @@ -1,290 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1998 Sven Radej <sven@lisa.exp.univie.ac.at> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef _KDIRWATCH_H -#define _KDIRWATCH_H - -#include <tqtimer.h> -#include <tqdatetime.h> -#include <tqmap.h> - -#include <tdelibs_export.h> - -#define kdirwatch KDirWatch::self() - -class KDirWatchPrivate; - - /** - * Watch directories and files for changes. - * The watched directories or files don't have to exist yet. - * - * When a watched directory is changed, i.e. when files therein are - * created or deleted, KDirWatch will emit the signal dirty(). - * - * When a watched, but previously not existing directory gets created, - * KDirWatch will emit the signal created(). - * - * When a watched directory gets deleted, KDirWatch will emit the - * signal deleted(). The directory is still watched for new - * creation. - * - * When a watched file is changed, i.e. attributes changed or written - * to, KDirWatch will emit the signal dirty(). - * - * Scanning of particular directories or files can be stopped temporarily - * and restarted. The whole class can be stopped and restarted. - * Directories and files can be added/removed from the list in any state. - * - * The implementation uses the FAM service when available; - * if FAM is not available, the DNOTIFY functionality is used on LINUX. - * As a last resort, a regular polling for change of modification times - * is done; the polling interval is a global config option: - * DirWatch/PollInterval and DirWatch/NFSPollInterval for NFS mounted - * directories. - * - * @see self() - * @short Class for watching directory and file changes. - * @author Sven Radej <sven@lisa.exp.univie.ac.at> - */ -class TDEIO_EXPORT KDirWatch : public TQObject -{ - Q_OBJECT - - public: - /** - * Constructor. - * - * Scanning begins immediately when a dir/file watch - * is added. - * @param parent the parent of the TQObject (or 0 for parent-less KDataTools) - * @param name the name of the TQObject, can be 0 - */ - KDirWatch (TQObject* parent = 0, const char* name = 0); - - /** - * Destructor. - * - * Stops scanning and cleans up. - */ - ~KDirWatch(); - - /** - * Adds a directory to be watched. - * - * The directory does not have to exist. When @p watchFiles is - * false (the default), the signals dirty(), created(), deleted() - * can be emitted, all for the watched directory. - * When @p watchFiles is true, all files in the watched directory - * are watched for changes, too. Thus, the signals dirty(), - * created(), deleted() can be emitted. - * - * @param path the path to watch - * @param watchFiles if true, the KDirWatch will also watch files - NOT IMPLEMENTED YET - * @param recursive if true, all sub directories are also watched - NOT IMPLEMENTED YET - */ - void addDir(const TQString& path, - bool watchFiles = false, bool recursive = false); - - /** - * Adds a file to be watched. - * @param file the file to watch - */ - void addFile(const TQString& file); - - /** - * Returns the time the directory/file was last changed. - * @param path the file to check - * @return the date of the last modification - */ - TQDateTime ctime(const TQString& path); - - /** - * Removes a directory from the list of scanned directories. - * - * If specified path is not in the list this does nothing. - * @param path the path of the dir to be removed from the list - */ - void removeDir(const TQString& path); - - /** - * Removes a file from the list of watched files. - * - * If specified path is not in the list this does nothing. - * @param file the file to be removed from the list - */ - void removeFile(const TQString& file); - - /** - * Stops scanning the specified path. - * - * The @p path is not deleted from the interal just, it is just skipped. - * Call this function when you perform an huge operation - * on this directory (copy/move big files or many files). When finished, - * call restartDirScan(path). - * - * @param path the path to skip - * @return true if the @p path is being watched, otherwise false - * @see restartDirScanning() - */ - bool stopDirScan(const TQString& path); - - /** - * Restarts scanning for specified path. - * - * Resets ctime. It doesn't notify - * the change (by emitted a signal), since the ctime value is reset. - * - * Call it when you are finished with big operations on that path, - * @em and when @em you have refreshed that path. - * - * @param path the path to restart scanning - * @return true if the @p path is being watched, otherwise false - * @see stopDirScanning() - */ - bool restartDirScan(const TQString& path); - - /** - * Starts scanning of all dirs in list. - * - * @param notify If true, all changed directories (since - * stopScan() call) will be notified for refresh. If notify is - * false, all ctimes will be reset (except those who are stopped, - * but only if @p skippedToo is false) and changed dirs won't be - * notified. You can start scanning even if the list is - * empty. First call should be called with @p false or else all - * directories - * in list will be notified. - * @param skippedToo if true, the skipped directoris (scanning of which was - * stopped with stopDirScan() ) will be reset and notified - * for change. Otherwise, stopped directories will continue to be - * unnotified. - */ - void startScan( bool notify=false, bool skippedToo=false ); - - /** - * Stops scanning of all directories in internal list. - * - * The timer is stopped, but the list is not cleared. - */ - void stopScan(); - - /** - * Is scanning stopped? - * After creation of a KDirWatch instance, this is false. - * @return true when scanning stopped - */ - bool isStopped() { return _isStopped; } - - /** - * Check if a directory is being watched by this KDirWatch instance - * @param path the directory to check - * @return true if the directory is being watched - */ - bool contains( const TQString& path ) const; - - /** - * Dump statistic information about all KDirWatch instances. - * This checks for consistency, too. - */ - static void statistics(); - - /** - * Emits created(). - * @param path the path of the file or directory - */ - void setCreated( const TQString &path ); - /** - * Emits dirty(). - * @param path the path of the file or directory - */ - void setDirty( const TQString &path ); - /** - * Emits deleted(). - * @param path the path of the file or directory - */ - void setDeleted( const TQString &path ); - - enum Method { FAM, DNotify, Stat, INotify }; - /** - * Returns the preferred internal method to - * watch for changes. - * @since 3.2 - */ - Method internalMethod(); - - /** - * The KDirWatch instance usually globally used in an application. - * It is automatically deleted when the application exits. - * - * However, you can create an arbitrary number of KDirWatch instances - * aside from this one - for those you have to take care of memory management. - * - * This function returns an instance of KDirWatch. If there is none, it - * will be created. - * - * @return a KDirWatch instance - */ - static KDirWatch* self(); - /** - * Returns true if there is an instance of KDirWatch. - * @return true if there is an instance of KDirWatch. - * @see KDirWatch::self() - * @since 3.1 - */ - static bool exists(); - - signals: - - /** - * Emitted when a watched object is changed. - * For a directory this signal is emitted when files - * therein are created or deleted. - * For a file this signal is emitted when its size or attributes change. - * - * When you watch a directory, changes in the size or attributes of - * contained files may or may not trigger this signal to be emitted - * depending on which backend is used by KDirWatch. - * - * The new ctime is set before the signal is emitted. - * @param path the path of the file or directory - */ - void dirty (const TQString &path); - - /** - * Emitted when a file or directory is created. - * @param path the path of the file or directory - */ - void created (const TQString &path ); - - /** - * Emitted when a file or directory is deleted. - * - * The object is still watched for new creation. - * @param path the path of the file or directory - */ - void deleted (const TQString &path ); - - private: - bool _isStopped; - - KDirWatchPrivate *d; - static KDirWatch* s_pSelf; -}; - -#endif - -// vim: sw=3 et diff --git a/kio/kio/kdirwatch_p.h b/kio/kio/kdirwatch_p.h deleted file mode 100644 index 8777f56b2..000000000 --- a/kio/kio/kdirwatch_p.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Private Header for class of KDirWatchPrivate - * - * this separate header file is needed for MOC processing - * because KDirWatchPrivate has signals and slots - */ - -#ifndef _KDIRWATCH_P_H -#define _KDIRWATCH_P_H - -#ifdef HAVE_FAM -#include <fam.h> -#endif - -#include <ctime> - -#define invalid_ctime ((time_t)-1) - -/* KDirWatchPrivate is a singleton and does the watching - * for every KDirWatch instance in the application. - */ -class KDirWatchPrivate : public TQObject -{ - Q_OBJECT -public: - - enum entryStatus { Normal = 0, NonExistent }; - enum entryMode { UnknownMode = 0, StatMode, DNotifyMode, INotifyMode, FAMMode }; - enum { NoChange=0, Changed=1, Created=2, Deleted=4 }; - - struct Client { - KDirWatch* instance; - int count; - // did the instance stop watching - bool watchingStopped; - // events blocked when stopped - int pending; - }; - - class Entry - { - public: - // the last observed modification time - time_t m_ctime; - // the last observed link count - int m_nlink; - entryStatus m_status; - entryMode m_mode; - bool isDir; - // instances interested in events - TQPtrList<Client> m_clients; - // nonexistent entries of this directory - TQPtrList<Entry> m_entries; - TQString path; - - int msecLeft, freq; - - void addClient(KDirWatch*); - void removeClient(KDirWatch*); - int clients(); - bool isValid() { return m_clients.count() || m_entries.count(); } - - bool dirty; - void propagate_dirty(); - -#ifdef HAVE_FAM - FAMRequest fr; -#endif - -#ifdef HAVE_DNOTIFY - int dn_fd; -#endif -#ifdef HAVE_INOTIFY - int wd; -#endif - }; - - typedef TQMap<TQString,Entry> EntryMap; - - KDirWatchPrivate(); - ~KDirWatchPrivate(); - - void resetList (KDirWatch*,bool); - void useFreq(Entry* e, int newFreq); - void addEntry(KDirWatch*,const TQString&, Entry*, bool); - void removeEntry(KDirWatch*,const TQString&, Entry*); - bool stopEntryScan(KDirWatch*, Entry*); - bool restartEntryScan(KDirWatch*, Entry*, bool ); - void stopScan(KDirWatch*); - void startScan(KDirWatch*, bool, bool); - - void removeEntries(KDirWatch*); - void statistics(); - - Entry* entry(const TQString&); - int scanEntry(Entry* e); - void emitEvent(Entry* e, int event, const TQString &fileName = TQString::null); - - // Memory management - delete when last KDirWatch gets deleted - void ref() { m_ref++; } - bool deref() { return ( --m_ref == 0 ); } - - static bool isNoisyFile( const char *filename ); - -public slots: - void slotRescan(); - void famEventReceived(); // for FAM - void slotActivated(); // for DNOTIFY - void slotRemoveDelayed(); - -public: - TQTimer *timer; - EntryMap m_mapEntries; - - int freq; - int statEntries; - int m_nfsPollInterval, m_PollInterval; - int m_ref; - bool useStat(Entry*); - - bool delayRemove; - TQPtrList<Entry> removeList; - - bool rescan_all; - TQTimer rescan_timer; - -#ifdef HAVE_FAM - TQSocketNotifier *sn; - FAMConnection fc; - bool use_fam; - - void checkFAMEvent(FAMEvent*); - bool useFAM(Entry*); -#endif - -#if defined(HAVE_DNOTIFY) || defined(HAVE_INOTIFY) - TQSocketNotifier *mSn; -#endif - -#ifdef HAVE_DNOTIFY - bool supports_dnotify; - int mPipe[2]; - TQIntDict<Entry> fd_Entry; - - static void dnotify_handler(int, siginfo_t *si, void *); - static void dnotify_sigio_handler(int, siginfo_t *si, void *); - bool useDNotify(Entry*); -#endif - -#ifdef HAVE_INOTIFY - bool supports_inotify; - int m_inotify_fd; - - bool useINotify(Entry*); -#endif -}; - -#endif // KDIRWATCH_P_H - diff --git a/kio/kio/kemailsettings.cpp b/kio/kio/kemailsettings.cpp deleted file mode 100644 index f8ad9f7dd..000000000 --- a/kio/kio/kemailsettings.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2000 Alex Zepeda <zipzippy@sonic.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id$ - */ - -#include "kemailsettings.h" - -#include <kconfig.h> -#include <klocale.h> -#include <kdebug.h> - -class KEMailSettingsPrivate { -public: - KEMailSettingsPrivate() : m_pConfig( 0 ) {} - ~KEMailSettingsPrivate() { delete m_pConfig; } - TDEConfig *m_pConfig; - TQStringList profiles; - TQString m_sDefaultProfile, m_sCurrentProfile; -}; - -TQString KEMailSettings::defaultProfileName() const -{ - return p->m_sDefaultProfile; -} - -TQString KEMailSettings::getSetting(KEMailSettings::Setting s) -{ - p->m_pConfig->setGroup(TQString("PROFILE_")+p->m_sCurrentProfile); - switch (s) { - case ClientProgram: { - return p->m_pConfig->readEntry("EmailClient"); - break; - } - case ClientTerminal: { - return ((p->m_pConfig->readBoolEntry("TerminalClient")) ? TQString("true") : TQString("false") ); - break; - } - case RealName: { - return p->m_pConfig->readEntry("FullName"); - break; - } - case EmailAddress: { - return p->m_pConfig->readEntry("EmailAddress"); - break; - } - case ReplyToAddress: { - return p->m_pConfig->readEntry("ReplyAddr"); - break; - } - case Organization: { - return p->m_pConfig->readEntry("Organization"); - break; - } - case OutServer: { - return p->m_pConfig->readEntry("OutgoingServer"); - break; - } - case OutServerLogin: { - return p->m_pConfig->readEntry("OutgoingUserName"); - break; - } - case OutServerPass: { - return p->m_pConfig->readEntry("OutgoingPassword"); - break; - } - case OutServerType: { - return p->m_pConfig->readEntry("OutgoingServerType"); - break; - } - case OutServerCommand: { - return p->m_pConfig->readEntry("OutgoingCommand"); - break; - } - case OutServerTLS: { - return ((p->m_pConfig->readBoolEntry("OutgoingServerTLS")) ? TQString("true") : TQString("false") ); - break; - } - case InServer: { - return p->m_pConfig->readEntry("IncomingServer"); - break; - } - case InServerLogin: { - return p->m_pConfig->readEntry("IncomingUserName"); - break; - } - case InServerPass: { - return p->m_pConfig->readEntry("IncomingPassword"); - break; - } - case InServerType: { - return p->m_pConfig->readEntry("IncomingServerType"); - break; - } - case InServerMBXType: { - return p->m_pConfig->readEntry("IncomingServerMBXType"); - break; - } - case InServerTLS: { - return ((p->m_pConfig->readBoolEntry("IncomingServerTLS")) ? TQString("true") : TQString("false") ); - break; - } - }; - return TQString::null; -} -void KEMailSettings::setSetting(KEMailSettings::Setting s, const TQString &v) -{ - p->m_pConfig->setGroup(TQString("PROFILE_")+p->m_sCurrentProfile); - switch (s) { - case ClientProgram: { - p->m_pConfig->writePathEntry("EmailClient", v); - break; - } - case ClientTerminal: { - p->m_pConfig->writeEntry("TerminalClient", (v == "true") ? true : false ); - break; - } - case RealName: { - p->m_pConfig->writeEntry("FullName", v); - break; - } - case EmailAddress: { - p->m_pConfig->writeEntry("EmailAddress", v); - break; - } - case ReplyToAddress: { - p->m_pConfig->writeEntry("ReplyAddr", v); - break; - } - case Organization: { - p->m_pConfig->writeEntry("Organization", v); - break; - } - case OutServer: { - p->m_pConfig->writeEntry("OutgoingServer", v); - break; - } - case OutServerLogin: { - p->m_pConfig->writeEntry("OutgoingUserName", v); - break; - } - case OutServerPass: { - p->m_pConfig->writeEntry("OutgoingPassword", v); - break; - } - case OutServerType: { - p->m_pConfig->writeEntry("OutgoingServerType", v); - break; - } - case OutServerCommand: { - p->m_pConfig->writeEntry("OutgoingCommand", v); - break; - } - case OutServerTLS: { - p->m_pConfig->writeEntry("OutgoingServerTLS", (v == "true") ? true : false ); - break; - } - case InServer: { - p->m_pConfig->writeEntry("IncomingServer", v); - break; - } - case InServerLogin: { - p->m_pConfig->writeEntry("IncomingUserName", v); - break; - } - case InServerPass: { - p->m_pConfig->writeEntry("IncomingPassword", v); - break; - } - case InServerType: { - p->m_pConfig->writeEntry("IncomingServerType", v); - break; - } - case InServerMBXType: { - p->m_pConfig->writeEntry("IncomingServerMBXType", v); - break; - } - case InServerTLS: { - p->m_pConfig->writeEntry("IncomingServerTLS", (v == "true") ? true : false ); - break; - } - }; - p->m_pConfig->sync(); -} - -void KEMailSettings::setDefault(const TQString &s) -{ - p->m_pConfig->setGroup("Defaults"); - p->m_pConfig->writeEntry("Profile", s); - p->m_pConfig->sync(); - p->m_sDefaultProfile=s; - -} - -void KEMailSettings::setProfile (const TQString &s) -{ - TQString groupname="PROFILE_"; - groupname.append(s); - p->m_sCurrentProfile=s; - if (!p->m_pConfig->hasGroup(groupname)) { // Create a group if it doesn't exist - p->m_pConfig->setGroup(groupname); - p->m_pConfig->writeEntry("ServerType", TQString::null); - p->m_pConfig->sync(); - p->profiles+=s; - } -} - -TQString KEMailSettings::currentProfileName() const -{ - return p->m_sCurrentProfile; -} - -TQStringList KEMailSettings::profiles() const -{ - return p->profiles; -} - -KEMailSettings::KEMailSettings() -{ - p = new KEMailSettingsPrivate(); - p->m_sCurrentProfile=TQString::null; - - p->m_pConfig = new TDEConfig("emaildefaults"); - - TQStringList groups = p->m_pConfig->groupList(); - for (TQStringList::Iterator it = groups.begin(); it != groups.end(); ++it) { - if ( (*it).left(8) == "PROFILE_" ) - p->profiles+= (*it).mid(8, (*it).length()); - } - - p->m_pConfig->setGroup("Defaults"); - p->m_sDefaultProfile=p->m_pConfig->readEntry("Profile", i18n("Default")); - if (!p->m_sDefaultProfile.isNull()) { - if (!p->m_pConfig->hasGroup(TQString("PROFILE_")+p->m_sDefaultProfile)) - setDefault(i18n("Default")); - else - setDefault(p->m_sDefaultProfile); - } else { - if (p->profiles.count()) { - setDefault(p->profiles[0]); - } else - setDefault(i18n("Default")); - } - setProfile(defaultProfileName()); -} - -KEMailSettings::~KEMailSettings() -{ - delete p; -} diff --git a/kio/kio/kemailsettings.h b/kio/kio/kemailsettings.h deleted file mode 100644 index 0ade4520e..000000000 --- a/kio/kio/kemailsettings.h +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * Copyright (c) 2000 Alex Zepeda <zipzippy@sonic.net> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#ifndef _KEMAILSETTINGS_H -#define _KEMAILSETTINGS_H - -#include <tqstring.h> -#include <tqstringlist.h> - -#include <tdelibs_export.h> - -class KEMailSettingsPrivate; - - -/** - * This is just a small class to facilitate accessing e-mail settings in - * a sane way, and allowing any program to manage multiple e-mail - * profiles effortlessly - * - * @author Alex Zepeda zipzippy@sonic.net - **/ -class TDEIO_EXPORT KEMailSettings { -public: - /** - * The list of settings that I thought of when I wrote this - * class. Any extra settings thought of later can be accessed - * easily with getExtendedSetting and setExtendedSetting. - * @see getSetting() - * @see setSetting() - * @see getExtendedSetting() - * @see setExtendedSetting() - **/ - enum Setting { - ClientProgram, - ClientTerminal, - RealName, - EmailAddress, - ReplyToAddress, - Organization, - OutServer, - OutServerLogin, - OutServerPass, - OutServerType, - OutServerCommand, - OutServerTLS, - InServer, - InServerLogin, - InServerPass, - InServerType, - InServerMBXType, - InServerTLS - }; - - /** - * The various extensions allowed. - **/ - enum Extension { - POP3, - SMTP, - OTHER - }; - - /** - * Default constructor, just sets things up. - **/ - KEMailSettings(); - - /** - * Default destructor, nothing to see here. - **/ - ~KEMailSettings(); - - /** - * List of profiles available. - * @return the list of profiles - **/ - TQStringList profiles() const; - - /** - * Returns the name of the current profile. - * @returns what profile we're currently using - **/ - TQString currentProfileName() const; - - /** - * Change the current profile. - * @param s the name of the new profile - **/ - void setProfile (const TQString &s); - - /** - * Returns the name of the default profile. - * @returns the name of the one that's currently default TQString::null if none - **/ - TQString defaultProfileName() const; - - /** - * Sets a new default. - * @param def the new default - **/ - void setDefault(const TQString &def); - - /** - * Get one of the predefined "basic" settings. - * @param s the setting to get - * @return the value of the setting, or TQString::null if not - * set - **/ - TQString getSetting(KEMailSettings::Setting s); - - /** - * Set one of the predefined "basic" settings. - * @param s the setting to set - * @param v the new value of the setting, or TQString::null to - * unset - **/ - void setSetting(KEMailSettings::Setting s, const TQString &v); - -private: - KEMailSettingsPrivate *p; -}; - -#endif diff --git a/kio/kio/kfilefilter.cpp b/kio/kio/kfilefilter.cpp deleted file mode 100644 index c927804b5..000000000 --- a/kio/kio/kfilefilter.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* This file is part of the KDE libraries - - Copyright (c) 2001,2002 Carsten Pfeiffer <pfeiffer@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License (LGPL) as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqregexp.h> - -#include <kfileitem.h> -#include <kglobal.h> - -#include "kfilefilter.h" - -KSimpleFileFilter::KSimpleFileFilter() - : m_filterDotFiles( true ), - m_filterSpecials( true ), - m_modeFilter( 0 ) -{ - m_nameFilters.setAutoDelete( true ); -} - -KSimpleFileFilter::~KSimpleFileFilter() -{ -} - -void KSimpleFileFilter::setFilterDotFiles( bool filter ) -{ - m_filterDotFiles = filter; -} - -void KSimpleFileFilter::setFilterSpecials( bool filter ) -{ - m_filterSpecials = filter; -} - -void KSimpleFileFilter::setNameFilters( const TQString& nameFilters ) -{ - // KDE 3.0 defaults - setNameFilters( nameFilters, false, ' ' ); -} - -void KSimpleFileFilter::setNameFilters( const TQString& nameFilters, - bool caseSensitive, - const TQChar& separator ) -{ - m_nameFilters.clear(); - - // Split on white space - TQStringList list = TQStringList::split(separator, nameFilters); - - TQStringList::ConstIterator it = list.begin(); - for ( ; it != list.end(); ++it ) - m_nameFilters.append(new TQRegExp(*it, caseSensitive, true )); -} - -void KSimpleFileFilter::setMimeFilters( const TQStringList& mimeFilters ) -{ - m_mimeFilters = mimeFilters; -} - -void KSimpleFileFilter::setModeFilter( mode_t mode ) -{ - m_modeFilter = mode; -} - -bool KSimpleFileFilter::passesFilter( const KFileItem *item ) const -{ - static const TQString& dot = TDEGlobal::staticQString("."); - static const TQString& dotdot = TDEGlobal::staticQString(".."); - - const TQString& name = item->name(); - - if ( m_filterDotFiles && item->isHidden() ) - return false; - - if ( m_filterSpecials && (name == dot || name == dotdot) ) - return false; - - if ( m_modeFilter && !(m_modeFilter & item->mode()) ) - return false; - - if ( !m_mimeFilters.isEmpty() ) { - // correct or guessed mimetype -- we don't mind - KMimeType::Ptr mime = item->mimeTypePtr(); - bool ok = false; - - TQStringList::ConstIterator it = m_mimeFilters.begin(); - for ( ; it != m_mimeFilters.end(); ++it ) { - if ( mime->is(*it) ) { // match! - ok = true; - break; - } - } - if ( !ok ) - return false; - } - - if ( !m_nameFilters.isEmpty() ) { - bool ok = false; - - TQPtrListIterator<TQRegExp> it( m_nameFilters ); - for ( ; it.current(); ++it ) { - if ( it.current()->exactMatch( name ) ) { // match! - ok = true; - break; - } - } - if ( !ok ) - return false; - } - - return true; // passes the filter! -} - -void KFileFilter::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -void KSimpleFileFilter::virtual_hook( int id, void* data ) -{ KFileFilter::virtual_hook( id, data ); } - diff --git a/kio/kio/kfilefilter.h b/kio/kio/kfilefilter.h deleted file mode 100644 index 2891e800e..000000000 --- a/kio/kio/kfilefilter.h +++ /dev/null @@ -1,170 +0,0 @@ -/* This file is part of the KDE libraries - - Copyright (c) 2001,2002 Carsten Pfeiffer <pfeiffer@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License (LGPL) as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KFILEFILTER_H -#define KFILEFILTER_H - -#include <tqptrlist.h> -#include <tqstringlist.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <tdelibs_export.h> - -class TQRegExp; -class KFileItem; - -/** - * A KFileFilter is a simple base class for file filters. Just - * reimplement passesFilter(). - * @short Base class for file filters. - */ -class TDEIO_EXPORT KFileFilter -{ -public: - /** - * Checks the given @p item. - * @param item the item to filter - * @return true if the @p item passes the filter, false otherwise - */ - virtual bool passesFilter( const KFileItem *item ) const = 0; -protected: - virtual void virtual_hook( int id, void* data ); -}; - -/** - * A simple file filter that can filter hidden dot files, by name, - * by mime type and by mode. - * @short A simple file filter. - */ -class TDEIO_EXPORT KSimpleFileFilter : public KFileFilter -{ -public: - /** - * Creates a new filter. By default, it filters only hidden dot files - * and "." and "..". - */ - KSimpleFileFilter(); - virtual ~KSimpleFileFilter(); - - /** - * Enable or disable filtering hidden dot files. - * This option is enabled by default. - * @param filter true to enable filtering dot files, false to - * disable - * @see filterDotFiles - */ - virtual void setFilterDotFiles( bool filter ); - /** - * Checks whether filtering dot files is enabled. - * This option is enabled by default. - * @return true if filtering is enabled, false otherwise - * @see setFilterDotFiles - */ - bool filterDotFiles() const { return m_filterDotFiles; } - - /** - * Filters "." and "..", default is true. - * @param filter true to enable, false otherwise - */ - virtual void setFilterSpecials( bool filter ); - /** - * Checks whether it filters "." and "..", default is true. - * @return true if enabled, false otherwise - */ - bool filterSpecials() const { return m_filterSpecials; } - - // ### KDE4 make virtual and bool caseSensitive = false - /** - * Sets a list of regular expressions to filter by name. - * The file will only pass if its name matches one of the regular - * expressions. - * @param nameFilters a list of regular expressions, separated by - * the character @p separator - * @param caseSensitive if true, matches case sensitive. False - * otherwise - * @param separator the separator in the @p nameFilter - * @since 3.1 - */ - void setNameFilters( const TQString& nameFilters, bool caseSensitive, - const TQChar& separator = ' ' ); - /** - * Sets a list of regular expressions to filter by name. - * The file will only pass if its name matches one of the regular - * expressions. - * @param nameFilters a list of regular expressions, separated by - * space (' ') - */ - virtual void setNameFilters( const TQString& nameFilters ); - - /** - * Sets a list of mime filters. A file can only pass if its - * mime type is contained in this list. - * @param mimeFilters the list of mime types - * @see setMimeFilter - */ - virtual void setMimeFilters( const TQStringList& mimeFilters ); - /** - * Returns the list of mime types. - * @return the list of mime types - * @see mimeFilter - */ - TQStringList mimeFilters() const { return m_mimeFilters; } - - /** - * Sets the mode filter. If the @p mode is 0, the filter is - * disabled. - * When enabled, a file will only pass if the files mode - * ANDed with @p mode is not zero. - * @param mode the new mode. 0 to disable - * @see modeFilter - */ - virtual void setModeFilter( mode_t mode ); - /** - * Returns the mode filter, as set by setModeFilter(). - * @return the mode filter, 0 if disabled - * @see setModeFilter - */ - mode_t modeFilter() const { return m_modeFilter; } - - /** - * Checks the given @p item. - * @param item the item to filter - * @return true if the @p item passes the filter, false otherwise - */ - virtual bool passesFilter( const KFileItem *item ) const; - -protected: - TQPtrList<TQRegExp> m_nameFilters; - -private: - TQStringList m_mimeFilters; - bool m_filterDotFiles :1; - bool m_filterSpecials :1; - mode_t m_modeFilter; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KSimpleFileFilterPrivate* d; -}; - -#endif // KFILEFILTER_H diff --git a/kio/kio/kfileitem.cpp b/kio/kio/kfileitem.cpp deleted file mode 100644 index fa08ae961..000000000 --- a/kio/kio/kfileitem.cpp +++ /dev/null @@ -1,1202 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1999 David Faure <faure@kde.org> - 2001 Carsten Pfeiffer <pfeiffer@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -// $Id$ - -#include <config.h> - -#include <sys/time.h> -#include <pwd.h> -#include <grp.h> -#include <sys/types.h> - -#include <assert.h> -#include <unistd.h> - -#include "kfileitem.h" - -#include <tqdir.h> -#include <tqfile.h> -#include <tqmap.h> -#include <tqstylesheet.h> -#include <tqimage.h> - -#include <kdebug.h> -#include <kfilemetainfo.h> -#include <ksambashare.h> -#include <knfsshare.h> -#include <kglobal.h> -#include <kglobalsettings.h> -#include <kiconloader.h> -#include <klargefile.h> -#include <klocale.h> -#include <kmimetype.h> -#include <krun.h> - -#ifdef HAVE_ELFICON -#include "tdelficon.h" -#endif // HAVE_ELFICON - -class KFileItem::KFileItemPrivate { - public: - TQString iconName; -}; - -KFileItem::KFileItem( const TDEIO::UDSEntry& _entry, const KURL& _url, - bool _determineMimeTypeOnDemand, bool _urlIsDirectory ) : - m_entry( _entry ), - m_url( _url ), - m_pMimeType( 0 ), - m_fileMode( KFileItem::Unknown ), - m_permissions( KFileItem::Unknown ), - m_bMarked( false ), - m_bLink( false ), - m_bIsLocalURL( _url.isLocalFile() ), - m_bMimeTypeKnown( false ), - m_hidden( Auto ), - d(0) -{ - readUDSEntry( _urlIsDirectory ); - init( _determineMimeTypeOnDemand ); -} - -KFileItem::KFileItem( mode_t _mode, mode_t _permissions, const KURL& _url, bool _determineMimeTypeOnDemand ) : - m_entry(), // warning ! - m_url( _url ), - m_strName( _url.fileName() ), - m_strText( TDEIO::decodeFileName( m_strName ) ), - m_pMimeType( 0 ), - m_fileMode ( _mode ), - m_permissions( _permissions ), - m_bMarked( false ), - m_bLink( false ), - m_bIsLocalURL( _url.isLocalFile() ), - m_bMimeTypeKnown( false ), - m_hidden( Auto ), - d(0) -{ - init( _determineMimeTypeOnDemand ); -} - -KFileItem::KFileItem( const KURL &url, const TQString &mimeType, mode_t mode ) -: m_url( url ), - m_strName( url.fileName() ), - m_strText( TDEIO::decodeFileName( m_strName ) ), - m_pMimeType( 0 ), - m_fileMode( mode ), - m_permissions( KFileItem::Unknown ), - m_bMarked( false ), - m_bLink( false ), - m_bIsLocalURL( url.isLocalFile() ), - m_bMimeTypeKnown( !mimeType.isEmpty() ), - m_hidden( Auto ), - d(0) -{ - if (m_bMimeTypeKnown) - m_pMimeType = KMimeType::mimeType( mimeType ); - - init( false ); -} - -KFileItem::KFileItem( const KFileItem & item ) : - d(0) -{ - assign( item ); -} - -KFileItem& KFileItem::operator=( const KFileItem & item ) -{ - assign( item ); - return *this; -} - -KFileItem::~KFileItem() -{ - delete d; -} - -void KFileItem::init( bool _determineMimeTypeOnDemand ) -{ - m_access = TQString::null; - m_size = (TDEIO::filesize_t) -1; - // metaInfo = KFileMetaInfo(); - for ( int i = 0; i < NumFlags; i++ ) - m_time[i] = (time_t) -1; - - // determine mode and/or permissions if unknown - if ( m_fileMode == KFileItem::Unknown || m_permissions == KFileItem::Unknown ) - { - mode_t mode = 0; - if ( m_url.isLocalFile() ) - { - /* directories may not have a slash at the end if - * we want to stat() them; it requires that we - * change into it .. which may not be allowed - * stat("/is/unaccessible") -> rwx------ - * stat("/is/unaccessible/") -> EPERM H.Z. - * This is the reason for the -1 - */ - KDE_struct_stat buf; - TQCString path = TQFile::encodeName(m_url.path( -1 )); - if ( KDE_lstat( path.data(), &buf ) == 0 ) - { - mode = buf.st_mode; - if ( S_ISLNK( mode ) ) - { - m_bLink = true; - if ( KDE_stat( path.data(), &buf ) == 0 ) - mode = buf.st_mode; - else // link pointing to nowhere (see kio/file/file.cc) - mode = (S_IFMT-1) | S_IRWXU | S_IRWXG | S_IRWXO; - } - // While we're at it, store the times - m_time[ Modification ] = buf.st_mtime; - m_time[ Access ] = buf.st_atime; - if ( m_fileMode == KFileItem::Unknown ) - m_fileMode = mode & S_IFMT; // extract file type - if ( m_permissions == KFileItem::Unknown ) - m_permissions = mode & 07777; // extract permissions - } - } - } - - // determine the mimetype - if (!m_pMimeType && !m_url.isEmpty()) - { - bool accurate = false; - bool isLocalURL; - KURL url = mostLocalURL(isLocalURL); - - m_pMimeType = KMimeType::findByURL( url, m_fileMode, isLocalURL, - // use fast mode if not mimetype on demand - _determineMimeTypeOnDemand, &accurate ); - //kdDebug() << "finding mimetype for " << url.url() << " : " << m_pMimeType->name() << endl; - // if we didn't use fast mode, or if we got a result, then this is the mimetype - // otherwise, determineMimeType will be able to do better. - m_bMimeTypeKnown = (!_determineMimeTypeOnDemand) || accurate; - } -} - -void KFileItem::readUDSEntry( bool _urlIsDirectory ) -{ - // extract the mode and the filename from the TDEIO::UDS Entry - bool UDS_URL_seen = false; - - if (&m_entry == NULL) return; - - TDEIO::UDSEntry::ConstIterator it = m_entry.begin(); - for( ; it != m_entry.end(); ++it ) { - switch ((*it).m_uds) { - - case TDEIO::UDS_FILE_TYPE: - m_fileMode = (mode_t)((*it).m_long); - break; - - case TDEIO::UDS_ACCESS: - m_permissions = (mode_t)((*it).m_long); - break; - - case TDEIO::UDS_USER: - m_user = ((*it).m_str); - break; - - case TDEIO::UDS_GROUP: - m_group = ((*it).m_str); - break; - - case TDEIO::UDS_NAME: - m_strName = (*it).m_str; - m_strText = TDEIO::decodeFileName( m_strName ); - break; - - case TDEIO::UDS_URL: - UDS_URL_seen = true; - m_url = KURL((*it).m_str); - if ( m_url.isLocalFile() ) - m_bIsLocalURL = true; - break; - - case TDEIO::UDS_MIME_TYPE: - m_pMimeType = KMimeType::mimeType((*it).m_str); - m_bMimeTypeKnown = true; - break; - - case TDEIO::UDS_GUESSED_MIME_TYPE: - m_guessedMimeType = (*it).m_str; - break; - - case TDEIO::UDS_LINK_DEST: - m_bLink = !(*it).m_str.isEmpty(); // we don't store the link dest - break; - - case TDEIO::UDS_ICON_NAME: - if ( !d ) - d = new KFileItemPrivate(); - d->iconName = (*it).m_str; - break; - - case TDEIO::UDS_HIDDEN: - if ( (*it).m_long ) - m_hidden = Hidden; - else - m_hidden = Shown; - break; - } - } - - // avoid creating these QStrings again and again - static const TQString& dot = TDEGlobal::staticQString("."); - if ( _urlIsDirectory && !UDS_URL_seen && !m_strName.isEmpty() && m_strName != dot ) - m_url.addPath( m_strName ); -} - -void KFileItem::refresh() -{ - m_fileMode = KFileItem::Unknown; - m_permissions = KFileItem::Unknown; - m_pMimeType = 0L; - m_user = TQString::null; - m_group = TQString::null; - m_metaInfo = KFileMetaInfo(); - m_hidden = Auto; - - // Basically, we can't trust any information we got while listing. - // Everything could have changed... - // Clearing m_entry makes it possible to detect changes in the size of the file, - // the time information, etc. - m_entry = TDEIO::UDSEntry(); - init( false ); -} - -void KFileItem::refreshMimeType() -{ - m_pMimeType = 0L; - init( false ); // Will determine the mimetype -} - -void KFileItem::setURL( const KURL &url ) -{ - m_url = url; - setName( url.fileName() ); -} - -void KFileItem::setName( const TQString& name ) -{ - m_strName = name; - m_strText = TDEIO::decodeFileName( m_strName ); -} - -TQString KFileItem::linkDest() const -{ - if (&m_entry == NULL) return TQString::null; - - // Extract it from the TDEIO::UDSEntry - TDEIO::UDSEntry::ConstIterator it = m_entry.begin(); - for( ; it != m_entry.end(); ++it ) - if ( (*it).m_uds == TDEIO::UDS_LINK_DEST ) - return (*it).m_str; - // If not in the TDEIO::UDSEntry, or if UDSEntry empty, use readlink() [if local URL] - if ( m_bIsLocalURL ) - { - char buf[1000]; - int n = readlink( TQFile::encodeName(m_url.path( -1 )), buf, sizeof(buf)-1 ); - if ( n != -1 ) - { - buf[ n ] = 0; - return TQFile::decodeName( buf ); - } - } - return TQString::null; -} - -TQString KFileItem::localPath() const -{ - if ( m_bIsLocalURL ) - { - return m_url.path(); - } - else - { - if (&m_entry == NULL) return TQString::null; - - // Extract the local path from the TDEIO::UDSEntry - TDEIO::UDSEntry::ConstIterator it = m_entry.begin(); - const TDEIO::UDSEntry::ConstIterator end = m_entry.end(); - for( ; it != end; ++it ) - if ( (*it).m_uds == TDEIO::UDS_LOCAL_PATH ) - return (*it).m_str; - } - - return TQString::null; -} - -TDEIO::filesize_t KFileItem::size(bool &exists) const -{ - exists = true; - if ( m_size != (TDEIO::filesize_t) -1 ) - return m_size; - - if (&m_entry == NULL) return 0L; - - // Extract it from the TDEIO::UDSEntry - TDEIO::UDSEntry::ConstIterator it = m_entry.begin(); - for( ; it != m_entry.end(); ++it ) - if ( (*it).m_uds == TDEIO::UDS_SIZE ) { - m_size = (*it).m_long; - return m_size; - } - // If not in the TDEIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL] - if ( m_bIsLocalURL ) - { - KDE_struct_stat buf; - if ( KDE_stat( TQFile::encodeName(m_url.path( -1 )), &buf ) == 0 ) - return buf.st_size; - } - exists = false; - return 0L; -} - -bool KFileItem::hasExtendedACL() const -{ - if (&m_entry == NULL) return false; - TDEIO::UDSEntry::ConstIterator it = m_entry.begin(); - for( ; it != m_entry.end(); it++ ) - if ( (*it).m_uds == TDEIO::UDS_EXTENDED_ACL ) { - return true; - } - return false; -} - -KACL KFileItem::ACL() const -{ - if ( hasExtendedACL() ) { - if (&m_entry == NULL) return KACL( m_permissions ); - - // Extract it from the TDEIO::UDSEntry - TDEIO::UDSEntry::ConstIterator it = m_entry.begin(); - for( ; it != m_entry.end(); ++it ) - if ( (*it).m_uds == TDEIO::UDS_ACL_STRING ) - return KACL((*it).m_str); - } - // create one from the basic permissions - return KACL( m_permissions ); -} - -KACL KFileItem::defaultACL() const -{ - if (&m_entry == NULL) return KACL(); - - // Extract it from the TDEIO::UDSEntry - TDEIO::UDSEntry::ConstIterator it = m_entry.begin(); - for( ; it != m_entry.end(); ++it ) - if ( (*it).m_uds == TDEIO::UDS_DEFAULT_ACL_STRING ) - return KACL((*it).m_str); - return KACL(); -} - -TDEIO::filesize_t KFileItem::size() const -{ - bool exists; - return size(exists); -} - -time_t KFileItem::time( unsigned int which ) const -{ - bool hasTime; - return time(which, hasTime); -} -time_t KFileItem::time( unsigned int which, bool &hasTime ) const -{ - hasTime = true; - unsigned int mappedWhich = 0; - - switch( which ) { - case TDEIO::UDS_MODIFICATION_TIME: - mappedWhich = Modification; - break; - case TDEIO::UDS_ACCESS_TIME: - mappedWhich = Access; - break; - case TDEIO::UDS_CREATION_TIME: - mappedWhich = Creation; - break; - } - - if ( m_time[mappedWhich] != (time_t) -1 ) - return m_time[mappedWhich]; - - if (&m_entry == NULL) return static_cast<time_t>(0); - - // Extract it from the TDEIO::UDSEntry - TDEIO::UDSEntry::ConstIterator it = m_entry.begin(); - for( ; it != m_entry.end(); ++it ) - if ( (*it).m_uds == which ) { - m_time[mappedWhich] = static_cast<time_t>((*it).m_long); - return m_time[mappedWhich]; - } - - // If not in the TDEIO::UDSEntry, or if UDSEntry empty, use stat() [if local URL] - if ( m_bIsLocalURL ) - { - KDE_struct_stat buf; - if ( KDE_stat( TQFile::encodeName(m_url.path(-1)), &buf ) == 0 ) - { - if(which == TDEIO::UDS_CREATION_TIME) { - // We can't determine creation time for local files - hasTime = false; - m_time[mappedWhich] = static_cast<time_t>(0); - return m_time[mappedWhich]; - } - m_time[mappedWhich] = (which == TDEIO::UDS_MODIFICATION_TIME) ? - buf.st_mtime : - /* which == TDEIO::UDS_ACCESS_TIME)*/ - buf.st_atime; - return m_time[mappedWhich]; - } - } - hasTime = false; - return static_cast<time_t>(0); -} - - -TQString KFileItem::user() const -{ - if ( m_user.isEmpty() && m_bIsLocalURL ) - { - KDE_struct_stat buff; - if ( KDE_lstat( TQFile::encodeName(m_url.path( -1 )), &buff ) == 0) // get uid/gid of the link, if it's a link - { - struct passwd *user = getpwuid( buff.st_uid ); - if ( user != 0L ) - m_user = TQString::fromLocal8Bit(user->pw_name); - } - } - return m_user; -} - -TQString KFileItem::group() const -{ -#ifdef Q_OS_UNIX - if (m_group.isEmpty() && m_bIsLocalURL ) - { - KDE_struct_stat buff; - if ( KDE_lstat( TQFile::encodeName(m_url.path( -1 )), &buff ) == 0) // get uid/gid of the link, if it's a link - { - struct group *ge = getgrgid( buff.st_gid ); - if ( ge != 0L ) { - m_group = TQString::fromLocal8Bit(ge->gr_name); - if (m_group.isEmpty()) - m_group.sprintf("%d",ge->gr_gid); - } else - m_group.sprintf("%d",buff.st_gid); - } - } -#endif - return m_group; -} - -TQString KFileItem::mimetype() const -{ - KFileItem * that = const_cast<KFileItem *>(this); - return that->determineMimeType()->name(); -} - -KMimeType::Ptr KFileItem::determineMimeType() -{ - if ( !m_pMimeType || !m_bMimeTypeKnown ) - { - bool isLocalURL; - KURL url = mostLocalURL(isLocalURL); - - m_pMimeType = KMimeType::findByURL( url, m_fileMode, isLocalURL ); - //kdDebug() << "finding mimetype for " << url.url() << " : " << m_pMimeType->name() << endl; - m_bMimeTypeKnown = true; - } - - return m_pMimeType; -} - -bool KFileItem::isMimeTypeKnown() const -{ - // The mimetype isn't known if determineMimeType was never called (on-demand determination) - // or if this fileitem has a guessed mimetype (e.g. ftp symlink) - in which case - // it always remains "not fully determined" - return m_bMimeTypeKnown && m_guessedMimeType.isEmpty(); -} - -TQString KFileItem::mimeComment() -{ - KMimeType::Ptr mType = determineMimeType(); - - bool isLocalURL; - KURL url = mostLocalURL(isLocalURL); - - TQString comment = mType->comment( url, isLocalURL ); - //kdDebug() << "finding comment for " << url.url() << " : " << m_pMimeType->name() << endl; - if (!comment.isEmpty()) - return comment; - else - return mType->name(); -} - -TQString KFileItem::iconName() -{ - if (d && (!d->iconName.isEmpty())) return d->iconName; - - bool isLocalURL; - KURL url = mostLocalURL(isLocalURL); - - //kdDebug() << "finding icon for " << url.url() << " : " << m_pMimeType->name() << endl; - return determineMimeType()->icon(url, isLocalURL); -} - -int KFileItem::overlays() const -{ - int _state = 0; - if ( m_bLink ) - _state |= KIcon::LinkOverlay; - - if ( !S_ISDIR( m_fileMode ) // Locked dirs have a special icon, use the overlay for files only - && !isReadable()) - _state |= KIcon::LockOverlay; - - if ( isHidden() ) - _state |= KIcon::HiddenOverlay; - - if( S_ISDIR( m_fileMode ) && m_bIsLocalURL) - { - if (KSambaShare::instance()->isDirectoryShared( m_url.path() ) || - KNFSShare::instance()->isDirectoryShared( m_url.path() )) - { - //kdDebug()<<"KFileShare::isDirectoryShared : "<<m_url.path()<<endl; - _state |= KIcon::ShareOverlay; - } - } - - if ( m_pMimeType->name() == "application/x-gzip" && m_url.fileName().right(3) == ".gz" ) - _state |= KIcon::ZipOverlay; - return _state; -} - -TQPixmap KFileItem::pixmap( int _size, int _state ) const -{ - if (d && (!d->iconName.isEmpty())) - return DesktopIcon(d->iconName,_size,_state); - - if ( !m_pMimeType ) - { - static const TQString & defaultFolderIcon = - TDEGlobal::staticQString(KMimeType::mimeType( "inode/directory" )->KServiceType::icon()); - - if ( S_ISDIR( m_fileMode ) ) - return DesktopIcon( defaultFolderIcon, _size, _state ); - - return DesktopIcon( "unknown", _size, _state ); - } - - _state |= overlays(); - - KMimeType::Ptr mime; - // Use guessed mimetype if the main one hasn't been determined for sure - if ( !m_bMimeTypeKnown && !m_guessedMimeType.isEmpty() ) - mime = KMimeType::mimeType( m_guessedMimeType ); - else - mime = m_pMimeType; - - // Support for gzipped files: extract mimetype of contained file - // See also the relevant code in overlays, which adds the zip overlay. - if ( mime->name() == "application/x-gzip" && m_url.fileName().right(3) == ".gz" ) - { - KURL sf; - sf.setPath( m_url.path().left( m_url.path().length() - 3 ) ); - //kdDebug() << "KFileItem::pixmap subFileName=" << subFileName << endl; - mime = KMimeType::findByURL( sf, 0, m_bIsLocalURL ); - } - - bool isLocalURL; - KURL url = mostLocalURL(isLocalURL); - - TQPixmap p = mime->pixmap( url, KIcon::Desktop, _size, _state ); - //kdDebug() << "finding pixmap for " << url.url() << " : " << mime->name() << endl; - if (p.isNull()) - kdWarning() << "Pixmap not found for mimetype " << m_pMimeType->name() << endl; - - if ( mime->name() == "application/x-executable" ) { - // At first glance it might seem to be a good idea to - // look for .desktop files for this executable before resorting to the embedded icon - // in the same fashion as the minicli, but on close examination this is NOT A GOOD IDEA. - // Specifically it allows one executable to mimic another purely based on filename, - // which could at certain times fool any user regardless of experience level. -#ifdef HAVE_ELFICON - // Check for an embedded icon - unsigned int icon_size; - libr_icon *icon = NULL; - libr_file *handle = NULL; - libr_access_t access = LIBR_READ; - - if((handle = libr_open(const_cast<char*>(url.path().ascii()), access)) == NULL) - { - kdWarning() << "failed to open file" << url.path() << endl; - return p; - } - - icon_size = _size; - icon = libr_icon_geticon_bysize(handle, icon_size); - - // See if the embedded icon name matches any icon file names already on the system - // If it does, use the system icon instead of the embedded one - int iconresnamefound = 0; - iconentry *entry = NULL; - iconlist icons; - if(!get_iconlist(handle, &icons)) - { - // Failed to obtain a list of ELF icons - kdWarning() << "failed to obtain ELF icon: " << libr_errmsg() << endl; - - // See if there is a system icon we can use - TQString sysIconName = elf_get_resource(handle, ".metadata_sysicon"); - if (!sysIconName.isEmpty()) { - if (TDEGlobal::iconLoader()->iconPath(sysIconName.ascii(), 0, true) != "") { - p = DesktopIcon( sysIconName.ascii(), _size, _state ); - } - } - - libr_close(handle); - return p; - } - else { - while((entry = get_nexticon(&icons, entry)) != NULL) - { - if(icon == NULL) - { - // Try loading this icon as fallback - icon = libr_icon_geticon_byname(handle, entry->name); - } - if (TDEGlobal::iconLoader()->iconPath(entry->name, 0, true) != "") { - iconresnamefound = 1; - p = DesktopIcon( entry->name, _size, _state ); - break; - } - } - } - - if ((iconresnamefound == 0) && (icon)) { - // Extract the embedded icon - size_t icon_data_length; - char* icondata = libr_icon_malloc(icon, &icon_data_length); - p.loadFromData(static_cast<uchar*>(static_cast<void*>(icondata)), icon_data_length); // EVIL CAST - if (icon_size != 0) { - TQImage ip = p.convertToImage(); - ip = ip.smoothScale(icon_size, icon_size); - p.convertFromImage(ip); - } - free(icondata); - libr_icon_close(icon); - } - - libr_close(handle); -#endif // HAVE_ELFICON - } - - return p; -} - -bool KFileItem::isReadable() const -{ - /* - struct passwd * user = getpwuid( geteuid() ); - bool isMyFile = (TQString::fromLocal8Bit(user->pw_name) == m_user); - // This gets ugly for the group.... - // Maybe we want a static TQString for the user and a static QStringList - // for the groups... then we need to handle the deletion properly... - */ - - if ( m_permissions != KFileItem::Unknown ) { - // No read permission at all - if ( !(S_IRUSR & m_permissions) && !(S_IRGRP & m_permissions) && !(S_IROTH & m_permissions) ) - return false; - - // Read permissions for all: save a stat call - if ( (S_IRUSR|S_IRGRP|S_IROTH) & m_permissions ) - return true; - } - - // Or if we can't read it [using ::access()] - not network transparent - if ( m_bIsLocalURL && ::access( TQFile::encodeName(m_url.path()), R_OK ) == -1 ) - return false; - - return true; -} - -bool KFileItem::isWritable() const -{ - /* - struct passwd * user = getpwuid( geteuid() ); - bool isMyFile = (TQString::fromLocal8Bit(user->pw_name) == m_user); - // This gets ugly for the group.... - // Maybe we want a static TQString for the user and a static QStringList - // for the groups... then we need to handle the deletion properly... - */ - - if ( m_permissions != KFileItem::Unknown ) { - // No write permission at all - if ( !(S_IWUSR & m_permissions) && !(S_IWGRP & m_permissions) && !(S_IWOTH & m_permissions) ) - return false; - } - - // Or if we can't read it [using ::access()] - not network transparent - if ( m_bIsLocalURL && ::access( TQFile::encodeName(m_url.path()), W_OK ) == -1 ) - return false; - - return true; -} - -bool KFileItem::isHidden() const -{ - if ( m_hidden != Auto ) - return m_hidden == Hidden; - - if ( !m_url.isEmpty() ) - return m_url.fileName()[0] == '.'; - else // should never happen - return m_strName[0] == '.'; -} - -bool KFileItem::isDir() const -{ - if ( m_fileMode == KFileItem::Unknown ) - { - kdDebug() << " KFileItem::isDir can't say -> false " << endl; - return false; // can't say for sure, so no - } - return (S_ISDIR(m_fileMode)); -/* - if (!S_ISDIR(m_fileMode)) { - if (m_url.isLocalFile()) { - KMimeType::Ptr ptr=KMimeType::findByURL(m_url,0,true,true); - if ((ptr!=0) && (ptr->is("directory/inode"))) return true; - } - return false - } else return true;*/ -} - -bool KFileItem::acceptsDrops() -{ - // A directory ? - if ( S_ISDIR( mode() ) ) { - return isWritable(); - } - - // But only local .desktop files and executables - if ( !m_bIsLocalURL ) - return false; - - if (( mimetype() == "application/x-desktop") || - ( mimetype() == "media/builtin-mydocuments") || - ( mimetype() == "media/builtin-mycomputer") || - ( mimetype() == "media/builtin-mynetworkplaces") || - ( mimetype() == "media/builtin-printers") || - ( mimetype() == "media/builtin-trash") || - ( mimetype() == "media/builtin-webbrowser")) - return true; - - // Executable, shell script ... ? - if ( ::access( TQFile::encodeName(m_url.path()), X_OK ) == 0 ) - return true; - - return false; -} - -TQString KFileItem::getStatusBarInfo() -{ - TQString text = m_strText; - - if ( m_bLink ) - { - TQString comment = determineMimeType()->comment( m_url, m_bIsLocalURL ); - TQString tmp; - if ( comment.isEmpty() ) - tmp = i18n ( "Symbolic Link" ); - else - tmp = i18n("%1 (Link)").arg(comment); - text += "->"; - text += linkDest(); - text += " "; - text += tmp; - } - else if ( S_ISREG( m_fileMode ) ) - { - bool hasSize; - TDEIO::filesize_t sizeValue = size(hasSize); - if(hasSize) - text += TQString(" (%1) ").arg( TDEIO::convertSize( sizeValue ) ); - text += mimeComment(); - } - else if ( S_ISDIR ( m_fileMode ) ) - { - text += "/ "; - text += mimeComment(); - } - else - { - text += " "; - text += mimeComment(); - } - text.replace('\n', " "); // replace any newlines with a space, so the statusbar doesn't get a two-line string which messes the display up, Alex - return text; -} - -TQString KFileItem::getToolTipText(int maxcount) -{ - // we can return TQString::null if no tool tip should be shown - TQString tip; - KFileMetaInfo info = metaInfo(); - - // the font tags are a workaround for the fact that the tool tip gets - // screwed if the color scheme uses white as default text color - const char* start = "<tr><td><nobr><font color=\"black\">"; - const char* mid = "</font></nobr></td><td><nobr><font color=\"black\">"; - const char* end = "</font></nobr></td></tr>"; - - tip = "<table cellspacing=0 cellpadding=0>"; - - tip += start + i18n("Name:") + mid + text() + end; - tip += start + i18n("Type:") + mid; - - TQString type = TQStyleSheet::escape(mimeComment()); - if ( m_bLink ) { - tip += i18n("Link to %1 (%2)").arg(linkDest(), type) + end; - } else - tip += type + end; - - if ( !S_ISDIR ( m_fileMode ) ) { - bool hasSize; - TDEIO::filesize_t sizeValue = size(hasSize); - if(hasSize) - tip += start + i18n("Size:") + mid + - TDEIO::convertSizeWithBytes(sizeValue) + end; - } - TQString timeStr = timeString( TDEIO::UDS_MODIFICATION_TIME); - if(!timeStr.isEmpty()) - tip += start + i18n("Modified:") + mid + - timeStr + end; -#ifndef Q_WS_WIN //TODO: show win32-specific permissions - TQString userStr = user(); - TQString groupStr = group(); - if(!userStr.isEmpty() || !groupStr.isEmpty()) - tip += start + i18n("Owner:") + mid + userStr + " - " + groupStr + end + - start + i18n("Permissions:") + mid + - parsePermissions(m_permissions) + end; -#endif - - if (info.isValid() && !info.isEmpty() ) - { - tip += "<tr><td colspan=2><center><s> </s></center></td></tr>"; - TQStringList keys = info.preferredKeys(); - - // now the rest - TQStringList::Iterator it = keys.begin(); - for (int count = 0; count<maxcount && it!=keys.end() ; ++it) - { - KFileMetaInfoItem item = info.item( *it ); - if ( item.isValid() ) - { - TQString s = item.string(); - if ( ( item.attributes() & KFileMimeTypeInfo::SqueezeText ) - && s.length() > 50) { - s.truncate(47); - s.append("..."); - } - if ( !s.isEmpty() ) - { - count++; - tip += start + - TQStyleSheet::escape( item.translatedKey() ) + ":" + - mid + - TQStyleSheet::escape( s ) + - end; - } - - } - } - } - tip += "</table>"; - - //kdDebug() << "making this the tool tip rich text:\n"; - //kdDebug() << tip << endl; - - return tip; -} - -void KFileItem::run() -{ - // It might be faster to pass skip that when we know the mimetype, - // and just call KRun::runURL. But then we need to use mostLocalURL() - // for application/x-desktop files, to be able to execute them. - (void) new KRun( m_url, m_fileMode, m_bIsLocalURL ); -} - -bool KFileItem::cmp( const KFileItem & item ) -{ - bool hasSize1,hasSize2,hasTime1,hasTime2; - hasSize1 = hasSize2 = hasTime1 = hasTime2 = false; - return ( m_strName == item.m_strName - && m_bIsLocalURL == item.m_bIsLocalURL - && m_fileMode == item.m_fileMode - && m_permissions == item.m_permissions - && m_user == item.m_user - && m_group == item.m_group - && m_bLink == item.m_bLink - && m_hidden == item.m_hidden - && size(hasSize1) == item.size(hasSize2) - && hasSize1 == hasSize2 - && time(TDEIO::UDS_MODIFICATION_TIME, hasTime1) == item.time(TDEIO::UDS_MODIFICATION_TIME, hasTime2) - && hasTime1 == hasTime2 - && (!d || !item.d || d->iconName == item.d->iconName) ); - - // Don't compare the mimetypes here. They might not be known, and we don't want to - // do the slow operation of determining them here. -} - -void KFileItem::assign( const KFileItem & item ) -{ - if ( this == &item ) - return; - m_entry = item.m_entry; - m_url = item.m_url; - m_bIsLocalURL = item.m_bIsLocalURL; - m_strName = item.m_strName; - m_strText = item.m_strText; - m_fileMode = item.m_fileMode; - m_permissions = item.m_permissions; - m_user = item.m_user; - m_group = item.m_group; - m_bLink = item.m_bLink; - m_pMimeType = item.m_pMimeType; - m_strLowerCaseName = item.m_strLowerCaseName; - m_bMimeTypeKnown = item.m_bMimeTypeKnown; - m_hidden = item.m_hidden; - m_guessedMimeType = item.m_guessedMimeType; - m_access = item.m_access; - m_metaInfo = item.m_metaInfo; - for ( int i = 0; i < NumFlags; i++ ) - m_time[i] = item.m_time[i]; - m_size = item.m_size; - // note: m_extra is NOT copied, as we'd have no control over who is - // deleting the data or not. - - // We had a mimetype previously (probably), so we need to re-determine it - determineMimeType(); - - if ( item.d ) { - if ( !d ) - d = new KFileItemPrivate; - d->iconName = item.d->iconName; - } else { - delete d; - d = 0; - } -} - -void KFileItem::setUDSEntry( const TDEIO::UDSEntry& _entry, const KURL& _url, - bool _determineMimeTypeOnDemand, bool _urlIsDirectory ) -{ - m_entry = _entry; - m_url = _url; - m_strName = TQString::null; - m_strText = TQString::null; - m_user = TQString::null; - m_group = TQString::null; - m_strLowerCaseName = TQString::null; - m_pMimeType = 0; - m_fileMode = KFileItem::Unknown; - m_permissions = KFileItem::Unknown; - m_bMarked = false; - m_bLink = false; - m_bIsLocalURL = _url.isLocalFile(); - m_bMimeTypeKnown = false; - m_hidden = Auto; - m_guessedMimeType = TQString::null; - m_metaInfo = KFileMetaInfo(); - - if ( d ) - d->iconName = TQString::null; - - readUDSEntry( _urlIsDirectory ); - init( _determineMimeTypeOnDemand ); -} - -void KFileItem::setFileMode( mode_t m ) -{ - m_fileMode = m; -} - -void KFileItem::setMimeType( const TQString& mimetype ) -{ - m_pMimeType = KMimeType::mimeType( mimetype ); -} - -void KFileItem::setExtraData( const void *key, void *value ) -{ - if ( !key ) - return; - - m_extra.replace( key, value ); -} - -const void * KFileItem::extraData( const void *key ) const -{ - TQMapConstIterator<const void*,void*> it = m_extra.find( key ); - if ( it != m_extra.end() ) - return it.data(); - return 0L; -} - -void * KFileItem::extraData( const void *key ) -{ - TQMapIterator<const void*,void*> it = m_extra.find( key ); - if ( it != m_extra.end() ) - return it.data(); - return 0L; -} - -void KFileItem::removeExtraData( const void *key ) -{ - m_extra.remove( key ); -} - -TQString KFileItem::permissionsString() const -{ - if (m_access.isNull()) - m_access = parsePermissions( m_permissions ); - - return m_access; -} - -TQString KFileItem::parsePermissions(mode_t perm) const -{ - char p[] = "---------- "; - - if (isDir()) - p[0]='d'; - else if (isLink()) - p[0]='l'; - - if (perm & TQFileInfo::ReadUser) - p[1]='r'; - if (perm & TQFileInfo::WriteUser) - p[2]='w'; - if ((perm & TQFileInfo::ExeUser) && !(perm & S_ISUID)) p[3]='x'; - else if ((perm & TQFileInfo::ExeUser) && (perm & S_ISUID)) p[3]='s'; - else if (!(perm & TQFileInfo::ExeUser) && (perm & S_ISUID)) p[3]='S'; - - if (perm & TQFileInfo::ReadGroup) - p[4]='r'; - if (perm & TQFileInfo::WriteGroup) - p[5]='w'; - if ((perm & TQFileInfo::ExeGroup) && !(perm & S_ISGID)) p[6]='x'; - else if ((perm & TQFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]='s'; - else if (!(perm & TQFileInfo::ExeGroup) && (perm & S_ISGID)) p[6]='S'; - - if (perm & TQFileInfo::ReadOther) - p[7]='r'; - if (perm & TQFileInfo::WriteOther) - p[8]='w'; - if ((perm & TQFileInfo::ExeOther) && !(perm & S_ISVTX)) p[9]='x'; - else if ((perm & TQFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]='t'; - else if (!(perm & TQFileInfo::ExeOther) && (perm & S_ISVTX)) p[9]='T'; - - if (hasExtendedACL()) - p[10]='+'; - - return TQString::fromLatin1(p); -} - -// check if we need to cache this -TQString KFileItem::timeString( unsigned int which ) const -{ - bool hasTime; - time_t time_ = time(which, hasTime); - if(!hasTime) return TQString::null; - - TQDateTime t; - t.setTime_t( time_); - return TDEGlobal::locale()->formatDateTime( t ); -} - -void KFileItem::setMetaInfo( const KFileMetaInfo & info ) -{ - m_metaInfo = info; -} - -const KFileMetaInfo & KFileItem::metaInfo(bool autoget, int) const -{ - bool isLocalURL; - KURL url = mostLocalURL(isLocalURL); - - if ( autoget && !m_metaInfo.isValid() && - TDEGlobalSettings::showFilePreview(url) ) - { - m_metaInfo = KFileMetaInfo( url, mimetype() ); - } - - return m_metaInfo; -} - -KURL KFileItem::mostLocalURL(bool &local) const -{ - TQString local_path = localPath(); - - if ( !local_path.isEmpty() ) - { - local = true; - KURL url; - url.setPath(local_path); - return url; - } - else - { - local = m_bIsLocalURL; - return m_url; - } -} - -void KFileItem::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -TQDataStream & operator<< ( TQDataStream & s, const KFileItem & a ) -{ - // We don't need to save/restore anything that refresh() invalidates, - // since that means we can re-determine those by ourselves. - s << a.m_url; - s << a.m_strName; - s << a.m_strText; - return s; -} - -TQDataStream & operator>> ( TQDataStream & s, KFileItem & a ) -{ - s >> a.m_url; - s >> a.m_strName; - s >> a.m_strText; - a.m_bIsLocalURL = a.m_url.isLocalFile(); - a.m_bMimeTypeKnown = false; - a.refresh(); - return s; -} diff --git a/kio/kio/kfileitem.h b/kio/kio/kfileitem.h deleted file mode 100644 index 0fcba9f4a..000000000 --- a/kio/kio/kfileitem.h +++ /dev/null @@ -1,671 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1999 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kfileitem_h__ -#define __kfileitem_h__ - -#include <tqstringlist.h> -#include <sys/stat.h> - -#include <tqptrlist.h> -#include <kio/global.h> -#include <kurl.h> -#include <kacl.h> -#include <kmimetype.h> -#include <kfilemetainfo.h> - -#define KFILEITEM_HAS_ISWRITABLE // only used in libkonq/konq_iconviewwidget.cc, will be removed for 3.4 - -/** - * A KFileItem is a generic class to handle a file, local or remote. - * In particular, it makes it easier to handle the result of TDEIO::listDir - * (UDSEntry isn't very friendly to use). - * It includes many file attributes such as mimetype, icon, text, mode, link... - */ -class TDEIO_EXPORT KFileItem -{ -public: - enum { Unknown = (mode_t) - 1 }; - - /** - * Creates an item representing a file, from a UDSEntry. - * This is the preferred constructor when using TDEIO::listDir(). - * - * @param _entry the KIO entry used to get the file, contains info about it - * @param _url the file url - * @param _determineMimeTypeOnDemand specifies if the mimetype of the given - * URL should be determined immediately or on demand - * @param _urlIsDirectory specifies if the url is just the directory of the - * fileitem and the filename from the UDSEntry should be used. - */ - KFileItem( const TDEIO::UDSEntry& _entry, const KURL& _url, - bool _determineMimeTypeOnDemand = false, - bool _urlIsDirectory = false ); - - /** - * Creates an item representing a file, from all the necessary info for it. - * @param _mode the file mode (according to stat() (e.g. S_IFDIR...) - * Set to KFileItem::Unknown if unknown. For local files, KFileItem will use stat(). - * @param _permissions the access permissions - * If you set both the mode and the permissions, you save a ::stat() for - * local files. - * Set to KFileItem::Unknown if you don't know the mode or the permission. - * @param _url the file url - * - * @param _determineMimeTypeOnDemand specify if the mimetype of the given URL - * should be determined immediately or on demand - */ - KFileItem( mode_t _mode, mode_t _permissions, const KURL& _url, - bool _determineMimeTypeOnDemand = false ); - - /** - * Creates an item representing a file, for which the mimetype is already known. - * @param url the file url - * @param mimeType the name of the file's mimetype - * @param mode the mode (S_IFDIR...) - */ - KFileItem( const KURL &url, const TQString &mimeType, mode_t mode ); - - /** - * Copy constructor. Note that extra-data set via setExtraData() is not - * deeply copied -- just the pointers are copied. - */ - KFileItem( const KFileItem &item ); - - /** - * Destructs the KFileItem. Extra data set via setExtraData() - * is not deleted. - */ - virtual ~KFileItem(); - - /** - * Throw away and re-read (for local files) all information about the file. - * This is called when the _file_ changes. - */ - void refresh(); - - /** - * Re-reads mimetype information. - * This is called when the mimetype database changes. - */ - void refreshMimeType(); - - /** - * Returns the url of the file. - * @return the url of the file - */ - const KURL & url() const { return m_url; } - - /** - * Sets the item's URL. Do not call unless you know what you are doing! - * (used for example when an item got renamed). - * @param url the item's URL - */ - void setURL( const KURL &url ); - - /** - * Sets the item's name (i.e. the filename). - * This is automatically done by setURL, to set the name from the URL's fileName(). - * This method is provided for some special cases like relative paths as names (KFindPart) - * @param name the item's name - */ - void setName( const TQString &name ); - - /** - * Returns the permissions of the file (stat.st_mode containing only permissions). - * @return the permissions of the file - */ - mode_t permissions() const { return m_permissions; } - - /** - * Returns the access permissions for the file as a string. - * @return the access persmission as string - */ - TQString permissionsString() const; - - /** - * Tells if the file has extended access level information ( Posix ACL ) - * @return true if the file has extend ACL information or false if it hasn't - * @since 3.5 - */ - bool hasExtendedACL() const; - - /** - * Returns the access control list for the file. - * @return the access control list as a KACL - * @since 3.5 - */ - KACL ACL() const; - - /** - * Returns the default access control list for the directory. - * @return the default access control list as a KACL - * @since 3.5 - */ - KACL defaultACL() const; - - /** - * Returns the file type (stat.st_mode containing only S_IFDIR, S_IFLNK, ...). - * @return the file type - */ - mode_t mode() const { return m_fileMode; } - - /** - * Returns the owner of the file. - * @return the file's owner - */ - TQString user() const; - - /** - * Returns the group of the file. - * @return the file's group - */ - TQString group() const; - - /** - * Returns true if this item represents a link in the UNIX sense of - * a link. - * @return true if the file is a link - */ - bool isLink() const { return m_bLink; } - - /** - * Returns true if this item represents a directory. - * @return true if the item is a directory - */ - bool isDir() const; - - /** - * Returns true if this item represents a file (and not a a directory) - * @return true if the item is a file - */ - bool isFile() const { return !isDir(); } - - /** - * Checks whether the file or directory is readable. In some cases - * (remote files), we may return true even though it can't be read. - * @return true if the file can be read - more precisely, - * false if we know for sure it can't - */ - bool isReadable() const; - - /** - * Checks whether the file or directory is writable. In some cases - * (remote files), we may return true even though it can't be written to. - * @return true if the file or directory can be written to - more precisely, - * false if we know for sure it can't - * @since 3.4 - */ - bool isWritable() const; - - /** - * Checks whether the file is hidden. - * @return true if the file is hidden. - */ - bool isHidden() const; - - /** - * Returns the link destination if isLink() == true. - * @return the link destination. TQString::null if the item is not a link - */ - TQString linkDest() const; - - /** - * Returns the local path if isLocalFile() == true or the KIO item has - * a UDS_LOCAL_PATH atom. - * @return the item local path, or TQString::null if not known - * @since 3.4 - */ - TQString localPath() const; - - //FIXME KDE4 deprecate this in favor of size(bool &hasSize) - /** - * Returns the size of the file, if known. - * @return the file size, or 0 if not known - */ - TDEIO::filesize_t size() const; - - /** - * Returns the size of the file, if known, and sets @p hasSize to false if not known - * @param @hasSize This is set to true if the size is known, and false if not known - * @return the file size, or 0 if not known - */ - TDEIO::filesize_t size(bool &hasSize) const; - - //FIXME KDE4 deprecate this in favor of time(unsigned int which, bool &hasSize) - /** - * Requests the modification, access or creation time, depending on @p which. - * @param which UDS_MODIFICATION_TIME, UDS_ACCESS_TIME or UDS_CREATION_TIME - * @return the time asked for, (time_t)0 if not available - * @see timeString() - */ - time_t time( unsigned int which ) const; - - /** - * Requests the modification, access or creation time, depending on @p which. - * @param which UDS_MODIFICATION_TIME, UDS_ACCESS_TIME or UDS_CREATION_TIME - * @param hasTime This is set to true is the time is known, and false if not known - * @return the time asked for, (time_t)0 if not known/available - * @see timeString() - */ - time_t time( unsigned int which, bool &hasTime ) const; - - /** - * Requests the modification, access or creation time as a string, depending - * on @p which. - * @param which UDS_MODIFICATION_TIME, UDS_ACCESS_TIME or UDS_CREATION_TIME - * @returns a formatted string of the requested time, TQString::null if time is not known - * @see time - */ - TQString timeString( unsigned int which = TDEIO::UDS_MODIFICATION_TIME ) const; - - /** - * Returns true if the file is a local file. - * @return true if the file is local, false otherwise - */ - bool isLocalFile() const { return m_bIsLocalURL; } - - /** - * Returns the text of the file item. - * It's not exactly the filename since some decoding happens ('%2F'->'/'). - * @return the text of the file item - */ - const TQString& text() const { return m_strText; } - - /** - * Return the name of the file item (without a path). - * Similar to text(), but unencoded, i.e. the original name. - * @param lowerCase if true, the name will be returned in lower case, - * which is useful to speed up sorting by name, case insensitively. - * @return the file's name - */ - const TQString& name( bool lowerCase = false ) const { - if ( !lowerCase ) - return m_strName; - else - if ( m_strLowerCaseName.isNull() ) - m_strLowerCaseName = m_strName.lower(); - return m_strLowerCaseName; - } - - /** - * Returns the mimetype of the file item. - * If @p _determineMimeTypeOnDemand was used in the constructor, this will determine - * the mimetype first. Equivalent to determineMimeType()->name() - * @return the mime type of the file - */ - TQString mimetype() const; - - /** - * Returns the mimetype of the file item. - * If _determineMimeTypeOnDemand was used in the constructor, this will determine - * the mimetype first. - * @return the mime type - */ - KMimeType::Ptr determineMimeType(); - - /** - * Returns the currently known mimetype of the file item. - * This will not try to determine the mimetype if unknown. - * @return the known mime type - */ - KMimeType::Ptr mimeTypePtr() const { return m_pMimeType; } - - bool isMimeTypeKnown() const; - /** - * Returns the descriptive comment for this mime type, or - * the mime type itself if none is present. - * @return the mime type description, or the mime type itself - */ - TQString mimeComment(); - - /** - * Returns the full path name to the icon that represents - * this mime type. - * @return iconName the name of the file's icon - */ - TQString iconName(); - - /** - * Returns a pixmap representing the file. - * @param _size Size for the pixmap in pixels. Zero will return the - * globally configured default size. - * @param _state The state of the icon: KIcon::DefaultState, - * KIcon::ActiveState or KIcon::DisabledState. - * @return the pixmap - */ - TQPixmap pixmap( int _size, int _state=0 ) const; - - /** - * Returns the overlays (bitfield of KIcon::*Overlay flags) that are used - * for this item's pixmap. Overlays are used to show for example, whether - * a file can be modified. - * @return the overlays of the pixmap - */ - int overlays() const; - - /** - * Returns the string to be displayed in the statusbar, - * e.g. when the mouse is over this item - * @return the status bar information - */ - TQString getStatusBarInfo(); - - /** - * Returns the string to be displayed in the tool tip when the mouse - * is over this item. This may load a plugin to determine additional - * information specific to the mimetype of the file. - * - * @param maxcount the maximum number of entries shown - * @return the tool tip string - */ - TQString getToolTipText(int maxcount = 6); - - /** - * Returns true if files can be dropped over this item. - * Contrary to popular belief, not only dirs will return true :) - * Executables, .desktop files, will do so as well. - * @return true if you can drop files over the item - */ - bool acceptsDrops( ); - - /** - * Let's "KRun" this file ! - * (e.g. when file is clicked or double-clicked or return is pressed) - */ - void run(); - - /** - * Returns the UDS entry. Used by the tree view to access all details - * by position. - * @return the UDS entry - */ - const TDEIO::UDSEntry & entry() const { return m_entry; } - - /** - * Used when updating a directory. marked == seen when refreshing. - * @return true if the file item is marked - */ - bool isMarked() const { return m_bMarked; } - /** - * Marks the item. - * @see isMarked() - */ - void mark() { m_bMarked = true; } - /** - * Unmarks the item. - * @see isMarked() - */ - void unmark() { m_bMarked = false; } - - /** - * Somewhat like a comparison operator, but more explicit. - * @param item the item to compare - * @return true if all values are equal - */ - bool cmp( const KFileItem & item ); - - /** - * This allows to associate some "extra" data to a KFileItem. As one - * KFileItem can be used by several objects (often views) which all need - * to add some data, you have to use a key to reference your extra data - * within the KFileItem. - * - * That way a KFileItem can hold and provide access to all those views - * separately. - * - * I.e. a KFileIconView that associates a KFileIconViewItem (an item suitable - * for use with TQIconView) does - * - * \code - * kfileItem->setExtraData( this, iconViewItem ); - * \endcode - * - * and can later access the iconViewItem by doing - * - * \code - * KFileIconViewItem *iconViewItem = static_cast<KFileIconViewItem*>( kfileItem->extraData( this )); - * \endcode - * - * This is usually more efficient then having every view associate data to - * items by using a separate TQDict or TQMap. - * - * Note: you have to remove and destroy the data you associated yourself - * when you don't need it anymore! - * - * @param key the key of the extra data - * @param value the value of the extra data - * @see extraData - * @see removeExtraData - */ - virtual void setExtraData( const void *key, void *value ); - - /** - * Retrieves the extra data with the given @p key. - * @param key the key of the extra data - * @return the extra data associated to an item with @p key via - * setExtraData. 0L if nothing was associated with @p key. - * @see extraData - */ - virtual const void * extraData( const void *key ) const; - - /** - * Retrieves the extra data with the given @p key. - * @param key the key of the extra data - * @return the extra data associated to an item with @p key via - * setExtraData. 0L if nothing was associated with @p key. - * @see extraData - */ - virtual void * extraData( const void *key ); - - /** - * Removes the extra data associated with an item via @p key. - * @param key the key of the extra data to remove - */ - virtual void removeExtraData( const void *key ); - - /** - * Sets the metainfo of this item to @p info. - * @param info the new meta info - */ - void setMetaInfo( const KFileMetaInfo & info ); - - /** - * Sets the file type (stat.st_mode containing only S_IFDIR, S_IFLNK, ...). - * @param m the new file type - * @since 3.5.0 - * @todo Actually explain what this does -- does setting S_IFDIR - * mean the file type is set to Directory? - */ - void setFileMode( mode_t m ); - - /** - * Sets new mimetype for item - * @param mimetype the new mimetype - * @since 3.5.0 - */ - void setMimeType( const TQString& mimetype ); - - /** - * Returns the metainfo of this item. - * @param autoget if true, the metainfo will automatically be created - * @param what ignored - */ - const KFileMetaInfo & metaInfo(bool autoget = true, - int what = KFileMetaInfo::Fastest) const; - - /** - * Somewhat like an assignment operator, but more explicit. - * Note: extra-data set with setExtraData() is not copied, so be careful - * what you do! - * - * @param item the item to copy - */ - void assign( const KFileItem & item ); - - /** - * Reinitialize KFileItem with a new UDSEntry. - * - * Note: extra-data set with setExtraData() is not changed or deleted, so - * be careful what you do! - * - * KDirListerCache uses it to save new/delete calls by updating existing - * items that are otherwise not needed anymore. - * - * @param entry the UDSEntry to assign to this KFileItem - * @param url the file url - * @param determineMimeTypeOnDemand specifies if the mimetype of the given - * URL should be determined immediately or on demand - * @param urlIsDirectory specifies if the url is just the directory of the - * fileitem and the filename from the UDSEntry should be used. - * @since 3.4.1 - */ - void setUDSEntry( const TDEIO::UDSEntry& entry, const KURL& url, - bool determineMimeTypeOnDemand = false, - bool urlIsDirectory = false ); - - /** - * Assignment operator, calls assign() - */ - KFileItem& operator=( const KFileItem& ); - - /** - * Tries to give a local URL for this file item if possible. - * The given boolean indicates if the returned url is local or not. - */ - KURL mostLocalURL(bool &local) const; - - ///////////// - -protected: - /** - * Computes the text, mode, and mimetype from the UDSEntry - * Called by constructor, but can be called again later - */ - void init( bool _determineMimeTypeOnDemand ); - - /** - * Extracts the data from the UDSEntry member and updates the KFileItem - * accordingly. - * @since 3.4.1 - */ - void readUDSEntry( bool _urlIsDirectory ); - - /** - * Parses the given permission set and provides it for access() - */ - TQString parsePermissions( mode_t perm ) const; - -private: - /** - * We keep a copy of the UDSEntry since we need it for getStatusBarInfo - */ - TDEIO::UDSEntry m_entry; - /** - * The url of the file - */ - KURL m_url; - - /** - * The text for this item, i.e. the file name without path, - */ - TQString m_strName; - - /** - * The text for this item, i.e. the file name without path, decoded - * ('%%' becomes '%', '%2F' becomes '/') - */ - TQString m_strText; - - /** - * the user and group assigned to the file. - */ - mutable TQString m_user, m_group; - - /** - * The filename in lower case (to speed up sorting) - */ - mutable TQString m_strLowerCaseName; - - /** - * The mimetype of the file - */ - KMimeType::Ptr m_pMimeType; - - /** - * The file mode - */ - mode_t m_fileMode; - /** - * The permissions - */ - mode_t m_permissions; - - /** - * Marked : see mark() - */ - bool m_bMarked:1; - /** - * Whether the file is a link - */ - bool m_bLink:1; - /** - * True if local file - */ - bool m_bIsLocalURL:1; - - bool m_bMimeTypeKnown:1; - - // Auto: check leading dot. - enum { Auto, Hidden, Shown } m_hidden:3; - - // For special case like link to dirs over FTP - TQString m_guessedMimeType; - mutable TQString m_access; - TQMap<const void*, void*> m_extra; - mutable KFileMetaInfo m_metaInfo; - - enum { Modification = 0, Access = 1, Creation = 2, NumFlags = 3 }; - mutable time_t m_time[3]; - mutable TDEIO::filesize_t m_size; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KFileItemPrivate; - KFileItemPrivate * d; - TDEIO_EXPORT friend TQDataStream & operator<< ( TQDataStream & s, const KFileItem & a ); - TDEIO_EXPORT friend TQDataStream & operator>> ( TQDataStream & s, KFileItem & a ); -}; - -/** - * List of KFileItems - */ -typedef TQPtrList<KFileItem> KFileItemList; - -/** - * Iterator for KFileItemList - */ -typedef TQPtrListIterator<KFileItem> KFileItemListIterator; - -TDEIO_EXPORT TQDataStream & operator<< ( TQDataStream & s, const KFileItem & a ); -TDEIO_EXPORT TQDataStream & operator>> ( TQDataStream & s, KFileItem & a ); - - -#endif diff --git a/kio/kio/kfilemetainfo.cpp b/kio/kio/kfilemetainfo.cpp deleted file mode 100644 index a5d34fa07..000000000 --- a/kio/kio/kfilemetainfo.cpp +++ /dev/null @@ -1,1859 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2001-2002 Rolf Magnus <ramagnus@kde.org> - * Copyright (C) 2001-2002 Carsten Pfeiffer <pfeiffer@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation version 2.0. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * $Id$ - */ - -#include <assert.h> - -#include <tqshared.h> -#include <tqdict.h> - -#include <ktrader.h> -#include <kstaticdeleter.h> -#include <tdeparts/componentfactory.h> -#include <kuserprofile.h> -#include <kdebug.h> -#include <kmimetype.h> -#include <kdatastream.h> // needed for serialization of bool -#include <klocale.h> -#include <kio/global.h> - -#include "kfilemetainfo.h" - -// shared data of a KFileMetaInfoItem -class KFileMetaInfoItem::Data : public TQShared -{ -public: - Data( const KFileMimeTypeInfo::ItemInfo* mti, const TQString& _key, - const TQVariant& _value ) - : TQShared(), - mimeTypeInfo( mti ), - key( _key ), - value( _value ), - dirty( false ), - added( false ), - removed( false ) - {} - - // we use this one for the streaming operators - Data() : mimeTypeInfo( 0L ) - {} - - ~Data() - { - if ( this == null ) // only the null item owns its mimeTypeInfo - delete mimeTypeInfo; - } - - const KFileMimeTypeInfo::ItemInfo* mimeTypeInfo; - // mimeTypeInfo has the key, too, but only for non-variable ones - TQString key; - TQVariant value; - bool dirty :1; - bool added :1; - bool removed :1; - - static Data* null; - static Data* makeNull(); -}; - -//this is our null data -KFileMetaInfoItem::Data* KFileMetaInfoItem::Data::null = 0L; -static KStaticDeleter<KFileMetaInfoItem::Data> sd_KFileMetaInfoItemData; - -KFileMetaInfoItem::Data* KFileMetaInfoItem::Data::makeNull() -{ - if (!null) - { - // We deliberately do not reset "null" after it has been destroyed! - // Otherwise we will run into problems later in ~KFileMetaInfoItem - // where the d-pointer is compared against null. - - KFileMimeTypeInfo::ItemInfo* info = new KFileMimeTypeInfo::ItemInfo(); - null = new Data(info, TQString::null, TQVariant()); - sd_KFileMetaInfoItemData.setObject( null ); - } - return null; -} - -KFileMetaInfoItem::KFileMetaInfoItem( const KFileMimeTypeInfo::ItemInfo* mti, - const TQString& key, const TQVariant& value ) - : d( new Data( mti, key, value ) ) -{ -} - -KFileMetaInfoItem::KFileMetaInfoItem( const KFileMetaInfoItem& item ) -{ - // operator= does everything that's necessary - d = Data::makeNull(); - *this = item; -} - -KFileMetaInfoItem::KFileMetaInfoItem() -{ - d = Data::makeNull(); -} - -KFileMetaInfoItem::~KFileMetaInfoItem() -{ - deref(); -} - -const KFileMetaInfoItem& KFileMetaInfoItem::operator= - (const KFileMetaInfoItem & item ) -{ - if (d != item.d) - { - // first deref the old one - deref(); - d = item.d; - // and now ref the new one - ref(); - } - - return *this; -} - -bool KFileMetaInfoItem::setValue( const TQVariant& value ) -{ - // We don't call makeNull here since it isn't necassery, see deref() - if ( d == Data::null ) return false; - - if ( ! (d->mimeTypeInfo->attributes() & KFileMimeTypeInfo::Modifiable ) || - ! (value.canCast(d->mimeTypeInfo->type()))) - { - kdDebug(7033) << "setting the value of " << key() << "failed\n"; - return false; - } - -// kdDebug(7033) << key() << ".setValue()\n"; - - if ( d->value == value ) - return true; - - d->dirty = true; - d->value = value; - // If we don't cast (and test for canCast in the above if), TQVariant is - // very picky about types (e.g. TQString vs. TQCString or int vs. uint) - d->value.cast(d->mimeTypeInfo->type()); - - return true; -} - -bool KFileMetaInfoItem::isRemoved() const -{ - return d->removed; -} - -TQString KFileMetaInfoItem::key() const -{ - return d->key; -} - -TQString KFileMetaInfoItem::translatedKey() const -{ - // are we a variable key? - if (d->mimeTypeInfo->key().isNull()) - { - // then try if we have luck with i18n() - return i18n(d->key.utf8()); - } - - return d->mimeTypeInfo->translatedKey(); -} - -const TQVariant& KFileMetaInfoItem::value() const -{ - return d->value; -} - -TQString KFileMetaInfoItem::string( bool mangle ) const -{ - return d->mimeTypeInfo->string(d->value, mangle); -} - -TQVariant::Type KFileMetaInfoItem::type() const -{ - return d->mimeTypeInfo->type(); -} - -uint KFileMetaInfoItem::unit() const -{ - return d->mimeTypeInfo->unit(); -} - -bool KFileMetaInfoItem::isModified() const -{ - return d->dirty; -} - -TQString KFileMetaInfoItem::prefix() const -{ - return d->mimeTypeInfo->prefix(); -} - -TQString KFileMetaInfoItem::suffix() const -{ - return d->mimeTypeInfo->suffix(); -} - -uint KFileMetaInfoItem::hint() const -{ - return d->mimeTypeInfo->hint(); -} - -uint KFileMetaInfoItem::attributes() const -{ - return d->mimeTypeInfo->attributes(); -} - -bool KFileMetaInfoItem::isEditable() const -{ - return d->mimeTypeInfo->attributes() & KFileMimeTypeInfo::Modifiable; -} - -bool KFileMetaInfoItem::isValid() const -{ - // We don't call makeNull here since it isn't necassery: - // If d is equal to null it means that null is initialized already. - // null is 0L when it hasn't been initialized and d is never 0L. - return d != Data::null; -} - -void KFileMetaInfoItem::setAdded() -{ - d->added = true; -} - -void KFileMetaInfoItem::setRemoved() -{ - d->removed = true; -} - -void KFileMetaInfoItem::ref() -{ - if (d != Data::null) d->ref(); -} - -void KFileMetaInfoItem::deref() -{ - // We don't call makeNull here since it isn't necassery: - // If d is equal to null it means that null is initialized already. - // null is 0L when it hasn't been initialized and d is never 0L. - if ((d != Data::null) && d->deref()) - { -// kdDebug(7033) << "item " << d->key -// << " is finally deleted\n"; - delete d; - d = 0; - } -} - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - -// shared data of a KFileMetaInfo -class KFileMetaInfo::Data : public TQShared -{ -public: - Data(const KURL& _url, uint _what) - : TQShared(), - url(_url), - what(_what), - mimeTypeInfo( 0L ) - {} - - // wee use this one for the streaming operators - Data() {}; - - KURL url; - uint what; - TQMap<TQString, KFileMetaInfoGroup> groups; - const KFileMimeTypeInfo* mimeTypeInfo; - TQStringList removedGroups; - - static Data* null; - static Data* makeNull(); - -}; - -KFileMetaInfo::KFileMetaInfo( const TQString& path, const TQString& mimeType, - uint what ) -{ - KURL u; - - u.setPath(path); - init(u, mimeType, what); -} - -KFileMetaInfo::KFileMetaInfo( const KURL& url, const TQString& mimeType, - uint what ) -{ - init(url, mimeType, what); -} - -void KFileMetaInfo::init( const KURL& url, const TQString& mimeType, - uint what ) -{ - d = new Data( url, what ); - - TQString mT; - if (mimeType.isEmpty()) - mT = KMimeType::findByURL(url)->name(); - else - mT = mimeType; - - // let's "share our property" - KFileMetaInfo item(*this); - - //kdDebug() << k_funcinfo << mT << " " << url << endl; - - d->mimeTypeInfo = KFileMetaInfoProvider::self()->mimeTypeInfo( mT, url.protocol() ); - if ( d->mimeTypeInfo ) - { - //kdDebug(7033) << "Found mimetype info for " << mT /* or protocol*/ << endl; - KFilePlugin *p = plugin(); - Q_ASSERT( p ); - if ( p && !p->readInfo( item, what) ) - { - deref(); - d = Data::makeNull(); - } - } - else - { -// kdDebug(7033) << "No mimetype info for " << mimeType << endl; - deref(); - d = Data::makeNull(); - } -} - -KFileMetaInfo::KFileMetaInfo( const KFileMetaInfo& original ) -{ - // operator= does everything that's necessary - d = Data::makeNull(); - *this = original; -} - -KFileMetaInfo::KFileMetaInfo() -{ - d = Data::makeNull(); -} - -KFileMetaInfo::~KFileMetaInfo() -{ - deref(); -} - -TQStringList KFileMetaInfo::supportedGroups() const -{ - assert(isValid()); - return d->mimeTypeInfo->supportedGroups(); -} - -TQStringList KFileMetaInfo::supportedKeys() const -{ - assert(isValid()); - return d->mimeTypeInfo->supportedKeys(); -} - -TQStringList KFileMetaInfo::groups() const -{ - TQStringList list; - TQMapConstIterator<TQString, KFileMetaInfoGroup> it = d->groups.begin(); - for ( ; it != d->groups.end(); ++it ) - list += (*it).name(); - - return list; -} - -TQStringList KFileMetaInfo::editableGroups() const -{ - TQStringList list; - TQStringList supported = supportedGroups(); - TQStringList::ConstIterator it = supported.begin(); - for ( ; it != supported.end(); ++it ) { - const KFileMimeTypeInfo::GroupInfo * groupInfo = d->mimeTypeInfo->groupInfo( *it ); - if ( groupInfo && groupInfo->attributes() & - (KFileMimeTypeInfo::Addable | KFileMimeTypeInfo::Removable) ) - list.append( *it ); - } - - return list; -} - -TQStringList KFileMetaInfo::preferredGroups() const -{ - assert(isValid()); - TQStringList list = groups(); - TQStringList newlist; - TQStringList preferred = d->mimeTypeInfo->preferredGroups(); - TQStringList::Iterator pref; - - // move all keys from the preferred groups that are in our list to a new list - for ( pref = preferred.begin(); pref != preferred.end(); ++pref ) - { - TQStringList::Iterator group = list.find(*pref); - if ( group != list.end() ) - { - newlist.append( *group ); - list.remove(group); - } - } - - // now the old list only contains the non-preferred items, so we - // add the remaining ones to newlist - newlist += list; - - return newlist; -} - -TQStringList KFileMetaInfo::preferredKeys() const -{ - TQStringList newlist; - - TQStringList list = preferredGroups(); - for (TQStringList::Iterator git = list.begin(); git != list.end(); ++git) - { - newlist += d->groups[*git].preferredKeys(); - } - - return newlist; -} - -KFileMetaInfoGroup KFileMetaInfo::group(const TQString& key) const -{ - TQMapIterator<TQString,KFileMetaInfoGroup> it = d->groups.find( key ); - if ( it != d->groups.end() ) - return it.data(); - else - return KFileMetaInfoGroup(); -} - -bool KFileMetaInfo::addGroup( const TQString& name ) -{ - assert(isValid()); - if ( d->mimeTypeInfo->supportedGroups().contains(name) && - ! d->groups.contains(name) ) - { - KFileMetaInfoGroup group( name, d->mimeTypeInfo ); - - // add all the items that can't be added by the user later - const KFileMimeTypeInfo::GroupInfo* ginfo = d->mimeTypeInfo->groupInfo(name); - Q_ASSERT(ginfo); - if (!ginfo) return false; - - TQStringList keys = ginfo->supportedKeys(); - for (TQStringList::Iterator it = keys.begin(); it != keys.end(); ++it) - { - const KFileMimeTypeInfo::ItemInfo* iteminfo = ginfo->itemInfo(*it); - Q_ASSERT(ginfo); - if (!iteminfo) return false; - - if ( !(iteminfo->attributes() & KFileMimeTypeInfo::Addable) && - (iteminfo->attributes() & KFileMimeTypeInfo::Modifiable)) - { - // append it now or never - group.appendItem(iteminfo->key(), TQVariant()); - } - - } - - d->groups.insert(name, group); - group.setAdded(); - return true; - } - - return false; -} - -bool KFileMetaInfo::removeGroup( const TQString& name ) -{ - TQMapIterator<TQString, KFileMetaInfoGroup> it = d->groups.find(name); - if ( (it==d->groups.end()) || - !((*it).attributes() & KFileMimeTypeInfo::Removable)) - return false; - - d->groups.remove(it); - d->removedGroups.append(name); - return true; -} - -TQStringList KFileMetaInfo::removedGroups() -{ - return d->removedGroups; -} - -const KFileMetaInfo& KFileMetaInfo::operator= (const KFileMetaInfo& info ) -{ - if (d != info.d) - { - deref(); - // first deref the old one - d = info.d; - // and now ref the new one - ref(); - } - return *this; -} - -bool KFileMetaInfo::isValid() const -{ - // We don't call makeNull here since it isn't necassery, see deref() - return d != Data::null; -} - -bool KFileMetaInfo::isEmpty() const -{ - for (TQMapIterator<TQString, KFileMetaInfoGroup> it = d->groups.begin(); - it!=d->groups.end(); ++it) - if (!(*it).isEmpty()) - return false; - return true; -} - -bool KFileMetaInfo::applyChanges() -{ - return applyChanges( path() ); -} - -bool KFileMetaInfo::applyChanges( const TQString& path ) -{ - bool doit = false; - -// kdDebug(7033) << "KFileMetaInfo::applyChanges()\n"; - - // look up if we need to write to the file - TQMapConstIterator<TQString, KFileMetaInfoGroup> it; - for (it = d->groups.begin(); it!=d->groups.end() && !doit; ++it) - { - if ( (*it).isModified() ) - doit = true; - - else - { - TQStringList keys = it.data().keys(); - for (TQStringList::Iterator it2 = keys.begin(); it2!=keys.end(); ++it2) - { - if ( (*it)[*it2].isModified() ) - { - doit = true; - break; - } - } - } - } - - if (!doit) - { - kdDebug(7033) << "Don't need to write, nothing changed\n"; - return true; - } - - KFilePlugin* p = plugin(); - if (!p) return false; - -// kdDebug(7033) << "Ok, trying to write the info\n"; - - KURL savedURL = url(); - d->url = KURL(); - d->url.setPath( path ); - - bool ret = p->writeInfo(*this); - - d->url = savedURL; - return ret; -} - -KFilePlugin * KFileMetaInfo::plugin() const -{ - assert(isValid()); - KFileMetaInfoProvider* prov = KFileMetaInfoProvider::self(); - return prov->plugin( d->mimeTypeInfo->mimeType(), d->url.protocol() ); -} - -TQString KFileMetaInfo::mimeType() const -{ - assert(isValid()); - return d->mimeTypeInfo->mimeType(); -} - -bool KFileMetaInfo::contains(const TQString& key) const -{ - TQStringList glist = groups(); - for (TQStringList::Iterator it = glist.begin(); it != glist.end(); ++it) - { - KFileMetaInfoGroup g = d->groups[*it]; - if (g.contains(key)) return true; - } - return false; -} - -bool KFileMetaInfo::containsGroup(const TQString& key) const -{ - return groups().contains(key); -} - -KFileMetaInfoItem KFileMetaInfo::item( const TQString& key) const -{ - TQStringList groups = preferredGroups(); - for (TQStringList::Iterator it = groups.begin(); it != groups.end(); ++it) - { - KFileMetaInfoItem i = d->groups[*it][key]; - if (i.isValid()) return i; - } - return KFileMetaInfoItem(); -} - -KFileMetaInfoItem KFileMetaInfo::item(const KFileMetaInfoItem::Hint hint) const -{ - TQStringList groups = preferredGroups(); - TQStringList::ConstIterator it; - for (it = groups.begin(); it != groups.end(); ++it) - { - KFileMetaInfoItem i = d->groups[*it].item(hint); - if (i.isValid()) return i; - } - return KFileMetaInfoItem(); -} - -KFileMetaInfoItem KFileMetaInfo::saveItem( const TQString& key, - const TQString& preferredGroup, - bool createGroup ) -{ - assert(isValid()); - // try the preferred groups first - if ( !preferredGroup.isEmpty() ) { - TQMapIterator<TQString,KFileMetaInfoGroup> it = - d->groups.find( preferredGroup ); - - // try to create the preferred group, if necessary - if ( it == d->groups.end() && createGroup ) { - const KFileMimeTypeInfo::GroupInfo *groupInfo = - d->mimeTypeInfo->groupInfo( preferredGroup ); - if ( groupInfo && groupInfo->supportedKeys().contains( key ) ) { - if ( addGroup( preferredGroup ) ) - it = d->groups.find( preferredGroup ); - } - } - - if ( it != d->groups.end() ) { - KFileMetaInfoItem item = it.data().addItem( key ); - if ( item.isValid() ) - return item; - } - } - - TQStringList groups = preferredGroups(); - - KFileMetaInfoItem item; - - TQStringList::ConstIterator groupIt = groups.begin(); - for ( ; groupIt != groups.end(); ++groupIt ) - { - TQMapIterator<TQString,KFileMetaInfoGroup> it = d->groups.find( *groupIt ); - if ( it != d->groups.end() ) - { - KFileMetaInfoGroup group = it.data(); - item = findEditableItem( group, key ); - if ( item.isValid() ) - return item; - } - else // not existant -- try to create the group - { - const KFileMimeTypeInfo::GroupInfo *groupInfo = - d->mimeTypeInfo->groupInfo( *groupIt ); - if ( groupInfo && groupInfo->supportedKeys().contains( key ) ) - { - if ( addGroup( *groupIt ) ) - { - KFileMetaInfoGroup group = d->groups[*groupIt]; - KFileMetaInfoItem item = group.addItem( key ); - if ( item.isValid() ) - return item; -// else ### add when removeGroup() is implemented :) -// removeGroup( *groupIt ); // couldn't add item -> remove - } - } - } - } - - // finally check for variable items - - return item; -} - -KFileMetaInfoItem KFileMetaInfo::findEditableItem( KFileMetaInfoGroup& group, - const TQString& key ) -{ - assert(isValid()); - KFileMetaInfoItem item = group.addItem( key ); - if ( item.isValid() && item.isEditable() ) - return item; - - if ( (d->mimeTypeInfo->groupInfo( group.name() )->attributes() & KFileMimeTypeInfo::Addable) ) - return item; - - return KFileMetaInfoItem(); -} - -KFileMetaInfoGroup KFileMetaInfo::appendGroup(const TQString& name) -{ - assert(isValid()); - if ( d->mimeTypeInfo->supportedGroups().contains(name) && - ! d->groups.contains(name) ) - { - KFileMetaInfoGroup group( name, d->mimeTypeInfo ); - d->groups.insert(name, group); - return group; - } - - else { - kdWarning(7033) << "Someone's trying to add a KFileMetaInfoGroup which is not supported or already existing: " << name << endl; - return KFileMetaInfoGroup(); - } -} - -TQString KFileMetaInfo::path() const -{ - return d->url.isLocalFile() ? d->url.path() : TQString::null; -} - -KURL KFileMetaInfo::url() const -{ - return d->url; -} - -void KFileMetaInfo::ref() -{ - if (d != Data::null) d->ref(); - -} - -void KFileMetaInfo::deref() -{ - // We don't call makeNull here since it isn't necassery: - // If d is equal to null it means that null is initialized already. - // null is 0L when it hasn't been initialized and d is never 0L. - if ((d != Data::null) && d->deref()) - { -// kdDebug(7033) << "metainfo object for " << d->url.path << " is finally deleted\n"; - delete d; - d = 0; - } - -} - - -KFileMetaInfo::Data* KFileMetaInfo::Data::null = 0L; -static KStaticDeleter<KFileMetaInfo::Data> sd_KFileMetaInfoData; - -KFileMetaInfo::Data* KFileMetaInfo::Data::makeNull() -{ - if (!null) - // We deliberately do not reset "null" after it has been destroyed! - // Otherwise we will run into problems later in ~KFileMetaInfoItem - // where the d-pointer is compared against null. - null = sd_KFileMetaInfoData.setObject( new KFileMetaInfo::Data(KURL(), 0) ); - return null; -} - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - -KFilePlugin::KFilePlugin( TQObject *parent, const char *name, - const TQStringList& /*args*/) - : TQObject( parent, name ) -{ -// kdDebug(7033) << "loaded a plugin for " << name << endl; -} - -KFilePlugin::~KFilePlugin() -{ -// kdDebug(7033) << "unloaded a plugin for " << name() << endl; -} - -KFileMimeTypeInfo * KFilePlugin::addMimeTypeInfo( const TQString& mimeType ) -{ - return KFileMetaInfoProvider::self()->addMimeTypeInfo( mimeType ); -} - -void KFilePlugin::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - - -KFileMimeTypeInfo::GroupInfo* KFilePlugin::addGroupInfo(KFileMimeTypeInfo* info, - const TQString& key, const TQString& translatedKey) const -{ - return info->addGroupInfo(key, translatedKey); -} - -void KFilePlugin::setAttributes(KFileMimeTypeInfo::GroupInfo* gi, uint attr) const -{ - gi->m_attr = attr; -} - -void KFilePlugin::addVariableInfo(KFileMimeTypeInfo::GroupInfo* gi, - TQVariant::Type type, uint attr) const -{ - gi->addVariableInfo(type, attr); -} - -KFileMimeTypeInfo::ItemInfo* KFilePlugin::addItemInfo(KFileMimeTypeInfo::GroupInfo* gi, - const TQString& key, - const TQString& translatedKey, - TQVariant::Type type) -{ - return gi->addItemInfo(key, translatedKey, type); -} - -void KFilePlugin::setAttributes(KFileMimeTypeInfo::ItemInfo* item, uint attr) -{ - item->m_attr = attr; -} - -void KFilePlugin::setHint(KFileMimeTypeInfo::ItemInfo* item, uint hint) -{ - item->m_hint = hint; -} - -void KFilePlugin::setUnit(KFileMimeTypeInfo::ItemInfo* item, uint unit) -{ - item->m_unit = unit; - // set prefix and suffix - switch (unit) - { - case KFileMimeTypeInfo::Seconds: - item->m_suffix = i18n("s"); break; - - case KFileMimeTypeInfo::MilliSeconds: - item->m_suffix = i18n("ms"); break; - - case KFileMimeTypeInfo::BitsPerSecond: - item->m_suffix = i18n("bps"); break; - - case KFileMimeTypeInfo::Pixels: - item->m_suffix = i18n("pixels"); break; - - case KFileMimeTypeInfo::Inches: - item->m_suffix = i18n("in"); break; - - case KFileMimeTypeInfo::Centimeters: - item->m_suffix = i18n("cm"); break; - - case KFileMimeTypeInfo::Bytes: - item->m_suffix = i18n("B"); break; - - case KFileMimeTypeInfo::KiloBytes: - item->m_suffix = i18n("KB"); break; - - case KFileMimeTypeInfo::FramesPerSecond: - item->m_suffix = i18n("fps"); break; - - case KFileMimeTypeInfo::DotsPerInch: - item->m_suffix = i18n("dpi"); break; - - case KFileMimeTypeInfo::BitsPerPixel: - item->m_suffix = i18n("bpp"); break; - - case KFileMimeTypeInfo::Hertz: - item->m_suffix = i18n("Hz"); break; - - case KFileMimeTypeInfo::Millimeters: - item->m_suffix = i18n("mm"); - } -} - -void KFilePlugin::setPrefix(KFileMimeTypeInfo::ItemInfo* item, const TQString& prefix) -{ - item->m_prefix = prefix; -} - -void KFilePlugin::setSuffix(KFileMimeTypeInfo::ItemInfo* item, const TQString& suffix) -{ - item->m_suffix = suffix; -} - -KFileMetaInfoGroup KFilePlugin::appendGroup(KFileMetaInfo& info, const TQString& key) -{ - return info.appendGroup(key); -} - -void KFilePlugin::appendItem(KFileMetaInfoGroup& group, const TQString& key, TQVariant value) -{ - group.appendItem(key, value); -} - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - - -KFileMetaInfoProvider * KFileMetaInfoProvider::s_self; -static KStaticDeleter<KFileMetaInfoProvider> sd; - -KFileMetaInfoProvider * KFileMetaInfoProvider::self() -{ - if ( !s_self ) - s_self = sd.setObject( s_self, new KFileMetaInfoProvider() ); - - return s_self; -} - -KFileMetaInfoProvider::KFileMetaInfoProvider() -{ - m_plugins.setAutoDelete( true ); -} - -KFileMetaInfoProvider::~KFileMetaInfoProvider() -{ - m_plugins.clear(); - sd.setObject( 0 ); -} - -KFilePlugin* KFileMetaInfoProvider::loadPlugin( const TQString& mimeType, const TQString& protocol ) -{ - //kdDebug() << "loadPlugin: mimeType=" << mimeType << " protocol=" << protocol << endl; - // Currently the idea is: either the mimetype is set or the protocol, but not both. - // We need PNG fileinfo, and trash: fileinfo, but not "PNG in the trash". - TQString queryMimeType, query; - if ( !mimeType.isEmpty() ) { - query = "(not exist [X-TDE-Protocol])"; - queryMimeType = mimeType; - } else { - query = TQString::fromLatin1( "[X-TDE-Protocol] == '%1'" ).arg(protocol); - // querying for a protocol: we have no mimetype, so we need to use KFilePlugin as one - queryMimeType = "KFilePlugin"; - // hopefully using KFilePlugin as genericMimeType too isn't a problem - } - const KTrader::OfferList offers = KTrader::self()->query( queryMimeType, "KFilePlugin", query, TQString::null ); - if ( offers.isEmpty() ) - return 0; - KService::Ptr service = *(offers.begin()); - Q_ASSERT( service && service->isValid() ); - if ( !service || !service->isValid() ) - return 0; - - KFilePlugin* plugin = KParts::ComponentFactory::createInstanceFromService<KFilePlugin> - ( service, TQT_TQOBJECT(this), mimeType.local8Bit() ); - if (!plugin) - kdWarning(7033) << "error loading the plugin from " << service->desktopEntryPath() << endl; - - return plugin; -} - -KFilePlugin* KFileMetaInfoProvider::loadAndRegisterPlugin( const TQString& mimeType, const TQString& protocol ) -{ - Q_ASSERT( m_pendingMimetypeInfos.isEmpty() ); - m_pendingMimetypeInfos.clear(); - - KFilePlugin* plugin = loadPlugin( mimeType, protocol ); - if ( !plugin ) { - // No plugin found. Remember that, to save time. - m_plugins.insert( protocol.isEmpty() ? mimeType : protocol, new CachedPluginInfo ); - return 0; - } - - if ( !protocol.isEmpty() ) { - // Protocol-metainfo: only one entry - Q_ASSERT( m_pendingMimetypeInfos.count() == 1 ); - KFileMimeTypeInfo* info = m_pendingMimetypeInfos[ protocol ]; - Q_ASSERT( info ); - m_plugins.insert( protocol, new CachedPluginInfo( plugin, info, true ) ); - } else { - // Mimetype-metainfo: the plugin can register itself for multiple mimetypes, remember them all - bool first = true; - TQDictIterator<KFileMimeTypeInfo> it( m_pendingMimetypeInfos ); - for( ; it.current(); ++it ) { - KFileMimeTypeInfo* info = it.current(); - m_plugins.insert( it.currentKey(), new CachedPluginInfo( plugin, info, first ) ); - first = false; - } - // Hopefully the above includes the mimetype we asked for! - if ( m_pendingMimetypeInfos.find( mimeType ) == 0 ) - kdWarning(7033) << plugin->className() << " was created for " << mimeType << " but doesn't call addMimeTypeInfo for it!" << endl; - } - m_pendingMimetypeInfos.clear(); - return plugin; -} - -KFilePlugin * KFileMetaInfoProvider::plugin(const TQString& mimeType) -{ - return plugin( mimeType, TQString::null ); -} - -KFilePlugin * KFileMetaInfoProvider::plugin(const TQString& mimeType, const TQString& protocol) -{ - //kdDebug(7033) << "plugin() : looking for plugin for protocol=" << protocol << " mimeType=" << mimeType << endl; - - if ( !protocol.isEmpty() ) { - CachedPluginInfo *cache = m_plugins.find( protocol ); - if ( cache && cache->plugin ) { - return cache->plugin; - } - if ( !cache ) { - KFilePlugin* plugin = loadAndRegisterPlugin( TQString::null, protocol ); - if ( plugin ) - return plugin; - } - } - - CachedPluginInfo *cache = m_plugins.find( mimeType ); - if ( cache ) { - return cache->plugin; - } - - KFilePlugin* plugin = loadAndRegisterPlugin( mimeType, TQString::null ); - -#if 0 - kdDebug(7033) << "currently loaded plugins:\n"; - - TQDictIterator<CachedPluginInfo> it( m_plugins ); - for( ; it.current(); ++it ) { - CachedPluginInfo* cache = it.current(); - kdDebug(7033) - << it.currentKey() // mimetype or protocol - << " : " << (cache->plugin ? cache->plugin->className() : "(no plugin)") << endl; // plugin - // TODO print cache->mimeTypeInfo - } -#endif - - return plugin; -} - -TQStringList KFileMetaInfoProvider::preferredKeys( const TQString& mimeType ) const -{ - KService::Ptr service = - KServiceTypeProfile::preferredService( mimeType, "KFilePlugin"); - - if ( !service || !service->isValid() ) - { -// kdDebug(7033) << "no valid service found\n"; - return TQStringList(); - } - return service->property("PreferredItems").toStringList(); -} - -TQStringList KFileMetaInfoProvider::preferredGroups( const TQString& mimeType ) const -{ - KService::Ptr service = - KServiceTypeProfile::preferredService( mimeType, "KFilePlugin"); - - if ( !service || !service->isValid() ) - { -// kdDebug(7033) << "no valid service found\n"; - return TQStringList(); - } - return service->property("PreferredGroups").toStringList(); -} - -const KFileMimeTypeInfo * KFileMetaInfoProvider::mimeTypeInfo( const TQString& mimeType ) -{ - return mimeTypeInfo( mimeType, TQString::null ); -} - -const KFileMimeTypeInfo * KFileMetaInfoProvider::mimeTypeInfo( const TQString& mimeType, const TQString& protocol ) -{ - //kdDebug(7033) << "mimeTypeInfo() : looking for plugin for protocol=" << protocol << " mimeType=" << mimeType << endl; - if ( !protocol.isEmpty() ) { - CachedPluginInfo *cache = m_plugins.find( protocol ); - if ( cache && cache->mimeTypeInfo ) { - return cache->mimeTypeInfo; - } - - if ( !cache ) { - loadAndRegisterPlugin( TQString::null, protocol ); - cache = m_plugins.find( protocol ); - if ( cache && cache->mimeTypeInfo ) { - return cache->mimeTypeInfo; - } - } - } - - CachedPluginInfo *cache = m_plugins.find( mimeType ); - if ( cache ) { - return cache->mimeTypeInfo; - } - - loadAndRegisterPlugin( mimeType, TQString::null ); - cache = m_plugins.find( mimeType ); - if ( cache ) { - return cache->mimeTypeInfo; - } - return 0; -} - -KFileMimeTypeInfo * KFileMetaInfoProvider::addMimeTypeInfo( - const TQString& mimeType ) -{ - - KFileMimeTypeInfo *info = m_pendingMimetypeInfos.find( mimeType ); - Q_ASSERT( !info ); - if ( !info ) - { - info = new KFileMimeTypeInfo( mimeType ); - m_pendingMimetypeInfos.insert( mimeType, info ); - } - - info->m_preferredKeys = preferredKeys( mimeType ); - info->m_preferredGroups = preferredGroups( mimeType ); - - return info; -} - -TQStringList KFileMetaInfoProvider::supportedMimeTypes() const -{ - TQStringList allMimeTypes; - TQString kfilePlugin = "KFilePlugin"; - - KTrader::OfferList offers = KTrader::self()->query( "KFilePlugin" ); - KTrader::OfferListIterator it = offers.begin(); - for ( ; it != offers.end(); ++it ) - { - const TQStringList mimeTypes = (*it)->serviceTypes(); - TQStringList::ConstIterator it2 = mimeTypes.begin(); - for ( ; it2 != mimeTypes.end(); ++it2 ) - if ( allMimeTypes.find( *it2 ) == allMimeTypes.end() && - *it2 != kfilePlugin ) // also in serviceTypes() - allMimeTypes.append( *it2 ); - } - - return allMimeTypes; -} - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - - -// shared data of a KFileMetaInfoGroup -class KFileMetaInfoGroup::Data : public TQShared -{ -public: - Data(const TQString& _name) - : TQShared(), - name(_name), - mimeTypeInfo(0L), - dirty( false ), - added( false ) - {} - - // we use this one for the streaming operators - Data() : mimeTypeInfo(0L) {} - ~Data() { - if ( this == null ) - delete mimeTypeInfo; - }; - - TQString name; - TQMap<TQString, KFileMetaInfoItem> items; - const KFileMimeTypeInfo* mimeTypeInfo; - TQStringList removedItems; - bool dirty :1; - bool added :1; - - static Data* null; - static Data* makeNull(); - -}; - -KFileMetaInfoGroup::KFileMetaInfoGroup( const TQString& name, - const KFileMimeTypeInfo* info ) - : d(new Data( name ) ) -{ - d->mimeTypeInfo = info; -} - -KFileMetaInfoGroup::KFileMetaInfoGroup( const KFileMetaInfoGroup& original ) -{ - // operator= does everything that's necessary - d = Data::makeNull(); - *this = original; -} - -KFileMetaInfoGroup::KFileMetaInfoGroup() -{ - d = Data::makeNull(); -} - -KFileMetaInfoGroup::~KFileMetaInfoGroup() -{ - deref(); -} - -const KFileMetaInfoGroup& KFileMetaInfoGroup::operator= (const KFileMetaInfoGroup& info ) -{ - if (d != info.d) - { - deref(); - // first deref the old one - d = info.d; - // and now ref the new one - ref(); - } - return *this; -} - -bool KFileMetaInfoGroup::isValid() const -{ - // We don't call makeNull here since it isn't necassery, see deref() - return d != Data::null; -} - -bool KFileMetaInfoGroup::isEmpty() const -{ - return d->items.isEmpty(); -} - -TQStringList KFileMetaInfoGroup::preferredKeys() const -{ - assert(isValid()); - TQStringList list = keys(); - TQStringList newlist; - TQStringList preferredKeys = d->mimeTypeInfo->preferredKeys(); - TQStringList::Iterator pref; - TQStringList::Iterator begin = preferredKeys.begin(); - TQStringList::Iterator end = preferredKeys.end(); - - // move all keys from the preferred keys that are in our list to a new list - for ( pref = begin; pref!=end; ++pref ) - { - TQStringList::Iterator item = list.find(*pref); - if ( item != list.end() ) - { - newlist.append( *item ); - list.remove(item); - } - } - - // now the old list only contains the non-preferred items, so we - // add the remaining ones to newlist - newlist += list; - - return newlist; -} - -TQStringList KFileMetaInfoGroup::keys() const -{ - if (d == Data::makeNull()) - kdWarning(7033) << "attempt to get the keys of " - "an invalid metainfo group"; - - TQStringList list; - - // make a TQStringList with all available keys - TQMapConstIterator<TQString, KFileMetaInfoItem> it; - for (it = d->items.begin(); it!=d->items.end(); ++it) - { - list.append(it.data().key()); -// kdDebug(7033) << "Item " << it.data().key() << endl; - } - return list; -} - -TQString KFileMetaInfoGroup::translatedName() const -{ - assert(isValid()); - return d->mimeTypeInfo->groupInfo(d->name)->translatedName(); -} - -TQStringList KFileMetaInfoGroup::supportedKeys() const -{ - assert(isValid()); - return d->mimeTypeInfo->groupInfo(d->name)->supportedKeys(); -} - -bool KFileMetaInfoGroup::supportsVariableKeys() const -{ - assert(isValid()); - return d->mimeTypeInfo->groupInfo(d->name)->supportsVariableKeys(); -} - -bool KFileMetaInfoGroup::contains( const TQString& key ) const -{ - return d->items.contains(key); -} - -KFileMetaInfoItem KFileMetaInfoGroup::item( const TQString& key) const -{ - TQMapIterator<TQString,KFileMetaInfoItem> it = d->items.find( key ); - if ( it != d->items.end() ) - return it.data(); - - return KFileMetaInfoItem(); -} - -KFileMetaInfoItem KFileMetaInfoGroup::item(uint hint) const -{ - TQMapIterator<TQString, KFileMetaInfoItem> it; - - for (it = d->items.begin(); it!=d->items.end(); ++it) - if (it.data().hint() == hint) - return it.data(); - - return KFileMetaInfoItem(); -} - -TQString KFileMetaInfoGroup::name() const -{ - return d->name; -} - -uint KFileMetaInfoGroup::attributes() const -{ - assert(isValid()); - return d->mimeTypeInfo->groupInfo(d->name)->attributes(); -} - -void KFileMetaInfoGroup::setAdded() -{ - d->added = true; -} - -bool KFileMetaInfoGroup::isModified() const -{ - return d->dirty; -} - -void KFileMetaInfoGroup::ref() -{ - if (d != Data::null) d->ref(); - -} - -void KFileMetaInfoGroup::deref() -{ - // We don't call makeNull here since it isn't necassery: - // If d is equal to null it means that null is initialized already. - // null is 0L when it hasn't been initialized and d is never 0L. - if ((d != Data::null) && d->deref()) - { -// kdDebug(7033) << "metainfo group " << d->name -// << " is finally deleted\n"; - delete d; - d = 0; - } - -} - -KFileMetaInfoItem KFileMetaInfoGroup::addItem( const TQString& key ) -{ - assert(isValid()); - TQMapIterator<TQString,KFileMetaInfoItem> it = d->items.find( key ); - if ( it != d->items.end() ) - return it.data(); - - const KFileMimeTypeInfo::GroupInfo* ginfo = d->mimeTypeInfo->groupInfo(d->name); - - if ( !ginfo ) { - Q_ASSERT( ginfo ); - return KFileMetaInfoItem(); - } - - const KFileMimeTypeInfo::ItemInfo* info = ginfo->itemInfo(key); - - if ( !info ) { - Q_ASSERT( info ); - return KFileMetaInfoItem(); - } - - KFileMetaInfoItem item; - - if (info->isVariableItem()) - item = KFileMetaInfoItem(ginfo->variableItemInfo(), key, TQVariant()); - else - item = KFileMetaInfoItem(info, key, TQVariant()); - - d->items.insert(key, item); - item.setAdded(); // mark as added - d->dirty = true; // mark ourself as dirty, too - return item; -} - -bool KFileMetaInfoGroup::removeItem( const TQString& key ) -{ - if (!isValid()) - { - kdDebug(7033) << "trying to remove an item from an invalid group\n"; - return false; - } - - TQMapIterator<TQString, KFileMetaInfoItem> it = d->items.find(key); - if ( it==d->items.end() ) - { - kdDebug(7033) << "trying to remove the non existant item " << key << "\n"; - return false; - } - - if (!((*it).attributes() & KFileMimeTypeInfo::Removable)) - { - kdDebug(7033) << "trying to remove a non removable item\n"; - return false; - } - - (*it).setRemoved(); - d->items.remove(it); - d->removedItems.append(key); - d->dirty = true; - return true; -} - -TQStringList KFileMetaInfoGroup::removedItems() -{ - return d->removedItems; -} - -KFileMetaInfoItem KFileMetaInfoGroup::appendItem(const TQString& key, - const TQVariant& value) -{ - //KDE4 enforce (value.type() == d->mimeTypeInfo->type()) - assert(isValid()); - const KFileMimeTypeInfo::GroupInfo* ginfo = d->mimeTypeInfo->groupInfo(d->name); - if ( !ginfo ) { - kdWarning() << "Trying to append a Metadata item for a non-existant group:" << d->name << endl; - return KFileMetaInfoItem(); - } - const KFileMimeTypeInfo::ItemInfo* info = ginfo->itemInfo(key); - if ( !info ) { - kdWarning() << "Trying to append a Metadata item for an unknown key (no ItemInfo): " << key << endl; - return KFileMetaInfoItem(); - } - - KFileMetaInfoItem item; - - if (info->key().isNull()) - item = KFileMetaInfoItem(ginfo->variableItemInfo(), key, value); - else - item = KFileMetaInfoItem(info, key, value); - - kdDebug(7033) << "KFileMetaInfogroup inserting a " << key << endl; - - d->items.insert(key, item); - return item; -} - -KFileMetaInfoGroup::Data* KFileMetaInfoGroup::Data::null = 0L; -static KStaticDeleter<KFileMetaInfoGroup::Data> sd_KFileMetaInfoGroupData; - -KFileMetaInfoGroup::Data* KFileMetaInfoGroup::Data::makeNull() -{ - if (!null) - { - // We deliberately do not reset "null" after it has been destroyed! - // Otherwise we will run into problems later in ~KFileMetaInfoItem - // where the d-pointer is compared against null. - null = new Data(TQString::null); - null->mimeTypeInfo = new KFileMimeTypeInfo(); - sd_KFileMetaInfoGroupData.setObject( null ); - } - return null; -} - - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - -KFileMimeTypeInfo::KFileMimeTypeInfo( const TQString& mimeType ) - : m_mimeType( mimeType ) -{ - m_groups.setAutoDelete( true ); -} - -KFileMimeTypeInfo::~KFileMimeTypeInfo() -{ -} - -const KFileMimeTypeInfo::GroupInfo * KFileMimeTypeInfo::groupInfo( const TQString& group ) const -{ - return m_groups.find( group ); -} - -KFileMimeTypeInfo::GroupInfo * KFileMimeTypeInfo::addGroupInfo( - const TQString& name, const TQString& translatedName ) -{ - GroupInfo* group = new GroupInfo( name, translatedName ); - m_groups.insert(name, group); - return group; -} - -TQStringList KFileMimeTypeInfo::supportedGroups() const -{ - TQStringList list; - TQDictIterator<GroupInfo> it( m_groups ); - for ( ; it.current(); ++it ) - list.append( it.current()->name() ); - - return list; -} - -TQStringList KFileMimeTypeInfo::translatedGroups() const -{ - TQStringList list; - TQDictIterator<GroupInfo> it( m_groups ); - for ( ; it.current(); ++it ) - list.append( it.current()->translatedName() ); - - return list; -} - -TQStringList KFileMimeTypeInfo::supportedKeys() const -{ - // not really efficient, but not those are not large lists, probably. - // maybe cache the result? - TQStringList keys; - TQStringList::ConstIterator lit; - TQDictIterator<GroupInfo> it( m_groups ); - for ( ; it.current(); ++it ) { // need to nuke dupes - TQStringList list = it.current()->supportedKeys(); - for ( lit = list.begin(); lit != list.end(); ++lit ) { - if ( keys.find( *lit ) == keys.end() ) - keys.append( *lit ); - } - } - - return keys; -} - -TQValidator * KFileMimeTypeInfo::createValidator(const TQString& group, - const TQString& key, - TQObject *parent, - const char *name) const -{ - KFilePlugin* plugin = KFileMetaInfoProvider::self()->plugin(m_mimeType); - if (plugin) return plugin->createValidator(mimeType(), group, key, - parent, name); - return 0; -} - - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - -KFileMimeTypeInfo::GroupInfo::GroupInfo( const TQString& name, - const TQString& translatedName ) - : m_name( name ), - m_translatedName( translatedName ), - m_attr( 0 ), - m_variableItemInfo( 0 ) - -{ - m_itemDict.setAutoDelete( true ); -} - -KFileMimeTypeInfo::GroupInfo::~GroupInfo() -{ - delete m_variableItemInfo; -} - -const KFileMimeTypeInfo::ItemInfo * KFileMimeTypeInfo::GroupInfo::itemInfo( const TQString& key ) const -{ - ItemInfo* item = m_itemDict.find( key ); - - // if we the item isn't found and variable keys are supported, we need to - // return the default variable key iteminfo. - if (!item && m_variableItemInfo) - { - return m_variableItemInfo; - } - return item; -} - -KFileMimeTypeInfo::ItemInfo* KFileMimeTypeInfo::GroupInfo::addItemInfo( - const TQString& key, const TQString& translatedKey, - TQVariant::Type type) -{ -// kdDebug(7034) << key << "(" << translatedKey << ") -> " << TQVariant::typeToName(type) << endl; - - ItemInfo* item = new ItemInfo(key, translatedKey, type); - m_supportedKeys.append(key); - m_itemDict.insert(key, item); - return item; -} - - -void KFileMimeTypeInfo::GroupInfo::addVariableInfo( TQVariant::Type type, - uint attr ) -{ - // just make sure that it's not already there - delete m_variableItemInfo; - m_variableItemInfo = new ItemInfo(TQString::null, TQString::null, type); - m_variableItemInfo->m_attr = attr; -} - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - -TQString KFileMimeTypeInfo::ItemInfo::string(const TQVariant& value, bool mangle) const -{ - TQString s; - - switch (value.type()) - { - case TQVariant::Invalid : - return "---"; - - case TQVariant::Bool : - s = value.toBool() ? i18n("Yes") : i18n("No"); - break; - - case TQVariant::Int : - if (unit() == KFileMimeTypeInfo::Seconds) - { - int seconds = value.toInt() % 60; - int minutes = value.toInt() / 60 % 60; - int hours = value.toInt() / 3600; - s = hours ? TQString().sprintf("%d:%02d:%02d",hours, minutes, seconds) - : TQString().sprintf("%02d:%02d", minutes, seconds); - return s; // no suffix wanted - } - else if (unit() == KFileMimeTypeInfo::Bytes) - { - // convertSize already adds the correct suffix - return TDEIO::convertSize(value.toInt()); - } - else if (unit() == KFileMimeTypeInfo::KiloBytes) - { - // convertSizeFromKB already adds the correct suffix - return TDEIO::convertSizeFromKB(value.toInt()); - } - else - s = TDEGlobal::locale()->formatNumber( value.toInt() , 0); - break; - - case TQVariant::LongLong : - s = TDEGlobal::locale()->formatNumber( value.toLongLong(), 0 ); - break; - - case TQVariant::ULongLong : - if ( unit() == KFileMimeTypeInfo::Bytes ) - return TDEIO::convertSize( value.toULongLong() ); - else if ( unit() == KFileMimeTypeInfo::KiloBytes ) - return TDEIO::convertSizeFromKB( value.toULongLong() ); - else - s = TDEGlobal::locale()->formatNumber( value.toULongLong(), 0 ); - break; - - case TQVariant::UInt : - s = TDEGlobal::locale()->formatNumber( value.toUInt() , 0); - break; - - case TQVariant::Double : - s = TDEGlobal::locale()->formatNumber( value.toDouble(), 3); - break; - - case TQVariant::Date : - s = TDEGlobal::locale()->formatDate( value.toDate(), true ); - break; - - case TQVariant::Time : - s = TDEGlobal::locale()->formatTime( value.toTime(), true ); - break; - - case TQVariant::DateTime : - s = TDEGlobal::locale()->formatDateTime( value.toDateTime(), - true, true ); - break; - - case TQVariant::Size : - s = TQString("%1 x %2").arg(value.toSize().width()) - .arg(value.toSize().height()); - break; - - case TQVariant::Point : - s = TQString("%1/%2").arg(value.toSize().width()) - .arg(value.toSize().height()); - break; - - default: - s = value.toString(); - } - - if (mangle && !s.isNull()) - { - s.prepend(prefix()); - s.append(" " + suffix()); - } - return s; -} - - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - - - -// stream operators - -/* serialization of a KFileMetaInfoItem: - first a bool that says if the items is valid, and if yes, - all the elements of the Data -*/ -TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoItem& item ) -{ - - KFileMetaInfoItem::Data* d = item.d; - - // if the object is invalid, put only a char in the stream - bool isValid = item.isValid(); - s << isValid; - // ### what do about mimetypeInfo ? - if (isValid) - s << d->key - << d->value - << d->dirty - << d->added - << d->removed; - - return s; -} - - -TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoItem& item ) -{ - bool isValid; - s >> isValid; - - if (!isValid) - { - item = KFileMetaInfoItem(); - return s; - } - - // we need a new object for our data - item.deref(); - item.d = new KFileMetaInfoItem::Data(); - - // ### what do about mimetypeInfo ? - bool dirty, added, removed; - s >> item.d->key - >> item.d->value - >> dirty - >> added - >> removed; - item.d->dirty = dirty; - item.d->added = added; - item.d->removed = removed; - - return s; -} - - -// serialization of a KFileMetaInfoGroup -// we serialize the name of the mimetype here instead of the mimetype info -// on the other side, we can simply use this to ask the provider for the info -TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoGroup& group ) -{ - KFileMetaInfoGroup::Data* d = group.d; - - // if the object is invalid, put only a byte in the stream - bool isValid = group.isValid(); - - s << isValid; - if (isValid) - { - s << d->name - << d->items - << d->mimeTypeInfo->mimeType(); - } - return s; -} - -TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& group ) -{ - TQString mimeType; - bool isValid; - s >> isValid; - - // if it's invalid, there is not much to do - if (!isValid) - { - group = KFileMetaInfoGroup(); - return s; - } - - // we need a new object for our data - group.deref(); - group.d = new KFileMetaInfoGroup::Data(); - - s >> group.d->name - >> group.d->items - >> mimeType; - - group.d->mimeTypeInfo = KFileMetaInfoProvider::self()->mimeTypeInfo(mimeType); - - // we need to set the item info for the items here - TQMapIterator<TQString, KFileMetaInfoItem> it = group.d->items.begin(); - for ( ; it != group.d->items.end(); ++it) - { - (*it).d->mimeTypeInfo = group.d->mimeTypeInfo->groupInfo(group.d->name) - ->itemInfo((*it).key()); - } - - return s; -} - -// serialization of a KFileMetaInfo object -// we serialize the name of the mimetype here instead of the mimetype info -// on the other side, we can simply use this to ask the provider for the info -TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfo& info ) -{ - KFileMetaInfo::Data* d = info.d; - - // if the object is invalid, put only a byte that tells this - bool isValid = info.isValid(); - - s << isValid; - if (isValid) - { - s << d->url - << d->what - << d->groups - << d->mimeTypeInfo->mimeType(); - } - return s; -} - -TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfo& info ) -{ - TQString mimeType; - bool isValid; - s >> isValid; - - // if it's invalid, there is not much to do - if (!isValid) - { - info = KFileMetaInfo(); - return s; - } - - // we need a new object for our data - info.deref(); - info.d = new KFileMetaInfo::Data(); - - s >> info.d->url - >> info.d->what - >> info.d->groups - >> mimeType; - info.d->mimeTypeInfo = KFileMetaInfoProvider::self()->mimeTypeInfo(mimeType); - - return s; -} - -#include "kfilemetainfo.moc" diff --git a/kio/kio/kfilemetainfo.h b/kio/kio/kfilemetainfo.h deleted file mode 100644 index ea843a5f3..000000000 --- a/kio/kio/kfilemetainfo.h +++ /dev/null @@ -1,1738 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2001-2002 Rolf Magnus <ramagnus@kde.org> - * Copyright (C) 2001-2002 Carsten Pfeiffer <pfeiffer@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation version 2.0. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -#ifndef KILEMETAINFO_H -#define KILEMETAINFO_H - -/* Hack for HPUX: Namespace pollution - m_unit is a define in <sys/sysmacros.h> */ -#define m_unit outouftheway_m_unit - -#include <tqdict.h> -#include <tqvariant.h> -#include <tqobject.h> -#include <tqstring.h> -#include <kurl.h> - -#undef m_unit - -class TQValidator; -class KFilePlugin; -class KFileMetaInfoGroup; - -/** - * @brief Represents the capabilities of a KFilePlugin for a given mimetype - * - * This class provides information about the capabilities that a - * KFilePlugin for a given mimetype has. It includes a list of metainfo - * groups and items together with their type, a prefix, suffix and some other - * information about how to use, display or edit the items. - * - * @author Rolf Magnus - * @author Carsten Pfeiffer - */ -class TDEIO_EXPORT KFileMimeTypeInfo -{ - // the plugin needs to be a friend because it puts the data into the object, - // and it should be the only one allowed to do this. - friend class KFilePlugin; - friend class KFileMetaInfoProvider; - -public: - KFileMimeTypeInfo() {} - - /** - * This enum is used to specify some attributes that an item can have, - * which fit neither in the Hint nor in the Unit enum. - */ - enum Attributes - { - Addable = 1, ///< The item or group can be added by a user - Removable = 2, ///< It can be removed - Modifiable = 4, ///< The value can be edited (no meaning for a group) - Cumulative = 8, /**< If an application wants to display information - for more than one file, it may add up the values - for this item (e.g. play time of an mp3 file) */ - Cummulative = Cumulative, ///< @deprecated Use Cumulative instead - Averaged = 16, /**< Similar to Cumulative, but the average should - be calculated instead of the sum */ - MultiLine = 32, /**< This attribute says that a string item is likely - to be more than one line long, so for editing, a - widget capable for multline text should be used - @since 3.1 */ - SqueezeText = 64 /**< If the text for this item is very long, it - should be squeezed to the size of the widget - where it's displayed - @since 3.1 */ - }; - - /** - * This enum is mainly for items that have a special meaning for some - * applications. - */ - enum Hint { - NoHint = 0, ///< No hint - Name = 1, ///< The name or title of the document - Author = 2, ///< The one who created the contents of it - Description = 3, ///< Description Some information about the document - Width = 4, ///< The width in pixels - Height = 5, ///< The height in pixels - Size = 6, ///< The size in pixels (width and height) - Bitrate = 7, ///< For media files - Length = 8, ///< The length of the file, also for media files - Hidden = 9, ///< The item is usually not shown to the user - Thumbnail = 10 ///< The item is a thumbnail picture of the file - - }; - - /** - * This enum exists so that you can specify units for items, which you - * can usually use for integer items, so an application knows how to - * display it (e.g. a time in seconds in a hh:mm:ss form). You can either - * use one of those units, or if you don't find one that fits, you can - * add it yourself using a prefix and/or suffix. - */ - enum Unit { - NoUnit = 0, ///< None of the listed units - Seconds = 1, ///< The item represents a time in seconds - MilliSeconds = 2, ///< The item represents a time in milliseconds - BitsPerSecond = 3, ///< A bit rate - Pixels = 4, ///< For image dimensions and similar - Inches = 5, ///< Sizes - Centimeters = 6, ///< Sizes - Bytes = 7, ///< Some data/file size in bytes - FramesPerSecond = 8, ///< A frame rate @since 3.1 - DotsPerInch = 9, ///< Resolution in DPI @since 3.1 - BitsPerPixel = 10, ///< A bit depth @since 3.1 - Hertz = 11, ///< Sample rates and similar @since 3.1 - KiloBytes = 12, ///< Some data/file size in kilobytes @since 3.1 - Millimeters = 13 ///< Sizes @since 3.3 - }; - - - class ItemInfo; - - /** - * @brief Information about a meta information group - * - * This is the class for one group of items of a KFileMimeTypeInfo. - * It contains, among other things, the information about the group's name - * and a list of supported items. - */ - class TDEIO_EXPORT GroupInfo - { - - friend class KFilePlugin; - friend class KFileMimeTypeInfo; - public: - /** - * Use this method to get a list of keys in the specified group that - * the plugin knows about. No variable keys. - * For a group that doesn't support variable keys, all keys that this - * group may have are returned. For a group that does support them, the - * non-variable ones are returned. See KFileMetaInfo about variable - * keys - * - * @return the list of keys supported for this mimetype - **/ - TQStringList supportedKeys() const - { - return m_supportedKeys; - } - - /** - * Use this method to get the name of the group. This string doesn't - * depend on the user's locale settings - * - * @return the group name - */ - const TQString& name() const - { - return m_name; - } - - /** - * Use this method to get the string to display to the user as group - * name. This may be different to name() and it returns the - * name in the user's language - * - * @return the translated group name - */ - const TQString& translatedName() const - { - return m_translatedName; - } - - /** - * A group object can contain several item objects (of which you can - * get the names with supportedKeys() . With this method, you can - * get one of those item objects. See ItemInfo - * - * @return a pointer to the item info. Don't delete this object! - */ - const ItemInfo * itemInfo( const TQString& key ) const; - - /** - * Get the attributes of this group (see Attributes) - * - * @return the attributes - */ - uint attributes() const - { - return m_attr; - } - - /** - * @return true if this group supports adding or removing arbitrary - * keys, false if not. - **/ - bool supportsVariableKeys() const - { - return m_variableItemInfo; - } - - /** - * If the group supports variable keys, you can query their item - * info with this method. The main reason for this is that you can - * get the type and attributes of variable keys. - * - * @return a pointer to the item info. Don't delete this object! - **/ - const ItemInfo* variableItemInfo( ) const - { - return m_variableItemInfo; - } - - /** @internal */ - ~GroupInfo(); - private: - /** @internal */ - GroupInfo( const TQString& name, const TQString& translatedName); - - /** @internal */ - KFileMimeTypeInfo::ItemInfo* addItemInfo( const TQString& key, - const TQString& translatedKey, - TQVariant::Type type); - - /** @internal */ - void addVariableInfo( TQVariant::Type type, uint attr ); - - TQString m_name; - TQString m_translatedName; - TQStringList m_supportedKeys; - uint m_attr; - ItemInfo* m_variableItemInfo; - TQDict<ItemInfo> m_itemDict; - - }; - - /** - * This is the class for one item of a KFileMimeTypeInfo. - * It contains every information about a KFileMetaInfoItem that this - * item has in common for each file of a specific mimetype. - **/ - class TDEIO_EXPORT ItemInfo - { - friend class KFilePlugin; - friend class GroupInfo; - public: - /** @internal */ - ItemInfo() {} // ### should be private? - - /** - * - * This method returns a translated prefix to be displayed before the - * value. Think e.g. of the $ in $30 - * - * @return the prefix - */ - const TQString& prefix() const - { - return m_prefix; - } - - /** - * This method returns a translated suffix to be displayed after the - * value. Think of the kbps in 128kbps - * - * @return the prefix - */ - const TQString& suffix() const - { - return m_suffix; - } - - /** - * The items for a file are stored as a TQVariant and this method - * can be used to get the data type of this item. - * - * @return the TQVariant type - */ - TQVariant::Type type() const - { - return m_type; - } - - /** - * Returns the name of the item. - * @return the name of the item - */ - const TQString& key() const - { - return m_key; - } - - /** - * Returns a string for the specified @p value, if possible. If not, - * TQString::null is returned. This can be used by programs if they want - * to display a sum or an average of some item for a list of files. - * - * @param value the value to convert - * @param mangle if true, the string will already contain prefix and - * suffix - * @return the converted string, or TQString::null if not possible - * @since 3.1 - */ - TQString string( const TQVariant& value, bool mangle = true ) const; - - /** - * Is this item the variable item? - * - * @return true if it is, false if not - */ - bool isVariableItem() const - { - // every valid item is supposed to have a non-null key - return key().isNull(); - } - - /** - * Returns a translation of the key for displaying to the user. If the - * plugin provides translation to the key, it's also in the user's - * language. - * @return the translated key - */ - const TQString& translatedKey() const - { - return m_translatedKey; - } - - /** - * Return the attributes of the item. See - * KFileMimeTypeInfo::Attributes. - * @return the attributes - */ - uint attributes() const - { - return m_attr; - } - - /** - * Return the hints for the item. See - * KFileMimeTypeInfo::Hint - * @return the hint - */ - uint hint() const - { - return m_hint; - } - - /** - * Return the unit of the item. See - * KFileMimeTypeInfo::Unit - * @return the unit - */ - uint unit() const - { - return m_unit; - } - - private: - /** @internal */ - ItemInfo(const TQString& key, const TQString& translatedKey, - TQVariant::Type type) - : m_key(key), m_translatedKey(translatedKey), - m_type(type), - m_attr(0), m_unit(NoUnit), m_hint(NoHint), - m_prefix(TQString::null), m_suffix(TQString::null) - {} - - TQString m_key; - TQString m_translatedKey; - TQVariant::Type m_type; - uint m_attr; - uint m_unit; - uint m_hint; - TQString m_prefix; - TQString m_suffix; - }; - - // ### could it be made private? Would this be BC? - ~KFileMimeTypeInfo(); - - /** - * Creates a validator for this item. Make sure to supply a proper - * @p parent argument or delete the validator yourself. - * - * @param group the group of the item - * @param key the key of the item - * @param parent the parent of the TQObject, or 0 for a parent-less object - * @param name the name of the TQObject, can be 0 - * @return the validator. You are responsible for deleting it. 0 if - * creation failed - */ - TQValidator * createValidator(const TQString& group, const TQString& key, - TQObject *parent = 0, const char *name = 0) const; - - /** - * Returns the list of all groups that the plugin for this mimetype - * supports. - * - * @return the list of groups - */ - TQStringList supportedGroups() const; - - /** - * Same as the above function, but returns the strings to display to the - * user. - * - * @return the list of groups - */ - TQStringList translatedGroups() const; - - /** - * This returns the list of groups in the preferred order that's specified - * in the .desktop file. - * - * @return the list of groups - */ - TQStringList preferredGroups() const - { - return m_preferredGroups; - } - - /** - * Returns the mimetype to which this info belongs. - * - * @return the mimetype of this info - */ - TQString mimeType() const {return m_mimeType;} - - /** - * Get the group info for a specific group. - * - * @param group the group whose group info should be retrieved - * @return a pointer to the info. 0 if it does not - * exist. Don't delete this object! - */ - const GroupInfo * groupInfo( const TQString& group ) const; - - // always returning stringlists which the user has to iterate and use them - // to look up the real items sounds strange to me. I think we should add - // our own iterators some time (somewhere in the future ;) - - /** - * Return a list of all supported keys without looking for a specific - * group - * - * @return the list of keys - */ - TQStringList supportedKeys() const; - - /** - * Return a list of all supported keys in preference order - * - * @return the list of keys - */ - TQStringList preferredKeys() const - { - return m_preferredKeys; - } - - // ### shouldn't this be private? BC? - GroupInfo * addGroupInfo( const TQString& name, - const TQString& translatedName); - - TQString m_translatedName; - TQStringList m_supportedKeys; - uint m_attr; - // bool m_supportsVariableKeys : 1; - TQDict<ItemInfo> m_itemDict; - -// ### this should be made private instead, but this would be BIC -protected: - /** @internal */ - KFileMimeTypeInfo( const TQString& mimeType ); - - TQDict<GroupInfo> m_groups; - TQString m_mimeType; - TQStringList m_preferredKeys; // same as KFileMetaInfoProvider::preferredKeys() - TQStringList m_preferredGroups; // same as KFileMetaInfoProvider::preferredKeys() -}; - - -/** - * @brief A meta information item about a file - * - * This is one item of the meta information about a file (see - * KFileMetaInfo). - */ -class TDEIO_EXPORT KFileMetaInfoItem -{ -public: - class Data; - typedef KFileMimeTypeInfo::Hint Hint; - typedef KFileMimeTypeInfo::Unit Unit; - typedef KFileMimeTypeInfo::Attributes Attributes; - - /** - * @internal - * You usually don't need to use this constructor yourself. Let - * KFileMetaInfo do it for you. - **/ - // ### hmm, then it should be private - KFileMetaInfoItem( const KFileMimeTypeInfo::ItemInfo* mti, - const TQString& key, const TQVariant& value); - - /** - * Copy constructor - **/ - KFileMetaInfoItem( const KFileMetaInfoItem & item ); - - /** - * The assignment operator, so you can do: - * @code - * KFileMetaInfoItem item = info.item("Title"); - * @endcode - * - * This will create a shared copy of the object. The actual data - * is automatically deleted if all copies go out of scope - **/ - const KFileMetaInfoItem& operator= (const KFileMetaInfoItem & item ); - - /** - * Default constructor. This creates an "invalid" item - */ - KFileMetaInfoItem(); - - ~KFileMetaInfoItem(); - - /** - * Returns the key of the item. - * - * @return the key of this item - */ - TQString key() const; - - /** - * Returns a translation of the key for displaying to the user. If the - * plugin provides translation to the key, it's also in the user's language - * - * @return the translated key - */ - TQString translatedKey() const; - - /** - * Returns the value of the item. - * - * @return the value of the item. - */ - const TQVariant& value() const; - - /** - * Returns a string containing the value, if possible. If not, - * TQString::null is returned. - * - * @param mangle if true, the string will already contain prefix and - * suffix - * @return the value string, or TQString::null if not possible - */ - TQString string( bool mangle = true ) const; - - /** - * Changes the value of the item. - * - * @param value the new value - * @return true if successful, false otherwise - */ - bool setValue( const TQVariant& value ); - - /** - * Return the type of the item. - * - * @return the type of the item - */ - TQVariant::Type type() const; - - /** - * You can query if the application can edit the item and write it back to - * the file with this method. - * - * @note This doesn't ensure that you have write access to the file and - * that enough space is available. - * - * @return true if the item's value can be changed, false if not - */ - bool isEditable() const; - - /** - * If you remove an item, it is only marked for removal for the file. On - * the next KFileMetaInfo::applyChanges() , it will be removed from - * the file. With this method, you can ask if the item is marked for - * removal. - * - * @return true if the item was removed, false if not - */ - bool isRemoved() const; - - /** - * If you change an item, it is marked as "dirty". On the next - * KFileMetaInfo::applyChanges() , the change will be written to the - * file. With this method, you can ask if this item is dirty. - * - * @return true if the item contains changes that have not yet been written - * back into the file. Removing or adding an item counts as such a change - */ - bool isModified() const; - - /** - * This method returns a translated prefix to be displayed before the - * value. Think e.g. of the $ in $30 - * - * @return the prefix - */ - TQString prefix() const; - - /** - * This method returns a translated suffix to be displayed after the - * value. Think of the kbps in 128kbps - * - * @return the suffix - */ - TQString suffix() const; - - /** - * Returns the hint for this item. See KFileMimeTypeInfo::Hint. - * - * @return the hint - **/ - uint hint() const; - - /** - * Returns the unit for this item. See KFileMimeTypeInfo::Unit. - * - * @return the unit - * @since 3.2 - **/ - uint unit() const; - - /** - * Returns the attributes for this item. See - * KFileMimeTypeInfo::Attributes. - * - * @return the attributes - **/ - uint attributes() const; - - /** - * Return true if the item is valid, i.e. if it contains data, false - * if it's invalid (created with the default constructor and not been - * assigned anything), or if KFileMetaInfoGroup::item() didn't find - * your requested item). - * - * @return true if valid, false if invalid - */ - bool isValid() const; - - TDEIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoItem& ); - TDEIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& ); - TDEIO_EXPORT friend TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoItem& ); - friend class KFileMetaInfoGroup; - -protected: - void setAdded(); - void setRemoved(); - - void ref(); - void deref(); - - Data *d; -}; - -/** - * @brief A group of meta information items about a file - * - * This is one group of meta information items about a file (see - * KFileMetaInfo). - */ -class TDEIO_EXPORT KFileMetaInfoGroup -{ - friend class KFilePlugin; - friend class KFileMetaInfo; - TDEIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& ); - TDEIO_EXPORT friend TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoGroup& ); - -public: - class Data; - /** - * @internal - * You usually don't need to use this constructor yourself. Let - * KFileMetaInfo do it for you. - **/ - // ### hmm, then it should be private - KFileMetaInfoGroup( const TQString& name, const KFileMimeTypeInfo* info ); - - /** - * Copy constructor - **/ - KFileMetaInfoGroup( const KFileMetaInfoGroup& original ); - - /** - * The assignment operator, so you can do: - * @code - * KFileMetaInfoGroup group = info.group("Technical"); - * @endcode - * - * This will create a shared copy of the object. The actual data - * is automatically deleted if all copies go out of scope - **/ - const KFileMetaInfoGroup& operator= (const KFileMetaInfoGroup& info ); - - /** - * Default constructor. This creates an "invalid" item - * - * @since 3.1 - */ - KFileMetaInfoGroup(); - - ~KFileMetaInfoGroup(); - - /** - * Returns true if the item is valid, i.e. if it contains data, false - * if it's invalid (created with the default constructor and not been - * assigned anything), or if KFileMetaInfoGroup::item() didn't find - * your requested item). - * - * @return true if valid, false if invalid - */ - bool isValid() const; - - /** - * Returns false if the object contains data, true if it's empty. An - * empty group is a group with no items (amazing, isn't it?). - * - * @return true if empty, false otherwise - */ - bool isEmpty() const; - - /** - * Returns true if an item as added or removed from the group. - * - * @return true if an item was added or removed from the group, otherwise - * false. - * - * @since 3.1 - */ - bool isModified() const; - - /** - * Operator for convenience. It does the same as item(), - * but you cannot specify a group to search in - */ - KFileMetaInfoItem operator[]( const TQString& key ) const - { return item( key ); } - - /** - * This method searches for the specified item. - * - * @param key the key of the item to search - * @return the specified item if found, an invalid item, if not - **/ - KFileMetaInfoItem item( const TQString& key ) const; - - /** - * Returns the item with the given @p hint. - * - * @param hint the hint of the item - * @return the item with the specified @p hint - **/ - KFileMetaInfoItem item( uint hint ) const; - - /** - * Convenience function. Returns the value of the specified key. - * It does the same as item(key).value(). - * - * @param key the key of the item to search - * @return the value with the given key - */ - const TQVariant value( const TQString& key ) const - { - const KFileMetaInfoItem &i = item( key ); - return i.value(); - } - - /** - * Use this method to get a list of keys in the specified group that - * the plugin knows about. No variable keys. - * For a group that doesn't support variable keys, all keys that this - * group may have are returned. For a group that does support them, the - * non-variable ones are returned. See KFileMetaInfo about variable - * keys - * - * @return the list of keys supported for this mimetype - **/ - TQStringList supportedKeys() const; - - /** - * Returns true if this group supports adding or removing arbitrary - * keys, false if not. - * - * @return true is variable keys are supported, false otherwise - **/ - bool supportsVariableKeys() const; - - /** - * Checks whether an item with the given @p key exists. - * - * @return true if an item for this @p key exists. - */ - bool contains( const TQString& key ) const; - - /** - * Returns a list of all keys. - * - * @return a list of all keys in the order they were inserted. - **/ - TQStringList keys() const; - - /** - * Returns a list of all keys in preference order. - * - * @return a list of all keys in preference order. - **/ - TQStringList preferredKeys() const; - - /** - * @return the list of possible types that the value for the specified key - * can be. You can use this to determine the possible types for new - * keys before you add them. - * - **/ - // ### do we really want to support that? - // let's not waste time on thinking about it. Let's just kick it for now - // and add it in 4.0 if needed ;) -// const TQMemArray<TQVariant::Type>& types( const TQString& key ) const; - - /** - * Add an item to the info. This is only possible if the specified @p key - * is in the supportedKeys list and not yet defined or if - * the group supports variable keys. - * - * @param key the key of the item - * @return the KFileMetaInfoItem for the given @p key - **/ - KFileMetaInfoItem addItem( const TQString& key ); - - /** - * Remove this item from the meta info of the file. You cannot query - * KFileMetaInfo for a removed object, but you can query for a list of - * removed items with removedItems() if you need to. - * If you re-add it, its value will be cleared. - * - * @param key the key of the removed item - * @return true if successful, false otherwise - */ - bool removeItem(const TQString& key); - - /** - * Returns a list of all removed items. - * - * @return a list of all removed items - */ - TQStringList removedItems(); - - /** - * The name of this group. - * - * @return the name of this group - */ - TQString name() const; - - /** - * The translated name of this group. - * - * @return the translated name of this group - * - * @since 3.2 - */ - TQString translatedName() const; - - /** - * Returns the attributes of this item. - * - * @return the attributes - */ - uint attributes() const; - -protected: - void setAdded(); - KFileMetaInfoItem appendItem( const TQString& key, const TQVariant& value); - - Data* d; - void ref(); - void deref(); - -}; - - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - - -/** - * @brief Meta Information about a file - * - * This is the class for objects that hold meta information about a file. - * The information is kept in form of a system of key/value pairs. See also - * KFileMetaInfoItem. - * This information is retrieved from the file through a plugin system, and - * this class is the main interface to it. - * If you want to write your own plugin, have a look at KFilePlugin. - * There are basically two different kinds of meta information: Fixed ones - * that the plugin knows about (e.g. an mp3 id3v1 tag has a well defined - * fixed list of fields), and variable keys that exist in mimetypes that - * support their own key/value system (comments in png files are of this type). - * Almost every file has fixed keys, but some also have variable keys. - * - * The groups and the What enum are not yet supported, but already added to - * the interface so that adding support doesn't break compatibility. - */ -class TDEIO_EXPORT KFileMetaInfo -{ -public: - typedef KFileMimeTypeInfo::Hint Hint; - typedef KFileMimeTypeInfo::Unit Unit; - typedef KFileMimeTypeInfo::Attributes Attributes; - class Data; - - /** - * This is used to specify what a KFileMetaInfo object should read, so - * you can specify if you want to read "expensive" items or not. - */ - enum What - { - Fastest = 0x1, /**< do the fastest possible read and omit all items - that might need a significantly longer time - than the others */ - DontCare = 0x2, ///< let the plugin decide what to read - - TechnicalInfo = 0x4, /**< extract technical details about the file, like - e.g. play time, resolution or a compressioni - type */ - ContentInfo = 0x8, /**< read information about the content of the file, - like comments or id3 tags */ - ExtenedAttr = 0x10, /**< read filesystem based extended attributes if - they are supported for the filesystem */ - Thumbnail = 0x20, /**< only read the file's thumbnail, if it contains - one */ - Preferred = 0x40, ///< get at least the preferred items - Everything = 0xffff ///< read everything, even if it might take a while - - }; - - /** - * The constructor. - * - * creating a KFileMetaInfo item through this will autoload the plugin - * belonging to the mimetype and try to get meta information about - * the specified file. - * - * If no info is available, you'll get an empty (not invalid) object. - * You can test for it with the isEmpty() method. - * - * @param path The file name. This must be the path to a local file. - * @param mimeType The name of the file's mimetype. If ommited, the - * mimetype is autodetected - * @param what one or more of the What enum values. It gives some - * hint to the plugin what information is desired. The plugin - * may still return more items. - * - * @note This version will @b only work for @b local (file:/) files. - * - **/ - KFileMetaInfo( const TQString& path, - const TQString& mimeType = TQString::null, - uint what = Fastest); - - /** - * Another constructor - * - * Similar to the above, but takes a URL so that meta-data may be retrieved - * over other protocols (ftp, etc.) - * - **/ - KFileMetaInfo( const KURL& url, - const TQString& mimeType = TQString::null, - uint what = Fastest); - - /** - * Default constructor. This will create an invalid object (see - * isValid(). - **/ - KFileMetaInfo(); - - /** - * Copy constructor. This creates a copy of the original object, but - * that copy will point to the same data, so if you change the original, - * the copy will be changed, too. After all, they are referring to the same - * file. - **/ - KFileMetaInfo( const KFileMetaInfo& original); - - ~KFileMetaInfo(); - - /** - * The assignment operator, so you can do e.g.: - * @code - * KFileMetaInfo info; - * if (something) info = KFileMetaInfo("/the/file"); - * @endcode - * - * This will create a shared copy of the object. The actual data - * is automatically deleted if all copies go out of scope. - **/ - const KFileMetaInfo& operator= (const KFileMetaInfo& info ); - - - /** - * Returns a list of all groups. - * - * @return the keys of the groups that the file has. - */ - TQStringList groups() const; - - /** - * Returns a list of all supported groups. - * - * @return the supported keys of the groups that the file has. - */ - TQStringList supportedGroups() const; - - /** - * Returns a list of the preferred groups. - * - * @return the keys of the preferred groups that the file has. - */ - TQStringList preferredGroups() const; - - /** - * Returns a list of all preferred keys. - * - * @return a list of all preferred keys. - */ - TQStringList preferredKeys() const; - - /** - * Returns a list of supported keys. - * - * @return a list of supported keys - */ - TQStringList supportedKeys() const; - - /** - * Returns the list of groups that you can add or remove from the file. - * - * @return the groups can be added or removed - */ - TQStringList editableGroups() const; - - // I'd like to keep those for lookup without group, at least the hint - // version - /** - * Returns the KFileMetaInfoItem with the given @p key. - * - * @param key the key of the item - * @return the item. Invalid if there is no item with the given @p key. - */ - KFileMetaInfoItem item(const TQString& key) const; - /** - * Returns the KFileMetaInfoItem with the given @p hint. - * - * @param hint the hint of the item - * @return the item. Invalid if there is no item with the given @p hint. - */ - KFileMetaInfoItem item(const KFileMetaInfoItem::Hint hint) const; - - /** - * Saves the item with the given @p key. - * - * @param key the key of the item - * @param preferredGroup the preferred group, or TQString::null - * @param createGroup true to create the group if necessary - * @return the saved item - */ - KFileMetaInfoItem saveItem( const TQString& key, - const TQString& preferredGroup = TQString::null, - bool createGroup = true ); - - /** - * Returns the KFileMetaInfoGroup with the given @p key. - * - * @param key the key of the item - * @return the group. Invalid if there is no group with the given @p key. - */ - KFileMetaInfoGroup group(const TQString& key) const; - - /** - * Returns the KFileMetaInfoGroup with the given @p key. - * - * @param key the key of the item - * @return the group. Invalid if there is no group with the given @p key. - */ - KFileMetaInfoGroup operator[] (const TQString& key) const - { - return group(key); - } - - /** - * Try to add the specified group. This will only succeed if it is - * in the list of editableGroups(). - * - * @note that all non-variable items that belong to this group are - * automatically added as empty item. - * - * @param name the name of the group to add - * @return true if successful, false if not - */ - bool addGroup( const TQString& name ); - - /** - * Remove the specified group. This will only succeed if it is - * in the list of editableGroups(). Beware that this also - * removes all the items in that group, so always ask the user - * before removing it! - * - * @param name the name of the group to remove - * @return true if successful, false if not - */ - bool removeGroup( const TQString& name ); - - /** - * Returns a list of removed groups. - * - * @return a list of removed groups. - */ - TQStringList removedGroups(); - - /** - * This method writes all pending changes of the meta info back to the file. - * If any items are marked as removed, they are really removed from the - * list. The info object as well as all items are updated. - * - * @return true if successful, false if not - */ - bool applyChanges(); - - /** - * This method writes all pending changes of the meta info to the file @p path. - * If any items are marked as removed, they are really removed from the - * list. The info object as well as all items are updated. - * - * @return true if successful, false if not - */ - bool applyChanges(const TQString& path); - - /** - * Checks whether an item with the given @p key exists. - * - * @param key the key to check - * @return whether an item for this @p key exists. - */ - bool contains( const TQString& key ) const; - - /** - * Checks whether a group with the given @p key exists. - * - * @param key the key to check - * @return whether a group with this name exists. - */ - bool containsGroup( const TQString& key ) const; - - /** - * Returns the value with the given @p key. - * - * @param key the key to retrieve - * @return the value. Invalid if it does not exist - */ - const TQVariant value( const TQString& key ) const - { - return item(key).value(); - } - - - /** - * Returns true if the item is valid, i.e. if actually represents the info - * about a file, false if the object is uninitialized. - * - * @return true if valid, false otherwise - */ - bool isValid() const; - - /** - * Returns false if the object contains data, true if it's empty. You'll - * get an empty object if no plugin for the file could be found. - * - * @return true if empty, false otherwise - */ - bool isEmpty() const; - - /** - * Returns the mime type of file. - * - * @return the file's mime type - */ - TQString mimeType() const; - - /** - * Returns the path of file - or TQString::null if file is non-local - * - * @return the file's path - or TQString::null if file is non-local - */ - TQString path() const; - - /** - * Returns the url of file - * - * @return the file's url - */ - KURL url() const; - - TDEIO_EXPORT friend TQDataStream& operator >>(TQDataStream& s, KFileMetaInfo& ); - TDEIO_EXPORT friend TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfo& ); - friend class KFilePlugin; - -protected: - KFileMetaInfoGroup appendGroup(const TQString& name); - - /** - * @return a pointer to the plugin that belogs to this object's mimetype. - * It will be auto-loaded if it's currently not loaded - **/ - KFilePlugin * plugin() const; - - void ref(); - void deref(); - - Data* d; - -private: - KFileMetaInfoItem findEditableItem( KFileMetaInfoGroup& group, - const TQString& key ); - - void init( const KURL& url, - const TQString& mimeType = TQString::null, - uint what = Fastest); -}; - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - - -/** - * @brief Base class for a meta information plugin - * - * Meta information plugins are used to extract useful information from files - * of a given type. These plugins are used in Konqueror's file properties - * dialog, for example. - * - * If you want to write your own plugin, you need to derive from this class. - * - * In the constructor of your class, you need to call addMimeTypeInfo() to tell - * the KFile framework which mimetype(s) your plugin supports. For each - * mimetype, use the addGroupInfo() and addItemInfo() methods to declare the - * meta information items the plugin calculates and to group them accordingly. - * For groups, use setAttributes() to customize your group (see - * KFileMimeTypeInfo::Attributes). For items, use setAttributes() to define the - * behaviour of the item; use setHint() to define the meaning of the item; use - * setUnit() to define the Unit, such as KFileMimeTypeInfo::Seconds or - * KFileMimeTypeInfo::KiloBytes. In short, the constructor defines the data - * structure of the meta information supported by your plugin. - * - * Example: - * @code - * FooPlugin::FooPlugin(TQObject *parent, const char *name, - * const TQStringList &args) - * : KFilePlugin(parent, name, args) - * { - * KFileMimeTypeInfo* info = addMimeTypeInfo( "application/x-foo" ); - * - * // our new group - * KFileMimeTypeInfo::GroupInfo* group = 0L; - * group = addGroupInfo(info, "FooInfo", i18n("Foo Information")); - * - * KFileMimeTypeInfo::ItemInfo* item; - * - * // our new items in the group - * item = addItemInfo(group, "Items", i18n("Items"), TQVariant::Int); - * item = addItemInfo(group, "Size", i18n("Size"), TQVariant::Int); - * setUnit(item, KFileMimeTypeInfo::KiloBytes); - * - * // strings are possible, too: - * //addItemInfo(group, "Document Type", i18n("Document type"), TQVariant::String); - * } - * @endcode - * - * Some meta information items are likely to be available in several different - * file formats, such as @c "Author", @c "Title" (for documents), and - * @c "Length" (for multimedia files). Be sure to use the naming scheme from - * existing plugins for your meta information items if possible. If, for - * example, the meta information of a group of files is shown in a table view, - * this will allow two files to share the same column (say "Length") even if - * they are of a different file type. - * - * You must overwrite the readInfo() method. In this method you need to extract - * the meta information of the given file. You can use a third-party library to - * achieve this task. This might be the best way for binary files, since a - * change in the file format is likely to be supported by subsequent releases - * of that library. Alternatively, for text-based file formats, you can use - * TQTextStream to parse the file. For simple file formats, TQRegExp can be of - * great help, too. - * - * After you extracted the relevant information, use appendGroup() and - * appendItem() to fill the meta information data structure (as defined in the - * constructor) with values. Note that you can leave out groups or items - * which are not appropriate for a particular file. - * - * Example: - * @code - * bool FooPlugin::readInfo( KFileMetaInfo& info, uint what) - * { - * int numItems = 0; - * int size = 0; - * - * // do your calculations here, e.g. using a third-party - * // library or by writing an own parser using e.g. QTextStream - * - * // calculate numItems and size ... - * - * // note: use the same key strings as in the constructor - * KFileMetaInfoGroup group = appendGroup(info, "FooInfo"); - * - * appendItem(group, "Items", numItems); - * appendItem(group, "Size", size); - * - * return true; - * } - * @endcode - * - * If you want to define mutable meta information items, you need to overwrite - * the writeInfo() method. In this method, you can use third-party library - * (appropriate mostly for binary files, see above) or TQTextStream to write the - * information back to the file. If you use TQTextStream, be sure to write all - * file contents back. - * - * For some items, it might be that not all possible values are allowed. You - * can overwrite the createValidator() method to define constraints for a meta - * information item. For example, the @c "Year" field for an MP3 file could - * reject values outside the range 1500 - 2050 (at least for now). The - * validator is used to check values before the writeInfo() method is called so - * that writeInfo() is only provided correct values. - * - * In your plugin, you need to create a factory for the KFilePlugin - * - * Example: - * @code - * typedef KGenericFactory<FooPlugin> FooFactory; - * K_EXPORT_COMPONENT_FACTORY(kfile_foo, FooFactory("kfile_foo")); - * @endcode - * - * To make your plugin available within KDE, you also need to provide a - * @c .desktop file which describes your plugin. The required fields in the - * file are: - * - * - @c Type: must be @c "Service" - * - @c Name: the name of the plugin - * - @c ServiceTypes: must contain @c "KFilePlugin" - * - @c X-TDE-Library: the name of the library containing the KFile plugin - * - @c MimeType: the mimetype(s) which are supported by the plugin - * - @c PreferredGroups: a comma-separated list of the most important groups. - * This list defines the order in which the meta information groups should be - * displayed - * - @c PreferredItems: a comma-separated list of the most important items. - * This list defines the order in which the meta information items should be - * displayed - * - * Example: - * @code - * [Desktop Entry] - * Encoding=UTF-8 - * Type=Service - * Name=Foo Info - * ServiceTypes=KFilePlugin - * X-TDE-Library=kfile_foo - * MimeType=application/x-foo - * PreferredGroups=FooInfo - * PreferredItems=Items,Size - * @endcode - **/ -class TDEIO_EXPORT KFilePlugin : public TQObject -{ - Q_OBJECT - -public: - /** - * Creates a new KFilePlugin instance. You need to implement a constructor - * with the same argument list as this is required by KGenericFactory - * - * @param parent the parent of the TQObject, can be @c 0 - * @param name the name of the TQObject, can be @c 0 - * @param args currently ignored - * - * @see addMimeTypeInfo() - * @see addGroupInfo() - * @see addItemInfo() - * @see TQObject() - **/ - KFilePlugin( TQObject *parent, const char *name, - const TQStringList& args ); - - /** - * Destructor - */ - virtual ~KFilePlugin(); - - /** - * Read the info from the file in this method and insert it into the - * provided KFileMetaInfo object. You can get the path to the file with - * KFileMetaInfo::path(). Use appendGroup() and appendItem() to fill - * @p info with the extracted values - * - * @param info the information will be written here - * @param what defines what to read, see KFileMetaInfo::What - * @return @c true if successful, @c false if it failed - * - * @see writeInfo() - **/ - virtual bool readInfo( KFileMetaInfo& info, - uint what = KFileMetaInfo::Fastest ) = 0; - - /** - * Similar to the readInfo() but for writing the info back to the file. - * If you don't have any writable keys, don't implement this method - * - * @param info the information that will be written - * @return @c true if successful, @c false if it failed - **/ - virtual bool writeInfo( const KFileMetaInfo& info ) const - { - Q_UNUSED(info); - return true; - } - - /** - * This method should create an appropriate validator for the specified - * item if it's editable or return a null pointer if not. If you don't have - * any editable items, you don't need to implement this method. - * - * If you you don't need any validation, e.g. you accept any input, you can - * simply return @c 0L, or not reimplement this method at all. - * - * @param mimeType the mime type - * @param group the group name of the validator item - * @param key the key name of the validator item - * @param parent the TQObject parent, can be @c 0 - * @param name the name of the TQObject, can be @c 0 - **/ - virtual TQValidator* createValidator( const TQString& mimeType, - const TQString& group, - const TQString& key, - TQObject* parent, - const char* name) const - { - Q_UNUSED(mimeType); Q_UNUSED(group);Q_UNUSED(key); - Q_UNUSED(parent);Q_UNUSED(name); - return 0; - } - -protected: - - /** - * Call this from within your constructor to tell the KFile framework what - * mimetypes your plugin supports. - * - * @param mimeType a string containing the mimetype, e.g. @c "text/html" - * @return a KFileMimeTypeInfo object, to be used with addGroupInfo() - **/ - KFileMimeTypeInfo * addMimeTypeInfo( const TQString& mimeType ); - // ### do we need this, if it only calls the provider? - // IMHO the Plugin shouldn't call its provider. - // DF: yes we need this. A plugin can create more than one mimetypeinfo. - // What sucks though, is to let plugins do that in their ctor. - // Would be much simpler to have a virtual init method for that, - // so that the provider can set up stuff with the plugin pointer first! - - /** - * Creates a meta information group for KFileMimeTypeInfo object returned - * by addMimeTypeInfo(). - * - * @param info the object returned by addMimeTypeInfo() - * @param key a unique string identifiing this group. For simplicity it is - * recommended to use the same string as for the translatedKey - * parameter - * @param translatedKey the translated version of the key string for - * displaying in user interfaces. Use i18n() to translate the string - * @return a GroupInfo object. Pass this object to addItemInfo to add meta - * information attributed to this group. - * - * @see setAttributes() - * @see addItemInfo() - **/ - KFileMimeTypeInfo::GroupInfo* addGroupInfo(KFileMimeTypeInfo* info, - const TQString& key, const TQString& translatedKey) const; - - /** - * Sets attributes of the GroupInfo object returned by addGroupInfo(). - * - * @param gi the object returned by addGroupInfo() - * @param attr the attributes for this group; these are values of type - * KFileMimeTypeInfo::Attributes, or'ed together - **/ - void setAttributes(KFileMimeTypeInfo::GroupInfo* gi, uint attr) const; - - void addVariableInfo(KFileMimeTypeInfo::GroupInfo* gi, TQVariant::Type type, - uint attr) const; - - /** - * Adds a meta information item to a GroupInfo object as returned by - * addGroupInfo(). - * - * @param gi the GroupInfo object to add a new item to - * @param key a unique string to identify this item. For simplicity it is - * recommended to use the same string as for the translatedKey - * parameter - * @param translatedKey the translated version of the key string for - * displaying in user interfaces. Use i18n() to translate the string - * @param type the type of the meta information item, e.g. TQVariant::Int - * or TQVariant::String. - * @return an ItemInfo object. Pass this object to setAttributes() - **/ - KFileMimeTypeInfo::ItemInfo* addItemInfo(KFileMimeTypeInfo::GroupInfo* gi, - const TQString& key, - const TQString& translatedKey, - TQVariant::Type type); - - /** - * Sets some attributes for a meta information item. The attributes - * describe if the item is mutable, how it should be computed for a list of - * files, and how it should be displayed - * - * @param item the ItemInfo object as returned by addItemInfo() - * @param attr the attributes for this item; these are values of type - * KFileMimeTypeInfo::Attributes, or'ed together - **/ - void setAttributes(KFileMimeTypeInfo::ItemInfo* item, uint attr); - - /** - * Defines the meaning of the meta information item. Some applications make - * use of this information, so be sure to check KFileMimeTypeInfo::Hint to - * see if an item's meaning is in the list. - * - * @param item the ItemInfo object as returned by addItemInfo() - * @param hint the item's meaning. See KFileMimeTypeInfo::Hint for a list - * of available meanings - **/ - void setHint(KFileMimeTypeInfo::ItemInfo* item, uint hint); - - /** - * Sets the unit used in the meta information item. This unit is used to - * format the value and to make large values human-readable. For example, - * if the item's unit is KFileMimeTypeInfo::Seconds and the value is 276, - * it will be displayed as 4:36. - * - * @param item the ItemInfo object as returned by addItemInfo() - * @param unit the item's unit. See KFileMimeTypeInfo::Unit for a list of - * available units - **/ - void setUnit(KFileMimeTypeInfo::ItemInfo* item, uint unit); - - /** - * Sets a prefix string which is displayed before the item's value. Use - * this string if no predefined unit fits the item's unit. Be sure to - * translate the string with i18n() - * - * @param item the ItemInfo object as returned by addItemInfo() - * @param prefix the prefix string to display - **/ - void setPrefix(KFileMimeTypeInfo::ItemInfo* item, const TQString& prefix); - - /** - * Sets a suffix string which is displayed before the item's value. Use - * this string if no predefined unit fits the item's unit. Be sure to - * translate the string with i18n() - * - * @param item the ItemInfo object as returned by addItemInfo() - * @param suffix the suffix string to display - **/ - void setSuffix(KFileMimeTypeInfo::ItemInfo* item, const TQString& suffix); - - /** - * Call this method from within readInfo() to indicate that you wish to - * fill meta information items of the group identified by @p key with - * values. - * - * @param info the KFileMetaInfo object. Use the parameter of the - * readInfo() method - * @param key the key string to identify the group. Use the string that you - * defined in your class' constructor - * @return a KFileMetaInfoGroup object, to be used in appendItem() - **/ - KFileMetaInfoGroup appendGroup(KFileMetaInfo& info, const TQString& key); - - /** - * Call this method from within readInfo() to fill the meta information item - * identified by @p key with a @p value - * - * @param group the KFileMetaInfoGroup object, as returned by appendGroup() - * @param key the key string to identify the item. - * @param value the value of the meta information item - **/ - void appendItem(KFileMetaInfoGroup& group, const TQString& key, TQVariant value); - - TQStringList m_preferredKeys; - TQStringList m_preferredGroups; - -protected: - /** - * Helper method to allow binary compatible extensions when needing - * "new virtual methods" - * - * @param id the identifier of the new "virtual" method - * @param data any parameter data the new "virtual" method needs - */ - virtual void virtual_hook( int id, void* data ); -private: - class KFilePluginPrivate; - KFilePluginPrivate *d; -}; - -/////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////// - - -/** - * @internal - * Synchronous access to metadata of a local file. Usually, you don't want - * to use this class for getting metainfo from a file. Use KFileMetaInfo - * directly. However, if you want to find out if a specific mimetype is - * supported and which groups and items are provided for it, you can ask - * the KFileMetainfoProvider for it. - **/ -class TDEIO_EXPORT KFileMetaInfoProvider: private QObject -{ - friend class KFilePlugin; - - Q_OBJECT -public: - virtual ~KFileMetaInfoProvider(); - - static KFileMetaInfoProvider * self(); - - /** - * @return a pointer to the plugin that belongs to the specified mimetype, - * which means also load the plugin if it's not in memory - */ - KFilePlugin * plugin( const TQString& mimeType ); // KDE4: merge with method below - - /** - * @return a pointer to the plugin that belongs to the specified mimetype, - * for the given protocol. - * This loads the plugin if it's not in memory yet. - */ - KFilePlugin * plugin( const TQString& mimeType, const TQString& protocol ); - - const KFileMimeTypeInfo * mimeTypeInfo( const TQString& mimeType ); // KDE4: merge with below - const KFileMimeTypeInfo * mimeTypeInfo( const TQString& mimeType, const TQString& protocol ); - - TQStringList preferredKeys( const TQString& mimeType ) const; - TQStringList preferredGroups( const TQString& mimeType ) const; - - /// @since 3.1 - TQStringList supportedMimeTypes() const; - -protected: // ## should be private, right? - KFileMetaInfoProvider(); - -private: - - // Data structure: - // Mimetype or Protocol -> { Plugin and MimeTypeInfo } - // The {} struct is CachedPluginInfo - struct CachedPluginInfo - { - CachedPluginInfo() : plugin( 0 ), mimeTypeInfo( 0 ), ownsPlugin( false ) {} - CachedPluginInfo( KFilePlugin* p, KFileMimeTypeInfo* i, bool owns ) - : plugin( p ), mimeTypeInfo( i ), ownsPlugin( owns ) {} - // auto-delete behavior - ~CachedPluginInfo() { - if ( ownsPlugin ) delete plugin; - delete mimeTypeInfo; - } - - // If plugin and mimeTypeInfo are 0, means that no plugin is available. - KFilePlugin* plugin; - KFileMimeTypeInfo* mimeTypeInfo; - // The problem here is that plugin can be shared in multiple instances, - // so the memory management isn't easy. KDE4 solution: use KSharedPtr? - // For now we flag one copy of the KFilePlugin pointer as being "owned". - bool ownsPlugin; - }; - - // The key is either a mimetype or a protocol. Those things don't look the same - // so there's no need for two QDicts. - TQDict<CachedPluginInfo> m_plugins; - - // This data is aggregated during the creation of a plugin, - // before being moved to the appropriate CachedPluginInfo(s) - // At any other time than during the loading of a plugin, this dict is EMPTY. - // Same key as in m_plugins: mimetype or protocol - TQDict<KFileMimeTypeInfo> m_pendingMimetypeInfos; - -private: - static KFileMetaInfoProvider * s_self; - - KFilePlugin* loadPlugin( const TQString& mimeType, const TQString& protocol ); - KFilePlugin* loadAndRegisterPlugin( const TQString& mimeType, const TQString& protocol ); - KFileMimeTypeInfo * addMimeTypeInfo( const TQString& mimeType ); - - class KFileMetaInfoProviderPrivate; - KFileMetaInfoProviderPrivate *d; - -}; - -TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoItem& ); -TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoItem& ); - -TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfoGroup& ); -TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfoGroup& ); - -TDEIO_EXPORT TQDataStream& operator <<(TQDataStream& s, const KFileMetaInfo& ); -TDEIO_EXPORT TQDataStream& operator >>(TQDataStream& s, KFileMetaInfo& ); - - -#endif // KILEMETAINFO_H diff --git a/kio/kio/kfileshare.cpp b/kio/kio/kfileshare.cpp deleted file mode 100644 index bf8cdca1d..000000000 --- a/kio/kio/kfileshare.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2001 David Faure <david@mandrakesoft.com> - Copyright (c) 2001 Laurent Montel <lmontel@mandrakesoft.com> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kfileshare.h" -#include <tqdir.h> -#include <tqfile.h> -#include <tqregexp.h> -#include <kprocess.h> -#include <kprocio.h> -#include <klocale.h> -#include <kstaticdeleter.h> -#include <kstandarddirs.h> -#include <kdebug.h> -#include <kdirwatch.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <kdirnotify_stub.h> -#include <ksimpleconfig.h> -#include <kuser.h> - -KFileShare::Authorization KFileShare::s_authorization = NotInitialized; -//TQStringList* KFileShare::s_shareList = 0L; -//static KStaticDeleter<TQStringList> sdShareList; -TQMap<TQString,TQString>* KFileShare::s_shareMap = 0L; -static KStaticDeleter<TQMap<TQString,TQString> > sdShareMap; - -KFileShare::ShareMode KFileShare::s_shareMode; -bool KFileShare::s_sambaEnabled; -bool KFileShare::s_nfsEnabled; -bool KFileShare::s_restricted; -TQString KFileShare::s_fileShareGroup; -bool KFileShare::s_sharingEnabled; - - -#define FILESHARECONF "/etc/security/fileshare.conf" - -KFileSharePrivate::KFileSharePrivate() -{ - KDirWatch::self()->addFile(FILESHARECONF); - connect(KDirWatch::self(), TQT_SIGNAL(dirty (const TQString&)),this, - TQT_SLOT(slotFileChange(const TQString &))); - connect(KDirWatch::self(), TQT_SIGNAL(created(const TQString&)),this, - TQT_SLOT(slotFileChange(const TQString &))); - connect(KDirWatch::self(), TQT_SIGNAL(deleted(const TQString&)),this, - TQT_SLOT(slotFileChange(const TQString &))); -} - -KFileSharePrivate::~KFileSharePrivate() -{ - KDirWatch::self()->removeFile(FILESHARECONF); -} - -KFileSharePrivate *KFileSharePrivate::_self=0L; - -static KStaticDeleter<KFileSharePrivate> kstFileShare; - -KFileSharePrivate* KFileSharePrivate::self() -{ - if (!_self) - _self = kstFileShare.setObject(_self, new KFileSharePrivate()); - return _self; -} - -void KFileSharePrivate::slotFileChange(const TQString &file) -{ - if(file==FILESHARECONF) { - KFileShare::readConfig(); - KFileShare::readShareList(); - } -} - -void KFileShare::readConfig() // static -{ - // Create KFileSharePrivate instance - KFileSharePrivate::self(); - KSimpleConfig config(TQString::fromLatin1(FILESHARECONF),true); - - s_sharingEnabled = config.readEntry("FILESHARING", "yes") == "yes"; - s_restricted = config.readEntry("RESTRICT", "yes") == "yes"; - s_fileShareGroup = config.readEntry("FILESHAREGROUP", "fileshare"); - - - if (!s_sharingEnabled) - s_authorization = UserNotAllowed; - else - if (!s_restricted ) - s_authorization = Authorized; - else { - // check if current user is in fileshare group - KUserGroup shareGroup(s_fileShareGroup); - if (shareGroup.users().findIndex(KUser()) > -1 ) - s_authorization = Authorized; - else - s_authorization = UserNotAllowed; - } - - if (config.readEntry("SHARINGMODE", "simple") == "simple") - s_shareMode = Simple; - else - s_shareMode = Advanced; - - - s_sambaEnabled = config.readEntry("SAMBA", "yes") == "yes"; - s_nfsEnabled = config.readEntry("NFS", "yes") == "yes"; -} - -KFileShare::ShareMode KFileShare::shareMode() { - if ( s_authorization == NotInitialized ) - readConfig(); - - return s_shareMode; -} - -bool KFileShare::sharingEnabled() { - if ( s_authorization == NotInitialized ) - readConfig(); - - return s_sharingEnabled; -} - -bool KFileShare::isRestricted() { - if ( s_authorization == NotInitialized ) - readConfig(); - - return s_restricted; -} - -TQString KFileShare::fileShareGroup() { - if ( s_authorization == NotInitialized ) - readConfig(); - - return s_fileShareGroup; -} - - -bool KFileShare::sambaEnabled() { - if ( s_authorization == NotInitialized ) - readConfig(); - - return s_sambaEnabled; -} - -bool KFileShare::nfsEnabled() { - if ( s_authorization == NotInitialized ) - readConfig(); - - return s_nfsEnabled; -} - - -void KFileShare::readShareList() -{ - KFileSharePrivate::self(); - if ( !s_shareMap ) - sdShareMap.setObject( s_shareMap, new TQMap<TQString,TQString> ); - else - s_shareMap->clear(); - - // /usr/sbin on Mandrake, $PATH allows flexibility for other distributions - TQString exe = findExe( "filesharelist" ); - if (exe.isEmpty()) { - s_authorization = ErrorNotFound; - return; - } - KProcIO proc; - proc << exe; - if ( !proc.start( TDEProcess::Block ) ) { - kdError() << "Can't run " << exe << endl; - s_authorization = ErrorNotFound; - return; - } - - // Reading code shamelessly stolen from khostname.cpp ;) - TQString line; - TQString options; - TQString path; - int length; - TQRegExp rx_line("([^\\s]+)\\s+(.*)"); - do { - length = proc.readln(line, true); - if ( length > 0 ) - { - if ( line[length-1] != '/' ) - line += '/'; - if( rx_line.search( line ) != -1 ) { - options = rx_line.cap(1); - path = rx_line.cap(2); - (*s_shareMap)[path] = options; - } - kdDebug(7000) << "Shared dir:" << line << endl; - } - } while (length > -1); -} - - -int KFileShare::isDirectoryShared( const TQString& _path ) -{ - int ret(0); - - if ( ! s_shareMap ) - readShareList(); - - TQString path( _path ); - if ( path[path.length()-1] != '/' ) - path += '/'; - //return s_shareList && s_shareList->contains( path ); - if( (*s_shareMap).contains(path) && !((*s_shareMap)[path].isEmpty()) ) { - ret+=1; - if( (*s_shareMap)[path].find("readwrite") != -1 ) - ret+=2; - } - - return ret; -} - -KFileShare::Authorization KFileShare::authorization() -{ - // The app should do this on startup, but if it doesn't, let's do here. - if ( s_authorization == NotInitialized ) - readConfig(); - return s_authorization; -} - -TQString KFileShare::findExe( const char* exeName ) -{ - // /usr/sbin on Mandrake, $PATH allows flexibility for other distributions - TQString path = TQString::fromLocal8Bit(getenv("PATH")) + TQString::fromLatin1(":/usr/sbin"); - TQString exe = KStandardDirs::findExe( exeName, path ); - if (exe.isEmpty()) - kdError() << exeName << " not found in " << path << endl; - return exe; -} - -bool KFileShare::setShared( const TQString& path, bool shared ) -{ - return SuSEsetShared( path, shared, false ); -} - -bool KFileShare::SuSEsetShared( const TQString& path, bool shared, bool rw ) -{ - if (! KFileShare::sharingEnabled() || - KFileShare::shareMode() == Advanced) - return false; - - TQString exe = KFileShare::findExe( "fileshareset" ); - if (exe.isEmpty()) - return false; - - // we want to share, so we kick it first - just to be sure - TDEProcess proc; - proc << exe; - proc << "--remove"; - proc << path; - proc.start( TDEProcess::Block ); - proc.clearArguments(); - - proc << exe; - if( rw ) - proc << "--rw"; - if ( shared ) - proc << "--add"; - else - proc << "--remove"; - proc << path; - proc.start( TDEProcess::Block ); // should be ok, the perl script terminates fast - bool ok = proc.normalExit() && (proc.exitStatus() == 0); - kdDebug(7000) << "KFileSharePropsPlugin::setShared normalExit=" - << proc.normalExit() << endl; - kdDebug(7000) << "KFileSharePropsPlugin::setShared exitStatus=" - << proc.exitStatus() << endl; - if ( proc.normalExit() ) { - switch( proc.exitStatus() ) { - case 1: - // User is not authorized - break; - case 3: - // Called script with --add, but path was already shared before. - // Result is nevertheless what the client wanted, so - // this is alright. - ok = true; - break; - case 4: - // Invalid mount point - break; - case 5: - // Called script with --remove, but path was not shared before. - // Result is nevertheless what the client wanted, so - // this is alright. - ok = true; - break; - case 6: - // There is no export method - break; - case 7: - // file sharing is disabled - break; - case 8: - // advanced sharing is enabled - break; - case 255: - // Abitrary error - break; - } - } - - return ok; -} - -bool KFileShare::sambaActive() -{ - // rcsmb is not executable by users, try ourselves - int status = system( "/sbin/checkproc -p /var/run/samba/smbd.pid /usr/sbin/smbd" ); - return status != -1 && WIFEXITED( status ) && WEXITSTATUS( status ) == 0; -} - -bool KFileShare::nfsActive() -{ - // rcnfsserver is not executable by users, try ourselves - int status = system( "/sbin/checkproc /usr/sbin/rpc.mountd" ); - if( status != -1 && WIFEXITED( status ) && WEXITSTATUS( status ) == 0 ) - { - status = system( "/sbin/checkproc -n nfsd" ); - if( status != -1 && WIFEXITED( status ) && WEXITSTATUS( status ) == 0 ) - return true; - } - return false; -} - -#include "kfileshare.moc" diff --git a/kio/kio/kfileshare.h b/kio/kio/kfileshare.h deleted file mode 100644 index ff473c122..000000000 --- a/kio/kio/kfileshare.h +++ /dev/null @@ -1,165 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2001 David Faure <david@mandrakesoft.com> - Copyright (c) 2001 Laurent Montel <lmontel@mandrakesoft.com> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef kfileshare_h -#define kfileshare_h -#include <tqobject.h> - -#include <tdelibs_export.h> - -class KDirWatch; - -/** - * @internal - * Do not use, ever. - */ -class KFileSharePrivate : public TQObject -{ - Q_OBJECT - -public: - KFileSharePrivate(); - ~KFileSharePrivate(); - KDirWatch* m_watchFile; - static KFileSharePrivate *self(); - static KFileSharePrivate *_self; -protected slots: // this is why this class needs to be in the .h - void slotFileChange(const TQString &); -}; - -/** - * Common functionality for the file sharing - * (communication with the backend) - * @since 3.1 - */ -class TDEIO_EXPORT KFileShare -{ - - -public: - /** - * Reads the file share configuration file - */ - static void readConfig(); - - /** - * Reads the list of shared folders - */ - static void readShareList(); - - - /** - * Call this to know if a directory is currently shared - */ - static int isDirectoryShared( const TQString& path ); - - enum Authorization { NotInitialized, ErrorNotFound, Authorized, UserNotAllowed }; - /** - * Call this to know if the current user is authorized to share directories - */ - static Authorization authorization(); - - static TQString findExe( const char* exeName ); - - /** - * Uses a suid perl script to share the given path - * with NFS and Samba - * @param path the path to share - * @param shared whether the path should be shared or not - * @returns whether the perl script was successful - */ - static bool setShared( const TQString& path, bool shared ); - - /* - * SuSE only enhancement for now - */ - static bool SuSEsetShared( const TQString& path, bool shared, bool ro ); - - /** - * The used share mode. - * Simple means that the simple sharing dialog is used and - * users can share only folders from there HOME folder. - * Advanced means that the advanced sharing dialog is used and - * users can share any folder. - */ - enum ShareMode { Simple, Advanced }; - - /** - * Returns whether sharing is enabled - * If this is false, file sharing is disabled and - * nobody can share files. - */ - static bool sharingEnabled(); - - /** - * Returns whether file sharing is restricted. - * If it is not restricted every user can shar files. - * If it is restricted only users in the configured - * file share group can share files. - */ - static bool isRestricted(); - - /** - * Returns the group that is used for file sharing. - * That is, all users in that group are allowed to - * share files if file sharing is restricted. - */ - static TQString fileShareGroup(); - - /** - * Returns the configured share mode - */ - static ShareMode shareMode(); - - /** - * Returns whether Samba is enabled - */ - static bool sambaEnabled(); - - /** - * Returns whether NFS is enabled - */ - static bool nfsEnabled(); - - /** - * Returns whether Samba is active (service is running) - * @internal - */ - static bool sambaActive(); - - /** - * Returns whether NFS is active (service is running) - * @internal - */ - static bool nfsActive(); - -private: - static Authorization s_authorization; -// static TQStringList* s_shareList; - static TQMap<TQString,TQString>* s_shareMap; - static ShareMode s_shareMode; - static bool s_sambaEnabled; - static bool s_nfsEnabled; - static bool s_restricted; - static TQString s_fileShareGroup; - static bool s_sharingEnabled; - -}; - -#endif diff --git a/kio/kio/kfilterbase.cpp b/kio/kio/kfilterbase.cpp deleted file mode 100644 index f9250cfe9..000000000 --- a/kio/kio/kfilterbase.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kfilterbase.h" -#include <klibloader.h> -#include <kmimetype.h> -#include <ktrader.h> -#include <kdebug.h> - -KFilterBase::KFilterBase() - : m_dev( 0L ), m_bAutoDel( false ) -{ -} - -KFilterBase::~KFilterBase() -{ - if ( m_bAutoDel ) - delete m_dev; -} - -void KFilterBase::setDevice( TQIODevice * dev, bool autodelete ) -{ - m_dev = dev; - m_bAutoDel = autodelete; -} - -KFilterBase * KFilterBase::findFilterByFileName( const TQString & fileName ) -{ - KMimeType::Ptr mime = KMimeType::findByPath( fileName ); - kdDebug(7005) << "KFilterBase::findFilterByFileName mime=" << mime->name() << endl; - return findFilterByMimeType(mime->name()); -} - -KFilterBase * KFilterBase::findFilterByMimeType( const TQString & mimeType ) -{ - KTrader::OfferList offers = KTrader::self()->query( "TDECompressionFilter", - TQString("'") + mimeType + "' in ServiceTypes" ); - KTrader::OfferList::ConstIterator it = offers.begin(); - KTrader::OfferList::ConstIterator end = offers.end(); - - kdDebug(7005) << "KFilterBase::findFilterByMimeType(" << mimeType << ") got " << offers.count() << " offers" << endl; - for (; it != end; ++it ) - { - if ((*it)->library().isEmpty()) { continue; } - KLibFactory *factory = KLibLoader::self()->factory((*it)->library().latin1()); - if (!factory) { continue; } - KFilterBase *filter = static_cast<KFilterBase*>( factory->create(0, (*it)->desktopEntryName().latin1() ) ); - if ( filter ) - return filter; - } - - if ( mimeType == "application/x-bzip2" || mimeType == "application/x-gzip" ) // #88574 - kdWarning(7005) << "KFilterBase::findFilterByMimeType : no filter found for " << mimeType << endl; - - return 0L; -} - -void KFilterBase::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -#include "kfilterbase.moc" diff --git a/kio/kio/kfilterbase.h b/kio/kio/kfilterbase.h deleted file mode 100644 index 25613c101..000000000 --- a/kio/kio/kfilterbase.h +++ /dev/null @@ -1,116 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kfilterbase__h -#define __kfilterbase__h - -#include <tqobject.h> -#include <tqstring.h> - -#include <tdelibs_export.h> - -#ifdef Q_WS_WIN -#undef ERROR //avoid conflicts -#endif - -class TQIODevice; - -/** - * This is the base class for compression filters - * such as gzip and bzip2. It's pretty much internal. - * Don't use directly, use KFilterDev instead. - */ -class TDEIO_EXPORT KFilterBase : public TQObject // needs to inherit TQObject for KLibFactory::create -{ - Q_OBJECT -public: - KFilterBase(); - virtual ~KFilterBase(); - - /** - * Sets the device on which the filter will work - * @param dev the device on which the filter will work - * @param autodelete if true, @p dev is deleted when the filter is deleted - */ - void setDevice( TQIODevice * dev, bool autodelete = false ); - // Note that this isn't in the constructor, because of KLibFactory::create, - // but it should be called before using the filterbase ! - - /** - * Returns the device on which the filter will work. - * @returns the device on which the filter will work - */ - TQIODevice * device() { return m_dev; } - /** \internal */ - virtual void init( int mode ) = 0; - /** \internal */ - virtual int mode() const = 0; - /** \internal */ - virtual void terminate() {} - /** \internal */ - virtual void reset() {} - /** \internal */ - virtual bool readHeader() = 0; - /** \internal */ - virtual bool writeHeader( const TQCString & filename ) = 0; - /** \internal */ - virtual void setOutBuffer( char * data, uint maxlen ) = 0; - /** \internal */ - virtual void setInBuffer( const char * data, uint size ) = 0; - /** \internal */ - virtual bool inBufferEmpty() const { return inBufferAvailable() == 0; } - /** \internal */ - virtual int inBufferAvailable() const = 0; - /** \internal */ - virtual bool outBufferFull() const { return outBufferAvailable() == 0; } - /** \internal */ - virtual int outBufferAvailable() const = 0; - - /** \internal */ - enum Result { OK, END, ERROR }; - /** \internal */ - virtual Result uncompress() = 0; - /** \internal */ - virtual Result compress( bool finish ) = 0; - - /** - * Call this to create the appropriate filter for the file - * named @p fileName. - * @param fileName the name of the file to filter - * @return the filter for the @p fileName, or 0 if not found - */ - static KFilterBase * findFilterByFileName( const TQString & fileName ); - - /** - * Call this to create the appropriate filter for the mimetype - * @p mimeType. For instance application/x-gzip. - * @param mimeType the mime type of the file to filter - * @return the filter for the @p mimeType, or 0 if not found - */ - static KFilterBase * findFilterByMimeType( const TQString & mimeType ); - -protected: - TQIODevice * m_dev; - bool m_bAutoDel; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KFilterBasePrivate; -}; - -#endif diff --git a/kio/kio/kfilterdev.cpp b/kio/kio/kfilterdev.cpp deleted file mode 100644 index 87d54f5e3..000000000 --- a/kio/kio/kfilterdev.cpp +++ /dev/null @@ -1,484 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kfilterdev.h" -#include "kfilterbase.h" -#include <kdebug.h> -#include <stdio.h> // for EOF -#include <stdlib.h> -#include <assert.h> -#include <tqfile.h> - -#define BUFFER_SIZE 8*1024 - -class KFilterDev::KFilterDevPrivate -{ -public: - KFilterDevPrivate() : bNeedHeader(true), bSkipHeaders(false), - autoDeleteFilterBase(false), bOpenedUnderlyingDevice(false), - bIgnoreData(false){} - bool bNeedHeader; - bool bSkipHeaders; - bool autoDeleteFilterBase; - bool bOpenedUnderlyingDevice; - bool bIgnoreData; - TQByteArray buffer; // Used as 'input buffer' when reading, as 'output buffer' when writing - TQCString ungetchBuffer; - TQCString origFileName; - KFilterBase::Result result; -}; - -KFilterDev::KFilterDev( KFilterBase * _filter, bool autoDeleteFilterBase ) - : filter(_filter) -{ - assert(filter); - d = new KFilterDevPrivate; - d->autoDeleteFilterBase = autoDeleteFilterBase; -} - -KFilterDev::~KFilterDev() -{ - if ( isOpen() ) - close(); - if ( d->autoDeleteFilterBase ) - delete filter; - delete d; -} - -#ifndef KDE_NO_COMPAT -//this one is static -// Cumbersome API. To be removed in KDE 3.0. -TQIODevice* KFilterDev::createFilterDevice(KFilterBase* base, TQFile* file) -{ - if (file==0) - return 0; - - //we don't need a filter - if (base==0) - return TQT_TQIODEVICE(new TQFile(file->name())); // A bit strange IMHO. We ask for a TQFile but we create another one !?! (DF) - - base->setDevice(TQT_TQIODEVICE(file)); - return new KFilterDev(base); -} -#endif - -//static -TQIODevice * KFilterDev::deviceForFile( const TQString & fileName, const TQString & mimetype, - bool forceFilter ) -{ - TQFile * f = new TQFile( fileName ); - KFilterBase * base = mimetype.isEmpty() ? KFilterBase::findFilterByFileName( fileName ) - : KFilterBase::findFilterByMimeType( mimetype ); - if ( base ) - { - base->setDevice(TQT_TQIODEVICE(f), true); - return new KFilterDev(base, true); - } - if(!forceFilter) - return TQT_TQIODEVICE(f); - else - { - delete f; - return 0L; - } -} - -TQIODevice * KFilterDev::device( TQIODevice* inDevice, const TQString & mimetype) -{ - return device( inDevice, mimetype, true ); -} - -TQIODevice * KFilterDev::device( TQIODevice* inDevice, const TQString & mimetype, bool autoDeleteInDevice ) -{ - if (inDevice==0) - return 0; - KFilterBase * base = KFilterBase::findFilterByMimeType(mimetype); - if ( base ) - { - base->setDevice(inDevice, autoDeleteInDevice); - return new KFilterDev(base, true /* auto-delete "base" */); - } - return 0; -} - -bool KFilterDev::open( TQ_OpenMode mode ) -{ - //kdDebug(7005) << "KFilterDev::open " << mode << endl; - if ( mode == IO_ReadOnly ) - { - d->buffer.resize(0); - d->ungetchBuffer.resize(0); - } - else - { - d->buffer.resize( BUFFER_SIZE ); - filter->setOutBuffer( d->buffer.data(), d->buffer.size() ); - } - d->bNeedHeader = !d->bSkipHeaders; - filter->init( mode ); - d->bOpenedUnderlyingDevice = !filter->device()->isOpen(); - bool ret = d->bOpenedUnderlyingDevice ? filter->device()->open( (TQ_OpenMode)mode ) : true; - d->result = KFilterBase::OK; - - if ( !ret ) - kdWarning(7005) << "KFilterDev::open: Couldn't open underlying device" << endl; - else - { - setState( IO_Open ); - setMode( mode ); - } - TQIODevice::at(0); - return ret; -} - -void KFilterDev::close() -{ - if ( !isOpen() ) - return; - //kdDebug(7005) << "KFilterDev::close" << endl; - if ( filter->mode() == IO_WriteOnly ) - writeBlock( 0L, 0 ); // finish writing - //kdDebug(7005) << "KFilterDev::close. Calling terminate()." << endl; - - filter->terminate(); - if ( d->bOpenedUnderlyingDevice ) - filter->device()->close(); - - setState( 0 ); // not IO_Open -} - -void KFilterDev::flush() -{ - //kdDebug(7005) << "KFilterDev::flush" << endl; - filter->device()->flush(); - // Hmm, might not be enough... -} - -#ifdef USE_QT4 -qint64 KFilterDev::size() const -#else // USE_QT4 -TQIODevice::Offset KFilterDev::size() const -#endif // USE_QT4 -{ - // Well, hmm, Houston, we have a problem. - // We can't know the size of the uncompressed data - // before uncompressing it....... - - // But readAll, which is not virtual, needs the size......... - - kdWarning(7005) << "KFilterDev::size - can't be implemented !!!!!!!! Returning -1 " << endl; - //abort(); - return (uint)-1; -} - -TQIODevice::Offset KFilterDev::at() const -{ - return TQIODevice::at(); -} - -bool KFilterDev::at( TQIODevice::Offset pos ) -{ - //kdDebug(7005) << "KFilterDev::at " << pos << " currently at " << TQIODevice::at() << endl; - - if ( TQIODevice::at() == pos ) - return true; - - Q_ASSERT ( filter->mode() == IO_ReadOnly ); - - if ( pos == 0 ) - { - TQIODevice::at(0); - // We can forget about the cached data - d->ungetchBuffer.resize(0); - d->bNeedHeader = !d->bSkipHeaders; - d->result = KFilterBase::OK; - filter->setInBuffer(0L,0); - filter->reset(); - return filter->device()->reset(); - } - - if ( TQIODevice::at() < pos ) // we can start from here - pos = pos - TQIODevice::at(); - else - { - // we have to start from 0 ! Ugly and slow, but better than the previous - // solution (KTarGz was allocating everything into memory) - if (!at(0)) // sets ioIndex to 0 - return false; - } - - //kdDebug(7005) << "KFilterDev::at : reading " << pos << " dummy bytes" << endl; - TQByteArray dummy( TQMIN( pos, 3*BUFFER_SIZE ) ); - d->bIgnoreData = true; - bool result = ( (TQIODevice::Offset)readBlock( dummy.data(), pos ) == pos ); - d->bIgnoreData = false; - return result; -} - -bool KFilterDev::atEnd() const -{ - return filter->device()->atEnd() && (d->result == KFilterBase::END) - && d->ungetchBuffer.isEmpty(); -} - -TQT_TQIO_LONG KFilterDev::tqreadBlock( char *data, TQT_TQIO_ULONG maxlen ) -{ - Q_ASSERT ( filter->mode() == IO_ReadOnly ); - //kdDebug(7005) << "KFilterDev::readBlock maxlen=" << maxlen << endl; - - uint dataReceived = 0; - if ( !d->ungetchBuffer.isEmpty() ) - { - uint len = d->ungetchBuffer.length(); - if ( !d->bIgnoreData ) - { - while ( ( dataReceived < len ) && ( dataReceived < maxlen ) ) - { - *data = d->ungetchBuffer[ len - dataReceived - 1 ]; - data++; - dataReceived++; - } - } - else - { - dataReceived = TQMIN( len, maxlen ); - } - d->ungetchBuffer.truncate( len - dataReceived ); - TQIODevice::at(TQIODevice::at() + dataReceived); - } - - // If we came to the end of the stream - // return what we got from the ungetchBuffer. - if ( d->result == KFilterBase::END ) - return dataReceived; - - // If we had an error, return -1. - if ( d->result != KFilterBase::OK ) - return -1; - - - TQ_ULONG outBufferSize; - if ( d->bIgnoreData ) - { - outBufferSize = TQMIN( maxlen, 3*BUFFER_SIZE ); - } - else - { - outBufferSize = maxlen; - } - outBufferSize -= dataReceived; - TQ_ULONG availOut = outBufferSize; - filter->setOutBuffer( data, outBufferSize ); - - bool decompressedAll = false; - while ( dataReceived < maxlen ) - { - if (filter->inBufferEmpty()) - { - // Not sure about the best size to set there. - // For sure, it should be bigger than the header size (see comment in readHeader) - d->buffer.resize( BUFFER_SIZE ); - // Request data from underlying device - int size = filter->device()->readBlock( d->buffer.data(), - d->buffer.size() ); - if ( size ) - filter->setInBuffer( d->buffer.data(), size ); - else { - if ( decompressedAll ) - { - // We decoded everything there was to decode. So -> done. - //kdDebug(7005) << "Seems we're done. dataReceived=" << dataReceived << endl; - d->result = KFilterBase::END; - break; - } - } - //kdDebug(7005) << "KFilterDev::readBlock got " << size << " bytes from device" << endl; - } - if (d->bNeedHeader) - { - (void) filter->readHeader(); - d->bNeedHeader = false; - } - - d->result = filter->uncompress(); - - if (d->result == KFilterBase::ERROR) - { - kdWarning(7005) << "KFilterDev: Error when uncompressing data" << endl; - break; - } - - // We got that much data since the last time we went here - uint outReceived = availOut - filter->outBufferAvailable(); - //kdDebug(7005) << "avail_out = " << filter->outBufferAvailable() << " result=" << d->result << " outReceived=" << outReceived << endl; - if( availOut < (uint)filter->outBufferAvailable() ) - kdWarning(7005) << " last availOut " << availOut << " smaller than new avail_out=" << filter->outBufferAvailable() << " !" << endl; - - dataReceived += outReceived; - if ( !d->bIgnoreData ) // Move on in the output buffer - { - data += outReceived; - availOut = maxlen - dataReceived; - } - else if ( maxlen - dataReceived < outBufferSize ) - { - availOut = maxlen - dataReceived; - } - TQIODevice::at(TQIODevice::at() + outReceived); - if (d->result == KFilterBase::END) - { - //kdDebug(7005) << "KFilterDev::readBlock got END. dataReceived=" << dataReceived << endl; - break; // Finished. - } - if (filter->inBufferEmpty() && filter->outBufferAvailable() != 0 ) - { - decompressedAll = true; - } - filter->setOutBuffer( data, availOut ); - } - - return dataReceived; -} - -TQT_TQIO_LONG KFilterDev::tqwriteBlock( const char *data /*0 to finish*/, TQT_TQIO_ULONG len ) -{ - Q_ASSERT ( filter->mode() == IO_WriteOnly ); - // If we had an error, return 0. - if ( d->result != KFilterBase::OK ) - return 0; - - bool finish = (data == 0L); - if (!finish) - { - filter->setInBuffer( data, len ); - if (d->bNeedHeader) - { - (void)filter->writeHeader( d->origFileName ); - d->bNeedHeader = false; - } - } - - uint dataWritten = 0; - uint availIn = len; - while ( dataWritten < len || finish ) - { - - d->result = filter->compress( finish ); - - if (d->result == KFilterBase::ERROR) - { - kdWarning(7005) << "KFilterDev: Error when compressing data" << endl; - // What to do ? - break; - } - - // Wrote everything ? - if (filter->inBufferEmpty() || (d->result == KFilterBase::END)) - { - // We got that much data since the last time we went here - uint wrote = availIn - filter->inBufferAvailable(); - - //kdDebug(7005) << " Wrote everything for now. avail_in = " << filter->inBufferAvailable() << " result=" << d->result << " wrote=" << wrote << endl; - - // Move on in the input buffer - data += wrote; - dataWritten += wrote; - TQIODevice::at(TQIODevice::at() + wrote); - - availIn = len - dataWritten; - //kdDebug(7005) << " KFilterDev::writeBlock availIn=" << availIn << " dataWritten=" << dataWritten << " ioIndex=" << ioIndex << endl; - if ( availIn > 0 ) // Not sure this will ever happen - filter->setInBuffer( data, availIn ); - } - - if (filter->outBufferFull() || (d->result == KFilterBase::END)) - { - //kdDebug(7005) << " KFilterDev::writeBlock writing to underlying. avail_out=" << filter->outBufferAvailable() << endl; - int towrite = d->buffer.size() - filter->outBufferAvailable(); - if ( towrite > 0 ) - { - // Write compressed data to underlying device - int size = filter->device()->writeBlock( d->buffer.data(), towrite ); - if ( size != towrite ) { - kdWarning(7005) << "KFilterDev::writeBlock. Could only write " << size << " out of " << towrite << " bytes" << endl; - return 0; // indicate an error (happens on disk full) - } - //else - //kdDebug(7005) << " KFilterDev::writeBlock wrote " << size << " bytes" << endl; - } - d->buffer.resize( 8*1024 ); - filter->setOutBuffer( d->buffer.data(), d->buffer.size() ); - if (d->result == KFilterBase::END) - { - //kdDebug(7005) << " KFilterDev::writeBlock END" << endl; - Q_ASSERT(finish); // hopefully we don't get end before finishing - break; - } - } - } - - return dataWritten; -} - -int KFilterDev::getch() -{ - Q_ASSERT ( filter->mode() == IO_ReadOnly ); - //kdDebug(7005) << "KFilterDev::getch" << endl; - if ( !d->ungetchBuffer.isEmpty() ) { - int len = d->ungetchBuffer.length(); - int ch = d->ungetchBuffer[ len-1 ]; - d->ungetchBuffer.truncate( len - 1 ); - TQIODevice::at(TQIODevice::at() + 1); - //kdDebug(7005) << "KFilterDev::getch from ungetch: " << TQString(TQChar(ch)) << endl; - return ch; - } - char buf[1]; - int ret = readBlock( buf, 1 ) == 1 ? buf[0] : EOF; - //kdDebug(7005) << "KFilterDev::getch ret=" << TQString(TQChar(ret)) << endl; - return ret; -} - -int KFilterDev::putch( int c ) -{ - //kdDebug(7005) << "KFilterDev::putch" << endl; - char buf[1]; - buf[0] = c; - return writeBlock( buf, 1 ) == 1 ? c : -1; -} - -int KFilterDev::ungetch( int ch ) -{ - //kdDebug(7005) << "KFilterDev::ungetch " << TQString(TQChar(ch)) << endl; - if ( ch == EOF ) // cannot unget EOF - return ch; - - // pipe or similar => we cannot ungetch, so do it manually - d->ungetchBuffer +=ch; - TQIODevice::at(TQIODevice::at() - 1); - return ch; -} - -void KFilterDev::setOrigFileName( const TQCString & fileName ) -{ - d->origFileName = fileName; -} - -void KFilterDev::setSkipHeaders() -{ - d->bSkipHeaders = true; -} diff --git a/kio/kio/kfilterdev.h b/kio/kio/kfilterdev.h deleted file mode 100644 index 8dd0999a9..000000000 --- a/kio/kio/kfilterdev.h +++ /dev/null @@ -1,204 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __kfilterdev_h -#define __kfilterdev_h - -#include <tqiodevice.h> -#include <tqstring.h> -#include <tdelibs_export.h> - -class TQFile; -class KFilterBase; - -/** - * A class for reading and writing compressed data onto a device - * (e.g. file, but other usages are possible, like a buffer or a socket). - * - * To simply read/write compressed files, see deviceForFile. - * - * @author David Faure <faure@kde.org> - */ -class TDEIO_EXPORT KFilterDev : public TQIODevice -{ -public: - /** - * Constructs a KFilterDev for a given filter (e.g. gzip, bzip2 etc.). - * @param filter the KFilterBase to use - * @param autoDeleteFilterBase when true this object will become the - * owner of @p filter. - */ - KFilterDev( KFilterBase * filter, bool autoDeleteFilterBase = false ); - /** - * Destructs the KFilterDev. - * Calls close() if the filter device is still open. - */ - virtual ~KFilterDev(); - - /** - * Open for reading or writing. - * If the KFilterBase's device is not opened, it will be opened. - */ -#ifdef qdoc -#else - virtual bool open( TQ_OpenMode mode ); -#endif - /** - * Close after reading or writing. - * If the KFilterBase's device was opened by open(), it will be closed. - */ - virtual void close(); - virtual void flush(); - - /** - * For writing gzip compressed files only: - * set the name of the original file, to be used in the gzip header. - * @param fileName the name of the original file - */ - void setOrigFileName( const TQCString & fileName ); - - /** - * Call this let this device skip the gzip headers when reading/writing. - * This way KFilterDev (with gzip filter) can be used as a direct wrapper - * around zlib - this is used by KZip. - * @since 3.1 - */ - void setSkipHeaders(); - - // Not implemented -#ifdef qdoc -#else -#ifdef USE_QT4 - virtual qint64 size() const; -#else // USE_QT4 - virtual TQIODevice::Offset size() const; -#endif // USE_QT4 -#endif - - virtual TQIODevice::Offset at() const; - /** - * That one can be quite slow, when going back. Use with care. - */ - virtual bool at( TQIODevice::Offset ); - - virtual bool atEnd() const; - -#ifdef qdoc -#else - virtual TQT_TQIO_LONG tqreadBlock( char *data, TQT_TQIO_ULONG maxlen ); - virtual TQT_TQIO_LONG tqwriteBlock( const char *data, TQT_TQIO_ULONG len ); -#endif - //int readLine( char *data, uint maxlen ); - - virtual int getch(); - virtual int putch( int ); - virtual int ungetch( int ); - -#ifdef KDE_NO_COMPAT -private: -#endif - /** - * Call this to create the appropriate filter device for @p base - * working on @p file . The returned TQIODevice has to be deleted - * after using. - * @deprecated. Use deviceForFile instead. - * To be removed in KDE 3.0 - */ - static TQIODevice* createFilterDevice(KFilterBase* base, TQFile* file) KDE_DEPRECATED; -public: - - /** - * Creates an i/o device that is able to read from @p fileName, - * whether it's compressed or not. Available compression filters - * (gzip/bzip2 etc.) will automatically be used. - * - * The compression filter to be used is determined from the @p fileName - * if @p mimetype is empty. Pass "application/x-gzip" or "application/x-bzip2" - * to force the corresponding decompression filter, if available. - * - * Warning: application/x-bzip2 may not be available. - * In that case a TQFile opened on the compressed data will be returned ! - * Use KFilterBase::findFilterByMimeType and code similar to what - * deviceForFile is doing, to better control what's happening. - * - * The returned TQIODevice has to be deleted after using. - * - * @param fileName the name of the file to filter - * @param mimetype the mime type of the file to filter, or TQString::null if unknown - * @param forceFilter if true, the function will either find a compression filter, or return 0. - * If false, it will always return a TQIODevice. If no - * filter is available it will return a simple TQFile. - * This can be useful if the file is usable without a filter. - * @return if a filter has been found, the TQIODevice for the filter. If the - * filter does not exist, the return value depends on @p forceFilter. - * The returned TQIODevice has to be deleted after using. - */ - static TQIODevice * deviceForFile( const TQString & fileName, const TQString & mimetype = TQString::null, - bool forceFilter = false ); - - /** - * Creates an i/o device that is able to read from the TQIODevice @p inDevice, - * whether the data is compressed or not. Available compression filters - * (gzip/bzip2 etc.) will automatically be used. - * - * The compression filter to be used is determined @p mimetype . - * Pass "application/x-gzip" or "application/x-bzip2" - * to use the corresponding decompression filter. - * - * Warning: application/x-bzip2 may not be available. - * In that case 0 will be returned ! - * - * The returned TQIODevice has to be deleted after using. - * @param inDevice input device, becomes owned by this device! Automatically deleted! - * @param mimetype the mime type for the filter - * @return a TQIODevice that filters the original stream. Must be deleted after - * using - */ - static TQIODevice * device( TQIODevice* inDevice, const TQString & mimetype); - // BIC: merge with device() method below, using default value for autoDeleteInDevice - - /** - * Creates an i/o device that is able to read from the TQIODevice @p inDevice, - * whether the data is compressed or not. Available compression filters - * (gzip/bzip2 etc.) will automatically be used. - * - * The compression filter to be used is determined @p mimetype . - * Pass "application/x-gzip" or "application/x-bzip2" - * to use the corresponding decompression filter. - * - * Warning: application/x-bzip2 may not be available. - * In that case 0 will be returned ! - * - * The returned TQIODevice has to be deleted after using. - * @param inDevice input device. Won't be deleted if @p autoDeleteInDevice = false - * @param mimetype the mime type for the filter - * @param autoDeleteInDevice if true, @p inDevice will be deleted automatically - * @return a TQIODevice that filters the original stream. Must be deleted after - * using - * @since 3.1 - */ - static TQIODevice * device( TQIODevice* inDevice, const TQString & mimetype, bool autoDeleteInDevice ); - -private: - KFilterBase *filter; - class KFilterDevPrivate; - KFilterDevPrivate * d; -}; - - -#endif - diff --git a/kio/kio/kimageio.cpp b/kio/kio/kimageio.cpp deleted file mode 100644 index e983cb945..000000000 --- a/kio/kio/kimageio.cpp +++ /dev/null @@ -1,566 +0,0 @@ - -/** -* kimgio.h -- Implementation of interface to the KDE Image IO library. -* Sirtaj Singh Kang <taj@kde.org>, 23 Sep 1998. -* -* $Id$ -* -* This library is distributed under the conditions of the GNU LGPL. -*/ - -#include"config.h" - -#include <tqdir.h> -#include <kapplication.h> -#include <kstandarddirs.h> -#include <tqstring.h> -#include <tqregexp.h> -#include <tqvaluelist.h> - -#include <ltdl.h> -#include "kimageio.h" -#include "kimageiofactory.h" -#include <klocale.h> -#include <klibloader.h> -#include <kglobal.h> -#include <kmimetype.h> -#include <tdesycocaentry.h> -#include <tdesycoca.h> -#include <kdebug.h> -#include <kstaticdeleter.h> - -#include <tqimage.h> - -KImageIOFormat::KImageIOFormat( const TQString &path) - : KSycocaEntry(path) -{ - bLibLoaded = false; - mReadFunc = 0; - mWriteFunc = 0; - TDEConfig config(path, true, false); - - config.setGroup("Image Format"); - mType = config.readEntry("Type"); - mHeader = KURL::decode_string(config.readEntry("Header"), 4); // Latin1 - mFlags = config.readEntry("Flags"); - bRead = config.readBoolEntry("Read"); - bWrite = config.readBoolEntry("Write"); - mSuffices = config.readListEntry("Suffices"); - mPattern = config.readEntry("Name"); - mMimetype = config.readEntry("Mimetype"); - mLib = config.readPathEntry("Library"); - rPaths = config.readPathListEntry("rPaths"); -} - -KImageIOFormat::KImageIOFormat( TQDataStream& _str, int offset) : - KSycocaEntry( _str, offset) -{ - bLibLoaded = false; - mReadFunc = 0; - mWriteFunc = 0; - load( _str ); -} - -KImageIOFormat::~KImageIOFormat() -{ -} - -void -KImageIOFormat::load( TQDataStream& _str) -{ - TQ_INT8 iRead, iWrite; - KSycocaEntry::read(_str, mType); - KSycocaEntry::read(_str, mHeader); - KSycocaEntry::read(_str, mFlags); - _str >> iRead >> iWrite; - KSycocaEntry::read(_str, mSuffices); - KSycocaEntry::read(_str, mMimetype); - KSycocaEntry::read(_str, mLib); - KSycocaEntry::read(_str, mPattern); - KSycocaEntry::read(_str, rPaths); - bRead = (iRead != 0); - bWrite = (iWrite != 0); -} - -void -KImageIOFormat::save( TQDataStream& _str) -{ - KSycocaEntry::save( _str ); - TQ_INT8 iRead = bRead ? 1 : 0; - TQ_INT8 iWrite = bWrite ? 1 : 0; - - _str << mType << mHeader << mFlags << iRead << iWrite - << mSuffices << mMimetype << mLib << mPattern << rPaths; -} - -void -KImageIOFormat::callLibFunc( bool read, TQImageIO *iio) -{ - if (!bLibLoaded) - { - if (mLib.isEmpty()) - { - iio->setStatus(1); // Error - return; - } - TQString libpath = KLibLoader::findLibrary(mLib.ascii()); - if ( libpath.isEmpty()) - { - iio->setStatus(1); // Error - return; - } - lt_dlhandle libhandle = lt_dlopen( TQFile::encodeName(libpath) ); - if (libhandle == 0) { - iio->setStatus(1); // error - kdWarning() << "KImageIOFormat::callLibFunc: couldn't dlopen " << mLib << "(" << lt_dlerror() << ")" << endl; - return; - } - bLibLoaded = true; - TQString funcName; - if (bRead) - { - funcName = "kimgio_"+mType.lower()+"_read"; - lt_ptr func = lt_dlsym(libhandle, funcName.ascii()); - - if (func == NULL) { - iio->setStatus(1); // error - kdWarning() << "couln't find " << funcName << " (" << lt_dlerror() << ")" << endl; - } - mReadFunc = (void (*)(TQImageIO *))func; - } - if (bWrite) - { - funcName = "kimgio_"+mType.lower()+"_write"; - lt_ptr func = lt_dlsym(libhandle, funcName.ascii()); - - if (func == NULL) { - iio->setStatus(1); // error - kdWarning() << "couln't find " << funcName << " (" << lt_dlerror() << ")" << endl; - } - mWriteFunc = (void (*)(TQImageIO *))func; - } - - } - if (read) - if (mReadFunc) - mReadFunc(iio); - else - iio->setStatus(1); // Error - else - if (mWriteFunc) - mWriteFunc(iio); - else - iio->setStatus(1); // Error -} - - -KImageIOFactory *KImageIOFactory::_self = 0; -KImageIOFormatList *KImageIOFactory::formatList = 0; - -static KStaticDeleter<KImageIOFormatList> kiioflsd; - -KImageIOFactory::KImageIOFactory() : KSycocaFactory( KST_KImageIO ) -{ - _self = this; - if (m_str) - { - // read from database - KSycocaEntry::read(*m_str, mReadPattern); - KSycocaEntry::read(*m_str, mWritePattern); - KSycocaEntry::read(*m_str, rPath); - if (!formatList) - { - kiioflsd.setObject( formatList, new KImageIOFormatList()); - lt_dlinit(); // Do this only once! - // Add rPaths. - for(TQStringList::Iterator it = rPath.begin(); - it != rPath.end(); ++it) - lt_dladdsearchdir( TQFile::encodeName(*it) ); - } - load(); - } - else - if (KSycoca::self()->isBuilding()) - { - // Build database - if (!formatList) - { - formatList = new KImageIOFormatList(); - } - } else - { - // We have no database at all.. uh-oh - } -} - -TQString -KImageIOFactory::createPattern( KImageIO::Mode _mode) -{ - TQStringList patterns; - TQString allPatterns; - TQString wildCard("*."); - TQString separator("|"); - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - KImageIOFormat *format = (*it); - if (((_mode == KImageIO::Reading) && format->bRead) || - ((_mode == KImageIO::Writing) && format->bWrite)) - { - TQString pattern; - TQStringList suffices = format->mSuffices; - for( TQStringList::ConstIterator it = suffices.begin(); - it != suffices.end(); - ++it) - { - if (!pattern.isEmpty()) - pattern += " "; - pattern = pattern + wildCard+(*it); - if (!allPatterns.isEmpty()) - allPatterns += " "; - allPatterns = allPatterns + wildCard +(*it); - } - if (!pattern.isEmpty()) - { - pattern = pattern + separator + format->mPattern; - patterns.append(pattern); - } - } - } - allPatterns = allPatterns + separator + i18n("All Pictures"); - patterns.sort(); - patterns.prepend(allPatterns); - - TQString pattern = patterns.join(TQString::fromLatin1("\n")); - return pattern; -} - -void -KImageIOFactory::readImage( TQImageIO *iio) -{ - (void) self(); // Make sure we exist - const char *fm = iio->format(); - if (!fm) - fm = TQImageIO::imageFormat( iio->ioDevice()); - kdDebug() << "KImageIO: readImage() format = " << fm << endl; - - KImageIOFormat *format = 0; - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - format = (*it); - if (format->mType == fm) - break; - } - if (!format || !format->bRead) - { - iio->setStatus(1); // error - return; - } - - format->callLibFunc( true, iio); -} - -void -KImageIOFactory::writeImage( TQImageIO *iio) -{ - (void) self(); // Make sure we exist - const char *fm = iio->format(); - if (!fm) - fm = TQImageIO::imageFormat( iio->ioDevice()); - kdDebug () << "KImageIO: writeImage() format = "<< fm << endl; - - KImageIOFormat *format = 0; - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - format = (*it); - if (format->mType == fm) - break; - } - if (!format || !format->bWrite) - { - iio->setStatus(1); // error - return; - } - - format->callLibFunc( false, iio); -} - -void -KImageIOFactory::load() -{ - KSycocaEntry::List list = allEntries(); - for( KSycocaEntry::List::Iterator it = list.begin(); - it != list.end(); - ++it) - { - KSycocaEntry *entry = static_cast<KSycocaEntry *>(*it); - KImageIOFormat *format = static_cast<KImageIOFormat *>(entry); - - // Since Qt doesn't allow us to unregister image formats - // we have to make sure not to add them a second time. - // This typically happens when the sycoca database was updated - // we need to reread it. - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - KImageIOFormat *_format = (*it); - if (format->mType == _format->mType) - { - // Already in list - format = 0; - break; - } - } - if (!format) - continue; - if (!format->mHeader.isEmpty() && !format->mLib.isEmpty()) - { - void (*readFunc)(TQImageIO *); - void (*writeFunc)(TQImageIO *); - if (format->bRead) - readFunc = readImage; - else - readFunc = 0; - if (format->bWrite) - writeFunc = writeImage; - else - writeFunc = 0; - TQImageIO::defineIOHandler( format->mType.ascii(), - format->mHeader.ascii(), - format->mFlags.ascii(), - readFunc, writeFunc); - } - formatList->append( format ); - } -} - -KImageIOFactory::~KImageIOFactory() -{ - _self = 0; - - // We would like to: - // * Free all KImageIOFormats. - // * Unload libs - // * Remove Qt IO handlers. - // But we can't remove IO handlers, so we better keep all KImageIOFormats - // in memory so that we can make sure not register IO handlers again whenever - // the sycoca database updates (Such event deletes this factory) -} - -KSycocaEntry* -KImageIOFactory::createEntry(int offset) -{ - KImageIOFormat *format = 0; - KSycocaType type; - TQDataStream *str = KSycoca::self()->findEntry(offset, type); - switch (type) - { - case KST_KImageIOFormat: - format = new KImageIOFormat(*str, offset); - break; - default: - return 0; - } - if (!format->isValid()) - { - delete format; - format = 0; - } - return format; -} - -void KImageIO::registerFormats() -{ - (void) KImageIOFactory::self(); -} - -TQString -KImageIO::pattern(Mode _mode) -{ - if (_mode == Reading) - return KImageIOFactory::self()->mReadPattern; - else - return KImageIOFactory::self()->mWritePattern; -} - -bool KImageIO::canWrite(const TQString& type) -{ - KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; - - if(formatList) - { - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - KImageIOFormat *format = (*it); - if (format->mType == type) - return format->bWrite; - } - } - - return false; -} - -bool KImageIO::canRead(const TQString& type) -{ - KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; - - if(formatList) - { - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - KImageIOFormat *format = (*it); - if (format->mType == type) - return format->bRead; - } - } - - return false; -} - -TQStringList KImageIO::types(Mode _mode ) { - KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; - TQStringList types; - - if(formatList) - { - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - KImageIOFormat *format = (*it); - if (((_mode == Reading) && format->bRead) || - ((_mode == Writing) && format->bWrite)) - types.append(format->mType); - } - } - - return types; -} - -TQString KImageIO::suffix(const TQString& type) -{ - KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; - - if(formatList) - { - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - KImageIOFormat *format = (*it); - if (format->mType == type) - return format->mSuffices[0]; - } - } - - return TQString::null; -} - -TQString KImageIO::typeForMime(const TQString& mimeType) -{ - KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; - - if(formatList) - { - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - KImageIOFormat *format = (*it); - if (format->mMimetype == mimeType) - return format->mType; - } - } - - return TQString::null; -} - -TQString KImageIO::type(const TQString& filename) -{ - KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; - TQString suffix = filename; - int dot = suffix.findRev('.'); - if (dot >= 0) - suffix = suffix.mid(dot + 1); - - if(formatList) - { - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - KImageIOFormat *format = (*it); - if (format->mSuffices.contains(suffix)) - return format->mType; - } - } - - return TQString::null; -} - -TQStringList KImageIO::mimeTypes( Mode _mode ) -{ - KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; - TQStringList mimeList; - - if(formatList) - { - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - KImageIOFormat *format = (*it); - if (((_mode == Reading) && format->bRead) || - ((_mode == Writing) && format->bWrite)) - if ( !format->mMimetype.isEmpty() ) - mimeList.append ( format->mMimetype ); - } - } - - return mimeList; -} - -bool KImageIO::isSupported( const TQString& _mimeType, Mode _mode ) -{ - KImageIOFormatList *formatList = KImageIOFactory::self()->formatList; - - if(formatList) - { - for( KImageIOFormatList::ConstIterator it = formatList->begin(); - it != formatList->end(); - ++it ) - { - KImageIOFormat *format = (*it); - if (format->mMimetype == _mimeType) - { - if (((_mode == Reading) && format->bRead) || - ((_mode == Writing) && format->bWrite)) - return true; - } - } - } - - return false; -} - -TQString KImageIO::mimeType( const TQString& _filename ) -{ - return KMimeType::findByURL( KURL( _filename ) )->name(); -} - -void KImageIOFormat::virtual_hook( int id, void* data ) -{ KSycocaEntry::virtual_hook( id, data ); } - -void KImageIOFactory::virtual_hook( int id, void* data ) -{ KSycocaFactory::virtual_hook( id, data ); } - diff --git a/kio/kio/kimageio.h b/kio/kio/kimageio.h deleted file mode 100644 index 671fb5f61..000000000 --- a/kio/kio/kimageio.h +++ /dev/null @@ -1,170 +0,0 @@ -/* -* kimageio.h -- Declaration of interface to the KDE Image IO library. -* Sirtaj Singh Kang <taj@kde.org>, 23 Sep 1998. -* -* This library is distributed under the conditions of the GNU LGPL. -*/ - -#ifndef SSK_KIMGIO_H -#define SSK_KIMGIO_H - -#include <tqstringlist.h> - -#include <tdelibs_export.h> - -/** - * Interface to the KDE Image IO plugin architecture. - * - * This library allows KDE applications to read and write images in a - * variety of formats, transparently via the TQImage and TQPixmap load - * and save methods. - * - * The image processing backends are written as image handlers compatible - * with the TQImageIO handler format. The backends are loaded on demand - * when a particular format is requested. Each format can be identified - * by a unique type id string. - * - * \b Formats: - * - * Currently supported formats include: - * @li BMP \<read\> \<write\> - * @li EPS \<read\> \<write\> - * @li EXR \<read\> - * @li G3 \<read\> - * @li GIF \<read\> - * @li ICO \<read\> - * @li JP2 \<read\> \<write\> - * @li JPEG \<read\> \<write\> - * @li NETPBM \<read\> \<write\> - * @li PCX \<read\> \<write\> - * @li PNG \<read\> \<write, only with newer libraries\> - * @li TGA \<read\> \<write\> - * @li TIFF \<read\> - * @li XBM \<read\> \<write\> - * @li XPM \<read\> \<write\> - * @li XV \<read\> \<write\> - * - * \b Usage: - * - * Simply call the KImageIO::registerFormats() static method declared - * in kimageio.h. - * - * \b Example: - * - * \code - * #include<tqpixmap.h> - * #include<kimageio.h> - * - * int main( int argc, char **argv ) - * { - * .... - * KImageIO::registerFormats(); - * ... // start main program - * } - * \endcode - * - * @see KImageIO, TQPixmap, TQImage, QImageIO - * @author Sirtaj Singh Kang - */ -class TDEIO_EXPORT KImageIO -{ -public: - /** - * Possible image file access modes. - * - * Used in various KImageIO static function. - **/ - enum Mode { Reading, Writing }; - - /** - * Registers all KImageIO supported formats. - */ - static void registerFormats(); - - /** - * Checks if a special type is supported for writing. - * @param type the type id of the image type - * @return true if the image format can be written - */ - static bool canWrite(const TQString& type); - - /** - * Checks if a special type is supported for reading. - * @param type the type id of the image type - * @return true if the image format can be read - */ - static bool canRead(const TQString& type); - - /** - * Returns a list of all KImageIO supported formats. - * - * @param mode Tells whether to retrieve modes that can be read or written. - * @return a list of the type ids - */ - static TQStringList types(Mode mode = Writing); - - - /** - * Returns a list of patterns of all KImageIO supported formats. - * - * These patterns can be passed to KFileDialog::getOpenFileName() - * or KFileDialog::getSaveFileName(), for example. - * - * @param mode Tells whether to retrieve modes that can be read or written. - * @return a space-separated list of file globs that describe the - * supported formats - */ - static TQString pattern(Mode mode = Reading); - - /** - * Returns the suffix of an image type. - * @param type the type id of the file format - * @return the suffix of the file format or TQString::null if it does not - * exist - */ - static TQString suffix(const TQString& type); - - /** - * Returns the type of a MIME type. - * @param mimeType the MIME type to search - * @return type id of the MIME type or TQString::null if the MIME type - * is not supported - * @since 3.1 - */ - static TQString typeForMime(const TQString& mimeType); - - /** - * Returns the type of given filename. - * @param filename the filename to check - * @return if the file name's suffix is known the type id of the - * file type, otherwise TQString::null - */ - static TQString type(const TQString& filename); - - /** - * Returns a list of MIME types for all KImageIO supported formats. - * - * @param mode Tells whether to retrieve modes that can be read or written. - * @return a list if MIME types of the supported formats - */ - static TQStringList mimeTypes( Mode mode = Writing ); - - /** - * Test to see whether a MIME type is supported to reading/writing. - * @param _mimeType the MIME type to check - * @param _mode Tells whether to check for reading or writing capabilities - * @return true if the type is supported - **/ - static bool isSupported( const TQString& _mimeType, Mode _mode = Writing ); - - /** - * Returns the MIME type of @p _filename. - * @param _filename the filename to check - * @return the MIME type of the file, or TQString::null - **/ - static TQString mimeType( const TQString& _filename ); -}; - - -#endif - diff --git a/kio/kio/kimageiofactory.h b/kio/kio/kimageiofactory.h deleted file mode 100644 index 6d2d15940..000000000 --- a/kio/kio/kimageiofactory.h +++ /dev/null @@ -1,142 +0,0 @@ -/* -* kimgio.h -- Declaration of interface to the KDE Image IO library. -* Sirtaj Singh Kang <taj@kde.org>, 23 Sep 1998. -* -* This library is distributed under the conditions of the GNU LGPL. -*/ - -#ifndef SSK_KIMGIOFACTORY_H -#define SSK_KIMGIOFACTORY_H - -#include "tdesycocafactory.h" -#include "kimageio.h" - -class KImageIOFormat; -class KImageIOFormatList; - -/** \internal */ -class TDEIO_EXPORT KImageIOFormat : public KSycocaEntry -{ - K_SYCOCATYPE( KST_KImageIOFormat, KSycocaEntry ) - -public: - typedef KSharedPtr<KImageIOFormat> Ptr; - typedef TQValueList<Ptr> List; -public: // KDoc seems to barf on those typedefs and generates no docs after them - /** - * Read a KImageIOFormat description file - */ - KImageIOFormat( const TQString & path); - - /** - * @internal construct a ImageIOFormat from a stream - */ - KImageIOFormat( TQDataStream& _str, int offset); - - virtual ~KImageIOFormat(); - - virtual TQString name() const { return mType; } - - virtual bool isValid() const { return true; } - - /** - * @internal - * Load the image format from a stream. - */ - virtual void load(TQDataStream& ); - - /** - * @internal - * Save the image format to a stream. - */ - virtual void save(TQDataStream& ); - - /** - * @internal - * Calls image IO function - */ - void callLibFunc( bool read, TQImageIO *); - -public: - TQString mType; - TQString mHeader; - TQString mFlags; - bool bRead; - bool bWrite; - TQStringList mSuffices; - TQString mPattern; - TQString mMimetype; - TQString mLib; - TQStringList rPaths; - bool bLibLoaded; - void (*mReadFunc)(TQImageIO *); - void (*mWriteFunc)(TQImageIO *); -protected: - virtual void virtual_hook( int id, void* data ); -}; - -/** \internal */ -class TDEIO_EXPORT KImageIOFormatList : public KImageIOFormat::List -{ -public: - KImageIOFormatList() { } -}; - - -/** \internal */ -class TDEIO_EXPORT KImageIOFactory : public KSycocaFactory -{ - friend class KImageIO; - K_SYCOCAFACTORY( KST_KImageIO ) -public: - static KImageIOFactory *self() - { if (!_self) new KImageIOFactory(); return _self; } - KImageIOFactory(); - virtual ~KImageIOFactory(); - -protected: // Internal stuff - /** - * @internal - * - * Load information from database - */ - void load(); - - /** - * @internal Create pattern string - **/ - TQString createPattern( KImageIO::Mode _mode); - - /** - * @internal Not used. - */ - virtual KSycocaEntry *createEntry(const TQString &, const char *) - { return 0; } - - /** - * @internal - */ - virtual KSycocaEntry *createEntry(int offset); - - /** - * @internal Read an image - **/ - static void readImage( TQImageIO *iio); - - /** - * @internal Write an image - **/ - static void writeImage( TQImageIO *iio); - -protected: - static KImageIOFactory *_self; - static KImageIOFormatList *formatList; - TQString mReadPattern; - TQString mWritePattern; - TQStringList rPath; -protected: - virtual void virtual_hook( int id, void* data ); -}; - -#endif - diff --git a/kio/kio/klimitediodevice.h b/kio/kio/klimitediodevice.h deleted file mode 100644 index 602ba45a0..000000000 --- a/kio/kio/klimitediodevice.h +++ /dev/null @@ -1,105 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2001, 2002 David Faure <david@mandrakesoft.com> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef klimitediodevice_h -#define klimitediodevice_h - -#include <kdebug.h> -#include <tqiodevice.h> -/** - * A readonly device that reads from an underlying device - * from a given point to another (e.g. to give access to a single - * file inside an archive). - * @author David Faure <david@mandrakesoft.com> - * @since 3.1 - */ -class TDEIO_EXPORT KLimitedIODevice : public TQIODevice -{ -public: - /** - * Creates a new KLimitedIODevice. - * @param dev the underlying device, opened or not - * This device itself auto-opens (in readonly mode), no need to open it. - * @param start where to start reading (position in bytes) - * @param length the length of the data to read (in bytes) - */ - KLimitedIODevice( TQIODevice *dev, int start, int length ) - : m_dev( dev ), m_start( start ), m_length( length ) - { - //kdDebug(7005) << "KLimitedIODevice::KLimitedIODevice start=" << start << " length=" << length << endl; - setType( IO_Direct ); // we support sequential too, but then atEnd() tries getch/ungetch ! - open( IO_ReadOnly ); - } - virtual ~KLimitedIODevice() {} - - virtual bool open( TQ_OpenMode m ) { - //kdDebug(7005) << "KLimitedIODevice::open m=" << m << endl; - if ( m & IO_ReadOnly ) { - /*bool ok = false; - if ( m_dev->isOpen() ) - ok = ( m_dev->mode() == IO_ReadOnly ); - else - ok = m_dev->open( m ); - if ( ok )*/ - m_dev->at( m_start ); // No concurrent access ! - } - else - kdWarning(7005) << "KLimitedIODevice::open only supports IO_ReadOnly!" << endl; - setState( IO_Open ); - setMode( m ); - return true; - } - virtual void close() {} - virtual void flush() {} - -#ifdef USE_QT4 - virtual qint64 size() const { return m_length; } -#else // USE_QT4 - virtual Offset size() const { return m_length; } -#endif // USE_QT4 - - virtual TQT_TQIO_LONG tqreadBlock ( char * data, TQT_TQIO_ULONG maxlen ) - { - maxlen = TQMIN( maxlen, m_length - at() ); // Apply upper limit - return m_dev->readBlock( data, maxlen ); - } - virtual TQT_TQIO_LONG tqwriteBlock ( const char *, TQT_TQIO_ULONG ) { return -1; } // unsupported - virtual int putch( int ) { return -1; } // unsupported - - virtual int getch() { - char c[2]; - if ( tqreadBlock(c, 1) == -1) - return -1; - else - return c[0]; - } - virtual int ungetch( int c ) { return m_dev->ungetch(c); } // ## apply lower limit ? - virtual Offset at() const { return m_dev->at() - m_start; } - virtual bool at( Offset pos ) { - Q_ASSERT( pos <= m_length ); - pos = QMIN( pos, m_length ); // Apply upper limit - return m_dev->at( m_start + pos ); - } - virtual bool atEnd() const { return m_dev->atEnd() || m_dev->at() >= m_start + m_length; } -private: - TQIODevice* m_dev; - TQ_ULONG m_start; - TQ_ULONG m_length; -}; - -#endif diff --git a/kio/kio/kmdbase.h b/kio/kio/kmdbase.h deleted file mode 100644 index b0c8f8b7d..000000000 --- a/kio/kio/kmdbase.h +++ /dev/null @@ -1,6 +0,0 @@ -// kmdbase.h is the old name. Use #include <kmdcodec.h> from now on -#ifdef KDE_NO_COMPAT -#error include <kmdcodec.h> instead of <kmdbase.h> -#else -#include <kmdcodec.h> -#endif diff --git a/kio/kio/kmessageboxwrapper.h b/kio/kio/kmessageboxwrapper.h deleted file mode 100644 index 3590b5e89..000000000 --- a/kio/kio/kmessageboxwrapper.h +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 1999 David Faure <faure@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation; - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#ifndef KMESSAGEBOXWRAPPER_H -#define KMESSAGEBOXWRAPPER_H -#include <kmessagebox.h> -#include <kapplication.h> -#include <kdebug.h> - -/** - * @internal - * Allows KIO classes to display dialog boxes with the correct - * theme/style even in non-GUI apps like kded and kfmclient - */ -class TDEIO_EXPORT KMessageBoxWrapper : public KMessageBox -{ -public: - static void error(TQWidget *parent, - const TQString &text, - const TQString &caption = TQString::null) - { - if (TDEApplication::guiEnabled()) { - kapp->enableStyles(); - KMessageBox::error( parent, text, caption ); - } else - kdWarning() << text << endl; - } - - static void sorry(TQWidget *parent, - const TQString &text, - const TQString &caption = TQString::null) - { - if (TDEApplication::guiEnabled()) { - kapp->enableStyles(); - KMessageBox::sorry( parent, text, caption ); - } else - kdWarning() << text << endl; - } - -}; -#endif diff --git a/kio/kio/kmimemagic.cpp b/kio/kio/kmimemagic.cpp deleted file mode 100644 index f639a7049..000000000 --- a/kio/kio/kmimemagic.cpp +++ /dev/null @@ -1,2317 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Fritz Elfert <fritz@kde.org> - Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#include "kmimemagic.h" -#include <kdebug.h> -#include <kapplication.h> -#include <tqfile.h> -#include <ksimpleconfig.h> -#include <kstandarddirs.h> -#include <kstaticdeleter.h> -#include <klargefile.h> -#include <assert.h> - -static int fsmagic(struct config_rec* conf, const char *fn, KDE_struct_stat *sb); -static void process(struct config_rec* conf, const TQString &); -static int ascmagic(struct config_rec* conf, unsigned char *buf, int nbytes); -static int tagmagic(unsigned char *buf, int nbytes); -static int textmagic(struct config_rec* conf, unsigned char *, int); - -static void tryit(struct config_rec* conf, unsigned char *buf, int nb); -static int match(struct config_rec* conf, unsigned char *, int); - -KMimeMagic* KMimeMagic::s_pSelf; -static KStaticDeleter<KMimeMagic> kmimemagicsd; - -KMimeMagic* KMimeMagic::self() -{ - if( !s_pSelf ) - initStatic(); - return s_pSelf; -} - -void KMimeMagic::initStatic() -{ - s_pSelf = kmimemagicsd.setObject( s_pSelf, new KMimeMagic() ); - s_pSelf->setFollowLinks( true ); -} - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/wait.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> -#include <time.h> -#include <utime.h> -#include <stdarg.h> -#include <tqregexp.h> -#include <tqstring.h> - -//#define MIME_MAGIC_DEBUG_TABLE // untested - -// Uncomment to debug the config-file parsing phase -//#define DEBUG_APPRENTICE -// Uncomment to debug the matching phase -//#define DEBUG_MIMEMAGIC - -#if (defined DEBUG_MIMEMAGIC || defined DEBUG_APPRENTICE) -#define DEBUG_LINENUMBERS -#endif - -/* - * Buitltin Mime types - */ -#define MIME_BINARY_UNKNOWN "application/octet-stream" -#define MIME_BINARY_UNREADABLE "application/x-unreadable" -#define MIME_BINARY_ZEROSIZE "application/x-zerosize" -#define MIME_TEXT_UNKNOWN "text/plain" -#define MIME_TEXT_PLAIN "text/plain" -#define MIME_INODE_DIR "inode/directory" -#define MIME_INODE_CDEV "inode/chardevice" -#define MIME_INODE_BDEV "inode/blockdevice" -#define MIME_INODE_FIFO "inode/fifo" -#define MIME_INODE_LINK "inode/link" -#define MIME_INODE_SOCK "inode/socket" -// Following should go in magic-file - Fritz -#define MIME_APPL_TROFF "application/x-troff" -#define MIME_APPL_TAR "application/x-tar" -#define MIME_TEXT_FORTRAN "text/x-fortran" - -#define MAXMIMESTRING 256 - -#define HOWMANY 4000 /* big enough to recognize most WWW files, and skip GPL-headers */ -#define MAXDESC 50 /* max leng of text description */ -#define MAXstring 64 /* max leng of "string" types */ - -typedef union VALUETYPE { - unsigned char b; - unsigned short h; - unsigned long l; - char s[MAXstring]; - unsigned char hs[2]; /* 2 bytes of a fixed-endian "short" */ - unsigned char hl[4]; /* 2 bytes of a fixed-endian "long" */ -} VALUETYPE; - -struct magic { - struct magic *next; /* link to next entry */ -#ifdef DEBUG_LINENUMBERS - int lineno; /* line number from magic file - doesn't say from which one ;) */ -#endif - - short flag; -#define INDIR 1 /* if '>(...)' appears, */ -#define UNSIGNED 2 /* comparison is unsigned */ - short cont_level; /* level of ">" */ - struct { - char type; /* byte short long */ - long offset; /* offset from indirection */ - } in; - long offset; /* offset to magic number */ - unsigned char reln; /* relation (0=eq, '>'=gt, etc) */ - char type; /* int, short, long or string. */ - char vallen; /* length of string value, if any */ -#define BYTE 1 -#define SHORT 2 -#define LONG 4 -#define STRING 5 -#define DATE 6 -#define BESHORT 7 -#define BELONG 8 -#define BEDATE 9 -#define LESHORT 10 -#define LELONG 11 -#define LEDATE 12 - VALUETYPE value; /* either number or string */ - unsigned long mask; /* mask before comparison with value */ - char nospflag; /* suppress space character */ - - /* NOTE: this string is suspected of overrunning - find it! */ - char desc[MAXDESC]; /* description */ -}; - -/* - * data structures for tar file recognition - * -------------------------------------------------------------------------- - * Header file for public domain tar (tape archive) program. - * - * @(#)tar.h 1.20 86/10/29 Public Domain. Created 25 August 1985 by John - * Gilmore, ihnp4!hoptoad!gnu. - * - * Header block on tape. - * - * I'm going to use traditional DP naming conventions here. A "block" is a big - * chunk of stuff that we do I/O on. A "record" is a piece of info that we - * care about. Typically many "record"s fit into a "block". - */ -#define RECORDSIZE 512 -#define NAMSIZ 100 -#define TUNMLEN 32 -#define TGNMLEN 32 - -union record { - char charptr[RECORDSIZE]; - struct header { - char name[NAMSIZ]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char chksum[8]; - char linkflag; - char linkname[NAMSIZ]; - char magic[8]; - char uname[TUNMLEN]; - char gname[TGNMLEN]; - char devmajor[8]; - char devminor[8]; - } header; -}; - -/* The magic field is filled with this if uname and gname are valid. */ -#define TMAGIC "ustar " /* 7 chars and a null */ - -/* - * file-function prototypes - */ -static int is_tar(unsigned char *, int); -static unsigned long signextend(struct magic *, unsigned long); -static int getvalue(struct magic *, char **); -static int hextoint(int); -static char *getstr(char *, char *, int, int *); -static int mget(union VALUETYPE *, unsigned char *, struct magic *, int); -static int mcheck(union VALUETYPE *, struct magic *); -static int mconvert(union VALUETYPE *, struct magic *); -static long from_oct(int, char *); - -/* - * includes for ASCII substring recognition formerly "names.h" in file - * command - * - * Original notes: names and types used by ascmagic in file(1). - * These tokens are - * here because they can appear anywhere in the first HOWMANY bytes, while - * tokens in /etc/magic must appear at fixed offsets into the file. Don't - * make HOWMANY too high unless you have a very fast CPU. - */ - -/* these types are used calculate index to 'types': keep em in sync! */ -/* HTML inserted in first because this is a web server module now */ -/* ENG removed because stupid */ -#define L_HTML 0x001 /* HTML */ -#define L_C 0x002 /* first and foremost on UNIX */ -#define L_MAKE 0x004 /* Makefiles */ -#define L_PLI 0x008 /* PL/1 */ -#define L_MACH 0x010 /* some kinda assembler */ -#define L_PAS 0x020 /* Pascal */ -#define L_JAVA 0x040 /* Java source */ -#define L_CPP 0x080 /* C++ */ -#define L_MAIL 0x100 /* Electronic mail */ -#define L_NEWS 0x200 /* Usenet Netnews */ -#define L_DIFF 0x400 /* Output of diff */ -#define L_OBJC 0x800 /* Objective C */ - -// Note: this is not a type, it's just used to mark items that should count more -#define FLAG_STRONG 0x1000 - -#define P_HTML 0 /* HTML */ -#define P_C 1 /* first and foremost on UNIX */ -#define P_MAKE 2 /* Makefiles */ -#define P_PLI 3 /* PL/1 */ -#define P_MACH 4 /* some kinda assembler */ -#define P_PAS 5 /* Pascal */ -#define P_JAVA 6 /* Java source */ -#define P_CPP 7 /* C++ */ -#define P_MAIL 8 /* Electronic mail */ -#define P_NEWS 9 /* Usenet Netnews */ -#define P_DIFF 10 /* Output of diff */ -#define P_OBJC 11 /* Objective C */ - -typedef struct asc_type { - const char *type; - int kwords; - double weight; -} asc_type; - -static const asc_type types[] = { - { "text/html", 19, 2 }, // 10 items but 10 different words only - { "text/x-c", 13, 1 }, - { "text/x-makefile", 4, 1.9 }, - { "text/x-pli", 1, 3 }, - { "text/x-assembler", 6, 2.1 }, - { "text/x-pascal", 1, 1 }, - { "text/x-java", 12, 1 }, - { "text/x-c++", 19, 1 }, - { "message/rfc822", 4, 1.9 }, - { "message/news", 3, 2 }, - { "text/x-diff", 4, 2 }, - { "text/x-objc", 10, 1 } -}; - -#define NTYPES (sizeof(types)/sizeof(asc_type)) - -static struct names { - const char *name; - short type; -} const names[] = { - { - "<html", L_HTML | FLAG_STRONG - }, - { - "<HTML", L_HTML | FLAG_STRONG - }, - { - "<head", L_HTML - }, - { - "<HEAD", L_HTML - }, - { - "<body", L_HTML - }, - { - "<BODY", L_HTML - }, - { - "<title", L_HTML - }, - { - "<TITLE", L_HTML - }, - { - "<h1", L_HTML - }, - { - "<H1", L_HTML - }, - { - "<a", L_HTML - }, - { - "<A", L_HTML - }, - { - "<img", L_HTML - }, - { - "<IMG", L_HTML - }, - { - "<!--", L_HTML - }, - { - "<!doctype", L_HTML - }, - { - "<!DOCTYPE", L_HTML - }, - { - "<div", L_HTML - }, - { - "<DIV", L_HTML - }, - { - "<frame", L_HTML - }, - { - "<FRAME", L_HTML - }, - { - "<frameset", L_HTML - }, - { - "<FRAMESET", L_HTML - }, - { - "<script", L_HTML | FLAG_STRONG - }, - { - "<SCRIPT", L_HTML | FLAG_STRONG - }, - { - "/*", L_C|L_CPP|L_JAVA|L_OBJC - }, - { - "//", L_C|L_CPP|L_JAVA|L_OBJC - }, - { - "#include", L_C|L_CPP - }, - { - "#ifdef", L_C|L_CPP - }, - { - "#ifndef", L_C|L_CPP - }, - { - "bool", L_C|L_CPP - }, - { - "char", L_C|L_CPP|L_JAVA|L_OBJC - }, - { - "int", L_C|L_CPP|L_JAVA|L_OBJC - }, - { - "float", L_C|L_CPP|L_JAVA|L_OBJC - }, - { - "void", L_C|L_CPP|L_JAVA|L_OBJC - }, - { - "extern", L_C|L_CPP - }, - { - "struct", L_C|L_CPP - }, - { - "union", L_C|L_CPP - }, - { - "implements", L_JAVA - }, - { - "super", L_JAVA - }, - { - "import", L_JAVA - }, - { - "class", L_CPP|L_JAVA - }, - { - "public", L_CPP|L_JAVA - }, - { - "private", L_CPP|L_JAVA - }, - { - "explicit", L_CPP - }, - { - "virtual", L_CPP - }, - { - "namespace", L_CPP - }, - { - "#import", L_OBJC - }, - { - "@interface", L_OBJC - }, - { - "@implementation", L_OBJC - }, - { - "@protocol", L_OBJC - }, - { - "CFLAGS", L_MAKE - }, - { - "LDFLAGS", L_MAKE - }, - { - "all:", L_MAKE - }, - { - ".PHONY:", L_MAKE - }, - { - "srcdir", L_MAKE - }, - { - "exec_prefix", L_MAKE - }, - /* - * Too many files of text have these words in them. Find another way - * to recognize Fortrash. - */ - { - ".ascii", L_MACH - }, - { - ".asciiz", L_MACH - }, - { - ".byte", L_MACH - }, - { - ".even", L_MACH - }, - { - ".globl", L_MACH - }, - { - "clr", L_MACH - }, - { - "(input", L_PAS - }, - { - "dcl", L_PLI - }, - { - "Received:", L_MAIL - }, - /* we now stop at '>' for tokens, so this one won't work { - ">From", L_MAIL - },*/ - { - "Return-Path:", L_MAIL - }, - { - "Cc:", L_MAIL - }, - { - "Newsgroups:", L_NEWS - }, - { - "Path:", L_NEWS - }, - { - "Organization:", L_NEWS - }, - { - "---", L_DIFF - }, - { - "+++", L_DIFF - }, - { - "***", L_DIFF - }, - { - "@@", L_DIFF - }, - { - NULL, 0 - } -}; - -/** - * Configuration for the utime() problem. - * Here's the problem: - * By looking into a file to determine its mimetype, we change its "last access" - * time (atime) and this can have side effects, like files in /tmp never being - * cleaned up because of that. So in temp directories, we restore the atime. - * Since this changes the ctime (last change of attributes), we don't do that - * anywhere else, because that breaks archiving programs, that check the ctime. - * Hence this class, to configure the directories where the atime should be restored. - */ -class KMimeMagicUtimeConf -{ -public: - KMimeMagicUtimeConf() - { - tmpDirs << TQString::fromLatin1("/tmp"); // default value - - // The trick is that we also don't want the user to override globally set - // directories. So we have to misuse KStandardDirs :} - TQStringList confDirs = TDEGlobal::dirs()->resourceDirs( "config" ); - if ( !confDirs.isEmpty() ) - { - TQString globalConf = confDirs.last() + "kmimemagicrc"; - if ( TQFile::exists( globalConf ) ) - { - KSimpleConfig cfg( globalConf ); - cfg.setGroup( "Settings" ); - tmpDirs = cfg.readListEntry( "atimeDirs" ); - } - if ( confDirs.count() > 1 ) - { - TQString localConf = confDirs.first() + "kmimemagicrc"; - if ( TQFile::exists( localConf ) ) - { - KSimpleConfig cfg( localConf ); - cfg.setGroup( "Settings" ); - tmpDirs += cfg.readListEntry( "atimeDirs" ); - } - } - for ( TQStringList::Iterator it = tmpDirs.begin() ; it != tmpDirs.end() ; ++it ) - { - TQString dir = *it; - if ( !dir.isEmpty() && dir[ dir.length()-1 ] != '/' ) - (*it) += '/'; - } - } -#if 0 - // debug code - for ( TQStringList::Iterator it = tmpDirs.begin() ; it != tmpDirs.end() ; ++it ) - kdDebug(7018) << " atimeDir: " << *it << endl; -#endif - } - - bool restoreAccessTime( const TQString & file ) const - { - TQString dir = file.left( file.findRev( '/' ) ); - bool res = tmpDirs.contains( dir ); - //kdDebug(7018) << "restoreAccessTime " << file << " dir=" << dir << " result=" << res << endl; - return res; - } - TQStringList tmpDirs; -}; - -/* current config */ -struct config_rec { - bool followLinks; - TQString resultBuf; - int accuracy; - - struct magic *magic, /* head of magic config list */ - *last; - KMimeMagicUtimeConf * utimeConf; -}; - -#ifdef MIME_MAGIC_DEBUG_TABLE -static void -test_table() -{ - struct magic *m; - struct magic *prevm = NULL; - - kdDebug(7018) << "test_table : started" << endl; - for (m = conf->magic; m; m = m->next) { - if (isprint((((unsigned long) m) >> 24) & 255) && - isprint((((unsigned long) m) >> 16) & 255) && - isprint((((unsigned long) m) >> 8) & 255) && - isprint(((unsigned long) m) & 255)) { - //debug("test_table: POINTER CLOBBERED! " - //"m=\"%c%c%c%c\" line=%d", - (((unsigned long) m) >> 24) & 255, - (((unsigned long) m) >> 16) & 255, - (((unsigned long) m) >> 8) & 255, - ((unsigned long) m) & 255, - prevm ? prevm->lineno : -1); - break; - } - prevm = m; - } -} -#endif - -#define EATAB {while (isascii((unsigned char) *l) && \ - isspace((unsigned char) *l)) ++l;} - -int KMimeMagic::parse_line(char *line, int *rule, int lineno) -{ - int ws_offset; - - /* delete newline */ - if (line[0]) { - line[strlen(line) - 1] = '\0'; - } - /* skip leading whitespace */ - ws_offset = 0; - while (line[ws_offset] && isspace(line[ws_offset])) { - ws_offset++; - } - - /* skip blank lines */ - if (line[ws_offset] == 0) { - return 0; - } - /* comment, do not parse */ - if (line[ws_offset] == '#') - return 0; - - /* if we get here, we're going to use it so count it */ - (*rule)++; - - /* parse it */ - return (parse(line + ws_offset, lineno) != 0); -} - -/* - * apprentice - load configuration from the magic file. - */ -int KMimeMagic::apprentice( const TQString& magicfile ) -{ - FILE *f; - char line[BUFSIZ + 1]; - int errs = 0; - int lineno; - int rule = 0; - TQCString fname; - - if (magicfile.isEmpty()) - return -1; - fname = TQFile::encodeName(magicfile); - f = fopen(fname, "r"); - if (f == NULL) { - kdError(7018) << "can't read magic file " << fname.data() << ": " << strerror(errno) << endl; - return -1; - } - - /* parse it */ - for (lineno = 1; fgets(line, BUFSIZ, f) != NULL; lineno++) - if (parse_line(line, &rule, lineno)) - errs++; - - fclose(f); - -#ifdef DEBUG_APPRENTICE - kdDebug(7018) << "apprentice: conf=" << conf << " file=" << magicfile << " m=" << (conf->magic ? "set" : "NULL") << " m->next=" << ((conf->magic && conf->magic->next) ? "set" : "NULL") << " last=" << (conf->last ? "set" : "NULL") << endl; - kdDebug(7018) << "apprentice: read " << lineno << " lines, " << rule << " rules, " << errs << " errors" << endl; -#endif - -#ifdef MIME_MAGIC_DEBUG_TABLE - test_table(); -#endif - - return (errs ? -1 : 0); -} - -int KMimeMagic::buff_apprentice(char *buff) -{ - char line[BUFSIZ + 2]; - int errs = 0; - int lineno = 1; - char *start = buff; - char *end; - int count = 0; - int rule = 0; - int len = strlen(buff) + 1; - - /* parse it */ - do { - count = (len > BUFSIZ-1)?BUFSIZ-1:len; - strncpy(line, start, count); - line[count] = '\0'; - if ((end = strchr(line, '\n'))) { - *(++end) = '\0'; - count = strlen(line); - } else - strcat(line, "\n"); - start += count; - len -= count; - if (parse_line(line, &rule, lineno)) - errs++; - lineno++; - } while (len > 0); - -#ifdef DEBUG_APPRENTICE - kdDebug(7018) << "buff_apprentice: conf=" << conf << " m=" << (conf->magic ? "set" : "NULL") << " m->next=" << ((conf->magic && conf->magic->next) ? "set" : "NULL") << " last=" << (conf->last ? "set" : "NULL") << endl; - kdDebug(7018) << "buff_apprentice: read " << lineno << " lines, " << rule << " rules, " << errs << " errors" << endl; -#endif - -#ifdef MIME_MAGIC_DEBUG_TABLE - test_table(); -#endif - - return (errs ? -1 : 0); -} - -/* - * extend the sign bit if the comparison is to be signed - */ -static unsigned long -signextend(struct magic *m, unsigned long v) -{ - if (!(m->flag & UNSIGNED)) - switch (m->type) { - /* - * Do not remove the casts below. They are vital. - * When later compared with the data, the sign - * extension must have happened. - */ - case BYTE: - v = (char) v; - break; - case SHORT: - case BESHORT: - case LESHORT: - v = (short) v; - break; - case DATE: - case BEDATE: - case LEDATE: - case LONG: - case BELONG: - case LELONG: - v = (long) v; - break; - case STRING: - break; - default: - kdError(7018) << "" << "signextend" << ": can't happen: m->type=" << m->type << endl; - return 998; //good value - } - return v; -} - -/* - * parse one line from magic file, put into magic[index++] if valid - */ -int KMimeMagic::parse(char *l, int -#ifdef DEBUG_LINENUMBERS - lineno -#endif - ) -{ - int i = 0; - struct magic *m; - char *t, - *s; - /* allocate magic structure entry */ - if ((m = (struct magic *) calloc(1, sizeof(struct magic))) == NULL) { - kdError(7018) << "parse: Out of memory." << endl; - return -1; - } - /* append to linked list */ - m->next = NULL; - if (!conf->magic || !conf->last) { - conf->magic = conf->last = m; - } else { - conf->last->next = m; - conf->last = m; - } - - /* set values in magic structure */ - m->flag = 0; - m->cont_level = 0; -#ifdef DEBUG_LINENUMBERS - m->lineno = lineno; -#endif - - while (*l == '>') { - ++l; /* step over */ - m->cont_level++; - } - - if (m->cont_level != 0 && *l == '(') { - ++l; /* step over */ - m->flag |= INDIR; - } - /* get offset, then skip over it */ - m->offset = (int) strtol(l, &t, 0); - if (l == t) { - kdError(7018) << "parse: offset " << l << " invalid" << endl; - } - l = t; - - if (m->flag & INDIR) { - m->in.type = LONG; - m->in.offset = 0; - /* - * read [.lbs][+-]nnnnn) - */ - if (*l == '.') { - switch (*++l) { - case 'l': - m->in.type = LONG; - break; - case 's': - m->in.type = SHORT; - break; - case 'b': - m->in.type = BYTE; - break; - default: - kdError(7018) << "parse: indirect offset type " << *l << " invalid" << endl; - break; - } - l++; - } - s = l; - if (*l == '+' || *l == '-') - l++; - if (isdigit((unsigned char) *l)) { - m->in.offset = strtol(l, &t, 0); - if (*s == '-') - m->in.offset = -m->in.offset; - } else - t = l; - if (*t++ != ')') { - kdError(7018) << "parse: missing ')' in indirect offset" << endl; - } - l = t; - } - while (isascii((unsigned char) *l) && isdigit((unsigned char) *l)) - ++l; - EATAB; - -#define NBYTE 4 -#define NSHORT 5 -#define NLONG 4 -#define NSTRING 6 -#define NDATE 4 -#define NBESHORT 7 -#define NBELONG 6 -#define NBEDATE 6 -#define NLESHORT 7 -#define NLELONG 6 -#define NLEDATE 6 - - if (*l == 'u') { - ++l; - m->flag |= UNSIGNED; - } - /* get type, skip it */ - if (strncmp(l, "byte", NBYTE) == 0) { - m->type = BYTE; - l += NBYTE; - } else if (strncmp(l, "short", NSHORT) == 0) { - m->type = SHORT; - l += NSHORT; - } else if (strncmp(l, "long", NLONG) == 0) { - m->type = LONG; - l += NLONG; - } else if (strncmp(l, "string", NSTRING) == 0) { - m->type = STRING; - l += NSTRING; - } else if (strncmp(l, "date", NDATE) == 0) { - m->type = DATE; - l += NDATE; - } else if (strncmp(l, "beshort", NBESHORT) == 0) { - m->type = BESHORT; - l += NBESHORT; - } else if (strncmp(l, "belong", NBELONG) == 0) { - m->type = BELONG; - l += NBELONG; - } else if (strncmp(l, "bedate", NBEDATE) == 0) { - m->type = BEDATE; - l += NBEDATE; - } else if (strncmp(l, "leshort", NLESHORT) == 0) { - m->type = LESHORT; - l += NLESHORT; - } else if (strncmp(l, "lelong", NLELONG) == 0) { - m->type = LELONG; - l += NLELONG; - } else if (strncmp(l, "ledate", NLEDATE) == 0) { - m->type = LEDATE; - l += NLEDATE; - } else { - kdError(7018) << "parse: type " << l << " invalid" << endl; - return -1; - } - /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */ - if (*l == '&') { - ++l; - m->mask = signextend(m, strtol(l, &l, 0)); - } else - m->mask = (unsigned long) ~0L; - EATAB; - - switch (*l) { - case '>': - case '<': - /* Old-style anding: "0 byte &0x80 dynamically linked" */ - case '&': - case '^': - case '=': - m->reln = *l; - ++l; - break; - case '!': - if (m->type != STRING) { - m->reln = *l; - ++l; - break; - } - /* FALL THROUGH */ - default: - if (*l == 'x' && isascii((unsigned char) l[1]) && - isspace((unsigned char) l[1])) { - m->reln = *l; - ++l; - goto GetDesc; /* Bill The Cat */ - } - m->reln = '='; - break; - } - EATAB; - - if (getvalue(m, &l)) - return -1; - /* - * now get last part - the description - */ - GetDesc: - EATAB; - if (l[0] == '\b') { - ++l; - m->nospflag = 1; - } else if ((l[0] == '\\') && (l[1] == 'b')) { - ++l; - ++l; - m->nospflag = 1; - } else - m->nospflag = 0; - // Copy description - until EOL or '#' (for comments) - while (*l != '\0' && *l != '#' && i < MAXDESC-1) - m->desc[i++] = *l++; - m->desc[i] = '\0'; - // Remove trailing spaces - while (--i>0 && isspace( m->desc[i] )) - m->desc[i] = '\0'; - - // old code - //while ((m->desc[i++] = *l++) != '\0' && i < MAXDESC) /* NULLBODY */ ; - -#ifdef DEBUG_APPRENTICE - kdDebug(7018) << "parse: line=" << lineno << " m=" << m << " next=" << m->next << " cont=" << m->cont_level << " desc=" << (m->desc ? m->desc : "NULL") << endl; -#endif - return 0; -} - -/* - * Read a numeric value from a pointer, into the value union of a magic - * pointer, according to the magic type. Update the string pointer to point - * just after the number read. Return 0 for success, non-zero for failure. - */ -static int -getvalue(struct magic *m, char **p) -{ - int slen; - - if (m->type == STRING) { - *p = getstr(*p, m->value.s, sizeof(m->value.s), &slen); - m->vallen = slen; - } else if (m->reln != 'x') - m->value.l = signextend(m, strtol(*p, p, 0)); - return 0; -} - -/* - * Convert a string containing C character escapes. Stop at an unescaped - * space or tab. Copy the converted version to "p", returning its length in - * *slen. Return updated scan pointer as function result. - */ -static char * -getstr(register char *s, register char *p, int plen, int *slen) -{ - char *origs = s, - *origp = p; - char *pmax = p + plen - 1; - register int c; - register int val; - - while ((c = *s++) != '\0') { - if (isspace((unsigned char) c)) - break; - if (p >= pmax) { - kdError(7018) << "String too long: " << origs << endl; - break; - } - if (c == '\\') { - switch (c = *s++) { - - case '\0': - goto out; - - default: - *p++ = (char) c; - break; - - case 'n': - *p++ = '\n'; - break; - - case 'r': - *p++ = '\r'; - break; - - case 'b': - *p++ = '\b'; - break; - - case 't': - *p++ = '\t'; - break; - - case 'f': - *p++ = '\f'; - break; - - case 'v': - *p++ = '\v'; - break; - - /* \ and up to 3 octal digits */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - val = c - '0'; - c = *s++; /* try for 2 */ - if (c >= '0' && c <= '7') { - val = (val << 3) | (c - '0'); - c = *s++; /* try for 3 */ - if (c >= '0' && c <= '7') - val = (val << 3) | (c - '0'); - else - --s; - } else - --s; - *p++ = (char) val; - break; - - /* \x and up to 3 hex digits */ - case 'x': - val = 'x'; /* Default if no digits */ - c = hextoint(*s++); /* Get next char */ - if (c >= 0) { - val = c; - c = hextoint(*s++); - if (c >= 0) { - val = (val << 4) + c; - c = hextoint(*s++); - if (c >= 0) { - val = (val << 4) + c; - } else - --s; - } else - --s; - } else - --s; - *p++ = (char) val; - break; - } - } else - *p++ = (char) c; - } - out: - *p = '\0'; - *slen = p - origp; - //for ( char* foo = origp; foo < p ; ++foo ) - // kdDebug(7018) << " " << *foo << endl; - return s; -} - - -/* Single hex char to int; -1 if not a hex char. */ -static int -hextoint(int c) -{ - if (!isascii((unsigned char) c)) - return -1; - if (isdigit((unsigned char) c)) - return c - '0'; - if ((c >= 'a') && (c <= 'f')) - return c + 10 - 'a'; - if ((c >= 'A') && (c <= 'F')) - return c + 10 - 'A'; - return -1; -} - -/* - * Convert the byte order of the data we are looking at - */ -static int -mconvert(union VALUETYPE *p, struct magic *m) -{ - switch (m->type) { - case BYTE: - return 1; - case STRING: - /* Null terminate */ - p->s[sizeof(p->s) - 1] = '\0'; - return 1; -#ifndef WORDS_BIGENDIAN - case SHORT: -#endif - case BESHORT: - p->h = (short) ((p->hs[0] << 8) | (p->hs[1])); - return 1; -#ifndef WORDS_BIGENDIAN - case LONG: - case DATE: -#endif - case BELONG: - case BEDATE: - p->l = (long) - ((p->hl[0] << 24) | (p->hl[1] << 16) | (p->hl[2] << 8) | (p->hl[3])); - return 1; -#ifdef WORDS_BIGENDIAN - case SHORT: -#endif - case LESHORT: - p->h = (short) ((p->hs[1] << 8) | (p->hs[0])); - return 1; -#ifdef WORDS_BIGENDIAN - case LONG: - case DATE: -#endif - case LELONG: - case LEDATE: - p->l = (long) - ((p->hl[3] << 24) | (p->hl[2] << 16) | (p->hl[1] << 8) | (p->hl[0])); - return 1; - default: - kdError(7018) << "mconvert: invalid type " << m->type << endl; - return 0; - } -} - - -static int -mget(union VALUETYPE *p, unsigned char *s, struct magic *m, - int nbytes) -{ - long offset = m->offset; - switch ( m->type ) - { - case BYTE: - if ( offset + 1 > nbytes-1 ) // nbytes = (size of file) + 1 - return 0; - break; - case SHORT: - case BESHORT: - case LESHORT: - if ( offset + 2 > nbytes-1 ) - return 0; - break; - case LONG: - case BELONG: - case LELONG: - case DATE: - case BEDATE: - case LEDATE: - if ( offset + 4 > nbytes-1 ) - return 0; - break; - case STRING: - break; - } - -// The file length might be < sizeof(union VALUETYPE) (David) -// -> pad with zeros (the 'file' command does it this way) -// Thanks to Stan Covington <stan@calderasystems.com> for detailed report - if (offset + (int)sizeof(union VALUETYPE) > nbytes) - { - int have = nbytes - offset; - memset(p, 0, sizeof(union VALUETYPE)); - if (have > 0) - memcpy(p, s + offset, have); - } else - memcpy(p, s + offset, sizeof(union VALUETYPE)); - - if (!mconvert(p, m)) - return 0; - - if (m->flag & INDIR) { - - switch (m->in.type) { - case BYTE: - offset = p->b + m->in.offset; - break; - case SHORT: - offset = p->h + m->in.offset; - break; - case LONG: - offset = p->l + m->in.offset; - break; - } - - if (offset + (int)sizeof(union VALUETYPE) > nbytes) - return 0; - - memcpy(p, s + offset, sizeof(union VALUETYPE)); - - if (!mconvert(p, m)) - return 0; - } - return 1; -} - -static int -mcheck(union VALUETYPE *p, struct magic *m) -{ - register unsigned long l = m->value.l; - register unsigned long v; - int matched; - - if ((m->value.s[0] == 'x') && (m->value.s[1] == '\0')) { - kdError(7018) << "BOINK" << endl; - return 1; - } - switch (m->type) { - case BYTE: - v = p->b; - break; - - case SHORT: - case BESHORT: - case LESHORT: - v = p->h; - break; - - case LONG: - case BELONG: - case LELONG: - case DATE: - case BEDATE: - case LEDATE: - v = p->l; - break; - - case STRING: - l = 0; - /* - * What we want here is: v = strncmp(m->value.s, p->s, - * m->vallen); but ignoring any nulls. bcmp doesn't give - * -/+/0 and isn't universally available anyway. - */ - v = 0; - { - register unsigned char *a = (unsigned char *) m->value.s; - register unsigned char *b = (unsigned char *) p->s; - register int len = m->vallen; - Q_ASSERT(len); - - while (--len >= 0) - if ((v = *b++ - *a++) != 0) - break; - } - break; - default: - kdError(7018) << "mcheck: invalid type " << m->type << endl; - return 0; /* NOTREACHED */ - } -#if 0 - tqDebug("Before signextend %08x", v); -#endif - v = signextend(m, v) & m->mask; -#if 0 - tqDebug("After signextend %08x", v); -#endif - - switch (m->reln) { - case 'x': - matched = 1; - break; - - case '!': - matched = v != l; - break; - - case '=': - matched = v == l; - break; - - case '>': - if (m->flag & UNSIGNED) - matched = v > l; - else - matched = (long) v > (long) l; - break; - - case '<': - if (m->flag & UNSIGNED) - matched = v < l; - else - matched = (long) v < (long) l; - break; - - case '&': - matched = (v & l) == l; - break; - - case '^': - matched = (v & l) != l; - break; - - default: - matched = 0; - kdError(7018) << "mcheck: can't happen: invalid relation " << m->reln << "." << endl; - break; /* NOTREACHED */ - } - - return matched; -} - -/* - * magic_process - process input file fn. Opens the file and reads a - * fixed-size buffer to begin processing the contents. - */ - -void process(struct config_rec* conf, const TQString & fn) -{ - int fd = 0; - unsigned char buf[HOWMANY + 1]; /* one extra for terminating '\0' */ - KDE_struct_stat sb; - int nbytes = 0; /* number of bytes read from a datafile */ - int tagbytes = 0; /* size of prefixed tag */ - TQCString fileName = TQFile::encodeName( fn ); - - /* - * first try judging the file based on its filesystem status - */ - if (fsmagic(conf, fileName, &sb) != 0) { - //resultBuf += "\n"; - return; - } - if ((fd = KDE_open(fileName, O_RDONLY)) < 0) { - /* We can't open it, but we were able to stat it. */ - /* - * if (sb.st_mode & 0002) addResult("writable, "); - * if (sb.st_mode & 0111) addResult("executable, "); - */ - //kdDebug(7018) << "can't read `" << fn << "' (" << strerror(errno) << ")." << endl; - conf->resultBuf = MIME_BINARY_UNREADABLE; - return; - } - /* - * try looking at the first HOWMANY bytes - */ - if ((nbytes = read(fd, (char *) buf, HOWMANY)) == -1) { - kdError(7018) << "" << fn << " read failed (" << strerror(errno) << ")." << endl; - conf->resultBuf = MIME_BINARY_UNREADABLE; - (void)close(fd); - return; - } - if ((tagbytes = tagmagic(buf, nbytes))) { - // Read buffer at new position - lseek(fd, tagbytes, SEEK_SET); - nbytes = read(fd, (char*)buf, HOWMANY); - if (nbytes < 0) { - conf->resultBuf = MIME_BINARY_UNREADABLE; - (void)close(fd); - return; - } - } - if (nbytes == 0) { - conf->resultBuf = MIME_BINARY_ZEROSIZE; - } else { - buf[nbytes++] = '\0'; /* null-terminate it */ - tryit(conf, buf, nbytes); - } - - if ( conf->utimeConf && conf->utimeConf->restoreAccessTime( fn ) ) - { - /* - * Try to restore access, modification times if read it. - * This changes the "change" time (ctime), but we can't do anything - * about that. - */ - struct utimbuf utbuf; - utbuf.actime = sb.st_atime; - utbuf.modtime = sb.st_mtime; - (void) utime(fileName, &utbuf); - } - (void) close(fd); -} - - -static void tryit(struct config_rec* conf, unsigned char *buf, int nb) -{ - /* try tests in /etc/magic (or surrogate magic file) */ - if (match(conf, buf, nb)) - return; - - /* try known keywords, check for ascii-ness too. */ - if (ascmagic(conf, buf, nb) == 1) - return; - - /* see if it's plain text */ - if (textmagic(conf, buf, nb)) - return; - - /* abandon hope, all ye who remain here */ - conf->resultBuf = MIME_BINARY_UNKNOWN; - conf->accuracy = 0; -} - -static int -fsmagic(struct config_rec* conf, const char *fn, KDE_struct_stat *sb) -{ - int ret = 0; - - /* - * Fstat is cheaper but fails for files you don't have read perms on. - * On 4.2BSD and similar systems, use lstat() to identify symlinks. - */ - ret = KDE_lstat(fn, sb); /* don't merge into if; see "ret =" above */ - - if (ret) { - return 1; - - } - /* - * if (sb->st_mode & S_ISUID) resultBuf += "setuid "; - * if (sb->st_mode & S_ISGID) resultBuf += "setgid "; - * if (sb->st_mode & S_ISVTX) resultBuf += "sticky "; - */ - - switch (sb->st_mode & S_IFMT) { - case S_IFDIR: - conf->resultBuf = MIME_INODE_DIR; - return 1; - case S_IFCHR: - conf->resultBuf = MIME_INODE_CDEV; - return 1; - case S_IFBLK: - conf->resultBuf = MIME_INODE_BDEV; - return 1; - /* TODO add code to handle V7 MUX and Blit MUX files */ -#ifdef S_IFIFO - case S_IFIFO: - conf->resultBuf = MIME_INODE_FIFO; - return 1; -#endif -#ifdef S_IFLNK - case S_IFLNK: - { - char buf[BUFSIZ + BUFSIZ + 4]; - register int nch; - KDE_struct_stat tstatbuf; - - if ((nch = readlink(fn, buf, BUFSIZ - 1)) <= 0) { - conf->resultBuf = MIME_INODE_LINK; - //conf->resultBuf += "\nunreadable"; - return 1; - } - buf[nch] = '\0'; /* readlink(2) forgets this */ - /* If broken symlink, say so and quit early. */ - if (*buf == '/') { - if (KDE_stat(buf, &tstatbuf) < 0) { - conf->resultBuf = MIME_INODE_LINK; - //conf->resultBuf += "\nbroken"; - return 1; - } - } else { - char *tmp; - char buf2[BUFSIZ + BUFSIZ + 4]; - - strncpy(buf2, fn, BUFSIZ); - buf2[BUFSIZ] = 0; - - if ((tmp = strrchr(buf2, '/')) == NULL) { - tmp = buf; /* in current dir */ - } else { - /* dir part plus (rel.) link */ - *++tmp = '\0'; - strcat(buf2, buf); - tmp = buf2; - } - if (KDE_stat(tmp, &tstatbuf) < 0) { - conf->resultBuf = MIME_INODE_LINK; - //conf->resultBuf += "\nbroken"; - return 1; - } else - strcpy(buf, tmp); - } - if (conf->followLinks) - process( conf, TQFile::decodeName( buf ) ); - else - conf->resultBuf = MIME_INODE_LINK; - return 1; - } - return 1; -#endif -#ifdef S_IFSOCK -#ifndef __COHERENT__ - case S_IFSOCK: - conf->resultBuf = MIME_INODE_SOCK; - return 1; -#endif -#endif - case S_IFREG: - break; - default: - kdError(7018) << "KMimeMagic::fsmagic: invalid mode 0" << sb->st_mode << "." << endl; - /* NOTREACHED */ - } - - /* - * regular file, check next possibility - */ - if (sb->st_size == 0) { - conf->resultBuf = MIME_BINARY_ZEROSIZE; - return 1; - } - return 0; -} - -/* - * Go through the whole list, stopping if you find a match. Process all the - * continuations of that match before returning. - * - * We support multi-level continuations: - * - * At any time when processing a successful top-level match, there is a current - * continuation level; it represents the level of the last successfully - * matched continuation. - * - * Continuations above that level are skipped as, if we see one, it means that - * the continuation that controls them - i.e, the lower-level continuation - * preceding them - failed to match. - * - * Continuations below that level are processed as, if we see one, it means - * we've finished processing or skipping higher-level continuations under the - * control of a successful or unsuccessful lower-level continuation, and are - * now seeing the next lower-level continuation and should process it. The - * current continuation level reverts to the level of the one we're seeing. - * - * Continuations at the current level are processed as, if we see one, there's - * no lower-level continuation that may have failed. - * - * If a continuation matches, we bump the current continuation level so that - * higher-level continuations are processed. - */ -static int -match(struct config_rec* conf, unsigned char *s, int nbytes) -{ - int cont_level = 0; - union VALUETYPE p; - struct magic *m; - -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "match: conf=" << conf << " m=" << (conf->magic ? "set" : "NULL") << " m->next=" << ((conf->magic && conf->magic->next) ? "set" : "NULL") << " last=" << (conf->last ? "set" : "NULL") << endl; - for (m = conf->magic; m; m = m->next) { - if (isprint((((unsigned long) m) >> 24) & 255) && - isprint((((unsigned long) m) >> 16) & 255) && - isprint((((unsigned long) m) >> 8) & 255) && - isprint(((unsigned long) m) & 255)) { - kdDebug(7018) << "match: POINTER CLOBBERED! " << endl; - break; - } - } -#endif - - for (m = conf->magic; m; m = m->next) { -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "match: line=" << m->lineno << " desc=" << m->desc << endl; -#endif - memset(&p, 0, sizeof(union VALUETYPE)); - - /* check if main entry matches */ - if (!mget(&p, s, m, nbytes) || - !mcheck(&p, m)) { - struct magic *m_cont; - - /* - * main entry didn't match, flush its continuations - */ - if (!m->next || (m->next->cont_level == 0)) { - continue; - } - m_cont = m->next; - while (m_cont && (m_cont->cont_level != 0)) { -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "match: line=" << m->lineno << " cont=" << m_cont->cont_level << " mc=" << m_cont->lineno << " mc->next=" << m_cont << " " << endl; -#endif - /* - * this trick allows us to keep *m in sync - * when the continue advances the pointer - */ - m = m_cont; - m_cont = m_cont->next; - } - continue; - } - /* if we get here, the main entry rule was a match */ - /* this will be the last run through the loop */ -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "match: rule matched, line=" << m->lineno << " type=" << m->type << " " << ((m->type == STRING) ? m->value.s : "") << endl; -#endif - - /* remember the match */ - conf->resultBuf = m->desc; - - cont_level++; - /* - * while (m && m->next && m->next->cont_level != 0 && ( m = - * m->next )) - */ - m = m->next; - while (m && (m->cont_level != 0)) { -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "match: line=" << m->lineno << " cont=" << m->cont_level << " type=" << m->type << " " << ((m->type == STRING) ? m->value.s : "") << endl; -#endif - if (cont_level >= m->cont_level) { - if (cont_level > m->cont_level) { - /* - * We're at the end of the level - * "cont_level" continuations. - */ - cont_level = m->cont_level; - } - if (mget(&p, s, m, nbytes) && - mcheck(&p, m)) { - /* - * This continuation matched. Print - * its message, with a blank before - * it if the previous item printed - * and this item isn't empty. - */ -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "continuation matched" << endl; -#endif - conf->resultBuf = m->desc; - cont_level++; - } - } - /* move to next continuation record */ - m = m->next; - } - // KDE-specific: need an actual mimetype for a real match - // If we only matched a rule with continuations but no mimetype, it's not a match - if ( !conf->resultBuf.isEmpty() ) - { -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "match: matched" << endl; -#endif - return 1; /* all through */ - } - } -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "match: failed" << endl; -#endif - return 0; /* no match at all */ -} - -// Try to parse prefixed tags before matching on content -// Sofar only ID3v2 tags (<=.4) are handled -static int tagmagic(unsigned char *buf, int nbytes) -{ - if(nbytes<40) return 0; - if(buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') { - int size = 10; - // Sanity (known version, no unknown flags) - if(buf[3] > 4) return 0; - if(buf[5] & 0x0F) return 0; - // Tag has v4 footer - if(buf[5] & 0x10) size += 10; - // Calculated syncsafe size - size += buf[9]; - size += buf[8] << 7; - size += buf[7] << 14; - size += buf[6] << 21; - return size; - } - return 0; -} - -struct Token { - char *data; - int length; -}; - -struct Tokenizer -{ - Tokenizer(char* buf, int nbytes) { - data = buf; - length = nbytes; - pos = 0; - } - bool isNewLine() { - return newline; - } - Token* nextToken() { - if (pos == 0) - newline = true; - else - newline = false; - token.data = data+pos; - token.length = 0; - while(pos<length) { - switch (data[pos]) { - case '\n': - newline = true; - case '\0': - case '\t': - case ' ': - case '\r': - case '\f': - case ',': - case ';': - case '>': - if (token.length == 0) token.data++; - else - return &token; - break; - default: - token.length++; - } - pos++; - } - return &token; - } - -private: - Token token; - char* data; - int length; - int pos; - bool newline; -}; - - -/* an optimization over plain strcmp() */ -//#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) -static inline bool STREQ(const Token *token, const char *b) { - const char *a = token->data; - int len = token->length; - if (a == b) return true; - while(*a && *b && len > 0) { - if (*a != *b) return false; - a++; b++; len--; - } - return (len == 0 && *b == 0); -} - -static int ascmagic(struct config_rec* conf, unsigned char *buf, int nbytes) -{ - int i; - double pct, maxpct, pctsum; - double pcts[NTYPES]; - int mostaccurate, tokencount; - int typeset, jonly, conly, jconly, objconly, cpponly; - int has_escapes = 0; - //unsigned char *s; - //char nbuf[HOWMANY + 1]; /* one extra for terminating '\0' */ - - /* these are easy, do them first */ - conf->accuracy = 70; - - /* - * for troff, look for . + letter + letter or .\"; this must be done - * to disambiguate tar archives' ./file and other trash from real - * troff input. - */ - if (*buf == '.') { - unsigned char *tp = buf + 1; - - while (isascii(*tp) && isspace(*tp)) - ++tp; /* skip leading whitespace */ - if ((isascii(*tp) && (isalnum(*tp) || *tp == '\\') && - isascii(*(tp + 1)) && (isalnum(*(tp + 1)) || *tp == '"'))) { - conf->resultBuf = MIME_APPL_TROFF; - return 1; - } - } - if ((*buf == 'c' || *buf == 'C') && - isascii(*(buf + 1)) && isspace(*(buf + 1))) { - /* Fortran */ - conf->resultBuf = MIME_TEXT_FORTRAN; - return 1; - } - assert(nbytes-1 < HOWMANY + 1); - /* look for tokens - this is expensive! */ - has_escapes = (memchr(buf, '\033', nbytes) != NULL); - Tokenizer tokenizer((char*)buf, nbytes); - const Token* token; - bool linecomment = false, blockcomment = false; - const struct names *p; - int typecount[NTYPES]; -/* - * Fritz: - * Try a little harder on C/C++/Java. - */ - memset(&typecount, 0, sizeof(typecount)); - typeset = 0; - jonly = 0; - conly = 0; - jconly = 0; - objconly = 0; - cpponly = 0; - tokencount = 0; - bool foundClass = false; // mandatory for java - // first collect all possible types and count matches - // we stop at '>' too, because of "<title>blah</title>" on HTML pages - while ((token = tokenizer.nextToken())->length > 0) { -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "KMimeMagic::ascmagic token=" << token << endl; -#endif - if (linecomment && tokenizer.isNewLine()) - linecomment = false; - if (blockcomment && STREQ(token, "*/")) { - blockcomment = false; - continue; - } - for (p = names; p->name ; p++) { - if (STREQ(token, p->name)) { -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "KMimeMagic::ascmagic token matches ! name=" << p->name << " type=" << p->type << endl; -#endif - tokencount++; - typeset |= p->type; - if(p->type & (L_C|L_CPP|L_JAVA|L_OBJC)) { - if (linecomment || blockcomment) { - continue; - } - else { - switch(p->type & (L_C|L_CPP|L_JAVA|L_OBJC)) - { - case L_JAVA: - jonly++; - break; - case L_OBJC: - objconly++; - break; - case L_CPP: - cpponly++; - break; - case (L_CPP|L_JAVA): - jconly++; - if ( !foundClass && STREQ(token, "class") ) - foundClass = true; - break; - case (L_C|L_CPP): - conly++; - break; - default: - if (STREQ(token, "//")) linecomment = true; - if (STREQ(token, "/*")) blockcomment = true; - } - } - } - for (i = 0; i < (int)NTYPES; i++) { - if ((1 << i) & p->type) typecount[i]+= p->type & FLAG_STRONG ? 2 : 1; - } - } - } - } - - if (typeset & (L_C|L_CPP|L_JAVA|L_OBJC)) { - conf->accuracy = 60; - if (!(typeset & ~(L_C|L_CPP|L_JAVA|L_OBJC))) { -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "C/C++/Java/ObjC: jonly=" << jonly << " conly=" << conly << " jconly=" << jconly << " objconly=" << objconly << endl; -#endif - if (jonly > 1 && foundClass) { - // At least two java-only tokens have matched, including "class" - conf->resultBuf = TQString(types[P_JAVA].type); - return 1; - } - if (jconly > 1) { - // At least two non-C (only C++ or Java) token have matched. - if (typecount[P_JAVA] < typecount[P_CPP]) - conf->resultBuf = TQString(types[P_CPP].type); - else - conf->resultBuf = TQString(types[P_JAVA].type); - return 1; - } - if (conly + cpponly > 1) { - // Either C or C++. - if (cpponly > 0) - conf->resultBuf = TQString(types[P_CPP].type); - else - conf->resultBuf = TQString(types[P_C].type); - return 1; - } - if (objconly > 0) { - conf->resultBuf = TQString(types[P_OBJC].type); - return 1; - } - } - } - - /* Neither C, C++ or Java (or all of them without able to distinguish): - * Simply take the token-class with the highest - * matchcount > 0 - */ - mostaccurate = -1; - maxpct = pctsum = 0.0; - for (i = 0; i < (int)NTYPES; i++) { - if (typecount[i] > 1) { // one word is not enough, we need at least two - pct = (double)typecount[i] / (double)types[i].kwords * - (double)types[i].weight; - pcts[i] = pct; - pctsum += pct; - if (pct > maxpct) { - maxpct = pct; - mostaccurate = i; - } -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "" << types[i].type << " has " << typecount[i] << " hits, " << types[i].kwords << " kw, weight " << types[i].weight << ", " << pct << " -> max = " << maxpct << "\n" << endl; -#endif - } - } - if (mostaccurate >= 0) { - if ( mostaccurate != P_JAVA || foundClass ) // 'class' mandatory for java - { - conf->accuracy = (int)(pcts[mostaccurate] / pctsum * 60); -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "mostaccurate=" << mostaccurate << " pcts=" << pcts[mostaccurate] << " pctsum=" << pctsum << " accuracy=" << conf->accuracy << endl; -#endif - conf->resultBuf = TQString(types[mostaccurate].type); - return 1; - } - } - - switch (is_tar(buf, nbytes)) { - case 1: - /* V7 tar archive */ - conf->resultBuf = MIME_APPL_TAR; - conf->accuracy = 90; - return 1; - case 2: - /* POSIX tar archive */ - conf->resultBuf = MIME_APPL_TAR; - conf->accuracy = 90; - return 1; - } - - for (i = 0; i < nbytes; i++) { - if (!isascii(*(buf + i))) - return 0; /* not all ascii */ - } - - /* all else fails, but it is ascii... */ - conf->accuracy = 90; - if (has_escapes) { - /* text with escape sequences */ - /* we leave this open for further differentiation later */ - conf->resultBuf = MIME_TEXT_UNKNOWN; - } else { - /* plain text */ - conf->resultBuf = MIME_TEXT_PLAIN; - } - return 1; -} - -/* Maximal length of a line we consider "reasonable". */ -#define TEXT_MAXLINELEN 300 - -// This code is taken from the "file" command, where it is licensed -// in the "beer-ware license" :-) -// Original author: <joerg@FreeBSD.ORG> -// Simplified by David Faure to avoid the static array char[256]. -static int textmagic(struct config_rec* conf, unsigned char * buf, int nbytes) -{ - int i; - unsigned char *cp; - - nbytes--; - - /* First, look whether there are "unreasonable" characters. */ - for (i = 0, cp = buf; i < nbytes; i++, cp++) - if ((*cp < 8) || (*cp>13 && *cp<32 && *cp!=27 ) || (*cp==0x7F)) - return 0; - - /* Now, look whether the file consists of lines of - * "reasonable" length. */ - - for (i = 0; i < nbytes;) { - cp = (unsigned char *) memchr(buf, '\n', nbytes - i); - if (cp == NULL) { - /* Don't fail if we hit the end of buffer. */ - if (i + TEXT_MAXLINELEN >= nbytes) - break; - else - return 0; - } - if (cp - buf > TEXT_MAXLINELEN) - return 0; - i += (cp - buf + 1); - buf = cp + 1; - } - conf->resultBuf = MIME_TEXT_PLAIN; - return 1; -} - - -/* - * is_tar() -- figure out whether file is a tar archive. - * - * Stolen (by author of file utility) from the public domain tar program: Public - * Domain version written 26 Aug 1985 John Gilmore (ihnp4!hoptoad!gnu). - * - * @(#)list.c 1.18 9/23/86 Public Domain - gnu $Id: mod_mime_magic.c,v 1.7 - * 1997/06/24 00:41:02 ikluft Exp ikluft $ - * - * Comments changed and some code/comments reformatted for file command by Ian - * Darwin. - */ - -#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') ) - -/* - * Return 0 if the checksum is bad (i.e., probably not a tar archive), 1 for - * old UNIX tar file, 2 for Unix Std (POSIX) tar file. - */ - -static int -is_tar(unsigned char *buf, int nbytes) -{ - register union record *header = (union record *) buf; - register int i; - register long sum, - recsum; - register char *p; - - if (nbytes < (int)sizeof(union record)) - return 0; - - recsum = from_oct(8, header->header.chksum); - - sum = 0; - p = header->charptr; - for (i = sizeof(union record); --i >= 0;) { - /* - * We can't use unsigned char here because of old compilers, - * e.g. V7. - */ - sum += 0xFF & *p++; - } - - /* Adjust checksum to count the "chksum" field as blanks. */ - for (i = sizeof(header->header.chksum); --i >= 0;) - sum -= 0xFF & header->header.chksum[i]; - sum += ' ' * sizeof header->header.chksum; - - if (sum != recsum) - return 0; /* Not a tar archive */ - - if (0 == strcmp(header->header.magic, TMAGIC)) - return 2; /* Unix Standard tar archive */ - - return 1; /* Old fashioned tar archive */ -} - - -/* - * Quick and dirty octal conversion. - * - * Result is -1 if the field is invalid (all blank, or nonoctal). - */ -static long -from_oct(int digs, char *where) -{ - register long value; - - while (isspace(*where)) { /* Skip spaces */ - where++; - if (--digs <= 0) - return -1; /* All blank field */ - } - value = 0; - while (digs > 0 && isodigit(*where)) { /* Scan til nonoctal */ - value = (value << 3) | (*where++ - '0'); - --digs; - } - - if (digs > 0 && *where && !isspace(*where)) - return -1; /* Ended on non-space/nul */ - - return value; -} - -KMimeMagic::KMimeMagic() -{ - // Magic file detection init - TQString mimefile = locate( "mime", "magic" ); - init( mimefile ); - // Add snippets from share/config/magic/* - TQStringList snippets = TDEGlobal::dirs()->findAllResources( "config", "magic/*.magic", true ); - for ( TQStringList::Iterator it = snippets.begin() ; it != snippets.end() ; ++it ) - if ( !mergeConfig( *it ) ) - kdWarning() << k_funcinfo << "Failed to parse " << *it << endl; -} - -KMimeMagic::KMimeMagic(const TQString & _configfile) -{ - init( _configfile ); -} - -void KMimeMagic::init( const TQString& _configfile ) -{ - int result; - conf = new config_rec; - - /* set up the magic list (empty) */ - conf->magic = conf->last = NULL; - magicResult = NULL; - conf->followLinks = false; - - conf->utimeConf = 0L; // created on demand - /* on the first time through we read the magic file */ - result = apprentice(_configfile); - if (result == -1) - return; -#ifdef MIME_MAGIC_DEBUG_TABLE - test_table(); -#endif -} - -/* - * The destructor. - * Free the magic-table and other resources. - */ -KMimeMagic::~KMimeMagic() -{ - if (conf) { - struct magic *p = conf->magic; - struct magic *q; - while (p) { - q = p; - p = p->next; - free(q); - } - delete conf->utimeConf; - delete conf; - } - delete magicResult; -} - -bool -KMimeMagic::mergeConfig(const TQString & _configfile) -{ - kdDebug(7018) << k_funcinfo << _configfile << endl; - int result; - - if (_configfile.isEmpty()) - return false; - result = apprentice(_configfile); - if (result == -1) { - return false; - } -#ifdef MIME_MAGIC_DEBUG_TABLE - test_table(); -#endif - return true; -} - -bool -KMimeMagic::mergeBufConfig(char * _configbuf) -{ - int result; - - if (conf) { - result = buff_apprentice(_configbuf); - if (result == -1) - return false; -#ifdef MIME_MAGIC_DEBUG_TABLE - test_table(); -#endif - return true; - } - return false; -} - -void -KMimeMagic::setFollowLinks( bool _enable ) -{ - conf->followLinks = _enable; -} - -KMimeMagicResult * -KMimeMagic::findBufferType(const TQByteArray &array) -{ - unsigned char buf[HOWMANY + 1]; /* one extra for terminating '\0' */ - - conf->resultBuf = TQString::null; - if ( !magicResult ) - magicResult = new KMimeMagicResult(); - magicResult->setInvalid(); - conf->accuracy = 100; - - int nbytes = array.size(); - - if (nbytes > HOWMANY) - nbytes = HOWMANY; - memcpy(buf, array.data(), nbytes); - if (nbytes == 0) { - conf->resultBuf = MIME_BINARY_ZEROSIZE; - } else { - buf[nbytes++] = '\0'; /* null-terminate it */ - tryit(conf, buf, nbytes); - } - /* if we have any results, put them in the request structure */ - magicResult->setMimeType(conf->resultBuf.stripWhiteSpace()); - magicResult->setAccuracy(conf->accuracy); - return magicResult; -} - -static void -refineResult(KMimeMagicResult *r, const TQString & _filename) -{ - TQString tmp = r->mimeType(); - if (tmp.isEmpty()) - return; - if ( tmp == "text/x-c" || tmp == "text/x-objc" ) - { - if ( _filename.right(2) == ".h" ) - tmp += "hdr"; - else - tmp += "src"; - r->setMimeType(tmp); - } - else - if ( tmp == "text/x-c++" ) - { - if ( _filename.endsWith(".h") - || _filename.endsWith(".hh") - || _filename.endsWith(".H") - || !_filename.right(4).contains('.')) - tmp += "hdr"; - else - tmp += "src"; - r->setMimeType(tmp); - } - else - if ( tmp == "application/x-sharedlib" ) - { - if ( _filename.find( ".so" ) == -1 ) - { - tmp = "application/x-executable"; - r->setMimeType( tmp ); - } - } -} - -KMimeMagicResult * -KMimeMagic::findBufferFileType( const TQByteArray &data, - const TQString &fn) -{ - KMimeMagicResult * r = findBufferType( data ); - refineResult(r, fn); - return r; -} - -/* - * Find the content-type of the given file. - */ -KMimeMagicResult* KMimeMagic::findFileType(const TQString & fn) -{ -#ifdef DEBUG_MIMEMAGIC - kdDebug(7018) << "KMimeMagic::findFileType " << fn << endl; -#endif - conf->resultBuf = TQString::null; - - if ( !magicResult ) - magicResult = new KMimeMagicResult(); - magicResult->setInvalid(); - conf->accuracy = 100; - - if ( !conf->utimeConf ) - conf->utimeConf = new KMimeMagicUtimeConf(); - - /* process it based on the file contents */ - process(conf, fn ); - - /* if we have any results, put them in the request structure */ - //finishResult(); - magicResult->setMimeType(conf->resultBuf.stripWhiteSpace()); - magicResult->setAccuracy(conf->accuracy); - refineResult(magicResult, fn); - return magicResult; -} diff --git a/kio/kio/kmimemagic.h b/kio/kio/kmimemagic.h deleted file mode 100644 index f5430a219..000000000 --- a/kio/kio/kmimemagic.h +++ /dev/null @@ -1,218 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/* - * KMimeMagic is inspired by the code of the - * Apache Web Server. - * - * Rewritten for KDE by Fritz Elfert - * fritz@kde.org - * Adaptations by Torben Weis <weis@kde.org> - * Fixes and documentation by David Faure <faure@kde.org> - */ - -#ifndef KMIMEMAGIC_H -#define KMIMEMAGIC_H - -#include <tqstring.h> -#include <tdelibs_export.h> - -class KMimeMagic; // see below (read this one first) - -/** - * @deprecated Use KMimeType::findByContent() instead - * May be removed in KDE 4.0. - * Returned by KMimeMagic @p find...Type methods. - * - * It contains the mimetype and the encoding of - * the file or buffer read. - */ -class TDEIO_EXPORT_DEPRECATED KMimeMagicResult -{ -public: - KMimeMagicResult() { m_iAccuracy = 100; } - ~KMimeMagicResult() { } - - /** - * Retrieve the mimetype (e.g. "text/html") of the file or buffer parsed. - */ - TQString mimeType() const { return m_strMimeType; } - /** - * Retrieve the accuracy of the matching. - */ - int accuracy() const { return m_iAccuracy; } - /** - * Returns whether the result is valid (i.e. mimetype not empty). - */ - bool isValid() const { return !m_strMimeType.isEmpty(); } - - ///////////////// - // Internal functions only - ///////////////// - void setMimeType( const TQString& _mime ) { m_strMimeType = _mime; } - void setAccuracy( int _accuracy ) { m_iAccuracy = _accuracy; } - void setInvalid() { m_strMimeType = TQString::null; } - -protected: - TQString m_strMimeType; - int m_iAccuracy; -}; - -/** - * @deprecated Use KMimeType::findByContent() instead - * May be removed in KDE 4.0. - * Determine auto-magically the type of file, - * not only by using its extension, but also by reading its contents. - * - * - * Unless specified otherwise, KMimeMagic uses - * $TDEDIR/share/mimelnk/magic for this purpose. - * - * To make KMimeMagic restore the 'atime' of a file after it opened it, - * add its directory in kmimemagicrc like: - * [Settings] - * atimeDirs=/tmp,/var/tmp,/home/dfaure/tmp - * This isn't done by default because it changes the 'ctime'. - * See kmimemagic.cpp for a full discussion on this issue. - * - * The basic usage of KMimeMagic is : - * @li Get a pointer to it, using KMimeMagic::self(). - * @li Use it for any file or buffer you want, using one of the three - * @p find...Type() methods. - * - * The result is contained in the class KMimeMagicResult. - */ -class TDEIO_EXPORT_DEPRECATED KMimeMagic -{ -public: - /** - * Create a parser and initialize it with the KDE-global data: - * the "magic" config file as well as the snippets from share/config/magic. - * @since 3.1 - */ - KMimeMagic(); - - /** - * Create a parser and initialize it with the given config file. - */ - KMimeMagic( const TQString & configFile ); - - /** - * Destroy the parser. - */ - ~KMimeMagic(); - - /** - * Merge an existing parse table with the data from the - * given file. - * - * @return @p true on success. - */ - bool mergeConfig( const TQString & configFile ); - - /** - * Merge an existing parse table with the data from the - * given buffer. - * - * @return @p true on success. - */ - bool mergeBufConfig(char *); - - /** - * Enable/Disable follow-links. - * - * (Default is disabled.) - */ - void setFollowLinks( bool _enable ); - - /** - * Try to find a MimeType for the given file. - * - * If no special - * MimeType is found, the default MimeType is returned. - * This function looks at the content of the file. - * - * @return A pointer to the result object. Do @em not delete the - * result object. After another call to KMimeMagic - * the returned result object changes its value - * since it is reused by KMimeMagic. - */ - KMimeMagicResult* findFileType( const TQString & _filename ); - - /** - * Same functionality as above, except data is not - * read from a file. - * - * Instead a buffer can be supplied which - * is examined. - * - * @return A pointer to the result object. Do @em not delete the - * result object. After another call to KMimeMagic - * the returned result object changes its value - * since it is reused by KMimeMagic. - */ - KMimeMagicResult* findBufferType( const TQByteArray &p ); - - /** - * Same functionality as findBufferType() but with - * additional capability of distinguishing between - * C-headers and C-Source. - * - * For this purpose this function looks - * at the extension of the filename. This means that 'filename' - * can be a filename on some FTP server, too. - * - * @return A pointer to the result object. Do @em not delete the - * result object. After another call to KMimeMagic - * the returned result object changes its value - * since it is reused by KMimeMagic. - */ - KMimeMagicResult * findBufferFileType( const TQByteArray &, const TQString & filename ); - - /** - * Returns a pointer to the unique KMimeMagic instance in this process. - */ - static KMimeMagic* self(); - -protected: - /** - * The result type. - */ - KMimeMagicResult * magicResult; - - static void initStatic(); - static KMimeMagic* s_pSelf; - -private: - void init( const TQString& configFile ); - - bool bunused; - TQString sunused; - - int parse_line(char *line, int *rule, int lineno); - int parse(char *, int); - int buff_apprentice(char*buff); - int apprentice(const TQString &configFile); - - struct config_rec *conf; // this is also our "d pointer" - int iunused; -}; - -#endif - diff --git a/kio/kio/kmimetype.cpp b/kio/kio/kmimetype.cpp deleted file mode 100644 index c6f879a73..000000000 --- a/kio/kio/kmimetype.cpp +++ /dev/null @@ -1,1172 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 1999 Waldo Bastian <bastian@kde.org> - * David Faure <faure@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation; - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ -// $Id$ - -#include <config.h> - -#include <sys/types.h> -#include <sys/stat.h> - -#include <assert.h> -#include <dirent.h> -#include <errno.h> -#include <stddef.h> -#include <unistd.h> -#include <stdlib.h> - -#include <kprotocolinfo.h> -#include <kio/global.h> -#include "kmimetype.h" -#include "kservicetypefactory.h" -#include "kmimemagic.h" -#include "kservice.h" -#include "krun.h" -#include "kautomount.h" -#include <kdirnotify_stub.h> - -#include <tqstring.h> -#include <tqfile.h> -#include <kmessageboxwrapper.h> - -#include <dcopclient.h> -#include <dcopref.h> -#include <kapplication.h> -#include <kprocess.h> -#include <kdebug.h> -#include <kdesktopfile.h> -#include <kdirwatch.h> -#include <kiconloader.h> -#include <klocale.h> -#include <ksimpleconfig.h> -#include <kstandarddirs.h> -#include <kurl.h> -#include <tdesycoca.h> -#include <kde_file.h> - -template class KSharedPtr<KMimeType>; -template class TQValueList<KMimeType::Ptr>; - -KMimeType::Ptr KMimeType::s_pDefaultType = 0L; -bool KMimeType::s_bChecked = false; - -void KMimeType::buildDefaultType() -{ - assert ( !s_pDefaultType ); - // Try to find the default type - KServiceType * mime = KServiceTypeFactory::self()-> - findServiceTypeByName( defaultMimeType() ); - - if (mime && mime->isType( KST_KMimeType )) - { - s_pDefaultType = KMimeType::Ptr((KMimeType *) mime); - } - else - { - errorMissingMimeType( defaultMimeType() ); - KStandardDirs stdDirs; - TQString sDefaultMimeType = stdDirs.resourceDirs("mime").first()+defaultMimeType()+".desktop"; - s_pDefaultType = new KMimeType( sDefaultMimeType, defaultMimeType(), - "unknown", "mime", TQStringList() ); - } -} - -KMimeType::Ptr KMimeType::defaultMimeTypePtr() -{ - if ( !s_pDefaultType ) // we need a default type first - buildDefaultType(); - return s_pDefaultType; -} - -// Check for essential mimetypes -void KMimeType::checkEssentialMimeTypes() -{ - if ( s_bChecked ) // already done - return; - if ( !s_pDefaultType ) // we need a default type first - buildDefaultType(); - - s_bChecked = true; // must be done before building mimetypes - - // No Mime-Types installed ? - // Lets do some rescue here. - if ( !KServiceTypeFactory::self()->checkMimeTypes() ) - { - KMessageBoxWrapper::error( 0L, i18n( "No mime types installed." ) ); - return; // no point in going any further - } - - if ( KMimeType::mimeType( "inode/directory" ) == s_pDefaultType ) - errorMissingMimeType( "inode/directory" ); - if ( KMimeType::mimeType( "inode/directory-locked" ) == s_pDefaultType ) - errorMissingMimeType( "inode/directory-locked" ); - if ( KMimeType::mimeType( "inode/blockdevice" ) == s_pDefaultType ) - errorMissingMimeType( "inode/blockdevice" ); - if ( KMimeType::mimeType( "inode/chardevice" ) == s_pDefaultType ) - errorMissingMimeType( "inode/chardevice" ); - if ( KMimeType::mimeType( "inode/socket" ) == s_pDefaultType ) - errorMissingMimeType( "inode/socket" ); - if ( KMimeType::mimeType( "inode/fifo" ) == s_pDefaultType ) - errorMissingMimeType( "inode/fifo" ); - if ( KMimeType::mimeType( "application/x-shellscript" ) == s_pDefaultType ) - errorMissingMimeType( "application/x-shellscript" ); - if ( KMimeType::mimeType( "application/x-executable" ) == s_pDefaultType ) - errorMissingMimeType( "application/x-executable" ); - if ( KMimeType::mimeType( "application/x-desktop" ) == s_pDefaultType ) - errorMissingMimeType( "application/x-desktop" ); -} - -void KMimeType::errorMissingMimeType( const TQString& _type ) -{ - TQString tmp = i18n( "Could not find mime type\n%1" ).arg( _type ); - - KMessageBoxWrapper::sorry( 0, tmp ); -} - -KMimeType::Ptr KMimeType::mimeType( const TQString& _name ) -{ - KServiceType * mime = KServiceTypeFactory::self()->findServiceTypeByName( _name ); - - if ( !mime || !mime->isType( KST_KMimeType ) ) - { - // When building tdesycoca, findServiceTypeByName doesn't create an object - // but returns one from a dict. - if ( !KSycoca::self()->isBuilding() ) - delete mime; - if ( !s_pDefaultType ) - buildDefaultType(); - return s_pDefaultType; - } - - // We got a mimetype - return KMimeType::Ptr((KMimeType *) mime); -} - -KMimeType::List KMimeType::allMimeTypes() -{ - return KServiceTypeFactory::self()->allMimeTypes(); -} - -KMimeType::Ptr KMimeType::findByURL( const KURL& _url, mode_t _mode, - bool _is_local_file, bool _fast_mode ) -{ - checkEssentialMimeTypes(); - TQString path = _url.path(); - - if ( !_fast_mode && !_is_local_file && _url.isLocalFile() ) - _is_local_file = true; - - if ( !_fast_mode && _is_local_file && (_mode == 0 || _mode == (mode_t)-1) ) - { - KDE_struct_stat buff; - if ( KDE_stat( TQFile::encodeName(path), &buff ) != -1 ) - _mode = buff.st_mode; - } - - // Look at mode_t first - if ( S_ISDIR( _mode ) ) - { - // Special hack for local files. We want to see whether we - // are allowed to enter the directory - if ( _is_local_file ) - { - if ( access( TQFile::encodeName(path), R_OK ) == -1 ) - return mimeType( "inode/directory-locked" ); - } - return mimeType( "inode/directory" ); - } - if ( S_ISCHR( _mode ) ) - return mimeType( "inode/chardevice" ); - if ( S_ISBLK( _mode ) ) - return mimeType( "inode/blockdevice" ); - if ( S_ISFIFO( _mode ) ) - return mimeType( "inode/fifo" ); - if ( S_ISSOCK( _mode ) ) - return mimeType( "inode/socket" ); - // KMimeMagic can do that better for local files - if ( !_is_local_file && S_ISREG( _mode ) && ( _mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) ) - return mimeType( "application/x-executable" ); - - TQString fileName ( _url.fileName() ); - - static const TQString& slash = TDEGlobal::staticQString("/"); - if ( ! fileName.isNull() && !path.endsWith( slash ) ) - { - // Try to find it out by looking at the filename - KMimeType::Ptr mime = KServiceTypeFactory::self()->findFromPattern( fileName ); - if ( mime ) - { - // Found something - can we trust it ? (e.g. don't trust *.pl over HTTP, could be anything) - if ( _is_local_file || _url.hasSubURL() || // Explicitly trust suburls - KProtocolInfo::determineMimetypeFromExtension( _url.protocol() ) ) - { - if ( _is_local_file && !_fast_mode ) { - if ( mime->patternsAccuracy()<100 ) - { - KMimeMagicResult* result = - KMimeMagic::self()->findFileType( path ); - - if ( result && result->isValid() && result->accuracy() > 0 ) - return mimeType( result->mimeType() ); - } - } - - return mime; - } - } - - static const TQString& dotdesktop = TDEGlobal::staticQString(".desktop"); - static const TQString& dotkdelnk = TDEGlobal::staticQString(".kdelnk"); - static const TQString& dotdirectory = TDEGlobal::staticQString(".directory"); - - // Another filename binding, hardcoded, is .desktop: - if ( fileName.endsWith( dotdesktop ) ) - return mimeType( "application/x-desktop" ); - // Another filename binding, hardcoded, is .kdelnk; - // this is preserved for backwards compatibility - if ( fileName.endsWith( dotkdelnk ) ) - return mimeType( "application/x-desktop" ); - // .directory files are detected as x-desktop by mimemagic - // but don't have a Type= entry. Better cheat and say they are text files - if ( fileName == dotdirectory ) - return mimeType( "text/plain" ); - } - - if ( !_is_local_file || _fast_mode ) - { - TQString def = KProtocolInfo::defaultMimetype( _url ); - if ( !def.isEmpty() && def != defaultMimeType() ) - { - // The protocol says it always returns a given mimetype (e.g. text/html for "man:") - return mimeType( def ); - } - if ( path.endsWith( slash ) || path.isEmpty() ) - { - // We have no filename at all. Maybe the protocol has a setting for - // which mimetype this means (e.g. directory). - // For HTTP (def==defaultMimeType()) we don't assume anything, - // because of redirections (e.g. freshmeat downloads). - if ( def.isEmpty() ) - { - // Assume inode/directory, if the protocol supports listing. - if ( KProtocolInfo::supportsListing( _url ) ) - return mimeType( TQString::fromLatin1("inode/directory") ); - else - return defaultMimeTypePtr(); // == 'no idea', e.g. for "data:,foo/" - } - } - - // No more chances for non local URLs - return defaultMimeTypePtr(); - } - - // Do some magic for local files - //kdDebug(7009) << TQString("Mime Type finding for '%1'").arg(path) << endl; - KMimeMagicResult* result = KMimeMagic::self()->findFileType( path ); - - // If we still did not find it, we must assume the default mime type - if ( !result || !result->isValid() ) - return defaultMimeTypePtr(); - - // The mimemagic stuff was successful - return mimeType( result->mimeType() ); -} - -KMimeType::Ptr KMimeType::findByURL( const KURL& _url, mode_t _mode, - bool _is_local_file, bool _fast_mode, - bool *accurate) -{ - KMimeType::Ptr mime = findByURL(_url, _mode, _is_local_file, _fast_mode); - if (accurate) *accurate = !(_fast_mode) || ((mime->patternsAccuracy() == 100) && mime != defaultMimeTypePtr()); - return mime; -} - -KMimeType::Ptr KMimeType::diagnoseFileName(const TQString &fileName, TQString &pattern) -{ - return KServiceTypeFactory::self()->findFromPattern( fileName, &pattern ); -} - -KMimeType::Ptr KMimeType::findByPath( const TQString& path, mode_t mode, bool fast_mode ) -{ - KURL u; - u.setPath(path); - return findByURL( u, mode, true, fast_mode ); -} - -KMimeType::Ptr KMimeType::findByContent( const TQByteArray &data, int *accuracy ) -{ - KMimeMagicResult *result = KMimeMagic::self()->findBufferType(data); - if (accuracy) - *accuracy = result->accuracy(); - return mimeType( result->mimeType() ); -} - -KMimeType::Ptr KMimeType::findByFileContent( const TQString &fileName, int *accuracy ) -{ - KMimeMagicResult *result = KMimeMagic::self()->findFileType(fileName); - if (accuracy) - *accuracy = result->accuracy(); - return mimeType( result->mimeType() ); -} - -#define GZIP_MAGIC1 0x1f -#define GZIP_MAGIC2 0x8b - -KMimeType::Format KMimeType::findFormatByFileContent( const TQString &fileName ) -{ - KMimeType::Format result; - result.compression = Format::NoCompression; - KMimeType::Ptr mime = findByPath(fileName); - - result.text = mime->name().startsWith("text/"); - TQVariant v = mime->property("X-TDE-text"); - if (v.isValid()) - result.text = v.toBool(); - - if (mime->name().startsWith("inode/")) - return result; - - TQFile f(fileName); - if (f.open(IO_ReadOnly)) - { - unsigned char buf[10+1]; - int l = f.readBlock((char *)buf, 10); - if ((l > 2) && (buf[0] == GZIP_MAGIC1) && (buf[1] == GZIP_MAGIC2)) - result.compression = Format::GZipCompression; - } - return result; -} - -KMimeType::KMimeType( const TQString & _fullpath, const TQString& _type, const TQString& _icon, - const TQString& _comment, const TQStringList& _patterns ) - : KServiceType( _fullpath, _type, _icon, _comment ) -{ - m_lstPatterns = _patterns; -} - -KMimeType::KMimeType( const TQString & _fullpath ) : KServiceType( _fullpath ) -{ - KDesktopFile _cfg( _fullpath, true ); - init ( &_cfg ); - - if ( !isValid() ) - kdWarning(7009) << "mimetype not valid '" << m_strName << "' (missing entry in the file ?)" << endl; -} - -KMimeType::KMimeType( KDesktopFile *config ) : KServiceType( config ) -{ - init( config ); - - if ( !isValid() ) - kdWarning(7009) << "mimetype not valid '" << m_strName << "' (missing entry in the file ?)" << endl; -} - -void KMimeType::init( KDesktopFile * config ) -{ - config->setDesktopGroup(); - m_lstPatterns = config->readListEntry( "Patterns", ';' ); - - // Read the X-TDE-AutoEmbed setting and store it in the properties map - TQString XKDEAutoEmbed = TQString::fromLatin1("X-TDE-AutoEmbed"); - if ( config->hasKey( XKDEAutoEmbed ) ) - m_mapProps.insert( XKDEAutoEmbed, TQVariant( config->readBoolEntry( XKDEAutoEmbed ), 0 ) ); - - TQString XKDEText = TQString::fromLatin1("X-TDE-text"); - if ( config->hasKey( XKDEText ) ) - m_mapProps.insert( XKDEText, config->readBoolEntry( XKDEText ) ); - - TQString XKDEIsAlso = TQString::fromLatin1("X-TDE-IsAlso"); - if ( config->hasKey( XKDEIsAlso ) ) { - TQString inherits = config->readEntry( XKDEIsAlso ); - if ( inherits != name() ) - m_mapProps.insert( XKDEIsAlso, inherits ); - else - kdWarning(7009) << "Error: " << inherits << " inherits from itself!!!!" << endl; - } - - TQString XKDEPatternsAccuracy = TQString::fromLatin1("X-TDE-PatternsAccuracy"); - if ( config->hasKey( XKDEPatternsAccuracy ) ) - m_mapProps.insert( XKDEPatternsAccuracy, config->readEntry( XKDEPatternsAccuracy ) ); - -} - -KMimeType::KMimeType( TQDataStream& _str, int offset ) : KServiceType( _str, offset ) -{ - loadInternal( _str ); // load our specific stuff -} - -void KMimeType::load( TQDataStream& _str ) -{ - KServiceType::load( _str ); - loadInternal( _str ); -} - -void KMimeType::loadInternal( TQDataStream& _str ) -{ - // kdDebug(7009) << "KMimeType::load( TQDataStream& ) : loading list of patterns" << endl; - _str >> m_lstPatterns; -} - -void KMimeType::save( TQDataStream& _str ) -{ - KServiceType::save( _str ); - // Warning adding/removing fields here involves a binary incompatible change - update version - // number in tdesycoca.h - _str << m_lstPatterns; -} - -TQVariant KMimeType::property( const TQString& _name ) const -{ - if ( _name == "Patterns" ) - return TQVariant( m_lstPatterns ); - - return KServiceType::property( _name ); -} - -TQStringList KMimeType::propertyNames() const -{ - TQStringList res = KServiceType::propertyNames(); - res.append( "Patterns" ); - - return res; -} - -KMimeType::~KMimeType() -{ -} - -TQPixmap KMimeType::pixmap( KIcon::Group _group, int _force_size, int _state, - TQString * _path ) const -{ - KIconLoader *iconLoader=TDEGlobal::iconLoader(); - TQString iconName=icon( TQString::null, false ); - if (!iconLoader->extraDesktopThemesAdded()) - { - TQPixmap pixmap=iconLoader->loadIcon( iconName, _group, _force_size, _state, _path, true ); - if (!pixmap.isNull() ) return pixmap; - - iconLoader->addExtraDesktopThemes(); - } - - return iconLoader->loadIcon( iconName , _group, _force_size, _state, _path, false ); -} - -TQPixmap KMimeType::pixmap( const KURL& _url, KIcon::Group _group, int _force_size, - int _state, TQString * _path ) const -{ - KIconLoader *iconLoader=TDEGlobal::iconLoader(); - TQString iconName=icon( _url, _url.isLocalFile() ); - if (!iconLoader->extraDesktopThemesAdded()) - { - TQPixmap pixmap=iconLoader->loadIcon( iconName, _group, _force_size, _state, _path, true ); - if (!pixmap.isNull() ) return pixmap; - - iconLoader->addExtraDesktopThemes(); - } - - return iconLoader->loadIcon( iconName , _group, _force_size, _state, _path, false ); -} - -TQPixmap KMimeType::pixmapForURL( const KURL & _url, mode_t _mode, KIcon::Group _group, - int _force_size, int _state, TQString * _path ) -{ - KIconLoader *iconLoader=TDEGlobal::iconLoader(); - TQString iconName = iconForURL( _url, _mode ); - - if (!iconLoader->extraDesktopThemesAdded()) - { - TQPixmap pixmap=iconLoader->loadIcon( iconName, _group, _force_size, _state, _path, true ); - if (!pixmap.isNull() ) return pixmap; - - iconLoader->addExtraDesktopThemes(); - } - - return iconLoader->loadIcon( iconName , _group, _force_size, _state, _path, false ); - -} - -TQString KMimeType::iconForURL( const KURL & _url, mode_t _mode ) -{ - const KMimeType::Ptr mt = findByURL( _url, _mode, _url.isLocalFile(), - false /*HACK*/); - static const TQString& unknown = TDEGlobal::staticQString("unknown"); - const TQString mimeTypeIcon = mt->icon( _url, _url.isLocalFile() ); - TQString i = mimeTypeIcon; - - // if we don't find an icon, maybe we can use the one for the protocol - if ( i == unknown || i.isEmpty() || mt == defaultMimeTypePtr() - // and for the root of the protocol (e.g. trash:/) the protocol icon has priority over the mimetype icon - || _url.path().length() <= 1 ) - { - i = favIconForURL( _url ); // maybe there is a favicon? - - if ( i.isEmpty() ) - i = KProtocolInfo::icon( _url.protocol() ); - - // root of protocol: if we found nothing, revert to mimeTypeIcon (which is usually "folder") - if ( _url.path().length() <= 1 && ( i == unknown || i.isEmpty() ) ) - i = mimeTypeIcon; - } - return i; -} - -TQString KMimeType::favIconForURL( const KURL& url ) -{ - // this method will be called quite often, so better not read the config - // again and again. - static bool useFavIcons = true; - static bool check = true; - if ( check ) { - check = false; - TDEConfig *config = TDEGlobal::config(); - TDEConfigGroupSaver cs( config, "HTML Settings" ); - useFavIcons = config->readBoolEntry( "EnableFavicon", true ); - } - - if ( url.isLocalFile() || !url.protocol().startsWith("http") - || !useFavIcons ) - return TQString::null; - - DCOPRef kded( "kded", "favicons" ); - DCOPReply result = kded.call( "iconForURL(KURL)", url ); - if ( result.isValid() ) - return result; - - return TQString::null; -} - -TQString KMimeType::parentMimeType() const -{ - TQVariant v = property("X-TDE-IsAlso"); - return v.toString(); -} - -bool KMimeType::is( const TQString& mimeTypeName ) const -{ - if ( name() == mimeTypeName ) - return true; - TQString st = parentMimeType(); - //if (st.isEmpty()) kdDebug(7009)<<"Parent mimetype is empty"<<endl; - while ( !st.isEmpty() ) - { - //kdDebug(7009)<<"Checking parent mime type: "<<st<<endl; - KMimeType::Ptr ptr = KMimeType::mimeType( st ); - if (!ptr) return false; //error - if ( ptr->name() == mimeTypeName ) - return true; - st = ptr->parentMimeType(); - } - return false; -} - -int KMimeType::patternsAccuracy() const { - TQVariant v = property("X-TDE-PatternsAccuracy"); - if (!v.isValid()) return 100; - else - return v.toInt(); -} - - -/******************************************************* - * - * KFolderType - * - ******************************************************/ - -TQString KFolderType::icon( const TQString& _url, bool _is_local ) const -{ - if ( !_is_local || _url.isEmpty() ) - return KMimeType::icon( _url, _is_local ); - - return KFolderType::icon( KURL(_url), _is_local ); -} - -TQString KFolderType::icon( const KURL& _url, bool _is_local ) const -{ - if ( !_is_local ) - return KMimeType::icon( _url, _is_local ); - - KURL u( _url ); - u.addPath( ".directory" ); - - TQString icon; - // using KStandardDirs as this one checks for path being - // a file instead of a directory - if ( KStandardDirs::exists( u.path() ) ) - { - KSimpleConfig cfg( u.path(), true ); - cfg.setDesktopGroup(); - icon = cfg.readEntry( "Icon" ); - TQString empty_icon = cfg.readEntry( "EmptyIcon" ); - - if ( !empty_icon.isEmpty() ) - { - bool isempty = false; - DIR *dp = 0L; - struct dirent *ep; - dp = opendir( TQFile::encodeName(_url.path()) ); - if ( dp ) - { - TQValueList<TQCString> entries; - // Note that readdir isn't guaranteed to return "." and ".." first (#79826) - ep=readdir( dp ); if ( ep ) entries.append( ep->d_name ); - ep=readdir( dp ); if ( ep ) entries.append( ep->d_name ); - if ( (ep=readdir( dp )) == 0L ) // third file is NULL entry -> empty directory - isempty = true; - else { - entries.append( ep->d_name ); - if ( readdir( dp ) == 0 ) { // only three - // check if we got "." ".." and ".directory" - isempty = entries.find( "." ) != entries.end() && - entries.find( ".." ) != entries.end() && - entries.find( ".directory" ) != entries.end(); - } - } - if (!isempty && !strcmp(ep->d_name, ".directory")) - isempty = (readdir(dp) == 0L); - closedir( dp ); - } - - if ( isempty ) - return empty_icon; - } - } - - if ( icon.isEmpty() ) - return KMimeType::icon( _url, _is_local ); - - if ( icon.startsWith( "./" ) ) { - // path is relative with respect to the location - // of the .directory file (#73463) - KURL v( _url ); - v.addPath( icon.mid( 2 ) ); - icon = v.path(); - } - - return icon; -} - -TQString KFolderType::comment( const TQString& _url, bool _is_local ) const -{ - if ( !_is_local || _url.isEmpty() ) - return KMimeType::comment( _url, _is_local ); - - return KFolderType::comment( KURL(_url), _is_local ); -} - -TQString KFolderType::comment( const KURL& _url, bool _is_local ) const -{ - if ( !_is_local ) - return KMimeType::comment( _url, _is_local ); - - KURL u( _url ); - u.addPath( ".directory" ); - - KDesktopFile cfg( u.path(), true ); - TQString comment = cfg.readComment(); - if ( comment.isEmpty() ) - return KMimeType::comment( _url, _is_local ); - - return comment; -} - -/******************************************************* - * - * KDEDesktopMimeType - * - ******************************************************/ - -TQString KDEDesktopMimeType::icon( const TQString& _url, bool _is_local ) const -{ - if ( !_is_local || _url.isEmpty() ) - return KMimeType::icon( _url, _is_local ); - - KURL u( _url ); - return icon( u, _is_local ); -} - -TQString KDEDesktopMimeType::icon( const KURL& _url, bool _is_local ) const -{ - if ( !_is_local ) - return KMimeType::icon( _url, _is_local ); - - KSimpleConfig cfg( _url.path(), true ); - cfg.setDesktopGroup(); - TQString icon = cfg.readEntry( "Icon" ); - TQString type = cfg.readEntry( "Type" ); - - if ( type == "FSDevice" || type == "FSDev") // need to provide FSDev for - // backwards compatibility - { - TQString unmount_icon = cfg.readEntry( "UnmountIcon" ); - TQString dev = cfg.readEntry( "Dev" ); - if ( !icon.isEmpty() && !unmount_icon.isEmpty() && !dev.isEmpty() ) - { - TQString mp = TDEIO::findDeviceMountPoint( dev ); - // Is the device not mounted ? - if ( mp.isNull() ) - return unmount_icon; - } - } else if ( type == "Link" ) { - const TQString emptyIcon = cfg.readEntry( "EmptyIcon" ); - if ( !emptyIcon.isEmpty() ) { - const TQString u = cfg.readPathEntry( "URL" ); - const KURL url( u ); - if ( url.protocol() == "trash" ) { - // We need to find if the trash is empty, preferrably without using a KIO job. - // So instead kio_trash leaves an entry in its config file for us. - KSimpleConfig trashConfig( "trashrc", true ); - trashConfig.setGroup( "Status" ); - if ( trashConfig.readBoolEntry( "Empty", true ) ) { - return emptyIcon; - } - } - } - } - - if ( icon.isEmpty() ) - return KMimeType::icon( _url, _is_local ); - - return icon; -} - -TQPixmap KDEDesktopMimeType::pixmap( const KURL& _url, KIcon::Group _group, int _force_size, - int _state, TQString * _path ) const -{ - TQString _icon = icon( _url, _url.isLocalFile() ); - TQPixmap pix = TDEGlobal::iconLoader()->loadIcon( _icon, _group, - _force_size, _state, _path, false ); - if ( pix.isNull() ) - pix = TDEGlobal::iconLoader()->loadIcon( "unknown", _group, - _force_size, _state, _path, false ); - return pix; -} - -TQString KDEDesktopMimeType::comment( const TQString& _url, bool _is_local ) const -{ - if ( !_is_local || _url.isEmpty() ) - return KMimeType::comment( _url, _is_local ); - - KURL u( _url ); - return comment( u, _is_local ); -} - -TQString KDEDesktopMimeType::comment( const KURL& _url, bool _is_local ) const -{ - if ( !_is_local ) - return KMimeType::comment( _url, _is_local ); - - KDesktopFile cfg( _url.path(), true ); - TQString comment = cfg.readComment(); - if ( comment.isEmpty() ) - return KMimeType::comment( _url, _is_local ); - - return comment; -} - -pid_t KDEDesktopMimeType::run( const KURL& u, bool _is_local ) -{ - // It might be a security problem to run external untrusted desktop - // entry files - if ( !_is_local ) - return 0; - - KSimpleConfig cfg( u.path(), true ); - cfg.setDesktopGroup(); - TQString type = cfg.readEntry( "Type" ); - if ( type.isEmpty() ) - { - TQString tmp = i18n("The desktop entry file %1 " - "has no Type=... entry.").arg(u.path() ); - KMessageBoxWrapper::error( 0, tmp); - return 0; - } - - //kdDebug(7009) << "TYPE = " << type.data() << endl; - - if ( type == "FSDevice" ) - return runFSDevice( u, cfg ); - else if ( type == "Application" ) - return runApplication( u, u.path() ); - else if ( type == "Link" ) - { - cfg.setDollarExpansion( true ); // for URL=file:$HOME (Simon) - return runLink( u, cfg ); - } - else if ( type == "MimeType" ) - return runMimeType( u, cfg ); - - - TQString tmp = i18n("The desktop entry of type\n%1\nis unknown.").arg( type ); - KMessageBoxWrapper::error( 0, tmp); - - return 0; -} - -pid_t KDEDesktopMimeType::runFSDevice( const KURL& _url, const KSimpleConfig &cfg ) -{ - pid_t retval = 0; - - TQString dev = cfg.readEntry( "Dev" ); - - if ( dev.isEmpty() ) - { - TQString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( _url.path() ); - KMessageBoxWrapper::error( 0, tmp); - return retval; - } - - TQString mp = TDEIO::findDeviceMountPoint( dev ); - // Is the device already mounted ? - if ( !mp.isNull() ) - { - KURL mpURL; - mpURL.setPath( mp ); - // Open a new window - retval = KRun::runURL( mpURL, TQString::fromLatin1("inode/directory") ); - } - else - { - bool ro = cfg.readBoolEntry( "ReadOnly", false ); - TQString fstype = cfg.readEntry( "FSType" ); - if ( fstype == "Default" ) // KDE-1 thing - fstype = TQString::null; - TQString point = cfg.readEntry( "MountPoint" ); -#ifndef Q_WS_WIN - (void) new KAutoMount( ro, fstype, dev, point, _url.path() ); -#endif - retval = -1; // we don't want to return 0, but we don't want to return a pid - } - - return retval; -} - -pid_t KDEDesktopMimeType::runApplication( const KURL& , const TQString & _serviceFile ) -{ - KService s( _serviceFile ); - if ( !s.isValid() ) - // The error message was already displayed, so we can just quit here - return 0; - - KURL::List lst; - return KRun::run( s, lst ); -} - -pid_t KDEDesktopMimeType::runLink( const KURL& _url, const KSimpleConfig &cfg ) -{ - TQString u = cfg.readPathEntry( "URL" ); - if ( u.isEmpty() ) - { - TQString tmp = i18n("The desktop entry file\n%1\nis of type Link but has no URL=... entry.").arg( _url.prettyURL() ); - KMessageBoxWrapper::error( 0, tmp ); - return 0; - } - - KURL url ( u ); - KRun* run = new KRun(url); - - // X-TDE-LastOpenedWith holds the service desktop entry name that - // was should be preferred for opening this URL if possible. - // This is used by the Recent Documents menu for instance. - TQString lastOpenedWidth = cfg.readEntry( "X-TDE-LastOpenedWith" ); - if ( !lastOpenedWidth.isEmpty() ) - run->setPreferredService( lastOpenedWidth ); - - return -1; // we don't want to return 0, but we don't want to return a pid -} - -pid_t KDEDesktopMimeType::runMimeType( const KURL& url , const KSimpleConfig & ) -{ - // Hmm, can't really use keditfiletype since we might be looking - // at the global file, or at a file not in share/mimelnk... - - TQStringList args; - args << "openProperties"; - args << url.path(); - - int pid; - if ( !TDEApplication::tdeinitExec("kfmclient", args, 0, &pid) ) - return pid; - - TDEProcess p; - p << "kfmclient" << args; - p.start(TDEProcess::DontCare); - return p.pid(); -} - -TQValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::builtinServices( const KURL& _url ) -{ - TQValueList<Service> result; - - if ( !_url.isLocalFile() ) - return result; - - KSimpleConfig cfg( _url.path(), true ); - cfg.setDesktopGroup(); - TQString type = cfg.readEntry( "Type" ); - - if ( type.isEmpty() ) - return result; - - if ( type == "FSDevice" ) - { - TQString dev = cfg.readEntry( "Dev" ); - if ( dev.isEmpty() ) - { - TQString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( _url.path() ); - KMessageBoxWrapper::error( 0, tmp); - } - else - { - TQString mp = TDEIO::findDeviceMountPoint( dev ); - // not mounted ? - if ( mp.isEmpty() ) - { - Service mount; - mount.m_strName = i18n("Mount"); - mount.m_type = ST_MOUNT; - result.append( mount ); - } - else - { - Service unmount; -#ifdef HAVE_VOLMGT - /* - * Solaris' volume management can only umount+eject - */ - unmount.m_strName = i18n("Eject"); -#else - unmount.m_strName = i18n("Unmount"); -#endif - unmount.m_type = ST_UNMOUNT; - result.append( unmount ); - } - } - } - - return result; -} - -TQValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::userDefinedServices( const TQString& path, bool bLocalFiles ) -{ - KSimpleConfig cfg( path, true ); - return userDefinedServices( path, cfg, bLocalFiles ); -} - -TQValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::userDefinedServices( const TQString& path, TDEConfig& cfg, bool bLocalFiles ) -{ - return userDefinedServices( path, cfg, bLocalFiles, KURL::List() ); -} - -TQValueList<KDEDesktopMimeType::Service> KDEDesktopMimeType::userDefinedServices( const TQString& path, TDEConfig& cfg, bool bLocalFiles, const KURL::List & file_list ) -{ - TQValueList<Service> result; - - cfg.setDesktopGroup(); - - if ( !cfg.hasKey( "Actions" ) && !cfg.hasKey( "X-TDE-GetActionMenu") ) - return result; - - if ( cfg.hasKey( "TryExec" ) ) - { - TQString tryexec = cfg.readPathEntry( "TryExec" ); - TQString exe = KStandardDirs::findExe( tryexec ); - if (exe.isEmpty()) { - return result; - } - } - - TQStringList keys; - - if( cfg.hasKey( "X-TDE-GetActionMenu" )) { - TQString dcopcall = cfg.readEntry( "X-TDE-GetActionMenu" ); - const TQCString app = TQString(dcopcall.section(' ', 0,0)).utf8(); - - TQByteArray dataToSend; - TQDataStream dataStream(dataToSend, IO_WriteOnly); - dataStream << file_list; - TQCString replyType; - TQByteArray replyData; - TQCString object = TQString(dcopcall.section(' ', 1,-2)).utf8(); - TQString function = dcopcall.section(' ', -1); - if(!function.endsWith("(KURL::List)")) { - kdWarning() << "Desktop file " << path << " contains an invalid X-TDE-ShowIfDcopCall - the function must take the exact parameter (KURL::List) and must be specified." << endl; - } else { - if(kapp->dcopClient()->call( app, object, - function.utf8(), - dataToSend, replyType, replyData, true, -1) - && replyType == "TQStringList" ) { - - TQDataStream dataStreamIn(replyData, IO_ReadOnly); - dataStreamIn >> keys; - } - } - } - - keys += cfg.readListEntry( "Actions", ';' ); //the desktop standard defines ";" as separator! - - if ( keys.count() == 0 ) - return result; - - TQStringList::ConstIterator it = keys.begin(); - TQStringList::ConstIterator end = keys.end(); - for ( ; it != end; ++it ) - { - //kdDebug(7009) << "CURRENT KEY = " << (*it) << endl; - - TQString group = *it; - - if (group == "_SEPARATOR_") - { - Service s; - result.append(s); - continue; - } - - group.prepend( "Desktop Action " ); - - bool bInvalidMenu = false; - - if ( cfg.hasGroup( group ) ) - { - cfg.setGroup( group ); - - if ( !cfg.hasKey( "Name" ) || !cfg.hasKey( "Exec" ) ) - bInvalidMenu = true; - else - { - TQString exec = cfg.readPathEntry( "Exec" ); - if ( bLocalFiles || exec.contains("%U") || exec.contains("%u") ) - { - Service s; - s.m_strName = cfg.readEntry( "Name" ); - s.m_strIcon = cfg.readEntry( "Icon" ); - s.m_strExec = exec; - s.m_type = ST_USER_DEFINED; - s.m_display = !cfg.readBoolEntry( "NoDisplay" ); - result.append( s ); - } - } - } - else - bInvalidMenu = true; - - if ( bInvalidMenu ) - { - TQString tmp = i18n("The desktop entry file\n%1\n has an invalid menu entry\n%2.").arg( path ).arg( *it ); - KMessageBoxWrapper::error( 0, tmp ); - } - } - - return result; -} - -void KDEDesktopMimeType::executeService( const TQString& _url, KDEDesktopMimeType::Service& _service ) -{ - KURL u; - u.setPath(_url); - KURL::List lst; - lst.append( u ); - executeService( lst, _service ); -} - -void KDEDesktopMimeType::executeService( const KURL::List& urls, KDEDesktopMimeType::Service& _service ) -{ - //kdDebug(7009) << "EXECUTING Service " << _service.m_strName << endl; - - if ( _service.m_type == ST_USER_DEFINED ) - { - kdDebug() << "KDEDesktopMimeType::executeService " << _service.m_strName - << " first url's path=" << urls.first().path() << " exec=" << _service.m_strExec << endl; - KRun::run( _service.m_strExec, urls, _service.m_strName, _service.m_strIcon, _service.m_strIcon ); - // The action may update the desktop file. Example: eject unmounts (#5129). - KDirNotify_stub allDirNotify("*", "KDirNotify*"); - allDirNotify.FilesChanged( urls ); - return; - } - else if ( _service.m_type == ST_MOUNT || _service.m_type == ST_UNMOUNT ) - { - Q_ASSERT( urls.count() == 1 ); - TQString path = urls.first().path(); - //kdDebug(7009) << "MOUNT&UNMOUNT" << endl; - - KSimpleConfig cfg( path, true ); - cfg.setDesktopGroup(); - TQString dev = cfg.readEntry( "Dev" ); - if ( dev.isEmpty() ) - { - TQString tmp = i18n("The desktop entry file\n%1\nis of type FSDevice but has no Dev=... entry.").arg( path ); - KMessageBoxWrapper::error( 0, tmp ); - return; - } - TQString mp = TDEIO::findDeviceMountPoint( dev ); - - if ( _service.m_type == ST_MOUNT ) - { - // Already mounted? Strange, but who knows ... - if ( !mp.isEmpty() ) - { - kdDebug(7009) << "ALREADY Mounted" << endl; - return; - } - - bool ro = cfg.readBoolEntry( "ReadOnly", false ); - TQString fstype = cfg.readEntry( "FSType" ); - if ( fstype == "Default" ) // KDE-1 thing - fstype = TQString::null; - TQString point = cfg.readEntry( "MountPoint" ); -#ifndef Q_WS_WIN - (void)new KAutoMount( ro, fstype, dev, point, path, false ); -#endif - } - else if ( _service.m_type == ST_UNMOUNT ) - { - // Not mounted? Strange, but who knows ... - if ( mp.isEmpty() ) - return; - -#ifndef Q_WS_WIN - (void)new KAutoUnmount( mp, path ); -#endif - } - } - else - assert( 0 ); -} - -const TQString & KMimeType::defaultMimeType() -{ - static const TQString & s_strDefaultMimeType = - TDEGlobal::staticQString( "application/octet-stream" ); - return s_strDefaultMimeType; -} - -void KMimeType::virtual_hook( int id, void* data ) -{ KServiceType::virtual_hook( id, data ); } - -void KFolderType::virtual_hook( int id, void* data ) -{ KMimeType::virtual_hook( id, data ); } - -void KDEDesktopMimeType::virtual_hook( int id, void* data ) -{ KMimeType::virtual_hook( id, data ); } - -void KExecMimeType::virtual_hook( int id, void* data ) -{ KMimeType::virtual_hook( id, data ); } - -#include "kmimetyperesolver.moc" - diff --git a/kio/kio/kmimetype.h b/kio/kio/kmimetype.h deleted file mode 100644 index 19a846b46..000000000 --- a/kio/kio/kmimetype.h +++ /dev/null @@ -1,641 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 1999 Waldo Bastian <bastian@kde.org> - * David Faure <faure@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation; - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#ifndef __kmimetype_h__ -#define __kmimetype_h__ - -#include <sys/types.h> -#include <sys/stat.h> - -#include <tqstringlist.h> -#include <tqvaluelist.h> -#include <tqpixmap.h> - -#include <kicontheme.h> -#include <kurl.h> -#include <tdesycocatype.h> -#include <kservicetype.h> - -class KSimpleConfig; -/** - * Represent a mime type, like "text/plain", and the data that is associated - * with it. - * - * The starting point you need is often the static methods. - * - * KMimeType inherits KServiceType because "text/plain" can be used to find - * services (apps and components) "which can open text/plain". - * - * @see KServiceType - */ -class TDEIO_EXPORT KMimeType : public KServiceType -{ - K_SYCOCATYPE( KST_KMimeType, KServiceType ) - -public: - typedef KSharedPtr<KMimeType> Ptr; - typedef TQValueList<Ptr> List; -public: - /** - * Constructor. - * - * You may pass in arguments to create a mimetype with - * specific properties. - * - * @param _fullpath the path to the configuration file (.desktop) - * @param _type the mime type itself - * @param _icon the name of the icon that represens the mime type - * @param _comment a comment describing the mime type - * @param _patterns a list of file globs that describes the names (or - * extensions) of the files with this mime type - */ - KMimeType( const TQString & _fullpath, const TQString& _type, const TQString& _icon, - const TQString& _comment, const TQStringList& _patterns ); - - /** - * Construct a mimetype and take all information from a config file. - * @param _fullpath the path to the configuration file (.desktop) - */ - KMimeType( const TQString & _fullpath ); - - /** - * Construct a mimetype and take all information from a desktop file. - * @param config the desktop configuration file that describes the mime type - */ - KMimeType( KDesktopFile *config ); - - /** - * @internal Construct a service from a stream. - * - * The stream must already be positionned at the correct offset - */ - KMimeType( TQDataStream& _str, int offset ); - - virtual ~KMimeType(); - - /** - * Return the filename of the icon associated with the mimetype. - * - * The arguments are unused, but provided so that KMimeType-derived classes - * can use them (e.g. KFolderType uses the URL to return one out of 2 icons) - * - * @return The path to the icon associated with this MIME type. - */ - virtual TQString icon( const TQString& , bool ) const { return m_strIcon; } - - /** - * Return the filename of the icon associated with the mimetype. - * - * The arguments are unused, but provided so that KMimeType-derived classes - * can use them (e.g. KFolderType uses the URL to return one out of 2 icons) - * - * @return The path to the icon associated with this MIME type. - */ - virtual TQString icon( const KURL& , bool ) const { return m_strIcon; } - - /** - * Use this function only if you don't have a special URL - * for which you search a pixmap. - * - * This function is useful to find - * out, which icon is usually chosen for a certain mime type. Since - * no URL is passed, it is impossible to obey icon hints in desktop - * entries for example. - * @param group The icon group where the icon is going to be used. - * @param force_size Override globallly configured icon size. - * Use 0 for the default size - * @param state The icon state, one of: @p KIcon::DefaultState, - * @p KIcon::ActiveState or @p KIcon::DisabledState. - * @param path Output parameter to get the full path. Seldom needed. - * Ignored if 0 - * @return the pixmap of the mime type, can be a default icon if not found - */ - virtual TQPixmap pixmap( KIcon::Group group, int force_size = 0, int state = 0, - TQString * path = 0L ) const; - - /** - * Find the pixmap for a given file of this mimetype. - * - * Convenience method that uses icon(), but also locates and - * load the pixmap. - * - * @param _url URL for the file. - * @param _group The icon group where the icon is going to be used. - * @param _force_size Override globallly configured icon size. - * Use 0 for the default size - * @param _state The icon state, one of: KIcon::DefaultState, - * KIcon::ActiveState or KIcon::DisabledState. - * @param _path Output parameter to get the full path. Seldom needed. - * Ignored if 0 - * @return the pixmap of the URL, can be a default icon if not found - */ - virtual TQPixmap pixmap( const KURL& _url, KIcon::Group _group, int _force_size = 0, - int _state = 0, TQString * _path = 0L ) const; - - /** - * Convenience method to find the pixmap for a URL. - * - * Call this one when you don't know the mimetype. - * - * @param _url URL for the file. - * @param _mode the mode of the file. The mode may modify the icon - * with overlays that show special properties of the - * icon. Use 0 for default - * @param _group The icon group where the icon is going to be used. - * @param _force_size Override globally configured icon size. - * Use 0 for the default size - * @param _state The icon state, one of: KIcon::DefaultState, - * KIcon::ActiveState or KIcon::DisabledState. - * @param _path Output parameter to get the full path. Seldom needed. - * Ignored if 0 - * @return the pixmap of the URL, can be a default icon if not found - */ - static TQPixmap pixmapForURL( const KURL & _url, mode_t _mode = 0, KIcon::Group _group = KIcon::Desktop, - int _force_size = 0, int _state = 0, TQString * _path = 0L ); - - - /** - * The same functionality as pixmapForURL(), but this method returns the name - * of the icon to load. You'll have to use KIconLoader to load the pixmap for it. - * The advantage of this method is that you can store the result, and then use it - * later on for any kind of size. - * @param _url URL for the file - * @param _mode the mode of the file. The mode may modify the icon - * with overlays that show special properties of the - * icon. Use 0 for default - * @return the name of the icon. The name of a default icon if there is no icon - * for the mime type - */ - static TQString iconForURL( const KURL & _url, mode_t _mode = 0 ); - - /** - * Return the "favicon" (see http://www.favicon.com) for the given @p url, - * if available. Does NOT attempt to download the favicon, it only returns - * one that is already available. - * - * If unavailable, returns TQString::null. - * @param url the URL of the favicon - * @return the name of the favicon, or TQString::null - */ - static TQString favIconForURL( const KURL& url ); - - /** - * Returns the descriptive comment associated with the MIME type. - * @return the descriptive comment associated with the MIME type - */ - TQString comment() const { return m_strComment; } - - /** - * Returns the descriptive comment associated with the MIME type. - * The arguments are unused, but provided so that KMimeType derived classes - * can use them. - * - * @return The descriptive comment associated with the MIME type, if any. - */ - virtual TQString comment( const TQString&, bool ) const { return m_strComment; } - - /** - * Returns the descriptive comment associated with the MIME type. - * The arguments are unused, but provided so that KMimeType derived classes - * can use them. - * - * @return The descriptive comment associated with the MIME type, if any. - */ - virtual TQString comment( const KURL&, bool ) const { return m_strComment; } - - /** - * Retrieve the list of patterns associated with the MIME Type. - * @return a list of file globs that describe the file names - * (or, usually, the extensions) of files with this mime type - */ - const TQStringList& patterns() const { return m_lstPatterns; } - - /** - * Load the mimetype from a stream. - * @param qs the stream to load from - */ - virtual void load( TQDataStream &qs ); - - /** - * Save the mimetype to a stream. - * @param qs the stream to save to - */ - virtual void save( TQDataStream &qs ); - - /** - * Returns the property with the given @p _name. - * @param _name the name of the property - * @return the value of the property - * @see propertyNames() - */ - virtual TQVariant property( const TQString& _name ) const; - - /** - * Retrieves a list of all properties associated with this - * KMimeType. - * @return a list of all property names - * @see property() - */ - virtual TQStringList propertyNames() const; - - /** - * Retrieve a pointer to the mime type @p _name or a pointer to the default - * mime type "application/octet-stream". - * - * 0L is @em never returned. - * - * @em Very @em important: Don't store the result in a KMimeType* ! - * - * @param _name the name of the mime type - * @return the pointer to the KMimeType with the given @p _name, or - * a pointer to the application/octet-stream KMimeType if - * not found - * @see KServiceType::serviceType - */ - static Ptr mimeType( const TQString& _name ); - - /** - * Finds a KMimeType with the given @p _url. - * This function looks at mode_t first. - * If that does not help it - * looks at the extension. This is fine for FTP, FILE, TAR and - * friends, but is not for HTTP ( cgi scripts! ). You should use - * KRun instead, but this function returns immediately while - * KRun is async. If no extension matches, then - * the file will be examined if the URL a local file or - * "application/octet-stream" is returned otherwise. - * - * @param _url Is the right most URL with a filesystem protocol. It - * is up to you to find out about that if you have a nested - * URL. For example - * "http://localhost/mist.gz#gzip:/decompress" would have to - * pass the "http://..." URL part, while - * "file:/tmp/x.tar#tar:/src/test.gz#gzip:/decompress" would - * have to pass the "tar:/..." part of the URL, since gzip is - * a filter protocol and not a filesystem protocol. - * @param _mode the mode of the file (used, for example, to identify - * executables) - * @param _is_local_file true if the file is local - * @param _fast_mode If set to true no disk access is allowed to - * find out the mimetype. The result may be suboptimal, but - * it is @em fast. - * @return A pointer to the matching mimetype. 0L is never returned. - * @em Very @em Important: Don't store the result in a KMimeType* ! - */ - static Ptr findByURL( const KURL& _url, mode_t _mode = 0, - bool _is_local_file = false, bool _fast_mode = false ); - - static Ptr findByURL( const KURL& _url, mode_t _mode, - bool _is_local_file, bool _fast_mode, - bool *accurate); - /** - * Finds a KMimeType with the given @p _url. - * This function looks at mode_t first. - * If that does not help it - * looks at the extension. This is fine for FTP, FILE, TAR and - * friends, but is not for HTTP ( cgi scripts! ). You should use - * KRun instead, but this function returns immediately while - * KRun is async. If no extension matches, then - * the file will be examined if the URL a local file or - * "application/octet-stream" is returned otherwise. - * - * Equivalent to - * \code - * KURL u; - * u.setPath(path); - * return findByURL( u, mode, true, fast_mode ); - * \endcode - * - * @param path the path to the file - * @param mode the mode of the file (used, for example, to identify - * executables) - * @param fast_mode If set to true no disk access is allowed to - * find out the mimetype. The result may be suboptimal, but - * it is @em fast. - * @return A pointer to the matching mimetype. 0L is never returned. - */ - static Ptr findByPath( const TQString& path, mode_t mode = 0, bool fast_mode = false ); - - /** - * Tries to find out the MIME type of a data chunk by looking for - * certain magic numbers and characteristic strings in it. - * - * @param data the data to examine - * @param accuracy If not a null pointer, *accuracy is set to the - * accuracy of the match (which is in the range 0..100) - * @return a pointer to the KMimeType. application/octet-stream's KMimeType of the - * type can not be found this way. - */ - static Ptr findByContent( const TQByteArray &data, int *accuracy=0 ); - - /** - * Tries to find out the MIME type of a file by looking for - * certain magic numbers and characteristic strings in it. - * This function is similar to the previous one. Note that the - * file name is not used for determining the file type, it is just - * used for loading the file's contents. - * - * @param fileName the path to the file - * @param accuracy If not a null pointer, *accuracy is set to the - * accuracy of the match (which is in the range 0..100) - * @return a pointer to the KMimeType. application/octet-stream's KMimeType of the - * type can not be found this way. - */ - static Ptr findByFileContent( const TQString &fileName, int *accuracy=0 ); - - struct Format{ - bool text : 1; - enum { NoCompression=0, GZipCompression } compression : 4; - unsigned dummy : 27; - }; - - /** - * Returns whether a file has an internal format that is human readable, - * or that would be human readable after decompression. - * @since 3.2 - */ - static Format findFormatByFileContent( const TQString &fileName ); - - /** - * Get all the mimetypes. - * - * Useful for showing the list of - * available mimetypes. - * More memory consuming than the ones above, don't use unless - * really necessary. - * @return the list of all existing KMimeTypes - */ - static List allMimeTypes(); - - /** - * Returns the name of the default mimetype. - * Always application/octet-stream, but this method exists - * for performance purposes. - * @return the name of the default mime type, always - * "application/octet-stream" - */ - static const TQString & defaultMimeType(); - - /** - * Returns the default mimetype. - * Always application/octet-stream. - * This can be used to check the result of mimeType(name). - * @return the "application/octet-stream" mimetype pointer. - * @since 3.2 - */ - static KMimeType::Ptr defaultMimeTypePtr(); - - /** - * If this mimetype inherits from ("is also") another mimetype, - * return the name of the parent. - * - * For instance a text/x-log is a special kind of text/plain, - * so the definition of text/x-log can say "X-TDE-IsAlso=text/plain". - * Or an smb-workgroup is a special kind of inode/directory, etc. - * This mechanism can also be used to rename mimetypes and preserve compat. - * - * Note that this notion doesn't map to the servicetype inheritance mechanism, - * since an application that handles the specific type doesn't necessarily handle - * the base type. The opposite is true though. - * - * @return the parent mime type, or TQString::null if not set - * @since 3.2 - */ - TQString parentMimeType() const; - - /** - * Do not use name()=="somename" anymore, to check for a given mimetype. - * For mimetype inheritance to work, use is("somename") instead. - * Warning, do not use inherits(), that's the servicetype inheritance concept! - * @since 3.2 - */ - bool is( const TQString& mimeTypeName ) const; - - /** - * @internal - * Determines the mimetype of file based on it's name and returns the - * matching pattern if any. - */ - static KMimeType::Ptr diagnoseFileName(const TQString &file, TQString &pattern); - -protected: - void loadInternal( TQDataStream& ); - void init( KDesktopFile * ); - - /** - * Signal a missing mime type. - * @param _type the missinf mime type - */ - static void errorMissingMimeType( const TQString& _type ); - - /** - * This function makes sure that the default mime type exists. - */ - static void buildDefaultType(); - - /** - * This function makes sure that vital mime types are installed. - */ - static void checkEssentialMimeTypes(); - /** - * true if check for vital mime types has been done. - */ - static bool s_bChecked; - - TQStringList m_lstPatterns; - - static Ptr s_pDefaultType; - -protected: - friend class KServiceTypeFactory; - int patternsAccuracy() const; - -protected: - virtual void virtual_hook( int id, void* data ); -}; - -/** - * Folder mime type. Handles locked folders, for instance. - * @short Mimetype for a folder (inode/directory) - */ -class TDEIO_EXPORT KFolderType : public KMimeType -{ - K_SYCOCATYPE( KST_KFolderType, KMimeType ) - -public: -// KFolderType( const TQString & _fullpath, const TQString& _type, const TQString& _icon, const TQString& _comment, -// const TQStringList& _patterns ); -// KFolderType( const TQString & _fullpath ) : KMimeType( _fullpath ) { } - /** - * Construct a folder mimetype and take all information from a desktop file. - * @param config the desktop configuration file that describes the mime type - */ - KFolderType( KDesktopFile *config) : KMimeType( config ) { } - /** \internal */ - KFolderType( TQDataStream& _str, int offset ) : KMimeType( _str, offset ) { } - - virtual TQString icon( const TQString& _url, bool _is_local ) const; - virtual TQString icon( const KURL& _url, bool _is_local ) const; - virtual TQString comment( const TQString& _url, bool _is_local ) const; - virtual TQString comment( const KURL& _url, bool _is_local ) const; -protected: - virtual void virtual_hook( int id, void* data ); -}; - -/** - * Mime type for desktop files. - * Handles mount/umount icon, and user-defined properties. - * @short Mimetype for a .desktop file - */ -class TDEIO_EXPORT KDEDesktopMimeType : public KMimeType -{ - K_SYCOCATYPE( KST_KDEDesktopMimeType, KMimeType ) - -public: - enum ServiceType { ST_MOUNT, ST_UNMOUNT, /* ST_PROPERTIES, */ ST_USER_DEFINED }; - - /** - * Structure representing a service, in the list of services - * returned by builtinServices and userDefinedServices - */ - struct Service - { - Service() { m_display = true; } - bool isEmpty() const { return m_strName.isEmpty(); } - TQString m_strName; - TQString m_strIcon; - TQString m_strExec; - ServiceType m_type; - bool m_display; - }; - // KDEDesktopMimeType( const TQString & _fullpath, const TQString& _type, const TQString& _icon, - // const TQString& _comment, const TQStringList& _patterns ); - // KDEDesktopMimeType( const TQString & _fullpath ) : KMimeType( _fullpath ) { } - /** - * Construct a desktop mimetype and take all information from a desktop file. - * @param config the desktop configuration file that describes the mime type - */ - KDEDesktopMimeType( KDesktopFile *config) : KMimeType( config ) { } - /** \internal */ - KDEDesktopMimeType( TQDataStream& _str, int offset ) : KMimeType( _str, offset ) { } - - virtual TQString icon( const TQString& _url, bool _is_local ) const; - virtual TQString icon( const KURL& _url, bool _is_local ) const; - virtual TQPixmap pixmap( const KURL& _url, KIcon::Group _group, int _force_size = 0, - int _state = 0, TQString * _path = 0L ) const; - virtual TQString comment( const TQString& _url, bool _is_local ) const; - virtual TQString comment( const KURL& _url, bool _is_local ) const; - - /** - * Returns a list of services for the given .desktop file that are handled - * by kio itself. Namely mount/unmount for FSDevice files. - * @return the list of services - */ - static TQValueList<Service> builtinServices( const KURL& _url ); - /** - * Returns a list of services defined by the user as possible actions - * on the given .desktop file. May include empty actions which represent where - * visual separators should appear in user-visible representations of those actions, - * such as separators in a menu. - * @param path the path to the desktop file describing the services - * @param bLocalFiles true if those services are to be applied to local files only - * (if false, services that don't have %u or %U in the Exec line won't be taken into account). - * @return the list of user deviced actions - */ - static TQValueList<Service> userDefinedServices( const TQString& path, bool bLocalFiles ); - - /** - * Overload of userDefinedServices for speed purposes: it takes a TDEConfig* so that - * the caller can check things in the file without having it parsed twice. - * @since 3.4 - */ - static TQValueList<Service> userDefinedServices( const TQString& path, TDEConfig& config, bool bLocalFiles ); - - /** - * Overload of userDefinedServices but also allows you to pass a list of urls for this file. - * This allows for the menu to be changed depending on the exact files via - * the X-TDE-GetActionMenu extension. - * @since 3.5 - */ - static TQValueList<Service> userDefinedServices( const TQString& path, TDEConfig& config, bool bLocalFiles, const KURL::List & file_list); - - /** - * @param path is the path of the desktop entry. - * @param service the service to execute - * @deprecated, see the other executeService - */ - static void executeService( const TQString& path, KDEDesktopMimeType::Service& service ) KDE_DEPRECATED; - - /** - * Execute @p service on the list of @p urls. - * @param urls the list of urls - * @param service the service to execute - */ - static void executeService( const KURL::List& urls, KDEDesktopMimeType::Service& service ); - - /** - * Invokes the default action for the desktop entry. If the desktop - * entry is not local, then only false is returned. Otherwise we - * would create a security problem. Only types Link and Mimetype - * could be followed. - * - * @param _url the url to run - * @param _is_local true if the URL is local, false otherwise - * @return true on success and false on failure. - * @see KRun::runURL - */ - static pid_t run( const KURL& _url, bool _is_local ); - -protected: - virtual TQPixmap pixmap( KIcon::Group group, int force_size = 0, int state = 0, - TQString * path = 0L ) const - { return KMimeType::pixmap( group, force_size, state, path ); } - - static pid_t runFSDevice( const KURL& _url, const KSimpleConfig &cfg ); - static pid_t runApplication( const KURL& _url, const TQString & _serviceFile ); - static pid_t runLink( const KURL& _url, const KSimpleConfig &cfg ); - static pid_t runMimeType( const KURL& _url, const KSimpleConfig &cfg ); -protected: - virtual void virtual_hook( int id, void* data ); -}; - -/** - * The mime type for executable files. - * @short MimeType for any executable, like /bin/ls - */ -class TDEIO_EXPORT KExecMimeType : public KMimeType -{ - K_SYCOCATYPE( KST_KExecMimeType, KMimeType ) - -public: - // KExecMimeType( const TQString & _fullpath, const TQString& _type, const TQString& _icon, - // const TQString& _comment, const TQStringList& _patterns ); - // KExecMimeType( const TQString & _fullpath ) : KMimeType( _fullpath ) { } - /** - * Construct a executable mimetype and take all information from a desktop file. - * @param config the desktop configuration file that describes the mime type - */ - KExecMimeType( KDesktopFile *config) : KMimeType( config ) { } - /** \internal */ - KExecMimeType( TQDataStream& _str, int offset ) : KMimeType( _str, offset ) { } -protected: - virtual void virtual_hook( int id, void* data ); -}; - -#endif diff --git a/kio/kio/kmimetypechooser.cpp b/kio/kio/kmimetypechooser.cpp deleted file mode 100644 index 8ab3a69ee..000000000 --- a/kio/kio/kmimetypechooser.cpp +++ /dev/null @@ -1,298 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2001 - 2004 Anders Lund <anders@alweb.dk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kmimetypechooser.h" - -#include <kconfig.h> -#include <kiconloader.h> -#include <klistview.h> -#include <klocale.h> -#include <kmimetype.h> -#include <kprocess.h> -#include <krun.h> -#include <tdesycoca.h> - -#include <tqlabel.h> -#include <tqlayout.h> -#include <tqlineedit.h> -#include <tqpushbutton.h> -#include <tqwhatsthis.h> - -//BEGIN KMimeTypeChooserPrivate -class KMimeTypeChooserPrivate -{ - public: - KListView *lvMimeTypes; - TQPushButton *btnEditMimeType; - - TQString defaultgroup; - TQStringList groups; - int visuals; -}; -//END - -//BEGIN KMimeTypeChooser -KMimeTypeChooser::KMimeTypeChooser( const TQString &text, - const TQStringList &selMimeTypes, - const TQString &defaultGroup, - const TQStringList &groupsToShow, - int visuals, - TQWidget *parent, - const char *name ) - : TQVBox( parent, name ) -{ - d = new KMimeTypeChooserPrivate(); - d->lvMimeTypes = 0; - d->btnEditMimeType = 0; - d->defaultgroup = defaultGroup; - d->groups = groupsToShow; - d->visuals = visuals; - - setSpacing( KDialogBase::spacingHint() ); - - if ( !text.isEmpty() ) - { - new TQLabel( text, this ); - } - - d->lvMimeTypes = new KListView( this ); - - d->lvMimeTypes->addColumn( i18n("Mime Type") ); -// d->lvMimeTypes->setColumnWidthMode( 0, TQListView::Manual ); - - if ( visuals & Comments ) - { - d->lvMimeTypes->addColumn( i18n("Comment") ); - d->lvMimeTypes->setColumnWidthMode( 1, TQListView::Manual ); - } - if ( visuals & Patterns ) - d->lvMimeTypes->addColumn( i18n("Patterns") ); - - d->lvMimeTypes->setRootIsDecorated( true ); - - loadMimeTypes( selMimeTypes ); - - if (visuals & KMimeTypeChooser::EditButton) - { - TQHBox *btns = new TQHBox( this ); - ((TQBoxLayout*)btns->layout())->addStretch(1); - d->btnEditMimeType = new TQPushButton( i18n("&Edit..."), btns ); - - connect( d->btnEditMimeType, TQT_SIGNAL(clicked()), this, TQT_SLOT(editMimeType()) ); - d->btnEditMimeType->setEnabled( false ); - connect( d->lvMimeTypes, TQT_SIGNAL( doubleClicked ( TQListViewItem * )), - this, TQT_SLOT( editMimeType())); - connect( d->lvMimeTypes, TQT_SIGNAL(currentChanged(TQListViewItem*)), - this, TQT_SLOT(slotCurrentChanged(TQListViewItem*)) ); - - TQWhatsThis::add( d->btnEditMimeType, i18n( - "Click this button to display the familiar TDE mime type editor.") ); - } -} - -KMimeTypeChooser::~KMimeTypeChooser() -{ - delete d; -} - -void KMimeTypeChooser::loadMimeTypes( const TQStringList &_selectedMimeTypes ) -{ - TQStringList selMimeTypes; - - if ( !_selectedMimeTypes.isEmpty() ) - selMimeTypes = _selectedMimeTypes; - else - selMimeTypes = mimeTypes(); - - d->lvMimeTypes->clear(); - - TQMap<TQString,TQListViewItem*> groups; - // thanks to tdebase/kcontrol/filetypes/filetypesview - KMimeType::List mimetypes = KMimeType::allMimeTypes(); - TQValueListIterator<KMimeType::Ptr> it(mimetypes.begin()); - - TQListViewItem *groupItem; - bool agroupisopen = false; - TQListViewItem *idefault = 0; //open this, if all other fails - TQListViewItem *firstChecked = 0; // make this one visible after the loop - - for (; it != mimetypes.end(); ++it) - { - TQString mimetype = (*it)->name(); - int index = mimetype.find("/"); - TQString maj = mimetype.left(index); - - if ( d->groups.count() && !d->groups.contains( maj ) ) - continue; - - TQString min = mimetype.right(mimetype.length() - (index+1)); - - TQMapIterator<TQString,TQListViewItem*> mit = groups.find( maj ); - if ( mit == groups.end() ) - { - groupItem = new TQListViewItem( d->lvMimeTypes, maj ); - groups.insert( maj, groupItem ); - if ( maj == d->defaultgroup ) - idefault = groupItem; - } - else - groupItem = mit.data(); - - TQCheckListItem *item = new TQCheckListItem( groupItem, min, TQCheckListItem::CheckBox ); - item->setPixmap( 0, SmallIcon( (*it)->icon(TQString::null,false) ) ); - - int cl = 1; - - if ( d->visuals & Comments ) - { - item->setText( cl, (*it)->comment(TQString::null, false) ); - cl++; - } - - if ( d->visuals & Patterns ) - item->setText( cl, (*it)->patterns().join("; ") ); - - if ( selMimeTypes.contains(mimetype) ) - { - item->setOn( true ); - groupItem->setOpen( true ); - agroupisopen = true; - if ( !firstChecked ) - firstChecked = item; - } - } - - if ( firstChecked ) - d->lvMimeTypes->ensureItemVisible( firstChecked ); - - if ( !agroupisopen && idefault ) - { - idefault->setOpen( true ); - d->lvMimeTypes->ensureItemVisible( idefault ); - } -} - -void KMimeTypeChooser::editMimeType() -{ - if ( !(d->lvMimeTypes->currentItem() && (d->lvMimeTypes->currentItem())->parent()) ) - return; - TQString mt = (d->lvMimeTypes->currentItem()->parent())->text( 0 ) + "/" + (d->lvMimeTypes->currentItem())->text( 0 ); - // thanks to libkonq/konq_operations.cc - connect( KSycoca::self(), TQT_SIGNAL(databaseChanged()), - this, TQT_SLOT(slotSycocaDatabaseChanged()) ); - TQString keditfiletype = TQString::fromLatin1("keditfiletype"); - KRun::runCommand( keditfiletype - + " --parent " + TQString::number( (ulong)topLevelWidget()->winId()) - + " " + TDEProcess::quote(mt), - keditfiletype, keditfiletype /*unused*/); -} - -void KMimeTypeChooser::slotCurrentChanged(TQListViewItem* i) -{ - if ( d->btnEditMimeType ) - d->btnEditMimeType->setEnabled( i->parent() ); -} - -void KMimeTypeChooser::slotSycocaDatabaseChanged() -{ - if ( KSycoca::self()->isChanged("mime") ) - loadMimeTypes(); -} - -TQStringList KMimeTypeChooser::mimeTypes() const -{ - TQStringList l; - TQListViewItemIterator it( d->lvMimeTypes ); - for (; it.current(); ++it) - { - if ( it.current()->parent() && ((TQCheckListItem*)it.current())->isOn() ) - l << it.current()->parent()->text(0) + "/" + it.current()->text(0); // FIXME uncecked, should be Ok unless someone changes mimetypes during this! - } - return l; -} - -TQStringList KMimeTypeChooser::patterns() const -{ - TQStringList l; - KMimeType::Ptr p; - TQString defMT = KMimeType::defaultMimeType(); - TQListViewItemIterator it( d->lvMimeTypes ); - for (; it.current(); ++it) - { - if ( it.current()->parent() && ((TQCheckListItem*)it.current())->isOn() ) - { - p = KMimeType::mimeType( it.current()->parent()->text(0) + "/" + it.current()->text(0) ); - if ( p->name() != defMT ) - l += p->patterns(); - } - } - return l; -} -//END - -//BEGIN KMimeTypeChooserDialog -KMimeTypeChooserDialog::KMimeTypeChooserDialog( - const TQString &caption, - const TQString& text, - const TQStringList &selMimeTypes, - const TQString &defaultGroup, - const TQStringList &groupsToShow, - int visuals, - TQWidget *parent, const char *name ) - : KDialogBase(parent, name, true, caption, Cancel|Ok, Ok) -{ - m_chooser = new KMimeTypeChooser( text, selMimeTypes, - defaultGroup, groupsToShow, visuals, - this, "chooser" ); - setMainWidget(m_chooser); - - TDEConfigGroup group( TDEGlobal::config(), "KMimeTypeChooserDialog"); - TQSize defaultSize( 400, 300 ); - resize( group.readSizeEntry("size", &defaultSize) ); -} - -KMimeTypeChooserDialog::KMimeTypeChooserDialog( - const TQString &caption, - const TQString& text, - const TQStringList &selMimeTypes, - const TQString &defaultGroup, - TQWidget *parent, const char *name ) - : KDialogBase(parent, name, true, caption, Cancel|Ok, Ok) -{ - m_chooser = new KMimeTypeChooser( text, selMimeTypes, - defaultGroup, TQStringList(), - KMimeTypeChooser::Comments|KMimeTypeChooser::Patterns|KMimeTypeChooser::EditButton, - this, "chooser" ); - setMainWidget(m_chooser); - - TDEConfigGroup group( TDEGlobal::config(), "KMimeTypeChooserDialog"); - TQSize defaultSize( 400, 300 ); - resize( group.readSizeEntry("size", &defaultSize) ); -} - - -KMimeTypeChooserDialog::~KMimeTypeChooserDialog() -{ - TDEConfigGroup group( TDEGlobal::config(), "KMimeTypeChooserDialog"); - group.writeEntry("size", size()); -} - -//END KMimeTypeChooserDialog - -// kate: space-indent on; indent-width 2; replace-tabs on; -#include "kmimetypechooser.moc" diff --git a/kio/kio/kmimetypechooser.h b/kio/kio/kmimetypechooser.h deleted file mode 100644 index 16ec052f5..000000000 --- a/kio/kio/kmimetypechooser.h +++ /dev/null @@ -1,180 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2001 - 2004 Anders Lund <anders@alweb.dk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef _KMIMETYPE_CHOOSER_H_ -#define _KMIMETYPE_CHOOSER_H_ - -#include <tqvbox.h> -#include <kdialogbase.h> - - -/** - * This widget provides a checkable list of all available mimetypes, - * and a list of selected ones, as well as a corresponding list of file - * extensions, an optional text and an optional edit button (not working yet). - * Mime types is presented in a list view, with name, comment and patterns columns. - * - * @author Anders Lund (anders at alweb dk), jan 23, 2002 - */ -class TDEIO_EXPORT KMimeTypeChooser : public TQVBox -{ - Q_OBJECT - - public: - /** - * Buttons and data for display. - */ - enum Visuals { - Comments=1, ///< Show the Mimetypes Comment field in a column ("HTML Document"). - Patterns=2, ///< Show the Mimetypes Patterns field in a column ("*.html;*.htm"). - EditButton=4 ///< Show the "Edit" button, allowing to edit the selected type. - }; - /** - * Create a new KMimeTypeChooser. - * - * @param text A Text to display above the list - * @param selectedMimeTypes A list of mimetype names, theese will be checked - * in the list if they exist. - * @param visuals A OR'd Visuals enum to decide which data and buttons to display. - * @param defaultGroup The group to open when no groups are selected (like - * "text"). If not provided, no group is opened. If @p groupsToShow - * is provided and defaultGroup is not a member of that, it is ignored. - * @param groupsToShow a list of mimetype groups to show. If empty, all - * groups are shown. - * @param parent The parent widget to use - * @param name The internal name of this object - */ - KMimeTypeChooser( const TQString& text=TQString::null, - const TQStringList &selectedMimeTypes=0, - const TQString &defaultGroup=TQString::null, - const TQStringList &groupsToShow=TQStringList(), - int visuals=Comments|Patterns|EditButton, - TQWidget *parent=0, const char *name=0 ); - ~KMimeTypeChooser(); - - /** - * @return a list of all selected selected mimetypes represented by their name. - */ - TQStringList mimeTypes() const; - /** - * @return a list of the fileame patterns associated with all selected mimetypes. - */ - TQStringList patterns() const; - - public slots: - /** - * @short edit the current mimetype - * Uses KRun to start the KDE mimetype editor for editing the currently - * selected mimetype. - */ - void editMimeType(); - - private slots: - /** - * @internal disables the "edit" button for groups - */ - void slotCurrentChanged(TQListViewItem* i); - - /** - * @internal called when the sycoca database has changed after - * the user edited a mimetype - */ - void slotSycocaDatabaseChanged(); - - private: - /** - * @internal Load mime types into the list view - * If @p selected is empty, selectedMimeTypesStringList() is called - * to fill it in. - */ - void loadMimeTypes( const TQStringList &selected=TQStringList() ); - - class KMimeTypeChooserPrivate *d; -}; - -/** - * @short A Dialog to choose some mimetypes. - * Provides a checkable tree list of mimetypes, with icons and optinally - * comments and patterns, and an (optional) button to display the KDE mimetype - * editor. - * - * Here is an example, using the dialog to set the text of two lineedits: - * - * @code - * TQString text = i18n("Select the MimeTypes you want for this file type."); - * TQStringList list = TQStringList::split( TQRegExp("\\s*;\\s*"), leMimetypes->text() ); - * KMimeTypeChooserDialog *d = new KMimeTypeChooserDialog( this, 0, - * i18n("Select Mime Types"), text, list, "text" ); - * if ( d->exec() == KDialogBase::Accepted ) { - * leWildcards->setText( d->chooser()->patterns().join(";") ); - * leMimetypes->setText( d->chooser()->mimeTypes().join(";") ); - * } - * @endcode - * - * @author Anders Lund (anders at alweb dk) dec 19, 2001 - */ -class TDEIO_EXPORT KMimeTypeChooserDialog : public KDialogBase -{ - public: - /** - * Create a KMimeTypeChooser dialog. - * - * @param caption The title of the dialog - * @param text A Text to display above the list - * @param selectedMimeTypes A list of mimetype names, theese will be - * checked in the list if they exist. - * patterns will be added to the list view. - * @param visuals A OR'd KMimetypeChooser::Visuals enum to decide which data - * and buttons to display. - * @param defaultGroup The group to open when no groups are selected (like - * "text"). If not provided, no group is opened. If @p groupsToShow - * is provided and defaultGroup is not a member of that, it is ignored. - * @param groupsToShow a list of mimetype groups to show. If empty, all - * groups are shown. - * @param parent The parent widget to use - * @param name The internal name of this object - */ - KMimeTypeChooserDialog( const TQString &caption=TQString::null, - const TQString& text=TQString::null, - const TQStringList &selectedMimeTypes=TQStringList(), - const TQString &defaultGroup=TQString::null, - const TQStringList &groupsToShow=TQStringList(), - int visuals=KMimeTypeChooser::Comments|KMimeTypeChooser::Patterns|KMimeTypeChooser::EditButton, - TQWidget *parent=0, const char *name=0 ); - - /** - * @overload - */ - KMimeTypeChooserDialog( const TQString &caption, - const TQString& text, - const TQStringList &selectedMimeTypes, - const TQString &defaultGroup, - TQWidget *parent=0, const char *name=0 ); - - ~KMimeTypeChooserDialog(); - - /** - * @return a pointer to the KMimeTypeChooser widget - */ - KMimeTypeChooser* chooser() { return m_chooser; } - - private: - KMimeTypeChooser *m_chooser; -}; -#endif // _KMIMETYPE_CHOOSER_H_ -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/kio/kio/kmimetyperesolver.h b/kio/kio/kmimetyperesolver.h deleted file mode 100644 index c8828a0da..000000000 --- a/kio/kio/kmimetyperesolver.h +++ /dev/null @@ -1,255 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - Copyright (C) 2000 Rik Hemsley <rik@kde.org> - Copyright (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kmimetyperesolver_h -#define __kmimetyperesolver_h - -#include <tqscrollview.h> -#include <tqptrlist.h> -#include <tqtimer.h> -#include <kdebug.h> - -/** - * @internal - * A baseclass for KMimeTypeResolver, with the interface, - * KMimeTypeResolverHelper uses. - */ -class TDEIO_EXPORT KMimeTypeResolverBase -{ -public: - virtual void slotViewportAdjusted() = 0; - virtual void slotProcessMimeIcons() = 0; -protected: - virtual void virtual_hook( int, void* ) {} -}; - -/** - * @internal - * This class is used by KMimeTypeResolver, because it can't be a QObject - * itself. So an object of this class is used to handle signals, slots etc. - * and forwards them to the KMimeTypeResolver instance. - */ -class TDEIO_EXPORT KMimeTypeResolverHelper : public TQObject -{ - Q_OBJECT - -public: - KMimeTypeResolverHelper( KMimeTypeResolverBase *resolver, - TQScrollView *view ) - : m_resolver( resolver ), - m_timer( new TQTimer( this ) ) - { - connect( m_timer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotProcessMimeIcons() )); - - connect( view->horizontalScrollBar(), TQT_SIGNAL( sliderMoved(int) ), - TQT_SLOT( slotAdjust() ) ); - connect( view->verticalScrollBar(), TQT_SIGNAL( sliderMoved(int) ), - TQT_SLOT( slotAdjust() ) ); - - view->viewport()->installEventFilter( this ); - } - - void start( int delay, bool singleShot ) - { - m_timer->start( delay, singleShot ); - } - -protected: - virtual bool eventFilter( TQObject *o, TQEvent *e ) - { - bool ret = TQObject::eventFilter( o, e ); - - if ( e->type() == TQEvent::Resize ) - m_resolver->slotViewportAdjusted(); - - return ret; - } - -private slots: - void slotProcessMimeIcons() - { - m_resolver->slotProcessMimeIcons(); - } - - void slotAdjust() - { - m_resolver->slotViewportAdjusted(); - } - -private: - KMimeTypeResolverBase *m_resolver; - TQTimer *m_timer; -}; - -/** - * This class implements the "delayed-mimetype-determination" feature, - * for konqueror's directory views (and KFileDialog's :). - * - * It determines the mimetypes of the icons in the background, but giving - * preferrence to the visible icons. - * - * It is implemented as a template, so that it can work with both QPtrListViewItem - * and TQIconViewItem, without requiring hacks such as void * or TQPtrDict lookups. - * - * Here's what the parent must implement : - * @li void mimeTypeDeterminationFinished(); - * @li TQScrollView * scrollWidget(); - * @li void determineIcon( IconItem * item ), which should call - * @li KFileItem::determineMimeType on the fileItem, and update the icon, etc. -*/ -template<class IconItem, class Parent> -class KMimeTypeResolver : public KMimeTypeResolverBase // if only this could be a TQObject.... -{ -public: - /** - * Creates a new KMimeTypeResolver with the given parent. - * @param parent the parent's resolver - */ - KMimeTypeResolver( Parent * parent ) - : m_parent(parent), - m_helper( new KMimeTypeResolverHelper(this, parent->scrollWidget())), - m_delayNonVisibleIcons(10) - {} - - virtual ~KMimeTypeResolver() { - delete m_helper; - } - - /** - * Start the mimetype-determination. Call this when the listing is completed. - * @param delayNonVisibleIcons the delay to use between icons not on screen. - * Usually 10, but should be set to 0 when the image preview feature is - * activated, because image preview can only start once we know the mimetypes - */ - void start( uint delayNonVisibleIcons = 10 ) - { - m_helper->start( 0, true /* single shot */ ); - m_delayNonVisibleIcons = delayNonVisibleIcons; - } - - /** - * The list of items to process. The view is free to - * clear it, insert new items into it, remove items, etc. - * @return the list of items to process - */ - TQPtrList<IconItem> m_lstPendingMimeIconItems; - - /** - * "Connected" to the viewportAdjusted signal of the scrollview - */ - virtual void slotViewportAdjusted(); - - /** - * "Connected" to the timer - */ - virtual void slotProcessMimeIcons(); - -private: - /** - * Find a visible icon and determine its mimetype. - * KonqDirPart will call this method repeatedly until it returns 0L - * (no more visible icon to process). - * @return the file item that was just processed. - */ - IconItem * findVisibleIcon(); - - Parent * m_parent; - KMimeTypeResolverHelper *m_helper; - uint m_delayNonVisibleIcons; -}; - -// The main slot -template<class IconItem, class Parent> -inline void KMimeTypeResolver<IconItem, Parent>::slotProcessMimeIcons() -{ - //kdDebug(1203) << "KMimeTypeResolver::slotProcessMimeIcons() " - // << m_lstPendingMimeIconItems.count() << endl; - IconItem * item = 0L; - int nextDelay = 0; - - if ( m_lstPendingMimeIconItems.count() > 0 ) - { - // We only find mimetypes for icons that are visible. When more - // of our viewport is exposed, we'll get a signal and then get - // the mimetypes for the newly visible icons. (Rikkus) - item = findVisibleIcon(); - } - - // No more visible items. - if (0 == item) - { - // Do the unvisible ones, then, but with a bigger delay, if so configured - if ( m_lstPendingMimeIconItems.count() > 0 ) - { - item = m_lstPendingMimeIconItems.first(); - nextDelay = m_delayNonVisibleIcons; - } - else - { - m_parent->mimeTypeDeterminationFinished(); - return; - } - } - - m_parent->determineIcon(item); - m_lstPendingMimeIconItems.remove(item); - m_helper->start( nextDelay, true /* single shot */ ); -} - -template<class IconItem, class Parent> -inline void KMimeTypeResolver<IconItem, Parent>::slotViewportAdjusted() -{ - if (m_lstPendingMimeIconItems.isEmpty()) return; - IconItem * item = findVisibleIcon(); - if (item) - { - m_parent->determineIcon( item ); - m_lstPendingMimeIconItems.remove(item); - m_helper->start( 0, true /* single shot */ ); - } -} - -template<class IconItem, class Parent> -inline IconItem * KMimeTypeResolver<IconItem, Parent>::findVisibleIcon() -{ - // Find an icon that's visible and whose mimetype we don't know. - - TQPtrListIterator<IconItem> it(m_lstPendingMimeIconItems); - if ( m_lstPendingMimeIconItems.count()<20) // for few items, it's faster to not bother - return m_lstPendingMimeIconItems.first(); - - TQScrollView * view = m_parent->scrollWidget(); - TQRect visibleContentsRect - ( - view->viewportToContents(TQPoint(0, 0)), - view->viewportToContents - ( - TQPoint(view->visibleWidth(), view->visibleHeight()) - ) - ); - - for (; it.current(); ++it) - if (visibleContentsRect.intersects(it.current()->rect())) - return it.current(); - - return 0L; -} - -#endif diff --git a/kio/kio/knfsshare.cpp b/kio/kio/knfsshare.cpp deleted file mode 100644 index 394120009..000000000 --- a/kio/kio/knfsshare.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqdict.h> -#include <tqfile.h> -#include <tqtextstream.h> - -#include <kdirwatch.h> -#include <kstaticdeleter.h> -#include <kdebug.h> -#include <kconfig.h> - -#include "knfsshare.h" - -class KNFSSharePrivate -{ -public: - KNFSSharePrivate(); - - bool readExportsFile(); - bool findExportsFile(); - - TQDict<bool> sharedPaths; - TQString exportsFile; -}; - -KNFSSharePrivate::KNFSSharePrivate() -{ - if (findExportsFile()) - readExportsFile(); -} - -/** - * Try to find the nfs config file path - * First tries the kconfig, then checks - * several well-known paths - * @return wether an 'exports' file was found. - **/ -bool KNFSSharePrivate::findExportsFile() { - TDEConfig config("knfsshare"); - config.setGroup("General"); - exportsFile = config.readPathEntry("exportsFile"); - - if ( TQFile::exists(exportsFile) ) - return true; - - if ( TQFile::exists("/etc/exports") ) - exportsFile = "/etc/exports"; - else { - kdDebug(7000) << "KNFSShare: Could not found exports file!" << endl; - return false; - } - - config.writeEntry("exportsFile",exportsFile); - return true; -} - -/** - * Reads all paths from the exports file - * and fills the sharedPaths dict with the values - */ -bool KNFSSharePrivate::readExportsFile() { - TQFile f(exportsFile); - - kdDebug(7000) << "KNFSShare::readExportsFile " << exportsFile << endl; - - if (!f.open(IO_ReadOnly)) { - kdError() << "KNFSShare: Could not open " << exportsFile << endl; - return false; - } - - - sharedPaths.clear(); - - TQTextStream s( &f ); - - bool continuedLine = false; // is true if the line before ended with a backslash - TQString completeLine; - - while ( !s.eof() ) - { - TQString currentLine = s.readLine().stripWhiteSpace(); - - if (continuedLine) { - completeLine += currentLine; - continuedLine = false; - } - else - completeLine = currentLine; - - // is the line continued in the next line ? - if ( completeLine[completeLine.length()-1] == '\\' ) - { - continuedLine = true; - // remove the ending backslash - completeLine.truncate( completeLine.length()-1 ); - continue; - } - - // comments or empty lines - if (completeLine.isEmpty() || - '#' == completeLine[0]) - { - continue; - } - - TQString path; - - // Handle quotation marks - if ( completeLine[0] == '"' ) { - int i = completeLine.find('"',1); - if (i == -1) { - kdError() << "KNFSShare: Parse error: Missing quotation mark: " << completeLine << endl; - continue; - } - path = completeLine.mid(1,i-1); - - } else { // no quotation marks - int i = completeLine.find(' '); - if (i == -1) - i = completeLine.find('\t'); - - if (i == -1) - path = completeLine; - else - path = completeLine.left(i); - - } - - kdDebug(7000) << "KNFSShare: Found path: " << path << endl; - - // normalize path - if ( path[path.length()-1] != '/' ) - path += '/'; - - bool b = true; - sharedPaths.insert(path,&b); - } - - f.close(); - - return true; - -} - -KNFSShare::KNFSShare() { - d = new KNFSSharePrivate(); - if (TQFile::exists(d->exportsFile)) { - KDirWatch::self()->addFile(d->exportsFile); - connect(KDirWatch::self(), TQT_SIGNAL(dirty (const TQString&)),this, - TQT_SLOT(slotFileChange(const TQString&))); - } -} - -KNFSShare::~KNFSShare() { - if (TQFile::exists(d->exportsFile)) { - KDirWatch::self()->removeFile(d->exportsFile); - } - delete d; -} - - -bool KNFSShare::isDirectoryShared( const TQString & path ) const { - TQString fixedPath = path; - if ( path[path.length()-1] != '/' ) - fixedPath += '/'; - - return d->sharedPaths.find(fixedPath) != 0; -} - -TQStringList KNFSShare::sharedDirectories() const { - TQStringList result; - TQDictIterator<bool> it(d->sharedPaths); - for( ; it.current(); ++it ) - result << it.currentKey(); - - return result; -} - -TQString KNFSShare::exportsPath() const { - return d->exportsFile; -} - - - -void KNFSShare::slotFileChange( const TQString & path ) { - if (path == d->exportsFile) - d->readExportsFile(); - - emit changed(); -} - -KNFSShare* KNFSShare::_instance = 0L; -static KStaticDeleter<KNFSShare> ksdNFSShare; - -KNFSShare* KNFSShare::instance() { - if (! _instance ) - _instance = ksdNFSShare.setObject(_instance, new KNFSShare()); - - return _instance; -} - -#include "knfsshare.moc" - diff --git a/kio/kio/knfsshare.h b/kio/kio/knfsshare.h deleted file mode 100644 index 64cd28dcf..000000000 --- a/kio/kio/knfsshare.h +++ /dev/null @@ -1,86 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef knfsshare_h -#define knfsshare_h - -#include <tqobject.h> - -#include <tdelibs_export.h> - -class KNFSSharePrivate; - -/** - * Similar functionality like KFileShare, - * but works only for NFS and do not need - * any suid script. - * It parses the /etc/exports file to get its information. - * Singleton class, call instance() to get an instance. - */ -class TDEIO_EXPORT KNFSShare : public TQObject -{ -Q_OBJECT -public: - /** - * Returns the one and only instance of KNFSShare - */ - static KNFSShare* instance(); - - /** - * Wether or not the given path is shared by NFS. - * @param path the path to check if it is shared by NFS. - * @return wether the given path is shared by NFS. - */ - bool isDirectoryShared( const TQString & path ) const; - - /** - * Returns a list of all directories shared by NFS. - * The resulting list is not sorted. - * @return a list of all directories shared by NFS. - */ - TQStringList sharedDirectories() const; - - /** - * KNFSShare destructor. - * Do not call! - * The instance is destroyed automatically! - */ - virtual ~KNFSShare(); - - /** - * Returns the path to the used exports file, - * or null if no exports file was found - */ - TQString exportsPath() const; - -signals: - /** - * Emitted when the /etc/exports file has changed - */ - void changed(); - -private: - KNFSShare(); - static KNFSShare* _instance; - KNFSSharePrivate* d; - -private slots: - void slotFileChange(const TQString&); -}; - -#endif diff --git a/kio/kio/kprotocolinfo.cpp b/kio/kio/kprotocolinfo.cpp deleted file mode 100644 index 9523b70cb..000000000 --- a/kio/kio/kprotocolinfo.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1999 Torben Weis <weis@kde.org> - Copyright (C) 2003 Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifdef MAKE_TDECORE_LIB //needed for proper linkage (win32) -#undef TDEIO_EXPORT -#define TDEIO_EXPORT KDE_EXPORT -#endif - -#include "kprotocolinfo.h" -#include "kprotocolinfofactory.h" -#include "kprotocolmanager.h" - -// Most of this class is implemented in tdecore/kprotocolinfo_tdecore.cpp -// This file only contains a few static class-functions that depend on -// KProtocolManager - -KProtocolInfo* KProtocolInfo::findProtocol(const KURL &url) -{ -#ifdef MAKE_TDECORE_LIB - return 0; -#else - TQString protocol = url.protocol(); - - if ( !KProtocolInfo::proxiedBy( protocol ).isEmpty() ) - { - TQString dummy; - protocol = KProtocolManager::slaveProtocol(url, dummy); - } - - return KProtocolInfoFactory::self()->findProtocol(protocol); -#endif -} - - -KProtocolInfo::Type KProtocolInfo::inputType( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return T_NONE; - - return prot->m_inputType; -} - -KProtocolInfo::Type KProtocolInfo::outputType( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return T_NONE; - - return prot->m_outputType; -} - - -bool KProtocolInfo::isSourceProtocol( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->m_isSourceProtocol; -} - -bool KProtocolInfo::isFilterProtocol( const KURL &url ) -{ - return isFilterProtocol (url.protocol()); -} - -bool KProtocolInfo::isFilterProtocol( const TQString &protocol ) -{ - // We call the findProtocol (const TQString&) to bypass any proxy settings. - KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol(protocol); - if ( !prot ) - return false; - - return !prot->m_isSourceProtocol; -} - -bool KProtocolInfo::isHelperProtocol( const KURL &url ) -{ - return isHelperProtocol (url.protocol()); -} - -bool KProtocolInfo::isHelperProtocol( const TQString &protocol ) -{ - // We call the findProtocol (const TQString&) to bypass any proxy settings. - KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol(protocol); - if ( !prot ) - return false; - - return prot->m_isHelperProtocol; -} - -bool KProtocolInfo::isKnownProtocol( const KURL &url ) -{ - return isKnownProtocol (url.protocol()); -} - -bool KProtocolInfo::isKnownProtocol( const TQString &protocol ) -{ - // We call the findProtocol (const TQString&) to bypass any proxy settings. - KProtocolInfo::Ptr prot = KProtocolInfoFactory::self()->findProtocol(protocol); - return ( prot != 0); -} - -bool KProtocolInfo::supportsListing( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->m_supportsListing; -} - -TQStringList KProtocolInfo::listing( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return TQStringList(); - - return prot->m_listing; -} - -bool KProtocolInfo::supportsReading( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->m_supportsReading; -} - -bool KProtocolInfo::supportsWriting( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->m_supportsWriting; -} - -bool KProtocolInfo::supportsMakeDir( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->m_supportsMakeDir; -} - -bool KProtocolInfo::supportsDeleting( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->m_supportsDeleting; -} - -bool KProtocolInfo::supportsLinking( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->m_supportsLinking; -} - -bool KProtocolInfo::supportsMoving( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->m_supportsMoving; -} - -bool KProtocolInfo::canCopyFromFile( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->m_canCopyFromFile; -} - - -bool KProtocolInfo::canCopyToFile( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->m_canCopyToFile; -} - -bool KProtocolInfo::canRenameFromFile( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->canRenameFromFile(); -} - - -bool KProtocolInfo::canRenameToFile( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->canRenameToFile(); -} - -bool KProtocolInfo::canDeleteRecursive( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return false; - - return prot->canDeleteRecursive(); -} - -KProtocolInfo::FileNameUsedForCopying KProtocolInfo::fileNameUsedForCopying( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return FromURL; - - return prot->fileNameUsedForCopying(); -} - -TQString KProtocolInfo::defaultMimetype( const KURL &url ) -{ - KProtocolInfo::Ptr prot = findProtocol(url); - if ( !prot ) - return TQString::null; - - return prot->m_defaultMimetype; -} - diff --git a/kio/kio/kprotocolinfo.h b/kio/kio/kprotocolinfo.h deleted file mode 100644 index 10addc610..000000000 --- a/kio/kio/kprotocolinfo.h +++ /dev/null @@ -1,688 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1999 Torben Weis <weis@kde.org> - Copyright (C) 2000-2001 Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __kprotocolinfo_h__ -#define __kprotocolinfo_h__ - -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqdatastream.h> - -#include <kurl.h> -#include <tdesycocaentry.h> -#include <tdesycocatype.h> - -/** - * Information about I/O (Internet, etc.) protocols supported by KDE. - - * This class is useful if you want to know which protocols - * KDE supports. In addition you can find out lots of information - * about a certain protocol. A KProtocolInfo instance represents a - * single protocol. Most of the functionality is provided by the static - * methods that scan the *.protocol files of all installed kioslaves to get - * this information. - * - * *.protocol files are installed in the "services" resource. - * - * @author Torben Weis <weis@kde.org> - */ -class TDEIO_EXPORT KProtocolInfo : public KSycocaEntry -{ - friend class KProtocolInfoFactory; - K_SYCOCATYPE( KST_KProtocolInfo, KSycocaEntry ) - -public: - typedef KSharedPtr<KProtocolInfo> Ptr; - -public: - /** - * Read a protocol description file - * @param path the path of the description file - */ - KProtocolInfo( const TQString & path); // KDE4: make private and add friend class KProtocolInfoBuildFactory - // Then we can get rid of the d pointer - - /** - * Returns whether the protocol description file is valid. - * @return true if valid, false otherwise - */ - virtual bool isValid() const { return !m_name.isEmpty(); } - - /** - * Returns the name of the protocol. - * - * This corresponds to the "protocol=" field in the protocol description file. - * - * @return the name of the protocol - * @see KURL::protocol() - */ - virtual TQString name() const { return m_name; } - - // - // Static functions: - // - - /** - * Returns list of all known protocols. - * @return a list of all known protocols - */ - static TQStringList protocols(); - - /** - * Returns whether a protocol is installed that is able to handle @p url. - * - * @param url the url to check - * @return true if the protocol is known - * @see name() - */ - static bool isKnownProtocol( const KURL &url ); - - /** - * Same as above except you can supply just the protocol instead of - * the whole URL. - */ - static bool isKnownProtocol( const TQString& protocol ) -#ifdef KPROTOCOLINFO_TDECORE - KDE_WEAK_SYMBOL -#endif - ; - - /** - * Returns the library / executable to open for the protocol @p protocol - * Example : "kio_ftp", meaning either the executable "kio_ftp" or - * the library "kio_ftp.la" (recommended), whichever is available. - * - * This corresponds to the "exec=" field in the protocol description file. - * @param protocol the protocol to check - * @return the executable of library to open, or TQString::null for - * unsupported protocols - * @see KURL::protocol() - */ - static TQString exec( const TQString& protocol ); - - /** - * Describes the type of a protocol. - */ - enum Type { T_STREAM, ///< protocol returns a stream - T_FILESYSTEM, ///<protocol describes location in a file system - T_NONE, ///< no information about the tyope available - T_ERROR ///< used to signal an error - }; - - /** - * Returns whether the protocol should be treated as a filesystem - * or as a stream when reading from it. - * - * This corresponds to the "input=" field in the protocol description file. - * Valid values for this field are "filesystem", "stream" or "none" (default). - * - * @param url the url to check - * @return the input type of the given @p url - */ - static Type inputType( const KURL &url ); - - /** - * Returns whether the protocol should be treated as a filesystem - * or as a stream when writing to it. - * - * This corresponds to the "output=" field in the protocol description file. - * Valid values for this field are "filesystem", "stream" or "none" (default). - * - * @param url the url to check - * @return the output type of the given @p url - */ - static Type outputType( const KURL &url ); - - /** - * Returns the list of fields this protocol returns when listing - * The current possibilities are - * Name, Type, Size, Date, AccessDate, Access, Owner, Group, Link, URL, MimeType - * as well as Extra1, Extra2 etc. for extra fields (see extraFields). - * - * This corresponds to the "listing=" field in the protocol description file. - * The supported fields should be separated with ',' in the protocol description file. - * - * @param url the url to check - * @return a list of field names - */ - static TQStringList listing( const KURL &url ); - - /** - * Definition of an extra field in the UDS entries, returned by a listDir operation. - * - * The name is the name of the column, translated. - * - * The type name comes from TQVariant::typeName() - * Currently supported types: "TQString", "TQDateTime" (ISO-8601 format) - * - * @since 3.2 - */ - struct ExtraField { - ExtraField() {} // for QValueList - ExtraField(const TQString& _name, const TQString& _type ) - : name(_name), type(_type) { - } - TQString name; - TQString type; // KDE4: make it TQVariant::Type - }; - typedef TQValueList<ExtraField > ExtraFieldList; - /** - * Definition of extra fields in the UDS entries, returned by a listDir operation. - * - * This corresponds to the "ExtraNames=" and "ExtraTypes=" fields in the protocol description file. - * Those two lists should be separated with ',' in the protocol description file. - * See ExtraField for details about names and types - * - * @since 3.2 - */ - static ExtraFieldList extraFields( const KURL& url ); - - /** - * Returns whether the protocol can act as a source protocol. - * - * A source protocol retrieves data from or stores data to the - * location specified by a URL. - * A source protocol is the opposite of a filter protocol. - * - * The "source=" field in the protocol description file determines - * whether a protocol is a source protocol or a filter protocol. - * @param url the url to check - * @return true if the protocol is a source of data (e.g. http), false if the - * protocol is a filter (e.g. gzip) - */ - static bool isSourceProtocol( const KURL &url ); - - /** - * Returns whether the protocol can act as a helper protocol. - * A helper protocol invokes an external application and does not return - * a file or stream. - * - * This corresponds to the "helper=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol is a helper protocol (e.g. vnc), false - * if not (e.g. http) - */ - static bool isHelperProtocol( const KURL &url ); - - /** - * Same as above except you can supply just the protocol instead of - * the whole URL. - */ - static bool isHelperProtocol( const TQString& protocol ) -#ifdef KPROTOCOLINFO_TDECORE - KDE_WEAK_SYMBOL -#endif - ; - - /** - * Returns whether the protocol can act as a filter protocol. - * - * A filter protocol can operate on data that is passed to it - * but does not retrieve/store data itself, like gzip. - * A filter protocol is the opposite of a source protocol. - * - * The "source=" field in the protocol description file determines - * whether a protocol is a source protocol or a filter protocol. - * Valid values for this field are "true" (default) for source protocol or - * "false" for filter protocol. - * - * @param url the url to check - * @return true if the protocol is a filter (e.g. gzip), false if the - * protocol is a helper or source - */ - static bool isFilterProtocol( const KURL &url ); - - /** - * Same as above except you can supply just the protocol instead of - * the whole URL. - */ - static bool isFilterProtocol( const TQString& protocol ) -#ifdef KPROTOCOLINFO_TDECORE - KDE_WEAK_SYMBOL -#endif - ; - - /** - * Returns whether the protocol can list files/objects. - * If a protocol supports listing it can be browsed in e.g. file-dialogs - * and konqueror. - * - * Whether a protocol supports listing is determined by the "listing=" - * field in the protocol description file. - * If the protocol support listing it should list the fields it provides in - * this field. If the protocol does not support listing this field should - * remain empty (default.) - * - * @param url the url to check - * @return true if the protocol support listing - * @see listing() - */ - static bool supportsListing( const KURL &url ); - - /** - * Returns whether the protocol can retrieve data from URLs. - * - * This corresponds to the "reading=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if it is possible to read from the URL - */ - static bool supportsReading( const KURL &url ); - - /** - * Returns whether the protocol can store data to URLs. - * - * This corresponds to the "writing=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol supports writing - */ - static bool supportsWriting( const KURL &url ); - - /** - * Returns whether the protocol can create directories/folders. - * - * This corresponds to the "makedir=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol can create directories - */ - static bool supportsMakeDir( const KURL &url ); - - /** - * Returns whether the protocol can delete files/objects. - * - * This corresponds to the "deleting=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol supports deleting - */ - static bool supportsDeleting( const KURL &url ); - - /** - * Returns whether the protocol can create links between files/objects. - * - * This corresponds to the "linking=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol supports linking - */ - static bool supportsLinking( const KURL &url ); - - /** - * Returns whether the protocol can move files/objects between different - * locations. - * - * This corresponds to the "moving=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol supports moving - */ - static bool supportsMoving( const KURL &url ); - - /** - * Returns whether the protocol can copy files/objects directly from the - * filesystem itself. If not, the application will read files from the - * filesystem using the file-protocol and pass the data on to the destination - * protocol. - * - * This corresponds to the "copyFromFile=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol can copy files from the local file system - */ - static bool canCopyFromFile( const KURL &url ); - - /** - * Returns whether the protocol can copy files/objects directly to the - * filesystem itself. If not, the application will receive the data from - * the source protocol and store it in the filesystem using the - * file-protocol. - * - * This corresponds to the "copyToFile=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol can copy files to the local file system - */ - static bool canCopyToFile( const KURL &url ); - - /** - * Returns whether the protocol can rename (i.e. move fast) files/objects - * directly from the filesystem itself. If not, the application will read - * files from the filesystem using the file-protocol and pass the data on - * to the destination protocol. - * - * This corresponds to the "renameFromFile=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol can rename/move files from the local file system - * @since 3.4 - */ - static bool canRenameFromFile( const KURL &url ); - - /** - * Returns whether the protocol can rename (i.e. move fast) files/objects - * directly to the filesystem itself. If not, the application will receive - * the data from the source protocol and store it in the filesystem using the - * file-protocol. - * - * This corresponds to the "renameToFile=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol can rename files to the local file system - * @since 3.4 - */ - static bool canRenameToFile( const KURL &url ); - - /** - * Returns whether the protocol can recursively delete directories by itself. - * If not (the usual case) then KIO will list the directory and delete files - * and empty directories one by one. - * - * This corresponds to the "deleteRecursive=" field in the protocol description file. - * Valid values for this field are "true" or "false" (default). - * - * @param url the url to check - * @return true if the protocol can delete non-empty directories by itself. - * @since 3.4 - */ - static bool canDeleteRecursive( const KURL &url ); - - typedef enum { Name, FromURL } FileNameUsedForCopying; - - /** - * This setting defines the strategy to use for generating a filename, when - * copying a file or directory to another directory. By default the destination - * filename is made out of the filename in the source URL. However if the - * ioslave displays names that are different from the filename of the URL - * (e.g. kio_fonts shows Arial for arial.ttf, or kio_trash shows foo.txt and - * uses some internal URL), using Name means that the display name (UDS_NAME) - * will be used to as the filename in the destination directory. - * - * This corresponds to the "fileNameUsedForCopying=" field in the protocol description file. - * Valid values for this field are "Name" or "FromURL" (default). - * - * @param url the url to check - * @return how to generate the filename in the destination directory when copying/moving - * @since 3.4 - */ - static FileNameUsedForCopying fileNameUsedForCopying( const KURL &url ); - - /** - * Returns default mimetype for this URL based on the protocol. - * - * This corresponds to the "defaultMimetype=" field in the protocol description file. - * - * @param url the url to check - * @return the default mime type of the protocol, or null if unknown - */ - static TQString defaultMimetype( const KURL& url ); - - /** - * Returns the name of the icon, associated with the specified protocol. - * - * This corresponds to the "Icon=" field in the protocol description file. - * - * @param protocol the protocol to check - * @return the icon of the protocol, or null if unknown - */ - static TQString icon( const TQString& protocol ); - - /** - * Returns the name of the config file associated with the - * specified protocol. This is useful if two similar protocols - * need to share a single config file, e.g. http and https. - * - * This corresponds to the "config=" field in the protocol description file. - * The default is the protocol name, see name() - * - * @param protocol the protocol to check - * @return the config file, or null if unknown - */ - static TQString config( const TQString& protocol ); - - /** - * Returns the soft limit on the number of slaves for this protocol. - * This limits the number of slaves used for a single operation, note - * that multiple operations may result in a number of instances that - * exceeds this soft limit. - * - * This corresponds to the "maxInstances=" field in the protocol description file. - * The default is 1. - * - * @param protocol the protocol to check - * @return the maximum number of slaves, or 1 if unknown - */ - static int maxSlaves( const TQString& protocol ); - - /** - * Returns whether mimetypes can be determined based on extension for this - * protocol. For some protocols, e.g. http, the filename extension in the URL - * can not be trusted to truly reflect the file type. - * - * This corresponds to the "determineMimetypeFromExtension=" field in the protocol description file. - * Valid values for this field are "true" (default) or "false". - * - * @param protocol the protocol to check - * @return true if the mime types can be determined by extension - */ - static bool determineMimetypeFromExtension( const TQString &protocol ); - - /** - * Returns the documentation path for the specified protocol. - * - * This corresponds to the "DocPath=" field in the protocol description file. - * - * @param protocol the protocol to check - * @return the docpath of the protocol, or null if unknown - * @since 3.2 - */ - static TQString docPath( const TQString& protocol ); - - /** - * Returns the protocol class for the specified protocol. - * - * This corresponds to the "Class=" field in the protocol description file. - * - * The following classes are defined: - * @li ":internet" for common internet protocols - * @li ":local" for protocols that access local resources - * - * Protocol classes always start with a ':' so that they can not be confused with - * the protocols themselves. - * - * @param protocol the protocol to check - * @return the class of the protocol, or null if unknown - * @since 3.2 - */ - static TQString protocolClass( const TQString& protocol ); - - /** - * Returns whether file previews should be shown for the specified protocol. - * - * This corresponds to the "ShowPreviews=" field in the protocol description file. - * - * By default previews are shown if protocolClass is :local. - * - * @param protocol the protocol to check - * @return true if previews should be shown by default, false otherwise - * @since 3.2 - */ - static bool showFilePreview( const TQString& protocol ); - - /** - * Returns the suggested URI parsing mode for the KURL parser. - * - * This corresponds to the "URIMode=" field in the protocol description file. - * - * The following parsing modes are defined: - * @li "url" for a standards compliant URL - * @li "rawuri" for a non-conformant URI for which URL parsing would be meaningless - * @li "mailto" for a mailto style URI (the path part contains only an email address) - * - * @param protocol the protocol to check - * @return the suggested parsing mode, or KURL::Auto if unspecified - * - * @since 3.2 - */ - static KURL::URIMode uriParseMode( const TQString& protocol ); - - /** - * Returns the list of capabilities provided by the kioslave implementing - * this protocol. - * - * This corresponds to the "Capabilities=" field in the protocol description file. - * - * The capability names are not defined globally, they are up to each - * slave implementation. For example when adding support for a new - * special command for mounting, one would add the string "Mount" to the - * capabilities list, and applications could check for that string - * before sending a special() command that would otherwise do nothing - * on older kioslave implementations. - * - * @param protocol the protocol to check - * @return the list of capabilities. - * - * @since 3.3 - */ - static TQStringList capabilities( const TQString& protocol ); - - /** - * Returns the name of the protocol through which the request - * will be routed if proxy support is enabled. - * - * A good example of this is the ftp protocol for which proxy - * support is commonly handled by the http protocol. - * - * This corresponds to the "ProxiedBy=" in the protocol description file. - * - * @since 3.3 - */ - static TQString proxiedBy( const TQString& protocol ); - -public: - // Internal functions: - /** - * @internal construct a KProtocolInfo from a stream - */ - KProtocolInfo( TQDataStream& _str, int offset); - - virtual ~KProtocolInfo(); - - /** - * @internal - * Load the protocol info from a stream. - */ - virtual void load(TQDataStream& ); - - /** - * @internal - * Save the protocol info to a stream. - */ - virtual void save(TQDataStream& ); - - ////////////////////////// DEPRECATED ///////////////////////// - // The following methods are deprecated: - - /// @deprecated - static Type inputType( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static Type outputType( const TQString& protocol ) KDE_DEPRECATED; - /** - * @deprecated - * Returns the list of fields this protocol returns when listing - * The current possibilities are - * Name, Type, Size, Date, AccessDate, Access, Owner, Group, Link, URL, MimeType - */ - static TQStringList listing( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static bool isSourceProtocol( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static bool supportsListing( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static bool supportsReading( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static bool supportsWriting( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static bool supportsMakeDir( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static bool supportsDeleting( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static bool supportsLinking( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static bool supportsMoving( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static bool canCopyFromFile( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static bool canCopyToFile( const TQString& protocol ) KDE_DEPRECATED; - /// @deprecated - static TQString defaultMimetype( const TQString& protocol) KDE_DEPRECATED; - //////////////////////// END DEPRECATED /////////////////////// - -protected: - TQString m_name; - TQString m_exec; - Type m_inputType; - Type m_outputType; - TQStringList m_listing; - bool m_isSourceProtocol; - bool m_isHelperProtocol; - bool m_supportsListing; - bool m_supportsReading; - bool m_supportsWriting; - bool m_supportsMakeDir; - bool m_supportsDeleting; - bool m_supportsLinking; - bool m_supportsMoving; - TQString m_defaultMimetype; - bool m_determineMimetypeFromExtension; - TQString m_icon; - bool m_canCopyFromFile; - bool m_canCopyToFile; - TQString m_config; - int m_maxSlaves; - - bool canRenameFromFile() const; // for kprotocolinfo_tdecore - bool canRenameToFile() const; // for kprotocolinfo_tdecore - bool canDeleteRecursive() const; // for kprotocolinfo_tdecore - FileNameUsedForCopying fileNameUsedForCopying() const; // for kprotocolinfo_tdecore - static KProtocolInfo* findProtocol(const KURL &url); // for kprotocolinfo_tdecore - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KProtocolInfoPrivate; - KProtocolInfoPrivate* d; -}; - -TDEIO_EXPORT TQDataStream& operator>>( TQDataStream& s, KProtocolInfo::ExtraField& field ); -TDEIO_EXPORT TQDataStream& operator<<( TQDataStream& s, const KProtocolInfo::ExtraField& field ); - -#endif diff --git a/kio/kio/kprotocolmanager.cpp b/kio/kio/kprotocolmanager.cpp deleted file mode 100644 index a4f8169f5..000000000 --- a/kio/kio/kprotocolmanager.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1999 Torben Weis <weis@kde.org> - Copyright (C) 2000- Waldo Bastain <bastain@kde.org> - Copyright (C) 2000- Dawit Alemayehu <adawit@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <string.h> -#include <sys/utsname.h> - -#include <dcopref.h> -#include <kdebug.h> -#include <kglobal.h> -#include <klocale.h> -#include <kconfig.h> -#include <kstandarddirs.h> -#include <klibloader.h> -#include <kstringhandler.h> -#include <kstaticdeleter.h> -#include <kio/slaveconfig.h> -#include <kio/ioslave_defaults.h> -#include <kio/http_slave_defaults.h> - -#include "kprotocolmanager.h" - -class -KProtocolManagerPrivate -{ -public: - KProtocolManagerPrivate(); - - ~KProtocolManagerPrivate(); - - TDEConfig *config; - TDEConfig *http_config; - bool init_busy; - KURL url; - TQString protocol; - TQString proxy; - TQString modifiers; - TQString useragent; -}; - -static KProtocolManagerPrivate* d = 0; -static KStaticDeleter<KProtocolManagerPrivate> kpmpksd; - -KProtocolManagerPrivate::KProtocolManagerPrivate() - :config(0), http_config(0), init_busy(false) -{ - kpmpksd.setObject(d, this); -} - -KProtocolManagerPrivate::~KProtocolManagerPrivate() -{ - delete config; - delete http_config; -} - - -// DEFAULT USERAGENT STRING -#define CFG_DEFAULT_UAGENT(X) \ -TQString("Mozilla/5.0 (compatible; Konqueror/%1.%2%3) KHTML/%4.%5.%6 (like Gecko)") \ - .arg(TDE_VERSION_MAJOR).arg(TDE_VERSION_MINOR).arg(X).arg(TDE_VERSION_MAJOR).arg(TDE_VERSION_MINOR).arg(TDE_VERSION_RELEASE) - -void KProtocolManager::reparseConfiguration() -{ - kpmpksd.destructObject(); - - // Force the slave config to re-read its config... - TDEIO::SlaveConfig::self()->reset (); -} - -TDEConfig *KProtocolManager::config() -{ - if (!d) - d = new KProtocolManagerPrivate; - - if (!d->config) - { - d->config = new TDEConfig("kioslaverc", true, false); - } - return d->config; -} - -TDEConfig *KProtocolManager::http_config() -{ - if (!d) - d = new KProtocolManagerPrivate; - - if (!d->http_config) - { - d->http_config = new TDEConfig("kio_httprc", false, false); - } - return d->http_config; -} - -/*=============================== TIMEOUT SETTINGS ==========================*/ - -int KProtocolManager::readTimeout() -{ - TDEConfig *cfg = config(); - cfg->setGroup( TQString::null ); - int val = cfg->readNumEntry( "ReadTimeout", DEFAULT_READ_TIMEOUT ); - return QMAX(MIN_TIMEOUT_VALUE, val); -} - -int KProtocolManager::connectTimeout() -{ - TDEConfig *cfg = config(); - cfg->setGroup( TQString::null ); - int val = cfg->readNumEntry( "ConnectTimeout", DEFAULT_CONNECT_TIMEOUT ); - return QMAX(MIN_TIMEOUT_VALUE, val); -} - -int KProtocolManager::proxyConnectTimeout() -{ - TDEConfig *cfg = config(); - cfg->setGroup( TQString::null ); - int val = cfg->readNumEntry( "ProxyConnectTimeout", DEFAULT_PROXY_CONNECT_TIMEOUT ); - return QMAX(MIN_TIMEOUT_VALUE, val); -} - -int KProtocolManager::responseTimeout() -{ - TDEConfig *cfg = config(); - cfg->setGroup( TQString::null ); - int val = cfg->readNumEntry( "ResponseTimeout", DEFAULT_RESPONSE_TIMEOUT ); - return QMAX(MIN_TIMEOUT_VALUE, val); -} - -/*========================== PROXY SETTINGS =================================*/ - -bool KProtocolManager::useProxy() -{ - return proxyType() != NoProxy; -} - -bool KProtocolManager::useReverseProxy() -{ - TDEConfig *cfg = config(); - cfg->setGroup( "Proxy Settings" ); - return cfg->readBoolEntry("ReversedException", false); -} - -KProtocolManager::ProxyType KProtocolManager::proxyType() -{ - TDEConfig *cfg = config(); - cfg->setGroup( "Proxy Settings" ); - return static_cast<ProxyType>(cfg->readNumEntry( "ProxyType" )); -} - -KProtocolManager::ProxyAuthMode KProtocolManager::proxyAuthMode() -{ - TDEConfig *cfg = config(); - cfg->setGroup( "Proxy Settings" ); - return static_cast<ProxyAuthMode>(cfg->readNumEntry( "AuthMode" )); -} - -/*========================== CACHING =====================================*/ - -bool KProtocolManager::useCache() -{ - TDEConfig *cfg = http_config(); - return cfg->readBoolEntry( "UseCache", true ); -} - -TDEIO::CacheControl KProtocolManager::cacheControl() -{ - TDEConfig *cfg = http_config(); - TQString tmp = cfg->readEntry("cache"); - if (tmp.isEmpty()) - return DEFAULT_CACHE_CONTROL; - return TDEIO::parseCacheControl(tmp); -} - -TQString KProtocolManager::cacheDir() -{ - TDEConfig *cfg = http_config(); - return cfg->readPathEntry("CacheDir", TDEGlobal::dirs()->saveLocation("cache","http")); -} - -int KProtocolManager::maxCacheAge() -{ - TDEConfig *cfg = http_config(); - return cfg->readNumEntry( "MaxCacheAge", DEFAULT_MAX_CACHE_AGE ); // 14 days -} - -int KProtocolManager::maxCacheSize() -{ - TDEConfig *cfg = http_config(); - return cfg->readNumEntry( "MaxCacheSize", DEFAULT_MAX_CACHE_SIZE ); // 5 MB -} - -TQString KProtocolManager::noProxyForRaw() -{ - TDEConfig *cfg = config(); - cfg->setGroup( "Proxy Settings" ); - - return cfg->readEntry( "NoProxyFor" ); -} - -TQString KProtocolManager::noProxyFor() -{ - TQString noProxy = noProxyForRaw(); - if (proxyType() == EnvVarProxy) - noProxy = TQString::fromLocal8Bit(getenv(noProxy.local8Bit())); - - return noProxy; -} - -TQString KProtocolManager::proxyFor( const TQString& protocol ) -{ - TQString scheme = protocol.lower(); - - if (scheme == "webdav") - scheme = "http"; - else if (scheme == "webdavs") - scheme = "https"; - - TDEConfig *cfg = config(); - cfg->setGroup( "Proxy Settings" ); - return cfg->readEntry( scheme + "Proxy" ); -} - -TQString KProtocolManager::proxyForURL( const KURL &url ) -{ - TQString proxy; - ProxyType pt = proxyType(); - - switch (pt) - { - case PACProxy: - case WPADProxy: - if (!url.host().isEmpty()) - { - KURL u (url); - TQString p = u.protocol().lower(); - - // webdav is a KDE specific protocol. Look up proxy - // information using HTTP instead... - if ( p == "webdav" ) - { - p = "http"; - u.setProtocol( p ); - } - else if ( p == "webdavs" ) - { - p = "https"; - u.setProtocol( p ); - } - - if ( p.startsWith("http") || p == "ftp" || p == "gopher" ) - DCOPRef( "kded", "proxyscout" ).call( "proxyForURL", u ).get( proxy ); - } - break; - case EnvVarProxy: - proxy = TQString(TQString::fromLocal8Bit(getenv(proxyFor(url.protocol()).local8Bit()))).stripWhiteSpace(); - break; - case ManualProxy: - proxy = proxyFor( url.protocol() ); - break; - case NoProxy: - default: - break; - } - - return (proxy.isEmpty() ? TQString::fromLatin1("DIRECT") : proxy); -} - -void KProtocolManager::badProxy( const TQString &proxy ) -{ - DCOPRef( "kded", "proxyscout" ).send( "blackListProxy", proxy ); -} - -/* - Domain suffix match. E.g. return true if host is "cuzco.inka.de" and - nplist is "inka.de,hadiko.de" or if host is "localhost" and nplist is - "localhost". -*/ -static bool revmatch(const char *host, const char *nplist) -{ - if (host == 0) - return false; - - const char *hptr = host + strlen( host ) - 1; - const char *nptr = nplist + strlen( nplist ) - 1; - const char *shptr = hptr; - - while ( nptr >= nplist ) - { - if ( *hptr != *nptr ) - { - hptr = shptr; - - // Try to find another domain or host in the list - while(--nptr>=nplist && *nptr!=',' && *nptr!=' ') ; - - // Strip out multiple spaces and commas - while(--nptr>=nplist && (*nptr==',' || *nptr==' ')) ; - } - else - { - if ( nptr==nplist || nptr[-1]==',' || nptr[-1]==' ') - return true; - if ( hptr == host ) // e.g. revmatch("bugs.kde.org","mybugs.kde.org") - return false; - - hptr--; - nptr--; - } - } - - return false; -} - -TQString KProtocolManager::slaveProtocol(const KURL &url, TQString &proxy) -{ - if (url.hasSubURL()) // We don't want the suburl's protocol - { - KURL::List list = KURL::split(url); - KURL::List::Iterator it = list.fromLast(); - return slaveProtocol(*it, proxy); - } - - if (!d) - d = new KProtocolManagerPrivate; - - if (d->url == url) - { - proxy = d->proxy; - return d->protocol; - } - - if (useProxy()) - { - proxy = proxyForURL(url); - if ((proxy != "DIRECT") && (!proxy.isEmpty())) - { - bool isRevMatch = false; - KProtocolManager::ProxyType type = proxyType(); - bool useRevProxy = ((type == ManualProxy) && useReverseProxy()); - - TQString noProxy; - // Check no proxy information iff the proxy type is either - // ManualProxy or EnvVarProxy - if ( (type == ManualProxy) || (type == EnvVarProxy) ) - noProxy = noProxyFor(); - - if (!noProxy.isEmpty()) - { - TQString qhost = url.host().lower(); - const char *host = qhost.latin1(); - TQString qno_proxy = noProxy.stripWhiteSpace().lower(); - const char *no_proxy = qno_proxy.latin1(); - isRevMatch = revmatch(host, no_proxy); - - // If no match is found and the request url has a port - // number, try the combination of "host:port". This allows - // users to enter host:port in the No-proxy-For list. - if (!isRevMatch && url.port() > 0) - { - qhost += ':' + TQString::number (url.port()); - host = qhost.latin1(); - isRevMatch = revmatch (host, no_proxy); - } - - // If the hostname does not contain a dot, check if - // <local> is part of noProxy. - if (!isRevMatch && host && (strchr(host, '.') == NULL)) - isRevMatch = revmatch("<local>", no_proxy); - } - - if ( (!useRevProxy && !isRevMatch) || (useRevProxy && isRevMatch) ) - { - d->url = proxy; - if ( d->url.isValid() ) - { - // The idea behind slave protocols is not applicable to http - // and webdav protocols. - TQString protocol = url.protocol().lower(); - if (protocol.startsWith("http") || protocol.startsWith("webdav")) - d->protocol = protocol; - else - { - d->protocol = d->url.protocol(); - kdDebug () << "slaveProtocol: " << d->protocol << endl; - } - - d->url = url; - d->proxy = proxy; - return d->protocol; - } - } - } - } - - d->url = url; - d->proxy = proxy = TQString::null; - d->protocol = url.protocol(); - return d->protocol; -} - -/*================================= USER-AGENT SETTINGS =====================*/ - -TQString KProtocolManager::userAgentForHost( const TQString& hostname ) -{ - TQString sendUserAgent = TDEIO::SlaveConfig::self()->configData("http", hostname.lower(), "SendUserAgent").lower(); - if (sendUserAgent == "false") - return TQString::null; - - TQString useragent = TDEIO::SlaveConfig::self()->configData("http", hostname.lower(), "UserAgent"); - - // Return the default user-agent if none is specified - // for the requested host. - if (useragent.isEmpty()) - return defaultUserAgent(); - - return useragent; -} - -TQString KProtocolManager::defaultUserAgent( ) -{ - TQString modifiers = TDEIO::SlaveConfig::self()->configData("http", TQString::null, "UserAgentKeys"); - return defaultUserAgent(modifiers); -} - -TQString KProtocolManager::defaultUserAgent( const TQString &_modifiers ) -{ - if (!d) - d = new KProtocolManagerPrivate; - - TQString modifiers = _modifiers.lower(); - if (modifiers.isEmpty()) - modifiers = DEFAULT_USER_AGENT_KEYS; - - if (d->modifiers == modifiers) - return d->useragent; - - TQString supp; - struct utsname nam; - if( uname(&nam) >= 0 ) - { - if( modifiers.contains('o') ) - { - supp += TQString("; %1").arg(nam.sysname); - if ( modifiers.contains('v') ) - supp += TQString(" %1").arg(nam.release); - } - if( modifiers.contains('p') ) - { - // TODO: determine this value instead of hardcoding it... - supp += TQString::fromLatin1("; X11"); - } - if( modifiers.contains('m') ) - { - supp += TQString("; %1").arg(nam.machine); - } - if( modifiers.contains('l') ) - { - TQStringList languageList = TDEGlobal::locale()->languageList(); - TQStringList::Iterator it = languageList.find( TQString::fromLatin1("C") ); - if( it != languageList.end() ) - { - if( languageList.contains( TQString::fromLatin1("en") ) > 0 ) - languageList.remove( it ); - else - (*it) = TQString::fromLatin1("en"); - } - if( languageList.count() ) - supp += TQString("; %1").arg(languageList.join(", ")); - } - } - d->modifiers = modifiers; - d->useragent = CFG_DEFAULT_UAGENT(supp); - return d->useragent; -} - -/*==================================== OTHERS ===============================*/ - -bool KProtocolManager::markPartial() -{ - TDEConfig *cfg = config(); - cfg->setGroup( TQString::null ); - return cfg->readBoolEntry( "MarkPartial", true ); -} - -int KProtocolManager::minimumKeepSize() -{ - TDEConfig *cfg = config(); - cfg->setGroup( TQString::null ); - return cfg->readNumEntry( "MinimumKeepSize", - DEFAULT_MINIMUM_KEEP_SIZE ); // 5000 byte -} - -bool KProtocolManager::autoResume() -{ - TDEConfig *cfg = config(); - cfg->setGroup( TQString::null ); - return cfg->readBoolEntry( "AutoResume", false ); -} - -bool KProtocolManager::persistentConnections() -{ - TDEConfig *cfg = config(); - cfg->setGroup( TQString::null ); - return cfg->readBoolEntry( "PersistentConnections", true ); -} - -bool KProtocolManager::persistentProxyConnection() -{ - TDEConfig *cfg = config(); - cfg->setGroup( TQString::null ); - return cfg->readBoolEntry( "PersistentProxyConnection", false ); -} - -TQString KProtocolManager::proxyConfigScript() -{ - TDEConfig *cfg = config(); - cfg->setGroup( "Proxy Settings" ); - return cfg->readEntry( "Proxy Config Script" ); -} diff --git a/kio/kio/kprotocolmanager.h b/kio/kio/kprotocolmanager.h deleted file mode 100644 index f7e27164b..000000000 --- a/kio/kio/kprotocolmanager.h +++ /dev/null @@ -1,389 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1999 Torben Weis <weis@kde.org> - Copyright (C) 2000- Waldo Bastain <bastain@kde.org> - Copyright (C) 2000- Dawit Alemayehu <adawit@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __kprotocolmanager_h__ -#define __kprotocolmanager_h__ - -#include <tqstringlist.h> - -#include <kapplication.h> -#include <kio/global.h> - -/** @deprecated Use KProtocolManager::defaultUserAgent() instead. */ -#define DEFAULT_USERAGENT_STRING "" - -class TDEConfig; - -/** - * Provides information about I/O (Internet, etc.) settings chosen/set - * by the end user. - * - * KProtocolManager has a heap of static functions that allows only read - * access to KDE's IO related settings. These include proxy, cache, file - * transfer resumption, timeout and user-agent related settings. - * - * The information provided by this class is generic enough to be applicable - * to any application that makes use of KDE's IO sub-system. Note that this - * mean the proxy, timeout etc. settings are saved in a separate user-specific - * config file and not in the config file of the application. - * - * Original author: - * @author Torben Weis <weis@kde.org> - * - * Revised by: - * @author Waldo Bastain <bastain@kde.org> - * @author Dawit Alemayehu <adawit@kde.org> - * @see KPAC - */ -class TDEIO_EXPORT KProtocolManager -{ -public: - - -/*=========================== USER-AGENT SETTINGS ===========================*/ - - - /** - * Returns the default user-agent string. - * - * @return the default user-agent string - */ - static TQString defaultUserAgent(); - - /** - * Returns the default user-agent value. - * - * @param keys can be any of the following: - * @li 'o' Show OS - * @li 'v' Show OS Version - * @li 'p' Show platform - * @li 'm' Show machine architecture - * @li 'l' Show language - * @return the default user-agent value with the given @p keys - */ - static TQString defaultUserAgent(const TQString &keys); - - /** - * Returns the userAgent string configured for the - * specified host. - * - * If hostname is not found or is empty (i.e. "" or - * TQString::null) this function will return the default - * user agent. - * - * @param hostname name of the host - * @return specified userAgent string - */ - static TQString userAgentForHost( const TQString &hostname ); - - -/*=========================== TIMEOUT CONFIG ================================*/ - - - /** - * Returns the preferred timeout value for reading from - * remote connections in seconds. - * - * @return timeout value for remote connection in secs. - */ - static int readTimeout(); - - /** - * Returns the preferred timeout value for remote connections - * in seconds. - * - * @return timeout value for remote connection in secs. - */ - static int connectTimeout(); - - /** - * Returns the preferred timeout value for proxy connections - * in seconds. - * - * @return timeout value for proxy connection in secs. - */ - static int proxyConnectTimeout(); - - /** - * Returns the preferred response timeout value for - * remote connecting in seconds. - * - * @return timeout value for remote connection in seconds. - */ - static int responseTimeout(); - - -/*=============================== PROXY CONFIG ==============================*/ - - - /** - * Returns true if the user specified a proxy server to make connections. - * - * @see slaveProtocol, proxyForURL, proxyFor - */ - static bool useProxy(); - - /** - * Returns true if the proxy settings should apply to the list - * returned by @ref noProxyFor. - * - * Normally addresses listed in the noProxyFor list are not routed - * through a proxy server. However, if this function returns true, - * then all addresses listed in the noProxyFor list are to be routed - * through a proxy server where as those that are not should bypass it. - * - * This function as well as @ref noProxyFor only apply when @ref proxyType - * is @p ManualProxy. - * - * @see proxyForURL, proxyFor, slaveProtocol - */ - static bool useReverseProxy(); - - /** - * Types of proxy configuration - * @li NoProxy - No proxy is used - * @li ManualProxy - Proxies are manually configured - * @li PACProxy - A Proxy configuration URL has been given - * @li WPADProxy - A proxy should be automatically discovered - * @li EnvVarProxy - Use the proxy values set through environment variables. - */ - enum ProxyType - { - NoProxy, - ManualProxy, - PACProxy, - WPADProxy, - EnvVarProxy - }; - - /** - * Returns the type of proxy configuration that is used. - * - * @see ProxyType - */ - static ProxyType proxyType(); - - /** - * Proxy authorization modes. - * - * @li Prompt - Ask for authorization as needed - * @li Automatic - Use auto login as defined in .kionetrc files. - * - * NOTE: .kionetrc files have the same format as ftp .netrc files. - * Please note the use of .kionetrc files is highly discouraged since - * password is stored in clear text. For future releases the ability - * to store preset password for proxy servers will probably be supported - * through KWallet integration. - */ - enum ProxyAuthMode - { - Prompt, - Automatic - }; - - /** - * Returns the way proxy authorization should be handled. - * - * @see ProxyAuthMode - */ - static ProxyAuthMode proxyAuthMode(); - - /** - * Returns a comma-separated list of hostnames or partial - * host-names that should bypass any proxy settings. - * - * This function as well as @ref useReverseProxy only apply - * when @ref proxyType is @p ManualProxy. - * - * @see useReverseProxy, proxyFor, proxyForURL, slaveProtocol - */ - static TQString noProxyFor(); - - /** - * Same as above except the environment variable name - * is returned instead of the variable value when - * @ref proxyType is @p EnvVarProxy. - * - * @see noProxyFor - * @since 3.5.x - */ - static TQString noProxyForRaw(); - - /** - * Returns the proxy server address for a given protocol. - * - * NOTE: This function does not take the @ref useReverseProxy() - * settings into account. - * - * @see useReverseProxy, slaveProtocol - * @param protocol the protocol whose proxy info is needed - * @returns the proxy server address if one is available, - * or TQString::null if not available - */ - static TQString proxyFor( const TQString& protocol ); - - /** - * Returns the proxy server address for a given URL. - * - * If @ref proxyType returns Automatic, an external service - * called KPAC (a kded module) is used to determine the proxy - * server. Otherwise, @ref proxyFor is invoked to determine - * whether the URL needs to be routed through a proxy server. - * - * NOTE: This function does not take the @ref useReverseProxy() - * or the @ref noProxyFor() settings into account. - * - * @see useReverseProxy, slaveProtocol, noProxyFor - * @param url the URL whose proxy info is needed - * @returns the proxy server address or the text "DIRECT" - * if no proxying is needed for the given address. - */ - static TQString proxyForURL( const KURL& url ); - - /** - * Marks this proxy as bad (down). It will not be used for the - * next 30 minutes. (The script may supply an alternate proxy) - * @param proxy the proxy to mark as bad (as URL) - */ - static void badProxy( const TQString & proxy ); - - /** - * Returns the URL of the script for automatic proxy configuration. - * @return the proxy configuration script - */ - static TQString proxyConfigScript(); - - -/*========================== CACHE CONFIG ===================================*/ - - - /** - * Returns true/false to indicate whether a cache - * should be used - * - * @return true to use the cache, false otherwisea - */ - static bool useCache(); - - /** - * Returns the maximum age in seconds cached files should be - * kept before they are deleted as necessary. - * - * @return the maximum cache age in seconds - */ - static int maxCacheAge(); - - /** - * Returns the maximum size that can be used for caching. - * - * By default this function returns the DEFAULT_MAX_CACHE_SIZE - * value as defined in http_slave_defaults.h. Not that the - * value returned is in bytes, hence a value of 5120 would mean - * 5 Kb. - * - * @return the maximum cache size in bytes - */ - static int maxCacheSize(); // Maximum cache size in Kb. - - /** - * The directory which contains the cache files. - * @return the directory that contains the cache files - */ - static TQString cacheDir(); - - /** - * Returns the Cache control directive to be used. - * @return the cache control value - */ - static TDEIO::CacheControl cacheControl(); - - -/*============================ DOWNLOAD CONFIG ==============================*/ - - /** - * Returns true if partial downloads should be - * automatically resumed. - * @return true to resume partial downloads - */ - static bool autoResume(); - - /** - * Returns true if partial downloads should be marked - * with a ".part" extension. - * @return true if partial downloads should get an ".part" extension - */ - static bool markPartial(); - - /** - * Returns the minimum file size for keeping aborted - * downloads. - * - * Any data downloaded that does not meet this minimum - * requirement will simply be discarded. The default size - * is 5 KB. - * - * @return the minimum keep size for aborted downloads in bytes - */ - static int minimumKeepSize(); - - - /*============================ NETWORK CONNECTIONS ==========================*/ - /** - * Returns true if proxy connections should be persistent. - * @return true if proxy connections should be persistent - * @since 3.1 - */ - static bool persistentProxyConnection(); - - /** - * Returns true if connections should be persistent - * @return true if the connections should be persistent - */ - static bool persistentConnections(); - -/*=============================== OTHERS ====================================*/ - - - /** - * Force a reload of the general config file of - * io-slaves ( kioslaverc). - */ - static void reparseConfiguration(); - - /** - * Return the protocol to use in order to handle the given @p url - * It's usually the same, except that FTP, when handled by a proxy, - * needs an HTTP ioslave. - * - * When a proxy is to be used, proxy contains the URL for the proxy. - * @param url the url to check - * @param proxy the URL of the proxy to use - * @return the slave protocol (e.g. 'http'), can be null if unknown - */ - static TQString slaveProtocol(const KURL &url, TQString &proxy); - - /** - * @internal - * (Shared with SlaveConfig) - */ - static TDEConfig *config(); -private: - static TDEConfig *http_config(); -}; -#endif diff --git a/kio/kio/kremoteencoding.cpp b/kio/kio/kremoteencoding.cpp deleted file mode 100644 index 632eeb8b2..000000000 --- a/kio/kio/kremoteencoding.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <config.h> - -#include <kdebug.h> -#include <kstringhandler.h> -#include "kremoteencoding.h" - -KRemoteEncoding::KRemoteEncoding(const char *name) - : codec(0L), d(0L) -{ - setEncoding(name); -} - -KRemoteEncoding::~KRemoteEncoding() -{ - // delete d; // not necessary yet -} - -TQString KRemoteEncoding::decode(const TQCString& name) const -{ -#ifdef CHECK_UTF8 - if (codec->mibEnum() == 106 && !KStringHandler::isUtf8(name)) - return TQString::fromLatin1(name); -#endif - - TQString result = codec->toUnicode(name); - if (codec->fromUnicode(result) != name) - // fallback in case of decoding failure - return TQString::fromLatin1(name); - - return result; -} - -TQCString KRemoteEncoding::encode(const TQString& name) const -{ - TQCString result = codec->fromUnicode(name); - if (codec->toUnicode(result) != name) - return name.latin1(); - - return result; -} - -TQCString KRemoteEncoding::encode(const KURL& url) const -{ - return encode(url.path()); -} - -TQCString KRemoteEncoding::directory(const KURL& url, bool ignore_trailing_slash) const -{ - TQString dir = url.directory(true, ignore_trailing_slash); - - return encode(dir); -} - -TQCString KRemoteEncoding::fileName(const KURL& url) const -{ - return encode(url.fileName()); -} - -void KRemoteEncoding::setEncoding(const char *name) -{ - // don't delete codecs - - if (name) - codec = TQTextCodec::codecForName(name); - else - codec = TQTextCodec::codecForMib( 106 ); // fallback to UTF-8 - - if (codec == 0L) - codec = TQTextCodec::codecForMib(1); - - kdDebug() << k_funcinfo << "setting encoding " << codec->name() - << " for name=" << name << endl; -} - -void KRemoteEncoding::virtual_hook(int, void*) -{ -} diff --git a/kio/kio/kremoteencoding.h b/kio/kio/kremoteencoding.h deleted file mode 100644 index 18dfe1fdb..000000000 --- a/kio/kio/kremoteencoding.h +++ /dev/null @@ -1,127 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KREMOTEENCODING_H -#define KREMOTEENCODING_H - -#include <kurl.h> -#include <tqstring.h> -#include <tqcstring.h> -#include <tqtextcodec.h> - -class KRemoteEncodingPrivate; -/** - * Allows encoding and decoding properly remote filenames into Unicode. - * - * Certain protocols do not specify an appropriate encoding for decoding - * their 8-bit data into proper Unicode forms. Therefore, ioslaves should - * use this class in order to convert those forms into QStrings before - * creating the respective TDEIO::UDSEntry. The same is true for decoding - * URLs to its components. - * - * Each TDEIO::SlaveBase has one object of this kind, even if it is not necessary. - * It can be accessed through TDEIO::SlaveBase::remoteEncoding. - * - * @short A class for handling remote filenames - * @author Thiago Macieira <thiago.macieira@kdemail.net> - * @since 3.3 - */ -class TDEIO_EXPORT KRemoteEncoding -{ -public: - /** - * Constructor. - * - * Constructs this object to use the given encoding name. - * If @p name is a null pointer, the standard encoding will be used. - */ - explicit KRemoteEncoding(const char *name = 0L); - - /** - * Destructor - */ - virtual ~KRemoteEncoding(); - - /** - * Converts the given full pathname or filename to Unicode. - * This function is supposed to work for dirnames, filenames - * or a full pathname. - */ - TQString decode(const TQCString& name) const; - - /** - * Converts the given name from Unicode. - * This function is supposed to work for dirnames, filenames - * or a full pathname. - */ - TQCString encode(const TQString& name) const; - - /** - * Converts the given URL into its 8-bit components - */ - TQCString encode(const KURL& url) const; - - /** - * Converts the given URL into 8-bit form and separate the - * dirname from the filename. This is useful for slave functions - * like stat or get. - * - * The dirname is returned with the final slash always stripped - */ - TQCString directory(const KURL& url, bool ignore_trailing_slash = true) const; - - /** - * Converts the given URL into 8-bit form and retrieve the filename. - */ - TQCString fileName(const KURL& url) const; - - /** - * Returns the encoding being used. - */ - inline const char *encoding() const - { return codec->name(); } - - /** - * Returns the MIB for the codec being used. - */ - inline int encodingMib() const - { return codec->mibEnum(); } - - /** - * Sets the encoding being used. - * This function does not change the global configuration. - * - * Pass a null pointer in @p name to revert to the standard - * encoding. - */ - void setEncoding(const char* name); - -protected: - TQTextCodec *codec; - - virtual void virtual_hook(int id, void* data); - -private: - // copy constructor - KRemoteEncoding(const KRemoteEncoding&); - - - KRemoteEncodingPrivate *d; -}; - -#endif diff --git a/kio/kio/krun.cpp b/kio/kio/krun.cpp deleted file mode 100644 index f99f636db..000000000 --- a/kio/kio/krun.cpp +++ /dev/null @@ -1,1574 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Torben Weis <weis@kde.org> - Copyright (C) 2006 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "krun.h" - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <typeinfo> - -#include <tqwidget.h> -#include <tqguardedptr.h> - -#include "kuserprofile.h" -#include "kmimetype.h" -#include "kmimemagic.h" -#include "kio/job.h" -#include "kio/global.h" -#include "kio/scheduler.h" -#include "kio/netaccess.h" -#include "kfile/kopenwith.h" -#include "kfile/krecentdocument.h" - -#include <kdatastream.h> -#include <kmessageboxwrapper.h> -#include <kurl.h> -#include <kapplication.h> -#include <kdebug.h> -#include <klocale.h> -#include <kprotocolinfo.h> -#include <kstandarddirs.h> -#include <kprocess.h> -#include <dcopclient.h> -#include <tqfile.h> -#include <tqfileinfo.h> -#include <tqtextstream.h> -#include <tqdatetime.h> -#include <tqregexp.h> -#include <kdesktopfile.h> -#include <kstartupinfo.h> -#include <kmacroexpander.h> -#include <kshell.h> -#include <kde_file.h> -#include <kstringhandler.h> - -#ifdef Q_WS_X11 -#include <twin.h> -#endif - -class KRun::KRunPrivate -{ -public: - KRunPrivate() { m_showingError = false; } - - bool m_showingError; - bool m_runExecutables; - - TQString m_preferredService; - TQString m_externalBrowser; - TQString m_localPath; - TQString m_suggestedFileName; - TQGuardedPtr <TQWidget> m_window; - TQCString m_asn; -}; - -pid_t KRun::runURL( const KURL& u, const TQString& _mimetype ) -{ - return runURL( u, _mimetype, false, true, TQString::null ); -} - -pid_t KRun::runURL( const KURL& u, const TQString& _mimetype, bool tempFile ) -{ - return runURL( u, _mimetype, tempFile, true, TQString::null ); -} - -pid_t KRun::runURL( const KURL& u, const TQString& _mimetype, bool tempFile, bool runExecutables ) -{ - return runURL( u, _mimetype, tempFile, runExecutables, TQString::null ); -} - -bool KRun::isExecutableFile( const KURL& url, const TQString &mimetype ) -{ - if ( !url.isLocalFile() ) - return false; - TQFileInfo file( url.path() ); - if ( file.isExecutable() ) // Got a prospective file to run - { - KMimeType::Ptr mimeType = KMimeType::mimeType( mimetype ); - - if ( mimeType->is("application/x-executable") || mimeType->is("application/x-executable-script") ) - return true; - } - return false; -} - -pid_t KRun::runURL( const KURL& u, const TQString& _mimetype, bool tempFile, bool runExecutables, const TQString& suggestedFileName ) -{ - return runURL( u, _mimetype, NULL, "", tempFile, runExecutables, suggestedFileName ); -} - -// This is called by foundMimeType, since it knows the mimetype of the URL -pid_t KRun::runURL( const KURL& u, const TQString& _mimetype, TQWidget* window, const TQCString& asn, - bool tempFile, bool runExecutables, const TQString& suggestedFileName ) -{ - bool noRun = false; - bool noAuth = false; - if ( _mimetype == "inode/directory-locked" ) - { - KMessageBoxWrapper::error( window, - i18n("<qt>Unable to enter <b>%1</b>.\nYou do not have access rights to this location.</qt>").arg(u.htmlURL()) ); - return 0; - } - else if ( (_mimetype == "application/x-desktop") || - (_mimetype == "media/builtin-mydocuments") || - (_mimetype == "media/builtin-mycomputer") || - (_mimetype == "media/builtin-mynetworkplaces") || - (_mimetype == "media/builtin-printers") || - (_mimetype == "media/builtin-trash") || - (_mimetype == "media/builtin-webbrowser") ) - { - if ( u.isLocalFile() && runExecutables ) - return KDEDesktopMimeType::run( u, true ); - } - else if ( isExecutableFile(u, _mimetype) ) - { - if ( u.isLocalFile() && runExecutables) - { - if (kapp->authorize("shell_access")) - { - TQString path = u.path(); - shellQuote( path ); - return (KRun::runCommand(path, TQString::null, TQString::null, window, asn)); // just execute the url as a command - // ## TODO implement deleting the file if tempFile==true - } - else - { - noAuth = true; - } - } - else if (_mimetype == "application/x-executable") - noRun = true; - } - else if ( isExecutable(_mimetype) ) - { - if (!runExecutables) - noRun = true; - - if (!kapp->authorize("shell_access")) - noAuth = true; - } - - if ( noRun ) - { - KMessageBox::sorry( window, - i18n("<qt>The file <b>%1</b> is an executable program. " - "For safety it will not be started.</qt>").arg(u.htmlURL())); - return 0; - } - if ( noAuth ) - { - KMessageBoxWrapper::error( window, - i18n("<qt>You do not have permission to run <b>%1</b>.</qt>").arg(u.htmlURL()) ); - return 0; - } - - KURL::List lst; - lst.append( u ); - - static const TQString& app_str = TDEGlobal::staticQString("Application"); - - KService::Ptr offer = KServiceTypeProfile::preferredService( _mimetype, app_str ); - - if ( !offer ) - { - // Open-with dialog - // TODO : pass the mimetype as a parameter, to show it (comment field) in the dialog ! - // Hmm, in fact KOpenWithDlg::setServiceType already guesses the mimetype from the first URL of the list... - return displayOpenWithDialog( lst, tempFile, suggestedFileName ); - } - - return KRun::run( *offer, lst, window, asn, tempFile, suggestedFileName ); -} - -bool KRun::displayOpenWithDialog( const KURL::List& lst ) -{ - return displayOpenWithDialog( lst, false, TQString::null ); -} - -bool KRun::displayOpenWithDialog( const KURL::List& lst, bool tempFiles ) -{ - return displayOpenWithDialog( lst, tempFiles, TQString::null ); -} - -bool KRun::displayOpenWithDialog( const KURL::List& lst, bool tempFiles, const TQString& suggestedFileName ) -{ - if (kapp && !kapp->authorizeKAction("openwith")) - { - // TODO: Better message, i18n freeze :-( - KMessageBox::sorry(0L, i18n("You are not authorized to open this file.")); - return false; - } - - KOpenWithDlg l( lst, i18n("Open with:"), TQString::null, 0L ); - if ( l.exec() ) - { - KService::Ptr service = l.service(); - if ( !!service ) - return KRun::run( *service, lst, 0 /*window*/, tempFiles, suggestedFileName ); - - kdDebug(7010) << "No service set, running " << l.text() << endl; - return KRun::run( l.text(), lst, suggestedFileName ); // TODO handle tempFiles - } - return false; -} - -void KRun::shellQuote( TQString &_str ) -{ - // Credits to Walter, says Bernd G. :) - if (_str.isEmpty()) // Don't create an explicit empty parameter - return; - TQChar q('\''); - _str.replace(q, "'\\''").prepend(q).append(q); -} - - -class KRunMX1 : public KMacroExpanderBase { -public: - KRunMX1( const KService &_service ) : - KMacroExpanderBase( '%' ), hasUrls( false ), hasSpec( false ), service( _service ) {} - bool hasUrls:1, hasSpec:1; - -protected: - virtual int expandEscapedMacro( const TQString &str, uint pos, TQStringList &ret ); - -private: - const KService &service; -}; - -int -KRunMX1::expandEscapedMacro( const TQString &str, uint pos, TQStringList &ret ) -{ - uint option = str[pos + 1]; - switch( option ) { - case 'c': - ret << service.name().replace( '%', "%%" ); - break; - case 'k': - ret << service.desktopEntryPath().replace( '%', "%%" ); - break; - case 'i': - ret << "-icon" << service.icon().replace( '%', "%%" ); - break; - case 'm': - ret << "-miniicon" << service.icon().replace( '%', "%%" ); - break; - case 'u': - case 'U': - hasUrls = true; - /* fallthrough */ - case 'f': - case 'F': - case 'n': - case 'N': - case 'd': - case 'D': - case 'v': - hasSpec = true; - /* fallthrough */ - default: - return -2; // subst with same and skip - } - return 2; -} - -class KRunMX2 : public KMacroExpanderBase { -public: - KRunMX2( const KURL::List &_urls ) : - KMacroExpanderBase( '%' ), ignFile( false ), urls( _urls ) {} - bool ignFile:1; - -protected: - virtual int expandEscapedMacro( const TQString &str, uint pos, TQStringList &ret ); - -private: - void subst( int option, const KURL &url, TQStringList &ret ); - - const KURL::List &urls; -}; - -void -KRunMX2::subst( int option, const KURL &url, TQStringList &ret ) -{ - switch( option ) { - case 'u': - ret << url.pathOrURL(); - break; - case 'd': - ret << url.directory(); - break; - case 'f': - ret << url.path(); - break; - case 'n': - ret << url.fileName(); - break; - case 'v': - if (url.isLocalFile() && TQFile::exists( url.path() ) ) - ret << KDesktopFile( url.path(), true ).readEntry( "Dev" ); - break; - } - return; -} - -int -KRunMX2::expandEscapedMacro( const TQString &str, uint pos, TQStringList &ret ) -{ - uint option = str[pos + 1]; - switch( option ) { - case 'f': - case 'u': - case 'n': - case 'd': - case 'v': - if( urls.isEmpty() ) { - if (!ignFile) - kdDebug() << "KRun::processDesktopExec: No URLs supplied to single-URL service " << str << endl; - } else if( urls.count() > 1 ) - kdWarning() << "KRun::processDesktopExec: " << urls.count() << " URLs supplied to single-URL service " << str << endl; - else - subst( option, urls.first(), ret ); - break; - case 'F': - case 'U': - case 'N': - case 'D': - option += 'a' - 'A'; - for( KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it ) - subst( option, *it, ret ); - break; - case '%': - ret = "%"; - break; - default: - return -2; // subst with same and skip - } - return 2; -} - -// BIC: merge methods below -TQStringList KRun::processDesktopExec(const KService &_service, const KURL::List& _urls, bool has_shell) { - return processDesktopExec( _service, _urls, has_shell, false, TQString::null ); -} - -TQStringList KRun::processDesktopExec(const KService &_service, const KURL::List& _urls, bool has_shell /* KDE4: remove */, bool tempFiles) -{ - return processDesktopExec( _service, _urls, has_shell, tempFiles, TQString::null ); -} - -TQStringList KRun::processDesktopExec(const KService &_service, const KURL::List& _urls, bool has_shell /* KDE4: remove */, bool tempFiles, const TQString& suggestedFileName) -{ - TQString exec = _service.exec(); - TQStringList result; - bool appHasTempFileOption; - - KRunMX1 mx1( _service ); - KRunMX2 mx2( _urls ); - - /// compatibility hack -- KDE 4: remove - TQRegExp re("^\\s*(?:/bin/)?sh\\s+-c\\s+(.*)$"); - if (!re.search( exec )) { - exec = TQString(re.cap( 1 )).stripWhiteSpace(); - for (uint pos = 0; pos < exec.length(); ) { - TQChar c = exec.unicode()[pos]; - if (c != '\'' && c != '"') - goto synerr; // what else can we do? after normal parsing the substs would be insecure - int pos2 = exec.find( c, pos + 1 ) - 1; - if (pos2 < 0) - goto synerr; // quoting error - memcpy( (void *)(exec.unicode() + pos), exec.unicode() + pos + 1, (pos2 - pos) * sizeof(TQChar)); - pos = pos2; - exec.remove( pos, 2 ); - } - } - - if( !mx1.expandMacrosShellQuote( exec ) ) - goto synerr; // error in shell syntax - - // FIXME: the current way of invoking kioexec disables term and su use - - // Check if we need "tempexec" (kioexec in fact) - appHasTempFileOption = tempFiles && _service.property("X-TDE-HasTempFileOption").toBool(); - if( tempFiles && !appHasTempFileOption && _urls.size() ) { - result << "kioexec" << "--tempfiles" << exec; - result += _urls.toStringList(); - if (has_shell) - result = KShell::joinArgs( result ); - return result; - } - - // Check if we need kioexec - if( !mx1.hasUrls ) { - for( KURL::List::ConstIterator it = _urls.begin(); it != _urls.end(); ++it ) - if ( !(*it).isLocalFile() && !KProtocolInfo::isHelperProtocol(*it) ) { - // We need to run the app through kioexec - result << "kioexec"; - if ( tempFiles ) - result << "--tempfiles"; - if ( !suggestedFileName.isEmpty() ) { - result << "--suggestedfilename"; - result << suggestedFileName; - } - result << exec; - result += _urls.toStringList(); - if (has_shell) - result = KShell::joinArgs( result ); - return result; - } - } - - if ( appHasTempFileOption ) - exec += " --tempfile"; - - // Did the user forget to append something like '%f'? - // If so, then assume that '%f' is the right choice => the application - // accepts only local files. - if( !mx1.hasSpec ) { - exec += " %f"; - mx2.ignFile = true; - } - - mx2.expandMacrosShellQuote( exec ); // syntax was already checked, so don't check return value - -/* - 1 = need_shell, 2 = terminal, 4 = su, 8 = has_shell - - 0 << split(cmd) - 1 << "sh" << "-c" << cmd - 2 << split(term) << "-e" << split(cmd) - 3 << split(term) << "-e" << "sh" << "-c" << cmd - - 4 << "tdesu" << "-u" << user << "-c" << cmd - 5 << "tdesu" << "-u" << user << "-c" << ("sh -c " + quote(cmd)) - 6 << split(term) << "-e" << "su" << user << "-c" << cmd - 7 << split(term) << "-e" << "su" << user << "-c" << ("sh -c " + quote(cmd)) - - 8 << cmd - 9 << cmd - a << term << "-e" << cmd - b << term << "-e" << ("sh -c " + quote(cmd)) - - c << "tdesu" << "-u" << user << "-c" << quote(cmd) - d << "tdesu" << "-u" << user << "-c" << quote("sh -c " + quote(cmd)) - e << term << "-e" << "su" << user << "-c" << quote(cmd) - f << term << "-e" << "su" << user << "-c" << quote("sh -c " + quote(cmd)) - - "sh -c" is needed in the "su" case, too, as su uses the user's login shell, not sh. - this could be optimized with the -s switch of some su versions (e.g., debian linux). -*/ - - if (_service.terminal()) { - TDEConfigGroupSaver gs(TDEGlobal::config(), "General"); - TQString terminal = TDEGlobal::config()->readPathEntry("TerminalApplication", "konsole"); - if (terminal == "konsole") - terminal += " -caption=%c %i %m"; - terminal += " "; - terminal += _service.terminalOptions(); - if( !mx1.expandMacrosShellQuote( terminal ) ) { - kdWarning() << "KRun: syntax error in command `" << terminal << "', service `" << _service.name() << "'" << endl; - return TQStringList(); - } - mx2.expandMacrosShellQuote( terminal ); - if (has_shell) - result << terminal; - else - result = KShell::splitArgs( terminal ); // assuming that the term spec never needs a shell! - result << "-e"; - } - - int err; - if (_service.substituteUid()) { - if (_service.terminal()) - result << "su"; - else - result << "tdesu" << "-u"; - result << _service.username() << "-c"; - KShell::splitArgs(exec, KShell::AbortOnMeta | KShell::TildeExpand, &err); - if (err == KShell::FoundMeta) { - shellQuote( exec ); - exec.prepend( "/bin/sh -c " ); - } else if (err != KShell::NoError) - goto synerr; - if (has_shell) - shellQuote( exec ); - result << exec; - } else { - if (has_shell) { - if (_service.terminal()) { - KShell::splitArgs(exec, KShell::AbortOnMeta | KShell::TildeExpand, &err); - if (err == KShell::FoundMeta) { - shellQuote( exec ); - exec.prepend( "/bin/sh -c " ); - } else if (err != KShell::NoError) - goto synerr; - } - result << exec; - } else { - result += KShell::splitArgs(exec, KShell::AbortOnMeta | KShell::TildeExpand, &err); - if (err == KShell::FoundMeta) - result << "/bin/sh" << "-c" << exec; - else if (err != KShell::NoError) - goto synerr; - } - } - - return result; - - synerr: - kdWarning() << "KRun: syntax error in command `" << _service.exec() << "', service `" << _service.name() << "'" << endl; - return TQStringList(); -} - -//static -TQString KRun::binaryName( const TQString & execLine, bool removePath ) -{ - // Remove parameters and/or trailing spaces. - TQStringList args = KShell::splitArgs( execLine ); - for (TQStringList::ConstIterator it = args.begin(); it != args.end(); ++it) - if (!(*it).contains('=')) - // Remove path if wanted - return removePath ? (*it).mid(TQString(*it).findRev('/') + 1) : *it; - return TQString(); -} - -static pid_t runCommandInternal( TDEProcess* proc, const KService* service, const TQString& binName, - const TQString &execName, const TQString & iconName, TQWidget* window, TQCString asn ) -{ - if (service && !service->desktopEntryPath().isEmpty() - && !KDesktopFile::isAuthorizedDesktopFile( service->desktopEntryPath() )) - { - kdWarning() << "No authorization to execute " << service->desktopEntryPath() << endl; - KMessageBox::sorry(window, i18n("You are not authorized to execute this file.")); - return 0; - } - TQString bin = KRun::binaryName( binName, true ); -#ifdef Q_WS_X11 // Startup notification doesn't work with QT/E, service isn't needed without Startup notification - bool silent; - TQCString wmclass; - KStartupInfoId id; - bool startup_notify = ( asn != "0" && KRun::checkStartupNotify( binName, service, &silent, &wmclass )); - if( startup_notify ) - { - id.initId( asn ); - id.setupStartupEnv(); - KStartupInfoData data; - data.setHostname(); - data.setBin( bin ); - if( !execName.isEmpty()) - data.setName( execName ); - else if( service && !service->name().isEmpty()) - data.setName( service->name()); - data.setDescription( i18n( "Launching %1" ).arg( data.name())); - if( !iconName.isEmpty()) - data.setIcon( iconName ); - else if( service && !service->icon().isEmpty()) - data.setIcon( service->icon()); - if( !wmclass.isEmpty()) - data.setWMClass( wmclass ); - if( silent ) - data.setSilent( KStartupInfoData::Yes ); - data.setDesktop( KWin::currentDesktop()); - if( window ) - data.setLaunchedBy( window->winId()); - KStartupInfo::sendStartup( id, data ); - } - pid_t pid = TDEProcessRunner::run( proc, binName, id ); - if( startup_notify && pid ) - { - KStartupInfoData data; - data.addPid( pid ); - KStartupInfo::sendChange( id, data ); - KStartupInfo::resetStartupEnv(); - } - return pid; -#else - Q_UNUSED( execName ); - Q_UNUSED( iconName ); - return TDEProcessRunner::run( proc, bin ); -#endif -} - -// This code is also used in klauncher. -bool KRun::checkStartupNotify( const TQString& /*binName*/, const KService* service, bool* silent_arg, TQCString* wmclass_arg ) -{ - bool silent = false; - TQCString wmclass; - if( service && service->property( "StartupNotify" ).isValid()) - { - silent = !service->property( "StartupNotify" ).toBool(); - wmclass = service->property( "StartupWMClass" ).toString().latin1(); - } - else if( service && service->property( "X-TDE-StartupNotify" ).isValid()) - { - silent = !service->property( "X-TDE-StartupNotify" ).toBool(); - wmclass = service->property( "X-TDE-WMClass" ).toString().latin1(); - } - else // non-compliant app - { - if( service ) - { - if( service->type() == "Application" ) - wmclass = "0"; // doesn't have .desktop entries needed, start as non-compliant - else - return false; // no startup notification at all - } - else - { -#if 0 - // Create startup notification even for apps for which there shouldn't be any, - // just without any visual feedback. This will ensure they'll be positioned on the proper - // virtual desktop, and will get user timestamp from the ASN ID. - wmclass = "0"; - silent = true; -#else // That unfortunately doesn't work, when the launched non-compliant application - // launches another one that is compliant and there is any delay inbetween (bnc:#343359) - return false; -#endif - } - } - if( silent_arg != NULL ) - *silent_arg = silent; - if( wmclass_arg != NULL ) - *wmclass_arg = wmclass; - return true; -} - -static pid_t runTempService( const KService& _service, const KURL::List& _urls, TQWidget* window, - const TQCString& asn, bool tempFiles, const TQString& suggestedFileName ) -{ - if (!_urls.isEmpty()) { - kdDebug(7010) << "runTempService: first url " << _urls.first().url() << endl; - } - - TQStringList args; - if ((_urls.count() > 1) && !_service.allowMultipleFiles()) - { - // We need to launch the application N times. That sucks. - // We ignore the result for application 2 to N. - // For the first file we launch the application in the - // usual way. The reported result is based on this - // application. - KURL::List::ConstIterator it = _urls.begin(); - while(++it != _urls.end()) - { - KURL::List singleUrl; - singleUrl.append(*it); - runTempService( _service, singleUrl, window, "", tempFiles, suggestedFileName ); - } - KURL::List singleUrl; - singleUrl.append(_urls.first()); - args = KRun::processDesktopExec(_service, singleUrl, false, tempFiles, suggestedFileName); - } - else - { - args = KRun::processDesktopExec(_service, _urls, false, tempFiles, suggestedFileName); - } - kdDebug(7010) << "runTempService: TDEProcess args=" << args << endl; - - TDEProcess * proc = new TDEProcess; - *proc << args; - - if (!_service.path().isEmpty()) - proc->setWorkingDirectory(_service.path()); - - return runCommandInternal( proc, &_service, KRun::binaryName( _service.exec(), false ), - _service.name(), _service.icon(), window, asn ); -} - -// WARNING: don't call this from processDesktopExec, since klauncher uses that too... -static KURL::List resolveURLs( const KURL::List& _urls, const KService& _service ) -{ - // Check which protocols the application supports. - // This can be a list of actual protocol names, or just KIO for KDE apps. - TQStringList supportedProtocols = _service.property("X-TDE-Protocols").toStringList(); - KRunMX1 mx1( _service ); - TQString exec = _service.exec(); - if ( mx1.expandMacrosShellQuote( exec ) && !mx1.hasUrls ) { - Q_ASSERT( supportedProtocols.isEmpty() ); // huh? If you support protocols you need %u or %U... - } else { - if ( supportedProtocols.isEmpty() ) - { - // compat mode: assume KIO if not set and it's a KDE app - TQStringList categories = _service.property("Categories").toStringList(); - if (( categories.find("TDE") != categories.end() ) && ( categories.find("KDE") != categories.end() )) - supportedProtocols.append( "KIO" ); - else { // if no KDE app, be a bit over-generic - supportedProtocols.append( "http"); - supportedProtocols.append( "ftp"); - } - } - } - kdDebug(7010) << "supportedProtocols:" << supportedProtocols << endl; - - KURL::List urls( _urls ); - if ( supportedProtocols.find( "KIO" ) == supportedProtocols.end() ) { - for( KURL::List::Iterator it = urls.begin(); it != urls.end(); ++it ) { - const KURL url = *it; - bool supported = url.isLocalFile() || supportedProtocols.find( url.protocol().lower() ) != supportedProtocols.end(); - kdDebug(7010) << "Looking at url=" << url << " supported=" << supported << endl; - if ( !supported && KProtocolInfo::protocolClass(url.protocol()) == ":local" ) - { - // Maybe we can resolve to a local URL? - KURL localURL = TDEIO::NetAccess::mostLocalURL( url, 0 ); - if ( localURL != url ) { - *it = localURL; - kdDebug(7010) << "Changed to " << localURL << endl; - } - } - } - } - return urls; -} - -// BIC merge methods below -pid_t KRun::run( const KService& _service, const KURL::List& _urls ) -{ - return run( _service, _urls, 0, false, TQString::null ); -} - -pid_t KRun::run( const KService& _service, const KURL::List& _urls, bool tempFiles ) -{ - return run( _service, _urls, 0, tempFiles, TQString::null ); -} - -pid_t KRun::run( const KService& _service, const KURL::List& _urls, TQWidget* window, bool tempFiles ) -{ - return run( _service, _urls, window, "", tempFiles, TQString::null ); -} - -pid_t KRun::run( const KService& _service, const KURL::List& _urls, TQWidget* window, const TQCString& asn, bool tempFiles ) -{ - return run( _service, _urls, window, asn, tempFiles, TQString::null ); -} - -pid_t KRun::run( const KService& _service, const KURL::List& _urls, TQWidget* window, bool tempFiles, const TQString& suggestedFileName ) -{ - return run( _service, _urls, window, "", tempFiles, suggestedFileName ); -} - -pid_t KRun::run( const KService& _service, const KURL::List& _urls, TQWidget* window, const TQCString& asn, - bool tempFiles, const TQString& suggestedFileName ) -{ - if (!_service.desktopEntryPath().isEmpty() && - !KDesktopFile::isAuthorizedDesktopFile( _service.desktopEntryPath())) - { - kdWarning() << "No authorization to execute " << _service.desktopEntryPath() << endl; - KMessageBox::sorry(window, i18n("You are not authorized to execute this service.")); - return 0; - } - - if ( !tempFiles ) - { - // Remember we opened those urls, for the "recent documents" menu in kicker - KURL::List::ConstIterator it = _urls.begin(); - for(; it != _urls.end(); ++it) { - //kdDebug(7010) << "KRecentDocument::adding " << (*it).url() << endl; - KRecentDocument::add( *it, _service.desktopEntryName() ); - } - } - - if ( tempFiles || _service.desktopEntryPath().isEmpty() || !suggestedFileName.isEmpty() ) - { - return runTempService(_service, _urls, window, asn, tempFiles, suggestedFileName); - } - - kdDebug(7010) << "KRun::run " << _service.desktopEntryPath() << endl; - - if (!_urls.isEmpty()) { - kdDebug(7010) << "First url " << _urls.first().url() << endl; - } - - // Resolve urls if needed, depending on what the app supports - const KURL::List urls = resolveURLs( _urls, _service ); - - TQString error; - int pid = 0; - - TQCString myasn = asn; - // startServiceByDesktopPath() doesn't take TQWidget*, add it to the startup info now - if( window != NULL ) - { - if( myasn.isEmpty()) - myasn = KStartupInfo::createNewStartupId(); - if( myasn != "0" ) - { - KStartupInfoId id; - id.initId( myasn ); - KStartupInfoData data; - data.setLaunchedBy( window->winId()); - KStartupInfo::sendChange( id, data ); - } - } - - int i = TDEApplication::startServiceByDesktopPath( - _service.desktopEntryPath(), urls.toStringList(), &error, 0L, &pid, myasn - ); - - if (i != 0) - { - kdDebug(7010) << error << endl; - KMessageBox::sorry( window, error ); - return 0; - } - - kdDebug(7010) << "startServiceByDesktopPath worked fine" << endl; - return (pid_t) pid; -} - - -pid_t KRun::run( const TQString& _exec, const KURL::List& _urls, const TQString& _name, - const TQString& _icon, const TQString&, const TQString&) -{ - KService::Ptr service = new KService(_name, _exec, _icon); - - return run(*service, _urls); -} - -pid_t KRun::runCommand( TQString cmd ) -{ - return KRun::runCommand( cmd, TQString::null, TQString::null, NULL, "" ); -} - -pid_t KRun::runCommand( const TQString& cmd, const TQString &execName, const TQString & iconName ) -{ - return KRun::runCommand( cmd, execName, iconName, NULL, "" ); -} - -pid_t KRun::runCommand( const TQString& cmd, const TQString &execName, const TQString & iconName, - TQWidget* window, const TQCString& asn ) -{ - kdDebug(7010) << "runCommand " << cmd << "," << execName << endl; - TDEProcess * proc = new TDEProcess; - proc->setUseShell(true); - *proc << cmd; - KService::Ptr service = KService::serviceByDesktopName( binaryName( execName, true ) ); - TQString bin = binaryName( cmd, false ); - int pos = bin.findRev( '/' ); - if (pos != -1) { - proc->setWorkingDirectory( bin.mid(0, pos) ); - } - return runCommandInternal( proc, service.data(), binaryName( execName, false ), execName, iconName, window, asn ); -} - -KRun::KRun( const KURL& url, mode_t mode, bool isLocalFile, bool showProgressInfo ) - :m_timer(0,"KRun::timer") -{ - init (url, 0, "", mode, isLocalFile, showProgressInfo); -} - -KRun::KRun( const KURL& url, TQWidget* window, mode_t mode, bool isLocalFile, - bool showProgressInfo ) - :m_timer(0,"KRun::timer") -{ - init (url, window, "", mode, isLocalFile, showProgressInfo); -} - -KRun::KRun( const KURL& url, TQWidget* window, const TQCString& asn, mode_t mode, bool isLocalFile, - bool showProgressInfo ) - :m_timer(0,"KRun::timer") -{ - init (url, window, asn, mode, isLocalFile, showProgressInfo); -} - -void KRun::init ( const KURL& url, TQWidget* window, const TQCString& asn, mode_t mode, bool isLocalFile, - bool showProgressInfo ) -{ - m_bFault = false; - m_bAutoDelete = true; - m_bProgressInfo = showProgressInfo; - m_bFinished = false; - m_job = 0L; - m_strURL = url; - m_bScanFile = false; - m_bIsDirectory = false; - m_bIsLocalFile = isLocalFile; - m_mode = mode; - d = new KRunPrivate; - d->m_runExecutables = true; - d->m_window = window; - d->m_asn = asn; - setEnableExternalBrowser(true); - - // Start the timer. This means we will return to the event - // loop and do initialization afterwards. - // Reason: We must complete the constructor before we do anything else. - m_bInit = true; - connect( &m_timer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotTimeout() ) ); - m_timer.start( 0, true ); - kdDebug(7010) << " new KRun " << this << " " << url.prettyURL() << " timer=" << &m_timer << endl; - - kapp->ref(); -} - -void KRun::init() -{ - kdDebug(7010) << "INIT called" << endl; - - bool bypassErrorMessage = false; - - if (m_strURL.url().startsWith("$(")) { - // check for environment variables and make necessary translations - TQString aValue = m_strURL.url(); - int nDollarPos = aValue.find( '$' ); - - while( nDollarPos != -1 && nDollarPos+1 < static_cast<int>(aValue.length())) { - // there is at least one $ - if( (aValue)[nDollarPos+1] == '(' ) { - uint nEndPos = nDollarPos+1; - // the next character is no $ - while ( (nEndPos <= aValue.length()) && (aValue[nEndPos]!=')') ) - nEndPos++; - nEndPos++; - TQString cmd = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); - - TQString result; - FILE *fs = popen(TQFile::encodeName(cmd).data(), "r"); - if (fs) - { - { - TQTextStream ts(fs, IO_ReadOnly); - result = ts.read().stripWhiteSpace(); - } - pclose(fs); - } - aValue.replace( nDollarPos, nEndPos-nDollarPos, result ); - } else if( (aValue)[nDollarPos+1] != '$' ) { - uint nEndPos = nDollarPos+1; - // the next character is no $ - TQString aVarName; - if (aValue[nEndPos]=='{') - { - while ( (nEndPos <= aValue.length()) && (aValue[nEndPos]!='}') ) - nEndPos++; - nEndPos++; - aVarName = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); - } - else - { - while ( nEndPos <= aValue.length() && (aValue[nEndPos].isNumber() - || aValue[nEndPos].isLetter() || aValue[nEndPos]=='_' ) ) - nEndPos++; - aVarName = aValue.mid( nDollarPos+1, nEndPos-nDollarPos-1 ); - } - const char* pEnv = 0; - if (!aVarName.isEmpty()) - pEnv = getenv( aVarName.ascii() ); - if( pEnv ) { - // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!! - // A environment variables may contain values in 8bit - // locale cpecified encoding or in UTF8 encoding. - aValue.replace( nDollarPos, nEndPos-nDollarPos, KStringHandler::from8Bit( pEnv ) ); - } else - aValue.remove( nDollarPos, nEndPos-nDollarPos ); - } else { - // remove one of the dollar signs - aValue.remove( nDollarPos, 1 ); - nDollarPos++; - } - nDollarPos = aValue.find( '$', nDollarPos ); - } - m_strURL = KURL(aValue); - bypassErrorMessage = true; - } - - if ( !m_strURL.isValid() ) - { - if (bypassErrorMessage == false) { - d->m_showingError = true; - KMessageBoxWrapper::error( d->m_window, i18n( "Malformed URL\n%1" ).arg( m_strURL.url() ) ); - d->m_showingError = false; - } - m_bFault = true; - m_bFinished = true; - m_timer.start( 0, true ); - return; - } - if ( !kapp->authorizeURLAction( "open", KURL(), m_strURL)) - { - TQString msg = TDEIO::buildErrorString(TDEIO::ERR_ACCESS_DENIED, m_strURL.prettyURL()); - d->m_showingError = true; - KMessageBoxWrapper::error( d->m_window, msg ); - d->m_showingError = false; - m_bFault = true; - m_bFinished = true; - m_timer.start( 0, true ); - return; - } - - if ( !m_bIsLocalFile && m_strURL.isLocalFile() ) - m_bIsLocalFile = true; - - TQString exec; - if (m_strURL.protocol().startsWith("http")) - { - exec = d->m_externalBrowser; - } - - if ( m_bIsLocalFile ) - { - if ( m_mode == 0 ) - { - KDE_struct_stat buff; - if ( KDE_stat( TQFile::encodeName(m_strURL.path()), &buff ) == -1 ) - { - d->m_showingError = true; - KMessageBoxWrapper::error( d->m_window, i18n( "<qt>Unable to run the command specified. The file or folder <b>%1</b> does not exist.</qt>" ).arg( m_strURL.htmlURL() ) ); - d->m_showingError = false; - m_bFault = true; - m_bFinished = true; - m_timer.start( 0, true ); - return; - } - m_mode = buff.st_mode; - } - - KMimeType::Ptr mime = KMimeType::findByURL( m_strURL, m_mode, m_bIsLocalFile ); - assert( mime != 0L ); - kdDebug(7010) << "MIME TYPE is " << mime->name() << endl; - foundMimeType( mime->name() ); - return; - } - else if ( !exec.isEmpty() || KProtocolInfo::isHelperProtocol( m_strURL ) ) { - kdDebug(7010) << "Helper protocol" << endl; - - bool ok = false; - KURL::List urls; - if (!((m_strURL.protocol().startsWith("http")) && (m_strURL.url() == "http://default.browser"))) - urls.append( m_strURL ); - if (exec.isEmpty()) - { - exec = KProtocolInfo::exec( m_strURL.protocol() ); - if (exec.isEmpty()) - { - foundMimeType(KProtocolInfo::defaultMimetype(m_strURL)); - return; - } - run( exec, urls ); - ok = true; - } - else if (exec.startsWith("!")) - { - exec = exec.mid(1); // Literal command - exec += " %u"; - run( exec, urls ); - ok = true; - } - else - { - KService::Ptr service = KService::serviceByStorageId( exec ); - if (service) - { - run( *service, urls, d->m_window, d->m_asn ); - ok = true; - } - } - - if (ok) - { - m_bFinished = true; - // will emit the error and autodelete this - m_timer.start( 0, true ); - return; - } - } - - if ((m_strURL.protocol().startsWith("http")) && (m_strURL.url() == "http://default.browser")) { - KURL::List urls; - run( "kfmclient openProfile webbrowsing", urls ); - m_bFinished = true; - // will emit the error and autodelete this - m_timer.start( 0, true ); - return; - } - - // Did we already get the information that it is a directory ? - if ( S_ISDIR( m_mode ) ) - { - foundMimeType( "inode/directory" ); - return; - } - - // Let's see whether it is a directory - - if ( !KProtocolInfo::supportsListing( m_strURL ) ) - { - //kdDebug(7010) << "Protocol has no support for listing" << endl; - // No support for listing => it can't be a directory (example: http) - scanFile(); - return; - } - - kdDebug(7010) << "Testing directory (stating)" << endl; - - // It may be a directory or a file, let's stat - TDEIO::StatJob *job = TDEIO::stat( m_strURL, true, 0 /* no details */, m_bProgressInfo ); - job->setWindow (d->m_window); - connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), - this, TQT_SLOT( slotStatResult( TDEIO::Job * ) ) ); - m_job = job; - kdDebug(7010) << " Job " << job << " is about stating " << m_strURL.url() << endl; -} - -KRun::~KRun() -{ - kdDebug(7010) << "KRun::~KRun() " << this << endl; - m_timer.stop(); - killJob(); - kapp->deref(); - kdDebug(7010) << "KRun::~KRun() done " << this << endl; - delete d; -} - -void KRun::scanFile() -{ - kdDebug(7010) << "###### KRun::scanFile " << m_strURL.url() << endl; - // First, let's check for well-known extensions - // Not when there is a query in the URL, in any case. - if ( m_strURL.query().isEmpty() ) - { - KMimeType::Ptr mime = KMimeType::findByURL( m_strURL ); - assert( mime != 0L ); - if ( mime->name() != "application/octet-stream" || m_bIsLocalFile ) - { - kdDebug(7010) << "Scanfile: MIME TYPE is " << mime->name() << endl; - foundMimeType( mime->name() ); - return; - } - } - - // No mimetype found, and the URL is not local (or fast mode not allowed). - // We need to apply the 'KIO' method, i.e. either asking the server or - // getting some data out of the file, to know what mimetype it is. - - if ( !KProtocolInfo::supportsReading( m_strURL ) ) - { - kdError(7010) << "#### NO SUPPORT FOR READING!" << endl; - m_bFault = true; - m_bFinished = true; - m_timer.start( 0, true ); - return; - } - kdDebug(7010) << this << " Scanning file " << m_strURL.url() << endl; - - TDEIO::TransferJob *job = TDEIO::get( m_strURL, false /*reload*/, m_bProgressInfo ); - job->setWindow (d->m_window); - connect(job, TQT_SIGNAL( result(TDEIO::Job *)), - this, TQT_SLOT( slotScanFinished(TDEIO::Job *))); - connect(job, TQT_SIGNAL( mimetype(TDEIO::Job *, const TQString &)), - this, TQT_SLOT( slotScanMimeType(TDEIO::Job *, const TQString &))); - m_job = job; - kdDebug(7010) << " Job " << job << " is about getting from " << m_strURL.url() << endl; -} - -void KRun::slotTimeout() -{ - kdDebug(7010) << this << " slotTimeout called" << endl; - if ( m_bInit ) - { - m_bInit = false; - init(); - return; - } - - if ( m_bFault ) { - emit error(); - } - if ( m_bFinished ) { - emit finished(); - } - else - { - if ( m_bScanFile ) - { - m_bScanFile = false; - scanFile(); - return; - } - else if ( m_bIsDirectory ) - { - m_bIsDirectory = false; - foundMimeType( "inode/directory" ); - return; - } - } - - if ( m_bAutoDelete ) - { - delete this; - return; - } -} - -void KRun::slotStatResult( TDEIO::Job * job ) -{ - m_job = 0L; - if (job->error()) - { - d->m_showingError = true; - kdError(7010) << this << " ERROR " << job->error() << " " << job->errorString() << endl; - job->showErrorDialog(); - //kdDebug(7010) << this << " KRun returning from showErrorDialog, starting timer to delete us" << endl; - d->m_showingError = false; - - m_bFault = true; - m_bFinished = true; - - // will emit the error and autodelete this - m_timer.start( 0, true ); - - } else { - - kdDebug(7010) << "Finished" << endl; - if(!dynamic_cast<TDEIO::StatJob*>(job)) - kdFatal() << "job is a " << typeid(*job).name() << " should be a StatJob" << endl; - - TQString knownMimeType; - TDEIO::UDSEntry entry = ((TDEIO::StatJob*)job)->statResult(); - TDEIO::UDSEntry::ConstIterator it = entry.begin(); - for( ; it != entry.end(); it++ ) { - switch( (*it).m_uds ) { - case TDEIO::UDS_FILE_TYPE: - if ( S_ISDIR( (mode_t)((*it).m_long) ) ) - m_bIsDirectory = true; // it's a dir - else - m_bScanFile = true; // it's a file - break; - case TDEIO::UDS_MIME_TYPE: // mimetype already known? (e.g. print:/manager) - knownMimeType = (*it).m_str; - break; - case TDEIO::UDS_LOCAL_PATH: - d->m_localPath = (*it).m_str; - break; - default: - break; - } - } - if ( !knownMimeType.isEmpty() ) - { - foundMimeType( knownMimeType ); - m_bFinished = true; - } - - // We should have found something - assert ( m_bScanFile || m_bIsDirectory ); - - // Start the timer. Once we get the timer event this - // protocol server is back in the pool and we can reuse it. - // This gives better performance than starting a new slave - m_timer.start( 0, true ); - } -} - -void KRun::slotScanMimeType( TDEIO::Job *, const TQString &mimetype ) -{ - if ( mimetype.isEmpty() ) - kdWarning(7010) << "KRun::slotScanFinished : MimetypeJob didn't find a mimetype! Probably a kioslave bug." << endl; - foundMimeType( mimetype ); - m_job = 0; -} - -void KRun::slotScanFinished( TDEIO::Job *job ) -{ - m_job = 0; - if (job->error()) - { - d->m_showingError = true; - kdError(7010) << this << " ERROR (stat) : " << job->error() << " " << job->errorString() << endl; - job->showErrorDialog(); - //kdDebug(7010) << this << " KRun returning from showErrorDialog, starting timer to delete us" << endl; - d->m_showingError = false; - - m_bFault = true; - m_bFinished = true; - - // will emit the error and autodelete this - m_timer.start( 0, true ); - } -} - -void KRun::foundMimeType( const TQString& type ) -{ - kdDebug(7010) << "Resulting mime type is " << type << endl; - -/* - // Automatically unzip stuff - - // Disabled since the new KIO doesn't have filters yet. - - if ( type == "application/x-gzip" || - type == "application/x-bzip" || - type == "application/x-bzip2" ) - { - KURL::List lst = KURL::split( m_strURL ); - if ( lst.isEmpty() ) - { - TQString tmp = i18n( "Malformed URL" ); - tmp += "\n"; - tmp += m_strURL.url(); - KMessageBoxWrapper::error( 0L, tmp ); - return; - } - - if ( type == "application/x-gzip" ) - lst.prepend( KURL( "gzip:/decompress" ) ); - else if ( type == "application/x-bzip" ) - lst.prepend( KURL( "bzip:/decompress" ) ); - else if ( type == "application/x-bzip2" ) - lst.prepend( KURL( "bzip2:/decompress" ) ); - else if ( type == "application/x-tar" ) - lst.prepend( KURL( "tar:/" ) ); - - // Move the HTML style reference to the leftmost URL - KURL::List::Iterator it = lst.begin(); - ++it; - (*lst.begin()).setRef( (*it).ref() ); - (*it).setRef( TQString::null ); - - // Create the new URL - m_strURL = KURL::join( lst ); - - kdDebug(7010) << "Now trying with " << debugString(m_strURL.url()) << endl; - - killJob(); - - // We don't know if this is a file or a directory. Let's test this first. - // (For instance a tar.gz is a directory contained inside a file) - // It may be a directory or a file, let's stat - TDEIO::StatJob *job = TDEIO::stat( m_strURL, m_bProgressInfo ); - connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), - this, TQT_SLOT( slotStatResult( TDEIO::Job * ) ) ); - m_job = job; - - return; - } -*/ - TDEIO::TransferJob *job = ::tqqt_cast<TDEIO::TransferJob *>( m_job ); - if ( job ) - { - job->putOnHold(); - TDEIO::Scheduler::publishSlaveOnHold(); - m_job = 0; - } - - Q_ASSERT( !m_bFinished ); - - // Suport for preferred service setting, see setPreferredService - if ( !d->m_preferredService.isEmpty() ) { - kdDebug(7010) << "Attempting to open with preferred service: " << d->m_preferredService << endl; - KService::Ptr serv = KService::serviceByDesktopName( d->m_preferredService ); - if ( serv && serv->hasServiceType( type ) ) - { - KURL::List lst; - lst.append( m_strURL ); - m_bFinished = KRun::run( *serv, lst, d->m_window, d->m_asn ); - /// Note: the line above means that if that service failed, we'll - /// go to runURL to maybe find another service, even though a dialog - /// box was displayed. That's good if runURL tries another service, - /// but it's not good if it tries the same one :} - } - } - - // Resolve .desktop files from media:/, remote:/, applications:/ etc. - if ( ((type == "application/x-desktop") || - (type == "media/builtin-mydocuments") || - (type == "media/builtin-mycomputer") || - (type == "media/builtin-mynetworkplaces") || - (type == "media/builtin-printers") || - (type == "media/builtin-trash") || - (type == "media/builtin-webbrowser")) /* or inheriting? */ && (!d->m_localPath.isEmpty()) ) - { - m_strURL = KURL(); - m_strURL.setPath( d->m_localPath ); - } - - if (!m_bFinished && KRun::runURL( m_strURL, type, d->m_window, d->m_asn, false, d->m_runExecutables, d->m_suggestedFileName )){ - m_bFinished = true; - } - else{ - m_bFinished = true; - m_bFault = true; - } - - m_timer.start( 0, true ); -} - -void KRun::killJob() -{ - if ( m_job ) - { - kdDebug(7010) << "KRun::killJob run=" << this << " m_job=" << m_job << endl; - m_job->kill(); - m_job = 0L; - } -} - -void KRun::abort() -{ - kdDebug(7010) << "KRun::abort " << this << " m_showingError=" << d->m_showingError << endl; - killJob(); - // If we're showing an error message box, the rest will be done - // after closing the msgbox -> don't autodelete nor emit signals now. - if ( d->m_showingError ) - return; - m_bFault = true; - m_bFinished = true; - m_bInit = false; - m_bScanFile = false; - - // will emit the error and autodelete this - m_timer.start( 0, true ); -} - -void KRun::setEnableExternalBrowser(bool b) -{ - if (b) - d->m_externalBrowser = TDEConfigGroup(TDEGlobal::config(), "General").readEntry("BrowserApplication"); - else - d->m_externalBrowser = TQString::null; -} - -void KRun::setPreferredService( const TQString& desktopEntryName ) -{ - d->m_preferredService = desktopEntryName; -} - -void KRun::setRunExecutables(bool b) -{ - d->m_runExecutables = b; -} - -void KRun::setSuggestedFileName( const TQString& fileName ) -{ - d->m_suggestedFileName = fileName; -} - -bool KRun::isExecutable( const TQString& serviceType ) -{ - return ( serviceType == "application/x-desktop" || - serviceType == "media/builtin-mydocuments" || - serviceType == "media/builtin-mycomputer" || - serviceType == "media/builtin-mynetworkplaces" || - serviceType == "media/builtin-printers" || - serviceType == "media/builtin-trash" || - serviceType == "media/builtin-webbrowser" || - serviceType == "application/x-executable" || - serviceType == "application/x-msdos-program" || - serviceType == "application/x-shellscript" ); -} - -/****************/ - -pid_t -TDEProcessRunner::run(TDEProcess * p, const TQString & binName) -{ - return (new TDEProcessRunner(p, binName))->pid(); -} - -#ifdef Q_WS_X11 -pid_t -TDEProcessRunner::run(TDEProcess * p, const TQString & binName, const KStartupInfoId& id ) -{ - return (new TDEProcessRunner(p, binName, id))->pid(); -} -#endif - -TDEProcessRunner::TDEProcessRunner(TDEProcess * p, const TQString & _binName ) - : TQObject(), - process_(p), - binName( _binName ) -{ - TQObject::connect( - process_, TQT_SIGNAL(processExited(TDEProcess *)), - this, TQT_SLOT(slotProcessExited(TDEProcess *))); - - process_->start(); - if ( !process_->pid() ) - slotProcessExited( process_ ); -} - -#ifdef Q_WS_X11 -TDEProcessRunner::TDEProcessRunner(TDEProcess * p, const TQString & _binName, const KStartupInfoId& id ) - : TQObject(), - process_(p), - binName( _binName ), - id_( id ) -{ - TQObject::connect( - process_, TQT_SIGNAL(processExited(TDEProcess *)), - this, TQT_SLOT(slotProcessExited(TDEProcess *))); - - process_->start(); - if ( !process_->pid() ) - slotProcessExited( process_ ); -} -#endif - -TDEProcessRunner::~TDEProcessRunner() -{ - delete process_; -} - - pid_t -TDEProcessRunner::pid() const -{ - return process_->pid(); -} - - void -TDEProcessRunner::slotProcessExited(TDEProcess * p) -{ - if (p != process_) - return; // Eh ? - - kdDebug(7010) << "slotProcessExited " << binName << endl; - kdDebug(7010) << "normalExit " << process_->normalExit() << endl; - kdDebug(7010) << "exitStatus " << process_->exitStatus() << endl; - bool showErr = process_->normalExit() - && ( process_->exitStatus() == 127 || process_->exitStatus() == 1 ); - if ( !binName.isEmpty() && ( showErr || process_->pid() == 0 ) ) - { - // Often we get 1 (zsh, csh) or 127 (ksh, bash) because the binary doesn't exist. - // We can't just rely on that, but it's a good hint. - // Before assuming its really so, we'll try to find the binName - // relatively to current directory, and then in the PATH. - if ( !TQFile( binName ).exists() && KStandardDirs::findExe( binName ).isEmpty() ) - { - kapp->ref(); - KMessageBox::sorry( 0L, i18n("Could not find the program '%1'").arg( binName ) ); - kapp->deref(); - } - } -#ifdef Q_WS_X11 - if( !id_.none()) - { - KStartupInfoData data; - data.addPid( pid()); // announce this pid for the startup notification has finished - data.setHostname(); - KStartupInfo::sendFinish( id_, data ); - } -#endif - deleteLater(); -} - -void KRun::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -#include "krun.moc" diff --git a/kio/kio/krun.h b/kio/kio/krun.h deleted file mode 100644 index 03186af85..000000000 --- a/kio/kio/krun.h +++ /dev/null @@ -1,512 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - Copyright (C) 2006 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __k_run_h__ -#define __k_run_h__ - -#include <sys/stat.h> -#include <sys/types.h> - -#include <tqobject.h> -#include <tqtimer.h> -#include <tqstring.h> -#include <kurl.h> -#include <kstartupinfo.h> - -class TDEProcess; -class KService; -namespace TDEIO { - class Job; - class StatJob; -} - -/** - * To open files with their associated applications in KDE, use KRun. - * - * It can execute any desktop entry, as well as any file, using - * the default application or another application "bound" to the file type - * (or URL protocol). - * - * In that example, the mimetype of the file is not known by the application, - * so a KRun instance must be created. It will determine the mimetype by itself. - * If the mimetype is known, or if you even know the service (application) to - * use for this file, use one of the static methods. - * - * By default KRun uses auto deletion. It causes the KRun instance to delete - * itself when the it finished its task. If you allocate the KRun - * object on the stack you must disable auto deletion, otherwise it will crash. - * - * @short Opens files with their associated applications in KDE - */ -class TDEIO_EXPORT KRun : public TQObject -{ - Q_OBJECT -public: - /** - * Create a KRun object to run the preferred application for a file/URL. - * KRun will first determine the type of the file, and will then - * run the associated application. - * - * @param url the URL of the file or directory to 'run' - * - * @param mode The @p st_mode field of <tt>struct stat</tt>. If - * you don't know this set it to 0. - * - * @param isLocalFile - * If this parameter is set to @p false then @p url is - * examined to find out whether it is a local URL or - * not. This flag is just used to improve speed, since the - * function KURL::isLocalFile is a bit slow. - * - * @param showProgressInfo - * Whether to show progress information when determining the - * type of the file (i.e. when using TDEIO::stat and TDEIO::mimetype) - * Before you set this to false to avoid a dialog box, think about - * a very slow FTP server... - * It is always better to provide progress info in such cases. - */ - KRun( const KURL& url, mode_t mode = 0, - bool isLocalFile = false, bool showProgressInfo = true ); - - /** - * BIC: Combine with the above ctor for KDE 4.0. - * @param window - * The top-level widget of the app that invoked this object. - * It is used to make sure private information like passwords - * are properly handled per application. - * @param url the URL of the file or directory to 'run' - * - * @param mode The @p st_mode field of <tt>struct stat</tt>. If - * you don't know this set it to 0. - * - * @param isLocalFile - * If this parameter is set to @p false then @p url is - * examined to find out whether it is a local URL or - * not. This flag is just used to improve speed, since the - * function KURL::isLocalFile is a bit slow. - * - * @param showProgressInfo - * Whether to show progress information when determining the - * type of the file (i.e. when using TDEIO::stat and TDEIO::mimetype) - * Before you set this to false to avoid a dialog box, think about - * a very slow FTP server... - * It is always better to provide progress info in such cases. - */ - KRun( const KURL& url, TQWidget* window, mode_t mode = 0, - bool isLocalFile = false, bool showProgressInfo = true ); - KRun( const KURL& url, TQWidget* window, const TQCString& asn, mode_t mode = 0, - bool isLocalFile = false, bool showProgressInfo = true ); - - /** - * Destructor. Don't call it yourself, since a KRun object auto-deletes - * itself. - */ - virtual ~KRun(); - - /** - * Abort this KRun. This kills any jobs launched by it, - * and leads to deletion if auto-deletion is on. - * This is much safer than deleting the KRun (in case it's - * currently showing an error dialog box, for instance) - */ - void abort(); - - /** - * Returns true if the KRun instance has an error. - * @return true when an error occurred - * @see error() - */ - bool hasError() const { return m_bFault; } - - /** - * Returns true if the KRun instance has finished. - * @return true if the KRun instance has finished - * @see finished() - */ - bool hasFinished() const { return m_bFinished; } - - /** - * Checks whether auto delete is activated. - * Auto-deletion causes the KRun instance to delete itself - * when it finished its task. - * By default auto deletion is on. - * @return true if auto deletion is on, false otherwise - */ - bool autoDelete() const { return m_bAutoDelete; } - - /** - * Enables or disabled auto deletion. - * Auto deletion causes the KRun instance to delete itself - * when it finished its task. If you allocate the KRun - * object on the stack you must disable auto deletion. - * By default auto deletion is on. - * @param b true to enable auto deletion, false to disable - */ - void setAutoDelete(bool b) { m_bAutoDelete = b; } - - /** - * Set the preferred service for opening this URL, after - * its mimetype will have been found by KRun. IMPORTANT: the service is - * only used if its configuration says it can handle this mimetype. - * This is used for instance for the X-TDE-LastOpenedWith key, for - * the recent documents list. - * @param desktopEntryName the desktopEntryName of the service, e.g. "kate". - */ - void setPreferredService( const TQString& desktopEntryName ); - - /** - * Sets whether executables, .desktop files or shell scripts should - * be run by KRun. This is enabled by default. - * @param b whether to run executable files or not. - * @see isExecutable() - * @since 3.2 - */ - void setRunExecutables(bool b); - - /** - * Sets whether the external webbrowser setting should be honoured. - * This is enabled by default. - * This should only be disabled in webbrowser applications. - * @param b whether to enable the external browser or not. - * @since 3.4 - */ - void setEnableExternalBrowser(bool b); - - /** - * Sets the file name to use in the case of downloading the file to a tempfile - * in order to give to a non-url-aware application. Some apps rely on the extension - * to determine the mimetype of the file. Usually the file name comes from the URL, - * but in the case of the HTTP Content-Disposition header, we need to override the - * file name. - * @since 3.5.3 - */ - void setSuggestedFileName( const TQString& fileName ); - - /** - * Open a list of URLs with a certain service (application). - * - * @param _service the service to run - * @param _urls the list of URLs, can be empty (app launched - * without argument) - * @param window The top-level widget of the app that invoked this object. - * @param tempFiles if true and _urls are local files, they will be deleted - * when the application exits. - * @return the process id, or 0 on error - * @since 3.5.2 - */ - static pid_t run( const KService& _service, const KURL::List& _urls, TQWidget* window, bool tempFiles = false ); - static pid_t run( const KService& _service, const KURL::List& _urls, TQWidget* window, - const TQCString& asn, bool tempFiles = false ); - /** - * Open a list of URLs with a certain service (application). - * - * @param _service the service to run - * @param _urls the list of URLs, can be empty (app launched - * without argument) - * @param tempFiles if true and _urls are local files, they will be deleted - * when the application exits. - * @return the process id, or 0 on error - */ - // BIC merge second overload with first one, using tempFiles=false - static pid_t run( const KService& _service, const KURL::List& _urls, bool tempFiles ); - static pid_t run( const KService& _service, const KURL::List& _urls ); - /// @since 3.5.3 - /// @internal - static pid_t run( const KService& _service, const KURL::List& _urls, TQWidget* window, bool tempFiles, const TQString& suggestedFileName ); - static pid_t run( const KService& _service, const KURL::List& _urls, TQWidget* window, - const TQCString& asn, bool tempFiles, const TQString& suggestedFileName ); - - /** - * Open a list of URLs with. - * - * @param _exec the name of the executable, for example - * "/usr/bin/netscape". - * @param _urls the list of URLs to open, can be empty (app launched without argument) - * @param _name the logical name of the application, for example - * "Netscape 4.06". - * @param _icon the icon which should be used by the application. - * @param _obsolete1 Do not use! - * @param _obsolete2 Do not use! - * @return the process id, or 0 on error - */ - static pid_t run( const TQString& _exec, const KURL::List& _urls, - const TQString& _name = TQString::null, - const TQString& _icon = TQString::null, - const TQString& _obsolete1 = TQString::null, - const TQString& _obsolete2 = TQString::null ); - - /** - * Open the given URL. - * - * This function is used after the mime type - * is found out. It will search for all services which can handle - * the mime type and call run() afterwards. - * @param _url the URL to open - * @param _mimetype the mime type of the resource - * @param tempFile if true and _url is a local file, it will be deleted - * when the launched application exits. - * @param runExecutables if false then local .desktop files, - * executables and shell scripts will not be run. - * See also isExecutable(). - * @return the process id, or 0 on error - */ - // BIC Merge second overload with first one using runExecutables=true, and - // merge third overload with first one as well using tempFiles=false and - // runExecutables=true - static pid_t runURL( const KURL& _url, const TQString& _mimetype, bool tempFile, bool runExecutables); - static pid_t runURL( const KURL& _url, const TQString& _mimetype, bool tempFile); - static pid_t runURL( const KURL& _url, const TQString& _mimetype ); - /// @since 3.5.3 - /// @internal - static pid_t runURL( const KURL& _url, const TQString& _mimetype, TQWidget* window, const TQCString& asn, bool tempFile, bool runExecutables, const TQString& suggestedFileName ); - static pid_t runURL( const KURL& _url, const TQString& _mimetype, bool tempFile, bool runExecutables, const TQString& suggestedFileName ); - - /** - * Run the given shell command and notifies kicker of the starting - * of the application. If the program to be called doesn't exist, - * an error box will be displayed. - * - * Use only when you know the full command line. Otherwise use the other - * static methods, or KRun's constructor. - * - * @p _cmd must be a shell command. You must not append "&" - * to it, since the function will do that for you. - * - * @return PID of running command, 0 if it could not be started, 0 - (PID - * of running command) if command was unsafe for map notification. - */ - static pid_t runCommand( TQString cmd ); - - /** - * Same as the other runCommand(), but it also takes the name of the - * binary, to display an error message in case it couldn't find it. - * - * @param cmd must be a shell command. You must not append "&" - * to it, since the function will do that for you. - * @param execName the name of the executable - * @param icon icon for app starting notification - * @return PID of running command, 0 if it could not be started, 0 - (PID - * of running command) if command was unsafe for map notification. - */ - static pid_t runCommand( const TQString& cmd, const TQString & execName, const TQString & icon ); - static pid_t runCommand( const TQString& cmd, const TQString & execName, const TQString & icon, - TQWidget* window, const TQCString& asn ); - - /** - * Display the Open-With dialog for those URLs, and run the chosen application. - * @param lst the list of applications to run - * @param tempFiles if true and lst are local files, they will be deleted - * when the application exits. - * @return false if the dialog was canceled - */ - // BIC merge second overload with first one, using tempFiles=false - static bool displayOpenWithDialog( const KURL::List& lst, bool tempFiles ); - static bool displayOpenWithDialog( const KURL::List& lst ); - /// @since 3.5.3 - /// @internal - static bool displayOpenWithDialog( const KURL::List& lst, bool tempFiles, const TQString& suggestedFileName ); - - /** - * Quotes a string for the shell. - * @param _str the string to quote. The quoted string will be written here - */ - static void shellQuote( TQString &_str ); - - /** - * Processes a Exec= line as found in .desktop files. - * @param _service the service to extract information from. - * @param _urls The urls the service should open. - * @param has_shell If true, the arguments are going to be fed into a - * shell e.g by using system(). - * If false, the arguments are going to be fed into a exec() kind - * call. - * If the arguments are intended for an exec() kind of call and - * the Exec line contains shell commands then "/bin/sh -c" is added. - * @param tempFiles if true and _urls are local files, they will be deleted - * when the application exits. - * @return a list of arguments suitable for either system() or exec(). - */ - static TQStringList processDesktopExec(const KService &_service, const KURL::List &_urls, bool has_shell, bool tempFiles); - static TQStringList processDesktopExec(const KService &_service, const KURL::List &_urls, bool has_shell); - /// @since 3.5.3 - /// @internal - static TQStringList processDesktopExec(const KService &_service, const KURL::List &_urls, bool has_shell, bool tempFiles, const TQString& suggestedFileName); - - /** - * Given a full command line (e.g. the Exec= line from a .desktop file), - * extract the name of the binary being run. - * @param execLine the full command line - * @param removePath if true, remove a (relative or absolute) path. E.g. /usr/bin/ls becomes ls. - * @return the name of the binary to run - * @since 3.1 - */ - static TQString binaryName( const TQString & execLine, bool removePath ); - - /** - * Returns whether @p serviceType refers to an executable program instead - * of a data file. - * @since 3.2 - */ - static bool isExecutable( const TQString& serviceType ); - - /** - * Returns wether the @p url of @p mimetype is executable. - * To be executable the file must pass the following rules: - * -# Must reside on the local filesystem. - * -# Must be marked as executable for the user by the filesystem. - * -# The mime type must inherit application/x-executable or application/x-executable-script. - * To allow a script to run when the above rules are satisfied add the entry - * @code - * X-TDE-IsAlso=application/x-executable-script - * @endcode - * to the mimetype's desktop file. - * @since 3.3 - */ - static bool isExecutableFile( const KURL& url, const TQString &mimetype ); - - /** - * @internal - * @since 3.4 - */ - static bool checkStartupNotify( const TQString& binName, const KService* service, bool* silent_arg, TQCString* wmclass_arg ); - -signals: - /** - * Emitted when the operation finished. - * @see hasFinished() - */ - void finished(); - /** - * Emitted when the operation had an error. - * @see hasError() - */ - void error(); - -protected slots: - void slotTimeout(); - void slotScanFinished( TDEIO::Job * ); - void slotScanMimeType( TDEIO::Job *, const TQString &type ); - virtual void slotStatResult( TDEIO::Job * ); - -protected: - virtual void init(); - - virtual void scanFile(); - - /** - * Called if the mimetype has been detected. The function checks - * whether the document and appends the gzip protocol to the - * URL. Otherwise runURL is called to finish the job. - */ - virtual void foundMimeType( const TQString& _type ); - - virtual void killJob(); - - KURL m_strURL; - bool m_bFault; - bool m_bAutoDelete; - bool m_bProgressInfo; - bool m_bFinished; - TDEIO::Job * m_job; - TQTimer m_timer; - - /** - * Used to indicate that the next action is to scan the file. - * This action is invoked from slotTimeout. - */ - bool m_bScanFile; - bool m_bIsDirectory; - - /** - * USed to indicate that the next action is to initialize. - * This action is invoked from slotTimeout - */ - bool m_bInit; - - bool m_bIsLocalFile; - mode_t m_mode; - -protected: - virtual void virtual_hook( int id, void* data ); - -private: - void init (const KURL& url, TQWidget* window, const TQCString& asn, mode_t mode, - bool isLocalFile, bool showProgressInfo); -private: - class KRunPrivate; - KRunPrivate *d; -}; - -#ifndef KDE_NO_COMPAT -/** - * @deprecated. Kept for source compatibility, does nothing nowadays. - * Do not use in new source. - * KRun can open the openwith dialog directly now. - * Use KRun::displayOpenWithDialog() if you were using KOpenWithHandler directly. - */ -class TDEIO_EXPORT_DEPRECATED KOpenWithHandler -{ -public: - KOpenWithHandler() {} - static bool exists() { return true; } -}; -#endif - -/** - * @internal - * This class watches a process launched by KRun. - * It sends a notification when the process exits (for the taskbar) - * and it will show an error message if necessary (e.g. "program not found"). - */ -class TDEIO_EXPORT TDEProcessRunner : public TQObject -{ - Q_OBJECT - - public: - - static pid_t run(TDEProcess *, const TQString & binName); -#ifdef Q_WS_X11 // We don't have KStartupInfo in Qt/Embedded - static pid_t run(TDEProcess *, const TQString & binName, const KStartupInfoId& id ); -#endif - - virtual ~TDEProcessRunner(); - - pid_t pid() const; - - protected slots: - - void slotProcessExited(TDEProcess *); - - private: - - TDEProcessRunner(TDEProcess *, const TQString & binName); -#ifdef Q_WS_X11 // We don't have KStartupInfo in Qt/Embedded - TDEProcessRunner(TDEProcess *, const TQString & binName, const KStartupInfoId& id ); -#endif - TDEProcessRunner(); - - TDEProcess * process_; - TQString binName; -#ifdef Q_WS_X11 // We don't have KStartupInfo in Qt/Embedded - KStartupInfoId id_; -#endif -}; - -#endif diff --git a/kio/kio/ksambashare.cpp b/kio/kio/ksambashare.cpp deleted file mode 100644 index ff5b9c104..000000000 --- a/kio/kio/ksambashare.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqdict.h> -#include <tqfile.h> -#include <tqtextstream.h> - -#include <kdirwatch.h> -#include <kstaticdeleter.h> -#include <kdebug.h> -#include <ksimpleconfig.h> - -#include "ksambashare.h" - -class KSambaSharePrivate -{ -public: - KSambaSharePrivate(); - - bool readSmbConf(); - bool findSmbConf(); - bool load(); - - TQDict<bool> sharedPaths; - TQString smbConf; -}; - -KSambaSharePrivate::KSambaSharePrivate() -{ - load(); -} - - -#define FILESHARECONF "/etc/security/fileshare.conf" - -bool KSambaSharePrivate::load() { - if (!findSmbConf()) - return false; - - return readSmbConf(); -} - -/** - * Try to find the samba config file path - * First tries the kconfig, then checks - * several well-known paths - * @return wether a smb.conf was found. - **/ -bool KSambaSharePrivate::findSmbConf() { - KSimpleConfig config(TQString::fromLatin1(FILESHARECONF),true); - smbConf = config.readEntry("SMBCONF"); - - if ( TQFile::exists(smbConf) ) - return true; - - if ( TQFile::exists("/etc/samba/smb.conf") ) - smbConf = "/etc/samba/smb.conf"; - else - if ( TQFile::exists("/etc/smb.conf") ) - smbConf = "/etc/smb.conf"; - else - if ( TQFile::exists("/usr/local/samba/lib/smb.conf") ) - smbConf = "/usr/local/samba/lib/smb.conf"; - else - if ( TQFile::exists("/usr/samba/lib/smb.conf") ) - smbConf = "/usr/samba/lib/smb.conf"; - else - if ( TQFile::exists("/usr/lib/smb.conf") ) - smbConf = "/usr/lib/smb.conf"; - else - if ( TQFile::exists("/usr/local/lib/smb.conf") ) - smbConf = "/usr/local/lib/smb.conf"; - else { - kdDebug(7000) << "KSambaShare: Could not found smb.conf!" << endl; - return false; - } - - return true; -} - - -/** - * Reads all path= entries from the smb.conf file - * and fills the sharedPaths dict with the values - */ -bool KSambaSharePrivate::readSmbConf() { - TQFile f(smbConf); - - kdDebug(7000) << "KSambaShare::readSmbConf " << smbConf << endl; - - if (!f.open(IO_ReadOnly)) { - kdError() << "KSambaShare: Could not open " << smbConf << endl; - return false; - } - - sharedPaths.clear(); - - TQTextStream s(&f); - - bool continuedLine = false; // is true if the line before ended with a backslash - TQString completeLine; - - while (!s.eof()) - { - TQString currentLine = s.readLine().stripWhiteSpace(); - - if (continuedLine) { - completeLine += currentLine; - continuedLine = false; - } - else - completeLine = currentLine; - - // is the line continued in the next line ? - if ( completeLine[completeLine.length()-1] == '\\' ) - { - continuedLine = true; - // remove the ending backslash - completeLine.truncate( completeLine.length()-1 ); - continue; - } - - // comments or empty lines - if (completeLine.isEmpty() || - '#' == completeLine[0] || - ';' == completeLine[0]) - { - continue; - } - - // parameter - int i = completeLine.find('='); - - if (i>-1) - { - TQString name = completeLine.left(i).stripWhiteSpace().lower(); - TQString value = completeLine.mid(i+1).stripWhiteSpace(); - - if (name == TDEGlobal::staticQString("path")) { - // Handle quotation marks - if ( value[0] == '"' ) - value.remove(0,1); - - if ( value[value.length()-1] == '"' ) - value.truncate(value.length()-1); - - // Normalize path - if ( value[value.length()-1] != '/' ) - value += '/'; - - bool b = true; - sharedPaths.insert(value,&b); - kdDebug(7000) << "KSambaShare: Found path: " << value << endl; - } - } - } - - f.close(); - - return true; - -} - -KSambaShare::KSambaShare() { - d = new KSambaSharePrivate(); - if (TQFile::exists(d->smbConf)) { - KDirWatch::self()->addFile(d->smbConf); - KDirWatch::self()->addFile(FILESHARECONF); - connect(KDirWatch::self(), TQT_SIGNAL(dirty (const TQString&)),this, - TQT_SLOT(slotFileChange(const TQString&))); - } -} - -KSambaShare::~KSambaShare() { - if (TQFile::exists(d->smbConf)) { - KDirWatch::self()->removeFile(d->smbConf); - KDirWatch::self()->removeFile(FILESHARECONF); - } - delete d; -} - -TQString KSambaShare::smbConfPath() const { - return d->smbConf; -} - -bool KSambaShare::isDirectoryShared( const TQString & path ) const { - TQString fixedPath = path; - if ( path[path.length()-1] != '/' ) - fixedPath += '/'; - - return d->sharedPaths.find(fixedPath) != 0; -} - -TQStringList KSambaShare::sharedDirectories() const { - TQStringList result; - TQDictIterator<bool> it(d->sharedPaths); - for( ; it.current(); ++it ) - result << it.currentKey(); - - return result; -} - -void KSambaShare::slotFileChange( const TQString & path ) { - if (path == d->smbConf) - d->readSmbConf(); - else - if (path == FILESHARECONF) - d->load(); - - emit changed(); -} - -KSambaShare* KSambaShare::_instance = 0L; -static KStaticDeleter<KSambaShare> ksdSambaShare; - -KSambaShare* KSambaShare::instance() { - if (! _instance ) - _instance = ksdSambaShare.setObject(_instance, new KSambaShare()); - - return _instance; -} - -#include "ksambashare.moc" - diff --git a/kio/kio/ksambashare.h b/kio/kio/ksambashare.h deleted file mode 100644 index ffd298588..000000000 --- a/kio/kio/ksambashare.h +++ /dev/null @@ -1,85 +0,0 @@ -/* This file is part of the KDE project - Copyright (c) 2004 Jan Schaefer <j_schaef@informatik.uni-kl.de> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef ksambashare_h -#define ksambashare_h - -#include <tqobject.h> - -#include <tdelibs_export.h> - -class KSambaSharePrivate; - -/** - * Similar functionality like KFileShare, - * but works only for Samba and do not need - * any suid script. - * Singleton class, call instance() to get an instance. - */ -class TDEIO_EXPORT KSambaShare : public TQObject -{ -Q_OBJECT -public: - /** - * Returns the one and only instance of KSambaShare - */ - static KSambaShare* instance(); - - /** - * Whether or not the given path is shared by Samba. - * @param path the path to check if it is shared by Samba. - * @return whether the given path is shared by Samba. - */ - bool isDirectoryShared( const TQString & path ) const; - - /** - * Returns a list of all directories shared by Samba. - * The resulting list is not sorted. - * @return a list of all directories shared by Samba. - */ - TQStringList sharedDirectories() const; - - /** - * KSambaShare destructor. - * Do not call! - * The instance is destroyed automatically! - */ - virtual ~KSambaShare(); - - /** - * Returns the path to the used smb.conf file - * or null if no file was found - */ - TQString smbConfPath() const; - -signals: - /** - * Emitted when the smb.conf file has changed - */ - void changed(); - -private: - KSambaShare(); - static KSambaShare* _instance; - KSambaSharePrivate* d; - -private slots: - void slotFileChange(const TQString&); -}; - -#endif diff --git a/kio/kio/kscan.cpp b/kio/kio/kscan.cpp deleted file mode 100644 index 49ae7c5ab..000000000 --- a/kio/kio/kscan.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2001 Carsten Pfeiffer <pfeiffer@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqfile.h> - -#include <klocale.h> -#include <ktrader.h> - -#include "kscan.h" - -// static factory method -KScanDialog * KScanDialog::getScanDialog( TQWidget *parent, const char *name, - bool modal ) -{ - KTrader::OfferList offers = KTrader::self()->query("KScan/KScanDialog"); - if ( offers.isEmpty() ) - return 0L; - - KService::Ptr ptr = *(offers.begin()); - KLibFactory *factory = KLibLoader::self()->factory( TQFile::encodeName(ptr->library()) ); - - if ( !factory ) - return 0; - - TQStringList args; - args << TQString::number( (int)modal ); - - TQObject *res = factory->create( TQT_TQOBJECT(parent), name, "KScanDialog", args ); - - return dynamic_cast<KScanDialog *>( res ); -} - - -KScanDialog::KScanDialog( int dialogFace, int buttonMask, - TQWidget *parent, const char *name, bool modal ) - : KDialogBase( dialogFace, i18n("Acquire Image"), buttonMask, Close, - parent, name, modal, true ), - m_currentId( 1 ) -{ -} - -KScanDialog::~KScanDialog() -{ -} - -bool KScanDialog::setup() -{ - return true; -} - -/////////////////////////////////////////////////////////////////// - - -// static factory method -KOCRDialog * KOCRDialog::getOCRDialog( TQWidget *parent, const char *name, - bool modal ) -{ - KTrader::OfferList offers = KTrader::self()->query("KScan/KOCRDialog"); - if ( offers.isEmpty() ) - return 0L; - - KService::Ptr ptr = *(offers.begin()); - KLibFactory *factory = KLibLoader::self()->factory( TQFile::encodeName(ptr->library()) ); - - if ( !factory ) - return 0; - - TQStringList args; - args << TQString::number( (int)modal ); - - TQObject *res = factory->create( TQT_TQOBJECT(parent), name, "KOCRDialog", args ); - - return dynamic_cast<KOCRDialog *>( res ); -} - - -KOCRDialog::KOCRDialog( int dialogFace, int buttonMask, - TQWidget *parent, const char *name, bool modal ) - : KDialogBase( dialogFace, i18n("OCR Image"), buttonMask, Close, - parent, name, modal, true ), - m_currentId( 1 ) -{ - -} - -KOCRDialog::~KOCRDialog() -{ -} - - -/////////////////////////////////////////////////////////////////// - - -KScanDialogFactory::KScanDialogFactory( TQObject *parent, const char *name ) - : KLibFactory( parent, name ), - m_instance( 0L ) -{ -} - -KScanDialogFactory::~KScanDialogFactory() -{ - delete m_instance; -} - -TQObject *KScanDialogFactory::createObject( TQObject *parent, const char *name, - const char *classname, - const TQStringList &args ) -{ - if ( strcmp( classname, "KScanDialog" ) != 0 ) - return 0; - - if ( parent && !parent->isWidgetType() ) - return 0; - - bool modal = false; - - if ( args.count() == 1 ) - modal = (bool)args[ 0 ].toInt(); - - return TQT_TQOBJECT(createDialog( TQT_TQWIDGET( parent ), name, modal )); -} - - -/////////////////////////////////////////////////////////////////// - - -KOCRDialogFactory::KOCRDialogFactory( TQObject *parent, const char *name ) - : KLibFactory( parent, name ), - m_instance( 0L ) -{ -} - -KOCRDialogFactory::~KOCRDialogFactory() -{ - delete m_instance; -} - -TQObject *KOCRDialogFactory::createObject( TQObject *parent, const char *name, - const char *classname, - const TQStringList &args ) -{ - if ( strcmp( classname, "KOCRDialog" ) != 0 ) - return 0; - - if ( parent && !parent->isWidgetType() ) - return 0; - - bool modal = false; - - if ( args.count() == 1 ) - modal = (bool)args[ 0 ].toInt(); - - return TQT_TQOBJECT(createDialog( TQT_TQWIDGET( parent ), name, modal )); -} - -void KScanDialog::virtual_hook( int id, void* data ) -{ KDialogBase::virtual_hook( id, data ); } - -void KScanDialogFactory::virtual_hook( int id, void* data ) -{ KLibFactory::virtual_hook( id, data ); } - -void KOCRDialog::virtual_hook( int id, void* data ) -{ KDialogBase::virtual_hook( id, data ); } - -void KOCRDialogFactory::virtual_hook( int id, void* data ) -{ KLibFactory::virtual_hook( id, data ); } - - -#include "kscan.moc" diff --git a/kio/kio/kscan.h b/kio/kio/kscan.h deleted file mode 100644 index 940b8ceaa..000000000 --- a/kio/kio/kscan.h +++ /dev/null @@ -1,370 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2001 Carsten Pfeiffer <pfeiffer@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KSCAN_H -#define KSCAN_H - -#include <kdialogbase.h> -#include <kinstance.h> -#include <klibloader.h> - -class TQImage; - -/** - * This is a base class for scanning dialogs. You can derive from this class - * and implement your own dialog. An implementation is available in - * tdegraphics/libkscan. - * - * Application developers that wish to add scanning support to their program - * can use the static method @p KScanDialog::getScanDialog() to get an instance - * of the user's preferred scanning dialog. - * - * Typical usage looks like this (e.g. in a slotShowScanDialog() method): - * - * \code - * if ( !m_scanDialog ) { - * m_scanDialog = KScanDialog::getScanDialog( this, "scandialog" ); - * if ( !m_scanDialog ) // no scanning support installed? - * return; - * - * connect( m_scanDialog, TQT_SIGNAL( finalImage( const TQImage&, int )), - * TQT_SLOT( slotScanned( const TQImage&, int ) )); - * } - * - * if ( m_scanDialog->setup() ) // only if scanner configured/available - * m_scanDialog->show(); - * \endcode - * - * This will create and show a non-modal scanning dialog. Connect to more - * signals if you like. - * - * If you implement an own scan-dialog, you also have to implement a - * KScanDialogFactory. - * - * @short A baseclass and accessor for Scanning Dialogs - * @author Carsten Pfeiffer <pfeiffer@kde.org> - */ -class TDEIO_EXPORT KScanDialog : public KDialogBase -{ - Q_OBJECT - -public: - /** - * Creates the user's preferred scanning dialog and returns it, - * or 0L if no scan-support - * is available. Pass a suitable @p parent widget, if you like. If you - * don't you have to 'delete' the returned pointer yourself. - * @param parent the QWidget's parent, or 0 - * @param name the name of the TQObject, can be 0 - * @param modal if true the dialog is model - * @return the KScanDialog, or 0 if the function failed - */ - static KScanDialog * getScanDialog( TQWidget *parent=0L, - const char *name=0, bool modal=false ); - /** - * Destructs the scan dialog. - */ - ~KScanDialog(); - - /** - * Reimplement this if you need to set up some things, before showing the - * dialog, e.g. to ask the user for the scanner device to use. If you - * return false (e.g. there is no device available or the user aborted - * device selection), the dialog will not be shown. - * - * @return true by default. - */ - virtual bool setup(); - -protected: - /** - * Constructs the scan dialog. If you implement an own dialog, you can - * customize it with the usual KDialogBase flags. - * - * @param dialogFace the KDialogBase::DialogType - * @param buttonMask a ORed mask of all buttons (see - * KDialogBase::ButtonCode) - * @param parent the QWidget's parent, or 0 - * @param name the name of the TQObject, can be 0 - * @param modal if true the dialog is model - * @see KDialogBase - */ - KScanDialog( int dialogFace=Tabbed, int buttonMask = Close|Help, - TQWidget *parent=0L, const char *name=0, bool modal=false ); - - /** - * Returns the current id for an image. You can use that in your subclass - * for the signals. The id is used in the signals to let people know - * which preview and which text-recognition belongs to which scan. - * - * @return the current id for the image - * @see nextId - * @see finalImage - * @see preview - * @see textRecognized - */ - int id() const { return m_currentId; } - - /** - * Returns the id for the next image. You can use that in your subclass - * for the signals. - * - * @return the id for the next image - * @see id - * @see finalImage - * @see preview - * @see textRecognized - * - */ - int nextId() { return ++m_currentId; } - -signals: - /** - * Informs you that an image has been previewed. - * @param img the image - * @param id the image's id - */ - void preview( const TQImage &img, int id ); - - /** - * Informs you that an image has scanned. @p id is the same as in the - * @p preview() signal, if this image had been previewed before. - * - * Note, that those id's may not be properly implemented in the current - * libkscan. - * @param img the image - * @param id the image's id - */ - void finalImage( const TQImage &img, int id ); - - /** - * Informs you that the image with the id @p id has been run through - * text-recognition. The text is in the TQString parameter. In the future, - * a compound document, using rich text will be used instead. - * - * @param text the text that has been recognized - * @param id the id of the image - */ - void textRecognized( const TQString &text, int id ); - -private: - int m_currentId; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KScanDialogPrivate; - KScanDialogPrivate *d; -}; - - -/** - * A factory for creating a KScanDialog. You need to reimplement - * createDialog(). - * @short Factory for creating KScanDialogs - */ -class TDEIO_EXPORT KScanDialogFactory : public KLibFactory -{ -public: - virtual ~KScanDialogFactory(); - - /** - * Your library should reimplement this method to return your KScanDialog - * derived dialog. - * @param parent the QWidget's parent, or 0 - * @param name the name of the TQObject, can be 0 - * @param modal if true the dialog is model - */ - virtual KScanDialog * createDialog( TQWidget *parent=0, const char *name=0, - bool modal=false ) = 0; - -protected: - /** - * Creates a new KScanDialogFactory. - * @param parent the QWidget's parent, or 0 - * @param name the name of the TQObject, can be 0 - */ - KScanDialogFactory( TQObject *parent=0, const char *name=0 ); - - virtual TQObject* createObject( TQObject* parent = 0, const char* name = 0, - const char* classname = TQOBJECT_OBJECT_NAME_STRING, - const TQStringList &args = TQStringList() ); - - - /** - * Creates a new instance with the given name. - * @param instanceName the name of the instance - */ - void setName( const TQCString& instanceName ) { - delete m_instance; - m_instance = new TDEInstance( instanceName ); - } - - /** - * Returns the instance. - * @return the TDEInstance - */ - TDEInstance *instance() const { return m_instance; } - -private: - TDEInstance *m_instance; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KScanDialogFactoryPrivate* d; -}; - -/** - * Base class for OCR Dialogs. - */ -class TDEIO_EXPORT KOCRDialog : public KDialogBase -{ - Q_OBJECT - -public: - /** - * Creates the user's preferred OCR dialog and returns it, - * or 0L if no OCR-support - * is available. Pass a suitable @p parent widget, if you like. If you - * don't you have to 'delete' the returned pointer yourself. - * @param parent the QWidget's parent, or 0 - * @param name the name of the TQObject, can be 0 - * @param modal if true the dialog is model - * @return the KOCRDialog, or 0 if the function failed - */ - static KOCRDialog * getOCRDialog( TQWidget *parent=0L, - const char *name=0, bool modal=false ); - ~KOCRDialog(); - -protected: - /** - * Constructs the OCR dialog. If you implement an own dialog, you can - * customize it with the usual KDialogBase flags. - * - * @param dialogFace the KDialogBase::DialogType - * @param buttonMask a ORed mask of all buttons (see - * KDialogBase::ButtonCode) - * @param parent the QWidget's parent, or 0 - * @param name the name of the TQObject, can be 0 - * @param modal if true the dialog is model - */ - KOCRDialog( int dialogFace=Tabbed, int buttonMask = Close|Help, - TQWidget *parent=0L, const char *name=0, bool modal=false ); - - /** - * Returns the current id for an image. You can use that in your subclass - * for the signals. The id is used in the signals to let people know - * which text-recognition belongs to which scan. - * - * @return the current id for the image - * @see nextId - * @see textRecognized - */ - int id() const { return m_currentId; } - - /** - * Returns the id for the next image. You can use that in your subclass - * for the signals. - * - * @return the id for the next image - * @see id - * @see textRecognized - */ - int nextId() { return ++m_currentId; } - -signals: - /** - * Informs you that the image with the id @p id has been run through - * text-recognition. The text is in the TQString parameter. In the future, - * a compound document, using rich text will be used instead. - * - * @param text the text that has been recognized - * @param id the id of the image - */ - void textRecognized( const TQString &text, int id ); - -private: - int m_currentId; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KOCRDialogPrivate; - KOCRDialogPrivate *d; -}; - - -/** - * A factory for creating a KOCRDialog. You need to reimplement - * createDialog(). - * @short Factory for creating KScanDialogs - */ -class TDEIO_EXPORT KOCRDialogFactory : public KLibFactory -{ -public: - virtual ~KOCRDialogFactory(); - - /** - * Your library should reimplement this method to return your KOCRDialog - * derived dialog. - * @param parent the QWidget's parent, or 0 - * @param name the name of the TQObject, can be 0 - * @param modal if true the dialog is model - */ - virtual KOCRDialog * createDialog( TQWidget *parent=0, const char *name=0, - bool modal=false ) = 0; - -protected: - /** - * Creates a new KScanDialogFactory. - * @param parent the QWidget's parent, or 0 - * @param name the name of the TQObject, can be 0 - */ - KOCRDialogFactory( TQObject *parent=0, const char *name=0 ); - - virtual TQObject* createObject( TQObject* parent = 0, const char* name = 0, - const char* className = TQOBJECT_OBJECT_NAME_STRING, - const TQStringList &args = TQStringList() ); - - - /** - * Creates a new instance with the given name. - * @param instanceName the name of the instance - */ - void setName( const TQCString& instanceName ) { - delete m_instance; - m_instance = new TDEInstance( instanceName ); - } - - /** - * Returns the instance. - * @return the TDEInstance - */ - TDEInstance *instance() const { return m_instance; } - -private: - TDEInstance *m_instance; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KOCRDialogFactory* d; -}; - - -#endif // KSCAN_H diff --git a/kio/kio/kservice.cpp b/kio/kio/kservice.cpp deleted file mode 100644 index 547df4651..000000000 --- a/kio/kio/kservice.cpp +++ /dev/null @@ -1,934 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 1999 - 2001 Waldo Bastian <bastian@kde.org> - * Copyright (C) 1999 David Faure <faure@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation; - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -// $Id$ - -#include <config.h> - -#include "kservice.h" -#include "kservice_p.h" - -#include <sys/types.h> -#include <sys/stat.h> - -#include <stddef.h> -#include <unistd.h> -#include <stdlib.h> - -#include <tqstring.h> -#include <tqfile.h> -#include <tqdir.h> -#include <tqtl.h> - -#include <ksimpleconfig.h> -#include <kapplication.h> -#include <kdebug.h> -#include <kdesktopfile.h> -#include <kglobal.h> -#include <kiconloader.h> -#include <klocale.h> -#include <kconfigbase.h> -#include <kstandarddirs.h> -#include <dcopclient.h> - -#include "kservicefactory.h" -#include "kservicetypefactory.h" -#include "kservicetype.h" -#include "kuserprofile.h" -#include "tdesycoca.h" - -class KService::KServicePrivate -{ -public: - TQStringList categories; - TQString menuId; -}; - -KService::KService( const TQString & _name, const TQString &_exec, const TQString &_icon) - : KSycocaEntry( TQString::null) -{ - d = new KServicePrivate; - m_bValid = true; - m_bDeleted = false; - m_strType = "Application"; - m_strName = _name; - m_strExec = _exec; - m_strIcon = _icon; - m_bTerminal = false; - m_bAllowAsDefault = true; - m_initialPreference = 10; -} - - -KService::KService( const TQString & _fullpath ) - : KSycocaEntry( _fullpath) -{ - KDesktopFile config( _fullpath ); - - init(&config); -} - -KService::KService( KDesktopFile *config ) - : KSycocaEntry( config->fileName()) -{ - init(config); -} - -void -KService::init( KDesktopFile *config ) -{ - d = new KServicePrivate; - m_bValid = true; - - bool absPath = !TQDir::isRelativePath(entryPath()); - bool kde4application = config->fileName().startsWith("/usr/share/applications/kde4/"); - - config->setDesktopGroup(); - - TQMap<TQString, TQString> entryMap = config->entryMap(config->group()); - - entryMap.remove("Encoding"); // reserved as part of Desktop Entry Standard - entryMap.remove("Version"); // reserved as part of Desktop Entry Standard - - m_bDeleted = config->readBoolEntry( "Hidden", false ); - entryMap.remove("Hidden"); - if (m_bDeleted) - { - //kdDebug() << "Hidden=true for " << entryPath() << endl; - m_bValid = false; - return; - } - - m_strName = config->readName(); - entryMap.remove("Name"); - if ( m_strName.isEmpty() ) - { - if (config->readEntry( "Exec" ).isEmpty()) - { - //kdWarning(7012) << "The desktop entry file " << entryPath() - // << " has no Name and no Exec" << endl; - m_bValid = false; - return; - } - // Try to make up a name. - m_strName = entryPath(); - int i = m_strName.findRev('/'); - m_strName = m_strName.mid(i+1); - i = m_strName.findRev('.'); - if (i != -1) - m_strName = m_strName.left(i); - } - - m_strType = config->readType(); - entryMap.remove("Type"); - if ( m_strType.isEmpty() ) - { - /*kdWarning(7012) << "The desktop entry file " << entryPath() - << " has no Type=... entry." - << " It should be \"Application\" or \"Service\"" << endl; - m_bValid = false; - return;*/ - m_strType = "Application"; - } else if ( m_strType != "Application" && m_strType != "Service" ) - { - kdWarning(7012) << "The desktop entry file " << entryPath() - << " has Type=" << m_strType - << " instead of \"Application\" or \"Service\"" << endl; - m_bValid = false; - return; - } - - // In case Try Exec is set, check if the application is available - if (!config->tryExec()) { - //kdDebug(7012) << "tryExec said false for " << entryPath() << endl; - m_bDeleted = true; - m_bValid = false; - return; - } - - TQString resource = config->resource(); - - if ( (m_strType == "Application") && - (!resource.isEmpty()) && - (resource != "apps") && - !absPath) - { - kdWarning(7012) << "The desktop entry file " << entryPath() - << " has Type=" << m_strType << " but is located under \"" << resource - << "\" instead of \"apps\"" << endl; - m_bValid = false; - return; - } - - if ( (m_strType == "Service") && - (!resource.isEmpty()) && - (resource != "services") && - !absPath) - { - kdWarning(7012) << "The desktop entry file " << entryPath() - << " has Type=" << m_strType << " but is located under \"" << resource - << "\" instead of \"services\"" << endl; - m_bValid = false; - return; - } - - TQString name = entryPath(); - int pos = name.findRev('/'); - if (pos != -1) - name = name.mid(pos+1); - pos = name.find('.'); - if (pos != -1) - name = name.left(pos); - - m_strExec = config->readPathEntry( "Exec" ); - if (kde4application && !m_strExec.startsWith("/")) { - m_strExec = "XDG_DATA_DIRS=/usr/share XDG_CONFIG_DIRS=/etc/xdg/ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:$PATH "+m_strExec; - } else if (config->readBoolEntry("X-TDE-SubstituteUID")) { - int space = m_strExec.find(" "); - if (space==-1) - m_strExec = KStandardDirs::findExe(m_strExec); - else { - const TQString command = m_strExec.left(space); - m_strExec.replace(command,KStandardDirs::findExe(command)); - } - } - - entryMap.remove("Exec"); - - m_strIcon = config->readEntry( "Icon", "unknown" ); - if (kde4application) { - if (TQFile::exists("/usr/share/icons/oxygen/22x22/apps/" + m_strIcon + ".png")) { - m_strIcon = "/usr/share/icons/oxygen/22x22/apps/" + m_strIcon + ".png"; - } else if (TQFile::exists("/usr/share/icons/hicolor/22x22/apps/" + m_strIcon + ".png")) { - m_strIcon = "/usr/share/icons/hicolor/22x22/apps/" + m_strIcon + ".png"; - } - } - entryMap.remove("Icon"); - m_bTerminal = (config->readBoolEntry( "Terminal" )); // should be a property IMHO - entryMap.remove("Terminal"); - m_strTerminalOptions = config->readEntry( "TerminalOptions" ); // should be a property IMHO - entryMap.remove("TerminalOptions"); - m_strPath = config->readPath(); - entryMap.remove("Path"); - m_strComment = config->readComment(); - entryMap.remove("Comment"); - m_strGenName = config->readGenericName(); - if (kde4application) { - m_strGenName += " [KDE4]"; - } - entryMap.remove("GenericName"); - TQString untranslatedGenericName = config->readEntryUntranslated( "GenericName" ); - if (!untranslatedGenericName.isEmpty()) - entryMap.insert("UntranslatedGenericName", untranslatedGenericName); - - m_lstKeywords = config->readListEntry("Keywords"); - entryMap.remove("Keywords"); - d->categories = config->readListEntry("Categories", ';'); - entryMap.remove("Categories"); - m_strLibrary = config->readEntry( "X-TDE-Library" ); - entryMap.remove("X-TDE-Library"); - m_strInit = config->readEntry("X-TDE-Init" ); - entryMap.remove("X-TDE-Init"); - - m_lstServiceTypes = config->readListEntry( "ServiceTypes" ); - entryMap.remove("ServiceTypes"); - // For compatibility with KDE 1.x - if (!kde4application) - m_lstServiceTypes += config->readListEntry( "MimeType", ';' ); - entryMap.remove("MimeType"); - - if ( m_strType == "Application" && !m_lstServiceTypes.contains("Application") ) - // Applications implement the service type "Application" ;-) - m_lstServiceTypes += "Application"; - - TQString dcopServiceType = config->readEntry("X-DCOP-ServiceType").lower(); - entryMap.remove("X-DCOP-ServiceType"); - if (dcopServiceType == "unique") - m_DCOPServiceType = DCOP_Unique; - else if (dcopServiceType == "multi") - m_DCOPServiceType = DCOP_Multi; - else if (dcopServiceType == "wait") - m_DCOPServiceType = DCOP_Wait; - else - m_DCOPServiceType = DCOP_None; - - m_strDesktopEntryName = name.lower(); - if (kde4application) - m_strDesktopEntryName = "kde4-" + m_strDesktopEntryName; - - m_bAllowAsDefault = config->readBoolEntry( "AllowDefault", true ); - entryMap.remove("AllowDefault"); - - m_initialPreference = config->readNumEntry( "X-TDE-InitialPreference", 1 ); - entryMap.remove("X-TDE-InitialPreference"); - if ( m_initialPreference == 1 ) - m_initialPreference = config->readNumEntry( "InitialPreference", 1 ); - entryMap.remove("InitialPreference"); - - // Store all additional entries in the property map. - // A TQMap<TQString,TQString> would be easier for this but we can't - // brake BC, so we have to store it in m_mapProps. -// tqWarning("Path = %s", entryPath().latin1()); - TQMap<TQString,TQString>::ConstIterator it = entryMap.begin(); - for( ; it != entryMap.end();++it) - { - //tqDebug(" Key = %s Data = %s", it.key().latin1(), it.data().latin1()); - TQString key = it.key(); - if (kde4application && key=="OnlyShowIn" && it.data()=="KDE;") - key = "NotShowIn"; - m_mapProps.insert( key, TQVariant( it.data())); - } -} - -KService::KService( TQDataStream& _str, int offset ) : KSycocaEntry( _str, offset ) -{ - d = new KServicePrivate; - load( _str ); -} - -KService::~KService() -{ - //debug("KService::~KService()"); - delete d; -} - -TQPixmap KService::pixmap( KIcon::Group _group, int _force_size, int _state, TQString * _path ) const -{ - KIconLoader *iconLoader=TDEGlobal::iconLoader(); - if (!iconLoader->extraDesktopThemesAdded()) - { - TQPixmap pixmap=iconLoader->loadIcon( m_strIcon, _group, _force_size, _state, _path, true ); - if (!pixmap.isNull() ) return pixmap; - - iconLoader->addExtraDesktopThemes(); - } - - return iconLoader->loadIcon( m_strIcon, _group, _force_size, _state, _path ); -} - -void KService::load( TQDataStream& s ) -{ - // dummies are here because of fields that were removed, to keep bin compat. - // Feel free to re-use, but fields for Applications only (not generic services) - // should rather be added to application.desktop - TQ_INT8 def, term, dummy1, dummy2; - TQ_INT8 dst, initpref; - TQString dummyStr1, dummyStr2; - int dummyI1, dummyI2; - TQ_UINT32 dummyUI32; - - // WARNING: IN KDE 3.x THIS NEEDS TO REMAIN COMPATIBLE WITH KDE 2.x! - // !! This data structure should remain binary compatible at all times !! - // You may add new fields at the end. Make sure to update the version - // number in tdesycoca.h - s >> m_strType >> m_strName >> m_strExec >> m_strIcon - >> term >> m_strTerminalOptions - >> m_strPath >> m_strComment >> m_lstServiceTypes >> def >> m_mapProps - >> m_strLibrary >> dummyI1 >> dummyI2 - >> dst - >> m_strDesktopEntryName - >> dummy1 >> dummyStr1 >> initpref >> dummyStr2 >> dummy2 - >> m_lstKeywords >> m_strInit >> dummyUI32 >> m_strGenName - >> d->categories >> d->menuId; - - m_bAllowAsDefault = def; - m_bTerminal = term; - m_DCOPServiceType = (DCOPServiceType_t) dst; - m_initialPreference = initpref; - - m_bValid = true; -} - -void KService::save( TQDataStream& s ) -{ - KSycocaEntry::save( s ); - TQ_INT8 def = m_bAllowAsDefault, initpref = m_initialPreference; - TQ_INT8 term = m_bTerminal; - TQ_INT8 dst = (TQ_INT8) m_DCOPServiceType; - TQ_INT8 dummy1 = 0, dummy2 = 0; // see ::load - TQString dummyStr1, dummyStr2; - int dummyI1 = 0, dummyI2 = 0; - TQ_UINT32 dummyUI32 = 0; - - // WARNING: IN KDE 3.x THIS NEEDS TO REMAIN COMPATIBLE WITH KDE 2.x! - // !! This data structure should remain binary compatible at all times !! - // You may add new fields at the end. Make sure to update the version - // number in tdesycoca.h - s << m_strType << m_strName << m_strExec << m_strIcon - << term << m_strTerminalOptions - << m_strPath << m_strComment << m_lstServiceTypes << def << m_mapProps - << m_strLibrary << dummyI1 << dummyI2 - << dst - << m_strDesktopEntryName - << dummy1 << dummyStr1 << initpref << dummyStr2 << dummy2 - << m_lstKeywords << m_strInit << dummyUI32 << m_strGenName - << d->categories << d->menuId; -} - -bool KService::hasServiceType( const TQString& _servicetype ) const -{ - if (!m_bValid) return false; // safety test - - //kdDebug(7012) << "Testing " << m_strDesktopEntryName << " for " << _servicetype << endl; - - KMimeType::Ptr mimePtr = KMimeType::mimeType( _servicetype ); - if ( mimePtr && mimePtr == KMimeType::defaultMimeTypePtr() ) - mimePtr = 0; - - bool isNumber; - // For each service type we are associated with, if it doesn't - // match then we try its parent service types. - TQStringList::ConstIterator it = m_lstServiceTypes.begin(); - for( ; it != m_lstServiceTypes.end(); ++it ) - { - (*it).toInt(&isNumber); - if (isNumber) - continue; - //kdDebug(7012) << " has " << (*it) << endl; - KServiceType::Ptr ptr = KServiceType::serviceType( *it ); - if ( ptr && ptr->inherits( _servicetype ) ) - return true; - - // The mimetype inheritance ("is also") works the other way. - // e.g. if we're looking for a handler for mimePtr==smb-workgroup - // then a handler for inode/directory is ok. - if ( mimePtr && mimePtr->is( *it ) ) - return true; - } - return false; -} - -int KService::initialPreferenceForMimeType( const TQString& mimeType ) const -{ - if (!m_bValid) return 0; // safety test - - bool isNumber; - - // For each service type we are associated with - TQStringList::ConstIterator it = m_lstServiceTypes.begin(); - for( ; it != m_lstServiceTypes.end(); ++it ) - { - (*it).toInt(&isNumber); - if (isNumber) - continue; - //kdDebug(7012) << " has " << (*it) << endl; - KServiceType::Ptr ptr = KServiceType::serviceType( *it ); - if ( !ptr || !ptr->inherits( mimeType ) ) - continue; - - int initalPreference = m_initialPreference; - ++it; - if (it != m_lstServiceTypes.end()) - { - int i = (*it).toInt(&isNumber); - if (isNumber) - initalPreference = i; - } - return initalPreference; - } - - KMimeType::Ptr mimePtr = KMimeType::mimeType( mimeType ); - if ( mimePtr && mimePtr == KMimeType::defaultMimeTypePtr() ) - mimePtr = 0; - - // Try its parent service types. - it = m_lstServiceTypes.begin(); - for( ; it != m_lstServiceTypes.end(); ++it ) - { - (*it).toInt(&isNumber); - if (isNumber) - continue; - - // The mimetype inheritance ("is also") works the other way. - // e.g. if we're looking for a handler for mimePtr==smb-workgroup - // then a handler for inode/directory is ok. - if ( !mimePtr || !mimePtr->is( *it ) ) - continue; - - int initalPreference = m_initialPreference; - ++it; - if (it != m_lstServiceTypes.end()) - { - int i = (*it).toInt(&isNumber); - if (isNumber) - initalPreference = i; - } - return initalPreference; - } - return 0; -} - -class KServiceReadProperty : public TDEConfigBase -{ -public: - KServiceReadProperty(const TQString &_key, const TQCString &_value) - : key(_key), value(_value) { } - - bool internalHasGroup(const TQCString &) const { /*tqDebug("hasGroup(const TQCString &)");*/ return false; } - - TQStringList groupList() const { return TQStringList(); } - - TQMap<TQString,TQString> entryMap(const TQString &group) const - { Q_UNUSED(group); return TQMap<TQString,TQString>(); } - - void reparseConfiguration() { } - - KEntryMap internalEntryMap( const TQString &pGroup) const - { Q_UNUSED(pGroup); return KEntryMap(); } - - KEntryMap internalEntryMap() const { return KEntryMap(); } - - void putData(const KEntryKey &_key, const KEntry& _data, bool _checkGroup) - { Q_UNUSED(_key); Q_UNUSED(_data); Q_UNUSED(_checkGroup); } - - KEntry lookupData(const KEntryKey &_key) const - { Q_UNUSED(_key); KEntry entry; entry.mValue = value; return entry; } -protected: - TQString key; - TQCString value; -}; - -TQVariant KService::property( const TQString& _name) const -{ - return property( _name, TQVariant::Invalid); -} - -// Return a string TQVariant if string isn't null, and invalid variant otherwise -// (the variant must be invalid if the field isn't in the .desktop file) -// This allows trader queries like "exist Library" to work. -static TQVariant makeStringVariant( const TQString& string ) -{ - // Using isEmpty here would be wrong. - // Empty is "specified but empty", null is "not specified" (in the .desktop file) - return string.isNull() ? TQVariant() : TQVariant( string ); -} - -TQVariant KService::property( const TQString& _name, TQVariant::Type t ) const -{ - if ( _name == "Type" ) - return TQVariant( m_strType ); // can't be null - else if ( _name == "Name" ) - return TQVariant( m_strName ); // can't be null - else if ( _name == "Exec" ) - return makeStringVariant( m_strExec ); - else if ( _name == "Icon" ) - return makeStringVariant( m_strIcon ); - else if ( _name == "Terminal" ) - return TQVariant( static_cast<int>(m_bTerminal) ); - else if ( _name == "TerminalOptions" ) - return makeStringVariant( m_strTerminalOptions ); - else if ( _name == "Path" ) - return makeStringVariant( m_strPath ); - else if ( _name == "Comment" ) - return makeStringVariant( m_strComment ); - else if ( _name == "GenericName" ) - return makeStringVariant( m_strGenName ); - else if ( _name == "ServiceTypes" ) - return TQVariant( m_lstServiceTypes ); - else if ( _name == "AllowAsDefault" ) - return TQVariant( static_cast<int>(m_bAllowAsDefault) ); - else if ( _name == "InitialPreference" ) - return TQVariant( m_initialPreference ); - else if ( _name == "Library" ) - return makeStringVariant( m_strLibrary ); - else if ( _name == "DesktopEntryPath" ) // can't be null - return TQVariant( entryPath() ); - else if ( _name == "DesktopEntryName") - return TQVariant( m_strDesktopEntryName ); // can't be null - else if ( _name == "Categories") - return TQVariant( d->categories ); - else if ( _name == "Keywords") - return TQVariant( m_lstKeywords ); - - // Ok we need to convert the property from a TQString to its real type. - // Maybe the caller helped us. - if (t == TQVariant::Invalid) - { - // No luck, let's ask KServiceTypeFactory what the type of this property - // is supposed to be. - t = KServiceTypeFactory::self()->findPropertyTypeByName(_name); - if (t == TQVariant::Invalid) - { - kdDebug(7012) << "Request for unknown property '" << _name << "'\n"; - return TQVariant(); // Unknown property: Invalid variant. - } - } - - // Then we use a homebuild class based on TDEConfigBase to convert the TQString. - // For some often used property types we do the conversion ourselves. - TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.find( _name ); - if ( (it == m_mapProps.end()) || (!it.data().isValid())) - { - //kdDebug(7012) << "Property not found " << _name << endl; - return TQVariant(); // No property set. - } - - switch(t) - { - case TQVariant::String: - return it.data(); - case TQVariant::Bool: - case TQVariant::Int: - { - TQString aValue = it.data().toString(); - int val = 0; - if (aValue == "true" || aValue == "on" || aValue == "yes") - val = 1; - else - { - bool bOK; - val = aValue.toInt( &bOK ); - if( !bOK ) - val = 0; - } - if (t == TQVariant::Bool) - { - return TQVariant((bool)val, 1); - } - return TQVariant(val); - } - default: - // All others - KServiceReadProperty ksrp(_name, it.data().toString().utf8()); - return ksrp.readPropertyEntry(_name, t); - } -} - -TQStringList KService::propertyNames() const -{ - TQStringList res; - - TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.begin(); - for( ; it != m_mapProps.end(); ++it ) - res.append( it.key() ); - - res.append( "Type" ); - res.append( "Name" ); - res.append( "Comment" ); - res.append( "GenericName" ); - res.append( "Icon" ); - res.append( "Exec" ); - res.append( "Terminal" ); - res.append( "TerminalOptions" ); - res.append( "Path" ); - res.append( "ServiceTypes" ); - res.append( "AllowAsDefault" ); - res.append( "InitialPreference" ); - res.append( "Library" ); - res.append( "DesktopEntryPath" ); - res.append( "DesktopEntryName" ); - res.append( "Keywords" ); - res.append( "Categories" ); - - return res; -} - -KService::List KService::allServices() -{ - return KServiceFactory::self()->allServices(); -} - -KService::Ptr KService::serviceByName( const TQString& _name ) -{ - KService * s = KServiceFactory::self()->findServiceByName( _name ); - return KService::Ptr( s ); -} - -KService::Ptr KService::serviceByDesktopPath( const TQString& _name ) -{ - KService * s = KServiceFactory::self()->findServiceByDesktopPath( _name ); - return KService::Ptr( s ); -} - -KService::Ptr KService::serviceByDesktopName( const TQString& _name ) -{ - KService * s = KServiceFactory::self()->findServiceByDesktopName( _name.lower() ); - if (!s && !_name.startsWith("kde-")) - s = KServiceFactory::self()->findServiceByDesktopName( "kde-"+_name.lower() ); - return KService::Ptr( s ); -} - -KService::Ptr KService::serviceByMenuId( const TQString& _name ) -{ - KService * s = KServiceFactory::self()->findServiceByMenuId( _name ); - return KService::Ptr( s ); -} - -KService::Ptr KService::serviceByStorageId( const TQString& _storageId ) -{ - KService::Ptr service = KService::serviceByMenuId( _storageId ); - if (service) - return service; - - service = KService::serviceByDesktopPath(_storageId); - if (service) - return service; - - if (!TQDir::isRelativePath(_storageId) && TQFile::exists(_storageId)) - return new KService(_storageId); - - TQString tmp = _storageId; - tmp = tmp.mid(tmp.findRev('/')+1); // Strip dir - - if (tmp.endsWith(".desktop")) - tmp.truncate(tmp.length()-8); - - if (tmp.endsWith(".kdelnk")) - tmp.truncate(tmp.length()-7); - - service = KService::serviceByDesktopName(tmp); - - return service; -} - -KService::List KService::allInitServices() -{ - return KServiceFactory::self()->allInitServices(); -} - -bool KService::substituteUid() const { - TQVariant v = property("X-TDE-SubstituteUID", TQVariant::Bool); - return v.isValid() && v.toBool(); -} - -TQString KService::username() const { - // See also KDesktopFile::tryExec() - TQString user; - TQVariant v = property("X-TDE-Username", TQVariant::String); - user = v.isValid() ? v.toString() : TQString::null; - if (user.isEmpty()) - user = ::getenv("ADMIN_ACCOUNT"); - if (user.isEmpty()) - user = "root"; - return user; -} - -bool KService::noDisplay() const { - TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.find( "NoDisplay" ); - if ( (it != m_mapProps.end()) && (it.data().isValid())) - { - TQString aValue = it.data().toString().lower(); - if (aValue == "true" || aValue == "on" || aValue == "yes") - return true; - } - - it = m_mapProps.find( "OnlyShowIn" ); - if ( (it != m_mapProps.end()) && (it.data().isValid())) - { - TQString aValue = it.data().toString(); - TQStringList aList = TQStringList::split(';', aValue); - if ((!aList.contains("TDE")) && (!aList.contains("KDE"))) - return true; - } - - it = m_mapProps.find( "NotShowIn" ); - if ( (it != m_mapProps.end()) && (it.data().isValid())) - { - TQString aValue = it.data().toString(); - TQStringList aList = TQStringList::split(';', aValue); - if ((aList.contains("TDE")) || (aList.contains("KDE"))) - return true; - } - - if (!kapp->authorizeControlModule(d->menuId)) - return true; - - return false; -} - -TQString KService::untranslatedGenericName() const { - TQVariant v = property("UntranslatedGenericName", TQVariant::String); - return v.isValid() ? v.toString() : TQString::null; -} - -bool KService::SuSEunimportant() const { - TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.find( "X-SuSE-Unimportant" ); - if ( (it == m_mapProps.end()) || (!it.data().isValid())) - { - return false; - } - - TQString aValue = it.data().toString(); - if (aValue == "true" || aValue == "on" || aValue == "yes") - return true; - else - return false; -} - -TQString KService::parentApp() const { - TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.find( "X-TDE-ParentApp" ); - if ( (it == m_mapProps.end()) || (!it.data().isValid())) - { - return TQString::null; - } - - return it.data().toString(); -} - -bool KService::allowMultipleFiles() const { - // Can we pass multiple files on the command line or do we have to start the application for every single file ? - if ( m_strExec.find( "%F" ) != -1 || m_strExec.find( "%U" ) != -1 || - m_strExec.find( "%N" ) != -1 || m_strExec.find( "%D" ) != -1 ) - return true; - else - return false; -} - -TQStringList KService::categories() const -{ - return d->categories; -} - -TQString KService::menuId() const -{ - return d->menuId; -} - -void KService::setMenuId(const TQString &menuId) -{ - d->menuId = menuId; -} - -TQString KService::storageId() const -{ - if (!d->menuId.isEmpty()) - return d->menuId; - return entryPath(); -} - -TQString KService::locateLocal() -{ - if (d->menuId.isEmpty() || desktopEntryPath().startsWith(".hidden") || - (TQDir::isRelativePath(desktopEntryPath()) && d->categories.isEmpty())) - return KDesktopFile::locateLocal(desktopEntryPath()); - - return ::locateLocal("xdgdata-apps", d->menuId); -} - -TQString KService::newServicePath(bool showInMenu, const TQString &suggestedName, - TQString *menuId, const TQStringList *reservedMenuIds) -{ - TQString base = suggestedName; - if (!showInMenu) - base.prepend("kde-"); - - TQString result; - for(int i = 1; true; i++) - { - if (i == 1) - result = base + ".desktop"; - else - result = base + TQString("-%1.desktop").arg(i); - - if (reservedMenuIds && reservedMenuIds->contains(result)) - continue; - - // Lookup service by menu-id - KService::Ptr s = serviceByMenuId(result); - if (s) - continue; - - if (showInMenu) - { - if (!locate("xdgdata-apps", result).isEmpty()) - continue; - } - else - { - TQString file = result.mid(4); // Strip "kde-" - if (!locate("apps", ".hidden/"+file).isEmpty()) - continue; - } - - break; - } - if (menuId) - *menuId = result; - - if (showInMenu) - { - return ::locateLocal("xdgdata-apps", result); - } - else - { - TQString file = result.mid(4); // Strip "kde-" - return ::locateLocal("apps", ".hidden/"+file); - } -} - - -void KService::virtual_hook( int id, void* data ) -{ KSycocaEntry::virtual_hook( id, data ); } - - -void KService::rebuildKSycoca(TQWidget *parent) -{ - KServiceProgressDialog dlg(parent, "tdesycoca_progress", - i18n("Updating System Configuration"), - i18n("Updating system configuration.")); - - TQByteArray data; - DCOPClient *client = kapp->dcopClient(); - - int result = client->callAsync("kded", "kbuildsycoca", "recreate()", - data, TQT_TQOBJECT(&dlg), TQT_SLOT(slotFinished())); - - if (result) - { - dlg.exec(); - } -} - -KServiceProgressDialog::KServiceProgressDialog(TQWidget *parent, const char *name, - const TQString &caption, const TQString &text) - : KProgressDialog(parent, name, caption, text, true) -{ - connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotProgress())); - progressBar()->setTotalSteps(20); - m_timeStep = 700; - m_timer.start(m_timeStep); - setAutoClose(false); -} - -void -KServiceProgressDialog::slotProgress() -{ - int p = progressBar()->progress(); - if (p == 18) - { - progressBar()->reset(); - progressBar()->setProgress(1); - m_timeStep = m_timeStep * 2; - m_timer.start(m_timeStep); - } - else - { - progressBar()->setProgress(p+1); - } -} - -void -KServiceProgressDialog::slotFinished() -{ - progressBar()->setProgress(20); - m_timer.stop(); - TQTimer::singleShot(1000, this, TQT_SLOT(close())); -} - -#include "kservice_p.moc" diff --git a/kio/kio/kservice.h b/kio/kio/kservice.h deleted file mode 100644 index 4db478ba6..000000000 --- a/kio/kio/kservice.h +++ /dev/null @@ -1,562 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kservices_h__ -#define __kservices_h__ - -#include <tqstringlist.h> -#include <tqmap.h> -#include <tqvariant.h> -#include <kicontheme.h> - -#include "tdesycocaentry.h" - -class TQDataStream; -class KDesktopFile; -class KService; -class KBuildSycoca; -class TQWidget; - -/** - * Represent a service, i.e. an application bound to one or several mimetypes - * (or servicetypes) as written in its desktop entry file. - * - * A service may be a library, too. - * The starting point you need is often the static methods. - * Service types are stored as desktop files in the "service" resource.. - * - * @see KServiceType - * @see KServiceGroup - * @author Torben Weis <weis@kde.org> - */ -class TDEIO_EXPORT KService : public KSycocaEntry -{ - K_SYCOCATYPE( KST_KService, KSycocaEntry ) - - friend class KBuildSycoca; - -public: - typedef KSharedPtr<KService> Ptr; - typedef TQValueList<Ptr> List; -public: - /** - * Construct a temporary service with a given name, exec-line and icon. - * @param _name the name of the service - * @param _exec the executable - * @param _icon the name of the icon - */ - KService( const TQString & _name, const TQString &_exec, const TQString &_icon); - - /** - * Construct a service and take all information from a config file. - * - * @param _fullpath Full path to the config file. - */ - explicit KService( const TQString & _fullpath ); - - /** - * Construct a service and take all information from a desktop file. - * @param config the desktop file to read - */ - KService( KDesktopFile *config ); // KDE-4.0: make explicit - - /** - * @internal - * Construct a service from a stream. - * The stream must already be positionned at the correct offset. - */ - KService( TQDataStream& _str, int offset ); - - virtual ~KService(); - - /** - * Returns the type of the service. - * @return the type of the service ("Application" or "Service") - */ - virtual TQString type() const { return m_strType; } - /** - * Returns the name of the service. - * @return the name of the service, - * or TQString::null if not set - */ - virtual TQString name() const { return m_strName; } - /** - * Returns the executable. - * @return the command that the service executes, - * or TQString::null if not set - */ - TQString exec() const { return m_strExec; } - /** - * Returns the name of the service's library. - * @return the name of the library that contains the services - * implementation, - * or TQString::null if not set - */ - TQString library() const { return m_strLibrary; } - /** - * Returns the name of the init function to call (KControl modules). - * @return the name of the init function to call in this service - * during startup of KDE. (KControl modules only), - * or TQString::null if not set - */ - TQString init() const { return m_strInit; } - - /** - * Returns the name of the icon. - * @return the icon associated with the service, - * or "unknown" if not set - */ - TQString icon() const { return m_strIcon; } - /** - * Returns the pixmap that represents the icon. - * @return a pixmap for this service (finds and loads icon()), - * null if not set - * @see icon() - */ - TQPixmap pixmap( KIcon::Group _group, int _force_size = 0, int _state = 0, - TQString * _path = 0L ) const; - /** - * Checks whethe the service should be run in a terminal. - * @return true if the service is to be run in a terminal. - */ - bool terminal() const { return m_bTerminal; } - /** - * Returns any options associated with the terminal the service - * runs in, if it requires a terminal. - * - * The service must be a tty-oriented program. - * @return the terminal options, - * or TQString::null if not set - */ - TQString terminalOptions() const { return m_strTerminalOptions; } - /** - * Checks whether the service runs with a different user id. - * @return true if the service has to be run under a different uid. - * @see username() - */ - bool substituteUid() const; - /** - * Returns the user name, if the service runs with a - * different user id. - * @return the username under which the service has to be run, - * or TQString::null if not set - * @see substututeUid()a - */ - TQString username() const; - - /** - * Returns the path to the location where the service desktop entry - * is stored. - * - * This is a relative path if the desktop entry was found in any - * of the locations pointed to by $TDEDIRS (e.g. "Internet/kppp.desktop") - * It is a full path if the desktop entry originates from another - * location. - * @return the path of the service's desktop file, - * or TQString::null if not set - */ - TQString desktopEntryPath() const { return entryPath(); } - - /** - * Returns the filename of the service desktop entry without any - * extension. E.g. "kppp" - * @return the name of the desktop entry without path or extension, - * or TQString::null if not set - */ - TQString desktopEntryName() const { return m_strDesktopEntryName; } - - /** - * Returns the menu ID of the service desktop entry. - * The menu ID is used to add or remove the entry to a menu. - * @return the menu ID - * @since 3.2 - */ - TQString menuId() const; - - /** - * Returns a normalized ID suitable for storing in configuration files. - * It will be based on the menu-id when available and otherwise falls - * back to desktopEntryPath() - * @return the storage ID - * @since 3.2 - */ - TQString storageId() const; - - /** - * Describes the DCOP type of the service. - * @li None - This service has no DCOP support - * @li Unique - This service provides a unique DCOP service. - * The service name is equal to the desktopEntryName. - * @li Multi - This service provides a DCOP service which can be run - * with multiple instances in parallel. The service name of - * an instance is equal to the desktopEntryName + "-" + - * the PID of the process. - * @li Wait - This service has no DCOP support, the launcher will wait - * till it is finished. - */ - enum DCOPServiceType_t { DCOP_None = 0, DCOP_Unique, DCOP_Multi, DCOP_Wait }; - - /** - * Returns the DCOPServiceType supported by this service. - * @return the DCOPServiceType supported by this service - */ - DCOPServiceType_t DCOPServiceType() const { return m_DCOPServiceType; } - - /** - * Returns the working directory to run the program in. - * @return the working directory to run the program in, - * or TQString::null if not set - */ - TQString path() const { return m_strPath; } - - /** - * Returns the descriptive comment for the service, if there is one. - * @return the descriptive comment for the service, or TQString::null - * if not set - */ - TQString comment() const { return m_strComment; } - - /** - * Returns the generic name for the service, if there is one - * (e.g. "Mail Client"). - * @return the generic name, - * or TQString::null if not set - */ - TQString genericName() const { return m_strGenName; } - - /** - * Returns the untranslated (US English) generic name - * for the service, if there is one - * (e.g. "Mail Client"). - * @return the generic name, - * or TQString::null if not set - * @since 3.2 - */ - TQString untranslatedGenericName() const; - - /** - * Returns a list of descriptive keywords the service, if there are any. - * @return the list of keywords - */ - TQStringList keywords() const { return m_lstKeywords; } - - /** - * Returns a list of VFolder categories. - * @return the list of VFolder categories - * @since 3.1 - */ - TQStringList categories() const; - - /** - * Returns the service types that this service supports. - * @return the list of service types that are supported - */ - TQStringList serviceTypes() const { return m_lstServiceTypes; } - - /** - * Checks whether the service supports this service type - * @param _service The name of the service type you are - * interested in determining whether this services supports. - * - * @return true if the service you specified is supported, - * otherwise false. - */ - bool hasServiceType( const TQString& _service ) const; - - /** - * Set to true if it is allowed to use this service as the default (main) - * action for the files it supports (e.g. Left Click in a file manager, or KRun in general). - * - * If not, then this service is only available in RMB popups, so it must - * be selected explicitely by the user in order to be used. - * Note that servicemenus supersede this functionality though, at least in konqueror. - * - * @return true if the service may be used as the default (main) handler - */ - bool allowAsDefault() const { return m_bAllowAsDefault; } - - /** - * Checks whether this service can handle several files as - * startup arguments. - * @return true if multiple files may be passed to this service at - * startup. False if only one file at a time may be passed. - */ - bool allowMultipleFiles() const; - - /** - * What preference to associate with this service initially (before - * the user has had any chance to define a profile for it). - * The bigger the value, the most preferred the service is. - * @return the service preference level of the service - */ - int initialPreference() const { return m_initialPreference; } - - /** - * What preference to associate with this service initially - * for handling the specified mimetype. (before the user has - * had any chance to define a profile for it). - * The bigger the value, the most preferred the service is. - * @return the service preference level of the service for - * this mimetype - */ - int initialPreferenceForMimeType( const TQString& mimeType ) const; - - /** - * @internal. Allows KServiceType::offers to tweak the initial preference. - */ - void setInitialPreference( int i ) { m_initialPreference = i; } - - /** - * Whether the entry should be suppressed in menus. - * @return true to suppress this service - */ - bool noDisplay() const; - /** - * check if the application entry is important - */ - bool SuSEunimportant() const; - - /** - * Name of the application this service belongs to. - * (Useful for e.g. plugins) - * @return the parent application, or TQString::null if not set - * @since 3.1 - */ - TQString parentApp() const; - - /** - * Returns the requested property. Some often used properties - * have convenience access functions like exec(), - * serviceTypes etc. - * - * It depends upon the serviceTypes() of this service which - * properties a service can have. - * - * @param _name the name of the property - * @return the property, or invalid if not found - * @see KServiceType - */ - virtual TQVariant property( const TQString& _name ) const; - - /** - * Returns the requested property. - * - * @param _name the name of the property - * @param t the assumed type of the property - * @return the property, or invalid if not found - * @see KServiceType - * @since 3.2 - */ - TQVariant property( const TQString& _name, TQVariant::Type t ) const; - - /** - * Returns the list of all properties that this service can have. - * That means, that some of these properties may be empty. - * @return the list of supported properties - */ - virtual TQStringList propertyNames() const; - - /** - * Checks whether the service is valid. - * @return true if the service is valid (e.g. name is not empty) - */ - bool isValid() const { return m_bValid; } - - /** - * Returns a path that can be used for saving changes to this - * service - * @return path that can be used for saving changes to this service - * @since 3.2 - */ - TQString locateLocal(); - - /** - * @internal - * Load the service from a stream. - */ - virtual void load( TQDataStream& ); - /** - * @internal - * Save the service to a stream. - */ - virtual void save( TQDataStream& ); - /** - * @internal - * Set the menu id - */ - void setMenuId(const TQString &menuId); - /** - * @internal - * Sets whether to use a terminal or not - */ - void setTerminal(bool b) { m_bTerminal = b; } - /** - * @internal - * Sets the terminal options to use - */ - void setTerminalOptions(const TQString &options) { m_strTerminalOptions = options; } - - /** - * Find a service by name, i.e. the translated Name field. You should - * really not use this method, since the name is translated. - * - * @param _name the name to search - * @return a pointer to the requested service or 0 if the service is - * unknown. - * @em Very @em important: Don't store the result in a KService* ! - */ - static Ptr serviceByName( const TQString& _name ); - - /** - * Find a service based on its path as returned by desktopEntryPath(). - * It's usually better to use serviceByStorageId() instead. - * - * @param _path the path of the configuration file - * @return a pointer to the requested service or 0 if the service is - * unknown. - * @em Very @em important: Don't store the result in a KService* ! - */ - static Ptr serviceByDesktopPath( const TQString& _path ); - - /** - * Find a service by the name of its desktop file, not depending on - * its actual location (as long as it's under the applnk or service - * directories). For instance "konqbrowser" or "kcookiejar". Note that - * the ".desktop" extension is implicit. - * - * This is the recommended method (safe even if the user moves stuff) - * but note that it assumes that no two entries have the same filename. - * - * @param _name the name of the configuration file - * @return a pointer to the requested service or 0 if the service is - * unknown. - * @em Very @em important: Don't store the result in a KService* ! - */ - static Ptr serviceByDesktopName( const TQString& _name ); - - /** - * Find a service by its menu-id - * - * @param _menuId the menu id of the service - * @return a pointer to the requested service or 0 if the service is - * unknown. - * @em Very @em important: Don't store the result in a KService* ! - * @since 3.2 - */ - static Ptr serviceByMenuId( const TQString& _menuId ); - - /** - * Find a service by its storage-id or desktop-file path. This - * function will try very hard to find a matching service. - * - * @param _storageId the storage id or desktop-file path of the service - * @return a pointer to the requested service or 0 if the service is - * unknown. - * @em Very @em important: Don't store the result in a KService* ! - * @since 3.2 - */ - static Ptr serviceByStorageId( const TQString& _storageId ); - - /** - * Returns the whole list of services. - * - * Useful for being able to - * to display them in a list box, for example. - * More memory consuming than the ones above, don't use unless - * really necessary. - * @return the list of all services - */ - static List allServices(); - - /** - * Returns all services that require initialisation. - * - * Only needed by "kcminit" - * @return the list of all services that need to be initialized - */ - static List allInitServices(); - - /** - * Returns a path that can be used to create a new KService based - * on @p suggestedName. - * @param showInMenu true, if the service should be shown in the TDE menu - * false, if the service should be hidden from the menu - * @param suggestedName name to base the file on, if a service with such - * name already exists, a prefix will be added to make it unique. - * @param menuId If provided, menuId will be set to the menu id to use for - * the KService - * @param reservedMenuIds If provided, the path and menu id will be chosen - * in such a way that the new menu id does not conflict with any - * of the reservedMenuIds - * @return The path to use for the new KService. - * @since 3.2 - */ - static TQString newServicePath(bool showInMenu, const TQString &suggestedName, - TQString *menuId = 0, - const TQStringList *reservedMenuIds = 0); - - - /** - * Rebuild KSycoca and show a progress dialog while doing so. - * @param parent Parent widget for the progress dialog - * @since 3.2 - */ - static void rebuildKSycoca(TQWidget *parent); - -protected: - - void init(KDesktopFile *config); - - TQStringList &accessServiceTypes() { return m_lstServiceTypes; } - - -private: - KService( const KService& ); // forbidden - KService& operator=(const KService&); - - TQString m_strType; - TQString m_strName; - TQString m_strExec; - TQString m_strIcon; - TQString m_strTerminalOptions; - TQString m_strPath; - TQString m_strComment; - TQString m_strLibrary; - TQStringList m_lstServiceTypes; - bool m_bAllowAsDefault; - int m_initialPreference; - bool m_bTerminal; - //bool m_bSuid; - //TQString m_strUsername; - TQString m_strDesktopEntryName; - //TQString m_docPath; - //bool m_bHideFromPanel; - DCOPServiceType_t m_DCOPServiceType; - TQMap<TQString,TQVariant> m_mapProps; - bool m_bValid; - TQStringList m_lstKeywords; - TQString m_strInit; - TQString m_strGenName; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KServicePrivate; - KServicePrivate* d; -}; -#endif diff --git a/kio/kio/kservice_p.h b/kio/kio/kservice_p.h deleted file mode 100644 index 180ab8fc3..000000000 --- a/kio/kio/kservice_p.h +++ /dev/null @@ -1,41 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2003 Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kservices_p_h__ -#define __kservices_p_h__ - -#include <tqtimer.h> - -#include <kprogress.h> - -class KServiceProgressDialog : public KProgressDialog -{ - Q_OBJECT -public: - KServiceProgressDialog(TQWidget *parent, const char *name, - const TQString &caption, const TQString &text); -public slots: - void slotProgress(); - void slotFinished(); - -private: - TQTimer m_timer; - int m_timeStep; -}; - -#endif diff --git a/kio/kio/kservicefactory.cpp b/kio/kio/kservicefactory.cpp deleted file mode 100644 index f4646fa75..000000000 --- a/kio/kio/kservicefactory.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 1999 David Faure <faure@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation; - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include "kservicefactory.h" -#include "tdesycoca.h" -#include "tdesycocatype.h" -#include "tdesycocadict.h" -#include "kservice.h" - -#include <tqstring.h> - -#include <klocale.h> -#include <kdebug.h> -#include <kglobal.h> -#include <kstandarddirs.h> -#include <kstaticdeleter.h> - -KServiceFactory::KServiceFactory() - : KSycocaFactory( KST_KServiceFactory ) -{ - m_offerListOffset = 0; - m_nameDictOffset = 0; - m_relNameDictOffset = 0; - m_menuIdDictOffset = 0; - if (m_str) - { - // Read Header - TQ_INT32 i; - (*m_str) >> i; - m_nameDictOffset = i; - (*m_str) >> i; - m_relNameDictOffset = i; - (*m_str) >> i; - m_offerListOffset = i; - (*m_str) >> i; - m_initListOffset = i; - (*m_str) >> i; - m_menuIdDictOffset = i; - - int saveOffset = m_str->device()->at(); - // Init index tables - m_nameDict = new KSycocaDict(m_str, m_nameDictOffset); - // Init index tables - m_relNameDict = new KSycocaDict(m_str, m_relNameDictOffset); - // Init index tables - m_menuIdDict = new KSycocaDict(m_str, m_menuIdDictOffset); - saveOffset = m_str->device()->at(saveOffset); - } - else - { - // Build new database - m_nameDict = new KSycocaDict(); - m_relNameDict = new KSycocaDict(); - m_menuIdDict = new KSycocaDict(); - } - _self = this; -} - -KServiceFactory::~KServiceFactory() -{ - _self = 0L; - delete m_nameDict; - delete m_relNameDict; - delete m_menuIdDict; -} - -KServiceFactory * KServiceFactory::self() -{ - if (!_self) { - _self = new KServiceFactory(); - } - return _self; -} - -KService * KServiceFactory::findServiceByName(const TQString &_name) -{ - if (!m_sycocaDict) return 0; // Error! - - // Warning : this assumes we're NOT building a database - // But since findServiceByName isn't called in that case... - // [ see KServiceTypeFactory for how to do it if needed ] - - int offset = m_sycocaDict->find_string( _name ); - if (!offset) return 0; // Not found - - KService * newService = createEntry(offset); - - // Check whether the dictionary was right. - if (newService && (newService->name() != _name)) - { - // No it wasn't... - delete newService; - newService = 0; // Not found - } - return newService; -} - -KService * KServiceFactory::findServiceByDesktopName(const TQString &_name) -{ - if (!m_nameDict) return 0; // Error! - - // Warning : this assumes we're NOT building a database - // But since findServiceByName isn't called in that case... - // [ see KServiceTypeFactory for how to do it if needed ] - - int offset = m_nameDict->find_string( _name ); - if (!offset) return 0; // Not found - - KService * newService = createEntry(offset); - - // Check whether the dictionary was right. - if (newService && (newService->desktopEntryName() != _name)) - { - // No it wasn't... - delete newService; - newService = 0; // Not found - } - return newService; -} - -KService * KServiceFactory::findServiceByDesktopPath(const TQString &_name) -{ - if (!m_relNameDict) return 0; // Error! - - // Warning : this assumes we're NOT building a database - // But since findServiceByName isn't called in that case... - // [ see KServiceTypeFactory for how to do it if needed ] - - int offset = m_relNameDict->find_string( _name ); - if (!offset) return 0; // Not found - - KService * newService = createEntry(offset); - - // Check whether the dictionary was right. - if (newService && (newService->desktopEntryPath() != _name)) - { - // No it wasn't... - delete newService; - newService = 0; // Not found - } - return newService; -} - -KService * KServiceFactory::findServiceByMenuId(const TQString &_menuId) -{ - if (!m_menuIdDict) return 0; // Error! - - // Warning : this assumes we're NOT building a database - // But since findServiceByMenuId isn't called in that case... - // [ see KServiceTypeFactory for how to do it if needed ] - - int offset = m_menuIdDict->find_string( _menuId ); - if (!offset) return 0; // Not found - - KService * newService = createEntry(offset); - - // Check whether the dictionary was right. - if (newService && (newService->menuId() != _menuId)) - { - // No it wasn't... - delete newService; - newService = 0; // Not found - } - return newService; -} - -KService* KServiceFactory::createEntry(int offset) -{ - KService * newEntry = 0L; - KSycocaType type; - TQDataStream *str = KSycoca::self()->findEntry(offset, type); - switch(type) - { - case KST_KService: - newEntry = new KService(*str, offset); - break; - - default: - kdError(7011) << TQString(TQString("KServiceFactory: unexpected object entry in KSycoca database (type = %1)").arg((int)type)) << endl; - return 0; - } - if (!newEntry->isValid()) - { - kdError(7011) << "KServiceFactory: corrupt object in KSycoca database!\n" << endl; - delete newEntry; - newEntry = 0; - } - return newEntry; -} - -KService::List KServiceFactory::allServices() -{ - KService::List result; - KSycocaEntry::List list = allEntries(); - for( KSycocaEntry::List::Iterator it = list.begin(); - it != list.end(); - ++it) - { - KService *newService = dynamic_cast<KService *>((*it).data()); - if (newService) - result.append( KService::Ptr( newService ) ); - } - return result; -} - -KService::List KServiceFactory::allInitServices() -{ - KService::List list; - if (!m_str) return list; - - // Assume we're NOT building a database - - m_str->device()->at(m_initListOffset); - TQ_INT32 entryCount; - (*m_str) >> entryCount; - - TQ_INT32 *offsetList = new TQ_INT32[entryCount]; - for(int i = 0; i < entryCount; i++) - { - (*m_str) >> offsetList[i]; - } - - for(int i = 0; i < entryCount; i++) - { - KService *newEntry = createEntry(offsetList[i]); - if (newEntry) - { - list.append( KService::Ptr( newEntry ) ); - } - } - delete [] offsetList; - return list; -} - -KService::List KServiceFactory::offers( int serviceTypeOffset ) -{ - KService::List list; - - TQDataStream *str = m_str; - // Jump to the offer list - str->device()->at( m_offerListOffset ); - - TQ_INT32 aServiceTypeOffset; - TQ_INT32 aServiceOffset; - // We might want to do a binary search instead of a linear search - // since servicetype offsets are sorted. Bah. - while (true) - { - (*str) >> aServiceTypeOffset; - if ( aServiceTypeOffset ) - { - (*str) >> aServiceOffset; - if ( aServiceTypeOffset == serviceTypeOffset ) - { - // Save stream position ! - int savedPos = str->device()->at(); - // Create Service - KService * serv = createEntry( aServiceOffset ); - if (serv) - list.append( KService::Ptr( serv ) ); - // Restore position - str->device()->at( savedPos ); - } else if ( aServiceTypeOffset > (TQ_INT32)serviceTypeOffset ) - break; // too far - } - else - break; // 0 => end of list - } - return list; -} - -KServiceFactory *KServiceFactory::_self = 0; - -void KServiceFactory::virtual_hook( int id, void* data ) -{ KSycocaFactory::virtual_hook( id, data ); } - diff --git a/kio/kio/kservicefactory.h b/kio/kio/kservicefactory.h deleted file mode 100644 index 4e6df6534..000000000 --- a/kio/kio/kservicefactory.h +++ /dev/null @@ -1,113 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kservicefactory_h__ -#define __kservicefactory_h__ - -#include <tqstringlist.h> - -#include "kservice.h" -#include "tdesycocafactory.h" -#include <assert.h> - -class KSycoca; -class KSycocaDict; - -/** - * @internal - * A sycoca factory for services (e.g. applications) - * It loads the services from parsing directories (e.g. applnk/) - * but can also create service from data streams or single config files - */ -class TDEIO_EXPORT KServiceFactory : public KSycocaFactory -{ - K_SYCOCAFACTORY( KST_KServiceFactory ) -public: - /** - * Create factory - */ - KServiceFactory(); - virtual ~KServiceFactory(); - - /** - * Construct a KService from a config file. - */ - virtual KSycocaEntry *createEntry(const TQString &, const char *) - { assert(0); return 0; } - - /** - * Find a service (by name, e.g. "Terminal") - */ - KService * findServiceByName( const TQString &_name ); - - /** - * Find a service (by desktop file name, e.g. "konsole") - */ - KService * findServiceByDesktopName( const TQString &_name ); - - /** - * Find a service ( by desktop path, e.g. "System/konsole.desktop") - */ - KService * findServiceByDesktopPath( const TQString &_name ); - - /** - * Find a service ( by menu id, e.g. "tde-konsole.desktop") - */ - KService * findServiceByMenuId( const TQString &_menuId ); - - /** - * @return the services supporting the given service type - */ - KService::List offers( int serviceTypeOffset ); - - /** - * @return all services. Very memory consuming, avoid using. - */ - KService::List allServices(); - - /** - * @return all services which have a "X-TDE-Init" line. - */ - KService::List allInitServices(); - - /** - * @return the unique service factory, creating it if necessary - */ - static KServiceFactory * self(); - -protected: - virtual KService * createEntry(int offset); - int m_offerListOffset; - int m_initListOffset; - KSycocaDict *m_nameDict; - int m_nameDictOffset; - KSycocaDict *m_relNameDict; - int m_relNameDictOffset; - KSycocaDict *m_menuIdDict; - int m_menuIdDictOffset; - -private: - static KServiceFactory *_self; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KServiceFactoryPrivate* d; -}; - -#endif diff --git a/kio/kio/kservicegroup.cpp b/kio/kio/kservicegroup.cpp deleted file mode 100644 index 2e27c99b0..000000000 --- a/kio/kio/kservicegroup.cpp +++ /dev/null @@ -1,724 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 2000 Waldo Bastian <bastian@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation; - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include <tqdir.h> - -#include <kiconloader.h> -#include <kglobal.h> -#include <kstandarddirs.h> -#include <klocale.h> -#include <kdebug.h> -#include <ksortablevaluelist.h> - -#include "kservicefactory.h" -#include "kservicegroupfactory.h" -#include "kservicegroup.h" -#include "kservice.h" -#include "tdesycoca.h" - -class KServiceGroup::Private -{ -public: - Private() { m_bNoDisplay = false; m_bShowEmptyMenu = false;m_bShowInlineHeader=false;m_bInlineAlias=false; m_bAllowInline = false; m_inlineValue = 4; m_bShortMenu = false; m_bGeneralDescription = false;} - bool m_bNoDisplay; - bool m_bShortMenu; - bool m_bGeneralDescription; - bool m_bShowEmptyMenu; - bool m_bShowInlineHeader; - bool m_bInlineAlias; - bool m_bAllowInline; - int m_inlineValue; - TQStringList suppressGenericNames; - TQString directoryEntryPath; - TQStringList sortOrder; -}; - -KServiceGroup::KServiceGroup( const TQString & name ) - : KSycocaEntry(name), m_childCount(-1) -{ - d = new KServiceGroup::Private; - m_bDeleted = false; - m_bDeep = false; -} - -KServiceGroup::KServiceGroup( const TQString &configFile, const TQString & _relpath ) - : KSycocaEntry(_relpath), m_childCount(-1) -{ - d = new KServiceGroup::Private; - m_bDeleted = false; - m_bDeep = false; - - TQString cfg = configFile; - if (cfg.isEmpty()) - cfg = _relpath+".directory"; - - d->directoryEntryPath = cfg; - - KDesktopFile config( cfg, true, "apps" ); - - m_strCaption = config.readName(); - m_strIcon = config.readIcon(); - m_strComment = config.readComment(); - m_bDeleted = config.readBoolEntry( "Hidden", false ); - d->m_bNoDisplay = config.readBoolEntry( "NoDisplay", false ); - if (d->directoryEntryPath.startsWith(TQDir::homeDirPath())) - d->m_bShortMenu = false; - else - d->m_bShortMenu = config.readBoolEntry( "X-SuSE-AutoShortMenu", false ); - d->m_bGeneralDescription = config.readBoolEntry( "X-SuSE-GeneralDescription", false ); - TQStringList tmpList; - if (config.hasKey("OnlyShowIn")) - { - if ((!config.readListEntry("OnlyShowIn", ';').contains("TDE")) && (!config.readListEntry("OnlyShowIn", ';').contains("KDE"))) - d->m_bNoDisplay = true; - } - if (config.hasKey("NotShowIn")) - { - if ((config.readListEntry("NotShowIn", ';').contains("TDE")) || (config.readListEntry("NotShowIn", ';').contains("KDE"))) - d->m_bNoDisplay = true; - } - - m_strBaseGroupName = config.readEntry( "X-TDE-BaseGroup" ); - d->suppressGenericNames = config.readListEntry( "X-TDE-SuppressGenericNames" ); - d->sortOrder = config.readListEntry("SortOrder"); - - // Fill in defaults. - if (m_strCaption.isEmpty()) - { - m_strCaption = _relpath; - if (m_strCaption.right(1) == "/") - m_strCaption = m_strCaption.left(m_strCaption.length()-1); - int i = m_strCaption.findRev('/'); - if (i > 0) - m_strCaption = m_strCaption.mid(i+1); - } - if (m_strIcon.isEmpty()) - m_strIcon = "folder"; -} - -KServiceGroup::KServiceGroup( TQDataStream& _str, int offset, bool deep ) : - KSycocaEntry( _str, offset ) -{ - d = new KServiceGroup::Private; - m_bDeep = deep; - load( _str ); -} - -KServiceGroup::~KServiceGroup() -{ - delete d; -} - -int KServiceGroup::childCount() -{ - if (m_childCount == -1) - { - TDEConfig global("kdeglobals"); - global.setGroup("KDE"); - bool showUnimportant = global.readBoolEntry("showUnimportant", true); - - m_childCount = 0; - - for( List::ConstIterator it = m_serviceList.begin(); - it != m_serviceList.end(); it++) - { - KSycocaEntry *p = (*it); - if (p->isType(KST_KService)) - { - KService *service = static_cast<KService *>(p); - if (!service->noDisplay()) - if ( showUnimportant || !service->SuSEunimportant() ) - m_childCount++; - } - else if (p->isType(KST_KServiceGroup)) - { - KServiceGroup *serviceGroup = static_cast<KServiceGroup *>(p); - m_childCount += serviceGroup->childCount(); - } - } - } - return m_childCount; -} - - -bool KServiceGroup::showInlineHeader() const -{ - return d->m_bShowInlineHeader; -} - -bool KServiceGroup::showEmptyMenu() const -{ - return d->m_bShowEmptyMenu; -} - -bool KServiceGroup::inlineAlias() const -{ - return d->m_bInlineAlias; -} - -void KServiceGroup::setInlineAlias(bool _b) -{ - d->m_bInlineAlias = _b; -} - -void KServiceGroup::setShowEmptyMenu(bool _b) -{ - d->m_bShowEmptyMenu=_b; -} - -void KServiceGroup::setShowInlineHeader(bool _b) -{ - d->m_bShowInlineHeader=_b; -} - -int KServiceGroup::inlineValue() const -{ - return d->m_inlineValue; -} - -void KServiceGroup::setInlineValue(int _val) -{ - d->m_inlineValue = _val; -} - -bool KServiceGroup::allowInline() const -{ - return d->m_bAllowInline; -} - -void KServiceGroup::setAllowInline(bool _b) -{ - d->m_bAllowInline = _b; -} - -bool KServiceGroup::noDisplay() const -{ - return d->m_bNoDisplay || m_strCaption.startsWith("."); -} - -TQStringList KServiceGroup::suppressGenericNames() const -{ - return d->suppressGenericNames; -} - -bool KServiceGroup::SuSEgeneralDescription() const -{ - return d->m_bGeneralDescription; -} - -bool KServiceGroup::SuSEshortMenu() const -{ - return d->m_bShortMenu; -} - -void KServiceGroup::load( TQDataStream& s ) -{ - TQStringList groupList; - TQ_INT8 noDisplay; - TQ_INT8 _showEmptyMenu; - TQ_INT8 inlineHeader; - TQ_INT8 _inlineAlias; - TQ_INT8 _allowInline; - s >> m_strCaption >> m_strIcon >> - m_strComment >> groupList >> m_strBaseGroupName >> m_childCount >> - noDisplay >> d->suppressGenericNames >> d->directoryEntryPath >> - d->sortOrder >> _showEmptyMenu >> inlineHeader >> _inlineAlias >> - _allowInline >> d->m_bShortMenu >> d->m_bGeneralDescription; - - d->m_bNoDisplay = (noDisplay != 0); - d->m_bShowEmptyMenu = ( _showEmptyMenu != 0 ); - d->m_bShowInlineHeader = ( inlineHeader != 0 ); - d->m_bInlineAlias = ( _inlineAlias != 0 ); - d->m_bAllowInline = ( _allowInline != 0 ); - - if (m_bDeep) - { - for(TQStringList::ConstIterator it = groupList.begin(); - it != groupList.end(); it++) - { - TQString path = *it; - if (path[path.length()-1] == '/') - { - KServiceGroup *serviceGroup; - serviceGroup = KServiceGroupFactory::self()->findGroupByDesktopPath(path, false); - if (serviceGroup) - m_serviceList.append( SPtr(serviceGroup) ); - } - else - { - KService *service; - service = KServiceFactory::self()->findServiceByDesktopPath(path); - if (service) - m_serviceList.append( SPtr(service) ); - } - } - } -} - -void KServiceGroup::addEntry( KSycocaEntry *entry) -{ - m_serviceList.append(entry); -} - -void KServiceGroup::save( TQDataStream& s ) -{ - KSycocaEntry::save( s ); - - TQStringList groupList; - for( List::ConstIterator it = m_serviceList.begin(); - it != m_serviceList.end(); it++) - { - KSycocaEntry *p = (*it); - if (p->isType(KST_KService)) - { - KService *service = static_cast<KService *>(p); - groupList.append( service->desktopEntryPath()); - } - else if (p->isType(KST_KServiceGroup)) - { - KServiceGroup *serviceGroup = static_cast<KServiceGroup *>(p); - groupList.append( serviceGroup->relPath()); - } - else - { - //fprintf(stderr, "KServiceGroup: Unexpected object in list!\n"); - } - } - - (void) childCount(); - - TQ_INT8 noDisplay = d->m_bNoDisplay ? 1 : 0; - TQ_INT8 _showEmptyMenu = d->m_bShowEmptyMenu ? 1 : 0; - TQ_INT8 inlineHeader = d->m_bShowInlineHeader ? 1 : 0; - TQ_INT8 _inlineAlias = d->m_bInlineAlias ? 1 : 0; - TQ_INT8 _allowInline = d->m_bAllowInline ? 1 : 0; - s << m_strCaption << m_strIcon << - m_strComment << groupList << m_strBaseGroupName << m_childCount << - noDisplay << d->suppressGenericNames << d->directoryEntryPath << - d->sortOrder <<_showEmptyMenu <<inlineHeader<<_inlineAlias<<_allowInline << - d->m_bShortMenu << d->m_bGeneralDescription; -} - -KServiceGroup::List -KServiceGroup::entries(bool sort) -{ - return entries(sort, true); -} - -KServiceGroup::List -KServiceGroup::entries(bool sort, bool excludeNoDisplay) -{ - return entries(sort, excludeNoDisplay, false); -} - -static void addItem(KServiceGroup::List &sorted, const KSycocaEntry::Ptr &p, bool &addSeparator) -{ - if (addSeparator && !sorted.isEmpty()) - sorted.append(new KServiceSeparator()); - sorted.append(p); - addSeparator = false; -} - -KServiceGroup::List -KServiceGroup::entries(bool sort, bool excludeNoDisplay, bool allowSeparators, bool sortByGenericName) -{ - return SuSEentries(sort, excludeNoDisplay, allowSeparators, sortByGenericName); -} - -KServiceGroup::List -KServiceGroup::SuSEentries(bool sort, bool excludeNoDisplay, bool allowSeparators, bool sortByGenericName, bool excludeSuSEunimportant) -{ - KServiceGroup *group = this; - - // If the entries haven't been loaded yet, we have to reload ourselves - // together with the entries. We can't only load the entries afterwards - // since the offsets could have been changed if the database has changed. - - if (!m_bDeep) { - - group = - KServiceGroupFactory::self()->findGroupByDesktopPath(relPath(), true); - - if (0 == group) // No guarantee that we still exist! - return List(); - } - - if (!sort) - return group->m_serviceList; - - // Sort the list alphabetically, according to locale. - // Groups come first, then services. - - KSortableValueList<SPtr,TQCString> slist; - KSortableValueList<SPtr,TQCString> glist; - for (List::ConstIterator it(group->m_serviceList.begin()); it != group->m_serviceList.end(); ++it) - { - KSycocaEntry *p = (*it); -// if( !p->isType(KST_KServiceGroup) && !p->isType(KST_KService)) -// continue; - bool noDisplay = p->isType(KST_KServiceGroup) ? - static_cast<KServiceGroup *>(p)->noDisplay() : - static_cast<KService *>(p)->noDisplay(); - if (excludeNoDisplay && noDisplay) - continue; - bool SuSEunimportant = p->isType(KST_KService) && - static_cast<KService *>(p)->SuSEunimportant(); - if (excludeSuSEunimportant && SuSEunimportant) - continue; - - // Choose the right list - KSortableValueList<SPtr,TQCString> & list = p->isType(KST_KServiceGroup) ? glist : slist; - TQString name; - if (p->isType(KST_KServiceGroup)) - name = static_cast<KServiceGroup *>(p)->caption(); - else if (sortByGenericName) - name = static_cast<KService *>(p)->genericName() + " " + p->name(); - else - name = p->name() + " " + static_cast<KService *>(p)->genericName(); - - TQCString key( name.length() * 4 + 1 ); - // strxfrm() crashes on Solaris -#ifndef USE_SOLARIS - // maybe it'd be better to use wcsxfrm() where available - size_t ln = strxfrm( key.data(), name.local8Bit().data(), key.size()); - if( ln != size_t( -1 )) - { - if( ln >= key.size()) - { // didn't fit? - key.resize( ln + 1 ); - if( strxfrm( key.data(), name.local8Bit().data(), key.size()) == size_t( -1 )) - key = name.local8Bit(); - } - } - else -#endif - { - key = name.local8Bit(); - } - list.insert(key,SPtr(*it)); - } - - return group->SuSEsortEntries( slist, glist, excludeNoDisplay, allowSeparators ); -} - -KServiceGroup::List -KServiceGroup::SuSEsortEntries( KSortableValueList<SPtr,TQCString> slist, KSortableValueList<SPtr,TQCString> glist, bool excludeNoDisplay, bool allowSeparators ) -{ - KServiceGroup *group = this; - - // Now sort - slist.sort(); - glist.sort(); - - if (d->sortOrder.isEmpty()) - { - d->sortOrder << ":M"; - d->sortOrder << ":F"; - d->sortOrder << ":OIH IL[4]"; //just inline header - } - - TQString rp = relPath(); - if(rp == "/") rp = TQString::null; - - // Iterate through the sort spec list. - // If an entry gets mentioned explicitly, we remove it from the sorted list - for (TQStringList::ConstIterator it(d->sortOrder.begin()); it != d->sortOrder.end(); ++it) - { - const TQString &item = *it; - if (item.isEmpty()) continue; - if (item[0] == '/') - { - TQString groupPath = rp + item.mid(1) + "/"; - // Remove entry from sorted list of services. - for(KSortableValueList<SPtr,TQCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2) - { - KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)((*it2).value())); - if (group->relPath() == groupPath) - { - glist.remove(it2); - break; - } - } - } - else if (item[0] != ':') - { - // Remove entry from sorted list of services. - // TODO: Remove item from sortOrder-list if not found - // TODO: This prevents duplicates - for(KSortableValueList<SPtr,TQCString>::Iterator it2 = slist.begin(); it2 != slist.end(); ++it2) - { - if (!(*it2).value()->isType(KST_KService)) - continue; - KService *service = (KService *)((KSycocaEntry *)((*it2).value())); - if (service->menuId() == item) - { - slist.remove(it2); - break; - } - } - } - } - - List sorted; - - bool needSeparator = false; - // Iterate through the sort spec list. - // Add the entries to the list according to the sort spec. - for (TQStringList::ConstIterator it(d->sortOrder.begin()); it != d->sortOrder.end(); ++it) - { - const TQString &item = *it; - if (item.isEmpty()) continue; - if (item[0] == ':') - { - // Special condition... - if (item == ":S") - { - if (allowSeparators) - needSeparator = true; - } - else if ( item.contains( ":O" ) ) - { - //todo parse attribute: - TQString tmp( item ); - tmp = tmp.remove(":O"); - TQStringList optionAttribute = TQStringList::split(" ",tmp); - if( optionAttribute.count()==0) - optionAttribute.append(tmp); - bool showEmptyMenu = false; - bool showInline = false; - bool showInlineHeader = false; - bool showInlineAlias = false; - int inlineValue = -1; - - for ( TQStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3 ) - { - parseAttribute( *it3, showEmptyMenu, showInline, showInlineHeader, showInlineAlias, inlineValue ); - } - for(KSortableValueList<SPtr,TQCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2) - { - KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)(*it2).value()); - group->setShowEmptyMenu( showEmptyMenu ); - group->setAllowInline( showInline ); - group->setShowInlineHeader( showInlineHeader ); - group->setInlineAlias( showInlineAlias ); - group->setInlineValue( inlineValue ); - } - - } - else if (item == ":M") - { - // Add sorted list of sub-menus - for(KSortableValueList<SPtr,TQCString>::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2) - { - addItem(sorted, (*it2).value(), needSeparator); - } - } - else if (item == ":F") - { - // Add sorted list of services - for(KSortableValueList<SPtr,TQCString>::Iterator it2 = slist.begin(); it2 != slist.end(); ++it2) - { - addItem(sorted, (*it2).value(), needSeparator); - } - } - else if (item == ":A") - { - // Add sorted lists of services and submenus - KSortableValueList<SPtr,TQCString>::Iterator it_s = slist.begin(); - KSortableValueList<SPtr,TQCString>::Iterator it_g = glist.begin(); - - while(true) - { - if (it_s == slist.end()) - { - if (it_g == glist.end()) - break; // Done - - // Insert remaining sub-menu - addItem(sorted, (*it_g).value(), needSeparator); - it_g++; - } - else if (it_g == glist.end()) - { - // Insert remaining service - addItem(sorted, (*it_s).value(), needSeparator); - it_s++; - } - else if ((*it_g).index() < (*it_s).index()) - { - // Insert sub-menu first - addItem(sorted, (*it_g).value(), needSeparator); - it_g++; - } - else - { - // Insert service first - addItem(sorted, (*it_s).value(), needSeparator); - it_s++; - } - } - } - } - else if (item[0] == '/') - { - TQString groupPath = rp + item.mid(1) + "/"; - - for (List::ConstIterator it2(group->m_serviceList.begin()); it2 != group->m_serviceList.end(); ++it2) - { - if (!(*it2)->isType(KST_KServiceGroup)) - continue; - KServiceGroup *group = (KServiceGroup *)((KSycocaEntry *)(*it2)); - if (group->relPath() == groupPath) - { - if (!excludeNoDisplay || !group->noDisplay()) - { - const TQString &nextItem = *( ++it ); - if ( nextItem.startsWith( ":O" ) ) - { - TQString tmp( nextItem ); - tmp = tmp.remove(":O"); - TQStringList optionAttribute = TQStringList::split(" ",tmp); - if( optionAttribute.count()==0) - optionAttribute.append(tmp); - bool bShowEmptyMenu = false; - bool bShowInline = false; - bool bShowInlineHeader = false; - bool bShowInlineAlias = false; - int inlineValue = -1; - for ( TQStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3 ) - { - parseAttribute( *it3 , bShowEmptyMenu, bShowInline, bShowInlineHeader, bShowInlineAlias , inlineValue ); - group->setShowEmptyMenu( bShowEmptyMenu ); - group->setAllowInline( bShowInline ); - group->setShowInlineHeader( bShowInlineHeader ); - group->setInlineAlias( bShowInlineAlias ); - group->setInlineValue( inlineValue ); - } - } - else - it--; - - addItem(sorted, (group), needSeparator); - } - break; - } - } - } - else - { - for (List::ConstIterator it2(group->m_serviceList.begin()); it2 != group->m_serviceList.end(); ++it2) - { - if (!(*it2)->isType(KST_KService)) - continue; - KService *service = (KService *)((KSycocaEntry *)(*it2)); - if (service->menuId() == item) - { - if (!excludeNoDisplay || !service->noDisplay()) - addItem(sorted, (*it2), needSeparator); - break; - } - } - } - } - - return sorted; -} - -void KServiceGroup::parseAttribute( const TQString &item , bool &showEmptyMenu, bool &showInline, bool &showInlineHeader, bool & showInlineAlias , int &inlineValue ) -{ - if( item == "ME") //menu empty - showEmptyMenu=true; - else if ( item == "NME") //not menu empty - showEmptyMenu=false; - else if( item == "I") //inline menu ! - showInline = true; - else if ( item == "NI") //not inline menu! - showInline = false; - else if( item == "IH") //inline header! - showInlineHeader= true; - else if ( item == "NIH") //not inline header! - showInlineHeader = false; - else if( item == "IA") //inline alias! - showInlineAlias = true; - else if ( item == "NIA") //not inline alias! - showInlineAlias = false; - else if( ( item ).contains( "IL" )) //inline limite! - { - TQString tmp( item ); - tmp = tmp.remove( "IL[" ); - tmp = tmp.remove( "]" ); - bool ok; - int _inlineValue = tmp.toInt(&ok); - if ( !ok ) //error - _inlineValue = -1; - inlineValue = _inlineValue; - } - else - kdDebug()<<" This attribute is not supported :"<<item<<endl; -} - -void KServiceGroup::setLayoutInfo(const TQStringList &layout) -{ - d->sortOrder = layout; -} - -TQStringList KServiceGroup::layoutInfo() const -{ - return d->sortOrder; -} - -KServiceGroup::Ptr -KServiceGroup::baseGroup( const TQString & _baseGroupName ) -{ - return KServiceGroupFactory::self()->findBaseGroup(_baseGroupName, true); -} - -KServiceGroup::Ptr -KServiceGroup::root() -{ - return KServiceGroupFactory::self()->findGroupByDesktopPath("/", true); -} - -KServiceGroup::Ptr -KServiceGroup::group(const TQString &relPath) -{ - if (relPath.isEmpty()) return root(); - return KServiceGroupFactory::self()->findGroupByDesktopPath(relPath, true); -} - -KServiceGroup::Ptr -KServiceGroup::childGroup(const TQString &parent) -{ - return KServiceGroupFactory::self()->findGroupByDesktopPath("#parent#"+parent, true); -} - -TQString -KServiceGroup::directoryEntryPath() const -{ - return d->directoryEntryPath; -} - - -void KServiceGroup::virtual_hook( int id, void* data ) -{ KSycocaEntry::virtual_hook( id, data ); } - - -KServiceSeparator::KServiceSeparator( ) - : KSycocaEntry("separator") -{ -} diff --git a/kio/kio/kservicegroup.h b/kio/kio/kservicegroup.h deleted file mode 100644 index f2cd5a09f..000000000 --- a/kio/kio/kservicegroup.h +++ /dev/null @@ -1,353 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2000 Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kservicegroup_h__ -#define __kservicegroup_h__ - -#include <tqptrlist.h> -#include <tqstring.h> -#include <tqshared.h> -#include <tqdatastream.h> -#include <tqvariant.h> - -#include <kdesktopfile.h> -#include <ksortablevaluelist.h> - -#include "tdesycocaentry.h" -#include "tdesycocatype.h" -#include "kservice.h" - -class KBuildServiceGroupFactory; - -/** - * KServiceGroup represents a group of service, for example - * screensavers. - * This class is typically used like this: - * - * \code - * // Lookup screensaver group - * KServiceGroup::Ptr group = KServiceGroup::baseGroup("screensavers"); - * if (!group || !group->isValid()) return; - * - * KServiceGroup::List list = group->entries(); - * - * // Iterate over all entries in the group - * for( KServiceGroup::List::ConstIterator it = list.begin(); - * it != list.end(); it++) - * { - * KSycocaEntry *p = (*it); - * if (p->isType(KST_KService)) - * { - * KService *s = static_cast<KService *>(p); - * printf("Name = %s\n", s->name().latin1()); - * } - * else if (p->isType(KST_KServiceGroup)) - * { - * KServiceGroup *g = static_cast<KServiceGroup *>(p); - * // Sub group ... - * } - * } - * \endcode - * @short Represents a group of services - */ -class TDEIO_EXPORT KServiceGroup : public KSycocaEntry -{ - friend class KBuildServiceGroupFactory; - K_SYCOCATYPE( KST_KServiceGroup, KSycocaEntry ) - -public: - typedef KSharedPtr<KServiceGroup> Ptr; - typedef KSharedPtr<KSycocaEntry> SPtr; - typedef TQValueList<SPtr> List; -public: - /** - * Construct a dummy servicegroup indexed with @p name. - * @param name the name of the service group - * @since 3.1 - */ - KServiceGroup( const TQString & name ); - - /** - * Construct a service and take all informations from a config file - * @param _fullpath full path to the config file - * @param _relpath relative path to the config file - */ - KServiceGroup( const TQString & _fullpath, const TQString & _relpath ); - - /** - * @internal construct a service from a stream. - * The stream must already be positionned at the correct offset - */ - KServiceGroup( TQDataStream& _str, int offset, bool deep ); - - virtual ~KServiceGroup(); - - /** - * Checks whether the entry is valid, returns always true. - * @return true - */ - bool isValid() const { return true; } - - /** - * Name used for indexing. - * @return the service group's name - */ - virtual TQString name() const { return entryPath(); } - - /** - * Returns the relative path of the service group. - * @return the service group's relative path - */ - virtual TQString relPath() const { return entryPath(); } - - /** - * Returns the caption of this group. - * @return the caption of this group - */ - TQString caption() const { return m_strCaption; } - - /** - * Returns the name of the icon associated with the group. - * @return the name of the icon associated with the group, - * or TQString::null if not set - */ - TQString icon() const { return m_strIcon; } - - /** - * Returns the comment about this service group. - * @return the descriptive comment for the group, if there is one, - * or TQString::null if not set - */ - TQString comment() const { return m_strComment; } - - /** - * Returns the total number of displayable services in this group and - * any of its subgroups. - * @return the number of child services - */ - int childCount(); - - /** - * Returns true if the NoDisplay flag was set, i.e. if this - * group should be hidden from menus, while still being in tdesycoca. - * @return true to hide this service group, false to display it - * @since 3.1 - */ - bool noDisplay() const; - - /** - * Return true if we want to display empty menu entry - * @return true to show this service group as menu entry is empty, false to hide it - * @since 3.4 - */ - bool showEmptyMenu() const; - void setShowEmptyMenu( bool b); - - /** - * @return true to show an inline header into menu - * @since 3.5 - */ - bool showInlineHeader() const; - void setShowInlineHeader(bool _b); - - /** - * @return true to show an inline alias item into menu - * @since 3.5 - */ - bool inlineAlias() const; - void setInlineAlias(bool _b); - /** - * @return true if we allow to inline menu. - * @since 3.5 - */ - bool allowInline() const; - void setAllowInline(bool _b); - - /** - * @return inline limite value - * @since 3.5 - */ - int inlineValue() const; - void setInlineValue(int _val); - - - /** - * Returns a list of untranslated generic names that should be - * be supressed when showing this group. - * E.g. The group "Games/Arcade" might want to suppress the generic name - * "Arcade Game" since it's redundant in this particular context. - * @since 3.2 - */ - TQStringList suppressGenericNames() const; - - /** - * @internal - * Sets information related to the layout of services in this group. - */ - void setLayoutInfo(const TQStringList &layout); - - /** - * Original API and feature kindly provided by SuSE - */ - bool SuSEshortMenu() const; - bool SuSEgeneralDescription() const; - - /** - * @internal - * Returns information related to the layout of services in this group. - */ - TQStringList layoutInfo() const; - - /** - * @internal - * Load the service from a stream. - */ - virtual void load( TQDataStream& ); - /** - * @internal - * Save the service to a stream. - */ - virtual void save( TQDataStream& ); - - /** - * List of all Services and ServiceGroups within this - * ServiceGroup. - * @param sorted true to sort items - * @param excludeNoDisplay true to exclude items marked "NoDisplay" - * @param allowSeparators true to allow separator items to be included - * @param sortByGenericName true to sort GenericName+Name instead of Name+GenericName - * @return the list of entries - * @since 3.2 - */ - List entries(bool sorted, bool excludeNoDisplay, bool allowSeparators, bool sortByGenericName=false); - virtual List entries(bool sorted, bool excludeNoDisplay); - - /** - * List of all Services and ServiceGroups within this - * ServiceGroup. - * @param sorted true to sort items - * @return the list of entried - */ - virtual List entries(bool sorted = false); - - /* - * Original API and feature kindly provided by SuSE - */ - virtual List SuSEentries(bool sort, bool excludeNoDisplay, bool allowSeparators, bool sortByGenericName, bool excludeSuSEunimportant = false); - virtual List SuSEsortEntries( KSortableValueList<SPtr,TQCString> slist, KSortableValueList<SPtr,TQCString> glist, bool excludeNoDisplay, bool allowSeparators ); - - /** - * Returns a non-empty string if the group is a special base group. - * By default, "Settings/" is the kcontrol base group ("settings") - * and "System/Screensavers/" is the screensavers base group ("screensavers"). - * This allows moving the groups without breaking those apps. - * - * The base group is defined by the X-TDE-BaseGroup key - * in the .directory file. - * @return the base group name, or null if no base group - */ - TQString baseGroupName() const { return m_strBaseGroupName; } - - /** - * Returns a path to the .directory file describing this service group. - * The path is either absolute or relative to the "apps" resource. - * @since 3.2 - */ - TQString directoryEntryPath() const; - - /** - * Returns the group for the given baseGroupName. - * Can return 0L if the directory (or the .directory file) was deleted. - * @return the base group with the given name, or 0 if not available. - */ - static Ptr baseGroup( const TQString &baseGroupName ); - - /** - * Returns the root service group. - * @return the root service group - */ - static Ptr root(); - - /** - * Returns the group with the given relative path. - * @param relPath the path of the service group - * @return the group with the given relative path name. - */ - static Ptr group(const TQString &relPath); - - /** - * Returns the group of services that have X-TDE-ParentApp equal - * to @p parent (siblings). - * @param parent the name of the service's parent - * @return the services group - * @since 3.1 - */ - static Ptr childGroup(const TQString &parent); - - /** - * This function parse attributes into menu - * @since 3.5 - */ - void parseAttribute( const TQString &item , bool &showEmptyMenu, bool &showInline, bool &showInlineHeader, bool & showInlineAlias ,int &inlineValue ); - -protected: - /** - * @internal - * Add a service to this group - */ - void addEntry( KSycocaEntry *entry); - - TQString m_strCaption; - TQString m_strIcon; - TQString m_strComment; - - List m_serviceList; - bool m_bDeep; - TQString m_strBaseGroupName; - int m_childCount; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class Private; - Private* d; -}; - -class TDEIO_EXPORT KServiceSeparator : public KSycocaEntry -{ - K_SYCOCATYPE( KST_KServiceSeparator, KSycocaEntry ) - -public: - typedef KSharedPtr<KServiceSeparator> Ptr; -public: - /** - * Construct a service separator - * @since 3.2 - */ - KServiceSeparator(); - - bool isValid() const { return true; } - - // Dummy - virtual TQString name() const { return "separator"; } - // Dummy - virtual void load( TQDataStream& ) { }; - // Dummy - virtual void save( TQDataStream& ) { }; -}; - -#endif diff --git a/kio/kio/kservicegroupfactory.cpp b/kio/kio/kservicegroupfactory.cpp deleted file mode 100644 index 56ec0c07f..000000000 --- a/kio/kio/kservicegroupfactory.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 2000 Waldo Bastian <bastian@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation; - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include "kservicegroupfactory.h" -#include "tdesycoca.h" -#include "tdesycocatype.h" -#include "tdesycocadict.h" -#include "kservice.h" - -#include <tqstring.h> - -#include <klocale.h> -#include <kdebug.h> -#include <kglobal.h> -#include <kstandarddirs.h> - -KServiceGroupFactory::KServiceGroupFactory() - : KSycocaFactory( KST_KServiceGroupFactory ) -{ - m_baseGroupDictOffset = 0; - if (m_str) - { - // Read Header - TQ_INT32 i; - (*m_str) >> i; - m_baseGroupDictOffset = i; - - int saveOffset = m_str->device()->at(); - // Init index tables - m_baseGroupDict = new KSycocaDict(m_str, m_baseGroupDictOffset); - m_str->device()->at(saveOffset); - } - else - { - // Build new database - m_baseGroupDict = new KSycocaDict(); - } - _self = this; -} - -KServiceGroupFactory::~KServiceGroupFactory() -{ - _self = 0L; - delete m_baseGroupDict; -} - -KServiceGroupFactory * KServiceGroupFactory::self() -{ - if (!_self) - _self = new KServiceGroupFactory(); - return _self; -} - -KServiceGroup * KServiceGroupFactory::findGroupByDesktopPath(const TQString &_name, bool deep) -{ - if (!m_sycocaDict) return 0; // Error! - - // Warning : this assumes we're NOT building a database - // But since findServiceByName isn't called in that case... - // [ see KServiceTypeFactory for how to do it if needed ] - - int offset = m_sycocaDict->find_string( _name ); - if (!offset) return 0; // Not found - - KServiceGroup * newGroup = createGroup(offset, deep); - - // Check whether the dictionary was right. - if (newGroup && (newGroup->relPath() != _name)) - { - // No it wasn't... - delete newGroup; - newGroup = 0; // Not found - } - return newGroup; -} - -KServiceGroup * KServiceGroupFactory::findBaseGroup(const TQString &_baseGroupName, bool deep) -{ - if (!m_baseGroupDict) return 0; // Error! - - // Warning : this assumes we're NOT building a database - // But since findServiceByName isn't called in that case... - // [ see KServiceTypeFactory for how to do it if needed ] - - int offset = m_baseGroupDict->find_string( _baseGroupName ); - if (!offset) return 0; // Not found - - KServiceGroup * newGroup = createGroup(offset, deep); - - // Check whether the dictionary was right. - if (newGroup && (newGroup->baseGroupName() != _baseGroupName)) - { - // No it wasn't... - delete newGroup; - newGroup = 0; // Not found - } - return newGroup; -} - -KServiceGroup* KServiceGroupFactory::createGroup(int offset, bool deep) -{ - KServiceGroup * newEntry = 0L; - KSycocaType type; - TQDataStream *str = KSycoca::self()->findEntry(offset, type); - switch(type) - { - case KST_KServiceGroup: - newEntry = new KServiceGroup(*str, offset, deep); - break; - - default: - kdError(7011) << TQString(TQString("KServiceGroupFactory: unexpected object entry in KSycoca database (type = %1)").arg((int)type)) << endl; - return 0; - } - if (!newEntry->isValid()) - { - kdError(7011) << "KServiceGroupFactory: corrupt object in KSycoca database!\n" << endl; - delete newEntry; - newEntry = 0; - } - return newEntry; -} - -KServiceGroup* KServiceGroupFactory::createEntry(int offset) -{ - return createGroup(offset, true); -} - -KServiceGroupFactory *KServiceGroupFactory::_self = 0; - -void KServiceGroupFactory::virtual_hook( int id, void* data ) -{ KSycocaFactory::virtual_hook( id, data ); } - diff --git a/kio/kio/kservicegroupfactory.h b/kio/kio/kservicegroupfactory.h deleted file mode 100644 index 77bc7c042..000000000 --- a/kio/kio/kservicegroupfactory.h +++ /dev/null @@ -1,80 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2000 Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kservicegroupfactory_h__ -#define __kservicegroupfactory_h__ - -#include <tqstringlist.h> - -#include "kservicegroup.h" -#include "tdesycocafactory.h" -#include <assert.h> - -class KSycoca; -class KSycocaDict; - -/** - * @internal - * A sycoca factory for service groups (e.g. list of applications) - * It loads the services from parsing directories (e.g. applnk/) - */ -class TDEIO_EXPORT KServiceGroupFactory : public KSycocaFactory -{ - K_SYCOCAFACTORY( KST_KServiceGroupFactory ) -public: - /** - * Create factory - */ - KServiceGroupFactory(); - virtual ~KServiceGroupFactory(); - - /** - * Construct a KServiceGroup from a config file. - */ - virtual KSycocaEntry *createEntry(const TQString &, const char *) - { assert(0); return 0; } - - /** - * Find a group ( by desktop path, e.g. "Applications/Editors") - */ - KServiceGroup * findGroupByDesktopPath( const TQString &_name, bool deep = true ); - - /** - * Find a base group by name, e.g. "settings" - */ - KServiceGroup * findBaseGroup( const TQString &_baseGroupName, bool deep = true ); - - /** - * @return the unique service group factory, creating it if necessary - */ - static KServiceGroupFactory * self(); -protected: - KServiceGroup* createGroup(int offset, bool deep); - KServiceGroup* createEntry(int offset); - KSycocaDict *m_baseGroupDict; - int m_baseGroupDictOffset; - -private: - static KServiceGroupFactory *_self; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KServiceGroupFactoryPrivate* d; -}; - -#endif diff --git a/kio/kio/kservicetype.cpp b/kio/kio/kservicetype.cpp deleted file mode 100644 index 8565029ee..000000000 --- a/kio/kio/kservicetype.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 1999 Waldo Bastian <bastian@kde.org> - * David Faure <faure@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation; - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include "kservice.h" -#include "tdesycoca.h" -#include "kservicetype.h" -#include "kservicetypefactory.h" -#include "kservicefactory.h" -#include "kuserprofile.h" -#include <assert.h> -#include <kdebug.h> -#include <kdesktopfile.h> - -template TQDataStream& operator>> <TQString, TQVariant>(TQDataStream&, TQMap<TQString, TQVariant>&); -template TQDataStream& operator<< <TQString, TQVariant>(TQDataStream&, const TQMap<TQString, TQVariant>&); - -class KServiceType::KServiceTypePrivate -{ -public: - KServiceTypePrivate() : parentTypeLoaded(false) { } - - KServiceType::Ptr parentType; - KService::List services; - bool parentTypeLoaded; -}; - -KServiceType::KServiceType( const TQString & _fullpath) - : KSycocaEntry(_fullpath), d(0) -{ - KDesktopFile config( _fullpath ); - - init(&config); -} - -KServiceType::KServiceType( KDesktopFile *config ) - : KSycocaEntry(config->fileName()), d(0) -{ - init(config); -} - -void -KServiceType::init( KDesktopFile *config) -{ - // Is it a mimetype ? - m_strName = config->readEntry( "MimeType" ); - - // Or is it a servicetype ? - if ( m_strName.isEmpty() ) - { - m_strName = config->readEntry( "X-TDE-ServiceType" ); - } - - m_strComment = config->readComment(); - m_bDeleted = config->readBoolEntry( "Hidden", false ); - m_strIcon = config->readIcon(); - - // We store this as property to preserve BC, we can't change that - // because KSycoca needs to remain BC between KDE 2.x and KDE 3.x - TQString sDerived = config->readEntry( "X-TDE-Derived" ); - m_bDerived = !sDerived.isEmpty(); - if ( m_bDerived ) - m_mapProps.insert( "X-TDE-Derived", sDerived ); - - TQStringList tmpList = config->groupList(); - TQStringList::Iterator gIt = tmpList.begin(); - - for( ; gIt != tmpList.end(); ++gIt ) - { - if ( (*gIt).find( "Property::" ) == 0 ) - { - config->setGroup( *gIt ); - TQVariant v = config->readPropertyEntry( "Value", - TQVariant::nameToType( config->readEntry( "Type" ).ascii() ) ); - if ( v.isValid() ) - m_mapProps.insert( (*gIt).mid( 10 ), v ); - } - } - - gIt = tmpList.begin(); - for( ; gIt != tmpList.end(); ++gIt ) - { - if( (*gIt).find( "PropertyDef::" ) == 0 ) - { - config->setGroup( *gIt ); - m_mapPropDefs.insert( (*gIt).mid( 13 ), - TQVariant::nameToType( config->readEntry( "Type" ).ascii() ) ); - } - } - - m_bValid = !m_strName.isEmpty(); -} - -KServiceType::KServiceType( const TQString & _fullpath, const TQString& _type, - const TQString& _icon, const TQString& _comment ) - : KSycocaEntry(_fullpath), d(0) -{ - m_strName = _type; - m_strIcon = _icon; - m_strComment = _comment; - m_bValid = !m_strName.isEmpty(); -} - -KServiceType::KServiceType( TQDataStream& _str, int offset ) - : KSycocaEntry( _str, offset ), d(0) -{ - load( _str); -} - -void -KServiceType::load( TQDataStream& _str ) -{ - TQ_INT8 b; - _str >> m_strName >> m_strIcon >> m_strComment >> m_mapProps >> m_mapPropDefs - >> b; - m_bValid = b; - m_bDerived = m_mapProps.contains("X-TDE-Derived"); -} - -void -KServiceType::save( TQDataStream& _str ) -{ - KSycocaEntry::save( _str ); - // !! This data structure should remain binary compatible at all times !! - // You may add new fields at the end. Make sure to update the version - // number in tdesycoca.h - _str << m_strName << m_strIcon << m_strComment << m_mapProps << m_mapPropDefs - << (TQ_INT8)m_bValid; -} - -KServiceType::~KServiceType() -{ - delete d; -} - -TQString KServiceType::parentServiceType() const -{ - TQVariant v = property("X-TDE-Derived"); - return v.toString(); -} - -bool KServiceType::inherits( const TQString& servTypeName ) const -{ - if ( name() == servTypeName ) - return true; - TQString st = parentServiceType(); - while ( !st.isEmpty() ) - { - KServiceType::Ptr ptr = KServiceType::serviceType( st ); - if (!ptr) return false; //error - if ( ptr->name() == servTypeName ) - return true; - st = ptr->parentServiceType(); - } - return false; -} - -TQVariant -KServiceType::property( const TQString& _name ) const -{ - TQVariant v; - - if ( _name == "Name" ) - v = TQVariant( m_strName ); - else if ( _name == "Icon" ) - v = TQVariant( m_strIcon ); - else if ( _name == "Comment" ) - v = TQVariant( m_strComment ); - else { - TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.find( _name ); - if ( it != m_mapProps.end() ) - v = it.data(); - } - - return v; -} - -TQStringList -KServiceType::propertyNames() const -{ - TQStringList res; - - TQMap<TQString,TQVariant>::ConstIterator it = m_mapProps.begin(); - for( ; it != m_mapProps.end(); ++it ) - res.append( it.key() ); - - res.append( "Name" ); - res.append( "Comment" ); - res.append( "Icon" ); - - return res; -} - -TQVariant::Type -KServiceType::propertyDef( const TQString& _name ) const -{ - TQMap<TQString,TQVariant::Type>::ConstIterator it = m_mapPropDefs.find( _name ); - if ( it == m_mapPropDefs.end() ) - return TQVariant::Invalid; - return it.data(); -} - -TQStringList -KServiceType::propertyDefNames() const -{ - TQStringList l; - - TQMap<TQString,TQVariant::Type>::ConstIterator it = m_mapPropDefs.begin(); - for( ; it != m_mapPropDefs.end(); ++it ) - l.append( it.key() ); - - return l; -} - -KServiceType::Ptr KServiceType::serviceType( const TQString& _name ) -{ - KServiceType * p = KServiceTypeFactory::self()->findServiceTypeByName( _name ); - return KServiceType::Ptr( p ); -} - -static void addUnique(KService::List &lst, TQDict<KService> &dict, const KService::List &newLst, bool lowPrio) -{ - TQValueListConstIterator<KService::Ptr> it = newLst.begin(); - for( ; it != newLst.end(); ++it ) - { - KService *service = static_cast<KService*>(*it); - if (dict.find(service->desktopEntryPath())) - continue; - dict.insert(service->desktopEntryPath(), service); - lst.append(service); - if (lowPrio) - service->setInitialPreference( 0 ); - } -} - -KService::List KServiceType::offers( const TQString& _servicetype ) -{ - TQDict<KService> dict(53); - KService::List lst; - - // Services associated directly with this servicetype (the normal case) - KServiceType::Ptr serv = KServiceTypeFactory::self()->findServiceTypeByName( _servicetype ); - if ( serv ) - addUnique(lst, dict, KServiceFactory::self()->offers( serv->offset() ), false); - else - kdWarning(7009) << "KServiceType::offers : servicetype " << _servicetype << " not found" << endl; - - // Find services associated with any mimetype parents. e.g. text/x-java -> text/plain - KMimeType::Ptr mime = dynamic_cast<KMimeType*>(static_cast<KServiceType *>(serv)); - bool isAMimeType = (mime != 0); - if (mime) - { - while(true) - { - TQString parent = mime->parentMimeType(); - if (parent.isEmpty()) - break; - mime = dynamic_cast<KMimeType *>(KServiceTypeFactory::self()->findServiceTypeByName( parent )); - if (!mime) - break; - - addUnique(lst, dict, KServiceFactory::self()->offers( mime->offset() ), false); - } - } - serv = mime = 0; - - //TQValueListIterator<KService::Ptr> it = lst.begin(); - //for( ; it != lst.end(); ++it ) - // kdDebug() << (*it).data() << " " << (*it)->name() << endl; - - // Support for all/* is deactivated by KServiceTypeProfile::configurationMode() - // (and makes no sense when querying for an "all" servicetype itself - // nor for non-mimetypes service types) - if ( !KServiceTypeProfile::configurationMode() - && isAMimeType - && _servicetype.left(4) != "all/" ) - { - // Support for services associated with "all" - KServiceType * servAll = KServiceTypeFactory::self()->findServiceTypeByName( "all/all" ); - if ( servAll ) - { - addUnique(lst, dict, KServiceFactory::self()->offers( servAll->offset() ), true); - } - else - kdWarning(7009) << "KServiceType::offers : servicetype all/all not found" << endl; - delete servAll; - - // Support for services associated with "allfiles" - if ( _servicetype != "inode/directory" && _servicetype != "inode/directory-locked" ) - { - KServiceType * servAllFiles = KServiceTypeFactory::self()->findServiceTypeByName( "all/allfiles" ); - if ( servAllFiles ) - { - addUnique(lst, dict, KServiceFactory::self()->offers( servAllFiles->offset() ), true); - } - else - kdWarning(7009) << "KServiceType::offers : servicetype all/allfiles not found" << endl; - delete servAllFiles; - } - } - - return lst; -} - -KServiceType::List KServiceType::allServiceTypes() -{ - return KServiceTypeFactory::self()->allServiceTypes(); -} - -KServiceType::Ptr KServiceType::parentType() -{ - if (d && d->parentTypeLoaded) - return d->parentType; - - if (!d) - d = new KServiceTypePrivate; - - TQString parentSt = parentServiceType(); - if (!parentSt.isEmpty()) - { - d->parentType = KServiceTypeFactory::self()->findServiceTypeByName( parentSt ); - if (!d->parentType) - kdWarning(7009) << "'" << desktopEntryPath() << "' specifies undefined mimetype/servicetype '"<< parentSt << "'" << endl; - } - - d->parentTypeLoaded = true; - - return d->parentType; -} - -void KServiceType::addService(KService::Ptr service) -{ - if (!d) - d = new KServiceTypePrivate; - - if (d->services.count() && d->services.last() == service) - return; - - d->services.append(service); -} - -KService::List KServiceType::services() -{ - if (d) - return d->services; - - return KService::List(); -} - -void KServiceType::virtual_hook( int id, void* data ) -{ KSycocaEntry::virtual_hook( id, data ); } diff --git a/kio/kio/kservicetype.h b/kio/kio/kservicetype.h deleted file mode 100644 index b1cad7284..000000000 --- a/kio/kio/kservicetype.h +++ /dev/null @@ -1,251 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - 1999 Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kservicetype_h__ -#define __kservicetype_h__ - -#include "tdesycocaentry.h" -#include "kservice.h" - -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqptrlist.h> -#include <tqmap.h> -#include <tqshared.h> -#include <tqdatastream.h> -#include <tqvariant.h> - -#include <ksimpleconfig.h> - -/** - * A service type is the generic notion for a mimetype, a type of service - * instead of a type of file. - * For instance, KOfficeFilter is a service type. - * It is associated to services according to the user profile (kuserprofile.h). - * Service types are stored as desktop files in $TDEHOME/share/servicetypes. - * @see KService - */ -class TDEIO_EXPORT KServiceType : public KSycocaEntry -{ - K_SYCOCATYPE( KST_KServiceType, KSycocaEntry ) - -public: - typedef KSharedPtr<KServiceType> Ptr; - typedef TQValueList<Ptr> List; -public: - - /** - * Constructor. You may pass in arguments to create a servicetype with - * specific properties. - * @param _fullpath the path of the service type's desktop file - * @param _name the name of the service type - * @param _icon the icon name of the service type (can be null) - * @param _comment a comment (can be null) - */ - KServiceType( const TQString & _fullpath, const TQString& _name, - const TQString& _icon, const TQString& _comment); - - /** - * Construct a service type and take all informations from a config file. - * @param _fullpath path of the desktop file, set to "" if calling from - * a inherited constructor. - */ - KServiceType( const TQString & _fullpath ); - - /** - * Construct a service type and take all informations from a deskop file. - * @param config the configuration file - */ - KServiceType( KDesktopFile *config); - - /** - * @internal construct a service from a stream. - * The stream must already be positionned at the correct offset - */ - KServiceType( TQDataStream& _str, int offset ); - - virtual ~KServiceType(); - - /** - * Returns the icon associated with this service type. Some - * derived classes offer special functions which take for - * example an URL and returns a special icon for this - * URL. An example is KMimeType, KFolderType and - * others. - * @return the name of the icon, can be TQString::null. - */ - TQString icon() const { return m_strIcon; } - - /** - * Returns the descriptive comment associated, if any. - * @return the comment, or TQString::null - */ - TQString comment() const { return m_strComment; } - - /** - * Returns the name of this service type. - * @return the name of the service type - */ - TQString name() const { return m_strName; } - - /** - * Returns the relative path to the desktop entry file responsible for - * this servicetype. - * For instance inode/directory.desktop, or kpart.desktop - * @return the path of the desktop file - */ - TQString desktopEntryPath() const { return entryPath(); } - - /** - * Checks whether this service type inherits another one. - * @return true if this service type inherits another one - * @see parentServiceType() - */ - bool isDerived() const { return m_bDerived; } - - /** - * If this service type inherits from another service type, - * return the name of the parent. - * @return the parent service type, or TQString:: null if not set - * @see isDerived() - */ - TQString parentServiceType() const; - - /** - * Checks whether this service type is or inherits from @p servTypeName. - * @return true if this servicetype is or inherits from @p servTypeName - * @since 3.1 - */ - bool inherits( const TQString& servTypeName ) const; - - /** - * Returns the requested property. Some often used properties - * have convenience access functions like name(), - * comment() etc. - * - * @param _name the name of the property - * @return the property, or invalid if not found - */ - virtual TQVariant property( const TQString& _name ) const; - - /** - * Returns the list of all properties of this service type. - * @return the list of properties - */ - virtual TQStringList propertyNames() const; - - /** - * Checks whether the service type is valid. - * @return true if the service is valid (e.g. name is not empty) - */ - bool isValid() const { return m_bValid; } - - /** - * Returns the type of the property with the given @p _name. - * - * @param _name the name of the property - * @return the property type, or null if not found - */ - virtual TQVariant::Type propertyDef( const TQString& _name ) const; - - virtual TQStringList propertyDefNames() const; - virtual const TQMap<TQString,TQVariant::Type>& propertyDefs() const { return m_mapPropDefs; } - - /** - * @internal - * Save ourselves to the data stream. - */ - virtual void save( TQDataStream& ); - - /** - * @internal - * Load ourselves from the data stream. - */ - virtual void load( TQDataStream& ); - - /** - * @internal - * Pointer to parent serice type - */ - // gcc 2.95.x doesn't understand KServiceType::Ptr here - /* KServiceType:: */ Ptr parentType(); - /** - * @internal - * Register service that provides this service type - */ - void addService(KService::Ptr service); - /** - * @internal - * List serices that provide this service type - */ - KService::List services(); - - /** - * Returns a pointer to the servicetype '_name' or 0L if the - * service type is unknown. - * VERY IMPORTANT : don't store the result in a KServiceType * ! - * @param _name the name of the service type to search - * @return the pointer to the service type, or 0 - */ - static Ptr serviceType( const TQString& _name ); - - /** - * Returns all services supporting the given servicetype name. - * This doesn't take care of the user profile. - * In fact it is used by KServiceTypeProfile, - * which is used by KTrader, and that's the one you should use. - * @param _servicetype the name of the service type to search - * @return the list of all services of the given type - */ - static KService::List offers( const TQString& _servicetype ); - - /** - * Returns a list of all the supported servicetypes. Useful for - * showing the list of available servicetypes in a listbox, - * for example. - * More memory consuming than the ones above, don't use unless - * really necessary. - * @return the list of all services - */ - static List allServiceTypes(); - -protected: - void init( KDesktopFile *config ); - -protected: - TQString m_strName; - TQString m_strIcon; - TQString m_strComment; - TQMap<TQString,TQVariant> m_mapProps; - TQMap<TQString,TQVariant::Type> m_mapPropDefs; - - bool m_bValid:1; - bool m_bDerived:1; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KServiceTypePrivate; - KServiceTypePrivate* d; -}; - -//TQDataStream& operator>>( TQDataStream& _str, KServiceType& s ); -//TQDataStream& operator<<( TQDataStream& _str, KServiceType& s ); - -#endif diff --git a/kio/kio/kservicetypefactory.cpp b/kio/kio/kservicetypefactory.cpp deleted file mode 100644 index ecf527384..000000000 --- a/kio/kio/kservicetypefactory.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 1999 Waldo Bastian <bastian@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation; - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include "kservicetypefactory.h" -#include "tdesycoca.h" -#include "tdesycocatype.h" -#include "tdesycocadict.h" -#include "kservicetype.h" -#include "kmimetype.h" -#include "kuserprofile.h" - -#include <kapplication.h> -#include <kdebug.h> -#include <assert.h> -#include <kstringhandler.h> -#include <tqfile.h> - -KServiceTypeFactory::KServiceTypeFactory() - : KSycocaFactory( KST_KServiceTypeFactory ) -{ - _self = this; - m_fastPatternOffset = 0; - m_otherPatternOffset = 0; - if (m_str) - { - // Read Header - TQ_INT32 i,n; - (*m_str) >> i; - m_fastPatternOffset = i; - (*m_str) >> i; - m_otherPatternOffset = i; - (*m_str) >> n; - - if (n > 1024) - { - KSycoca::flagError(); - } - else - { - TQString str; - for(;n;n--) - { - KSycocaEntry::read(*m_str, str); - (*m_str) >> i; - m_propertyTypeDict.insert(str, i); - } - } - } -} - - -KServiceTypeFactory::~KServiceTypeFactory() -{ - _self = 0L; - KServiceTypeProfile::clear(); -} - -KServiceTypeFactory * KServiceTypeFactory::self() -{ - if (!_self) - _self = new KServiceTypeFactory(); - return _self; -} - -KServiceType * KServiceTypeFactory::findServiceTypeByName(const TQString &_name) -{ - if (!m_sycocaDict) return 0L; // Error! - assert (!KSycoca::self()->isBuilding()); - int offset = m_sycocaDict->find_string( _name ); - if (!offset) return 0; // Not found - KServiceType * newServiceType = createEntry(offset); - - // Check whether the dictionary was right. - if (newServiceType && (newServiceType->name() != _name)) - { - // No it wasn't... - delete newServiceType; - newServiceType = 0; // Not found - } - return newServiceType; -} - -TQVariant::Type KServiceTypeFactory::findPropertyTypeByName(const TQString &_name) -{ - if (!m_sycocaDict) - return TQVariant::Invalid; // Error! - - assert (!KSycoca::self()->isBuilding()); - - TQMapConstIterator<TQString,int> it = m_propertyTypeDict.find(_name); - if (it != m_propertyTypeDict.end()) { - return (TQVariant::Type)it.data(); - } - - return TQVariant::Invalid; -} - -KMimeType * KServiceTypeFactory::findFromPattern(const TQString &_filename, TQString *match) -{ - // Assume we're NOT building a database - if (!m_str) return 0; - - // Get stream to the header - TQDataStream *str = m_str; - - str->device()->at( m_fastPatternOffset ); - - TQ_INT32 nrOfEntries; - (*str) >> nrOfEntries; - TQ_INT32 entrySize; - (*str) >> entrySize; - - TQ_INT32 fastOffset = str->device()->at( ); - - TQ_INT32 matchingOffset = 0; - - // Let's go for a binary search in the "fast" pattern index - TQ_INT32 left = 0; - TQ_INT32 right = nrOfEntries - 1; - TQ_INT32 middle; - // Extract extension - int lastDot = _filename.findRev('.'); - int ext_len = _filename.length() - lastDot - 1; - if (lastDot != -1 && ext_len <= 4) // if no '.', skip the extension lookup - { - TQString extension = _filename.right( ext_len ); - extension = extension.leftJustify(4); - - TQString pattern; - while (left <= right) { - middle = (left + right) / 2; - // read pattern at position "middle" - str->device()->at( middle * entrySize + fastOffset ); - KSycocaEntry::read(*str, pattern); - int cmp = pattern.compare( extension ); - if (cmp < 0) - left = middle + 1; - else if (cmp == 0) // found - { - (*str) >> matchingOffset; - // don't return newServiceType - there may be an "other" pattern that - // matches best this file, like *.tar.bz - if (match) - *match = "*."+pattern.stripWhiteSpace(); - break; // but get out of the fast patterns - } - else - right = middle - 1; - } - } - - // Now try the "other" Pattern table - if ( m_patterns.isEmpty() ) { - str->device()->at( m_otherPatternOffset ); - - TQString pattern; - TQ_INT32 mimetypeOffset; - - while (true) - { - KSycocaEntry::read(*str, pattern); - if (pattern.isEmpty()) // end of list - break; - (*str) >> mimetypeOffset; - m_patterns.push_back( pattern ); - m_pattern_offsets.push_back( mimetypeOffset ); - } - } - - assert( m_patterns.size() == m_pattern_offsets.size() ); - - TQStringList::const_iterator it = m_patterns.begin(); - TQStringList::const_iterator end = m_patterns.end(); - TQValueVector<TQ_INT32>::const_iterator it_offset = m_pattern_offsets.begin(); - - for ( ; it != end; ++it, ++it_offset ) - { - if ( KStringHandler::matchFileName( _filename, *it ) ) - { - if ( !matchingOffset || !(*it).endsWith( "*" ) ) // *.html wins over Makefile.* - { - matchingOffset = *it_offset; - if (match) - *match = *it; - break; - } - } - } - - if ( matchingOffset ) { - KServiceType *newServiceType = createEntry( matchingOffset ); - assert (newServiceType && newServiceType->isType( KST_KMimeType )); - return (KMimeType *) newServiceType; - } - else - return 0; -} - -KMimeType::List KServiceTypeFactory::allMimeTypes() -{ - KMimeType::List result; - KSycocaEntry::List list = allEntries(); - for( KSycocaEntry::List::Iterator it = list.begin(); - it != list.end(); - ++it) - { - KMimeType *newMimeType = dynamic_cast<KMimeType *>((*it).data()); - if (newMimeType) - result.append( KMimeType::Ptr( newMimeType ) ); - } - return result; -} - -KServiceType::List KServiceTypeFactory::allServiceTypes() -{ - KServiceType::List result; - KSycocaEntry::List list = allEntries(); - for( KSycocaEntry::List::Iterator it = list.begin(); - it != list.end(); - ++it) - { -#ifndef Q_WS_QWS - KServiceType *newServiceType = dynamic_cast<KServiceType *>((*it).data()); -#else //FIXME - KServiceType *newServiceType = (KServiceType*)(*it).data(); -#endif - if (newServiceType) - result.append( KServiceType::Ptr( newServiceType ) ); - } - return result; -} - -bool KServiceTypeFactory::checkMimeTypes() -{ - TQDataStream *str = KSycoca::self()->findFactory( factoryId() ); - if (!str) return false; - - // check if there are mimetypes/servicetypes - return (m_beginEntryOffset != m_endEntryOffset); -} - -KServiceType * KServiceTypeFactory::createEntry(int offset) -{ - KServiceType *newEntry = 0; - KSycocaType type; - TQDataStream *str = KSycoca::self()->findEntry(offset, type); - if (!str) return 0; - - switch(type) - { - case KST_KServiceType: - newEntry = new KServiceType(*str, offset); - break; - case KST_KMimeType: - newEntry = new KMimeType(*str, offset); - break; - case KST_KFolderType: - newEntry = new KFolderType(*str, offset); - break; - case KST_KDEDesktopMimeType: - newEntry = new KDEDesktopMimeType(*str, offset); - break; - case KST_KExecMimeType: - newEntry = new KExecMimeType(*str, offset); - break; - - default: - kdError(7011) << TQString(TQString("KServiceTypeFactory: unexpected object entry in KSycoca database (type = %1)").arg((int)type)) << endl; - break; - } - if (newEntry && !newEntry->isValid()) - { - kdError(7011) << "KServiceTypeFactory: corrupt object in KSycoca database!\n" << endl; - delete newEntry; - newEntry = 0; - } - return newEntry; -} - -KServiceTypeFactory *KServiceTypeFactory::_self = 0; - -void KServiceTypeFactory::virtual_hook( int id, void* data ) -{ KSycocaFactory::virtual_hook( id, data ); } - -// vim: ts=3 sw=3 et diff --git a/kio/kio/kservicetypefactory.h b/kio/kio/kservicetypefactory.h deleted file mode 100644 index e18630b2c..000000000 --- a/kio/kio/kservicetypefactory.h +++ /dev/null @@ -1,123 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __k_service_type_factory_h__ -#define __k_service_type_factory_h__ - -#include <assert.h> - -#include <tqstringlist.h> -#include <tqvaluevector.h> - -#include "tdesycocafactory.h" -#include "kmimetype.h" - -class KSycoca; -class KSycocaDict; - -class KServiceType; -class KFolderType; -class KDEDesktopMimeType; -class KExecMimeType; - -/** - * @internal - * A sycoca factory for service types (e.g. mimetypes) - * It loads the service types from parsing directories (e.g. mimelnk/) - * but can also create service types from data streams or single config files - */ -class TDEIO_EXPORT KServiceTypeFactory : public KSycocaFactory -{ - K_SYCOCAFACTORY( KST_KServiceTypeFactory ) -public: - /** - * Create factory - */ - KServiceTypeFactory(); - - virtual ~KServiceTypeFactory(); - - /** - * Not meant to be called at this level - */ - virtual KSycocaEntry *createEntry(const TQString &, const char *) - { assert(0); return 0; } - - /** - * Find a service type in the database file (allocates it) - * Overloaded by KBuildServiceTypeFactory to return a memory one. - */ - virtual KServiceType * findServiceTypeByName(const TQString &_name); - - /** - * Find a the property type of a named property. - */ - TQVariant::Type findPropertyTypeByName(const TQString &_name); - - /** - * Find a mimetype from a filename (using the pattern list) - * @param _filename filename to check. - * @param match if provided, returns the pattern that matched. - */ - KMimeType * findFromPattern(const TQString &_filename, TQString *match = 0); - - /** - * @return all mimetypes - * Slow and memory consuming, avoid using - */ - KMimeType::List allMimeTypes(); - - /** - * @return all servicetypes - * Slow and memory consuming, avoid using - */ - KServiceType::List allServiceTypes(); - - /** - * @return true if at least one mimetype is present - * Safety test - */ - bool checkMimeTypes(); - - /** - * @return the unique servicetype factory, creating it if necessary - */ - static KServiceTypeFactory * self(); - -protected: - virtual KServiceType *createEntry(int offset); - -private: - static KServiceTypeFactory *_self; - -protected: - int m_fastPatternOffset; - int m_otherPatternOffset; - TQMap<TQString,int> m_propertyTypeDict; - -private: - TQStringList m_patterns; - TQValueVector<TQ_INT32> m_pattern_offsets; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KServiceTypeFactoryPrivate* d; -}; - -#endif diff --git a/kio/kio/kshellcompletion.cpp b/kio/kio/kshellcompletion.cpp deleted file mode 100644 index 2fb67a31f..000000000 --- a/kio/kio/kshellcompletion.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Smith <dsmith@algonet.se> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <stdlib.h> -#include <kdebug.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqregexp.h> -#include <kcompletion.h> - -#include "kshellcompletion.h" - -class KShellCompletionPrivate -{ -}; - -KShellCompletion::KShellCompletion() : KURLCompletion() -{ - m_word_break_char = ' '; - m_quote_char1 = '\"'; - m_quote_char2 = '\''; - m_escape_char = '\\'; -} - -/* - * makeCompletion() - * - * Entry point for file name completion - */ -TQString KShellCompletion::makeCompletion(const TQString &text) -{ - // Split text at the last unquoted space - // - splitText(text, m_text_start, m_text_compl); - - // Remove quotes from the text to be completed - // - TQString tmp = unquote(m_text_compl); - m_text_compl = tmp; - - // Do exe-completion if there was no unquoted space - // - bool is_exe_completion = true; - - for ( uint i = 0; i < m_text_start.length(); i++ ) { - if ( m_text_start[i] != m_word_break_char ) { - is_exe_completion = false; - break; - } - } - - Mode mode = (is_exe_completion ? ExeCompletion : FileCompletion ); - - setMode(mode); - - // Make completion on the last part of text - // - return KURLCompletion::makeCompletion( m_text_compl ); -} - -/* - * postProcessMatch, postProcessMatches - * - * Called by KCompletion before emitting match() and matches() - * - * Add add the part of the text that was not completed - * Add quotes when needed - */ -void KShellCompletion::postProcessMatch( TQString *match ) const -{ - //kDebugInfo("KShellCompletion::postProcessMatch() in: '%s'", - // match->latin1()); - - KURLCompletion::postProcessMatch( match ); - - if ( match->isNull() ) - return; - - if ( match->right(1) == TQChar('/') ) - quoteText( match, false, true ); // don't quote the trailing '/' - else - quoteText( match, false, false ); // quote the whole text - - match->prepend( m_text_start ); - - //kDebugInfo("KShellCompletion::postProcessMatch() ut: '%s'", - // match->latin1()); -} - -void KShellCompletion::postProcessMatches( TQStringList *matches ) const -{ - KURLCompletion::postProcessMatches( matches ); - - for ( TQStringList::Iterator it = matches->begin(); - it != matches->end(); it++ ) - { - if ( !(*it).isNull() ) { - if ( (*it).right(1) == TQChar('/') ) - quoteText( &(*it), false, true ); // don't quote trailing '/' - else - quoteText( &(*it), false, false ); // quote the whole text - - (*it).prepend( m_text_start ); - } - } -} - -void KShellCompletion::postProcessMatches( KCompletionMatches *matches ) const -{ - KURLCompletion::postProcessMatches( matches ); - - for ( KCompletionMatches::Iterator it = matches->begin(); - it != matches->end(); it++ ) - { - if ( !(*it).value().isNull() ) { - if ( (*it).value().right(1) == TQChar('/') ) - quoteText( &(*it).value(), false, true ); // don't quote trailing '/' - else - quoteText( &(*it).value(), false, false ); // quote the whole text - - (*it).value().prepend( m_text_start ); - } - } -} - -/* - * splitText - * - * Split text at the last unquoted space - * - * text_start = [out] text at the left, including the space - * text_compl = [out] text at the right - */ -void KShellCompletion::splitText(const TQString &text, TQString &text_start, - TQString &text_compl) const -{ - bool in_quote = false; - bool escaped = false; - TQChar p_last_quote_char; - int last_unquoted_space = -1; - int end_space_len = 0; - - for (uint pos = 0; pos < text.length(); pos++) { - - end_space_len = 0; - - if ( escaped ) { - escaped = false; - } - else if ( in_quote && text[pos] == p_last_quote_char ) { - in_quote = false; - } - else if ( !in_quote && text[pos] == m_quote_char1 ) { - p_last_quote_char = m_quote_char1; - in_quote = true; - } - else if ( !in_quote && text[pos] == m_quote_char2 ) { - p_last_quote_char = m_quote_char2; - in_quote = true; - } - else if ( text[pos] == m_escape_char ) { - escaped = true; - } - else if ( !in_quote && text[pos] == m_word_break_char ) { - - end_space_len = 1; - - while ( pos+1 < text.length() && text[pos+1] == m_word_break_char ) { - end_space_len++; - pos++; - } - - if ( pos+1 == text.length() ) - break; - - last_unquoted_space = pos; - } - } - - text_start = text.left( last_unquoted_space + 1 ); - - // the last part without trailing blanks - text_compl = text.mid( last_unquoted_space + 1 ); - -// text_compl = text.mid( last_unquoted_space + 1, -// text.length() - end_space_len - (last_unquoted_space + 1) ); - - //kDebugInfo("split right = '%s'", text_compl.latin1()); -} - -/* - * quoteText() - * - * Add quotations to 'text' if needed or if 'force' = true - * Returns true if quotes were added - * - * skip_last => ignore the last charachter (we add a space or '/' to all filenames) - */ -bool KShellCompletion::quoteText(TQString *text, bool force, bool skip_last) const -{ - int pos = 0; - - if ( !force ) { - pos = text->find( m_word_break_char ); - if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1; - } - - if ( !force && pos == -1 ) { - pos = text->find( m_quote_char1 ); - if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1; - } - - if ( !force && pos == -1 ) { - pos = text->find( m_quote_char2 ); - if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1; - } - - if ( !force && pos == -1 ) { - pos = text->find( m_escape_char ); - if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1; - } - - if ( force || (pos >= 0) ) { - - // Escape \ in the string - text->replace( m_escape_char, - TQString( m_escape_char ) + m_escape_char ); - - // Escape " in the string - text->replace( m_quote_char1, - TQString( m_escape_char ) + m_quote_char1 ); - - // " at the beginning - text->insert( 0, m_quote_char1 ); - - // " at the end - if ( skip_last ) - text->insert( text->length()-1, m_quote_char1 ); - else - text->insert( text->length(), m_quote_char1 ); - - return true; - } - - return false; -} - -/* - * unquote - * - * Remove quotes and return the result in a new string - * - */ -TQString KShellCompletion::unquote(const TQString &text) const -{ - bool in_quote = false; - bool escaped = false; - TQChar p_last_quote_char; - TQString result; - - for (uint pos = 0; pos < text.length(); pos++) { - - if ( escaped ) { - escaped = false; - result.insert( result.length(), text[pos] ); - } - else if ( in_quote && text[pos] == p_last_quote_char ) { - in_quote = false; - } - else if ( !in_quote && text[pos] == m_quote_char1 ) { - p_last_quote_char = m_quote_char1; - in_quote = true; - } - else if ( !in_quote && text[pos] == m_quote_char2 ) { - p_last_quote_char = m_quote_char2; - in_quote = true; - } - else if ( text[pos] == m_escape_char ) { - escaped = true; - result.insert( result.length(), text[pos] ); - } - else { - result.insert( result.length(), text[pos] ); - } - - } - - return result; -} - -void KShellCompletion::virtual_hook( int id, void* data ) -{ KURLCompletion::virtual_hook( id, data ); } - -#include "kshellcompletion.moc" - diff --git a/kio/kio/kshellcompletion.h b/kio/kio/kshellcompletion.h deleted file mode 100644 index fa90c509e..000000000 --- a/kio/kio/kshellcompletion.h +++ /dev/null @@ -1,85 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Smith <dsmith@algonet.se> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KSHELLCOMPLETION_H -#define KSHELLCOMPLETION_H - -#include <tqstring.h> -#include <tqstringlist.h> - -#include "kurlcompletion.h" - -class KShellCompletionPrivate; - -/** - * This class does shell-like completion of file names. - * A string passed to makeCompletion() will be interpreted as a shell - * command line. Completion will be done on the last argument on the line. - * Returned matches consist of the first arguments (uncompleted) plus the - * completed last argument. - * - * @short Shell-like completion of file names - * @author David Smith <dsmith@algonet.se> - */ -class TDEIO_EXPORT KShellCompletion : public KURLCompletion -{ - Q_OBJECT - -public: - /** - * Constructs a KShellCompletion object. - */ - KShellCompletion(); - - /** - * Finds completions to the given text. - * The first match is returned and emitted in the signal match(). - * @param text the text to complete - * @return the first match, or TQString::null if not found - */ - TQString makeCompletion(const TQString &text); - -protected: - // Called by KCompletion - void postProcessMatch( TQString *match ) const; - void postProcessMatches( TQStringList *matches ) const; - void postProcessMatches( KCompletionMatches *matches ) const; - -private: - // Find the part of text that should be completed - void splitText(const TQString &text, TQString &text_start, TQString &text_compl) const; - // Insert quotes and neseccary escapes - bool quoteText(TQString *text, bool force, bool skip_last) const; - TQString unquote(const TQString &text) const; - - TQString m_text_start; // part of the text that was not completed - TQString m_text_compl; // part of the text that was completed (unchanged) - - TQChar m_word_break_char; - TQChar m_quote_char1; - TQChar m_quote_char2; - TQChar m_escape_char; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - KShellCompletionPrivate *d; -}; - -#endif // KSHELLCOMPLETION_H diff --git a/kio/kio/kshred.cpp b/kio/kio/kshred.cpp deleted file mode 100644 index f3997bf58..000000000 --- a/kio/kio/kshred.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/*--------------------------------------------------------------------------* - KShred.h Copyright (c) 2000 MieTerra LLC. - Credits: Andreas F. Pour <bugs@mieterra.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "kshred.h" -#include <time.h> -#include <klocale.h> -#include <kdebug.h> -#include <stdlib.h> -#include <kapplication.h> - -// antlarr: KDE 4: Make it const TQString & -KShred::KShred(TQString fileName) -{ - if (fileName.isEmpty()) - { - kdError() << "KShred: missing file name in constructor" << endl; - file = 0L; - } - else - { - file = new TQFile(); - file->setName(fileName); - if (!file->open(IO_ReadWrite)) - { - kdError() << "KShred: cannot open file '" << fileName.local8Bit().data() << "' for writing\n" << endl; - file = 0L; - fileSize = 0; - } - else - fileSize = file->size(); - - totalBytes = 0; - bytesWritten = 0; - lastSignalled = 0; - tbpc = 0; - fspc = 0; - } -} - - -KShred::~KShred() -{ - if (file != 0L) - delete file; -} - - -bool -KShred::fill1s() -{ - return fillbyte(0xFF); -} - - -bool -KShred::fill0s() -{ - return fillbyte(0x0); -} - - -bool -KShred::fillbyte(unsigned int byte) -{ - if (file == 0L) - return false; - unsigned char buff[4096]; - memset((void *) buff, byte, 4096); - - unsigned int n; - for (unsigned int todo = fileSize; todo > 0; todo -= n) - { - n = (todo > 4096 ? 4096 : todo); - if (!writeData(buff, n)) - return false; - } - if (!flush()) - return false; - return file->at(0); -} - - -bool -KShred::fillpattern(unsigned char *data, unsigned int size) -{ - if (file == 0L) - return false; - - unsigned int n; - for (unsigned int todo = fileSize; todo > 0; todo -= n) - { - n = (todo > size ? size : todo); - if (!writeData(data, n)) - return false; - } - if (!flush()) - return false; - return file->at(0); -} - - -bool -KShred::fillrandom() -{ - if (file == 0L) - return false; - - long int buff[4096 / sizeof(long int)]; - unsigned int n; - - for (unsigned int todo = fileSize; todo > 0; todo -= n) - { - n = (todo > 4096 ? 4096 : todo); - // assumes that 4096 is a multipe of sizeof(long int) - int limit = (n + sizeof(long int) - 1) / sizeof(long int); - for (int i = 0; i < limit; i++) - buff[i] = kapp->random(); - - if (!writeData((unsigned char *) buff, n)) - return false; - } - if (!flush()) - return false; - return file->at(0); -} - - -// antlarr: KDE 4: Make it const TQString & -bool -KShred::shred(TQString fileName) -{ - if (fileName.isEmpty()) - return false; - - KShred shredder(fileName); - return shredder.shred(); -} - - -bool -KShred::writeData(unsigned char *data, unsigned int size) -{ - unsigned int ret = 0; - - // write 'data' of size 'size' to the file - while ((ret < size) && (file->putch((int) data[ret]) >= 0)) - ret++; - - if ((totalBytes > 0) && (ret > 0)) - { - if (tbpc == 0) - { - tbpc = ((unsigned int) (totalBytes / 100)) == 0 ? 1 : totalBytes / 100; - fspc = ((unsigned int) (fileSize / 100)) == 0 ? 1 : fileSize / 100; - } - bytesWritten += ret; - unsigned int pc = (unsigned int) (bytesWritten / tbpc); - if (pc > lastSignalled) - { - emit processedSize(fspc * pc); - lastSignalled = pc; - } - } - return ret == size; -} - - -bool -KShred::flush() -{ - if (file == 0L) - return false; - - file->flush(); - return (fsync(file->handle()) == 0); -} - - -// shred the file, then close and remove it -// -// UPDATED: this function now uses 35 passes based on the the article -// Peter Gutmann, "Secure Deletion of Data from Magnetic and Solid-State -// Memory", first published in the Sixth USENIX Security Symposium -// Proceedings, San Jose, CA, July 22-25, 1996 (available online at -// http://rootprompt.org/article.php3?article=473) - -bool -KShred::shred() -{ - unsigned char p[6][3] = {{'\222', '\111', '\044'}, {'\111', '\044', '\222'}, - {'\044', '\222', '\111'}, {'\155', '\266', '\333'}, - {'\266', '\333', '\155'}, {'\333', '\155', '\266'}}; - TQString msg = i18n("Shredding: pass %1 of 35"); - - emit processedSize(0); - - // thirty-five times writing the entire file size - totalBytes = fileSize * 35; - int iteration = 1; - - for (int ctr = 0; ctr < 4; ctr++) - if (!fillrandom()) - return false; - else - { - emit infoMessage(msg.arg(iteration)); - } - - if (!fillbyte((unsigned int) 0x55)) // '0x55' is 01010101 - return false; - emit infoMessage(msg.arg(iteration)); - - if (!fillbyte((unsigned int) 0xAA)) // '0xAA' is 10101010 - return false; - emit infoMessage(msg.arg(iteration)); - - for (unsigned int ctr = 0; ctr < 3; ctr++) - if (!fillpattern(p[ctr], 3)) // '0x92', '0x49', '0x24' - return false; - else - { - emit infoMessage(msg.arg(iteration)); - } - - for (unsigned int ctr = 0; ctr <= 255 ; ctr += 17) - if (!fillbyte(ctr)) // sequence of '0x00', '0x11', ..., '0xFF' - return false; - else - { - emit infoMessage(msg.arg(iteration)); - } - - for (unsigned int ctr = 0; ctr < 6; ctr++) - if (!fillpattern(p[ctr], 3)) // '0x92', '0x49', '0x24' - return false; - else - { - emit infoMessage(msg.arg(iteration)); - } - - for (int ctr = 0; ctr < 4; ctr++) - if (!fillrandom()) - return false; - else - { - emit infoMessage(msg.arg(iteration)); - } - - if (!file->remove()) - return false; - file = 0L; - emit processedSize(fileSize); - return true; -} - -#include "kshred.moc" - diff --git a/kio/kio/kshred.h b/kio/kio/kshred.h deleted file mode 100644 index 7f817c1ea..000000000 --- a/kio/kio/kshred.h +++ /dev/null @@ -1,156 +0,0 @@ -/*--------------------------------------------------------------------------* - KShred.h Copyright (c) 2000 MieTerra LLC. - Credits: Andreas F. Pour <bugs@mieterra.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#ifndef kshred_h -#define kshred_h - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <tqstring.h> -#include <tqfile.h> -#include <tqobject.h> - -#include <kio/global.h> - -/** - * @deprecated - * Erase a file in a way that makes recovery impossible -- well, no guarentee - * of that, but at least as difficult as reasonably possible. - * For this, KShred write several times over the - * existing file, using different patterns, before deleting it. - * @author Andreas F. Pour <bugs@mieterra.com> - * @author David Faure <faure@kde.org> (integration into KDE and progress signal) - */ -class TDEIO_EXPORT_DEPRECATED KShred : public TQObject { // KDE4: remove - - Q_OBJECT - - public: - - /** - * Initialize the class using the name of the file to 'shred'. - * @param fileName fully qualified name of the file to shred. - */ - KShred(TQString fileName); - - /* - * Destructor for the class. - */ - ~KShred(); - - /** - * Writes all 1's over the entire file and flushes the file buffers. - * @return true on success, false on error (invalid filename or write error) - */ - - bool fill1s(); - /** - * Writes all 0's over the entire file and flushes the file buffers. - * @return true on success, false on error (invalid filename or write error) - */ - bool fill0s(); - - /** - * Writes the specified byte over the entire file and flushes the file buffers. - * @param byte the value to write over every byte of the file - * @return true on success, false on error (invalid filename or write error) - */ - bool fillbyte(unsigned int byte); - - /** - * Writes random bites over the entire file and flushes the file buffers. - * @return true on success, false on error (invalid filename or write error) - */ - bool fillrandom(); - - /** - * Writes the specified byte array over the entire file and flushes the file buffers. - * @param pattern the value to write over the entire file - * @param size the length of the 'pattern' byte array - * @return true on success, false on error (invalid filename or write error) - */ - bool fillpattern(unsigned char *pattern, unsigned int size); - - /** - * Shreds a file by writing a series of values over it (uses - * #fill0s, then fill1s, then fillrandom, then - * fillbyte with 0101..., then fillbyte with 1010.... - * @return true on success, false on error (invalid filename or write error) - */ - bool shred(); - - /** - * The simplest method to shred a file. - * No need to create an instance of the class. - * @param fileName fully qualified name of the file to shred. - */ - static bool shred(TQString fileName); - - signals: - /** - * Shows progress of the shredding. - * @param bytes the number of bytes written to the file - */ - void processedSize(TDEIO::filesize_t bytes); - - /** - * Shows a message in the progress dialog - * @param message the message to display - */ - void infoMessage(const TQString & message); - - private: - /** - * @internal write the data to the file - */ - bool writeData(unsigned char *data, unsigned int size); - - /** - * @internal flush the data to the file - */ - bool flush(); - - /** - * @internal structure for the file information - */ - TQFile *file; - - /** - * @internal for the size of the file - */ - TDEIO::filesize_t fileSize; - - /** - * @internal for keeping track of progress - */ - unsigned int totalBytes; - unsigned int bytesWritten; - unsigned int lastSignalled; - unsigned int tbpc; - unsigned int fspc; - private: - class KShredPrivate* d; -}; - -#endif diff --git a/kio/kio/ktar.cpp b/kio/kio/ktar.cpp deleted file mode 100644 index 9bde2873a..000000000 --- a/kio/kio/ktar.cpp +++ /dev/null @@ -1,980 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - Copyright (C) 2003 Leo Savernik <l.savernik@aon.at> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -//#include <stdio.h> -#include <stdlib.h> // strtol -#include <time.h> // time() -/*#include <unistd.h> -#include <grp.h> -#include <pwd.h>*/ -#include <assert.h> - -#include <tqcstring.h> -#include <tqdir.h> -#include <tqfile.h> -#include <kdebug.h> -#include <kmimetype.h> -#include <ktempfile.h> - -#include <kfilterdev.h> -#include <kfilterbase.h> - -#include "ktar.h" -#include <kstandarddirs.h> - -//////////////////////////////////////////////////////////////////////// -/////////////////////////// KTar /////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -class KTar::KTarPrivate -{ -public: - KTarPrivate() : tarEnd( 0 ), tmpFile( 0 ) {} - TQStringList dirList; - int tarEnd; - KTempFile* tmpFile; - TQString mimetype; - TQCString origFileName; - - bool fillTempFile(const TQString & filename); - bool writeBackTempFile( const TQString & filename ); -}; - -KTar::KTar( const TQString& filename, const TQString & _mimetype ) - : KArchive( 0 ) -{ - m_filename = filename; - d = new KTarPrivate; - TQString mimetype( _mimetype ); - bool forced = true; - if ( mimetype.isEmpty() ) // Find out mimetype manually - { - if ( TQFile::exists( filename ) ) - mimetype = KMimeType::findByFileContent( filename )->name(); - else - mimetype = KMimeType::findByPath( filename, 0, true )->name(); - kdDebug(7041) << "KTar::KTar mimetype = " << mimetype << endl; - - // Don't move to prepareDevice - the other constructor theoretically allows ANY filter - if ( mimetype == "application/x-tgz" || mimetype == "application/x-targz" || // the latter is deprecated but might still be around - mimetype == "application/x-webarchive" ) - { - // that's a gzipped tar file, so ask for gzip filter - mimetype = "application/x-gzip"; - } - else if ( mimetype == "application/x-tbz" ) // that's a bzipped2 tar file, so ask for bz2 filter - { - mimetype = "application/x-bzip2"; - } - else - { - // Something else. Check if it's not really gzip though (e.g. for KOffice docs) - TQFile file( filename ); - if ( file.open( IO_ReadOnly ) ) - { - unsigned char firstByte = file.getch(); - unsigned char secondByte = file.getch(); - unsigned char thirdByte = file.getch(); - if ( firstByte == 0037 && secondByte == 0213 ) - mimetype = "application/x-gzip"; - else if ( firstByte == 'B' && secondByte == 'Z' && thirdByte == 'h' ) - mimetype = "application/x-bzip2"; - else if ( firstByte == 'P' && secondByte == 'K' && thirdByte == 3 ) - { - unsigned char fourthByte = file.getch(); - if ( fourthByte == 4 ) - mimetype = "application/x-zip"; - } - else if ( firstByte == 0xfd && secondByte == '7' && thirdByte == 'z' ) - { - unsigned char fourthByte = file.getch(); - unsigned char fifthByte = file.getch(); - unsigned char sixthByte = file.getch(); - if ( fourthByte == 'X' && fifthByte == 'Z' && sixthByte == 0x00 ) - mimetype = "application/x-xz"; - } - else if ( firstByte == 0x5d && secondByte == 0x00 && thirdByte == 0x00 ) - { - unsigned char fourthByte = file.getch(); - if ( fourthByte == 0x80 ) - mimetype = "application/x-lzma"; - } - } - file.close(); - } - forced = false; - } - d->mimetype = mimetype; - - prepareDevice( filename, mimetype, forced ); -} - -void KTar::prepareDevice( const TQString & filename, - const TQString & mimetype, bool /*forced*/ ) -{ - if( "application/x-tar" == mimetype ) - setDevice( TQT_TQIODEVICE(new TQFile( filename )) ); - else - { - // The compression filters are very slow with random access. - // So instead of applying the filter to the device, - // the file is completly extracted instead, - // and we work on the extracted tar file. - // This improves the extraction speed by the tar ioslave dramatically, - // if the archive file contains many files. - // This is because the tar ioslave extracts one file after the other and normally - // has to walk through the decompression filter each time. - // Which is in fact nearly as slow as a complete decompression for each file. - d->tmpFile = new KTempFile(locateLocal("tmp", "ktar-"),".tar"); - kdDebug( 7041 ) << "KTar::prepareDevice creating TempFile: " << d->tmpFile->name() << endl; - d->tmpFile->setAutoDelete(true); - - // KTempFile opens the file automatically, - // the device must be closed, however, for KArchive.setDevice() - TQFile* file = d->tmpFile->file(); - file->close(); - setDevice(TQT_TQIODEVICE(file)); - } -} - -KTar::KTar( TQIODevice * dev ) - : KArchive( dev ) -{ - Q_ASSERT( dev ); - d = new KTarPrivate; -} - -KTar::~KTar() -{ - // mjarrett: Closes to prevent ~KArchive from aborting w/o device - if( isOpened() ) - close(); - - if (d->tmpFile) - delete d->tmpFile; // will delete the device - else if ( !m_filename.isEmpty() ) - delete device(); // we created it ourselves - - - delete d; -} - -void KTar::setOrigFileName( const TQCString & fileName ) -{ - if ( !isOpened() || !(mode() & IO_WriteOnly) ) - { - kdWarning(7041) << "KTar::setOrigFileName: File must be opened for writing first.\n"; - return; - } - d->origFileName = fileName; -} - -TQ_LONG KTar::readRawHeader(char *buffer) { - // Read header - TQ_LONG n = device()->readBlock( buffer, 0x200 ); - if ( n == 0x200 && buffer[0] != 0 ) { - // Make sure this is actually a tar header - if (strncmp(buffer + 257, "ustar", 5)) { - // The magic isn't there (broken/old tars), but maybe a correct checksum? - TQCString s; - - int check = 0; - for( uint j = 0; j < 0x200; ++j ) - check += buffer[j]; - - // adjust checksum to count the checksum fields as blanks - for( uint j = 0; j < 8 /*size of the checksum field including the \0 and the space*/; j++ ) - check -= buffer[148 + j]; - check += 8 * ' '; - - s.sprintf("%o", check ); - - // only compare those of the 6 checksum digits that mean something, - // because the other digits are filled with all sorts of different chars by different tars ... - // Some tars right-justify the checksum so it could start in one of three places - we have to check each. - if( strncmp( buffer + 148 + 6 - s.length(), s.data(), s.length() ) - && strncmp( buffer + 148 + 7 - s.length(), s.data(), s.length() ) - && strncmp( buffer + 148 + 8 - s.length(), s.data(), s.length() ) ) { - kdWarning(7041) << "KTar: invalid TAR file. Header is: " << TQCString( buffer+257, 5 ) << endl; - return -1; - } - }/*end if*/ - } else { - // reset to 0 if 0x200 because logical end of archive has been reached - if (n == 0x200) n = 0; - }/*end if*/ - return n; -} - -bool KTar::readLonglink(char *buffer,TQCString &longlink) { - TQ_LONG n = 0; - TQIODevice *dev = device(); - // read size of longlink from size field in header - // size is in bytes including the trailing null (which we ignore) - buffer[ 0x88 ] = 0; // was 0x87, but 0x88 fixes BR #26437 - char *dummy; - const char* p = buffer + 0x7c; - while( *p == ' ' ) ++p; - int size = (int)strtol( p, &dummy, 8 ); - - longlink.resize(size); - size--; // ignore trailing null - dummy = longlink.data(); - int offset = 0; - while (size > 0) { - int chunksize = QMIN(size, 0x200); - n = dev->readBlock( dummy + offset, chunksize ); - if (n == -1) return false; - size -= chunksize; - offset += 0x200; - }/*wend*/ - // jump over the rest - int skip = 0x200 - (n % 0x200); - if (skip < 0x200) { - if (dev->readBlock(buffer,skip) != skip) return false; - } - return true; -} - -TQ_LONG KTar::readHeader(char *buffer,TQString &name,TQString &symlink) { - name.truncate(0); - symlink.truncate(0); - while (true) { - TQ_LONG n = readRawHeader(buffer); - if (n != 0x200) return n; - - // is it a longlink? - if (strcmp(buffer,"././@LongLink") == 0) { - char typeflag = buffer[0x9c]; - TQCString longlink; - readLonglink(buffer,longlink); - switch (typeflag) { - case 'L': name = TQFile::decodeName(longlink); break; - case 'K': symlink = TQFile::decodeName(longlink); break; - }/*end switch*/ - } else { - break; - }/*end if*/ - }/*wend*/ - - // if not result of longlink, read names directly from the header - if (name.isEmpty()) - // there are names that are exactly 100 bytes long - // and neither longlink nor \0 terminated (bug:101472) - name = TQFile::decodeName(TQCString(buffer, 101)); - if (symlink.isEmpty()) - symlink = TQFile::decodeName(TQCString(buffer + 0x9d, 101)); - - return 0x200; -} - -/* - * If we have created a temporary file, we have - * to decompress the original file now and write - * the contents to the temporary file. - */ -bool KTar::KTarPrivate::fillTempFile( const TQString & filename) { - if ( ! tmpFile ) - return true; - - kdDebug( 7041 ) << - "KTar::openArchive: filling tmpFile of mimetype '" << mimetype << - "' ... " << endl; - - bool forced = false; - if( "application/x-gzip" == mimetype - || "application/x-bzip2" == mimetype - || "application/x-lzma" == mimetype - || "application/x-xz" == mimetype) - forced = true; - - TQIODevice *filterDev = KFilterDev::deviceForFile( filename, mimetype, forced ); - - if( filterDev ) { - TQFile* file = tmpFile->file(); - file->close(); - if ( ! file->open( IO_WriteOnly ) ) - { - delete filterDev; - return false; - } - TQByteArray buffer(8*1024); - if ( ! filterDev->open( IO_ReadOnly ) ) - { - delete filterDev; - return false; - } - TQ_LONG len = -1; - while ( !filterDev->atEnd() && len != 0) { - len = filterDev->readBlock(buffer.data(),buffer.size()); - if ( len < 0 ) { // corrupted archive - delete filterDev; - return false; - } - file->writeBlock(buffer.data(),len); - } - filterDev->close(); - delete filterDev; - - file->close(); - if ( ! file->open( IO_ReadOnly ) ) - return false; - } - else - kdDebug( 7041 ) << "KTar::openArchive: no filterdevice found!" << endl; - - kdDebug( 7041 ) << "KTar::openArchive: filling tmpFile finished." << endl; - return true; -} - -bool KTar::openArchive( int mode ) -{ - kdDebug( 7041 ) << "KTar::openArchive" << endl; - if ( !(mode & IO_ReadOnly) ) - return true; - - if ( !d->fillTempFile( m_filename ) ) - return false; - - // We'll use the permission and user/group of d->rootDir - // for any directory we emulate (see findOrCreate) - //struct stat buf; - //stat( m_filename, &buf ); - - d->dirList.clear(); - TQIODevice* dev = device(); - - if ( !dev ) - return false; - - // read dir infos - char buffer[ 0x200 ]; - bool ende = false; - do - { - TQString name; - TQString symlink; - - // Read header - TQ_LONG n = readHeader(buffer,name,symlink); - if (n < 0) return false; - if (n == 0x200) - { - bool isdir = false; - TQString nm; - - if ( name.right(1) == "/" ) - { - isdir = true; - name = name.left( name.length() - 1 ); - } - - int pos = name.findRev( '/' ); - if ( pos == -1 ) - nm = name; - else - nm = name.mid( pos + 1 ); - - // read access - buffer[ 0x6b ] = 0; - char *dummy; - const char* p = buffer + 0x64; - while( *p == ' ' ) ++p; - int access = (int)strtol( p, &dummy, 8 ); - - // read user and group - TQString user( buffer + 0x109 ); - TQString group( buffer + 0x129 ); - - // read time - buffer[ 0x93 ] = 0; - p = buffer + 0x88; - while( *p == ' ' ) ++p; - int time = (int)strtol( p, &dummy, 8 ); - - // read type flag - char typeflag = buffer[ 0x9c ]; - // '0' for files, '1' hard link, '2' symlink, '5' for directory - // (and 'L' for longlink filenames, 'K' for longlink symlink targets) - // and 'D' for GNU tar extension DUMPDIR - if ( typeflag == '5' ) - isdir = true; - - bool isDumpDir = false; - if ( typeflag == 'D' ) - { - isdir = false; - isDumpDir = true; - } - //bool islink = ( typeflag == '1' || typeflag == '2' ); - //kdDebug(7041) << "typeflag=" << typeflag << " islink=" << islink << endl; - - if (isdir) - access |= S_IFDIR; // f*cking broken tar files - - KArchiveEntry* e; - if ( isdir ) - { - //kdDebug(7041) << "KTar::openArchive directory " << nm << endl; - e = new KArchiveDirectory( this, nm, access, time, user, group, symlink ); - } - else - { - // read size - buffer[ 0x88 ] = 0; // was 0x87, but 0x88 fixes BR #26437 - char *dummy; - const char* p = buffer + 0x7c; - while( *p == ' ' ) ++p; - int size = (int)strtol( p, &dummy, 8 ); - - // for isDumpDir we will skip the additional info about that dirs contents - if ( isDumpDir ) - { - //kdDebug(7041) << "KTar::openArchive " << nm << " isDumpDir" << endl; - e = new KArchiveDirectory( this, nm, access, time, user, group, symlink ); - } - else - { - - // Let's hack around hard links. Our classes don't support that, so make them symlinks - if ( typeflag == '1' ) - { - kdDebug(7041) << "HARD LINK, setting size to 0 instead of " << size << endl; - size = 0; // no contents - } - - //kdDebug(7041) << "KTar::openArchive file " << nm << " size=" << size << endl; - e = new KArchiveFile( this, nm, access, time, user, group, symlink, - dev->at(), size ); - } - - // Skip contents + align bytes - int rest = size % 0x200; - int skip = size + (rest ? 0x200 - rest : 0); - //kdDebug(7041) << "KTar::openArchive, at()=" << dev->at() << " rest=" << rest << " skipping " << skip << endl; - if (! dev->at( dev->at() + skip ) ) - kdWarning(7041) << "KTar::openArchive skipping " << skip << " failed" << endl; - } - - if ( pos == -1 ) - { - if ( nm == "." ) // special case - { - Q_ASSERT( isdir ); - if ( isdir ) - setRootDir( static_cast<KArchiveDirectory *>( e ) ); - } - else - rootDir()->addEntry( e ); - } - else - { - // In some tar files we can find dir/./file => call cleanDirPath - TQString path = TQDir::cleanDirPath( name.left( pos ) ); - // Ensure container directory exists, create otherwise - KArchiveDirectory * d = findOrCreate( path ); - d->addEntry( e ); - } - } - else - { - //tqDebug("Terminating. Read %d bytes, first one is %d", n, buffer[0]); - d->tarEnd = dev->at() - n; // Remember end of archive - ende = true; - } - } while( !ende ); - return true; -} - -/* - * Writes back the changes of the temporary file - * to the original file. - * Must only be called if in IO_WriteOnly mode - */ -bool KTar::KTarPrivate::writeBackTempFile( const TQString & filename ) { - if ( ! tmpFile ) - return true; - - kdDebug(7041) << "Write temporary file to compressed file" << endl; - kdDebug(7041) << filename << " " << mimetype << endl; - - bool forced = false; - if( "application/x-gzip" == mimetype - || "application/x-bzip2" == mimetype - || "application/x-lzma" == mimetype - || "application/x-xz" == mimetype) - forced = true; - - TQIODevice *dev = KFilterDev::deviceForFile( filename, mimetype, forced ); - if( dev ) { - TQFile* file = tmpFile->file(); - file->close(); - if ( ! file->open(IO_ReadOnly) || ! dev->open(IO_WriteOnly) ) - { - file->close(); - delete dev; - return false; - } - if ( forced ) - static_cast<KFilterDev *>(dev)->setOrigFileName( origFileName ); - TQByteArray buffer(8*1024); - TQ_LONG len; - while ( ! file->atEnd()) { - len = file->readBlock(buffer.data(),buffer.size()); - dev->writeBlock(buffer.data(),len); - } - file->close(); - dev->close(); - delete dev; - } - - kdDebug(7041) << "Write temporary file to compressed file done." << endl; - return true; -} - -bool KTar::closeArchive() -{ - d->dirList.clear(); - - // If we are in write mode and had created - // a temporary tar file, we have to write - // back the changes to the original file - if( mode() == IO_WriteOnly) - return d->writeBackTempFile( m_filename ); - - return true; -} - -bool KTar::writeDir( const TQString& name, const TQString& user, const TQString& group ) -{ - mode_t perm = 040755; - time_t the_time = time(0); - return writeDir(name,user,group,perm,the_time,the_time,the_time); -#if 0 - if ( !isOpened() ) - { - kdWarning(7041) << "KTar::writeDir: You must open the tar file before writing to it\n"; - return false; - } - - if ( !(mode() & IO_WriteOnly) ) - { - kdWarning(7041) << "KTar::writeDir: You must open the tar file for writing\n"; - return false; - } - - // In some tar files we can find dir/./ => call cleanDirPath - TQString dirName ( TQDir::cleanDirPath( name ) ); - - // Need trailing '/' - if ( dirName.right(1) != "/" ) - dirName += "/"; - - if ( d->dirList.contains( dirName ) ) - return true; // already there - - char buffer[ 0x201 ]; - memset( buffer, 0, 0x200 ); - if ( mode() & IO_ReadWrite ) device()->at(d->tarEnd); // Go to end of archive as might have moved with a read - - // If more than 100 chars, we need to use the LongLink trick - if ( dirName.length() > 99 ) - { - strcpy( buffer, "././@LongLink" ); - fillBuffer( buffer, " 0", dirName.length()+1, 'L', user.local8Bit(), group.local8Bit() ); - device()->writeBlock( buffer, 0x200 ); - strncpy( buffer, TQFile::encodeName(dirName), 0x200 ); - buffer[0x200] = 0; - // write long name - device()->writeBlock( buffer, 0x200 ); - // not even needed to reclear the buffer, tar doesn't do it - } - else - { - // Write name - strncpy( buffer, TQFile::encodeName(dirName), 0x200 ); - buffer[0x200] = 0; - } - - fillBuffer( buffer, " 40755", 0, 0x35, user.local8Bit(), group.local8Bit()); - - // Write header - device()->writeBlock( buffer, 0x200 ); - if ( mode() & IO_ReadWrite ) d->tarEnd = device()->at(); - - d->dirList.append( dirName ); // contains trailing slash - return true; // TODO if wanted, better error control -#endif -} - -bool KTar::prepareWriting( const TQString& name, const TQString& user, const TQString& group, uint size ) -{ - mode_t dflt_perm = 0100644; - time_t the_time = time(0); - return prepareWriting(name,user,group,size,dflt_perm, - the_time,the_time,the_time); -} - -bool KTar::doneWriting( uint size ) -{ - // Write alignment - int rest = size % 0x200; - if ( mode() & IO_ReadWrite ) - d->tarEnd = device()->at() + (rest ? 0x200 - rest : 0); // Record our new end of archive - if ( rest ) - { - char buffer[ 0x201 ]; - for( uint i = 0; i < 0x200; ++i ) - buffer[i] = 0; - TQ_LONG nwritten = device()->writeBlock( buffer, 0x200 - rest ); - return nwritten == 0x200 - rest; - } - return true; -} - -/*** Some help from the tar sources -struct posix_header -{ byte offset - char name[100]; * 0 * 0x0 - char mode[8]; * 100 * 0x64 - char uid[8]; * 108 * 0x6c - char gid[8]; * 116 * 0x74 - char size[12]; * 124 * 0x7c - char mtime[12]; * 136 * 0x88 - char chksum[8]; * 148 * 0x94 - char typeflag; * 156 * 0x9c - char linkname[100]; * 157 * 0x9d - char magic[6]; * 257 * 0x101 - char version[2]; * 263 * 0x107 - char uname[32]; * 265 * 0x109 - char gname[32]; * 297 * 0x129 - char devmajor[8]; * 329 * 0x149 - char devminor[8]; * 337 * ... - char prefix[155]; * 345 * - * 500 * -}; -*/ - -void KTar::fillBuffer( char * buffer, - const char * mode, int size, time_t mtime, char typeflag, - const char * uname, const char * gname ) -{ - // mode (as in stat()) - assert( strlen(mode) == 6 ); - strcpy( buffer+0x64, mode ); - buffer[ 0x6a ] = ' '; - buffer[ 0x6b ] = '\0'; - - // dummy uid - strcpy( buffer + 0x6c, " 765 "); - // dummy gid - strcpy( buffer + 0x74, " 144 "); - - // size - TQCString s; - s.sprintf("%o", size); // OCT - s = s.rightJustify( 11, ' ' ); - strcpy( buffer + 0x7c, s.data() ); - buffer[ 0x87 ] = ' '; // space-terminate (no null after) - - // modification time - s.sprintf("%lo", static_cast<unsigned long>(mtime) ); // OCT - s = s.rightJustify( 11, ' ' ); - strcpy( buffer + 0x88, s.data() ); - buffer[ 0x93 ] = ' '; // space-terminate (no null after) - - // spaces, replaced by the check sum later - buffer[ 0x94 ] = 0x20; - buffer[ 0x95 ] = 0x20; - buffer[ 0x96 ] = 0x20; - buffer[ 0x97 ] = 0x20; - buffer[ 0x98 ] = 0x20; - buffer[ 0x99 ] = 0x20; - - /* From the tar sources : - Fill in the checksum field. It's formatted differently from the - other fields: it has [6] digits, a null, then a space -- rather than - digits, a space, then a null. */ - - buffer[ 0x9a ] = '\0'; - buffer[ 0x9b ] = ' '; - - // type flag (dir, file, link) - buffer[ 0x9c ] = typeflag; - - // magic + version - strcpy( buffer + 0x101, "ustar"); - strcpy( buffer + 0x107, "00" ); - - // user - strcpy( buffer + 0x109, uname ); - // group - strcpy( buffer + 0x129, gname ); - - // Header check sum - int check = 32; - for( uint j = 0; j < 0x200; ++j ) - check += buffer[j]; - s.sprintf("%o", check ); // OCT - s = s.rightJustify( 7, ' ' ); - strcpy( buffer + 0x94, s.data() ); -} - -void KTar::writeLonglink(char *buffer, const TQCString &name, char typeflag, - const char *uname, const char *gname) { - strcpy( buffer, "././@LongLink" ); - int namelen = name.length() + 1; - fillBuffer( buffer, " 0", namelen, 0, typeflag, uname, gname ); - device()->writeBlock( buffer, 0x200 ); - int offset = 0; - while (namelen > 0) { - int chunksize = QMIN(namelen, 0x200); - memcpy(buffer, name.data()+offset, chunksize); - // write long name - device()->writeBlock( buffer, 0x200 ); - // not even needed to reclear the buffer, tar doesn't do it - namelen -= chunksize; - offset += 0x200; - }/*wend*/ -} - -bool KTar::prepareWriting(const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime) { - return KArchive::prepareWriting(name,user,group,size,perm,atime,mtime,ctime); -} - -bool KTar::prepareWriting_impl(const TQString &name, const TQString &user, - const TQString &group, uint size, mode_t perm, - time_t /*atime*/, time_t mtime, time_t /*ctime*/) { - if ( !isOpened() ) - { - kdWarning(7041) << "KTar::prepareWriting: You must open the tar file before writing to it\n"; - return false; - } - - if ( !(mode() & IO_WriteOnly) ) - { - kdWarning(7041) << "KTar::prepareWriting: You must open the tar file for writing\n"; - return false; - } - - // In some tar files we can find dir/./file => call cleanDirPath - TQString fileName ( TQDir::cleanDirPath( name ) ); - - /* - // Create toplevel dirs - // Commented out by David since it's not necessary, and if anybody thinks it is, - // he needs to implement a findOrCreate equivalent in writeDir. - // But as KTar and the "tar" program both handle tar files without - // dir entries, there's really no need for that - TQString tmp ( fileName ); - int i = tmp.findRev( '/' ); - if ( i != -1 ) - { - TQString d = tmp.left( i + 1 ); // contains trailing slash - if ( !m_dirList.contains( d ) ) - { - tmp = tmp.mid( i + 1 ); - writeDir( d, user, group ); // WARNING : this one doesn't create its toplevel dirs - } - } - */ - - char buffer[ 0x201 ]; - memset( buffer, 0, 0x200 ); - if ( mode() & IO_ReadWrite ) device()->at(d->tarEnd); // Go to end of archive as might have moved with a read - - // provide converted stuff we need lateron - TQCString encodedFilename = TQFile::encodeName(fileName); - TQCString uname = user.local8Bit(); - TQCString gname = group.local8Bit(); - - // If more than 100 chars, we need to use the LongLink trick - if ( fileName.length() > 99 ) - writeLonglink(buffer,encodedFilename,'L',uname,gname); - - // Write (potentially truncated) name - strncpy( buffer, encodedFilename, 99 ); - buffer[99] = 0; - // zero out the rest (except for what gets filled anyways) - memset(buffer+0x9d, 0, 0x200 - 0x9d); - - TQCString permstr; - permstr.sprintf("%o",perm); - permstr = permstr.rightJustify(6, ' '); - fillBuffer(buffer, permstr, size, mtime, 0x30, uname, gname); - - // Write header - return device()->writeBlock( buffer, 0x200 ) == 0x200; -} - -bool KTar::writeDir(const TQString& name, const TQString& user, - const TQString& group, mode_t perm, - time_t atime, time_t mtime, time_t ctime) { - return KArchive::writeDir(name,user,group,perm,atime,mtime,ctime); -} - -bool KTar::writeDir_impl(const TQString &name, const TQString &user, - const TQString &group, mode_t perm, - time_t /*atime*/, time_t mtime, time_t /*ctime*/) { - if ( !isOpened() ) - { - kdWarning(7041) << "KTar::writeDir: You must open the tar file before writing to it\n"; - return false; - } - - if ( !(mode() & IO_WriteOnly) ) - { - kdWarning(7041) << "KTar::writeDir: You must open the tar file for writing\n"; - return false; - } - - // In some tar files we can find dir/./ => call cleanDirPath - TQString dirName ( TQDir::cleanDirPath( name ) ); - - // Need trailing '/' - if ( dirName.right(1) != "/" ) - dirName += "/"; - - if ( d->dirList.contains( dirName ) ) - return true; // already there - - char buffer[ 0x201 ]; - memset( buffer, 0, 0x200 ); - if ( mode() & IO_ReadWrite ) device()->at(d->tarEnd); // Go to end of archive as might have moved with a read - - // provide converted stuff we need lateron - TQCString encodedDirname = TQFile::encodeName(dirName); - TQCString uname = user.local8Bit(); - TQCString gname = group.local8Bit(); - - // If more than 100 chars, we need to use the LongLink trick - if ( dirName.length() > 99 ) - writeLonglink(buffer,encodedDirname,'L',uname,gname); - - // Write (potentially truncated) name - strncpy( buffer, encodedDirname, 99 ); - buffer[99] = 0; - // zero out the rest (except for what gets filled anyways) - memset(buffer+0x9d, 0, 0x200 - 0x9d); - - TQCString permstr; - permstr.sprintf("%o",perm); - permstr = permstr.rightJustify(6, ' '); - fillBuffer( buffer, permstr, 0, mtime, 0x35, uname, gname); - - // Write header - device()->writeBlock( buffer, 0x200 ); - if ( mode() & IO_ReadWrite ) d->tarEnd = device()->at(); - - d->dirList.append( dirName ); // contains trailing slash - return true; // TODO if wanted, better error control -} - -bool KTar::writeSymLink(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t atime, time_t mtime, time_t ctime) { - return KArchive::writeSymLink(name,target,user,group,perm,atime,mtime,ctime); -} - -bool KTar::writeSymLink_impl(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t /*atime*/, time_t mtime, time_t /*ctime*/) { - if ( !isOpened() ) - { - kdWarning(7041) << "KTar::writeSymLink: You must open the tar file before writing to it\n"; - return false; - } - - if ( !(mode() & IO_WriteOnly) ) - { - kdWarning(7041) << "KTar::writeSymLink: You must open the tar file for writing\n"; - return false; - } - - device()->flush(); - - // In some tar files we can find dir/./file => call cleanDirPath - TQString fileName ( TQDir::cleanDirPath( name ) ); - - char buffer[ 0x201 ]; - memset( buffer, 0, 0x200 ); - if ( mode() & IO_ReadWrite ) device()->at(d->tarEnd); // Go to end of archive as might have moved with a read - - // provide converted stuff we need lateron - TQCString encodedFilename = TQFile::encodeName(fileName); - TQCString encodedTarget = TQFile::encodeName(target); - TQCString uname = user.local8Bit(); - TQCString gname = group.local8Bit(); - - // If more than 100 chars, we need to use the LongLink trick - if (target.length() > 99) - writeLonglink(buffer,encodedTarget,'K',uname,gname); - if ( fileName.length() > 99 ) - writeLonglink(buffer,encodedFilename,'L',uname,gname); - - // Write (potentially truncated) name - strncpy( buffer, encodedFilename, 99 ); - buffer[99] = 0; - // Write (potentially truncated) symlink target - strncpy(buffer+0x9d, encodedTarget, 99); - buffer[0x9d+99] = 0; - // zero out the rest - memset(buffer+0x9d+100, 0, 0x200 - 100 - 0x9d); - - TQCString permstr; - permstr.sprintf("%o",perm); - permstr = permstr.rightJustify(6, ' '); - fillBuffer(buffer, permstr, 0, mtime, 0x32, uname, gname); - - // Write header - bool retval = device()->writeBlock( buffer, 0x200 ) == 0x200; - if ( mode() & IO_ReadWrite ) d->tarEnd = device()->at(); - return retval; -} - -void KTar::virtual_hook( int id, void* data ) { - switch (id) { - case VIRTUAL_WRITE_SYMLINK: { - WriteSymlinkParams *params = reinterpret_cast<WriteSymlinkParams *>(data); - params->retval = writeSymLink_impl(*params->name,*params->target, - *params->user,*params->group,params->perm, - params->atime,params->mtime,params->ctime); - break; - } - case VIRTUAL_WRITE_DIR: { - WriteDirParams *params = reinterpret_cast<WriteDirParams *>(data); - params->retval = writeDir_impl(*params->name,*params->user, - *params->group,params->perm, - params->atime,params->mtime,params->ctime); - break; - } - case VIRTUAL_PREPARE_WRITING: { - PrepareWritingParams *params = reinterpret_cast<PrepareWritingParams *>(data); - params->retval = prepareWriting_impl(*params->name,*params->user, - *params->group,params->size,params->perm, - params->atime,params->mtime,params->ctime); - break; - } - default: - KArchive::virtual_hook( id, data ); - }/*end switch*/ -} - diff --git a/kio/kio/ktar.h b/kio/kio/ktar.h deleted file mode 100644 index fc238073c..000000000 --- a/kio/kio/ktar.h +++ /dev/null @@ -1,171 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - Copyright (C) 2003 Leo Savernik <l.savernik@aon.at> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __ktar_h -#define __ktar_h - -#include <sys/stat.h> -#include <sys/types.h> - -#include <tqdatetime.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqdict.h> - -#include <karchive.h> - -/** - * A class for reading / writing (optionally compressed) tar archives. - * - * KTar allows you to read and write tar archives, including those - * that are compressed using gzip, bzip2, or xz. - * - * @author Torben Weis <weis@kde.org>, David Faure <faure@kde.org> - */ -class TDEIO_EXPORT KTar : public KArchive -{ -public: - /** - * Creates an instance that operates on the given filename - * using the compression filter associated to given mimetype. - * - * @param filename is a local path (e.g. "/home/weis/myfile.tgz") - * @param mimetype "application/x-gzip", "application/x-bzip2", - * or "application/x-xz" - * Do not use application/x-tgz or similar - you only need to - * specify the compression layer ! If the mimetype is omitted, it - * will be determined from the filename. - */ - KTar( const TQString& filename, const TQString & mimetype = TQString::null ); - - /** - * Creates an instance that operates on the given device. - * The device can be compressed (KFilterDev) or not (TQFile, etc.). - * @warning Do not assume that giving a TQFile here will decompress the file, - * in case it's compressed! - * @param dev the device to read from. If the source is compressed, the - * TQIODevice must take care of decompression - */ - KTar( TQIODevice * dev ); - - /** - * If the tar ball is still opened, then it will be - * closed automatically by the destructor. - */ - virtual ~KTar(); - - /** - * The name of the tar file, as passed to the constructor - * Null if you used the TQIODevice constructor. - * @return the name of the file, or TQString::null if unknown - */ - TQString fileName() { return m_filename; } // TODO KDE4 const - - /** - * Special function for setting the "original file name" in the gzip header, - * when writing a tar.gz file. It appears when using in the "file" command, - * for instance. Should only be called if the underlying device is a KFilterDev! - * @param fileName the original file name - */ - void setOrigFileName( const TQCString & fileName ); - - // TODO(BIC) make virtual. For now it must be implemented by virtual_hook. - bool writeSymLink(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t atime, time_t mtime, time_t ctime); - virtual bool writeDir( const TQString& name, const TQString& user, const TQString& group ); - // TODO(BIC) make virtual. For now it must be implemented by virtual_hook. - bool writeDir( const TQString& name, const TQString& user, const TQString& group, - mode_t perm, time_t atime, time_t mtime, time_t ctime ); - virtual bool prepareWriting( const TQString& name, const TQString& user, const TQString& group, uint size ); - // TODO(BIC) make virtual. For now it must be implemented by virtual_hook. - bool prepareWriting( const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime ); - virtual bool doneWriting( uint size ); - -protected: - /** - * Opens the archive for reading. - * Parses the directory listing of the archive - * and creates the KArchiveDirectory/KArchiveFile entries. - * @param mode the mode of the file - */ - virtual bool openArchive( int mode ); - virtual bool closeArchive(); - -private: - /** - * @internal - */ - void prepareDevice( const TQString & filename, const TQString & mimetype, bool forced = false ); - - /** - * @internal - * Fills @p buffer for writing a file as required by the tar format - * Has to be called LAST, since it does the checksum - * (normally, only the name has to be filled in before) - * @param mode is expected to be 6 chars long, [uname and gname 31]. - */ - void fillBuffer( char * buffer, const char * mode, int size, time_t mtime, - char typeflag, const char * uname, const char * gname ); - - /** - * @internal - * Writes an overlong name into a special longlink entry. Call this - * if the file name or symlink target (or both) are longer than 99 chars. - * @p buffer buffer at least 0x200 bytes big to be used as a write buffer - * @p name 8-bit encoded file name to be written - * @p typeflag specifying the type of the entry, 'L' for filenames or - * 'K' for symlink targets. - * @p uname user name - * @p gname group name - */ - void writeLonglink(char *buffer, const TQCString &name, char typeflag, - const char *uname, const char *gname); - - TQ_LONG readRawHeader(char *buffer); - bool readLonglink(char *buffer,TQCString &longlink); - TQ_LONG readHeader(char *buffer,TQString &name,TQString &symlink); - - TQString m_filename; -protected: - virtual void virtual_hook( int id, void* data ); - bool prepareWriting_impl(const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime); - bool writeDir_impl(const TQString& name, const TQString& user, - const TQString& group, mode_t perm, - time_t atime, time_t mtime, time_t ctime ); - bool writeSymLink_impl(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t atime, time_t mtime, time_t ctime); -private: - class KTarPrivate; - KTarPrivate * d; -}; - -/** - * Old, deprecated naming - */ -#define KTarGz KTar -#define KTarEntry KArchiveEntry -#define KTarFile KArchiveFile -#define KTarDirectory KArchiveDirectory - -#endif diff --git a/kio/kio/ktrader.cpp b/kio/kio/ktrader.cpp deleted file mode 100644 index 585c6a499..000000000 --- a/kio/kio/ktrader.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "ktrader.h" -#include "ktraderparsetree.h" - -#include <tqtl.h> -#include <tqbuffer.h> - -#include <kuserprofile.h> -#include <kstandarddirs.h> -#include <kstaticdeleter.h> -#include <kdebug.h> - -template class KStaticDeleter<KTrader>; - -using namespace TDEIO; - -class KTraderSorter -{ -public: - KTraderSorter() { m_pService = 0; }; - KTraderSorter( const KTraderSorter& s ) : m_userPreference( s.m_userPreference ), - m_bAllowAsDefault( s.m_bAllowAsDefault ), - m_traderPreference( s.m_traderPreference ), m_pService( s.m_pService ) { } - KTraderSorter( const KService::Ptr &_service, double _pref1, int _pref2, bool _default ) - { m_pService = _service; - m_userPreference = _pref2; - m_traderPreference = _pref1; - m_bAllowAsDefault = _default; - } - - KService::Ptr service() const { return m_pService; } - - bool operator< ( const KTraderSorter& ) const; - -private: - /** - * The bigger this number is, the better is this service in - * the users opinion. - */ - int m_userPreference; - /** - * Is it allowed to use this service for default actions. - */ - bool m_bAllowAsDefault; - - /** - * The bigger this number is, the better is this service with - * respect to the queries preferences expression. - */ - double m_traderPreference; - - KService::Ptr m_pService; -}; - -bool KTraderSorter::operator< ( const KTraderSorter& _o ) const -{ - if ( _o.m_bAllowAsDefault && !m_bAllowAsDefault ) - return true; - if ( _o.m_userPreference > m_userPreference ) - return true; - if ( _o.m_userPreference < m_userPreference ) - return false; - if ( _o.m_traderPreference > m_traderPreference ) - return true; - return false; -} - -// -------------------------------------------------- - -KTrader* KTrader::s_self = 0; -static KStaticDeleter<KTrader> ktradersd; - -KTrader* KTrader::self() -{ - if ( !s_self ) - ktradersd.setObject( s_self, new KTrader ); - - return s_self; -} - -KTrader::KTrader() -{ -} - -KTrader::~KTrader() -{ -} - -KTrader::OfferList KTrader::query( const TQString& _servicetype, const TQString& _constraint, - const TQString& _preferences ) const -{ - return query( _servicetype, TQString::null, _constraint, _preferences ); -} - -KTrader::OfferList KTrader::query( const TQString& _servicetype, const TQString& _genericServiceType, - const TQString& _constraint, - const TQString& _preferences ) const -{ - // TODO: catch errors here - ParseTreeBase::Ptr constr; - ParseTreeBase::Ptr prefs; - - if ( !_constraint.isEmpty() ) - constr = TDEIO::parseConstraints( _constraint ); - - if ( !_preferences.isEmpty() ) - prefs = TDEIO::parsePreferences( _preferences ); - - KServiceTypeProfile::OfferList lst; - KTrader::OfferList ret; - - // Get all services of this service type. - lst = KServiceTypeProfile::offers( _servicetype, _genericServiceType ); - if ( lst.count() == 0 ) - return ret; - - if ( !!constr ) - { - // Find all services matching the constraint - // and remove the other ones - KServiceTypeProfile::OfferList::Iterator it = lst.begin(); - while( it != lst.end() ) - { - if ( matchConstraint( constr, (*it).service(), lst ) != 1 ) - it = lst.remove( it ); - else - ++it; - } - } - - if ( !!prefs ) - { - TQValueList<KTraderSorter> sorter; - KServiceTypeProfile::OfferList::Iterator it = lst.begin(); - for( ; it != lst.end(); ++it ) - { - PreferencesReturn p = matchPreferences( prefs, (*it).service(), lst ); - if ( p.type == PreferencesReturn::PRT_DOUBLE ) - sorter.append( KTraderSorter( (*it).service(), p.f, (*it).preference(), (*it).allowAsDefault() ) ); - } - qBubbleSort( sorter ); - - TQValueList<KTraderSorter>::Iterator it2 = sorter.begin(); - for( ; it2 != sorter.end(); ++it2 ) - ret.prepend( (*it2).service() ); - } - else - { - KServiceTypeProfile::OfferList::Iterator it = lst.begin(); - for( ; it != lst.end(); ++it ) - ret.append( (*it).service() ); - } - -#ifndef NDEBUG - TQString query = _servicetype; - if ( !_genericServiceType.isEmpty() ) { - query += ", "; - query += _genericServiceType; - } - kdDebug(7014) << "query for " << query - << " : returning " << ret.count() << " offers" << endl; -#endif - return ret; -} - -void KTrader::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -#include "ktrader.moc" diff --git a/kio/kio/ktrader.h b/kio/kio/ktrader.h deleted file mode 100644 index 98891b48d..000000000 --- a/kio/kio/ktrader.h +++ /dev/null @@ -1,295 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __ktrader_h__ -#define __ktrader_h__ - -#include <tqstring.h> -#include <tqobject.h> -#include <kservice.h> - -/** - * A Trader interface, similar to the CORBA Trader. - * - * Basically, it provides a way for an application to query - * all KDE services (that is, applications and components) that match - * a specific set of requirements. This allows you to find an - * application in real-time without you having to hard-code the name - * and/or path of the application. - * - * \par Examples - * - * A few examples will make this a lot more clear. - * - * Say you have an application that will display HTML. In this - * example, you don't want to link to tdehtml... and furthermore, you - * really don't care if the HTML browser is ours or not, as long as - * it works. The way that you formulate your query as well as the way - * that you execute the browser depends on whether or not you want the - * browser to run stand-alone or embedded. - * - * If you want the browser to run standalone, then you will limit the - * query to search for all services that handle 'text/html' @em and, - * furthermore, they must be applications (Type=Application). You - * then will use KRun::run() to invoke the application. In "trader-speak", - * this looks like this: - * \code - * KTrader::OfferList offers = KTrader::self()->query("text/html", "Type == 'Application'"); - * KService::Ptr ptr = offers.first(); - * KURL::List lst; - * lst.append("http://www.kde.org/index.html"); - * KRun::run(*ptr, lst); - * \endcode - * - * Now, say that you want to list all KParts component that can handle HTML. - * \code - * KTrader::OfferList offers = KTrader::self()->query("text/html", "KParts/ReadOnlyPart"); - * \endcode - * - * If you want to get the preferred KParts component for text/html you could use - * KServiceTypeProfile::preferredService("text/html", "KParts/ReadOnlyPart"), although if this is about - * loading that component you would rather use KParts::ComponentFactory directly. - * - * - * Please note that when including property names containing arithmetic operators like - or +, then you have - * to put brackets around the property name, in order to correctly separate arithmetic operations from - * the name. So for example a constraint expression like - * X-TDE-Blah < 4 - * needs to be written as - * [X-TDE-Blah] < 4 - * otherwise it could also be interpreted as - * Substract the numeric value of the property "KDE" and "Blah" from the property "X" and make sure it - * is less than 4. - * Instead of the other meaning, make sure that the numeric value of "X-TDE-Blah" is less than 4. - * - * See also the formal syntax defined in @ref tradersyntax . - * - * @short Provides a way to query the KDE infrastructure for specific - * applications or components. - * @author Torben Weis <weis@kde.org> - */ -class TDEIO_EXPORT KTrader : public TQObject -{ - Q_OBJECT -public: - /** - * A list of services. - */ - typedef TQValueList<KService::Ptr> OfferList; - typedef TQValueListIterator<KService::Ptr> OfferListIterator; - - /** - * Standard destructor - */ - virtual ~KTrader(); - - /** - * The main function in the KTrader class. - * - * It will return a list of services that match your - * specifications. The only required parameter is the service - * type. This is something like 'text/plain' or 'text/html'. The - * constraint parameter is used to limit the possible choices - * returned based on the constraints you give it. - * - * The @p constraint language is rather full. The most common - * keywords are AND, OR, NOT, IN, and EXIST, all used in an - * almost spoken-word form. An example is: - * \code - * (Type == 'Service') and (('KParts/ReadOnlyPart' in ServiceTypes) or (exist Exec)) - * \endcode - * - * The keys used in the query (Type, ServiceType, Exec) are all - * fields found in the .desktop files. - * - * @param servicetype A service type like 'text/plain', 'text/html', or 'KOfficePlugin'. - * @param constraint A constraint to limit the choices returned, TQString::null to - * get all services of the given @p servicetype - * @param preferences Indicates a particular preference to return, TQString::null to ignore. - * Uses an expression in the constraint language that must return - * a number - * - * @return A list of services that satisfy the query - * @see http://developer.kde.org/documentation/library/3.5-api/tdelibs-apidocs/kio/kio/html/tradersyntax.html - */ - virtual OfferList query( const TQString& servicetype, - const TQString& constraint = TQString::null, - const TQString& preferences = TQString::null) const; - - /** - * A variant of query(), that takes two service types as an input. - * It is not exactly the same as adding the second service type - * in the constraints of the other query call, because this one - * takes into account user preferences for this combination of service types. - * - * Example usage: - * To get list of applications that can handle a given mimetype, - * set @p servicetype to the mimetype and @p genericServiceType is "Application". - * To get list of embeddable components that can handle a given mimetype, - * set @p servicetype to the mimetype and @p genericServiceType is "KParts/ReadOnlyPart". - * - * @param servicetype A service type like 'text/plain', 'text/html', or 'KOfficePlugin'. - * @param genericServiceType a basic service type, like 'KParts/ReadOnlyPart' or 'Application' - * @param constraint A constraint to limit the choices returned, TQString::null to - * get all services of the given @p servicetype - * @param preferences Indicates a particular preference to return, TQString::null to ignore. - * Uses an expression in the constraint language that must return - * a number - * - * @return A list of services that satisfy the query - * @see http://developer.kde.org/documentation/library/kdeqt/tradersyntax.html - */ - OfferList query( const TQString& servicetype, const TQString& genericServiceType, - const TQString& constraint /*= TQString::null*/, - const TQString& preferences /*= TQString::null*/) const; - - /** - * This is a static pointer to a KTrader instance. - * - * You will need - * to use this to access the KTrader functionality since the - * constuctors are protected. - * - * @return Static KTrader instance - */ - static KTrader* self(); - -protected: - /** - * @internal - */ - KTrader(); - -private: - static KTrader* s_self; -protected: - virtual void virtual_hook( int id, void* data ); -}; - -/** @page tradersyntax Trader Syntax - * - * - * @section Literals - * - * As elementary atoms of the constraint language, KTrader supports - * booleans, integers, floats and strings. Boolean literals are - * @a TRUE and @a FALSE . Integers can be positive or negative, - * i.e. @a 42 and @a -10 are legal values. Floating point - * numbers are @a 3.141592535 or @a -999.999 . Scientific notation - * like @a 1.5e-2 is not supported. Character literals are delimited - * by single quotation marks, e.g. @a 'Bernd' . - * - * - * @section Symbols - * - * Identifiers in query string are interpreted as property names, which - * are listed in the service's <tt>.desktop</tt> file. For example, - * <tt>Name</tt> is the name of the service, <tt>ServiceTypes</tt> is a - * list of the service types it supports. Note that only properties can - * be written as-is which start with an alphabetical character and contain - * only alphanumerical characters. Other properties have to be enclosed in - * brackets, e.g. <tt>[X-TDE-Init]</tt>. Properties must not contain any - * special characters other than <tt>-</tt>. - * - * Special property names: - * - <b>DesktopEntryName</b> stands for the filename of the service - * desktop entry without any extension. This can be useful to - * exclude some specific services. - * - <b>DesktopEntryPath</b> stands for the relative or full path - * to the .desktop file, see KService::desktopEntryPath. Mentionned - * here for completeness, better not use it (things can be moved - * around). - * - <b>Library</b> is the property whose value is set by - * <tt>X-TDE-Library</tt> in the .desktop file. This renaming - * happened to conform to the desktop file standard, but the - * property name didn't change. - * - * - * @section Comparison - * - * Supported comparison operators are: - * - * - <tt>==</tt> - * - <tt>!=</tt> - * - <tt><</tt> - * - <tt><=</tt> - * - <tt>></tt> - * - <tt>>=</tt> - * - * - * @section Arithmetic Arithmetic and boolean expressions - * - * - <tt>+</tt> - * - <tt>-</tt> - * - <tt>*</tt> - * - <tt>/</tt> - * - <tt>and</tt> - * - <tt>or</tt> - * - <tt>not</tt> - * - * Note that the arithmetic operators are possible for integers and - * floating point numbers. <tt>-</tt> is both a unary and binary operator, - * <tt>not</tt> is a unary operator. - * - * - * @section Other Other operators - * - * - <tt>~</tt> - * - <tt>in</tt> - * - <tt>exist</tt> - * - <tt>()</tt> - * - * The tilde operator stands for a substring match. For example, - * <tt>KParts ~ 'KParts/ReadOnlyPart'</tt> is TRUE. The membership - * operator <tt>in</tt> tests whether a value is in a list. A list is a - * string with semi-colon- or comma-separated entries, depending on the - * type. An example for the membership operator is - * <tt>'text/plain' in ServiceTypes</tt>. - * The <tt>exist</tt> tests whether a certain property is defined in the - * <tt>.desktop</tt> file. Subexpressions are written in parentheses. - * - * Warning, testing the contents of a property only works if the property - * is specified. There is not support for default values. If the property - * might be missing, and you still want such services to be included, you - * have to check for existence before testing it. For instance, to say - * that MyProp is a boolean that defaults to true, and that you want the - * services that have it set to true, use: - * <tt>not exist MyProp or MyProp</tt> - * Simply testing for <tt>MyProp</tt> would - * exclude the services without the property at all. - * - * - * @section Examples - * - * The following examples show filters for .desktop files. - * <tt>Type</tt>, <tt>ServiceTypes</tt> and <tt>MimeType</tt> are - * properties in .desktop files. Be aware that within KTrader MimeType - * properties are understood as ServiceTypes ones. - * - * - * - <tt>Type == 'Application'</tt>@n - * All services that are applications. - * - <tt>'KParts/ReadOnlyPart' in ServiceTypes</tt>@n - * All read-only KParts. - * - <tt>('KParts/ReadOnlyPart' in ServiceTypes) and ('text/plain' in ServiceTypes)</tt>@n - * All read-only KParts that handle the mime type 'text/plain'. - * - * @author Bernd Gehrmann <a href="mailto:bernd@tdevelop.org">bernd@tdevelop.org</a> -*/ - - -#endif diff --git a/kio/kio/ktraderparse.cpp b/kio/kio/ktraderparse.cpp deleted file mode 100644 index 627791c00..000000000 --- a/kio/kio/ktraderparse.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <assert.h> -#include <stdlib.h> - -// TODO: Torben: On error free memory! - -extern "C" -{ -#include "ktraderparse.h" -} - -#include "ktraderparsetree.h" -#include <kdebug.h> - -using namespace TDEIO; - -static ParseTreeBase::Ptr *pTree = 0; -static const char* sCode = 0; - -ParseTreeBase::Ptr TDEIO::parseConstraints( const TQString& _constr ) -{ - TQCString str = _constr.utf8(); - sCode = str.data(); - KTraderParse_mainParse( sCode ); - sCode = 0; - assert( pTree ); - return *pTree; -} - -ParseTreeBase::Ptr TDEIO::parsePreferences( const TQString& _prefs ) -{ - TQCString str = _prefs.utf8(); - sCode = str.data(); - KTraderParse_mainParse( sCode ); - sCode = 0; - assert( pTree ); - return *pTree; -} - -void KTraderParse_setParseTree( void *_ptr1 ) -{ - if ( !pTree ) - pTree = new ParseTreeBase::Ptr; // ### leak; should use KStaticDeleter - *pTree = static_cast<ParseTreeBase*>( _ptr1 ); -} - - -void KTraderParse_error( const char* err ) -{ - kdWarning(7014) << "Parsing '" << sCode << "' gave " << err << endl; -} - -void* KTraderParse_newOR( void *_ptr1, void *_ptr2 ) -{ - return new ParseTreeOR( (ParseTreeBase*)_ptr1, (ParseTreeBase*)_ptr2 ); -} - -void* KTraderParse_newAND( void *_ptr1, void *_ptr2 ) -{ - return new ParseTreeAND( (ParseTreeBase*)_ptr1, (ParseTreeBase*)_ptr2 ); -} - -void* KTraderParse_newCMP( void *_ptr1, void *_ptr2, int _i ) -{ - return new ParseTreeCMP( (ParseTreeBase*)_ptr1, (ParseTreeBase*)_ptr2, _i ); -} - -void* KTraderParse_newIN( void *_ptr1, void *_ptr2 ) -{ - return new ParseTreeIN( (ParseTreeBase*)_ptr1, (ParseTreeBase*)_ptr2 ); -} - -void* KTraderParse_newMATCH( void *_ptr1, void *_ptr2 ) -{ - return new ParseTreeMATCH( (ParseTreeBase*)_ptr1, (ParseTreeBase*)_ptr2 ); -} - -void* KTraderParse_newCALC( void *_ptr1, void *_ptr2, int _i ) -{ - return new ParseTreeCALC( (ParseTreeBase*)_ptr1, (ParseTreeBase*)_ptr2, _i ); -} - -void* KTraderParse_newBRACKETS( void *_ptr1 ) -{ - return new ParseTreeBRACKETS( (ParseTreeBase*)_ptr1 ); -} - -void* KTraderParse_newNOT( void *_ptr1 ) -{ - return new ParseTreeNOT( (ParseTreeBase*)_ptr1 ); -} - -void* KTraderParse_newEXIST( char *_ptr1 ) -{ - ParseTreeEXIST *t = new ParseTreeEXIST( _ptr1 ); - free(_ptr1); - return t; -} - -void* KTraderParse_newID( char *_ptr1 ) -{ - ParseTreeID *t = new ParseTreeID( _ptr1 ); - free(_ptr1); - return t; -} - -void* KTraderParse_newSTRING( char *_ptr1 ) -{ - ParseTreeSTRING *t = new ParseTreeSTRING( _ptr1 ); - free(_ptr1); - return t; -} - -void* KTraderParse_newNUM( int _i ) -{ - return new ParseTreeNUM( _i ); -} - -void* KTraderParse_newFLOAT( float _f ) -{ - return new ParseTreeDOUBLE( _f ); -} - -void* KTraderParse_newBOOL( char _b ) -{ - return new ParseTreeBOOL( (bool)_b ); -} - -void* KTraderParse_newMAX2( char *_id ) -{ - ParseTreeMAX2 *t = new ParseTreeMAX2( _id ); - free(_id); - return t; -} - -void* KTraderParse_newMIN2( char *_id ) -{ - ParseTreeMIN2 *t = new ParseTreeMIN2( _id ); - free(_id); - return t; -} diff --git a/kio/kio/ktraderparse.h b/kio/kio/ktraderparse.h deleted file mode 100644 index bfeb15fe0..000000000 --- a/kio/kio/ktraderparse.h +++ /dev/null @@ -1,52 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __parse_h__ -#define __parse_h__ - -/* - * Functions definition for yacc - */ -void KTraderParse_mainParse( const char *_code ); -void KTraderParse_setParseTree( void *_ptr1 ); -void KTraderParse_error( const char* err ); -void* KTraderParse_newOR( void *_ptr1, void *_ptr2 ); -void* KTraderParse_newAND( void *_ptr1, void *_ptr2 ); -void* KTraderParse_newCMP( void *_ptr1, void *_ptr2, int _i ); -void* KTraderParse_newIN( void *_ptr1, void *_ptr2 ); -void* KTraderParse_newMATCH( void *_ptr1, void *_ptr2 ); -void* KTraderParse_newCALC( void *_ptr1, void *_ptr2, int _i ); -void* KTraderParse_newBRACKETS( void *_ptr1 ); -void* KTraderParse_newNOT( void *_ptr1 ); -void* KTraderParse_newEXIST( char *_ptr1 ); -void* KTraderParse_newID( char *_ptr1 ); -void* KTraderParse_newSTRING( char *_ptr1 ); -void* KTraderParse_newNUM( int _i ); -void* KTraderParse_newFLOAT( float _f ); -void* KTraderParse_newBOOL( char _b ); - -void* KTraderParse_newWITH( void *_ptr1 ); -void* KTraderParse_newMAX( void *_ptr1 ); -void* KTraderParse_newMIN( void *_ptr1 ); -void* KTraderParse_newMAX2( char *_id ); -void* KTraderParse_newMIN2( char *_id ); -void* KTraderParse_newFIRST(); -void* KTraderParse_newRANDOM(); - -#endif diff --git a/kio/kio/ktraderparsetree.cpp b/kio/kio/ktraderparsetree.cpp deleted file mode 100644 index 0a04b7918..000000000 --- a/kio/kio/ktraderparsetree.cpp +++ /dev/null @@ -1,714 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "ktraderparsetree.h" - -namespace TDEIO { - -bool ParseTreeOR::eval( ParseContext *_context ) const -{ - ParseContext c1( _context ); - ParseContext c2( _context ); - -// don't evaluate both expressions but return immediately -// if the first one of them succeeds. Otherwise queries like -// ((not exist Blah) or (Blah == 'Foo')) do not work, because -// the evaluation of the second term ends up in a fatal error -// (Simon) - - if ( !m_pLeft->eval( &c1 ) ) - return false; - - if ( c1.type != ParseContext::T_BOOL ) - return false; - - _context->b = c1.b; - _context->type = ParseContext::T_BOOL; - if ( c1.b ) - return true; - - if ( !m_pRight->eval( &c2 ) ) - return false; - - if ( c2.type != ParseContext::T_BOOL ) - return false; - - _context->b = ( c1.b || c2.b ); - _context->type = ParseContext::T_BOOL; - - return true; -} - -bool ParseTreeAND::eval( ParseContext *_context ) const -{ - _context->type = ParseContext::T_BOOL; - - ParseContext c1( _context ); - ParseContext c2( _context ); - if ( !m_pLeft->eval( &c1 ) ) - return false; - if ( c1.type != ParseContext::T_BOOL ) - return false; - if ( !c1.b ) - { - _context->b = false; - return true; - } - - if ( !m_pRight->eval( &c2 ) ) - return false; - if ( c2.type != ParseContext::T_BOOL ) - return false; - - _context->b = ( c1.b && c2.b ); - - return true; -} - -bool ParseTreeCALC::eval( ParseContext *_context ) const -{ - ParseContext c1( _context ); - ParseContext c2( _context ); - if ( !m_pLeft->eval( &c1 ) ) - return false; - if ( !m_pRight->eval( &c2 ) ) - return false; - - // Bool extension - if ( c1.type != ParseContext::T_NUM && c1.type != ParseContext::T_DOUBLE && c1.type != ParseContext::T_BOOL ) - return false; - // Bool extension - if ( c2.type != ParseContext::T_NUM && c2.type != ParseContext::T_DOUBLE && c2.type != ParseContext::T_BOOL ) - return false; - // Bool extension - if ( c1.type == ParseContext::T_BOOL && c2.type == ParseContext::T_BOOL ) - return false; - - /** - * Make types compatible - */ - if ( c1.type == ParseContext::T_NUM && c2.type == ParseContext::T_DOUBLE ) - { - c1.type = ParseContext::T_DOUBLE; - c1.f = (double)c1.i; - } - else if ( c1.type == ParseContext::T_DOUBLE && c2.type == ParseContext::T_NUM ) - { - c2.type = ParseContext::T_DOUBLE; - c2.f = (double)c2.i; - } - // Bool extension - else if ( c1.type == ParseContext::T_BOOL && c2.type == ParseContext::T_NUM ) - { - c1.type = ParseContext::T_NUM; - if ( c1.b ) - c1.i = 1; - else - c1.i = -1; - } - // Bool extension - else if ( c1.type == ParseContext::T_BOOL && c2.type == ParseContext::T_DOUBLE ) - { - c1.type = ParseContext::T_DOUBLE; - if ( c1.b ) - c1.f = 1.0; - else - c1.f = -1.0; - } - // Bool extension - else if ( c1.type == ParseContext::T_NUM && c2.type == ParseContext::T_BOOL ) - { - c2.type = ParseContext::T_NUM; - if ( c2.b ) - c2.i = 1; - else - c2.i = -1; - } - // Bool extension - else if ( c1.type == ParseContext::T_DOUBLE && c2.type == ParseContext::T_BOOL ) - { - c2.type = ParseContext::T_DOUBLE; - if ( c2.b ) - c2.f = 1.0; - else - c2.f = -1.0; - } - - _context->type = c1.type; - - /** - * Calculate - */ - switch( m_cmd ) - { - case 1: /* Add */ - if ( c1.type == ParseContext::T_DOUBLE ) - { - _context->f = ( c1.f + c2.f ); - return true; - } - if ( c1.type == ParseContext::T_NUM ) - { - _context->i = ( c1.i + c2.i ); - return true; - } - break; - case 2: /* Sub */ - if ( c1.type == ParseContext::T_DOUBLE ) - { - _context->f = ( c1.f - c2.f ); - return true; - } - if ( c1.type == ParseContext::T_NUM ) - { - _context->i = ( c1.i - c2.i ); - return true; - } - break; - case 3: /* Mul */ - if ( c1.type == ParseContext::T_DOUBLE ) - { - //cout << "Double Mult" << endl; - _context->f = ( c1.f * c2.f ); - return true; - } - if ( c1.type == ParseContext::T_NUM ) - { - _context->i = ( c1.i * c2.i ); - return true; - } - break; - case 4: /* Div */ - if ( c1.type == ParseContext::T_DOUBLE ) - { - _context->f = ( c1.f / c2.f ); - return true; - } - if ( c1.type == ParseContext::T_NUM ) - { - _context->i = ( c1.i / c2.i ); - return true; - } - break; - } - - return false; -} - -bool ParseTreeCMP::eval( ParseContext *_context ) const -{ - //cout << "CMP 1 cmd=" << m_cmd << endl; - ParseContext c1( _context ); - ParseContext c2( _context ); - if ( !m_pLeft->eval( &c1 ) ) - return false; - - if ( !m_pRight->eval( &c2 ) ) - return false; - - /** - * Make types compatible - */ - if ( c1.type == ParseContext::T_NUM && c2.type == ParseContext::T_DOUBLE ) - { - c1.type = ParseContext::T_DOUBLE; - c1.f = (double)c1.i; - } - else if ( c1.type == ParseContext::T_DOUBLE && c2.type == ParseContext::T_NUM ) - { - c2.type = ParseContext::T_DOUBLE; - c2.f = (double)c2.i; - } - - /** - * Compare - */ - _context->type = ParseContext::T_BOOL; - - switch( m_cmd ) - { - case 1: /* EQ */ - if ( c1.type != c2.type ) - { - _context->b = false; - return true; - } - if ( c1.type == ParseContext::T_STRING ) - { - _context->b = ( c1.str == c2.str ); - return true; - } - if ( c1.type == ParseContext::T_BOOL ) - { - _context->b = ( c1.b == c2.b ); - return true; - } - if ( c1.type == ParseContext::T_DOUBLE ) - { - _context->b = ( c1.f == c2.f ); - return true; - } - if ( c1.type == ParseContext::T_NUM ) - { - _context->b = ( c1.i == c2.i ); - return true; - } - break; - case 2: /* NEQ */ - if ( c1.type != c2.type ) - { - _context->b = true; - return true; - } - if ( c1.type == ParseContext::T_STRING ) - { - _context->b = ( c1.str != c2.str ); - return true; - } - if ( c1.type == ParseContext::T_BOOL ) - { - _context->b = ( c1.b != c2.b ); - return true; - } - if ( c1.type == ParseContext::T_DOUBLE ) - { - _context->b = ( c1.f != c2.f ); - return true; - } - if ( c1.type == ParseContext::T_NUM ) - { - _context->b = ( c1.i != c2.i ); - return true; - } - break; - case 3: /* GEQ */ - if ( c1.type != c2.type ) - { - _context->b = false; - return true; - } - if ( c1.type == ParseContext::T_DOUBLE ) - { - _context->b = ( c1.f >= c2.f ); - return true; - } - if ( c1.type == ParseContext::T_NUM ) - { - _context->b = ( c1.i >= c2.i ); - return true; - } - _context->b = false; - return true; - - case 4: /* LEQ */ - if ( c1.type != c2.type ) - { - _context->b = false; - return true; - } - if ( c1.type == ParseContext::T_DOUBLE ) - { - _context->b = ( c1.f <= c2.f ); - return true; - } - if ( c1.type == ParseContext::T_NUM ) - { - _context->b = ( c1.i <= c2.i ); - return true; - } - _context->b = false; - return true; - - case 5: /* < */ - if ( c1.type != c2.type ) - { - _context->b = false; - return true; - } - if ( c1.type == ParseContext::T_DOUBLE ) - { - _context->b = ( c1.f < c2.f ); - return true; - } - if ( c1.type == ParseContext::T_NUM ) - { - _context->b = ( c1.i < c2.i ); - return true; - } - _context->b = false; - return true; - - case 6: /* > */ - if ( c1.type != c2.type ) - { - _context->b = false; - return true; - } - if ( c1.type == ParseContext::T_DOUBLE ) - { - _context->b = ( c1.f > c2.f ); - return true; - } - if ( c1.type == ParseContext::T_NUM ) - { - _context->b = ( c1.i > c2.i ); - return true; - } - _context->b = false; - return true; - - } - - return false; -} - -bool ParseTreeNOT::eval( ParseContext *_context ) const -{ - ParseContext c1( _context ); - if ( !m_pLeft->eval( &c1 ) ) - return false; - if ( c1.type != ParseContext::T_BOOL ) - return false; - - _context->b = !c1.b; - _context->type = ParseContext::T_BOOL; - - return true; -} - -bool ParseTreeEXIST::eval( ParseContext *_context ) const -{ - _context->type = ParseContext::T_BOOL; - - TQVariant prop = _context->service->property( m_id ); - _context->b = prop.isValid(); - - return true; -} - -bool ParseTreeMATCH::eval( ParseContext *_context ) const -{ - _context->type = ParseContext::T_BOOL; - - ParseContext c1( _context ); - ParseContext c2( _context ); - if ( !m_pLeft->eval( &c1 ) ) - return false; - if ( !m_pRight->eval( &c2 ) ) - return false; - if ( c1.type != ParseContext::T_STRING || c2.type != ParseContext::T_STRING ) - return false; - - _context->b = ( c2.str.find( c1.str ) != -1 ); - - return true; -} - -bool ParseTreeIN::eval( ParseContext *_context ) const -{ - _context->type = ParseContext::T_BOOL; - - ParseContext c1( _context ); - ParseContext c2( _context ); - if ( !m_pLeft->eval( &c1 ) ) - return false; - if ( !m_pRight->eval( &c2 ) ) - return false; - - if ( (c1.type == ParseContext::T_NUM) && - (c2.type == ParseContext::T_SEQ) && - ((*(c2.seq.begin())).type() == TQVariant::Int)) { - - TQValueList<TQVariant>::ConstIterator it = c2.seq.begin(); - TQValueList<TQVariant>::ConstIterator end = c2.seq.end(); - _context->b = false; - for (; it != end; it++) - if ((*it).type() == TQVariant::Int && - (*it).toInt() == c1.i) { - _context->b = true; - break; - } - return true; - } - - if ( c1.type == ParseContext::T_DOUBLE && - c2.type == ParseContext::T_SEQ && - (*(c2.seq.begin())).type() == TQVariant::Double) { - - TQValueList<TQVariant>::ConstIterator it = c2.seq.begin(); - TQValueList<TQVariant>::ConstIterator end = c2.seq.end(); - _context->b = false; - for (; it != end; it++) - if ((*it).type() == TQVariant::Double && - (*it).toDouble() == c1.i) { - _context->b = true; - break; - } - return true; - } - - if ( c1.type == ParseContext::T_STRING && c2.type == ParseContext::T_STR_SEQ ) - { - _context->b = ( c2.strSeq.find( c1.str ) != c2.strSeq.end() ); - return true; - } - - return false; -} - -bool ParseTreeID::eval( ParseContext *_context ) const -{ - TQVariant prop = _context->service->property( m_str ); - if ( !prop.isValid() ) - return false; - - if ( prop.type() == TQVariant::String ) - { - _context->str = prop.toString(); - _context->type = ParseContext::T_STRING; - return true; - } - - if ( prop.type() == TQVariant::Int ) - { - _context->i = prop.toInt(); - _context->type = ParseContext::T_NUM; - return true; - } - - if ( prop.type() == TQVariant::Bool ) - { - _context->b = prop.toBool(); - _context->type = ParseContext::T_BOOL; - return true; - } - - if ( prop.type() == TQVariant::Double ) - { - _context->f = prop.toDouble(); - _context->type = ParseContext::T_DOUBLE; - return true; - } - - if ( prop.type() == TQVariant::List ) - { - _context->seq = prop.toList(); - _context->type = ParseContext::T_SEQ; - return true; - } - - if ( prop.type() == TQVariant::StringList ) - { - _context->strSeq = prop.toStringList(); - _context->type = ParseContext::T_STR_SEQ; - return true; - } - - // Value has unknown type - return false; -} - -bool ParseTreeMIN2::eval( ParseContext *_context ) const -{ - _context->type = ParseContext::T_DOUBLE; - - TQVariant prop = _context->service->property( m_strId ); - if ( !prop.isValid() ) - return false; - - if ( !_context->initMaxima( m_strId ) ) - return false; - - TQMap<TQString,PreferencesMaxima>::Iterator it = _context->maxima.find( m_strId ); - if ( it == _context->maxima.end() ) - return false; - - if ( prop.type() == TQVariant::Int && it.data().type == PreferencesMaxima::PM_INT ) - { - _context->f = (double)( prop.toInt() - it.data().iMin ) / - (double)(it.data().iMax - it.data().iMin ) * (-2.0) + 1.0; - return true; - } - else if ( prop.type() == TQVariant::Double && it.data().type == PreferencesMaxima::PM_DOUBLE ) - { - _context->f = ( prop.toDouble() - it.data().fMin ) / (it.data().fMax - it.data().fMin ) - * (-2.0) + 1.0; - return true; - } - - return false; -} - -bool ParseTreeMAX2::eval( ParseContext *_context ) const -{ - _context->type = ParseContext::T_DOUBLE; - - TQVariant prop = _context->service->property( m_strId ); - if ( !prop.isValid() ) - return false; - - // Create extrema - if ( !_context->initMaxima( m_strId ) ) - return false; - - // Find extrema - TQMap<TQString,PreferencesMaxima>::Iterator it = _context->maxima.find( m_strId ); - if ( it == _context->maxima.end() ) - return false; - - if ( prop.type() == TQVariant::Int && it.data().type == PreferencesMaxima::PM_INT ) - { - _context->f = (double)( prop.toInt() - it.data().iMin ) / - (double)(it.data().iMax - it.data().iMin ) * 2.0 - 1.0; - return true; - } - else if ( prop.type() == TQVariant::Double && it.data().type == PreferencesMaxima::PM_DOUBLE ) - { - _context->f = ( prop.toDouble() - it.data().fMin ) / - (it.data().fMax - it.data().fMin ) * 2.0 - 1.0; - return true; - } - - return false; -} - -int matchConstraint( const ParseTreeBase *_tree, const KService::Ptr &_service, - const KServiceTypeProfile::OfferList& _list ) -{ - // Empty tree matches always - if ( !_tree ) - return 1; - - TQMap<TQString,PreferencesMaxima> maxima; - ParseContext c( _service, _list, maxima ); - - // Error during evaluation ? - if ( !_tree->eval( &c ) ) - return -1; - - // Did we get a bool ? - if ( c.type != ParseContext::T_BOOL ) - return -1; - - return ( c.b ? 1 : 0 ); -} - -PreferencesReturn matchPreferences( const ParseTreeBase *_tree, const KService::Ptr &_service, - const KServiceTypeProfile::OfferList& _list ) -{ - // By default: error - PreferencesReturn ret; - - if ( !_tree ) - return ret; - - TQMap<TQString,PreferencesMaxima> maxima; - ParseContext c( _service, _list, maxima ); - - if ( !_tree->eval( &c ) ) - return ret; - - // Did we get a numeric return value ? - if ( c.type == ParseContext::T_NUM ) - { - ret.type = PreferencesReturn::PRT_DOUBLE; - ret.f = (double)c.i; - } - else if ( c.type == ParseContext::T_DOUBLE ) - { - ret.type = PreferencesReturn::PRT_DOUBLE; - ret.f = c.f; - } - - return ret; -} - -bool ParseContext::initMaxima( const TQString& _prop ) -{ - // Is the property known ? - TQVariant prop = service->property( _prop ); - if ( !prop.isValid() ) - return false; - - // Numeric ? - if ( prop.type() != TQVariant::Int && prop.type() != TQVariant::Double ) - return false; - - // Did we cache the result ? - TQMap<TQString,PreferencesMaxima>::Iterator it = maxima.find( _prop ); - if ( it != maxima.end() ) - return ( it.data().type == PreferencesMaxima::PM_DOUBLE || - it.data().type == PreferencesMaxima::PM_INT ); - - // Double or Int ? - PreferencesMaxima extrema; - if ( prop.type() == TQVariant::Int ) - extrema.type = PreferencesMaxima::PM_INVALID_INT; - else - extrema.type = PreferencesMaxima::PM_INVALID_DOUBLE; - - // Iterate over all offers - KServiceTypeProfile::OfferList::ConstIterator oit = offers.begin(); - for( ; oit != offers.end(); ++oit ) - { - TQVariant p = (*oit).service()->property( _prop ); - if ( p.isValid() ) - { - // Determine new maximum/minimum - if ( extrema.type == PreferencesMaxima::PM_INVALID_INT ) - { - extrema.type = PreferencesMaxima::PM_INT; - extrema.iMin = p.toInt(); - extrema.iMax = p.toInt(); - } - // Correct existing extrema - else if ( extrema.type == PreferencesMaxima::PM_INT ) - { - if ( p.toInt() < extrema.iMin ) - extrema.iMin = p.toInt(); - if ( p.toInt() > extrema.iMax ) - extrema.iMax = p.toInt(); - } - // Determine new maximum/minimum - else if ( extrema.type == PreferencesMaxima::PM_INVALID_DOUBLE ) - { - extrema.type = PreferencesMaxima::PM_DOUBLE; - extrema.fMin = p.toDouble(); - extrema.fMax = p.toDouble(); - } - // Correct existing extrema - else if ( extrema.type == PreferencesMaxima::PM_DOUBLE ) - { - if ( p.toDouble() < it.data().fMin ) - extrema.fMin = p.toDouble(); - if ( p.toDouble() > it.data().fMax ) - extrema.fMax = p.toDouble(); - } - } - } - - // Cache the result - maxima.insert( _prop, extrema ); - - // Did we succeed ? - return ( extrema.type == PreferencesMaxima::PM_DOUBLE || - extrema.type == PreferencesMaxima::PM_INT ); -} - -} diff --git a/kio/kio/ktraderparsetree.h b/kio/kio/ktraderparsetree.h deleted file mode 100644 index a08b61a5a..000000000 --- a/kio/kio/ktraderparsetree.h +++ /dev/null @@ -1,371 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __parse_tree_h__ -#define __parse_tree_h__ - -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqvaluelist.h> -#include <tqmap.h> -#include <tqshared.h> - -#include <kservice.h> -#include <kuserprofile.h> - -#include "ktrader.h" - -namespace TDEIO { - -class ParseTreeBase; - -/** \internal */ -struct TDEIO_EXPORT PreferencesReturn -{ - enum Type { PRT_DOUBLE, PRT_ERROR }; - - PreferencesReturn() { type = PRT_ERROR; } - - PreferencesReturn( const PreferencesReturn& _r ) - { - type = _r.type; - f = _r.f; - } - - Type type; - double f; -}; - - -/** - * @internal - * @return 0 => Does not match - * 1 => Does match - * <0 => Error - */ -TDEIO_EXPORT int matchConstraint( const ParseTreeBase *_tree, const KService::Ptr &, - const KServiceTypeProfile::OfferList& ); - -/** - * @internal - * @return 1 on success or <0 on Error - */ -TDEIO_EXPORT PreferencesReturn matchPreferences( const ParseTreeBase *_tree, const KService::Ptr &, - const KServiceTypeProfile::OfferList& ); - -/** - * @internal - */ -struct TDEIO_EXPORT PreferencesMaxima -{ - enum Type { PM_ERROR, PM_INVALID_INT, PM_INVALID_DOUBLE, PM_DOUBLE, PM_INT }; - - Type type; - int iMax; - int iMin; - double fMax; - double fMin; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseContext -{ -public: - /** - * This is NOT a copy constructor. - */ - ParseContext( const ParseContext* _ctx ) : service( _ctx->service ), maxima( _ctx->maxima ), - offers( _ctx->offers ) {} - ParseContext( const KService::Ptr & _service, const KServiceTypeProfile::OfferList& _offers, - TQMap<TQString,PreferencesMaxima>& _m ) - : service( _service ), maxima( _m ), offers( _offers ) {} - - bool initMaxima( const TQString& _prop); - - enum Type { T_STRING = 1, T_DOUBLE = 2, T_NUM = 3, T_BOOL = 4, - T_STR_SEQ = 5, T_SEQ = 6 }; - - TQString str; - int i; - double f; - bool b; - TQValueList<TQVariant> seq; - TQStringList strSeq; - Type type; - - KService::Ptr service; - - TQMap<TQString,PreferencesMaxima>& maxima; - const KServiceTypeProfile::OfferList& offers; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeBase : public KShared -{ -public: - typedef KSharedPtr<ParseTreeBase> Ptr; - ParseTreeBase() { } - - virtual bool eval( ParseContext *_context ) const = 0; -protected: - virtual ~ParseTreeBase() { }; -}; - -TDEIO_EXPORT ParseTreeBase::Ptr parseConstraints( const TQString& _constr ); -TDEIO_EXPORT ParseTreeBase::Ptr parsePreferences( const TQString& _prefs ); - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeOR : public ParseTreeBase -{ -public: - ParseTreeOR( ParseTreeBase *_ptr1, ParseTreeBase *_ptr2 ) { m_pLeft = _ptr1; m_pRight = _ptr2; } - - bool eval( ParseContext *_context ) const; - -protected: - ParseTreeBase::Ptr m_pLeft; - ParseTreeBase::Ptr m_pRight; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeAND : public ParseTreeBase -{ -public: - ParseTreeAND( ParseTreeBase *_ptr1, ParseTreeBase *_ptr2 ) { m_pLeft = _ptr1; m_pRight = _ptr2; } - - bool eval( ParseContext *_context ) const; - -protected: - ParseTreeBase::Ptr m_pLeft; - ParseTreeBase::Ptr m_pRight; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeCMP : public ParseTreeBase -{ -public: - ParseTreeCMP( ParseTreeBase *_ptr1, ParseTreeBase *_ptr2, int _i ) { m_pLeft = _ptr1; m_pRight = _ptr2; m_cmd = _i; } - - bool eval( ParseContext *_context ) const; - -protected: - ParseTreeBase::Ptr m_pLeft; - ParseTreeBase::Ptr m_pRight; - int m_cmd; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeIN : public ParseTreeBase -{ -public: - ParseTreeIN( ParseTreeBase *_ptr1, ParseTreeBase *_ptr2 ) { m_pLeft = _ptr1; m_pRight = _ptr2; } - - bool eval( ParseContext *_context ) const; - -protected: - ParseTreeBase::Ptr m_pLeft; - ParseTreeBase::Ptr m_pRight; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeMATCH : public ParseTreeBase -{ -public: - ParseTreeMATCH( ParseTreeBase *_ptr1, ParseTreeBase *_ptr2 ) { m_pLeft = _ptr1; m_pRight = _ptr2; } - - bool eval( ParseContext *_context ) const; - -protected: - ParseTreeBase::Ptr m_pLeft; - ParseTreeBase::Ptr m_pRight; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeCALC : public ParseTreeBase -{ -public: - ParseTreeCALC( ParseTreeBase *_ptr1, ParseTreeBase *_ptr2, int _i ) { m_pLeft = _ptr1; m_pRight = _ptr2; m_cmd = _i; } - - bool eval( ParseContext *_context ) const; - -protected: - ParseTreeBase::Ptr m_pLeft; - ParseTreeBase::Ptr m_pRight; - int m_cmd; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeBRACKETS : public ParseTreeBase -{ -public: - ParseTreeBRACKETS( ParseTreeBase *_ptr ) { m_pLeft = _ptr; } - - bool eval( ParseContext *_context ) const { return m_pLeft->eval( _context ); } - -protected: - ParseTreeBase::Ptr m_pLeft; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeNOT : public ParseTreeBase -{ -public: - ParseTreeNOT( ParseTreeBase *_ptr ) { m_pLeft = _ptr; } - - bool eval( ParseContext *_context ) const; - -protected: - ParseTreeBase::Ptr m_pLeft; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeEXIST : public ParseTreeBase -{ -public: - ParseTreeEXIST( const char *_id ) { m_id = _id; } - - bool eval( ParseContext *_context ) const; - -protected: - TQString m_id; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeID : public ParseTreeBase -{ -public: - ParseTreeID( const char *arg ) { m_str = arg; } - - bool eval( ParseContext *_context ) const; - -protected: - TQString m_str; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeSTRING : public ParseTreeBase -{ -public: - ParseTreeSTRING( const char *arg ) { m_str = arg; } - - bool eval( ParseContext *_context ) const { _context->type = ParseContext::T_STRING; _context->str = m_str; return true; } - -protected: - TQString m_str; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeNUM : public ParseTreeBase -{ -public: - ParseTreeNUM( int arg ) { m_int = arg; } - - bool eval( ParseContext *_context ) const { _context->type = ParseContext::T_NUM; _context->i = m_int; return true; } - -protected: - int m_int; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeDOUBLE : public ParseTreeBase -{ -public: - ParseTreeDOUBLE( double arg ) { m_double = arg; } - - bool eval( ParseContext *_context ) const { _context->type = ParseContext::T_DOUBLE; _context->f = m_double; return true; } - -protected: - double m_double; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeBOOL : public ParseTreeBase -{ -public: - ParseTreeBOOL( bool arg ) { m_bool = arg; } - - bool eval( ParseContext *_context ) const { _context->type = ParseContext::T_BOOL; _context->b = m_bool; return true; } - -protected: - bool m_bool; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeMAX2 : public ParseTreeBase -{ -public: - ParseTreeMAX2( const char *_id ) { m_strId = _id; } - - bool eval( ParseContext *_context ) const; - -protected: - TQString m_strId; -}; - -/** - * @internal - */ -class TDEIO_EXPORT ParseTreeMIN2 : public ParseTreeBase -{ -public: - ParseTreeMIN2( const char *_id ) { m_strId = _id; } - - bool eval( ParseContext *_context ) const; - -protected: - TQString m_strId; -}; - -} - -#endif diff --git a/kio/kio/kurifilter.cpp b/kio/kio/kurifilter.cpp deleted file mode 100644 index 5c50f4fa9..000000000 --- a/kio/kio/kurifilter.cpp +++ /dev/null @@ -1,451 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 2000 Yves Arrouye <yves@realnames.com> - * Copyright (C) 2000 Dawit Alemayehu <adawit at kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include <config.h> - -#include <kdebug.h> -#include <kiconloader.h> -#include <ktrader.h> -#include <kmimetype.h> -#include <klibloader.h> -#include <kstaticdeleter.h> -#include <tdeparts/componentfactory.h> - -#ifdef HAVE_ELFICON -#include <tqimage.h> -#include "tdelficon.h" -#endif // HAVE_ELFICON - -#include "kurifilter.h" - -template class TQPtrList<KURIFilterPlugin>; - -KURIFilterPlugin::KURIFilterPlugin( TQObject *parent, const char *name, double pri ) - :TQObject( parent, name ) -{ - m_strName = TQString::fromLatin1( name ); - m_dblPriority = pri; -} - -void KURIFilterPlugin::setFilteredURI( KURIFilterData& data, const KURL& uri ) const -{ - if ( data.uri() != uri ) - { - data.m_pURI = uri; - data.m_bChanged = true; - } -} - -class KURIFilterDataPrivate -{ -public: - KURIFilterDataPrivate() {}; - TQString abs_path; - TQString args; - TQString typedString; -}; - -KURIFilterData::KURIFilterData( const KURIFilterData& data ) -{ - m_iType = data.m_iType; - m_pURI = data.m_pURI; - m_strErrMsg = data.m_strErrMsg; - m_strIconName = data.m_strIconName; - m_bChanged = data.m_bChanged; - m_bCheckForExecutables = data.m_bCheckForExecutables; - d = new KURIFilterDataPrivate; - d->abs_path = data.absolutePath(); - d->typedString = data.typedString(); - d->args = data.argsAndOptions(); -} - -KURIFilterData::~KURIFilterData() -{ - delete d; - d = 0; -} - -void KURIFilterData::init( const KURL& url ) -{ - m_iType = KURIFilterData::UNKNOWN; - m_pURI = url; - m_strErrMsg = TQString::null; - m_strIconName = TQString::null; - m_bCheckForExecutables = true; - m_bChanged = true; - d = new KURIFilterDataPrivate; - d->typedString = url.url(); -} - -void KURIFilterData::init( const TQString& url ) -{ - m_iType = KURIFilterData::UNKNOWN; - m_pURI = url; - m_strErrMsg = TQString::null; - m_strIconName = TQString::null; - m_bCheckForExecutables = true; - m_bChanged = true; - d = new KURIFilterDataPrivate; - d->typedString = url; -} - -void KURIFilterData::reinit(const KURL &url) -{ - delete d; - init(url); -} - -void KURIFilterData::reinit(const TQString &url) -{ - delete d; - init(url); -} - -TQString KURIFilterData::typedString() const -{ - return d->typedString; -} - -void KURIFilterData::setCheckForExecutables( bool check ) -{ - m_bCheckForExecutables = check; -} - -bool KURIFilterData::hasArgsAndOptions() const -{ - return !d->args.isEmpty(); -} - -bool KURIFilterData::hasAbsolutePath() const -{ - return !d->abs_path.isEmpty(); -} - -bool KURIFilterData::setAbsolutePath( const TQString& absPath ) -{ - // Since a malformed URL could possibly be a relative - // URL we tag it as a possible local resource... - if( (!m_pURI.isValid() || m_pURI.isLocalFile()) ) - { - d->abs_path = absPath; - return true; - } - return false; -} - -TQString KURIFilterData::absolutePath() const -{ - return d->abs_path; -} - -TQString KURIFilterData::argsAndOptions() const -{ - return d->args; -} - -TQString KURIFilterData::iconName() -{ - if( m_bChanged ) - { - m_customIconPixmap = TQPixmap(); - switch ( m_iType ) - { - case KURIFilterData::LOCAL_FILE: - case KURIFilterData::LOCAL_DIR: - case KURIFilterData::NET_PROTOCOL: - { - m_strIconName = KMimeType::iconForURL( m_pURI ); - break; - } - case KURIFilterData::EXECUTABLE: - { - TQString exeName = m_pURI.url(); - exeName = exeName.mid( exeName.findRev( '/' ) + 1 ); // strip path if given - KService::Ptr service = KService::serviceByDesktopName( exeName ); -#ifndef HAVE_ELFICON - // Try to find an icon with the same name as the binary (useful for non-tde apps) - // FIXME: We should only do this if the binary is in the system path somewhere, - // otherwise TDE could end up showing system icons for user binaries - if (service && service->icon() != TQString::fromLatin1( "unknown" )) { - m_strIconName = service->icon(); - } - else if ( !TDEGlobal::iconLoader()->loadIcon( exeName, KIcon::NoGroup, 16, KIcon::DefaultState, 0, true ).isNull() ) { - m_strIconName = exeName; - } - else { - // use default - m_strIconName = TQString::fromLatin1("exec"); - } -#else // HAVE_ELFICON - // Try to find an icon with the same name as the binary (useful for non-tde apps) - // FIXME: We should only do this if the binary is in the system path somewhere, - // otherwise TDE could end up showing system icons for user binaries - if (service && service->icon() != TQString::fromLatin1( "unknown" )) { - m_strIconName = service->icon(); - } - else if ( !TDEGlobal::iconLoader()->loadIcon( exeName, KIcon::NoGroup, 16, KIcon::DefaultState, 0, true ).isNull() ) { - m_strIconName = exeName; - } - else { - // use default - m_strIconName = TQString::fromLatin1("exec"); - } - // Try to load from elf file (if supported) - // Check for an embedded icon - unsigned int icon_size; - libr_icon *icon = NULL; - libr_file *handle = NULL; - libr_access_t access = LIBR_READ; - char libr_can_continue = 1; - - if((handle = libr_open(const_cast<char*>(m_pURI.path().ascii()), access)) == NULL) - { - kdWarning() << "failed to open file" << m_pURI.path() << endl; - libr_can_continue = 0; - } - - if (libr_can_continue == 1) { - icon_size = 32; // FIXME: Is this a reasonable size request for all possible usages of kurifilter? - icon = libr_icon_geticon_bysize(handle, icon_size); - - if (libr_can_continue == 1) { - // See if the embedded icon name matches any icon file names already on the system - // If it does, use the system icon instead of the embedded one - int iconresnamefound = 0; - iconentry *entry = NULL; - iconlist icons; - if(!get_iconlist(handle, &icons)) - { - // Failed to obtain a list of ELF icons - kdWarning() << "failed to obtain ELF icon: " << libr_errmsg() << endl; - - // See if there is a system icon we can use - TQString sysIconName = elf_get_resource(handle, ".metadata_sysicon"); - if (!sysIconName.isEmpty()) { - if (TDEGlobal::iconLoader()->iconPath(sysIconName.ascii(), 0, true) != "") { - m_strIconName = sysIconName; - } - } - - libr_close(handle); - libr_can_continue = 0; - } - else { - while((entry = get_nexticon(&icons, entry)) != NULL) - { - if(icon == NULL) - { - // Try loading this icon as fallback - icon = libr_icon_geticon_byname(handle, entry->name); - } - if (TDEGlobal::iconLoader()->iconPath(entry->name, 0, true) != "") { - iconresnamefound = 1; - m_strIconName = entry->name; - break; - } - } - } - - if (libr_can_continue == 1) { - if ((iconresnamefound == 0) && (icon)) { - // Extract the embedded icon - size_t icon_data_length; - char* icondata = libr_icon_malloc(icon, &icon_data_length); - m_customIconPixmap.loadFromData(static_cast<uchar*>(static_cast<void*>(icondata)), icon_data_length); // EVIL CAST - if (icon_size != 0) { - TQImage ip = m_customIconPixmap.convertToImage(); - ip = ip.smoothScale(icon_size, icon_size); - m_customIconPixmap.convertFromImage(ip); - } - free(icondata); - libr_icon_close(icon); - } - - libr_close(handle); - } - } - } -#endif // HAVE_ELFICON - break; - } - case KURIFilterData::HELP: - { - m_strIconName = TQString::fromLatin1("khelpcenter"); - break; - } - case KURIFilterData::SHELL: - { - m_strIconName = TQString::fromLatin1("konsole"); - break; - } - case KURIFilterData::ERROR: - case KURIFilterData::BLOCKED: - { - m_strIconName = TQString::fromLatin1("error"); - break; - } - default: - m_strIconName = TQString::null; - break; - } - m_bChanged = false; - } - return m_strIconName; -} - -TQPixmap KURIFilterData::customIconPixmap() -{ - return m_customIconPixmap; -} - -//******************************************** KURIFilterPlugin ********************************************** -void KURIFilterPlugin::setArguments( KURIFilterData& data, const TQString& args ) const -{ - data.d->args = args; -} - -//******************************************** KURIFilter ********************************************** -KURIFilter *KURIFilter::s_self; -static KStaticDeleter<KURIFilter> kurifiltersd; - -KURIFilter *KURIFilter::self() -{ - if (!s_self) - s_self = kurifiltersd.setObject(s_self, new KURIFilter); - return s_self; -} - -KURIFilter::KURIFilter() -{ - m_lstPlugins.setAutoDelete(true); - loadPlugins(); -} - -KURIFilter::~KURIFilter() -{ -} - -bool KURIFilter::filterURI( KURIFilterData& data, const TQStringList& filters ) -{ - bool filtered = false; - KURIFilterPluginList use_plugins; - - // If we have a filter list, only include the once - // explicitly specified by it. Otherwise, use all available filters... - if( filters.isEmpty() ) - use_plugins = m_lstPlugins; // Use everything that is loaded... - else - { - //kdDebug() << "Named plugins requested..." << endl; - for( TQStringList::ConstIterator lst = filters.begin(); lst != filters.end(); ++lst ) - { - TQPtrListIterator<KURIFilterPlugin> it( m_lstPlugins ); - for( ; it.current() ; ++it ) - { - if( (*lst) == it.current()->name() ) - { - //kdDebug() << "Will use filter plugin named: " << it.current()->name() << endl; - use_plugins.append( it.current() ); - break; // We already found it ; so lets test the next named filter... - } - } - } - } - - TQPtrListIterator<KURIFilterPlugin> it( use_plugins ); - //kdDebug() << "Using " << use_plugins.count() << " out of the " - // << m_lstPlugins.count() << " available plugins" << endl; - for (; it.current() && !filtered; ++it) - { - //kdDebug() << "Using a filter plugin named: " << it.current()->name() << endl; - filtered |= it.current()->filterURI( data ); - } - return filtered; -} - -bool KURIFilter::filterURI( KURL& uri, const TQStringList& filters ) -{ - KURIFilterData data = uri; - bool filtered = filterURI( data, filters ); - if( filtered ) uri = data.uri(); - return filtered; -} - -bool KURIFilter::filterURI( TQString& uri, const TQStringList& filters ) -{ - KURIFilterData data = uri; - bool filtered = filterURI( data, filters ); - if( filtered ) uri = data.uri().url(); - return filtered; - -} - -KURL KURIFilter::filteredURI( const KURL &uri, const TQStringList& filters ) -{ - KURIFilterData data = uri; - filterURI( data, filters ); - return data.uri(); -} - -TQString KURIFilter::filteredURI( const TQString &uri, const TQStringList& filters ) -{ - KURIFilterData data = uri; - filterURI( data, filters ); - return data.uri().url(); -} - -TQPtrListIterator<KURIFilterPlugin> KURIFilter::pluginsIterator() const -{ - return TQPtrListIterator<KURIFilterPlugin>(m_lstPlugins); -} - -TQStringList KURIFilter::pluginNames() const -{ - TQStringList list; - for(TQPtrListIterator<KURIFilterPlugin> i = pluginsIterator(); *i; ++i) - list.append((*i)->name()); - return list; -} - -void KURIFilter::loadPlugins() -{ - KTrader::OfferList offers = KTrader::self()->query( "KURIFilter/Plugin" ); - - KTrader::OfferList::ConstIterator it = offers.begin(); - KTrader::OfferList::ConstIterator end = offers.end(); - - for (; it != end; ++it ) - { - KURIFilterPlugin *plugin = KParts::ComponentFactory::createInstanceFromService<KURIFilterPlugin>( *it, 0, (*it)->desktopEntryName().latin1() ); - if ( plugin ) - m_lstPlugins.append( plugin ); - } - - // NOTE: Plugin priority is now determined by - // the entry in the .desktop files... - // TODO: Config dialog to differentiate "system" - // plugins from "user-defined" ones... - // m_lstPlugins.sort(); -} - -void KURIFilterPlugin::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -#include "kurifilter.moc" diff --git a/kio/kio/kurifilter.h b/kio/kio/kurifilter.h deleted file mode 100644 index fd7cb9b3c..000000000 --- a/kio/kio/kurifilter.h +++ /dev/null @@ -1,667 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2000-2001,2003 Dawit Alemayehu <adawit at kde.org> - * - * Original author - * Copyright (C) 2000 Yves Arrouye <yves@realnames.com> - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#ifndef __kurifilter_h__ -#define __kurifilter_h__ - -#include <tqptrlist.h> -#include <tqobject.h> -#include <tqstringlist.h> -#include <tqpixmap.h> - -#include <kurl.h> - -#ifdef Q_OS_WIN -#undef ERROR -#endif - -class KURIFilterPrivate; -class KURIFilterDataPrivate; - -class TDECModule; - -/** -* A basic message object used for exchanging filtering -* information between the filter plugins and the application -* requesting the filtering service. -* -* Use this object if you require a more detailed information -* about the URI you want to filter. Any application can create -* an instance of this class and send it to KURIFilter to -* have the plugins fill out all possible information about the -* URI. -* -* \b Example -* -* \code -* TQString text = "kde.org"; -* KURIFilterData d = text; -* bool filtered = KURIFilter::self()->filter( d ); -* cout << "URL: " << text.latin1() << endl -* << "Filtered URL: " << d.uri().url().latin1() << endl -* << "URI Type: " << d.uriType() << endl -* << "Was Filtered: " << filtered << endl; -* \endcode -* -* The above code should yield the following output: -* \code -* URI: kde.org -* Filtered URI: http://kde.org -* URI Type: 0 <== means NET_PROTOCOL -* Was Filtered: 1 <== means the URL was successfully filtered -* \endcode -* -* @short A message object for exchanging filtering URI info. -* @author Dawit Alemayehu <adawit at kde.org> -*/ - -class TDEIO_EXPORT KURIFilterData -{ -friend class KURIFilterPlugin; - -public: - /** - * Describes the type of the URI that was filtered. - * Here is a brief description of the types: - * - * @li NET_PROTOCOL - Any network protocol: http, ftp, nttp, pop3, etc... - * @li LOCAL_FILE - A local file whose executable flag is not set - * @li LOCAL_DIR - A local directory - * @li EXECUTABLE - A local file whose executable flag is set - * @li HELP - A man or info page - * @li SHELL - A shell executable (ex: echo "Test..." >> ~/testfile) - * @li BLOCKED - A URI that should be blocked/filtered (ex: ad filtering) - * @li ERROR - An incorrect URI (ex: "~johndoe" when user johndoe - * does not exist in that system ) - * @li UNKNOWN - A URI that is not identified. Default value when - * a KURIFilterData is first created. - */ - enum URITypes { NET_PROTOCOL=0, LOCAL_FILE, LOCAL_DIR, EXECUTABLE, HELP, SHELL, BLOCKED, ERROR, UNKNOWN }; - - /** - * Default constructor. - * - * Creates a URIFilterData object. - */ - KURIFilterData() { init(); } - - /** - * Creates a URIFilterData object from the given URL. - * - * @param url is the URL to be filtered. - */ - KURIFilterData( const KURL& url ) { init( url); } - - /** - * Creates a URIFilterData object from the given string. - * - * @param url is the string to be filtered. - */ - KURIFilterData( const TQString& url ) { init( url ); } - - /** - * Copy constructor. - * - * Creates a URIFilterData object from another - * URI filter data object. - * - * @param data the uri filter data to be copied. - */ - KURIFilterData( const KURIFilterData& data); - - /** - * Destructor. - */ - ~KURIFilterData(); - - /** - * This method has been deprecated and will always return - * true. You should instead use the result from the - * KURIFilter::filterURI() calls. - * - * @deprecated - */ - KDE_DEPRECATED bool hasBeenFiltered() const { return true; } - - /** - * Returns the filtered or the original URL. - * - * This function returns the filtered url if one - * of the plugins successfully filtered the original - * URL. Otherwise, it returns the original URL. - * See hasBeenFiltered() and - * - * @return the filtered or original url. - */ - KURL uri() const { return m_pURI; } - - /** - * Returns an error message. - * - * This functions returns the error message set - * by the plugin whenever the uri type is set to - * KURIFilterData::ERROR. Otherwise, it returns - * a TQString::null. - * - * @return the error message or a NULL when there is none. - */ - TQString errorMsg() const { return m_strErrMsg; } - - /** - * Returns the URI type. - * - * This method always returns KURIFilterData::UNKNOWN - * if the given URL was not filtered. - * @return the type of the URI - */ - URITypes uriType() const { return m_iType; } - - /** - * Sets the URL to be filtered. - * - * Use this function to set the string to be - * filtered when you construct an empty filter - * object. - * - * @param url the string to be filtered. - */ - void setData( const TQString& url ) { reinit( url ); } - - /** - * Same as above except the argument is a URL. - * - * Use this function to set the string to be - * filtered when you construct an empty filter - * object. - * - * @param url the URL to be filtered. - */ - void setData( const KURL& url ) { reinit( url ); } - - /** - * Sets the absolute path to be used whenever the supplied - * data is a relative local URL. - * - * NOTE: This function should only be used for local resources, - * i.e. the "file:/" protocol. It is useful for specifying the - * absolute path in cases where the actual URL might be relative. - * meta object. If deriving the path from a KURL, make sure you - * set the argument for this function to the result of calling - * path () instead of url (). - * - * @param abs_path the abolute path to the local resource. - * @return true if absolute path is successfully set. Otherwise, false. - */ - bool setAbsolutePath( const TQString& abs_path ); - - /** - * Returns the absolute path if one has already been set. - * @return the absolute path, or TQString::null - * @see hasAbsolutePath() - */ - TQString absolutePath() const; - - /** - * Checks whether the supplied data had an absolute path. - * @return true if the supplied data has an absolute path - * @see absolutePath() - */ - bool hasAbsolutePath() const; - - /** - * Returns the command line options and arguments for a - * local resource when present. - * - * @return options and arguments when present, otherwise TQString::null - */ - TQString argsAndOptions() const; - - /** - * Checks whether the current data is a local resource with - * command line options and arguments. - * @return true if the current data has command line options and arguments - */ - bool hasArgsAndOptions() const; - - /** - * Returns the name of the icon that matches - * the current filtered URL. - * - * NOTE that this function will return a NULL - * string by default and when no associated icon - * is found. - * - * @return the name of the icon associated with the resource, - * or TQString::null if not found - */ - TQString iconName(); - - /** - * Returns the current custom icon - * The results are valid iff iconName() has - * returned TQString::null - * - * @return a pixmap with the current custom icon, - * or a null pixmap if no icon is available - */ - TQPixmap customIconPixmap(); - - /** - * Check whether the provided uri is executable or not. - * - * Setting this to false ensures that typing the name of - * an executable does not start that application. This is - * useful in the location bar of a browser. The default - * value is true. - * - * @since 3.2 - */ - void setCheckForExecutables (bool check); - - /** - * @return true if the filters should attempt to check whether the - * supplied uri is an executable. False otherwise. - * - * @since 3.2 - */ - bool checkForExecutables() const { return m_bCheckForExecutables; } - - /** - * @return the string as typed by the user, before any URL processing is done - * @since 3.2 - */ - TQString typedString() const; - - /** - * Overloaded assigenment operator. - * - * This function allows you to easily assign a KURL - * to a KURIFilterData object. - * - * @return an instance of a KURIFilterData object. - */ - KURIFilterData& operator=( const KURL& url ) { reinit( url ); return *this; } - - /** - * Overloaded assigenment operator. - * - * This function allows you to easily assign a QString - * to a KURIFilterData object. - * - * @return an instance of a KURIFilterData object. - */ - KURIFilterData& operator=( const TQString& url ) { reinit( url ); return *this; } - -protected: - - /** - * Initializes the KURIFilterData on construction. - * @param url the URL to initialize the object with - */ - void init( const KURL& url); - - /** - * Initializes the KURIFilterData on construction. - * @param url the URL to initialize the object with - */ - void init( const TQString& url = TQString::null ); - -private: - - // BC hack to avoid leaking KURIFilterDataPrivate objects. - // setData() and operator= used to call init() without deleting `d' - void reinit(const KURL& url); - void reinit(const TQString& url = TQString::null); - - bool m_bCheckForExecutables; - bool m_bChanged; - - TQString m_strErrMsg; - TQString m_strIconName; - - KURL m_pURI; - URITypes m_iType; - KURIFilterDataPrivate *d; - - TQPixmap m_customIconPixmap; -}; - - -/** - * Base class for URI filter plugins. - * - * This class applies a single filter to a URI. All plugins designed - * to provide URI filtering service should inherit from this abstract - * class and provide a concrete implementation. - * - * All inheriting classes need to implement the pure virtual function - * filterURI. - * - * @short Abstract class for URI filter plugins. - */ -class TDEIO_EXPORT KURIFilterPlugin : public TQObject -{ - Q_OBJECT - - -public: - - /** - * Constructs a filter plugin with a given name and - * priority. - * - * @param parent the parent object, or 0 for no parent - * @param name the name of the plugin, or 0 for no name - * @param pri the priority of the plugin. - */ - KURIFilterPlugin( TQObject *parent = 0, const char *name = 0, double pri = 1.0 ); - - /** - * Returns the filter's name. - * - * @return A string naming the filter. - */ - virtual TQString name() const { return m_strName; } - - /** - * Returns the filter's priority. - * - * Each filter has an assigned priority, a float from 0 to 1. Filters - * with the lowest priority are first given a chance to filter a URI. - * - * @return The priority of the filter. - */ - virtual double priority() const { return m_dblPriority; } - - /** - * Filters a URI. - * - * @param data the URI data to be filtered. - * @return A boolean indicating whether the URI has been changed. - */ - virtual bool filterURI( KURIFilterData& data ) const = 0; - - /** - * Creates a configuration module for the filter. - * - * It is the responsibility of the caller to delete the module - * once it is not needed anymore. - * - * @return A configuration module, 0 if the filter isn't configurable. - */ - virtual TDECModule *configModule( TQWidget*, const char* ) const { return 0; } - - /** - * Returns the name of the configuration module for the filter. - * - * @return the name of a configuration module or TQString::null if none. - */ - virtual TQString configName() const { return name(); } - -protected: - - /** - * Sets the the URL in @p data to @p uri. - */ - void setFilteredURI ( KURIFilterData& data, const KURL& uri ) const; - - /** - * Sets the error message in @p data to @p errormsg. - */ - void setErrorMsg ( KURIFilterData& data, const TQString& errmsg ) const { - data.m_strErrMsg = errmsg; - } - - /** - * Sets the URI type in @p data to @p type. - */ - void setURIType ( KURIFilterData& data, KURIFilterData::URITypes type) const { - data.m_iType = type; - data.m_bChanged = true; - } - - /** - * Sets the arguments and options string in @p data - * to @p args if any were found during filterting. - */ - void setArguments( KURIFilterData& data, const TQString& args ) const; - - TQString m_strName; - double m_dblPriority; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class KURIFilterPluginPrivate *d; -}; - - -/** - * A list of filter plugins. - */ -class TDEIO_EXPORT KURIFilterPluginList : public TQPtrList<KURIFilterPlugin> -{ -public: - virtual int compareItems(Item a, Item b) - { - double diff = ((KURIFilterPlugin *) a)->priority() - ((KURIFilterPlugin *) b)->priority(); - return diff < 0 ? -1 : (diff > 0 ? 1 : 0); - } - -private: - KURIFilterPrivate *d; - -}; - -/** - * Manages the filtering of URIs. - * - * The intention of this plugin class is to allow people to extend the - * functionality of KURL without modifying it directly. This way KURL will - * remain a generic parser capable of parsing any generic URL that adheres - * to specifications. - * - * The KURIFilter class applies a number of filters to a URI and returns the - * filtered version whenever possible. The filters are implemented using - * plugins to provide easy extensibility of the filtering mechanism. New - * filters can be added in the future by simply inheriting from - * KURIFilterPlugin and implementing the KURIFilterPlugin::filterURI - * method. - * - * Use of this plugin-manager class is straight forward. Since it is a - * singleton object, all you have to do is obtain an instance by doing - * @p KURIFilter::self() and use any of the public member functions to - * preform the filtering. - * - * \b Example - * - * To simply filter a given string: - * - * \code - * bool filtered = KURIFilter::self()->filterURI( "kde.org" ); - * \endcode - * - * You can alternatively use a KURL: - * - * \code - * KURL url = "kde.org"; - * bool filtered = KURIFilter::self()->filterURI( url ); - * \endcode - * - * If you have a constant string or a constant URL, simply invoke the - * corresponding function to obtain the filtered string or URL instead - * of a boolean flag: - * - * \code - * TQString u = KURIFilter::self()->filteredURI( "kde.org" ); - * \endcode - * - * You can also restrict the filter(s) to be used by supplying - * the name of the filter(s) to use. By defualt all available - * filters will be used. To use specific filters, add the names - * of the filters you want to use to a TQStringList and invoke - * the appropriate filtering function. The examples below show - * the use of specific filters. The first one uses a single - * filter called kshorturifilter while the second example uses - * multiple filters: - * - * \code - * TQString text = "kde.org"; - * bool filtered = KURIFilter::self()->filterURI( text, "kshorturifilter" ); - * \endcode - * - * \code - * TQStringList list; - * list << "kshorturifilter" << "localdomainfilter"; - * bool filtered = KURIFilter::self()->filterURI( text, list ); - * \endcode - * - * KURIFilter also allows richer data exchange through a simple - * meta-object called @p KURIFilterData. Using this meta-object - * you can find out more information about the URL you want to - * filter. See KURIFilterData for examples and details. - * - * @short Filters a given URL into its proper format whenever possible. - */ - -class TDEIO_EXPORT KURIFilter -{ -public: - /** - * Destructor - */ - ~KURIFilter (); - - /** - * Returns an instance of KURIFilter. - */ - static KURIFilter* self(); - - /** - * Filters the URI given by the object URIFilterData. - * - * The given URL is filtered based on the specified list of filters. - * If the list is empty all available filters would be used. - * - * @param data object that contains the URI to be filtered. - * @param filters specify the list of filters to be used. - * - * @return a boolean indicating whether the URI has been changed - */ - bool filterURI( KURIFilterData& data, const TQStringList& filters = TQStringList() ); - - /** - * Filters the URI given by the URL. - * - * The given URL is filtered based on the specified list of filters. - * If the list is empty all available filters would be used. - * - * @param uri the URI to filter. - * @param filters specify the list of filters to be used. - * - * @return a boolean indicating whether the URI has been changed - */ - bool filterURI( KURL &uri, const TQStringList& filters = TQStringList() ); - - /** - * Filters a string representing a URI. - * - * The given URL is filtered based on the specified list of filters. - * If the list is empty all available filters would be used. - * - * @param uri The URI to filter. - * @param filters specify the list of filters to be used. - * - * @return a boolean indicating whether the URI has been changed - */ - bool filterURI( TQString &uri, const TQStringList& filters = TQStringList() ); - - /** - * Returns the filtered URI. - * - * The given URL is filtered based on the specified list of filters. - * If the list is empty all available filters would be used. - * - * @param uri The URI to filter. - * @param filters specify the list of filters to be used. - * - * @return the filtered URI or null if it cannot be filtered - */ - KURL filteredURI( const KURL &uri, const TQStringList& filters = TQStringList() ); - - /** - * Return a filtered string representation of a URI. - * - * The given URL is filtered based on the specified list of filters. - * If the list is empty all available filters would be used. - * - * @param uri the URI to filter. - * @param filters specify the list of filters to be used. - * - * @return the filtered URI or null if it cannot be filtered - */ - TQString filteredURI( const TQString &uri, const TQStringList& filters = TQStringList() ); - - /** - * Return an iterator to iterate over all loaded - * plugins. - * - * @return a plugin iterator. - */ - TQPtrListIterator<KURIFilterPlugin> pluginsIterator() const; - - /** - * Return a list of the names of all loaded plugins. - * - * @return a TQStringList of plugin names - * @since 3.1 - */ - TQStringList pluginNames() const; - -protected: - - /** - * A protected constructor. - * - * This constructor creates a KURIFilter and - * initializes all plugins it can find by invoking - * loadPlugins. - */ - KURIFilter(); - - /** - * Loads all allowed plugins. - * - * This function loads all filters that have not - * been disbled. - */ - void loadPlugins(); - -private: - static KURIFilter *s_self; - KURIFilterPluginList m_lstPlugins; - KURIFilterPrivate *d; -}; - -#endif diff --git a/kio/kio/kurlcompletion.cpp b/kio/kio/kurlcompletion.cpp deleted file mode 100644 index 2dc4185cc..000000000 --- a/kio/kio/kurlcompletion.cpp +++ /dev/null @@ -1,1604 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 4; c-basic-offset:4 -*- - - This file is part of the KDE libraries - Copyright (C) 2000 David Smith <dsmith@algonet.se> - Copyright (C) 2004 Scott Wheeler <wheeler@kde.org> - - This class was inspired by a previous KURLCompletion by - Henner Zeller <zeller@think.de> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <config.h> -#include <stdlib.h> -#include <assert.h> -#include <limits.h> - -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqvaluelist.h> -#include <tqregexp.h> -#include <tqtimer.h> -#include <tqdir.h> -#include <tqfile.h> -#include <tqtextstream.h> -#include <tqdeepcopy.h> -#include <tqthread.h> - -#include <kapplication.h> -#include <kdebug.h> -#include <kcompletion.h> -#include <kurl.h> -#include <kio/jobclasses.h> -#include <kio/job.h> -#include <kprotocolinfo.h> -#include <kconfig.h> -#include <kglobal.h> -#include <klocale.h> -#include <kde_file.h> - -#include <sys/types.h> -#include <dirent.h> -#include <unistd.h> -#include <sys/stat.h> -#include <pwd.h> -#include <time.h> -#include <sys/param.h> - -#include "kurlcompletion.h" - -static bool expandTilde(TQString &); -static bool expandEnv(TQString &); - -static TQString unescape(const TQString &text); - -// Permission mask for files that are executable by -// user, group or other -#define MODE_EXE (S_IXUSR | S_IXGRP | S_IXOTH) - -// Constants for types of completion -enum ComplType {CTNone=0, CTEnv, CTUser, CTMan, CTExe, CTFile, CTUrl, CTInfo}; - -class CompletionThread; - -/** - * A custom event type that is used to return a list of completion - * matches from an asyncrynous lookup. - */ - -class CompletionMatchEvent : public TQCustomEvent -{ -public: - CompletionMatchEvent( CompletionThread *thread ) : - TQCustomEvent( uniqueType() ), - m_completionThread( thread ) - {} - - CompletionThread *completionThread() const { return m_completionThread; } - static int uniqueType() { return User + 61080; } - -private: - CompletionThread *m_completionThread; -}; - -class CompletionThread : public TQThread -{ -protected: - CompletionThread( KURLCompletion *receiver ) : - TQThread(), - m_receiver( receiver ), - m_terminationRequested( false ) - {} - -public: - void requestTermination() { m_terminationRequested = true; } - TQDeepCopy<TQStringList> matches() const { return m_matches; } - -protected: - void addMatch( const TQString &match ) { m_matches.append( match ); } - bool terminationRequested() const { return m_terminationRequested; } - void done() - { - if ( !m_terminationRequested ) - kapp->postEvent( m_receiver, new CompletionMatchEvent( this ) ); - else - delete this; - } - -private: - KURLCompletion *m_receiver; - TQStringList m_matches; - bool m_terminationRequested; -}; - -/** - * A simple thread that fetches a list of tilde-completions and returns this - * to the caller via a CompletionMatchEvent. - */ - -class UserListThread : public CompletionThread -{ -public: - UserListThread( KURLCompletion *receiver ) : - CompletionThread( receiver ) - {} - -protected: - virtual void run() - { - static const TQChar tilde = '~'; - - struct passwd *pw; - while ( ( pw = ::getpwent() ) && !terminationRequested() ) - addMatch( tilde + TQString::fromLocal8Bit( pw->pw_name ) ); - - ::endpwent(); - - addMatch( tilde ); - - done(); - } -}; - -class DirectoryListThread : public CompletionThread -{ -public: - DirectoryListThread( KURLCompletion *receiver, - const TQStringList &dirList, - const TQString &filter, - bool onlyExe, - bool onlyDir, - bool noHidden, - bool appendSlashToDir ) : - CompletionThread( receiver ), - m_dirList( TQDeepCopy<TQStringList>( dirList ) ), - m_filter( TQDeepCopy<TQString>( filter ) ), - m_onlyExe( onlyExe ), - m_onlyDir( onlyDir ), - m_noHidden( noHidden ), - m_appendSlashToDir( appendSlashToDir ) - {} - - virtual void run(); - -private: - TQStringList m_dirList; - TQString m_filter; - bool m_onlyExe; - bool m_onlyDir; - bool m_noHidden; - bool m_appendSlashToDir; -}; - -void DirectoryListThread::run() -{ - // Thread safety notes: - // - // There very possibly may be thread safety issues here, but I've done a check - // of all of the things that would seem to be problematic. Here are a few - // things that I have checked to be safe here (some used indirectly): - // - // TQDir::currentDirPath(), TQDir::setCurrent(), TQFile::decodeName(), TQFile::encodeName() - // TQString::fromLocal8Bit(), TQString::local8Bit(), TQTextCodec::codecForLocale() - // - // Also see (for POSIX functions): - // http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html - - DIR *dir = 0; - - for ( TQStringList::ConstIterator it = m_dirList.begin(); - it != m_dirList.end() && !terminationRequested(); - ++it ) - { - // Open the next directory - - if ( !dir ) { - dir = ::opendir( TQFile::encodeName( *it ) ); - if ( ! dir ) { - kdDebug() << "Failed to open dir: " << *it << endl; - done(); - return; - } - } - - // A trick from KIO that helps performance by a little bit: - // chdir to the directroy so we won't have to deal with full paths - // with stat() - - TQString path = TQDir::currentDirPath(); - TQDir::setCurrent( *it ); - - // Loop through all directory entries - // Solaris and IRIX dirent structures do not allocate space for d_name. On - // systems that do (HP-UX, Linux, Tru64 UNIX), we overallocate space but - // that's ok. -#ifndef HAVE_READDIR_R - struct dirent *dirEntry = 0; - while ( !terminationRequested() && - (dirEntry = ::readdir( dir))) -#else -#if !defined(MAXPATHLEN) && defined(__GNU__) -#define MAXPATHLEN UCHAR_MAX -#endif - struct dirent *dirPosition = (struct dirent *) malloc( sizeof( struct dirent ) + MAXPATHLEN + 1 ); - struct dirent *dirEntry = 0; - while ( !terminationRequested() && - ::readdir_r( dir, dirPosition, &dirEntry ) == 0 && dirEntry ) -#endif - - { - // Skip hidden files if m_noHidden is true - - if ( dirEntry->d_name[0] == '.' && m_noHidden ) - continue; - - // Skip "." - - if ( dirEntry->d_name[0] == '.' && dirEntry->d_name[1] == '\0' ) - continue; - - // Skip ".." - - if ( dirEntry->d_name[0] == '.' && dirEntry->d_name[1] == '.' && dirEntry->d_name[2] == '\0' ) - continue; - - TQString file = TQFile::decodeName( dirEntry->d_name ); - - if ( m_filter.isEmpty() || file.startsWith( m_filter ) ) { - - if ( m_onlyExe || m_onlyDir || m_appendSlashToDir ) { - KDE_struct_stat sbuff; - - if ( KDE_stat( dirEntry->d_name, &sbuff ) == 0 ) { - - // Verify executable - - if ( m_onlyExe && ( sbuff.st_mode & MODE_EXE ) == 0 ) - continue; - - // Verify directory - - if ( m_onlyDir && !S_ISDIR( sbuff.st_mode ) ) - continue; - - // Add '/' to directories - - if ( m_appendSlashToDir && S_ISDIR( sbuff.st_mode ) ) - file.append( '/' ); - - } - else { - kdDebug() << "Could not stat file " << file << endl; - continue; - } - } - - addMatch( file ); - } - } - - // chdir to the original directory - - TQDir::setCurrent( path ); - - ::closedir( dir ); - dir = 0; -#ifdef HAVE_READDIR_R - free( dirPosition ); -#endif - } - - done(); -} - -/////////////////////////////////////////////////////// -/////////////////////////////////////////////////////// -// MyURL - wrapper for KURL with some different functionality -// - -class KURLCompletion::MyURL -{ -public: - MyURL(const TQString &url, const TQString &cwd); - MyURL(const MyURL &url); - ~MyURL(); - - KURL *kurl() const { return m_kurl; } - - TQString protocol() const { return m_kurl->protocol(); } - // The directory with a trailing '/' - TQString dir() const { return m_kurl->directory(false, false); } - TQString file() const { return m_kurl->fileName(false); } - - // The initial, unparsed, url, as a string. - TQString url() const { return m_url; } - - // Is the initial string a URL, or just a path (whether absolute or relative) - bool isURL() const { return m_isURL; } - - void filter( bool replace_user_dir, bool replace_env ); - -private: - void init(const TQString &url, const TQString &cwd); - - KURL *m_kurl; - TQString m_url; - bool m_isURL; -}; - -KURLCompletion::MyURL::MyURL(const TQString &url, const TQString &cwd) -{ - init(url, cwd); -} - -KURLCompletion::MyURL::MyURL(const MyURL &url) -{ - m_kurl = new KURL( *(url.m_kurl) ); - m_url = url.m_url; - m_isURL = url.m_isURL; -} - -void KURLCompletion::MyURL::init(const TQString &url, const TQString &cwd) -{ - // Save the original text - m_url = url; - - // Non-const copy - TQString url_copy = url; - - // Special shortcuts for "man:" and "info:" - if ( url_copy[0] == '#' ) { - if ( url_copy[1] == '#' ) - url_copy.replace( 0, 2, TQString("info:") ); - else - url_copy.replace( 0, 1, TQString("man:") ); - } - - // Look for a protocol in 'url' - TQRegExp protocol_regex = TQRegExp( "^[^/\\s\\\\]*:" ); - - // Assume "file:" or whatever is given by 'cwd' if there is - // no protocol. (KURL does this only for absoute paths) - if ( protocol_regex.search( url_copy ) == 0 ) - { - m_kurl = new KURL( url_copy ); - m_isURL = true; - } - else // relative path or ~ or $something - { - m_isURL = false; - if ( cwd.isEmpty() ) - { - m_kurl = new KURL(); - if ( !TQDir::isRelativePath(url_copy) || url_copy[0] == '$' || url_copy[0] == '~' ) - m_kurl->setPath( url_copy ); - else - *m_kurl = url_copy; - } - else - { - KURL base = KURL::fromPathOrURL( cwd ); - base.adjustPath(+1); - - if ( !TQDir::isRelativePath(url_copy) || url_copy[0] == '~' || url_copy[0] == '$' ) - { - m_kurl = new KURL(); - m_kurl->setPath( url_copy ); - } - else // relative path - { - //m_kurl = new KURL( base, url_copy ); - m_kurl = new KURL( base ); - m_kurl->addPath( url_copy ); - } - } - } -} - -KURLCompletion::MyURL::~MyURL() -{ - delete m_kurl; -} - -void KURLCompletion::MyURL::filter( bool replace_user_dir, bool replace_env ) -{ - TQString d = dir() + file(); - if ( replace_user_dir ) expandTilde( d ); - if ( replace_env ) expandEnv( d ); - m_kurl->setPath( d ); -} - -/////////////////////////////////////////////////////// -/////////////////////////////////////////////////////// -// KURLCompletionPrivate -// -class KURLCompletionPrivate -{ -public: - KURLCompletionPrivate() : url_auto_completion(true), - userListThread(0), - dirListThread(0) {} - ~KURLCompletionPrivate(); - - TQValueList<KURL*> list_urls; - - bool onlyLocalProto; - - // urlCompletion() in Auto/Popup mode? - bool url_auto_completion; - - // Append '/' to directories in Popup mode? - // Doing that stat's all files and is slower - bool popup_append_slash; - - // Keep track of currently listed files to avoid reading them again - TQString last_path_listed; - TQString last_file_listed; - TQString last_prepend; - int last_compl_type; - int last_no_hidden; - - TQString cwd; // "current directory" = base dir for completion - - KURLCompletion::Mode mode; // ExeCompletion, FileCompletion, DirCompletion - bool replace_env; - bool replace_home; - bool complete_url; // if true completing a URL (i.e. 'prepend' is a URL), otherwise a path - - TDEIO::ListJob *list_job; // kio job to list directories - - TQString prepend; // text to prepend to listed items - TQString compl_text; // text to pass on to KCompletion - - // Filters for files read with kio - bool list_urls_only_exe; // true = only list executables - bool list_urls_no_hidden; - TQString list_urls_filter; // filter for listed files - - CompletionThread *userListThread; - CompletionThread *dirListThread; -}; - -KURLCompletionPrivate::~KURLCompletionPrivate() -{ - if ( userListThread ) - userListThread->requestTermination(); - if ( dirListThread ) - dirListThread->requestTermination(); -} - -/////////////////////////////////////////////////////// -/////////////////////////////////////////////////////// -// KURLCompletion -// - -KURLCompletion::KURLCompletion() : KCompletion() -{ - init(); -} - - -KURLCompletion::KURLCompletion( Mode mode ) : KCompletion() -{ - init(); - setMode ( mode ); -} - -KURLCompletion::~KURLCompletion() -{ - stop(); - delete d; -} - - -void KURLCompletion::init() -{ - d = new KURLCompletionPrivate; - - d->cwd = TQDir::homeDirPath(); - - d->replace_home = true; - d->replace_env = true; - d->last_no_hidden = false; - d->last_compl_type = 0; - d->list_job = 0L; - d->mode = KURLCompletion::FileCompletion; - - // Read settings - TDEConfig *c = TDEGlobal::config(); - TDEConfigGroupSaver cgs( c, "URLCompletion" ); - - d->url_auto_completion = c->readBoolEntry("alwaysAutoComplete", true); - d->popup_append_slash = c->readBoolEntry("popupAppendSlash", true); - d->onlyLocalProto = c->readBoolEntry("LocalProtocolsOnly", false); -} - -void KURLCompletion::setDir(const TQString &dir) -{ - d->cwd = dir; -} - -TQString KURLCompletion::dir() const -{ - return d->cwd; -} - -KURLCompletion::Mode KURLCompletion::mode() const -{ - return d->mode; -} - -void KURLCompletion::setMode( Mode mode ) -{ - d->mode = mode; -} - -bool KURLCompletion::replaceEnv() const -{ - return d->replace_env; -} - -void KURLCompletion::setReplaceEnv( bool replace ) -{ - d->replace_env = replace; -} - -bool KURLCompletion::replaceHome() const -{ - return d->replace_home; -} - -void KURLCompletion::setReplaceHome( bool replace ) -{ - d->replace_home = replace; -} - -/* - * makeCompletion() - * - * Entry point for file name completion - */ -TQString KURLCompletion::makeCompletion(const TQString &text) -{ - //kdDebug() << "KURLCompletion::makeCompletion: " << text << " d->cwd=" << d->cwd << endl; - - MyURL url(text, d->cwd); - - d->compl_text = text; - - // Set d->prepend to the original URL, with the filename [and ref/query] stripped. - // This is what gets prepended to the directory-listing matches. - int toRemove = url.file().length() - url.kurl()->query().length(); - if ( url.kurl()->hasRef() ) - toRemove += url.kurl()->ref().length() + 1; - d->prepend = text.left( text.length() - toRemove ); - d->complete_url = url.isURL(); - - TQString match; - - // Environment variables - // - if ( d->replace_env && envCompletion( url, &match ) ) - return match; - - // User directories - // - if ( d->replace_home && userCompletion( url, &match ) ) - return match; - - // Replace user directories and variables - url.filter( d->replace_home, d->replace_env ); - - //kdDebug() << "Filtered: proto=" << url.protocol() - // << ", dir=" << url.dir() - // << ", file=" << url.file() - // << ", kurl url=" << *url.kurl() << endl; - - if ( d->mode == ExeCompletion ) { - // Executables - // - if ( exeCompletion( url, &match ) ) - return match; - - // KRun can run "man:" and "info:" etc. so why not treat them - // as executables... - - if ( urlCompletion( url, &match ) ) - return match; - } - else if ( d->mode == SystemExeCompletion ) { - // Executables - // - if ( systemexeCompletion( url, &match ) ) - return match; - - // KRun can run "man:" and "info:" etc. so why not treat them - // as executables... - - if ( urlCompletion( url, &match ) ) - return match; - } - else { - // Local files, directories - // - if ( fileCompletion( url, &match ) ) - return match; - - // All other... - // - if ( urlCompletion( url, &match ) ) - return match; - } - - setListedURL( CTNone ); - stop(); - - return TQString::null; -} - -/* - * finished - * - * Go on and call KCompletion. - * Called when all matches have been added - */ -TQString KURLCompletion::finished() -{ - if ( d->last_compl_type == CTInfo ) - return KCompletion::makeCompletion( d->compl_text.lower() ); - else - return KCompletion::makeCompletion( d->compl_text ); -} - -/* - * isRunning - * - * Return true if either a KIO job or the DirLister - * is running - */ -bool KURLCompletion::isRunning() const -{ - return d->list_job || (d->dirListThread && !d->dirListThread->finished()); -} - -/* - * stop - * - * Stop and delete a running KIO job or the DirLister - */ -void KURLCompletion::stop() -{ - if ( d->list_job ) { - d->list_job->kill(); - d->list_job = 0L; - } - - if ( !d->list_urls.isEmpty() ) { - TQValueList<KURL*>::Iterator it = d->list_urls.begin(); - for ( ; it != d->list_urls.end(); it++ ) - delete (*it); - d->list_urls.clear(); - } - - if ( d->dirListThread ) { - d->dirListThread->requestTermination(); - d->dirListThread = 0; - } -} - -/* - * Keep track of the last listed directory - */ -void KURLCompletion::setListedURL( int complType, - const TQString& dir, - const TQString& filter, - bool no_hidden ) -{ - d->last_compl_type = complType; - d->last_path_listed = dir; - d->last_file_listed = filter; - d->last_no_hidden = (int)no_hidden; - d->last_prepend = d->prepend; -} - -bool KURLCompletion::isListedURL( int complType, - const TQString& dir, - const TQString& filter, - bool no_hidden ) -{ - return d->last_compl_type == complType - && ( d->last_path_listed == dir - || (dir.isEmpty() && d->last_path_listed.isEmpty()) ) - && ( filter.startsWith(d->last_file_listed) - || (filter.isEmpty() && d->last_file_listed.isEmpty()) ) - && d->last_no_hidden == (int)no_hidden - && d->last_prepend == d->prepend; // e.g. relative path vs absolute -} - -/* - * isAutoCompletion - * - * Returns true if completion mode is Auto or Popup - */ -bool KURLCompletion::isAutoCompletion() -{ - return completionMode() == TDEGlobalSettings::CompletionAuto - || completionMode() == TDEGlobalSettings::CompletionPopup - || completionMode() == TDEGlobalSettings::CompletionMan - || completionMode() == TDEGlobalSettings::CompletionPopupAuto; -} -////////////////////////////////////////////////// -////////////////////////////////////////////////// -// User directories -// - -bool KURLCompletion::userCompletion(const MyURL &url, TQString *match) -{ - if ( url.protocol() != "file" - || !url.dir().isEmpty() - || url.file().at(0) != '~' ) - return false; - - if ( !isListedURL( CTUser ) ) { - stop(); - clear(); - - if ( !d->userListThread ) { - d->userListThread = new UserListThread( this ); - d->userListThread->start(); - - // If the thread finishes quickly make sure that the results - // are added to the first matching case. - - d->userListThread->wait( 200 ); - TQStringList l = d->userListThread->matches(); - addMatches( l ); - } - } - *match = finished(); - return true; -} - -///////////////////////////////////////////////////// -///////////////////////////////////////////////////// -// Environment variables -// - -extern char **environ; // Array of environment variables - -bool KURLCompletion::envCompletion(const MyURL &url, TQString *match) -{ - if ( url.file().at(0) != '$' ) - return false; - - if ( !isListedURL( CTEnv ) ) { - stop(); - clear(); - - char **env = environ; - - TQString dollar = TQString("$"); - - TQStringList l; - - while ( *env ) { - TQString s = TQString::fromLocal8Bit( *env ); - - int pos = s.find('='); - - if ( pos == -1 ) - pos = s.length(); - - if ( pos > 0 ) - l.append( dollar + s.left(pos) ); - - env++; - } - - addMatches( l ); - } - - setListedURL( CTEnv ); - - *match = finished(); - return true; -} - -////////////////////////////////////////////////// -////////////////////////////////////////////////// -// Executables -// - -bool KURLCompletion::exeCompletion(const MyURL &url, TQString *match) -{ - if ( url.protocol() != "file" ) - return false; - - TQString dir = url.dir(); - - dir = unescape( dir ); // remove escapes - - // Find directories to search for completions, either - // - // 1. complete path given in url - // 2. current directory (d->cwd) - // 3. $PATH - // 4. no directory at all - - TQStringList dirList; - - if ( !TQDir::isRelativePath(dir) ) { - // complete path in url - dirList.append( dir ); - } - else if ( !dir.isEmpty() && !d->cwd.isEmpty() ) { - // current directory - dirList.append( d->cwd + '/' + dir ); - } - else if ( !url.file().isEmpty() ) { - // $PATH - dirList = TQStringList::split(KPATH_SEPARATOR, - TQString::fromLocal8Bit(::getenv("PATH"))); - - TQStringList::Iterator it = dirList.begin(); - - for ( ; it != dirList.end(); it++ ) - (*it).append('/'); - } - - // No hidden files unless the user types "." - bool no_hidden_files = url.file().at(0) != '.'; - - // List files if needed - // - if ( !isListedURL( CTExe, dir, url.file(), no_hidden_files ) ) - { - stop(); - clear(); - - setListedURL( CTExe, dir, url.file(), no_hidden_files ); - - *match = listDirectories( dirList, url.file(), true, false, no_hidden_files ); - } - else if ( !isRunning() ) { - *match = finished(); - } - else { - if ( d->dirListThread ) - setListedURL( CTExe, dir, url.file(), no_hidden_files ); - *match = TQString::null; - } - - return true; -} - -////////////////////////////////////////////////// -////////////////////////////////////////////////// -// System Executables -// - -bool KURLCompletion::systemexeCompletion(const MyURL &url, TQString *match) -{ - if ( url.protocol() != "file" ) - return false; - - TQString dir = url.dir(); - - dir = unescape( dir ); // remove escapes - - // Find directories to search for completions, either - // - // 1. complete path given in url - // 2. current directory (d->cwd) - // 3. $PATH - // 4. no directory at all - - TQStringList dirList; - - if ( !url.file().isEmpty() ) { - // $PATH - dirList = TQStringList::split(KPATH_SEPARATOR, - TQString::fromLocal8Bit(::getenv("PATH"))); - - TQStringList::Iterator it = dirList.begin(); - - for ( ; it != dirList.end(); it++ ) - (*it).append('/'); - } - - // No hidden files unless the user types "." - bool no_hidden_files = url.file().at(0) != '.'; - - // List files if needed - // - if ( !isListedURL( CTExe, dir, url.file(), no_hidden_files ) ) - { - stop(); - clear(); - - setListedURL( CTExe, dir, url.file(), no_hidden_files ); - - *match = listDirectories( dirList, url.file(), true, false, no_hidden_files ); - } - else if ( !isRunning() ) { - *match = finished(); - } - else { - if ( d->dirListThread ) - setListedURL( CTExe, dir, url.file(), no_hidden_files ); - *match = TQString::null; - } - - return true; -} - -////////////////////////////////////////////////// -////////////////////////////////////////////////// -// Local files -// - -bool KURLCompletion::fileCompletion(const MyURL &url, TQString *match) -{ - if ( url.protocol() != "file" ) - return false; - - TQString dir = url.dir(); - - if (url.url()[0] == '.') - { - if (url.url().length() == 1) - { - *match = - ( completionMode() == TDEGlobalSettings::CompletionMan )? "." : ".."; - return true; - } - if (url.url().length() == 2 && url.url()[1]=='.') - { - *match=".."; - return true; - } - } - - //kdDebug() << "fileCompletion " << url.url() << " dir=" << dir << endl; - - dir = unescape( dir ); // remove escapes - - // Find directories to search for completions, either - // - // 1. complete path given in url - // 2. current directory (d->cwd) - // 3. no directory at all - - TQStringList dirList; - - if ( !TQDir::isRelativePath(dir) ) { - // complete path in url - dirList.append( dir ); - } - else if ( !d->cwd.isEmpty() ) { - // current directory - dirList.append( d->cwd + '/' + dir ); - } - - // No hidden files unless the user types "." - bool no_hidden_files = ( url.file().at(0) != '.' ); - - // List files if needed - // - if ( !isListedURL( CTFile, dir, "", no_hidden_files ) ) - { - stop(); - clear(); - - setListedURL( CTFile, dir, "", no_hidden_files ); - - // Append '/' to directories in Popup mode? - bool append_slash = ( d->popup_append_slash - && (completionMode() == TDEGlobalSettings::CompletionPopup || - completionMode() == TDEGlobalSettings::CompletionPopupAuto ) ); - - bool only_dir = ( d->mode == DirCompletion ); - - *match = listDirectories( dirList, "", false, only_dir, no_hidden_files, - append_slash ); - } - else if ( !isRunning() ) { - *match = finished(); - } - else { - *match = TQString::null; - } - - return true; -} - -////////////////////////////////////////////////// -////////////////////////////////////////////////// -// URLs not handled elsewhere... -// - -bool KURLCompletion::urlCompletion(const MyURL &url, TQString *match) -{ - //kdDebug() << "urlCompletion: url = " << *url.kurl() << endl; - if (d->onlyLocalProto && KProtocolInfo::protocolClass(url.protocol()) != ":local") - return false; - - // Use d->cwd as base url in case url is not absolute - KURL url_cwd = KURL::fromPathOrURL( d->cwd ); - - // Create an URL with the directory to be listed - KURL url_dir( url_cwd, url.kurl()->url() ); - - // Don't try url completion if - // 1. malformed url - // 2. protocol that doesn't have listDir() - // 3. there is no directory (e.g. "ftp://ftp.kd" shouldn't do anything) - // 4. auto or popup completion mode depending on settings - - bool man_or_info = ( url_dir.protocol() == TQString("man") - || url_dir.protocol() == TQString("info") ); - - if ( !url_dir.isValid() - || !KProtocolInfo::supportsListing( url_dir ) - || ( !man_or_info - && ( url_dir.directory(false,false).isEmpty() - || ( isAutoCompletion() - && !d->url_auto_completion ) ) ) ) { - return false; - } - - url_dir.setFileName(""); // not really nesseccary, but clear the filename anyway... - - // Remove escapes - TQString dir = url_dir.directory( false, false ); - - dir = unescape( dir ); - - url_dir.setPath( dir ); - - // List files if needed - // - if ( !isListedURL( CTUrl, url_dir.prettyURL(), url.file() ) ) - { - stop(); - clear(); - - setListedURL( CTUrl, url_dir.prettyURL(), "" ); - - TQValueList<KURL*> url_list; - url_list.append( new KURL( url_dir ) ); - - listURLs( url_list, "", false ); - - *match = TQString::null; - } - else if ( !isRunning() ) { - *match = finished(); - } - else { - *match = TQString::null; - } - - return true; -} - -////////////////////////////////////////////////// -////////////////////////////////////////////////// -// Directory and URL listing -// - -/* - * addMatches - * - * Called to add matches to KCompletion - */ -void KURLCompletion::addMatches( const TQStringList &matches ) -{ - TQStringList::ConstIterator it = matches.begin(); - TQStringList::ConstIterator end = matches.end(); - - if ( d->complete_url ) - for ( ; it != end; it++ ) - addItem( d->prepend + KURL::encode_string(*it)); - else - for ( ; it != end; it++ ) - addItem( d->prepend + (*it)); -} - -/* - * listDirectories - * - * List files starting with 'filter' in the given directories, - * either using DirLister or listURLs() - * - * In either case, addMatches() is called with the listed - * files, and eventually finished() when the listing is done - * - * Returns the match if available, or TQString::null if - * DirLister timed out or using kio - */ -TQString KURLCompletion::listDirectories( - const TQStringList &dirList, - const TQString &filter, - bool only_exe, - bool only_dir, - bool no_hidden, - bool append_slash_to_dir) -{ - assert( !isRunning() ); - - if ( !::getenv("KURLCOMPLETION_LOCAL_KIO") ) { - - //kdDebug() << "Listing (listDirectories): " << dirList << " filter=" << filter << " without KIO" << endl; - - // Don't use KIO - - if ( d->dirListThread ) - d->dirListThread->requestTermination(); - - TQStringList dirs; - - for ( TQStringList::ConstIterator it = dirList.begin(); - it != dirList.end(); - ++it ) - { - KURL url; - url.setPath(*it); - if ( kapp->authorizeURLAction( "list", KURL(), url ) ) - dirs.append( *it ); - } - - d->dirListThread = new DirectoryListThread( this, dirs, filter, only_exe, only_dir, - no_hidden, append_slash_to_dir ); - d->dirListThread->start(); - d->dirListThread->wait( 200 ); - addMatches( d->dirListThread->matches() ); - - return finished(); - } - else { - - // Use KIO - //kdDebug() << "Listing (listDirectories): " << dirList << " with KIO" << endl; - - TQValueList<KURL*> url_list; - - TQStringList::ConstIterator it = dirList.begin(); - - for ( ; it != dirList.end(); it++ ) - url_list.append( new KURL(*it) ); - - listURLs( url_list, filter, only_exe, no_hidden ); - // Will call addMatches() and finished() - - return TQString::null; - } -} - -/* - * listURLs - * - * Use KIO to list the given urls - * - * addMatches() is called with the listed files - * finished() is called when the listing is done - */ -void KURLCompletion::listURLs( - const TQValueList<KURL *> &urls, - const TQString &filter, - bool only_exe, - bool no_hidden ) -{ - assert( d->list_urls.isEmpty() ); - assert( d->list_job == 0L ); - - d->list_urls = urls; - d->list_urls_filter = filter; - d->list_urls_only_exe = only_exe; - d->list_urls_no_hidden = no_hidden; - -// kdDebug() << "Listing URLs: " << urls[0]->prettyURL() << ",..." << endl; - - // Start it off by calling slotIOFinished - // - // This will start a new list job as long as there - // are urls in d->list_urls - // - slotIOFinished(0L); -} - -/* - * slotEntries - * - * Receive files listed by KIO and call addMatches() - */ -void KURLCompletion::slotEntries(TDEIO::Job*, const TDEIO::UDSEntryList& entries) -{ - TQStringList matches; - - TDEIO::UDSEntryListConstIterator it = entries.begin(); - TDEIO::UDSEntryListConstIterator end = entries.end(); - - TQString filter = d->list_urls_filter; - - int filter_len = filter.length(); - - // Iterate over all files - // - for (; it != end; ++it) { - TQString name; - TQString url; - bool is_exe = false; - bool is_dir = false; - - TDEIO::UDSEntry e = *it; - TDEIO::UDSEntry::ConstIterator it_2 = e.begin(); - - for( ; it_2 != e.end(); it_2++ ) { - switch ( (*it_2).m_uds ) { - case TDEIO::UDS_NAME: - name = (*it_2).m_str; - break; - case TDEIO::UDS_ACCESS: - is_exe = ((*it_2).m_long & MODE_EXE) != 0; - break; - case TDEIO::UDS_FILE_TYPE: - is_dir = ((*it_2).m_long & S_IFDIR) != 0; - break; - case TDEIO::UDS_URL: - url = (*it_2).m_str; - break; - } - } - - if (!url.isEmpty()) { - // kdDebug() << "KURLCompletion::slotEntries url: " << url << endl; - name = KURL(url).fileName(); - } - - // kdDebug() << "KURLCompletion::slotEntries name: " << name << endl; - - if ( name[0] == '.' && - ( d->list_urls_no_hidden || - name.length() == 1 || - ( name.length() == 2 && name[1] == '.' ) ) ) - continue; - - if ( d->mode == DirCompletion && !is_dir ) - continue; - - if ( filter_len == 0 || name.left(filter_len) == filter ) { - if ( is_dir ) - name.append( '/' ); - - if ( is_exe || !d->list_urls_only_exe ) - matches.append( name ); - } - } - - addMatches( matches ); -} - -/* - * slotIOFinished - * - * Called when a KIO job is finished. - * - * Start a new list job if there are still urls in - * d->list_urls, otherwise call finished() - */ -void KURLCompletion::slotIOFinished( TDEIO::Job * job ) -{ -// kdDebug() << "slotIOFinished() " << endl; - - assert( job == d->list_job ); - - if ( d->list_urls.isEmpty() ) { - - d->list_job = 0L; - - finished(); // will call KCompletion::makeCompletion() - - } - else { - - KURL *kurl = d->list_urls.first(); - - d->list_urls.remove( kurl ); - -// kdDebug() << "Start KIO: " << kurl->prettyURL() << endl; - - d->list_job = TDEIO::listDir( *kurl, false ); - d->list_job->addMetaData("no-auth-prompt", "true"); - - assert( d->list_job ); - - connect( d->list_job, - TQT_SIGNAL(result(TDEIO::Job*)), - TQT_SLOT(slotIOFinished(TDEIO::Job*)) ); - - connect( d->list_job, - TQT_SIGNAL( entries( TDEIO::Job*, const TDEIO::UDSEntryList&)), - TQT_SLOT( slotEntries( TDEIO::Job*, const TDEIO::UDSEntryList&)) ); - - delete kurl; - } -} - -/////////////////////////////////////////////////// -/////////////////////////////////////////////////// - -/* - * postProcessMatch, postProcessMatches - * - * Called by KCompletion before emitting match() and matches() - * - * Append '/' to directories for file completion. This is - * done here to avoid stat()'ing a lot of files - */ -void KURLCompletion::postProcessMatch( TQString *match ) const -{ -// kdDebug() << "KURLCompletion::postProcess: " << *match << endl; - - if ( !match->isEmpty() ) { - - // Add '/' to directories in file completion mode - // unless it has already been done - if ( d->last_compl_type == CTFile ) - adjustMatch( *match ); - } -} - -void KURLCompletion::adjustMatch( TQString& match ) const -{ - if ( match.at( match.length()-1 ) != '/' ) - { - TQString copy; - - if ( match.startsWith( TQString("file:") ) ) - copy = KURL(match).path(); - else - copy = match; - - expandTilde( copy ); - expandEnv( copy ); - if ( TQDir::isRelativePath(copy) ) - copy.prepend( d->cwd + '/' ); - -// kdDebug() << "postProcess: stating " << copy << endl; - - KDE_struct_stat sbuff; - - TQCString file = TQFile::encodeName( copy ); - - if ( KDE_stat( (const char*)file, &sbuff ) == 0 ) { - if ( S_ISDIR ( sbuff.st_mode ) ) - match.append( '/' ); - } - else { - kdDebug() << "Could not stat file " << copy << endl; - } - } -} - -void KURLCompletion::postProcessMatches( TQStringList * matches ) const -{ - if ( !matches->isEmpty() && d->last_compl_type == CTFile ) { - TQStringList::Iterator it = matches->begin(); - for (; it != matches->end(); ++it ) { - adjustMatch( (*it) ); - } - } -} - -void KURLCompletion::postProcessMatches( KCompletionMatches * matches ) const -{ - if ( !matches->isEmpty() && d->last_compl_type == CTFile ) { - KCompletionMatches::Iterator it = matches->begin(); - for (; it != matches->end(); ++it ) { - adjustMatch( (*it).value() ); - } - } -} - -void KURLCompletion::customEvent(TQCustomEvent *e) -{ - if ( e->type() == CompletionMatchEvent::uniqueType() ) { - - CompletionMatchEvent *event = static_cast<CompletionMatchEvent *>( e ); - - event->completionThread()->wait(); - - if ( !isListedURL( CTUser ) ) { - stop(); - clear(); - addMatches( event->completionThread()->matches() ); - } - - setListedURL( CTUser ); - - if ( d->userListThread == event->completionThread() ) - d->userListThread = 0; - - if ( d->dirListThread == event->completionThread() ) - d->dirListThread = 0; - - delete event->completionThread(); - } -} - -// static -TQString KURLCompletion::replacedPath( const TQString& text, bool replaceHome, bool replaceEnv ) -{ - if ( text.isEmpty() ) - return text; - - MyURL url( text, TQString::null ); // no need to replace something of our current cwd - if ( !url.kurl()->isLocalFile() ) - return text; - - url.filter( replaceHome, replaceEnv ); - return url.dir() + url.file(); -} - - -TQString KURLCompletion::replacedPath( const TQString& text ) -{ - return replacedPath( text, d->replace_home, d->replace_env ); -} - -///////////////////////////////////////////////////////// -///////////////////////////////////////////////////////// -// Static functions - -/* - * expandEnv - * - * Expand environment variables in text. Escaped '$' are ignored. - * Return true if expansion was made. - */ -static bool expandEnv( TQString &text ) -{ - // Find all environment variables beginning with '$' - // - int pos = 0; - - bool expanded = false; - - while ( (pos = text.find('$', pos)) != -1 ) { - - // Skip escaped '$' - // - if ( text[pos-1] == '\\' ) { - pos++; - } - // Variable found => expand - // - else { - // Find the end of the variable = next '/' or ' ' - // - int pos2 = text.find( ' ', pos+1 ); - int pos_tmp = text.find( '/', pos+1 ); - - if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) ) - pos2 = pos_tmp; - - if ( pos2 == -1 ) - pos2 = text.length(); - - // Replace if the variable is terminated by '/' or ' ' - // and defined - // - if ( pos2 >= 0 ) { - int len = pos2 - pos; - TQString key = text.mid( pos+1, len-1); - TQString value = - TQString::fromLocal8Bit( ::getenv(key.local8Bit()) ); - - if ( !value.isEmpty() ) { - expanded = true; - text.replace( pos, len, value ); - pos = pos + value.length(); - } - else { - pos = pos2; - } - } - } - } - - return expanded; -} - -/* - * expandTilde - * - * Replace "~user" with the users home directory - * Return true if expansion was made. - */ -static bool expandTilde(TQString &text) -{ - if ( text[0] != '~' ) - return false; - - bool expanded = false; - - // Find the end of the user name = next '/' or ' ' - // - int pos2 = text.find( ' ', 1 ); - int pos_tmp = text.find( '/', 1 ); - - if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) ) - pos2 = pos_tmp; - - if ( pos2 == -1 ) - pos2 = text.length(); - - // Replace ~user if the user name is terminated by '/' or ' ' - // - if ( pos2 >= 0 ) { - - TQString user = text.mid( 1, pos2-1 ); - TQString dir; - - // A single ~ is replaced with $HOME - // - if ( user.isEmpty() ) { - dir = TQDir::homeDirPath(); - } - // ~user is replaced with the dir from passwd - // - else { - struct passwd *pw = ::getpwnam( user.local8Bit() ); - - if ( pw ) - dir = TQFile::decodeName( pw->pw_dir ); - - ::endpwent(); - } - - if ( !dir.isEmpty() ) { - expanded = true; - text.replace(0, pos2, dir); - } - } - - return expanded; -} - -/* - * unescape - * - * Remove escapes and return the result in a new string - * - */ -static TQString unescape(const TQString &text) -{ - TQString result; - - for (uint pos = 0; pos < text.length(); pos++) - if ( text[pos] != '\\' ) - result.insert( result.length(), text[pos] ); - - return result; -} - -void KURLCompletion::virtual_hook( int id, void* data ) -{ KCompletion::virtual_hook( id, data ); } - -#include "kurlcompletion.moc" - diff --git a/kio/kio/kurlcompletion.h b/kio/kio/kurlcompletion.h deleted file mode 100644 index f785696b4..000000000 --- a/kio/kio/kurlcompletion.h +++ /dev/null @@ -1,236 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Smith <dsmith@algonet.se> - - This class was inspired by a previous KURLCompletion by - Henner Zeller <zeller@think.de> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KURLCOMPLETION_H -#define KURLCOMPLETION_H - -#include <kcompletion.h> -#include <kio/jobclasses.h> -#include <tqstring.h> -#include <tqstringlist.h> - -class KURL; -class KURLCompletionPrivate; - -/** - * This class does completion of URLs including user directories (~user) - * and environment variables. Remote URLs are passed to KIO. - * - * @short Completion of a single URL - * @author David Smith <dsmith@algonet.se> - */ -class TDEIO_EXPORT KURLCompletion : public KCompletion -{ - Q_OBJECT - -public: - /** - * Determines how completion is done. - * @li ExeCompletion - executables in $PATH or with full path. - * @li FileCompletion - all files with full path or in dir(), URLs - * are listed using KIO. - * @li DirCompletion - Same as FileCompletion but only returns directories. - */ - enum Mode { ExeCompletion=1, FileCompletion, DirCompletion, SystemExeCompletion }; - - /** - * Constructs a KURLCompletion object in FileCompletion mode. - */ - KURLCompletion(); - /** - * This overloaded constructor allows you to set the Mode to ExeCompletion - * or FileCompletion without using setMode. Default is FileCompletion. - */ - KURLCompletion(Mode); - /** - * Destructs the KURLCompletion object. - */ - virtual ~KURLCompletion(); - - /** - * Finds completions to the given text. - * - * Remote URLs are listed with KIO. For performance reasons, local files - * are listed with KIO only if KURLCOMPLETION_LOCAL_KIO is set. - * The completion is done asyncronously if KIO is used. - * - * Returns the first match for user, environment, and local dir completion - * and TQString::null for asynchronous completion (KIO or threaded). - * - * @param text the text to complete - * @return the first match, or TQString::null if not found - */ - virtual TQString makeCompletion(const TQString &text); // KDE4: remove return value, it's often null due to threading - - /** - * Sets the current directory (used as base for completion). - * Default = $HOME. - * @param dir the current directory, either as a path or URL - */ - virtual void setDir(const TQString &dir); - - /** - * Returns the current directory, as it was given in setDir - * @return the current directory (path or URL) - */ - virtual TQString dir() const; - - /** - * Check whether asynchronous completion is in progress. - * @return true if asynchronous completion is in progress - */ - virtual bool isRunning() const; - - /** - * Stops asynchronous completion. - */ - virtual void stop(); - - /** - * Returns the completion mode: exe or file completion (default FileCompletion). - * @return the completion mode - */ - virtual Mode mode() const; - - /** - * Changes the completion mode: exe or file completion - * @param mode the new completion mode - */ - virtual void setMode( Mode mode ); - - /** - * Checks whether environment variables are completed and - * whether they are replaced internally while finding completions. - * Default is enabled. - * @return true if environment vvariables will be replaced - */ - virtual bool replaceEnv() const; - - /** - * Enables/disables completion and replacement (internally) of - * environment variables in URLs. Default is enabled. - * @param replace true to replace environment variables - */ - virtual void setReplaceEnv( bool replace ); - - /** - * Returns whether ~username is completed and whether ~username - * is replaced internally with the user's home directory while - * finding completions. Default is enabled. - * @return true to replace tilde with the home directory - */ - virtual bool replaceHome() const; - - /** - * Enables/disables completion of ~username and replacement - * (internally) of ~username with the user's home directory. - * Default is enabled. - * @param replace true to replace tilde with the home directory - */ - virtual void setReplaceHome( bool replace ); - - /** - * Replaces username and/or environment variables, depending on the - * current settings and returns the filtered url. Only works with - * local files, i.e. returns back the original string for non-local - * urls. - * @param text the text to process - * @return the path or URL resulting from this operation. If you - * want to convert it to a KURL, use KURL::fromPathOrURL. - */ - TQString replacedPath( const TQString& text ); - - /** - * @internal I'll let ossi add a real one to KShell :) - * @since 3.2 - */ - static TQString replacedPath( const TQString& text, - bool replaceHome, bool replaceEnv = true ); - - class MyURL; -protected: - // Called by KCompletion, adds '/' to directories - void postProcessMatch( TQString *match ) const; - void postProcessMatches( TQStringList *matches ) const; - void postProcessMatches( KCompletionMatches* matches ) const; - - virtual void customEvent( TQCustomEvent *e ); - -protected slots: - void slotEntries( TDEIO::Job *, const TDEIO::UDSEntryList& ); - void slotIOFinished( TDEIO::Job * ); - -private: - - bool isAutoCompletion(); - - bool userCompletion(const MyURL &url, TQString *match); - bool envCompletion(const MyURL &url, TQString *match); - bool exeCompletion(const MyURL &url, TQString *match); - bool systemexeCompletion(const MyURL &url, TQString *match); - bool fileCompletion(const MyURL &url, TQString *match); - bool urlCompletion(const MyURL &url, TQString *match); - - // List a directory using readdir() - void listDir( const TQString& dir, - TQStringList *matches, - const TQString& filter, - bool only_exe, - bool no_hidden ); - - // List the next dir in m_dirs - TQString listDirectories(const TQStringList &, - const TQString &, - bool only_exe = false, - bool only_dir = false, - bool no_hidden = false, - bool stat_files = true); - - void listURLs( const TQValueList<KURL *> &urls, - const TQString &filter = TQString::null, - bool only_exe = false, - bool no_hidden = false ); - - void addMatches( const TQStringList & ); - TQString finished(); - - void init(); - - void setListedURL(int compl_type /* enum ComplType */, - const TQString& dir = TQString::null, - const TQString& filter = TQString::null, - bool no_hidden = false ); - - bool isListedURL( int compl_type /* enum ComplType */, - const TQString& dir = TQString::null, - const TQString& filter = TQString::null, - bool no_hidden = false ); - - void adjustMatch( TQString& match ) const; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - KURLCompletionPrivate *d; -}; - -#endif // KURLCOMPLETION_H diff --git a/kio/kio/kurlpixmapprovider.cpp b/kio/kio/kurlpixmapprovider.cpp deleted file mode 100644 index caeedf066..000000000 --- a/kio/kio/kurlpixmapprovider.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* This file is part of the KDE libraries - - Copyright (c) 2000 Carsten Pfeiffer <pfeiffer@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License (LGPL) as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kurlpixmapprovider.h" - -TQPixmap KURLPixmapProvider::pixmapFor( const TQString& url, int size ) { - KURL u; - if ( url.at(0) == '/' ) - u.setPath( url ); - else - u = url; - return KMimeType::pixmapForURL( u, 0, KIcon::Desktop, size ); - } - -void KURLPixmapProvider::virtual_hook( int id, void* data ) -{ KPixmapProvider::virtual_hook( id, data ); } diff --git a/kio/kio/kurlpixmapprovider.h b/kio/kio/kurlpixmapprovider.h deleted file mode 100644 index 82be4bd1b..000000000 --- a/kio/kio/kurlpixmapprovider.h +++ /dev/null @@ -1,59 +0,0 @@ -/* This file is part of the KDE libraries - - Copyright (c) 2000 Carsten Pfeiffer <pfeiffer@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License (LGPL) as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KURLPIXMAPPROVIDER_H -#define KURLPIXMAPPROVIDER_H - -#include <kpixmapprovider.h> -#include <kmimetype.h> - -/** - * Implementation of KPixmapProvider. - * - * Uses KMimeType::pixmapForURL() to resolve icons. - * - * Instatiate this class and supply it to the desired class, e.g. - * \code - * KHistoryCombo *combo = new KHistoryCombo( this ); - * combo->setPixmapProvider( new KURLPixmapProvider ); - * [...] - * \endcode - * - * @short Resolves pixmaps for URLs - * @author Carsten Pfeiffer <pfeiffer@kde.org> - */ -class TDEIO_EXPORT KURLPixmapProvider : public KPixmapProvider -{ -public: - /** - * Returns a pixmap for @p url with size @p size. - * Uses KMimeType::pixmapForURL(). - * @param url the URL to fetch a pixmap for - * @param size the size of the pixmap in pixels, or 0 for default. - * @return the resulting pixmap - * @see KIcon::StdSizes - */ - virtual TQPixmap pixmapFor( const TQString& url, int size = 0 ); -protected: - virtual void virtual_hook( int id, void* data ); -}; - - -#endif // KURLPIXMAPPROVIDER_H diff --git a/kio/kio/kuserprofile.cpp b/kio/kio/kuserprofile.cpp deleted file mode 100644 index b413b3cd5..000000000 --- a/kio/kio/kuserprofile.cpp +++ /dev/null @@ -1,355 +0,0 @@ -/* This file is part of the KDE libraries - * Copyright (C) 1999 Torben Weis <weis@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation; - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include "kuserprofile.h" -#include "kservice.h" -#include "kservicetype.h" -#include "kservicetypefactory.h" - -#include <kconfig.h> -#include <kapplication.h> -#include <kglobal.h> -#include <kdebug.h> -#include <kstaticdeleter.h> - -#include <tqtl.h> - -template class TQPtrList<KServiceTypeProfile>; -typedef TQPtrList<KServiceTypeProfile> KServiceTypeProfileList; - -/********************************************* - * - * KServiceTypeProfile - * - *********************************************/ - -KServiceTypeProfileList* KServiceTypeProfile::s_lstProfiles = 0L; -static KStaticDeleter< KServiceTypeProfileList > profileDeleter; -bool KServiceTypeProfile::s_configurationMode = false; - -void KServiceTypeProfile::initStatic() -{ - if ( s_lstProfiles ) - return; - - // Make sure that a KServiceTypeFactory gets created. - (void) KServiceTypeFactory::self(); - - profileDeleter.setObject(s_lstProfiles, new KServiceTypeProfileList); - s_lstProfiles->setAutoDelete( true ); - - TDEConfig config( "profilerc", true, false); - - static const TQString & defaultGroup = TDEGlobal::staticQString("<default>"); - - TQStringList tmpList = config.groupList(); - for (TQStringList::Iterator aIt = tmpList.begin(); - aIt != tmpList.end(); ++aIt) { - if ( *aIt == defaultGroup ) - continue; - - config.setGroup( *aIt ); - - TQString appId = config.readEntry( "Application" ); - - KService::Ptr pService = KService::serviceByStorageId(appId); - - if ( pService ) { - TQString application = pService->storageId(); - TQString type = config.readEntry( "ServiceType" ); - TQString type2 = config.readEntry( "GenericServiceType" ); - if (type2.isEmpty()) // compat code - type2 = (pService->type() == "Application") ? "Application" : "KParts/ReadOnlyPart"; - int pref = config.readNumEntry( "Preference" ); - - if ( !type.isEmpty() /* && pref >= 0*/ ) // Don't test for pref here. We want those in the list, to mark them as forbidden - { - KServiceTypeProfile* p = - KServiceTypeProfile::serviceTypeProfile( type, type2 ); - - if ( !p ) { - p = new KServiceTypeProfile( type, type2 ); - s_lstProfiles->append( p ); - } - - bool allow = config.readBoolEntry( "AllowAsDefault" ); - //kdDebug(7014) << "KServiceTypeProfile::initStatic adding service " << application << " to profile for " << type << "," << type2 << " with preference " << pref << endl; - p->addService( application, pref, allow ); - } - } - } -} - -//static -void KServiceTypeProfile::clear() -{ - // HACK tdesycoca may open the dummy db, in such case the first call to tdesycoca - // in initStatic() leads to closing the dummy db and clear() being called - // in the middle of it, making s_lstProfiles be NULL - if( s_lstProfiles == NULL || s_lstProfiles->count() == 0 ) - return; - profileDeleter.destructObject(); -} - -//static -KServiceTypeProfile::OfferList KServiceTypeProfile::offers( const TQString& _servicetype, const TQString& _genericServiceType ) -{ - OfferList offers; - TQStringList serviceList; - //kdDebug(7014) << "KServiceTypeProfile::offers( " << _servicetype << "," << _genericServiceType << " )" << endl; - - // Note that KServiceTypeProfile::offers() calls KServiceType::offers(), - // so we _do_ get the new services, that are available but not in the profile. - if ( _genericServiceType.isEmpty() ) - { - initStatic(); - // We want all profiles for servicetype, if we have profiles. - // ## Slow loop, if profilerc is big. We should use a map instead? - TQPtrListIterator<KServiceTypeProfile> it( *s_lstProfiles ); - for( ; it.current(); ++it ) - if ( it.current()->m_strServiceType == _servicetype ) - { - offers += it.current()->offers(); - } - //kdDebug(7014) << "Found profile: " << offers.count() << " offers" << endl; - } - else - { - KServiceTypeProfile* profile = serviceTypeProfile( _servicetype, _genericServiceType ); - if ( profile ) - { - //kdDebug(7014) << "Found profile: " << profile->offers().count() << " offers" << endl; - offers += profile->offers(); - } - else - { - // Try the other way round, order is not like size, it doesn't matter. - profile = serviceTypeProfile( _genericServiceType, _servicetype ); - if ( profile ) - { - //kdDebug(7014) << "Found profile after switching: " << profile->offers().count() << " offers" << endl; - offers += profile->offers(); - } - } - } - - // Collect services, to make the next loop faster - OfferList::Iterator itOffers = offers.begin(); - for( ; itOffers != offers.end(); ++itOffers ) - serviceList += (*itOffers).service()->desktopEntryPath(); // this should identify each service uniquely - //kdDebug(7014) << "serviceList: " << serviceList.join(",") << endl; - - // Now complete with any other offers that aren't in the profile - // This can be because the services have been installed after the profile was written, - // but it's also the case for any service that's neither App nor ReadOnlyPart, e.g. RenameDlg/Plugin - KService::List list = KServiceType::offers( _servicetype ); - //kdDebug(7014) << "Using KServiceType::offers, result: " << list.count() << " offers" << endl; - TQValueListIterator<KService::Ptr> it = list.begin(); - for( ; it != list.end(); ++it ) - { - if (_genericServiceType.isEmpty() /*no constraint*/ || (*it)->hasServiceType( _genericServiceType )) - { - // Check that we don't already have it ;) - if ( serviceList.find( (*it)->desktopEntryPath() ) == serviceList.end() ) - { - bool allow = (*it)->allowAsDefault(); - KServiceOffer o( (*it), (*it)->initialPreferenceForMimeType(_servicetype), allow ); - offers.append( o ); - //kdDebug(7014) << "Appending offer " << (*it)->name() << " initial preference=" << (*it)->initialPreference() << " allow-as-default=" << allow << endl; - } - //else - // kdDebug(7014) << "Already having offer " << (*it)->name() << endl; - } - } - - qBubbleSort( offers ); - -#if 0 - // debug code, comment if you wish but don't remove. - kdDebug(7014) << "Sorted list:" << endl; - OfferList::Iterator itOff = offers.begin(); - for( ; itOff != offers.end(); ++itOff ) - kdDebug(7014) << (*itOff).service()->name() << " allow-as-default=" << (*itOff).allowAsDefault() << endl; -#endif - - //kdDebug(7014) << "Returning " << offers.count() << " offers" << endl; - return offers; -} - -KServiceTypeProfile::KServiceTypeProfile( const TQString& _servicetype, const TQString& _genericServiceType ) -{ - initStatic(); - - m_strServiceType = _servicetype; - m_strGenericServiceType = _genericServiceType; -} - -KServiceTypeProfile::~KServiceTypeProfile() -{ -} - -void KServiceTypeProfile::addService( const TQString& _service, - int _preference, bool _allow_as_default ) -{ - m_mapServices[ _service ].m_iPreference = _preference; - m_mapServices[ _service ].m_bAllowAsDefault = _allow_as_default; -} - -int KServiceTypeProfile::preference( const TQString& _service ) const -{ - KService::Ptr service = KService::serviceByName( _service ); - if (!service) - return 0; - TQMap<TQString,Service>::ConstIterator it = m_mapServices.find( service->storageId() ); - if ( it == m_mapServices.end() ) - return 0; - - return it.data().m_iPreference; -} - -bool KServiceTypeProfile::allowAsDefault( const TQString& _service ) const -{ - KService::Ptr service = KService::serviceByName( _service ); - if (!service) - return false; - - // Does the service itself not allow that ? - if ( !service->allowAsDefault() ) - return false; - - // Look what the user says ... - TQMap<TQString,Service>::ConstIterator it = m_mapServices.find( service->storageId() ); - if ( it == m_mapServices.end() ) - return 0; - - return it.data().m_bAllowAsDefault; -} - -KServiceTypeProfile* KServiceTypeProfile::serviceTypeProfile( const TQString& _servicetype, const TQString& _genericServiceType ) -{ - initStatic(); - static const TQString& app_str = TDEGlobal::staticQString("Application"); - - const TQString &_genservicetype = ((!_genericServiceType.isEmpty()) ? _genericServiceType : app_str); - - TQPtrListIterator<KServiceTypeProfile> it( *s_lstProfiles ); - for( ; it.current(); ++it ) - if (( it.current()->m_strServiceType == _servicetype ) && - ( it.current()->m_strGenericServiceType == _genservicetype)) - return it.current(); - - return 0; -} - - -KServiceTypeProfile::OfferList KServiceTypeProfile::offers() const -{ - OfferList offers; - - kdDebug(7014) << "KServiceTypeProfile::offers serviceType=" << m_strServiceType << " genericServiceType=" << m_strGenericServiceType << endl; - KService::List list = KServiceType::offers( m_strServiceType ); - TQValueListIterator<KService::Ptr> it = list.begin(); - for( ; it != list.end(); ++it ) - { - //kdDebug(7014) << "KServiceTypeProfile::offers considering " << (*it)->name() << endl; - if ( m_strGenericServiceType.isEmpty() || (*it)->hasServiceType( m_strGenericServiceType ) ) - { - // Now look into the profile, to find this service's preference. - TQMap<TQString,Service>::ConstIterator it2 = m_mapServices.find( (*it)->storageId() ); - - if( it2 != m_mapServices.end() ) - { - //kdDebug(7014) << "found in mapServices pref=" << it2.data().m_iPreference << endl; - if ( it2.data().m_iPreference > 0 ) { - bool allow = (*it)->allowAsDefault(); - if ( allow ) - allow = it2.data().m_bAllowAsDefault; - KServiceOffer o( (*it), it2.data().m_iPreference, allow ); - offers.append( o ); - } - } - else - { - //kdDebug(7014) << "not found in mapServices. Appending." << endl; - // We use 0 as the preference to ensure new apps don't take over existing apps (which default to 1) - KServiceOffer o( (*it), 0, (*it)->allowAsDefault() ); - offers.append( o ); - } - }/* else - kdDebug(7014) << "Doesn't have " << m_strGenericServiceType << endl;*/ - } - - qBubbleSort( offers ); - - //kdDebug(7014) << "KServiceTypeProfile::offers returning " << offers.count() << " offers" << endl; - return offers; -} - -KService::Ptr KServiceTypeProfile::preferredService( const TQString & _serviceType, const TQString & _genericServiceType ) -{ - OfferList lst = offers( _serviceType, _genericServiceType ); - - OfferList::Iterator itOff = lst.begin(); - // Look for the first one that is allowed as default. - // Since the allowed-as-default are first anyway, we only have - // to look at the first one to know. - if( itOff != lst.end() && (*itOff).allowAsDefault() ) - return (*itOff).service(); - - //kdDebug(7014) << "No offers, or none allowed as default" << endl; - return 0L; -} - -/********************************************* - * - * KServiceOffer - * - *********************************************/ - -KServiceOffer::KServiceOffer() -{ - m_iPreference = -1; -} - -KServiceOffer::KServiceOffer( const KServiceOffer& _o ) -{ - m_pService = _o.m_pService; - m_iPreference = _o.m_iPreference; - m_bAllowAsDefault = _o.m_bAllowAsDefault; -} - -KServiceOffer::KServiceOffer( KService::Ptr _service, int _pref, bool _default ) -{ - m_pService = _service; - m_iPreference = _pref; - m_bAllowAsDefault = _default; -} - - -bool KServiceOffer::operator< ( const KServiceOffer& _o ) const -{ - // Put offers allowed as default FIRST. - if ( _o.m_bAllowAsDefault && !m_bAllowAsDefault ) - return false; // _o is default and not 'this'. - if ( !_o.m_bAllowAsDefault && m_bAllowAsDefault ) - return true; // 'this' is default but not _o. - // Both offers are allowed or not allowed as default - // -> use preferences to sort them - // The bigger the better, but we want the better FIRST - return _o.m_iPreference < m_iPreference; -} diff --git a/kio/kio/kuserprofile.h b/kio/kio/kuserprofile.h deleted file mode 100644 index 45b58fe6a..000000000 --- a/kio/kio/kuserprofile.h +++ /dev/null @@ -1,282 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kuserprofile_h__ -#define __kuserprofile_h__ - -#include <tqmap.h> -#include <tqstring.h> -#include <tqptrlist.h> -#include <tqvaluelist.h> - -#include <kservice.h> - -/** - * This class holds the user-specific preferences of a service - * (whether it can be a default offer or not, how big is the preference - * for this offer, ...). Basically it is a reference to a - * KService, a number that represents the user's preference (bigger - * is better) and a flag whether the KService can be used as default. - * - * @see KService - * @short Holds the user's preference of a service. - */ -class TDEIO_EXPORT KServiceOffer -{ -public: - /** - * Create an invalid service offer. - */ - KServiceOffer(); - - /** - * Copy constructor. - * Shallow copy (the KService will not be copied). - */ - KServiceOffer( const KServiceOffer& ); - - /** - * Creates a new KServiceOffer. - * @param _service a pointer to the KService - * @param _pref the user's preference value, must be positive, - * bigger is better - * @param _default true if the service should be used as - * default - */ - KServiceOffer( KService::Ptr _service, - int _pref, bool _default ); - - /** - * A service is bigger that the other when it can be default - * (and the other is not) and its preference value it higher. - */ - bool operator< ( const KServiceOffer& ) const; - /** - * Is it allowed to use this service for default actions - * (e.g. Left Click in a file manager, or KRun in general). - * @return true if the service is a allowed as default - */ - bool allowAsDefault() const { return m_bAllowAsDefault; } - /** - * The bigger this number is, the better is this service. - * @return the preference number (negative numbers will be - * returned by invalid service offers) - */ - int preference() const { return m_iPreference; } - /** - * The service which this offer is about. - * @return the service this offer is about, can be 0 - * in valid offers or when not set - */ - KService::Ptr service() const { return m_pService; } - /** - * Check whether the entry is valid. A service is valid if - * its preference value is positive. - * @return true if the service offer is valid - */ - bool isValid() const { return m_iPreference >= 0; } - -private: - int m_iPreference; - bool m_bAllowAsDefault; - KService::Ptr m_pService; -private: - class KServiceOfferPrivate; -}; - -/** - * KServiceTypeProfile represents the user's preferences for services - * of a service type. - * It consists of a list of services (service offers) for the service type - * that is sorted by the user's preference. - * KTrader uses KServiceTypeProfile to sort its results, so usually - * you can just use KTrader to find the user's preferred service. - * - * @see KService - * @see KServiceType - * @see KServiceOffer - * @see KTrader - * @short Represents the user's preferences for services of a service type - */ -class TDEIO_EXPORT KServiceTypeProfile -{ -public: - typedef TQValueList<KServiceOffer> OfferList; - - ~KServiceTypeProfile(); - - /** - * @deprecated Remove in KDE 4, unused. - * Returns the users preference of the given service. - * @param _service the name of the service to check - * @return the user's preference number of the given - * @p _service, or 0 the service is unknown. - */ - int preference( const TQString& _service ) const; - - /** - * @deprecated Remove in KDE 4, unused. - * Checks whether the given @p _service can be used as default. - * @param _service the name of the service to check - * @return true if allowed as default - */ - bool allowAsDefault( const TQString& _service ) const; - - /** - * Returns the list of all service offers for the service types - * that are represented by this profile. - * @return the list of KServiceOffer instances - */ - OfferList offers() const; - - /** - * Returns the preferred service for @p _serviceType and @p _genericServiceType - * ("Application", type of component, or null). - * - * @param serviceType the service type (e.g. a MIME type) - * @param genericServiceType the generic service type (e.g. "Application" or - * "KParts/ReadOnlyPart") - * @return the preferred service, or 0 if no service is available - */ - static KService::Ptr preferredService( const TQString & serviceType, const TQString & genericServiceType ); - - /** - * Returns the profile for the requested service type. - * @param servicetype the service type (e.g. a MIME type) - * @param genericServiceType the generic service type (e.g. "Application" - * or "KParts/ReadOnlyPart"). Can be TQString::null, - * then the "Application" generic type will be used - * @return the KServiceTypeProfile with the given arguments, or 0 if not found - */ - static KServiceTypeProfile* serviceTypeProfile( const TQString& servicetype, const TQString & genericServiceType = TQString::null ); - - /** - * Returns the offers associated with a given servicetype, sorted by preference. - * This is what KTrader uses to get the list of offers, before applying the - * constraints and preferences. - * - * If @p genericServiceType is specified, a list is returned with - * the offers associated with the combination of the two service types. - * This is almost like an "foo in ServiceTypes" constraint in the KTrader, - * but the difference is that to order the offers, we will look at entries - * specifically for those two service types. Typically, this is used for - * getting the list of embeddable components that can handle a given mimetype. - * In that case, @p servicetype is the mimetype and @p genericServiceType is "KParts/ReadOnlyPart". - * - * @param servicetype the service type (e.g. a MIME type) - * @param genericServiceType the generic service type (e.g. "Application" - * or "KParts/ReadOnlyPart"). Can be TQString::null, - * then all generic types will be included - * @return the list of offers witht he given parameters - */ - static OfferList offers( const TQString& servicetype, const TQString& genericServiceType = TQString::null ); - - /** - * Returns a list of all KServiceTypeProfiles. - * @return a list of all KServiceTypeProfiles - */ - static const TQPtrList<KServiceTypeProfile>& serviceTypeProfiles() { return *s_lstProfiles; } - - /** - * Clear all cached information - */ - static void clear(); - - /** - * This method activates a special mode of KServiceTypeProfile, in which all/all - * and all/allfiles are excluded from the results of the queries. - * It is meant for the configuration module _only_. - * @internal - */ - static void setConfigurationMode() { s_configurationMode = true; } - - /** - * This method deactivates the special mode above of KServiceTypeProfile - * It is meant for the configuration module _only_. - * @internal - * @since 3.5.7 - */ - static void unsetConfigurationMode() { s_configurationMode = false; } - - /** - * @internal - */ - static bool configurationMode() { return s_configurationMode; } - -protected: - /** - * Constructor is called when the user profile is read for the - * first time. - * @param serviceType the service type (e.g. a MIME type) - * @param genericServiceType the generic service type (e.g. "Application" - * or "KParts/ReadOnlyPart"). Can be TQString::null, - * then the "Application" generic type will be used - */ - KServiceTypeProfile( const TQString& serviceType, - const TQString& genericServiceType = TQString::null ); - - /** - * Add a service to this profile. - * @param _service the name of the service - * @param _preference the user's preference value, must be positive, - * bigger is better - * @param _allow_as_default true if the service should be used as - * default - */ - void addService( const TQString& _service, int _preference = 1, bool _allow_as_default = true ); - -private: - /** - * Represents the users assessment of a special service - */ - struct Service - { - /** - * The bigger this number is, the better is this service. - */ - int m_iPreference; - /** - * Is it allowed to use this service for default actions. - */ - bool m_bAllowAsDefault; - }; - - /** - * Map of all services for which we have assessments. - */ - TQMap<TQString,Service> m_mapServices; - - /** - * ServiceType of this profile. - */ - TQString m_strServiceType; - - /** - * Secondary ServiceType of this profile. - */ - TQString m_strGenericServiceType; - - static void initStatic(); - static TQPtrList<KServiceTypeProfile>* s_lstProfiles; - static bool s_configurationMode; -private: - class KServiceTypeProfilePrivate* d; -}; - -#endif diff --git a/kio/kio/kzip.cpp b/kio/kio/kzip.cpp deleted file mode 100644 index 6241cc1ca..000000000 --- a/kio/kio/kzip.cpp +++ /dev/null @@ -1,1460 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - Copyright (C) 2002 Holger Schroeder <holger-kde@holgis.net> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/* - This class implements a kioslave to access ZIP files from KDE. - you can use it in IO_ReadOnly or in IO_WriteOnly mode, and it - behaves just as expected (i hope ;-) ). - It can also be used in IO_ReadWrite mode, in this case one can - append files to an existing zip archive. when you append new files, which - are not yet in the zip, it works as expected, they are appended at the end. - when you append a file, which is already in the file, the reference to the - old file is dropped and the new one is added to the zip. but the - old data from the file itself is not deleted, it is still in the - zipfile. so when you want to have a small and garbagefree zipfile, - just read the contents of the appended zipfile and write it to a new one - in IO_WriteOnly mode. especially take care of this, when you don't want - to leak information of how intermediate versions of files in the zip - were looking. - For more information on the zip fileformat go to - http://www.pkware.com/support/appnote.html . - -*/ - -#include "kzip.h" -#include "kfilterdev.h" -#include "klimitediodevice.h" -#include <kmimetype.h> -#include <ksavefile.h> -#include <kdebug.h> - -#include <tqasciidict.h> -#include <tqfile.h> -#include <tqdir.h> -#include <tqdatetime.h> -#include <tqptrlist.h> - -#include <zlib.h> -#include <time.h> -#include <string.h> - -const int max_path_len = 4095; // maximum number of character a path may contain - -static void transformToMsDos(const TQDateTime& dt, char* buffer) -{ - if ( dt.isValid() ) - { - const TQ_UINT16 time = - ( dt.time().hour() << 11 ) // 5 bit hour - | ( dt.time().minute() << 5 ) // 6 bit minute - | ( dt.time().second() >> 1 ); // 5 bit double seconds - - buffer[0] = char(time); - buffer[1] = char(time >> 8); - - const TQ_UINT16 date = - ( ( dt.date().year() - 1980 ) << 9 ) // 7 bit year 1980-based - | ( dt.date().month() << 5 ) // 4 bit month - | ( dt.date().day() ); // 5 bit day - - buffer[2] = char(date); - buffer[3] = char(date >> 8); - } - else // !dt.isValid(), assume 1980-01-01 midnight - { - buffer[0] = 0; - buffer[1] = 0; - buffer[2] = 33; - buffer[3] = 0; - } -} - -static time_t transformFromMsDos(const char* buffer) -{ - TQ_UINT16 time = (uchar)buffer[0] | ( (uchar)buffer[1] << 8 ); - int h = time >> 11; - int m = ( time & 0x7ff ) >> 5; - int s = ( time & 0x1f ) * 2 ; - TQTime qt(h, m, s); - - TQ_UINT16 date = (uchar)buffer[2] | ( (uchar)buffer[3] << 8 ); - int y = ( date >> 9 ) + 1980; - int o = ( date & 0x1ff ) >> 5; - int d = ( date & 0x1f ); - TQDate qd(y, o, d); - - TQDateTime dt( qd, qt ); - return dt.toTime_t(); -} - -// == parsing routines for zip headers - -/** all relevant information about parsing file information */ -struct ParseFileInfo { - // file related info -// TQCString name; // filename - mode_t perm; // permissions of this file - time_t atime; // last access time (UNIX format) - time_t mtime; // modification time (UNIX format) - time_t ctime; // creation time (UNIX format) - int uid; // user id (-1 if not specified) - int gid; // group id (-1 if not specified) - TQCString guessed_symlink; // guessed symlink target - int extralen; // length of extra field - - // parsing related info - bool exttimestamp_seen; // true if extended timestamp extra field - // has been parsed - bool newinfounix_seen; // true if Info-ZIP Unix New extra field has - // been parsed - - ParseFileInfo() : perm(0100644), uid(-1), gid(-1), extralen(0), - exttimestamp_seen(false), newinfounix_seen(false) { - ctime = mtime = atime = time(0); - } -}; - -/** updates the parse information with the given extended timestamp extra field. - * @param buffer start content of buffer known to contain an extended - * timestamp extra field (without magic & size) - * @param size size of field content (must not count magic and size entries) - * @param islocal true if this is a local field, false if central - * @param pfi ParseFileInfo object to be updated - * @return true if processing was successful - */ -static bool parseExtTimestamp(const char *buffer, int size, bool islocal, - ParseFileInfo &pfi) { - if (size < 1) { - kdDebug(7040) << "premature end of extended timestamp (#1)" << endl; - return false; - }/*end if*/ - int flags = *buffer; // read flags - buffer += 1; - size -= 1; - - if (flags & 1) { // contains modification time - if (size < 4) { - kdDebug(7040) << "premature end of extended timestamp (#2)" << endl; - return false; - }/*end if*/ - pfi.mtime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8 - | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24); - buffer += 4; - size -= 4; - }/*end if*/ - // central extended field cannot contain more than the modification time - // even if other flags are set - if (!islocal) { - pfi.exttimestamp_seen = true; - return true; - }/*end if*/ - - if (flags & 2) { // contains last access time - if (size < 4) { - kdDebug(7040) << "premature end of extended timestamp (#3)" << endl; - return true; - }/*end if*/ - pfi.atime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8 - | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24); - buffer += 4; - size -= 4; - }/*end if*/ - - if (flags & 4) { // contains creation time - if (size < 4) { - kdDebug(7040) << "premature end of extended timestamp (#4)" << endl; - return true; - }/*end if*/ - pfi.ctime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8 - | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24); - buffer += 4; - }/*end if*/ - - pfi.exttimestamp_seen = true; - return true; -} - -/** updates the parse information with the given Info-ZIP Unix old extra field. - * @param buffer start of content of buffer known to contain an Info-ZIP - * Unix old extra field (without magic & size) - * @param size size of field content (must not count magic and size entries) - * @param islocal true if this is a local field, false if central - * @param pfi ParseFileInfo object to be updated - * @return true if processing was successful - */ -static bool parseInfoZipUnixOld(const char *buffer, int size, bool islocal, - ParseFileInfo &pfi) { - // spec mandates to omit this field if one of the newer fields are available - if (pfi.exttimestamp_seen || pfi.newinfounix_seen) return true; - - if (size < 8) { - kdDebug(7040) << "premature end of Info-ZIP unix extra field old" << endl; - return false; - }/*end if*/ - - pfi.atime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8 - | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24); - buffer += 4; - pfi.mtime = time_t((uchar)buffer[0] | (uchar)buffer[1] << 8 - | (uchar)buffer[2] << 16 | (uchar)buffer[3] << 24); - buffer += 4; - if (islocal && size >= 12) { - pfi.uid = (uchar)buffer[0] | (uchar)buffer[1] << 8; - buffer += 2; - pfi.gid = (uchar)buffer[0] | (uchar)buffer[1] << 8; - buffer += 2; - }/*end if*/ - return true; -} - -#if 0 // not needed yet -/** updates the parse information with the given Info-ZIP Unix new extra field. - * @param buffer start of content of buffer known to contain an Info-ZIP - * Unix new extra field (without magic & size) - * @param size size of field content (must not count magic and size entries) - * @param islocal true if this is a local field, false if central - * @param pfi ParseFileInfo object to be updated - * @return true if processing was successful - */ -static bool parseInfoZipUnixNew(const char *buffer, int size, bool islocal, - ParseFileInfo &pfi) { - if (!islocal) { // contains nothing in central field - pfi.newinfounix = true; - return true; - }/*end if*/ - - if (size < 4) { - kdDebug(7040) << "premature end of Info-ZIP unix extra field new" << endl; - return false; - }/*end if*/ - - pfi.uid = (uchar)buffer[0] | (uchar)buffer[1] << 8; - buffer += 2; - pfi.gid = (uchar)buffer[0] | (uchar)buffer[1] << 8; - buffer += 2; - - pfi.newinfounix = true; - return true; -} -#endif - -/** - * parses the extra field - * @param buffer start of buffer where the extra field is to be found - * @param size size of the extra field - * @param islocal true if this is part of a local header, false if of central - * @param pfi ParseFileInfo object which to write the results into - * @return true if parsing was successful - */ -static bool parseExtraField(const char *buffer, int size, bool islocal, - ParseFileInfo &pfi) { - // extra field in central directory doesn't contain useful data, so we - // don't bother parsing it - if (!islocal) return true; - - while (size >= 4) { // as long as a potential extra field can be read - int magic = (uchar)buffer[0] | (uchar)buffer[1] << 8; - buffer += 2; - int fieldsize = (uchar)buffer[0] | (uchar)buffer[1] << 8; - buffer += 2; - size -= 4; - - if (fieldsize > size) { - //kdDebug(7040) << "fieldsize: " << fieldsize << " size: " << size << endl; - kdDebug(7040) << "premature end of extra fields reached" << endl; - break; - }/*end if*/ - - switch (magic) { - case 0x5455: // extended timestamp - if (!parseExtTimestamp(buffer, fieldsize, islocal, pfi)) return false; - break; - case 0x5855: // old Info-ZIP unix extra field - if (!parseInfoZipUnixOld(buffer, fieldsize, islocal, pfi)) return false; - break; -#if 0 // not needed yet - case 0x7855: // new Info-ZIP unix extra field - if (!parseInfoZipUnixNew(buffer, fieldsize, islocal, pfi)) return false; - break; -#endif - default: - /* ignore everything else */; - }/*end switch*/ - - buffer += fieldsize; - size -= fieldsize; - }/*wend*/ - return true; -} - -//////////////////////////////////////////////////////////////////////// -/////////////////////////// KZip /////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -class KZip::KZipPrivate -{ -public: - KZipPrivate() - : m_crc( 0 ), - m_currentFile( 0L ), - m_currentDev( 0L ), - m_compression( 8 ), - m_extraField( KZip::NoExtraField ), - m_offset( 0L ), - m_saveFile( 0 ) {} - - unsigned long m_crc; // checksum - KZipFileEntry* m_currentFile; // file currently being written - TQIODevice* m_currentDev; // filterdev used to write to the above file - TQPtrList<KZipFileEntry> m_fileList; // flat list of all files, for the index (saves a recursive method ;) - int m_compression; - KZip::ExtraField m_extraField; - unsigned int m_offset; // holds the offset of the place in the zip, - // where new data can be appended. after openarchive it points to 0, when in - // writeonly mode, or it points to the beginning of the central directory. - // each call to writefile updates this value. - KSaveFile* m_saveFile; -}; - -KZip::KZip( const TQString& filename ) - : KArchive( 0L ) -{ - //kdDebug(7040) << "KZip(filename) reached." << endl; - Q_ASSERT( !filename.isEmpty() ); - m_filename = filename; - d = new KZipPrivate; - // unusual: this ctor leaves the device set to 0. - // This is for the use of KSaveFile, see openArchive. - // KDE4: move KSaveFile support to base class, KArchive. -} - -KZip::KZip( TQIODevice * dev ) - : KArchive( dev ) -{ - //kdDebug(7040) << "KZip::KZip( TQIODevice * dev) reached." << endl; - d = new KZipPrivate; -} - -KZip::~KZip() -{ - // mjarrett: Closes to prevent ~KArchive from aborting w/o device - //kdDebug(7040) << "~KZip reached." << endl; - if( isOpened() ) - close(); - if ( !m_filename.isEmpty() ) { // we created the device ourselves - if ( d->m_saveFile ) // writing mode - delete d->m_saveFile; - else // reading mode - delete device(); // (the TQFile) - } - delete d; -} - -bool KZip::openArchive( int mode ) -{ - //kdDebug(7040) << "openarchive reached." << endl; - d->m_fileList.clear(); - - switch ( mode ) { - case IO_WriteOnly: - // The use of KSaveFile can't be done in the ctor (no mode known yet) - // Ideally we would reimplement open() and do it there (BIC) - if ( !m_filename.isEmpty() ) { - kdDebug(7040) << "Writing to a file using KSaveFile" << endl; - d->m_saveFile = new KSaveFile( m_filename ); - if ( d->m_saveFile->status() != 0 ) { - kdWarning(7040) << "KSaveFile creation for " << m_filename << " failed, " << strerror( d->m_saveFile->status() ) << endl; - delete d->m_saveFile; - d->m_saveFile = 0; - return false; - } - Q_ASSERT( d->m_saveFile->file() ); - setDevice( TQT_TQIODEVICE(d->m_saveFile->file()) ); - } - return true; - case IO_ReadOnly: - case IO_ReadWrite: - { - // ReadWrite mode still uses TQFile for now; we'd need to copy to the tempfile, in fact. - if ( !m_filename.isEmpty() ) { - setDevice( TQT_TQIODEVICE(new TQFile( m_filename )) ); - if ( !device()->open( mode ) ) - return false; - } - break; // continued below - } - default: - kdWarning(7040) << "Unsupported mode " << mode << endl; - return false; - } - - char buffer[47]; - - // Check that it's a valid ZIP file - // the above code opened the underlying device already. - TQIODevice* dev = device(); - - if (!dev) { - return false; - } - - uint offset = 0; // holds offset, where we read - int n; - - // contains information gathered from the local file headers - TQAsciiDict<ParseFileInfo> pfi_map(1009, true /*case sensitive */, true /*copy keys*/); - pfi_map.setAutoDelete(true); - - // We set a bool for knowing if we are allowed to skip the start of the file - bool startOfFile = true; - - for (;;) // repeat until 'end of entries' signature is reached - { -kdDebug(7040) << "loop starts" << endl; -kdDebug(7040) << "dev->at() now : " << dev->at() << endl; - n = dev->readBlock( buffer, 4 ); - - if (n < 4) - { - kdWarning(7040) << "Invalid ZIP file. Unexpected end of file. (#1)" << endl; - - return false; - } - - if ( !memcmp( buffer, "PK\5\6", 4 ) ) // 'end of entries' - { - kdDebug(7040) << "PK56 found end of archive" << endl; - startOfFile = false; - break; - } - - if ( !memcmp( buffer, "PK\3\4", 4 ) ) // local file header - { - kdDebug(7040) << "PK34 found local file header" << endl; - startOfFile = false; - // can this fail ??? - dev->at( dev->at() + 2 ); // skip 'version needed to extract' - - // read static header stuff - n = dev->readBlock( buffer, 24 ); - if (n < 24) { - kdWarning(7040) << "Invalid ZIP file. Unexpected end of file. (#4)" << endl; - return false; - } - - int gpf = (uchar)buffer[0]; // "general purpose flag" not "general protection fault" ;-) - int compression_mode = (uchar)buffer[2] | (uchar)buffer[3] << 8; - time_t mtime = transformFromMsDos( buffer+4 ); - - TQ_LONG compr_size = (uchar)buffer[12] | (uchar)buffer[13] << 8 - | (uchar)buffer[14] << 16 | (uchar)buffer[15] << 24; - TQ_LONG uncomp_size = (uchar)buffer[16] | (uchar)buffer[17] << 8 - | (uchar)buffer[18] << 16 | (uchar)buffer[19] << 24; - int namelen = (uchar)buffer[20] | (uchar)buffer[21] << 8; - int extralen = (uchar)buffer[22] | (uchar)buffer[23] << 8; - - kdDebug(7040) << "general purpose bit flag: " << gpf << endl; - kdDebug(7040) << "compressed size: " << compr_size << endl; - kdDebug(7040) << "uncompressed size: " << uncomp_size << endl; - kdDebug(7040) << "namelen: " << namelen << endl; - kdDebug(7040) << "extralen: " << extralen << endl; - kdDebug(7040) << "archive size: " << dev->size() << endl; - - // read filename - TQCString filename(namelen + 1); - n = dev->readBlock(filename.data(), namelen); - if ( n < namelen ) { - kdWarning(7040) << "Invalid ZIP file. Name not completely read (#2)" << endl; - return false; - } - - ParseFileInfo *pfi = new ParseFileInfo(); - pfi->mtime = mtime; - pfi_map.insert(filename.data(), pfi); - - // read and parse the beginning of the extra field, - // skip rest of extra field in case it is too long - unsigned int extraFieldEnd = dev->at() + extralen; - pfi->extralen = extralen; - int handledextralen = QMIN(extralen, (int)sizeof buffer); - - kdDebug(7040) << "handledextralen: " << handledextralen << endl; - - n = dev->readBlock(buffer, handledextralen); - // no error msg necessary as we deliberately truncate the extra field - if (!parseExtraField(buffer, handledextralen, true, *pfi)) - { - kdWarning(7040) << "Invalid ZIP File. Broken ExtraField." << endl; - return false; - } - - // jump to end of extra field - dev->at( extraFieldEnd ); - - // we have to take care of the 'general purpose bit flag'. - // if bit 3 is set, the header doesn't contain the length of - // the file and we look for the signature 'PK\7\8'. - if ( gpf & 8 ) - { - // here we have to read through the compressed data to find - // the next PKxx - kdDebug(7040) << "trying to seek for next PK78" << endl; - bool foundSignature = false; - - while (!foundSignature) - { - n = dev->readBlock( buffer, 1 ); - if (n < 1) - { - kdWarning(7040) << "Invalid ZIP file. Unexpected end of file. (#2)" << endl; - return false; - } - - if ( buffer[0] != 'P' ) - continue; - - n = dev->readBlock( buffer, 3 ); - if (n < 3) - { - kdWarning(7040) << "Invalid ZIP file. Unexpected end of file. (#3)" << endl; - return false; - } - - // we have to detect three magic tokens here: - // PK34 for the next local header in case there is no data descriptor - // PK12 for the central header in case there is no data descriptor - // PK78 for the data descriptor in case it is following the compressed data - - if ( buffer[0] == 'K' && buffer[1] == 7 && buffer[2] == 8 ) - { - foundSignature = true; - dev->at( dev->at() + 12 ); // skip the 'data_descriptor' - } - else if ( ( buffer[0] == 'K' && buffer[1] == 1 && buffer[2] == 2 ) - || ( buffer[0] == 'K' && buffer[1] == 3 && buffer[2] == 4 ) ) - { - foundSignature = true; - dev->at( dev->at() - 4 ); // go back 4 bytes, so that the magic bytes can be found... - } - else if ( buffer[0] == 'P' || buffer[1] == 'P' || buffer[2] == 'P' ) - { - // We have another P character so we must go back a little to check if it is a magic - dev->at( dev->at() - 3 ); - } - - } - } - else - { - // here we skip the compressed data and jump to the next header - kdDebug(7040) << "general purpose bit flag indicates, that local file header contains valid size" << endl; - // check if this could be a symbolic link - if (compression_mode == NoCompression - && uncomp_size <= max_path_len - && uncomp_size > 0) { - // read content and store it - pfi->guessed_symlink.resize(uncomp_size + 1); - kdDebug(7040) << "guessed symlink size: " << uncomp_size << endl; - n = dev->readBlock(pfi->guessed_symlink.data(), uncomp_size); - if (n < uncomp_size) { - kdWarning(7040) << "Invalid ZIP file. Unexpected end of file. (#5)" << endl; - return false; - } - } else { - - if ( compr_size > (TQ_LONG)dev->size() ) - { - // here we cannot trust the compressed size, so scan through the compressed - // data to find the next header - bool foundSignature = false; - - while (!foundSignature) - { - n = dev->readBlock( buffer, 1 ); - if (n < 1) - { - kdWarning(7040) << "Invalid ZIP file. Unexpected end of file. (#2)" << endl; - return false; - } - - if ( buffer[0] != 'P' ) - continue; - - n = dev->readBlock( buffer, 3 ); - if (n < 3) - { - kdWarning(7040) << "Invalid ZIP file. Unexpected end of file. (#3)" << endl; - return false; - } - - // we have to detect three magic tokens here: - // PK34 for the next local header in case there is no data descriptor - // PK12 for the central header in case there is no data descriptor - // PK78 for the data descriptor in case it is following the compressed data - - if ( buffer[0] == 'K' && buffer[1] == 7 && buffer[2] == 8 ) - { - foundSignature = true; - dev->at( dev->at() + 12 ); // skip the 'data_descriptor' - } - - if ( ( buffer[0] == 'K' && buffer[1] == 1 && buffer[2] == 2 ) - || ( buffer[0] == 'K' && buffer[1] == 3 && buffer[2] == 4 ) ) - { - foundSignature = true; - dev->at( dev->at() - 4 ); - // go back 4 bytes, so that the magic bytes can be found - // in the next cycle... - } - } - } - else - { -// kdDebug(7040) << "before interesting dev->at(): " << dev->at() << endl; - bool success; - success = dev->at( dev->at() + compr_size ); // can this fail ??? -/* kdDebug(7040) << "after interesting dev->at(): " << dev->at() << endl; - if ( success ) - kdDebug(7040) << "dev->at was successful... " << endl; - else - kdDebug(7040) << "dev->at failed... " << endl;*/ - } - - } - -// not needed any more -/* // here we calculate the length of the file in the zip - // with headers and jump to the next header. - uint skip = compr_size + namelen + extralen; - offset += 30 + skip;*/ - } - } - else if ( !memcmp( buffer, "PK\1\2", 4 ) ) // central block - { - kdDebug(7040) << "PK12 found central block" << endl; - startOfFile = false; - - // so we reached the central header at the end of the zip file - // here we get all interesting data out of the central header - // of a file - offset = dev->at() - 4; - - //set offset for appending new files - if ( d->m_offset == 0L ) d->m_offset = offset; - - n = dev->readBlock( buffer + 4, 42 ); - if (n < 42) { - kdWarning(7040) << "Invalid ZIP file, central entry too short" << endl; // not long enough for valid entry - return false; - } - - //int gpf = (uchar)buffer[9] << 8 | (uchar)buffer[10]; - //kdDebug() << "general purpose flag=" << gpf << endl; - // length of the filename (well, pathname indeed) - int namelen = (uchar)buffer[29] << 8 | (uchar)buffer[28]; - TQCString bufferName( namelen + 1 ); - n = dev->readBlock( bufferName.data(), namelen ); - if ( n < namelen ) - kdWarning(7040) << "Invalid ZIP file. Name not completely read" << endl; - - ParseFileInfo *pfi = pfi_map[bufferName]; - if (!pfi) { // can that happen? - pfi_map.insert(bufferName.data(), pfi = new ParseFileInfo()); - } - TQString name( TQFile::decodeName(bufferName) ); - - //kdDebug(7040) << "name: " << name << endl; - // only in central header ! see below. - // length of extra attributes - int extralen = (uchar)buffer[31] << 8 | (uchar)buffer[30]; - // length of comment for this file - int commlen = (uchar)buffer[33] << 8 | (uchar)buffer[32]; - // compression method of this file - int cmethod = (uchar)buffer[11] << 8 | (uchar)buffer[10]; - - //kdDebug(7040) << "cmethod: " << cmethod << endl; - //kdDebug(7040) << "extralen: " << extralen << endl; - - // uncompressed file size - uint ucsize = (uchar)buffer[27] << 24 | (uchar)buffer[26] << 16 | - (uchar)buffer[25] << 8 | (uchar)buffer[24]; - // compressed file size - uint csize = (uchar)buffer[23] << 24 | (uchar)buffer[22] << 16 | - (uchar)buffer[21] << 8 | (uchar)buffer[20]; - - // offset of local header - uint localheaderoffset = (uchar)buffer[45] << 24 | (uchar)buffer[44] << 16 | - (uchar)buffer[43] << 8 | (uchar)buffer[42]; - - // some clever people use different extra field lengths - // in the central header and in the local header... funny. - // so we need to get the localextralen to calculate the offset - // from localheaderstart to dataoffset - int localextralen = pfi->extralen; // FIXME: this will not work if - // no local header exists - - //kdDebug(7040) << "localextralen: " << localextralen << endl; - - // offset, where the real data for uncompression starts - uint dataoffset = localheaderoffset + 30 + localextralen + namelen; //comment only in central header - - //kdDebug(7040) << "esize: " << esize << endl; - //kdDebug(7040) << "eoffset: " << eoffset << endl; - //kdDebug(7040) << "csize: " << csize << endl; - - int os_madeby = (uchar)buffer[5]; - bool isdir = false; - int access = 0100644; - - if (os_madeby == 3) { // good ole unix - access = (uchar)buffer[40] | (uchar)buffer[41] << 8; - } - - TQString entryName; - - if ( name.endsWith( "/" ) ) // Entries with a trailing slash are directories - { - isdir = true; - name = name.left( name.length() - 1 ); - if (os_madeby != 3) access = S_IFDIR | 0755; - else Q_ASSERT(access & S_IFDIR); - } - - int pos = name.findRev( '/' ); - if ( pos == -1 ) - entryName = name; - else - entryName = name.mid( pos + 1 ); - Q_ASSERT( !entryName.isEmpty() ); - - KArchiveEntry* entry; - if ( isdir ) - { - TQString path = TQDir::cleanDirPath( name ); - KArchiveEntry* ent = rootDir()->entry( path ); - if ( ent && ent->isDirectory() ) - { - //kdDebug(7040) << "Directory already exists, NOT going to add it again" << endl; - entry = 0L; - } - else - { - entry = new KArchiveDirectory( this, entryName, access, (int)pfi->mtime, rootDir()->user(), rootDir()->group(), TQString::null ); - //kdDebug(7040) << "KArchiveDirectory created, entryName= " << entryName << ", name=" << name << endl; - } - } - else - { - TQString symlink; - if (S_ISLNK(access)) { - symlink = TQFile::decodeName(pfi->guessed_symlink); - } - entry = new KZipFileEntry( this, entryName, access, pfi->mtime, - rootDir()->user(), rootDir()->group(), - symlink, name, dataoffset, - ucsize, cmethod, csize ); - static_cast<KZipFileEntry *>(entry)->setHeaderStart( localheaderoffset ); - //kdDebug(7040) << "KZipFileEntry created, entryName= " << entryName << ", name=" << name << endl; - d->m_fileList.append( static_cast<KZipFileEntry *>( entry ) ); - } - - if ( entry ) - { - if ( pos == -1 ) - { - rootDir()->addEntry(entry); - } - else - { - // In some tar files we can find dir/./file => call cleanDirPath - TQString path = TQDir::cleanDirPath( name.left( pos ) ); - // Ensure container directory exists, create otherwise - KArchiveDirectory * tdir = findOrCreate( path ); - tdir->addEntry(entry); - } - } - - //calculate offset to next entry - offset += 46 + commlen + extralen + namelen; - bool b = dev->at(offset); - Q_ASSERT( b ); - if ( !b ) - return false; - } - else if ( startOfFile ) - { - // The file does not start with any ZIP header (e.g. self-extractable ZIP files) - // Therefore we need to find the first PK\003\004 (local header) - kdDebug(7040) << "Try to skip start of file" << endl; - startOfFile = false; - bool foundSignature = false; - - while (!foundSignature) - { - n = dev->readBlock( buffer, 1 ); - if (n < 1) - { - kdWarning(7040) << "Invalid ZIP file. Unexpected end of file. " << k_funcinfo << endl; - return false; - } - - if ( buffer[0] != 'P' ) - continue; - - n = dev->readBlock( buffer, 3 ); - if (n < 3) - { - kdWarning(7040) << "Invalid ZIP file. Unexpected end of file. " << k_funcinfo << endl; - return false; - } - - // We have to detect the magic token for a local header: PK\003\004 - /* - * Note: we do not need to check the other magics, if the ZIP file has no - * local header, then it has not any files! - */ - if ( buffer[0] == 'K' && buffer[1] == 3 && buffer[2] == 4 ) - { - foundSignature = true; - dev->at( dev->at() - 4 ); // go back 4 bytes, so that the magic bytes can be found... - } - else if ( buffer[0] == 'P' || buffer[1] == 'P' || buffer[2] == 'P' ) - { - // We have another P character so we must go back a little to check if it is a magic - dev->at( dev->at() - 3 ); - } - } - } - else - { - kdWarning(7040) << "Invalid ZIP file. Unrecognized header at offset " << offset << endl; - - return false; - } - } - //kdDebug(7040) << "*** done *** " << endl; - return true; -} - -bool KZip::closeArchive() -{ - if ( ! ( mode() & IO_WriteOnly ) ) - { - //kdDebug(7040) << "closearchive readonly reached." << endl; - return true; - } - - kdDebug() << k_funcinfo << "device=" << device() << endl; - //ReadWrite or WriteOnly - //write all central dir file entries - - if ( !device() ) // saving aborted - return false; - - // to be written at the end of the file... - char buffer[ 22 ]; // first used for 12, then for 22 at the end - uLong crc = crc32(0L, Z_NULL, 0); - - TQ_LONG centraldiroffset = device()->at(); - //kdDebug(7040) << "closearchive: centraldiroffset: " << centraldiroffset << endl; - TQ_LONG atbackup = centraldiroffset; - TQPtrListIterator<KZipFileEntry> it( d->m_fileList ); - - for ( ; it.current() ; ++it ) - { //set crc and compressed size in each local file header - if ( !device()->at( it.current()->headerStart() + 14 ) ) - return false; - //kdDebug(7040) << "closearchive setcrcandcsize: filename: " - // << it.current()->path() - // << " encoding: "<< it.current()->encoding() << endl; - - uLong mycrc = it.current()->crc32(); - buffer[0] = char(mycrc); // crc checksum, at headerStart+14 - buffer[1] = char(mycrc >> 8); - buffer[2] = char(mycrc >> 16); - buffer[3] = char(mycrc >> 24); - - int mysize1 = it.current()->compressedSize(); - buffer[4] = char(mysize1); // compressed file size, at headerStart+18 - buffer[5] = char(mysize1 >> 8); - buffer[6] = char(mysize1 >> 16); - buffer[7] = char(mysize1 >> 24); - - int myusize = it.current()->size(); - buffer[8] = char(myusize); // uncompressed file size, at headerStart+22 - buffer[9] = char(myusize >> 8); - buffer[10] = char(myusize >> 16); - buffer[11] = char(myusize >> 24); - - if ( device()->writeBlock( buffer, 12 ) != 12 ) - return false; - } - device()->at( atbackup ); - - for ( it.toFirst(); it.current() ; ++it ) - { - //kdDebug(7040) << "closearchive: filename: " << it.current()->path() - // << " encoding: "<< it.current()->encoding() << endl; - - TQCString path = TQFile::encodeName(it.current()->path()); - - const int extra_field_len = 9; - int bufferSize = extra_field_len + path.length() + 46; - char* buffer = new char[ bufferSize ]; - - memset(buffer, 0, 46); // zero is a nice default for most header fields - - const char head[] = - { - 'P', 'K', 1, 2, // central file header signature - 0x14, 3, // version made by (3 == UNIX) - 0x14, 0 // version needed to extract - }; - - // I do not know why memcpy is not working here - //memcpy(buffer, head, sizeof(head)); - tqmemmove(buffer, head, sizeof(head)); - - buffer[ 10 ] = char(it.current()->encoding()); // compression method - buffer[ 11 ] = char(it.current()->encoding() >> 8); - - transformToMsDos( it.current()->datetime(), &buffer[ 12 ] ); - - uLong mycrc = it.current()->crc32(); - buffer[ 16 ] = char(mycrc); // crc checksum - buffer[ 17 ] = char(mycrc >> 8); - buffer[ 18 ] = char(mycrc >> 16); - buffer[ 19 ] = char(mycrc >> 24); - - int mysize1 = it.current()->compressedSize(); - buffer[ 20 ] = char(mysize1); // compressed file size - buffer[ 21 ] = char(mysize1 >> 8); - buffer[ 22 ] = char(mysize1 >> 16); - buffer[ 23 ] = char(mysize1 >> 24); - - int mysize = it.current()->size(); - buffer[ 24 ] = char(mysize); // uncompressed file size - buffer[ 25 ] = char(mysize >> 8); - buffer[ 26 ] = char(mysize >> 16); - buffer[ 27 ] = char(mysize >> 24); - - buffer[ 28 ] = char(it.current()->path().length()); // filename length - buffer[ 29 ] = char(it.current()->path().length() >> 8); - - buffer[ 30 ] = char(extra_field_len); - buffer[ 31 ] = char(extra_field_len >> 8); - - buffer[ 40 ] = char(it.current()->permissions()); - buffer[ 41 ] = char(it.current()->permissions() >> 8); - - int myhst = it.current()->headerStart(); - buffer[ 42 ] = char(myhst); //relative offset of local header - buffer[ 43 ] = char(myhst >> 8); - buffer[ 44 ] = char(myhst >> 16); - buffer[ 45 ] = char(myhst >> 24); - - // file name - strncpy( buffer + 46, path, path.length() ); - //kdDebug(7040) << "closearchive length to write: " << bufferSize << endl; - - // extra field - char *extfield = buffer + 46 + path.length(); - extfield[0] = 'U'; - extfield[1] = 'T'; - extfield[2] = 5; - extfield[3] = 0; - extfield[4] = 1 | 2 | 4; // specify flags from local field - // (unless I misread the spec) - // provide only modification time - unsigned long time = (unsigned long)it.current()->date(); - extfield[5] = char(time); - extfield[6] = char(time >> 8); - extfield[7] = char(time >> 16); - extfield[8] = char(time >> 24); - - crc = crc32(crc, (Bytef *)buffer, bufferSize ); - bool ok = ( device()->writeBlock( buffer, bufferSize ) == bufferSize ); - delete[] buffer; - if ( !ok ) - return false; - } - TQ_LONG centraldirendoffset = device()->at(); - //kdDebug(7040) << "closearchive: centraldirendoffset: " << centraldirendoffset << endl; - //kdDebug(7040) << "closearchive: device()->at(): " << device()->at() << endl; - - //write end of central dir record. - buffer[ 0 ] = 'P'; //end of central dir signature - buffer[ 1 ] = 'K'; - buffer[ 2 ] = 5; - buffer[ 3 ] = 6; - - buffer[ 4 ] = 0; // number of this disk - buffer[ 5 ] = 0; - - buffer[ 6 ] = 0; // number of disk with start of central dir - buffer[ 7 ] = 0; - - int count = d->m_fileList.count(); - //kdDebug(7040) << "number of files (count): " << count << endl; - - - buffer[ 8 ] = char(count); // total number of entries in central dir of - buffer[ 9 ] = char(count >> 8); // this disk - - buffer[ 10 ] = buffer[ 8 ]; // total number of entries in the central dir - buffer[ 11 ] = buffer[ 9 ]; - - int cdsize = centraldirendoffset - centraldiroffset; - buffer[ 12 ] = char(cdsize); // size of the central dir - buffer[ 13 ] = char(cdsize >> 8); - buffer[ 14 ] = char(cdsize >> 16); - buffer[ 15 ] = char(cdsize >> 24); - - //kdDebug(7040) << "end : centraldiroffset: " << centraldiroffset << endl; - //kdDebug(7040) << "end : centraldirsize: " << cdsize << endl; - - buffer[ 16 ] = char(centraldiroffset); // central dir offset - buffer[ 17 ] = char(centraldiroffset >> 8); - buffer[ 18 ] = char(centraldiroffset >> 16); - buffer[ 19 ] = char(centraldiroffset >> 24); - - buffer[ 20 ] = 0; //zipfile comment length - buffer[ 21 ] = 0; - - if ( device()->writeBlock( buffer, 22 ) != 22 ) - return false; - - if ( d->m_saveFile ) { - d->m_saveFile->close(); - setDevice( 0 ); - delete d->m_saveFile; - d->m_saveFile = 0; - } - - //kdDebug(7040) << __FILE__" reached." << endl; - return true; -} - -// Doesn't need to be reimplemented anymore. Remove for KDE-4.0 -bool KZip::writeFile( const TQString& name, const TQString& user, const TQString& group, uint size, const char* data ) -{ - mode_t mode = 0100644; - time_t the_time = time(0); - return KArchive::writeFile( name, user, group, size, mode, the_time, - the_time, the_time, data ); -} - -// Doesn't need to be reimplemented anymore. Remove for KDE-4.0 -bool KZip::writeFile( const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime, - const char* data ) { - return KArchive::writeFile(name, user, group, size, perm, atime, mtime, - ctime, data); -} - -// Doesn't need to be reimplemented anymore. Remove for KDE-4.0 -bool KZip::prepareWriting( const TQString& name, const TQString& user, const TQString& group, uint size ) -{ - mode_t dflt_perm = 0100644; - time_t the_time = time(0); - return prepareWriting(name,user,group,size,dflt_perm, - the_time,the_time,the_time); -} - -// Doesn't need to be reimplemented anymore. Remove for KDE-4.0 -bool KZip::prepareWriting(const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime) { - return KArchive::prepareWriting(name,user,group,size,perm,atime,mtime,ctime); -} - -bool KZip::prepareWriting_impl(const TQString &name, const TQString &user, - const TQString &group, uint /*size*/, mode_t perm, - time_t atime, time_t mtime, time_t ctime) { - //kdDebug(7040) << "prepareWriting reached." << endl; - if ( !isOpened() ) - { - tqWarning( "KZip::writeFile: You must open the zip file before writing to it\n"); - return false; - } - - if ( ! ( mode() & IO_WriteOnly ) ) // accept WriteOnly and ReadWrite - { - tqWarning( "KZip::writeFile: You must open the zip file for writing\n"); - return false; - } - - if ( !device() ) { // aborted - //kdWarning(7040) << "prepareWriting_impl: no device" << endl; - return false; - } - - // set right offset in zip. - if ( !device()->at( d->m_offset ) ) { - kdWarning(7040) << "prepareWriting_impl: cannot seek in ZIP file. Disk full?" << endl; - abort(); - return false; - } - - // delete entries in the filelist with the same filename as the one we want - // to save, so that we don�t have duplicate file entries when viewing the zip - // with konqi... - // CAUTION: the old file itself is still in the zip and won't be removed !!! - TQPtrListIterator<KZipFileEntry> it( d->m_fileList ); - - //kdDebug(7040) << "filename to write: " << name <<endl; - for ( ; it.current() ; ++it ) - { - //kdDebug(7040) << "prepfilename: " << it.current()->path() <<endl; - if (name == it.current()->path() ) - { - //kdDebug(7040) << "removing following entry: " << it.current()->path() <<endl; - d->m_fileList.remove(); - } - - } - // Find or create parent dir - KArchiveDirectory* parentDir = rootDir(); - TQString fileName( name ); - int i = name.findRev( '/' ); - if ( i != -1 ) - { - TQString dir = name.left( i ); - fileName = name.mid( i + 1 ); - //kdDebug(7040) << "KZip::prepareWriting ensuring " << dir << " exists. fileName=" << fileName << endl; - parentDir = findOrCreate( dir ); - } - - // construct a KZipFileEntry and add it to list - KZipFileEntry * e = new KZipFileEntry( this, fileName, perm, mtime, user, group, TQString::null, - name, device()->at() + 30 + name.length(), // start - 0 /*size unknown yet*/, d->m_compression, 0 /*csize unknown yet*/ ); - e->setHeaderStart( device()->at() ); - //kdDebug(7040) << "wrote file start: " << e->position() << " name: " << name << endl; - parentDir->addEntry( e ); - - d->m_currentFile = e; - d->m_fileList.append( e ); - - int extra_field_len = 0; - if ( d->m_extraField == ModificationTime ) - extra_field_len = 17; // value also used in doneWriting() - - // write out zip header - TQCString encodedName = TQFile::encodeName(name); - int bufferSize = extra_field_len + encodedName.length() + 30; - //kdDebug(7040) << "KZip::prepareWriting bufferSize=" << bufferSize << endl; - char* buffer = new char[ bufferSize ]; - - buffer[ 0 ] = 'P'; //local file header signature - buffer[ 1 ] = 'K'; - buffer[ 2 ] = 3; - buffer[ 3 ] = 4; - - buffer[ 4 ] = 0x14; // version needed to extract - buffer[ 5 ] = 0; - - buffer[ 6 ] = 0; // general purpose bit flag - buffer[ 7 ] = 0; - - buffer[ 8 ] = char(e->encoding()); // compression method - buffer[ 9 ] = char(e->encoding() >> 8); - - transformToMsDos( e->datetime(), &buffer[ 10 ] ); - - buffer[ 14 ] = 'C'; //dummy crc - buffer[ 15 ] = 'R'; - buffer[ 16 ] = 'C'; - buffer[ 17 ] = 'q'; - - buffer[ 18 ] = 'C'; //compressed file size - buffer[ 19 ] = 'S'; - buffer[ 20 ] = 'I'; - buffer[ 21 ] = 'Z'; - - buffer[ 22 ] = 'U'; //uncompressed file size - buffer[ 23 ] = 'S'; - buffer[ 24 ] = 'I'; - buffer[ 25 ] = 'Z'; - - buffer[ 26 ] = (uchar)(encodedName.length()); //filename length - buffer[ 27 ] = (uchar)(encodedName.length() >> 8); - - buffer[ 28 ] = (uchar)(extra_field_len); // extra field length - buffer[ 29 ] = (uchar)(extra_field_len >> 8); - - // file name - strncpy( buffer + 30, encodedName, encodedName.length() ); - - // extra field - if ( d->m_extraField == ModificationTime ) - { - char *extfield = buffer + 30 + encodedName.length(); - // "Extended timestamp" header (0x5455) - extfield[0] = 'U'; - extfield[1] = 'T'; - extfield[2] = 13; // data size - extfield[3] = 0; - extfield[4] = 1 | 2 | 4; // contains mtime, atime, ctime - - extfield[5] = char(mtime); - extfield[6] = char(mtime >> 8); - extfield[7] = char(mtime >> 16); - extfield[8] = char(mtime >> 24); - - extfield[9] = char(atime); - extfield[10] = char(atime >> 8); - extfield[11] = char(atime >> 16); - extfield[12] = char(atime >> 24); - - extfield[13] = char(ctime); - extfield[14] = char(ctime >> 8); - extfield[15] = char(ctime >> 16); - extfield[16] = char(ctime >> 24); - } - - // Write header - bool b = (device()->writeBlock( buffer, bufferSize ) == bufferSize ); - d->m_crc = 0L; - delete[] buffer; - - Q_ASSERT( b ); - if (!b) { - abort(); - return false; - } - - // Prepare device for writing the data - // Either device() if no compression, or a KFilterDev to compress - if ( d->m_compression == 0 ) { - d->m_currentDev = device(); - return true; - } - - d->m_currentDev = KFilterDev::device( device(), "application/x-gzip", false ); - Q_ASSERT( d->m_currentDev ); - if ( !d->m_currentDev ) { - abort(); - return false; // ouch - } - static_cast<KFilterDev *>(d->m_currentDev)->setSkipHeaders(); // Just zlib, not gzip - - b = d->m_currentDev->open( IO_WriteOnly ); - Q_ASSERT( b ); - return b; -} - -bool KZip::doneWriting( uint size ) -{ - if ( d->m_currentFile->encoding() == 8 ) { - // Finish - (void)d->m_currentDev->writeBlock( 0, 0 ); - delete d->m_currentDev; - } - // If 0, d->m_currentDev was device() - don't delete ;) - d->m_currentDev = 0L; - - Q_ASSERT( d->m_currentFile ); - //kdDebug(7040) << "donewriting reached." << endl; - //kdDebug(7040) << "filename: " << d->m_currentFile->path() << endl; - //kdDebug(7040) << "getpos (at): " << device()->at() << endl; - d->m_currentFile->setSize(size); - int extra_field_len = 0; - if ( d->m_extraField == ModificationTime ) - extra_field_len = 17; // value also used in doneWriting() - - int csize = device()->at() - - d->m_currentFile->headerStart() - 30 - - d->m_currentFile->path().length() - extra_field_len; - d->m_currentFile->setCompressedSize(csize); - //kdDebug(7040) << "usize: " << d->m_currentFile->size() << endl; - //kdDebug(7040) << "csize: " << d->m_currentFile->compressedSize() << endl; - //kdDebug(7040) << "headerstart: " << d->m_currentFile->headerStart() << endl; - - //kdDebug(7040) << "crc: " << d->m_crc << endl; - d->m_currentFile->setCRC32( d->m_crc ); - - d->m_currentFile = 0L; - - // update saved offset for appending new files - d->m_offset = device()->at(); - return true; -} - -bool KZip::writeSymLink(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t atime, time_t mtime, time_t ctime) { - return KArchive::writeSymLink(name,target,user,group,perm,atime,mtime,ctime); -} - -bool KZip::writeSymLink_impl(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t atime, time_t mtime, time_t ctime) { - - // reassure that symlink flag is set, otherwise strange things happen on - // extraction - perm |= S_IFLNK; - Compression c = compression(); - setCompression(NoCompression); // link targets are never compressed - - if (!prepareWriting(name, user, group, 0, perm, atime, mtime, ctime)) { - kdWarning() << "KZip::writeFile prepareWriting failed" << endl; - setCompression(c); - return false; - } - - TQCString symlink_target = TQFile::encodeName(target); - if (!writeData(symlink_target, symlink_target.length())) { - kdWarning() << "KZip::writeFile writeData failed" << endl; - setCompression(c); - return false; - } - - if (!doneWriting(symlink_target.length())) { - kdWarning() << "KZip::writeFile doneWriting failed" << endl; - setCompression(c); - return false; - } - - setCompression(c); - return true; -} - -void KZip::virtual_hook( int id, void* data ) -{ - switch (id) { - case VIRTUAL_WRITE_DATA: { - WriteDataParams* params = reinterpret_cast<WriteDataParams *>(data); - params->retval = writeData_impl( params->data, params->size ); - break; - } - case VIRTUAL_WRITE_SYMLINK: { - WriteSymlinkParams *params = reinterpret_cast<WriteSymlinkParams *>(data); - params->retval = writeSymLink_impl(*params->name,*params->target, - *params->user,*params->group,params->perm, - params->atime,params->mtime,params->ctime); - break; - } - case VIRTUAL_PREPARE_WRITING: { - PrepareWritingParams *params = reinterpret_cast<PrepareWritingParams *>(data); - params->retval = prepareWriting_impl(*params->name,*params->user, - *params->group,params->size,params->perm, - params->atime,params->mtime,params->ctime); - break; - } - default: - KArchive::virtual_hook( id, data ); - }/*end switch*/ -} - -// made virtual using virtual_hook -bool KZip::writeData(const char * c, uint i) -{ - return KArchive::writeData( c, i ); -} - -bool KZip::writeData_impl(const char * c, uint i) -{ - Q_ASSERT( d->m_currentFile ); - Q_ASSERT( d->m_currentDev ); - if (!d->m_currentFile || !d->m_currentDev) { - abort(); - return false; - } - - // crc to be calculated over uncompressed stuff... - // and they didn't mention it in their docs... - d->m_crc = crc32(d->m_crc, (const Bytef *) c , i); - - TQ_LONG written = d->m_currentDev->writeBlock( c, i ); - //kdDebug(7040) << "KZip::writeData wrote " << i << " bytes." << endl; - bool ok = written == (TQ_LONG)i; - if ( !ok ) - abort(); - return ok; -} - -void KZip::setCompression( Compression c ) -{ - d->m_compression = ( c == NoCompression ) ? 0 : 8; -} - -KZip::Compression KZip::compression() const -{ - return ( d->m_compression == 8 ) ? DeflateCompression : NoCompression; -} - -void KZip::setExtraField( ExtraField ef ) -{ - d->m_extraField = ef; -} - -KZip::ExtraField KZip::extraField() const -{ - return d->m_extraField; -} - -void KZip::abort() -{ - if ( d->m_saveFile ) { - d->m_saveFile->abort(); - setDevice( 0 ); - } -} - - -/////////////// - -TQByteArray KZipFileEntry::data() const -{ - TQIODevice* dev = device(); - TQByteArray arr; - if ( dev ) { - arr = dev->readAll(); - delete dev; - } - return arr; -} - -TQIODevice* KZipFileEntry::device() const -{ - //kdDebug(7040) << "KZipFileEntry::device creating iodevice limited to pos=" << position() << ", csize=" << compressedSize() << endl; - // Limit the reading to the appropriate part of the underlying device (e.g. file) - KLimitedIODevice* limitedDev = new KLimitedIODevice( archive()->device(), position(), compressedSize() ); - if ( encoding() == 0 || compressedSize() == 0 ) // no compression (or even no data) - return limitedDev; - - if ( encoding() == 8 ) - { - // On top of that, create a device that uncompresses the zlib data - TQIODevice* filterDev = KFilterDev::device( limitedDev, "application/x-gzip" ); - if ( !filterDev ) - return 0L; // ouch - static_cast<KFilterDev *>(filterDev)->setSkipHeaders(); // Just zlib, not gzip - bool b = filterDev->open( IO_ReadOnly ); - Q_ASSERT( b ); - return filterDev; - } - - kdError() << "This zip file contains files compressed with method " - << encoding() <<", this method is currently not supported by KZip," - <<" please use a command-line tool to handle this file." << endl; - return 0L; -} diff --git a/kio/kio/kzip.h b/kio/kio/kzip.h deleted file mode 100644 index 9e4d24eeb..000000000 --- a/kio/kio/kzip.h +++ /dev/null @@ -1,284 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2002 Holger Schroeder <holger-kde@holgis.net> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __kzip_h -#define __kzip_h - -#include <sys/stat.h> -#include <sys/types.h> - -#include <tqdatetime.h> -#include <tqstring.h> -#include <tqstringlist.h> -#include <tqdict.h> -#include <tqvaluelist.h> -#include <karchive.h> - -class KZipFileEntry; -/** - * This class implements a kioslave to access zip files from KDE. - * You can use it in IO_ReadOnly or in IO_WriteOnly mode, and it - * behaves just as expected. - * It can also be used in IO_ReadWrite mode, in this case one can - * append files to an existing zip archive. When you append new files, which - * are not yet in the zip, it works as expected, i.e. the files are appended at the end. - * When you append a file, which is already in the file, the reference to the - * old file is dropped and the new one is added to the zip - but the - * old data from the file itself is not deleted, it is still in the - * zipfile. so when you want to have a small and garbage-free zipfile, - * just read the contents of the appended zip file and write it to a new one - * in IO_WriteOnly mode. This is especially important when you don't want - * to leak information of how intermediate versions of files in the zip - * were looking. - * For more information on the zip fileformat go to - * http://www.pkware.com/products/enterprise/white_papers/appnote.html - * @short A class for reading/writing zip archives. - * @author Holger Schroeder <holger-kde@holgis.net> - * @since 3.1 - */ -class TDEIO_EXPORT KZip : public KArchive -{ -public: - /** - * Creates an instance that operates on the given filename. - * using the compression filter associated to given mimetype. - * - * @param filename is a local path (e.g. "/home/holger/myfile.zip") - */ - KZip( const TQString& filename ); - - /** - * Creates an instance that operates on the given device. - * The device can be compressed (KFilterDev) or not (TQFile, etc.). - * @warning Do not assume that giving a TQFile here will decompress the file, - * in case it's compressed! - * @param dev the device to access - */ - KZip( TQIODevice * dev ); - - /** - * If the zip file is still opened, then it will be - * closed automatically by the destructor. - */ - virtual ~KZip(); - - /** - * The name of the zip file, as passed to the constructor. - * Null if you used the TQIODevice constructor. - * @return the zip's file name, or null if a TQIODevice is used - */ - TQString fileName() { return m_filename; } - - /** - * Describes the contents of the "extra field" for a given file in the Zip archive. - */ - enum ExtraField { NoExtraField = 0, ///< No extra field - ModificationTime = 1, ///< Modification time ("extended timestamp" header) - DefaultExtraField = 1 - }; - - /** - * Call this before writeFile or prepareWriting, to define what the next - * file to be written should have in its extra field. - * @param ef the type of "extra field" - * @see extraField() - */ - void setExtraField( ExtraField ef ); - - /** - * The current type of "extra field" that will be used for new files. - * @return the current type of "extra field" - * @see setExtraField() - */ - ExtraField extraField() const; - - /** - * Describes the compression type for a given file in the Zip archive. - */ - enum Compression { NoCompression = 0, ///< Uncompressed. - DeflateCompression = 1 ///< Deflate compression method. - }; - - - /** - * Call this before writeFile or prepareWriting, to define whether the next - * files to be written should be compressed or not. - * @param c the new compression mode - * @see compression() - */ - void setCompression( Compression c ); - - /** - * The current compression mode that will be used for new files. - * @return the current compression mode - * @see setCompression() - */ - Compression compression() const; - - /** - * If an archive is opened for writing then you can add a new file - * using this function. - * This method takes the whole data at once. - * @param name can include subdirs e.g. path/to/the/file - * @param user the user owning the file - * @param group the group owning the file - * @param size the size of the file - * @param data a pointer to the data - * @return true if successful, false otherwise - */ - virtual bool writeFile( const TQString& name, const TQString& user, const TQString& group, uint size, const char* data ); // BC: remove reimplementation for KDE-4.0 - - /** - * Alternative method for writing: call prepareWriting(), then feed the data - * in small chunks using writeData(), and call doneWriting() when done. - * @param name can include subdirs e.g. path/to/the/file - * @param user the user owning the file - * @param group the group owning the file - * @param size unused argument - * @return true if successful, false otherwise - */ - virtual bool prepareWriting( const TQString& name, const TQString& user, const TQString& group, uint size ); - - // TODO(BIC) make virtual. For now it must be implemented by virtual_hook. - bool writeSymLink(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t atime, time_t mtime, time_t ctime); - // TODO(BIC) make virtual. For now it must be implemented by virtual_hook. - bool prepareWriting( const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime ); - // TODO(BIC) make virtual. For now it must be implemented by virtual_hook. - bool writeFile( const TQString& name, const TQString& user, const TQString& group, - uint size, mode_t perm, time_t atime, time_t mtime, - time_t ctime, const char* data ); - /** - * Write data to a file that has been created using prepareWriting(). - * @param data a pointer to the data - * @param size the size of the chunk - * @return true if successful, false otherwise - */ - bool writeData( const char* data, uint size ); // TODO make virtual - - /** - * Write data to a file that has been created using prepareWriting(). - * @param size the size of the file - * @return true if successful, false otherwise - */ - virtual bool doneWriting( uint size ); - -protected: - /** - * Opens the archive for reading. - * Parses the directory listing of the archive - * and creates the KArchiveDirectory/KArchiveFile entries. - * @param mode the mode of the file - */ - virtual bool openArchive( int mode ); - /// Closes the archive - virtual bool closeArchive(); - - /** - * @internal Not needed for zip - */ - virtual bool writeDir( const TQString& name, const TQString& user, const TQString& group) { Q_UNUSED(name); Q_UNUSED(user); Q_UNUSED(group); return true; } - // TODO(BIC) uncomment and make virtual for KDE 4. -// bool writeDir( const TQString& name, const TQString& user, const TQString& group, -// mode_t perm, time_t atime, time_t mtime, time_t ctime ); - -protected: - virtual void virtual_hook( int id, void* data ); - /** @internal for virtual_hook */ - // from KArchive - bool writeData_impl( const char* data, uint size ); - bool prepareWriting_impl(const TQString& name, const TQString& user, - const TQString& group, uint size, mode_t perm, - time_t atime, time_t mtime, time_t ctime); - bool writeSymLink_impl(const TQString &name, const TQString &target, - const TQString &user, const TQString &group, - mode_t perm, time_t atime, time_t mtime, time_t ctime); -private: - void abort(); - -private: - TQString m_filename; - class KZipPrivate; - KZipPrivate * d; -}; - - -/** - * @internal - */ -class TDEIO_EXPORT KZipFileEntry : public KArchiveFile -{ -public: - /*KZipFileEntry() : st(-1) - {}*/ - KZipFileEntry( KZip* zip, const TQString& name, int access, int date, - const TQString& user, const TQString& group, const TQString& symlink, - const TQString& path, TQ_LONG start, TQ_LONG uncompressedSize, - int encoding, TQ_LONG compressedSize) : - KArchiveFile( zip, name, access, date, user, group, symlink, - start, uncompressedSize ), - m_crc(0), - m_compressedSize(compressedSize), - m_headerStart(0), - m_encoding(encoding), - m_path( path ) - {} - int encoding() const { return m_encoding; } - TQ_LONG compressedSize() const { return m_compressedSize; } - - /// Only used when writing - void setCompressedSize(TQ_LONG compressedSize) { m_compressedSize = compressedSize; } - - /// Header start: only used when writing - void setHeaderStart(TQ_LONG headerstart) { m_headerStart = headerstart; } - TQ_LONG headerStart() const {return m_headerStart; } - - /// CRC: only used when writing - unsigned long crc32() const { return m_crc; } - void setCRC32(unsigned long crc32) { m_crc=crc32; } - - /// Name with complete path - KArchiveFile::name() is the filename only (no path) - TQString path() const { return m_path; } - - /** - * @return the content of this file. - * Call data() with care (only once per file), this data isn't cached. - */ - virtual TQByteArray data() const; - - /** - * This method returns a TQIODevice to read the file contents. - * This is obviously for reading only. - * Note that the ownership of the device is being transferred to the caller, - * who will have to delete it. - * The returned device auto-opens (in readonly mode), no need to open it. - */ - TQIODevice* device() const; // WARNING, not virtual! - -private: - unsigned long m_crc; - TQ_LONG m_compressedSize; - TQ_LONG m_headerStart; - int m_encoding; - TQString m_path; - // KDE4: d pointer or at least some int for future extensions -}; - -#endif diff --git a/kio/kio/lex.c b/kio/kio/lex.c deleted file mode 100644 index 99848a2f3..000000000 --- a/kio/kio/lex.c +++ /dev/null @@ -1,1759 +0,0 @@ -#define yy_create_buffer kiotrader_create_buffer -#define yy_delete_buffer kiotrader_delete_buffer -#define yy_scan_buffer kiotrader_scan_buffer -#define yy_scan_string kiotrader_scan_string -#define yy_scan_bytes kiotrader_scan_bytes -#define yy_flex_debug kiotrader_flex_debug -#define yy_init_buffer kiotrader_init_buffer -#define yy_flush_buffer kiotrader_flush_buffer -#define yy_load_buffer_state kiotrader_load_buffer_state -#define yy_switch_to_buffer kiotrader_switch_to_buffer -#define yyin kiotraderin -#define yyleng kiotraderleng -#define yylex kiotraderlex -#define yyout kiotraderout -#define yyrestart kiotraderrestart -#define yytext kiotradertext -#define yywrap kiotraderwrap - -#line 20 "lex.c" -/* A lexical scanner generated by flex */ - -/* Scanner skeleton version: - * $Header$ - */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 - -#include <stdio.h> -#include <unistd.h> - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include <stdlib.h> - -/* Use prototypes in function declarations. */ -#define YY_USE_PROTOS - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -#if __STDC__ - -#define YY_USE_PROTOS -#define YY_USE_CONST - -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ - -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include <io.h> -#include <stdlib.h> -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - - -#ifdef YY_USE_PROTOS -#define YY_PROTO(proto) proto -#else -#define YY_PROTO(proto) () -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#define YY_BUF_SIZE 16384 - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -extern int yyleng; -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ - -/* Return all but the first 'n' matched characters back to the input stream. */ - -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext_ptr ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ -typedef unsigned int yy_size_t; - - -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - }; - -static YY_BUFFER_STATE yy_current_buffer = 0; - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart YY_PROTO(( FILE *input_file )); - -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) - -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); - -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) - -typedef unsigned char YY_CHAR; -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -typedef int yy_state_type; -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); -static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 25 -#define YY_END_OF_BUFFER 26 -static yyconst short int yy_accept[63] = - { 0, - 0, 0, 26, 24, 23, 23, 24, 24, 14, 14, - 24, 19, 3, 14, 4, 22, 22, 22, 24, 22, - 22, 22, 22, 22, 22, 23, 2, 0, 17, 18, - 20, 0, 19, 5, 1, 6, 22, 22, 22, 0, - 22, 22, 10, 22, 22, 22, 9, 22, 22, 0, - 21, 8, 22, 12, 13, 7, 22, 15, 22, 16, - 11, 0 - } ; - -static yyconst int yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 1, 1, 1, 1, 1, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 1, 1, 15, - 16, 17, 1, 1, 18, 19, 19, 19, 20, 21, - 19, 19, 19, 19, 19, 22, 19, 19, 19, 19, - 19, 23, 24, 25, 26, 19, 19, 19, 19, 19, - 27, 1, 28, 1, 1, 1, 29, 19, 19, 30, - - 31, 19, 19, 19, 32, 19, 19, 19, 33, 34, - 35, 19, 19, 36, 37, 38, 19, 19, 19, 39, - 19, 19, 1, 1, 1, 40, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst int yy_meta[41] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 1, 1, 3, 1, 1, 1, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 1, 2, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 1 - } ; - -static yyconst short int yy_base[67] = - { 0, - 0, 0, 95, 96, 39, 41, 78, 88, 96, 78, - 77, 33, 74, 73, 72, 0, 69, 63, 0, 51, - 45, 49, 17, 47, 45, 48, 96, 75, 96, 65, - 64, 63, 40, 96, 96, 96, 0, 54, 49, 46, - 43, 40, 0, 32, 36, 31, 0, 44, 47, 38, - 96, 0, 28, 0, 0, 0, 44, 0, 15, 0, - 0, 96, 54, 56, 44, 59 - } ; - -static yyconst short int yy_def[67] = - { 0, - 62, 1, 62, 62, 62, 62, 62, 63, 62, 62, - 62, 62, 62, 62, 62, 64, 64, 64, 65, 64, - 64, 64, 64, 64, 64, 62, 62, 63, 62, 62, - 62, 62, 62, 62, 62, 62, 64, 64, 64, 66, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 66, - 62, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 0, 62, 62, 62, 62 - } ; - -static yyconst short int yy_nxt[137] = - { 0, - 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, - 10, 11, 9, 12, 13, 14, 15, 16, 16, 16, - 17, 16, 16, 16, 18, 16, 19, 4, 20, 16, - 21, 22, 23, 24, 25, 16, 16, 16, 16, 9, - 26, 26, 26, 26, 32, 44, 33, 40, 45, 26, - 26, 32, 61, 33, 28, 28, 28, 28, 37, 37, - 50, 50, 50, 60, 59, 51, 58, 57, 56, 55, - 54, 53, 52, 51, 49, 48, 31, 31, 30, 29, - 47, 46, 43, 42, 41, 39, 38, 36, 35, 34, - 31, 30, 29, 27, 62, 3, 62, 62, 62, 62, - - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62 - } ; - -static yyconst short int yy_chk[137] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 5, 5, 6, 6, 12, 23, 12, 65, 23, 26, - 26, 33, 59, 33, 63, 63, 63, 63, 64, 64, - 66, 66, 66, 57, 53, 50, 49, 48, 46, 45, - 44, 42, 41, 40, 39, 38, 32, 31, 30, 28, - 25, 24, 22, 21, 20, 18, 17, 15, 14, 13, - 11, 10, 8, 7, 3, 62, 62, 62, 62, 62, - - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "lex.l" -#define INITIAL 0 -#line 2 "lex.l" -#define yylval kiotraderlval -#define yywrap kiotraderwrap - -#include "yacc.h" -#include <string.h> -#include <stdlib.h> -#define YY_NO_UNPUT - -char* KTraderParse_putSymbol( char *_name ); -char *KTraderParse_putSymbolInBrackets( char *_name ); -char* KTraderParse_putString( char *_name ); -int yywrap(); -int kiotraderlex(void); -void KTraderParse_initFlex( const char *_code ); - -#line 447 "lex.c" - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); -#else -extern int yywrap YY_PROTO(( void )); -#endif -#endif - -#ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput YY_PROTO(( void )); -#else -static int input YY_PROTO(( void )); -#endif -#endif - -#if YY_STACK_USED -static int yy_start_stack_ptr = 0; -static int yy_start_stack_depth = 0; -static int *yy_start_stack = 0; -#ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); -#endif -#ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); -#endif -#ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); -#endif - -#else -#define YY_NO_PUSH_STATE 1 -#define YY_NO_POP_STATE 1 -#define YY_NO_TOP_STATE 1 -#endif - -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include <stdlib.h> -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ - -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL int yylex YY_PROTO(( void )) -#endif - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 21 "lex.l" - - -#line 601 "lex.c" - - if ( yy_init ) - { - yy_init = 0; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 63 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 96 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - -do_action: /* This label is used only to access EOF actions. */ - - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 23 "lex.l" -{ return EQ; } - YY_BREAK -case 2: -YY_RULE_SETUP -#line 24 "lex.l" -{ return NEQ; } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 25 "lex.l" -{ return LE; } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 26 "lex.l" -{ return GR; } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 27 "lex.l" -{ return LEQ; } - YY_BREAK -case 6: -YY_RULE_SETUP -#line 28 "lex.l" -{ return GEQ; } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 29 "lex.l" -{ return NOT; } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 30 "lex.l" -{ return AND; } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 31 "lex.l" -{ return OR; } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 32 "lex.l" -{ return TOKEN_IN; } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 33 "lex.l" -{ return EXIST; } - YY_BREAK -case 12: -YY_RULE_SETUP -#line 34 "lex.l" -{ return MAX; } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 35 "lex.l" -{ return MIN; } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 37 "lex.l" -{ yylval.name = 0L; return (int)(*yytext); } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 39 "lex.l" -{ yylval.valb = 1; return VAL_BOOL; } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 40 "lex.l" -{ yylval.valb = 0; return VAL_BOOL; } - YY_BREAK -case 17: -YY_RULE_SETUP -#line 42 "lex.l" -{ yylval.name = KTraderParse_putString( yytext ); return VAL_STRING; } - YY_BREAK -case 18: -YY_RULE_SETUP -#line 44 "lex.l" -{ yylval.vali = atoi( yytext ); return VAL_NUM; } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 45 "lex.l" -{ yylval.vali = atoi( yytext ); return VAL_NUM; } - YY_BREAK -case 20: -YY_RULE_SETUP -#line 47 "lex.l" -{ yylval.vald = atof( yytext ); return VAL_FLOAT; } - YY_BREAK -case 21: -YY_RULE_SETUP -#line 49 "lex.l" -{ yylval.name = KTraderParse_putSymbolInBrackets( yytext ); return VAL_ID; } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 51 "lex.l" -{ yylval.name = KTraderParse_putSymbol( yytext ); return VAL_ID; } - YY_BREAK -case 23: -YY_RULE_SETUP -#line 53 "lex.l" -/* eat up whitespace */ - YY_BREAK -case 24: -YY_RULE_SETUP -#line 55 "lex.l" -{ printf( "Unrecognized character: %s\n", yytext ); } - YY_BREAK -case 25: -YY_RULE_SETUP -#line 57 "lex.l" -ECHO; - YY_BREAK -#line 809 "lex.c" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ - - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; - - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; -#endif - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - - return ret_val; - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 63 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -#ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) -#else -static yy_state_type yy_try_NUL_trans( yy_current_state ) -yy_state_type yy_current_state; -#endif - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 63 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 62); - - return yy_is_jam ? 0 : yy_current_state; - } - - -#ifndef YY_NO_UNPUT -#ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) -#else -static void yyunput( c, yy_bp ) -int c; -register char *yy_bp; -#endif - { - register char *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ - - -#ifdef __cplusplus -static int yyinput() -#else -static int input() -#endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; - - - return c; - } - - -#ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) -#else -void yyrestart( input_file ) -FILE *input_file; -#endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -#ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) -#else -void yy_switch_to_buffer( new_buffer ) -YY_BUFFER_STATE new_buffer; -#endif - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -#ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) -#else -void yy_load_buffer_state() -#endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) -#else -YY_BUFFER_STATE yy_create_buffer( file, size ) -FILE *file; -int size; -#endif - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; - } - - -#ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) -#else -void yy_delete_buffer( b ) -YY_BUFFER_STATE b; -#endif - { - if ( ! b ) - return; - - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); - - yy_flex_free( (void *) b ); - } - - - -#ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) -#else -void yy_init_buffer( b, file ) -YY_BUFFER_STATE b; -FILE *file; -#endif - - - { - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - -#if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; -#else -#if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; -#else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -#endif -#endif - } - - -#ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) -#else -void yy_flush_buffer( b ) -YY_BUFFER_STATE b; -#endif - - { - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } - - -#ifndef YY_NO_SCAN_BUFFER -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) -#else -YY_BUFFER_STATE yy_scan_buffer( base, size ) -char *base; -yy_size_t size; -#endif - { - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; - } -#endif - - -#ifndef YY_NO_SCAN_STRING -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) -#else -YY_BUFFER_STATE yy_scan_string( yy_str ) -yyconst char *yy_str; -#endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; - - return yy_scan_bytes( yy_str, len ); - } -#endif - - -#ifndef YY_NO_SCAN_BYTES -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) -#else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) -yyconst char *bytes; -int len; -#endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; - - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; - } -#endif - - -#ifndef YY_NO_PUSH_STATE -#ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) -#else -static void yy_push_state( new_state ) -int new_state; -#endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; - - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); - - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); - - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); - - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } - - yy_start_stack[yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); - } -#endif - - -#ifndef YY_NO_POP_STATE -static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } -#endif - - -#ifndef YY_NO_TOP_STATE -static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } -#endif - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -#ifdef YY_USE_PROTOS -static void yy_fatal_error( yyconst char msg[] ) -#else -static void yy_fatal_error( msg ) -char msg[]; -#endif - { - (void) fprintf( stderr, "[lex] %s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - - - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) - - -/* Internal utility routines. */ - -#ifndef yytext_ptr -#ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) -#else -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -yyconst char *s2; -int n; -#endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -#endif - -#ifdef YY_NEED_STRLEN -#ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) -#else -static int yy_flex_strlen( s ) -yyconst char *s; -#endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; - } -#endif - - -#ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) -#else -static void *yy_flex_alloc( size ) -yy_size_t size; -#endif - { - return (void *) malloc( size ); - } - -#ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) -#else -static void *yy_flex_realloc( ptr, size ) -void *ptr; -yy_size_t size; -#endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } - -#ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) -#else -static void yy_flex_free( ptr ) -void *ptr; -#endif - { - free( ptr ); - } - -#if YY_MAIN -int main() - { - yylex(); - return 0; - } -#endif -#line 57 "lex.l" - - -char* KTraderParse_putSymbolInBrackets( char *_name ) -{ - int l = strlen( _name )-1; - char *p = (char *)malloc( l ); - if (p != NULL) - { - strncpy( p, _name+1, l-1 ); - p[l-1] = 0; - } - - return p; -} - -char *KTraderParse_putSymbol( char *_name ) -{ - char *p = (char*)malloc( strlen( _name ) + 1 ); - if (p != NULL) - { - strcpy( p, _name ); - } - return p; -} - -char* KTraderParse_putString( char *_str ) -{ - int l = strlen( _str ); - char *p = (char*)malloc( l ); - char *s = _str + 1; - char *d = p; - - if (p == NULL) - return NULL; - - while ( s != _str + l - 1 ) - { - if ( *s != '\\' ) - *d++ = *s++; - else - { - s++; - if ( s != _str + l - 1 ) - { - if ( *s == '\\' ) - *d++ = '\\'; - else if ( *s == 'n' ) - *d++ = '\n'; - else if ( *s == 'r' ) - *d++ = '\r'; - else if ( *s == 't' ) - *d++ = '\t'; - s++; - } - } - } - *d = 0; - return p; -} - -void KTraderParse_initFlex( const char *_code ) -{ - yy_switch_to_buffer( yy_scan_string( _code ) ); -} - -int yywrap() -{ - yy_delete_buffer( YY_CURRENT_BUFFER ); - return 1; -} diff --git a/kio/kio/lex.l b/kio/kio/lex.l deleted file mode 100644 index 073a34965..000000000 --- a/kio/kio/lex.l +++ /dev/null @@ -1,126 +0,0 @@ -%{ -#define yylval kiotraderlval -#define yywrap kiotraderwrap - -#include "yacc.h" -#include <string.h> -#include <stdlib.h> -#define YY_NO_UNPUT - -char* KTraderParse_putSymbol( char *_name ); -char *KTraderParse_putSymbolInBrackets( char *_name ); -char* KTraderParse_putString( char *_name ); -int yywrap(); -int kiotraderlex(void); -void KTraderParse_initFlex( const char *_code ); - -%} - -DIGIT [0-9] - -%% - -"==" { return EQ; } -"!=" { return NEQ; } -"<" { return LE; } -">" { return GR; } -"<=" { return LEQ; } -">=" { return GEQ; } -"not" { return NOT; } -"and" { return AND; } -"or" { return OR; } -"in" { return TOKEN_IN; } -"exist" { return EXIST; } -"max" { return MAX; } -"min" { return MIN; } - -"~"|"/"|"+"|"-"|"="|"*"|"("|")"|"," { yylval.name = 0L; return (int)(*yytext); } - -"TRUE" { yylval.valb = 1; return VAL_BOOL; } -"FALSE" { yylval.valb = 0; return VAL_BOOL; } - -"'"[^']*"'" { yylval.name = KTraderParse_putString( yytext ); return VAL_STRING; } - -"-"{DIGIT}+ { yylval.vali = atoi( yytext ); return VAL_NUM; } -{DIGIT}+ { yylval.vali = atoi( yytext ); return VAL_NUM; } - -{DIGIT}*"\."{DIGIT}+ { yylval.vald = atof( yytext ); return VAL_FLOAT; } - -\[[a-zA-Z][a-zA-Z0-9\-]*\] { yylval.name = KTraderParse_putSymbolInBrackets( yytext ); return VAL_ID; } - -[a-zA-Z][a-zA-Z0-9]* { yylval.name = KTraderParse_putSymbol( yytext ); return VAL_ID; } - -[ \t\n]+ /* eat up whitespace */ - -. { printf( "Unrecognized character: %s\n", yytext ); } - -%% - -char* KTraderParse_putSymbolInBrackets( char *_name ) -{ - int l = strlen( _name )-1; - char *p = (char *)malloc( l ); - if (p != NULL) - { - strncpy( p, _name+1, l-1 ); - p[l-1] = 0; - } - - return p; -} - -char *KTraderParse_putSymbol( char *_name ) -{ - char *p = (char*)malloc( strlen( _name ) + 1 ); - if (p != NULL) - { - strcpy( p, _name ); - } - return p; -} - -char* KTraderParse_putString( char *_str ) -{ - int l = strlen( _str ); - char *p = (char*)malloc( l ); - char *s = _str + 1; - char *d = p; - - if (p == NULL) - return NULL; - - while ( s != _str + l - 1 ) - { - if ( *s != '\\' ) - *d++ = *s++; - else - { - s++; - if ( s != _str + l - 1 ) - { - if ( *s == '\\' ) - *d++ = '\\'; - else if ( *s == 'n' ) - *d++ = '\n'; - else if ( *s == 'r' ) - *d++ = '\r'; - else if ( *s == 't' ) - *d++ = '\t'; - s++; - } - } - } - *d = 0; - return p; -} - -void KTraderParse_initFlex( const char *_code ) -{ - yy_switch_to_buffer( yy_scan_string( _code ) ); -} - -int yywrap() -{ - yy_delete_buffer( YY_CURRENT_BUFFER ); - return 1; -} diff --git a/kio/kio/metainfojob.cpp b/kio/kio/metainfojob.cpp deleted file mode 100644 index d28914f20..000000000 --- a/kio/kio/metainfojob.cpp +++ /dev/null @@ -1,184 +0,0 @@ -// -*- c++ -*- -// vim: ts=4 sw=4 et -/* This file is part of the KDE libraries - Copyright (C) 2002 Rolf Magnus <ramagnus@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation version 2.0. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - $Id$ -*/ - -#include <kdatastream.h> // Do not remove, needed for correct bool serialization -#include <kfileitem.h> -#include <kdebug.h> -#include <kfilemetainfo.h> -#include <kio/kservice.h> -#include <tdeparts/componentfactory.h> - -#include <tqtimer.h> - -#include "metainfojob.moc" - -using namespace TDEIO; - -struct TDEIO::MetaInfoJobPrivate -{ - KFileItemList items; // all the items we got - KFileItemListIterator* currentItem; // argh! No default constructor - bool deleteItems; // Delete the KFileItems when done? - bool succeeded; // if the current item is ok -}; - -MetaInfoJob::MetaInfoJob(const KFileItemList &items, bool deleteItems) - : TDEIO::Job(false /* no GUI */) -{ - d = new MetaInfoJobPrivate; - d->deleteItems = deleteItems; - d->succeeded = false; - d->items = items; - d->currentItem = new KFileItemListIterator(d->items); - - d->items.setAutoDelete(deleteItems); - - if (d->currentItem->isEmpty()) - { - kdDebug(7007) << "nothing to do for the MetaInfoJob\n"; - emitResult(); - return; - } - - kdDebug(7007) << "starting MetaInfoJob\n"; - - // Return to event loop first, determineNextFile() might delete this; - // (no idea what that means, it comes from previewjob) - TQTimer::singleShot(0, this, TQT_SLOT(start())); -} - -MetaInfoJob::~MetaInfoJob() -{ - delete d->currentItem; - delete d; -} - -void MetaInfoJob::start() -{ - getMetaInfo(); -} - -void MetaInfoJob::removeItem(const KFileItem* item) -{ - if (d->currentItem->current() == item) - { - subjobs.first()->kill(); - subjobs.removeFirst(); - determineNextFile(); - } - - d->items.remove(d->items.find(item)); -} - -void MetaInfoJob::determineNextFile() -{ - if (d->currentItem->atLast()) - { - kdDebug(7007) << "finished MetaInfoJob\n"; - emitResult(); - return; - } - - ++(*d->currentItem); - d->succeeded = false; - - // does the file item already have the needed info? Then shortcut - if (d->currentItem->current()->metaInfo(false).isValid()) - { -// kdDebug(7007) << "Is already valid *************************\n"; - emit gotMetaInfo(d->currentItem->current()); - determineNextFile(); - return; - } - - getMetaInfo(); -} - -void MetaInfoJob::slotResult( TDEIO::Job *job ) -{ - subjobs.remove(job); - Q_ASSERT(subjobs.isEmpty()); // We should have only one job at a time ... - - determineNextFile(); -} - -void MetaInfoJob::getMetaInfo() -{ - Q_ASSERT(!d->currentItem->isEmpty()); - - KURL URL; - URL.setProtocol("metainfo"); - URL.setPath(d->currentItem->current()->url().path()); - - TDEIO::TransferJob* job = TDEIO::get(URL, false, false); - addSubjob(job); - - connect(job, TQT_SIGNAL(data(TDEIO::Job *, const TQByteArray &)), - this, TQT_SLOT(slotMetaInfo(TDEIO::Job *, const TQByteArray &))); - - job->addMetaData("mimeType", d->currentItem->current()->mimetype()); -} - - -void MetaInfoJob::slotMetaInfo(TDEIO::Job*, const TQByteArray &data) -{ - KFileMetaInfo info; - TQDataStream s(data, IO_ReadOnly); - - s >> info; - - d->currentItem->current()->setMetaInfo(info); - emit gotMetaInfo(d->currentItem->current()); - d->succeeded = true; -} - -TQStringList MetaInfoJob::availablePlugins() -{ - TQStringList result; - KTrader::OfferList plugins = KTrader::self()->query("KFilePlugin"); - for (KTrader::OfferList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it) - result.append((*it)->desktopEntryName()); - return result; -} - -TQStringList MetaInfoJob::supportedMimeTypes() -{ - TQStringList result; - KTrader::OfferList plugins = KTrader::self()->query("KFilePlugin"); - for (KTrader::OfferList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it) - result += (*it)->property("MimeTypes").toStringList(); - return result; -} - -TDEIO_EXPORT MetaInfoJob *TDEIO::fileMetaInfo( const KFileItemList &items) -{ - return new MetaInfoJob(items, false); -} - -TDEIO_EXPORT MetaInfoJob *TDEIO::fileMetaInfo( const KURL::List &items) -{ - KFileItemList fileItems; - for (KURL::List::ConstIterator it = items.begin(); it != items.end(); ++it) - fileItems.append(new KFileItem(KFileItem::Unknown, KFileItem::Unknown, *it, true)); - return new MetaInfoJob(fileItems, true); -} - diff --git a/kio/kio/metainfojob.h b/kio/kio/metainfojob.h deleted file mode 100644 index e2152bded..000000000 --- a/kio/kio/metainfojob.h +++ /dev/null @@ -1,119 +0,0 @@ -// -*- c++ -*- -// vim: ts=4 sw=4 et -/* This file is part of the KDE libraries - Copyright (C) 2001 Rolf Magnus <ramagnus@kde.org> - parts of this taken from previewjob.h - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation version 2.0. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_metainfojob_h__ -#define __kio_metainfojob_h__ - -#include <kio/job.h> -#include <kfileitem.h> - -namespace TDEIO { - /** - * MetaInfoJob is a KIO Job to retrieve meta information from files. - * - * @short KIO Job to retrieve meta information from files. - * @since 3.1 - */ - class TDEIO_EXPORT MetaInfoJob : public TDEIO::Job - { - Q_OBJECT - public: - /** - * Creates a new MetaInfoJob. - * @param items A list of KFileItems to get the metainfo for - * @param deleteItems If true, the finished KFileItems are deleted - */ - MetaInfoJob(const KFileItemList &items, bool deleteItems = false); - virtual ~MetaInfoJob(); - - /** - * Removes an item from metainfo extraction. - * - * @param item the item that should be removed from the queue - */ - void removeItem( const KFileItem *item ); - - /** - * Returns a list of all available metainfo plugins. The list - * contains the basenames of the plugins' .desktop files (no path, - * no .desktop). - * @return the list of available meta info plugins - */ - static TQStringList availablePlugins(); - - /** - * Returns a list of all supported MIME types. The list can - * contain entries like text/ * (without the space). - * @return the list of MIME types that are supported - */ - static TQStringList supportedMimeTypes(); - - signals: - /** - * Emitted when the meta info for @p item has been successfully - * retrieved. - * @param item the KFileItem describing the fetched item - */ - void gotMetaInfo( const KFileItem *item ); - /** - * Emitted when metainfo for @p item could not be extracted, - * either because a plugin for its MIME type does not - * exist, or because something went wrong. - * @param item the KFileItem of the file that failed - */ - void failed( const KFileItem *item ); - - protected: - void getMetaInfo(); - - protected slots: - virtual void slotResult( TDEIO::Job *job ); - - private slots: - void start(); - void slotMetaInfo(TDEIO::Job *, const TQByteArray &); - - private: - void determineNextFile(); -// void saveMetaInfo(const TQByteArray info); - - private: - struct MetaInfoJobPrivate *d; - }; - - /** - * Retrieves meta information for the given items. - * - * @param items files to get metainfo for - * @return the MetaInfoJob to retrieve the items - */ - TDEIO_EXPORT MetaInfoJob* fileMetaInfo(const KFileItemList& items); - - /** - * Retrieves meta information for the given items. - * - * @param items files to get metainfo for - * @return the MetaInfoJob to retrieve the items - */ - TDEIO_EXPORT MetaInfoJob* fileMetaInfo(const KURL::List& items); -} - -#endif diff --git a/kio/kio/netaccess.cpp b/kio/kio/netaccess.cpp deleted file mode 100644 index 11c20be49..000000000 --- a/kio/kio/netaccess.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/* $Id$ - - This file is part of the KDE libraries - Copyright (C) 1997 Torben Weis (weis@kde.org) - Copyright (C) 1998 Matthias Ettrich (ettrich@kde.org) - Copyright (C) 1999 David Faure (faure@kde.org) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <stdlib.h> -#include <stdio.h> -#include <signal.h> -#include <unistd.h> - -#include <cstring> - -#include <tqstring.h> -#include <tqapplication.h> -#include <tqfile.h> -#include <tqmetaobject.h> - -#include <kapplication.h> -#include <klocale.h> -#include <ktempfile.h> -#include <kdebug.h> -#include <kurl.h> -#include <kio/job.h> -#include <kio/scheduler.h> - -#include "kio/netaccess.h" - -using namespace TDEIO; - -TQString * NetAccess::lastErrorMsg; -int NetAccess::lastErrorCode = 0; -TQStringList* NetAccess::tmpfiles; - -bool NetAccess::download(const KURL& u, TQString & target) -{ - return NetAccess::download (u, target, 0); -} - -bool NetAccess::download(const KURL& u, TQString & target, TQWidget* window) -{ - if (u.isLocalFile()) { - // file protocol. We do not need the network - target = u.path(); - bool accessible = checkAccess(target, R_OK); - if(!accessible) - { - if(!lastErrorMsg) - lastErrorMsg = new TQString; - *lastErrorMsg = i18n("File '%1' is not readable").arg(target); - lastErrorCode = ERR_COULD_NOT_READ; - } - return accessible; - } - - if (target.isEmpty()) - { - KTempFile tmpFile; - target = tmpFile.name(); - if (!tmpfiles) - tmpfiles = new TQStringList; - tmpfiles->append(target); - } - - NetAccess kioNet; - KURL dest; - dest.setPath( target ); - return kioNet.filecopyInternal( u, dest, -1, true /*overwrite*/, - false, window, false /*copy*/); -} - -bool NetAccess::upload(const TQString& src, const KURL& target) -{ - return NetAccess::upload(src, target, 0); -} - -bool NetAccess::upload(const TQString& src, const KURL& target, TQWidget* window) -{ - if (target.isEmpty()) - return false; - - // If target is local... well, just copy. This can be useful - // when the client code uses a temp file no matter what. - // Let's make sure it's not the exact same file though - if (target.isLocalFile() && target.path() == src) - return true; - - NetAccess kioNet; - KURL s; - s.setPath(src); - return kioNet.filecopyInternal( s, target, -1, true /*overwrite*/, - false, window, false /*copy*/ ); -} - -bool NetAccess::copy( const KURL & src, const KURL & target ) -{ - return NetAccess::file_copy( src, target, -1, false /*not overwrite*/, false, 0L ); -} - -bool NetAccess::copy( const KURL & src, const KURL & target, TQWidget* window ) -{ - return NetAccess::file_copy( src, target, -1, false /*not overwrite*/, false, window ); -} - -bool NetAccess::file_copy( const KURL& src, const KURL& target, int permissions, - bool overwrite, bool resume, TQWidget* window ) -{ - NetAccess kioNet; - return kioNet.filecopyInternal( src, target, permissions, overwrite, resume, - window, false /*copy*/ ); -} - - -bool NetAccess::file_move( const KURL& src, const KURL& target, int permissions, - bool overwrite, bool resume, TQWidget* window ) -{ - NetAccess kioNet; - return kioNet.filecopyInternal( src, target, permissions, overwrite, resume, - window, true /*move*/ ); -} - -bool NetAccess::dircopy( const KURL & src, const KURL & target ) -{ - return NetAccess::dircopy( src, target, 0 ); -} - -bool NetAccess::dircopy( const KURL & src, const KURL & target, TQWidget* window ) -{ - KURL::List srcList; - srcList.append( src ); - return NetAccess::dircopy( srcList, target, window ); -} - -bool NetAccess::dircopy( const KURL::List & srcList, const KURL & target, TQWidget* window ) -{ - NetAccess kioNet; - return kioNet.dircopyInternal( srcList, target, window, false /*copy*/ ); -} - -bool NetAccess::move( const KURL& src, const KURL& target, TQWidget* window ) -{ - KURL::List srcList; - srcList.append( src ); - return NetAccess::move( srcList, target, window ); -} - -bool NetAccess::move( const KURL::List& srcList, const KURL& target, TQWidget* window ) -{ - NetAccess kioNet; - return kioNet.dircopyInternal( srcList, target, window, true /*move*/ ); -} - -bool NetAccess::exists( const KURL & url ) -{ - return NetAccess::exists( url, false, 0 ); -} - -bool NetAccess::exists( const KURL & url, TQWidget* window ) -{ - return NetAccess::exists( url, false, window ); -} - -bool NetAccess::exists( const KURL & url, bool source ) -{ - return NetAccess::exists( url, source, 0 ); -} - -bool NetAccess::exists( const KURL & url, bool source, TQWidget* window ) -{ - if ( url.isLocalFile() ) - return TQFile::exists( url.path() ); - NetAccess kioNet; - return kioNet.statInternal( url, 0 /*no details*/, source, window ); -} - -bool NetAccess::stat( const KURL & url, TDEIO::UDSEntry & entry ) -{ - return NetAccess::stat( url, entry, 0 ); -} - -bool NetAccess::stat( const KURL & url, TDEIO::UDSEntry & entry, TQWidget* window ) -{ - NetAccess kioNet; - bool ret = kioNet.statInternal( url, 2 /*all details*/, true /*source*/, window ); - if (ret) - entry = kioNet.m_entry; - return ret; -} - -KURL NetAccess::mostLocalURL(const KURL & url, TQWidget* window) -{ - if ( url.isLocalFile() ) - { - return url; - } - - TDEIO::UDSEntry entry; - if (!stat(url, entry, window)) - { - return url; - } - - TQString path; - - // Extract the local path from the TDEIO::UDSEntry - TDEIO::UDSEntry::ConstIterator it = entry.begin(); - const TDEIO::UDSEntry::ConstIterator end = entry.end(); - for ( ; it != end; ++it ) - { - if ( (*it).m_uds == TDEIO::UDS_LOCAL_PATH ) - { - path = (*it).m_str; - break; - } - } - - if ( !path.isEmpty() ) - { - KURL new_url; - new_url.setPath(path); - return new_url; - } - - return url; -} - - -bool NetAccess::del( const KURL & url ) -{ - return NetAccess::del( url, 0 ); -} - -bool NetAccess::del( const KURL & url, TQWidget* window ) -{ - NetAccess kioNet; - return kioNet.delInternal( url, window ); -} - -bool NetAccess::mkdir( const KURL & url, int permissions ) -{ - return NetAccess::mkdir( url, 0, permissions ); -} - -bool NetAccess::mkdir( const KURL & url, TQWidget* window, int permissions ) -{ - NetAccess kioNet; - return kioNet.mkdirInternal( url, permissions, window ); -} - -TQString NetAccess::fish_execute( const KURL & url, const TQString command, TQWidget* window ) -{ - NetAccess kioNet; - return kioNet.fish_executeInternal( url, command, window ); -} - -bool NetAccess::synchronousRun( Job* job, TQWidget* window, TQByteArray* data, - KURL* finalURL, TQMap<TQString, TQString>* metaData ) -{ - NetAccess kioNet; - return kioNet.synchronousRunInternal( job, window, data, finalURL, metaData ); -} - -TQString NetAccess::mimetype( const KURL& url ) -{ - NetAccess kioNet; - return kioNet.mimetypeInternal( url, 0 ); -} - -TQString NetAccess::mimetype( const KURL& url, TQWidget* window ) -{ - NetAccess kioNet; - return kioNet.mimetypeInternal( url, window ); -} - -void NetAccess::removeTempFile(const TQString& name) -{ - if (!tmpfiles) - return; - if (tmpfiles->contains(name)) - { - unlink(TQFile::encodeName(name)); - tmpfiles->remove(name); - } -} - -bool NetAccess::filecopyInternal(const KURL& src, const KURL& target, int permissions, - bool overwrite, bool resume, TQWidget* window, bool move) -{ - bJobOK = true; // success unless further error occurs - - TDEIO::Scheduler::checkSlaveOnHold(true); - TDEIO::Job * job = move - ? TDEIO::file_move( src, target, permissions, overwrite, resume ) - : TDEIO::file_copy( src, target, permissions, overwrite, resume ); - job->setWindow (window); - connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), - this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); - - enter_loop(); - return bJobOK; -} - -bool NetAccess::dircopyInternal(const KURL::List& src, const KURL& target, - TQWidget* window, bool move) -{ - bJobOK = true; // success unless further error occurs - - TDEIO::Job * job = move - ? TDEIO::move( src, target ) - : TDEIO::copy( src, target ); - job->setWindow (window); - connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), - this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); - - enter_loop(); - return bJobOK; -} - -bool NetAccess::statInternal( const KURL & url, int details, bool source, - TQWidget* window ) -{ - bJobOK = true; // success unless further error occurs - TDEIO::StatJob * job = TDEIO::stat( url, !url.isLocalFile() && !url.url().startsWith("beagle:?") ); - job->setWindow (window); - job->setDetails( details ); - job->setSide( source ); - connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), - this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); - enter_loop(); - return bJobOK; -} - -bool NetAccess::delInternal( const KURL & url, TQWidget* window ) -{ - bJobOK = true; // success unless further error occurs - TDEIO::Job * job = TDEIO::del( url ); - job->setWindow (window); - connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), - this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); - enter_loop(); - return bJobOK; -} - -bool NetAccess::mkdirInternal( const KURL & url, int permissions, - TQWidget* window ) -{ - bJobOK = true; // success unless further error occurs - TDEIO::Job * job = TDEIO::mkdir( url, permissions ); - job->setWindow (window); - connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), - this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); - enter_loop(); - return bJobOK; -} - -TQString NetAccess::mimetypeInternal( const KURL & url, TQWidget* window ) -{ - bJobOK = true; // success unless further error occurs - m_mimetype = TQString::fromLatin1("unknown"); - TDEIO::Job * job = TDEIO::mimetype( url ); - job->setWindow (window); - connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), - this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); - connect( job, TQT_SIGNAL( mimetype (TDEIO::Job *, const TQString &) ), - this, TQT_SLOT( slotMimetype (TDEIO::Job *, const TQString &) ) ); - enter_loop(); - return m_mimetype; -} - -void NetAccess::slotMimetype( TDEIO::Job *, const TQString & type ) -{ - m_mimetype = type; -} - -TQString NetAccess::fish_executeInternal(const KURL & url, const TQString command, TQWidget* window) -{ - TQString target, remoteTempFileName, resultData; - KURL tempPathUrl; - KTempFile tmpFile; - tmpFile.setAutoDelete( true ); - - if( url.protocol() == "fish" ) - { - // construct remote temp filename - tempPathUrl = url; - remoteTempFileName = tmpFile.name(); - // only need the filename KTempFile adds some KDE specific dirs - // that probably does not exist on the remote side - int pos = remoteTempFileName.findRev('/'); - remoteTempFileName = "/tmp/fishexec_" + remoteTempFileName.mid(pos + 1); - tempPathUrl.setPath( remoteTempFileName ); - bJobOK = true; // success unless further error occurs - TQByteArray packedArgs; - TQDataStream stream( packedArgs, IO_WriteOnly ); - - stream << int('X') << tempPathUrl << command; - - TDEIO::Job * job = TDEIO::special( tempPathUrl, packedArgs, true ); - job->setWindow( window ); - connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), - this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); - enter_loop(); - - // since the TDEIO::special does not provide feedback we need to download the result - if( NetAccess::download( tempPathUrl, target, window ) ) - { - TQFile resultFile( target ); - - if (resultFile.open( IO_ReadOnly )) - { - TQTextStream ts( &resultFile ); - ts.setEncoding( TQTextStream::Locale ); // Locale?? - resultData = ts.read(); - resultFile.close(); - NetAccess::del( tempPathUrl, window ); - } - } - } - else - { - resultData = i18n( "ERROR: Unknown protocol '%1'" ).arg( url.protocol() ); - } - return resultData; -} - -bool NetAccess::synchronousRunInternal( Job* job, TQWidget* window, TQByteArray* data, - KURL* finalURL, TQMap<TQString,TQString>* metaData ) -{ - job->setWindow( window ); - - m_metaData = metaData; - if ( m_metaData ) { - for ( TQMap<TQString, TQString>::iterator it = m_metaData->begin(); it != m_metaData->end(); ++it ) { - job->addMetaData( it.key(), it.data() ); - } - } - - if ( finalURL ) { - SimpleJob *sj = dynamic_cast<SimpleJob*>( job ); - if ( sj ) { - m_url = sj->url(); - } - } - - connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), - this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); - - TQMetaObject *meta = job->metaObject(); - - static const char dataSignal[] = "data(TDEIO::Job*,const " TQBYTEARRAY_OBJECT_NAME_STRING "&)"; - if ( meta->findSignal( dataSignal ) != -1 ) { - connect( job, TQT_SIGNAL(data(TDEIO::Job*,const TQByteArray&)), - this, TQT_SLOT(slotData(TDEIO::Job*,const TQByteArray&)) ); - } - - static const char redirSignal[] = "redirection(TDEIO::Job*,const KURL&)"; - if ( meta->findSignal( redirSignal ) != -1 ) { - connect( job, TQT_SIGNAL(redirection(TDEIO::Job*,const KURL&)), - this, TQT_SLOT(slotRedirection(TDEIO::Job*, const KURL&)) ); - } - - enter_loop(); - - if ( finalURL ) - *finalURL = m_url; - if ( data ) - *data = m_data; - - return bJobOK; -} - -// If a troll sees this, he kills me -void tqt_enter_modal( TQWidget *widget ); -void tqt_leave_modal( TQWidget *widget ); - -void NetAccess::enter_loop() -{ - TQWidget dummy(0,0,(WFlags)(WType_Dialog | WShowModal)); - dummy.setFocusPolicy( TQ_NoFocus ); - tqt_enter_modal(&dummy); - tqApp->enter_loop(); - tqt_leave_modal(&dummy); -} - -void NetAccess::slotResult( TDEIO::Job * job ) -{ - lastErrorCode = job->error(); - bJobOK = !job->error(); - if ( !bJobOK ) - { - if ( !lastErrorMsg ) - lastErrorMsg = new TQString; - *lastErrorMsg = job->errorString(); - } - if ( job->isA("TDEIO::StatJob") ) - m_entry = static_cast<TDEIO::StatJob *>(job)->statResult(); - - if ( m_metaData ) - *m_metaData = job->metaData(); - - tqApp->exit_loop(); -} - -void NetAccess::slotData( TDEIO::Job*, const TQByteArray& data ) -{ - if ( data.isEmpty() ) - return; - - unsigned offset = m_data.size(); - m_data.resize( offset + data.size() ); - std::memcpy( m_data.data() + offset, data.data(), data.size() ); -} - -void NetAccess::slotRedirection( TDEIO::Job*, const KURL& url ) -{ - m_url = url; -} - -#include "netaccess.moc" diff --git a/kio/kio/netaccess.h b/kio/kio/netaccess.h deleted file mode 100644 index 54dd02974..000000000 --- a/kio/kio/netaccess.h +++ /dev/null @@ -1,540 +0,0 @@ -/* - This file is part of the KDE libraries - Copyright (C) 1997 Torben Weis (weis@kde.org) - Copyright (C) 1998 Matthias Ettrich (ettrich@kde.org) - Copyright (C) 1999-2004 David Faure (faure@kde.org) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_netaccess_h -#define __kio_netaccess_h - -#include <tqobject.h> -#include <tqstring.h> -#include <kio/global.h> - -class TQStringList; -class TQWidget; -class KURL; -template<typename T, typename K> class TQMap; - -namespace TDEIO { - - class Job; - - /** - * Net Transparency. - * - * NetAccess allows you to do simple file operation (load, save, - * copy, delete...) without working with TDEIO::Job directly. - * Whereas a TDEIO::Job is asynchronous, meaning that the - * developer has to connect slots for it, TDEIO::NetAccess provides - * synchronous downloads and uploads, as well as temporary file - * creation and removal. The functions appear to be blocking, - * but the Qt event loop continues running while the operations - * are handled. This means that the GUI will not freeze. - * - * This class isn't meant to be used as a class but only as a simple - * namespace for static functions, though an instance of the class - * is built for internal purposes. - * - * Port to kio done by David Faure, faure@kde.org - * - * @short Provides an easy, synchronous interface to KIO file operations. - */ -class TDEIO_EXPORT NetAccess : public TQObject -{ - Q_OBJECT - -public: - /** - * Downloads a file from an arbitrary URL (@p src) to a - * temporary file on the local filesystem (@p target). - * - * If the argument - * for @p target is an empty string, download will generate a - * unique temporary filename in /tmp. Since @p target is a reference - * to TQString you can access this filename easily. Download will - * return true if the download was successful, otherwise false. - * - * Special case: - * If the URL is of kind file:, then no downloading is - * processed but the full filename is returned in @p target. - * That means you @em have to take care about the @p target argument. - * (This is very easy to do, please see the example below.) - * - * Download is synchronous. That means you can use it like - * this, (assuming @p u is a string which represents a URL and your - * application has a loadFile() function): - * - * \code - * TQString tmpFile; - * if( TDEIO::NetAccess::download( u, tmpFile, window ) ) - * { - * loadFile( tmpFile ); - * TDEIO::NetAccess::removeTempFile( tmpFile ); - * } else { - * KMessageBox::error(this, TDEIO::NetAccess::lastErrorString() ); - * } - * \endcode - * - * Of course, your user interface will still process exposure/repaint - * events during the download. - * - * If the download fails, lastError() and lastErrorString() will be set. - * - * @param src URL Reference to the file to download. - * @param target String containing the final local location of the - * file. If you insert an empty string, it will - * return a location in a temporary spot. <B>Note:</B> - * you are responsible for the removal of this file when - * you are finished reading it using removeTempFile. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be - * cached only for a short duration after which the user will - * again be prompted for passwords as needed. - * @return true if successful, false for failure. Use lastErrorString() to - * get the reason it failed. - * - * @see lastErrorString() - * @since 3.2 - */ - static bool download(const KURL& src, TQString & target, TQWidget* window); - - /** - * @deprecated. Use the function above instead. - */ - static bool download(const KURL& src, TQString & target) KDE_DEPRECATED; - - /** - * Removes the specified file if and only if it was created - * by TDEIO::NetAccess as a temporary file for a former download. - * - * Note: This means that if you created your temporary with KTempFile, - * use KTempFile::unlink() or KTempFile::setAutoDelete() to have - * it removed. - * - * @param name Path to temporary file to remove. May not be - * empty. - */ - static void removeTempFile(const TQString& name); - - /** - * Uploads file @p src to URL @p target. - * - * Both must be specified, unlike download. - * Note that this is assumed to be used for saving a file over - * the network, so overwriting is set to true. This is not the - * case with copy. - * - * @param src URL Referencing the file to upload. - * @param target URL containing the final location of the file. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be cached - * only for a short duration after which the user will again be - * prompted for passwords as needed. - * - * @return true if successful, false for failure - * @since 3.2 - */ - static bool upload(const TQString& src, const KURL& target, TQWidget* window); - - /** - * @deprecated. Use the function above instead. - */ - static bool upload(const TQString& src, const KURL& target) KDE_DEPRECATED; - - /** - * Alternative to upload for copying over the network. - * Overwrite is false, so this will fail if @p target exists. - * - * This one takes two URLs and is a direct equivalent - * of TDEIO::file_copy (not TDEIO::copy!). - * It will be renamed file_copy in KDE4, so better use file_copy. - * - * @param src URL Referencing the file to upload. - * @param target URL containing the final location of the file. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be cached - * only for a short duration after which the user will again be - * prompted for passwords as needed. - * - * @return true if successful, false for failure - */ - static bool copy( const KURL& src, const KURL& target, TQWidget* window ); - // KDE4: rename to file_copy - - /** - * @deprecated. Use the function above instead. - */ - static bool copy( const KURL& src, const KURL& target ) KDE_DEPRECATED; - // KDE4: merge with above - - /** - * Full-fledged equivalent of TDEIO::file_copy - */ - static bool file_copy( const KURL& src, const KURL& dest, int permissions=-1, - bool overwrite=false, bool resume=false, TQWidget* window = 0L ); - - /** - * Full-fledged equivalent of TDEIO::file_move. - * Moves or renames *one file*. - * @since 3.2 - */ - static bool file_move( const KURL& src, const KURL& target, int permissions=-1, - bool overwrite=false, bool resume=false, TQWidget* window = 0L ); - - - /** - * Alternative method for copying over the network. - * Overwrite is false, so this will fail if @p target exists. - * - * This one takes two URLs and is a direct equivalent - * of TDEIO::copy!. - * This means that it can copy files and directories alike - * (it should have been named copy()). - * - * @param src URL Referencing the file to upload. - * @param target URL containing the final location of the - * file. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be cached - * only for a short duration after which the user will again be - * prompted for passwords as needed. - * @return true if successful, false for failure - */ - static bool dircopy( const KURL& src, const KURL& target, TQWidget* window ); - - /** - * @deprecated. Use the function above instead. - */ - static bool dircopy( const KURL& src, const KURL& target ) KDE_DEPRECATED; // KDE4: merge - - /** - * Overloaded method, which takes a list of source URLs - */ - static bool dircopy( const KURL::List& src, const KURL& target, TQWidget* window = 0L ); - - /** - * Full-fledged equivalent of TDEIO::move. - * Moves or renames one file or directory. - * @since 3.2 - */ - static bool move( const KURL& src, const KURL& target, TQWidget* window = 0L ); - - /** - * Full-fledged equivalent of TDEIO::move. - * Moves or renames a list of files or directories. - * @since 3.2 - */ - static bool move( const KURL::List& src, const KURL& target, TQWidget* window = 0L ); - - /** - * Tests whether a URL exists. - * - * @param url the URL we are testing - * @param source if true, we want to read from that URL. - * If false, we want to write to it. - * IMPORTANT: see documentation for TDEIO::stat for more details about this. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be - * cached only for a short duration after which the user will - * again be prompted for passwords as needed. - * @return true if the URL exists and we can do the operation specified by - * @p source, false otherwise - * @since 3.2 - */ - static bool exists(const KURL& url, bool source, TQWidget* window); - - /** - * @deprecated. Use the function above instead. - * @since 3.2 - */ - static bool exists(const KURL& url, TQWidget* window) KDE_DEPRECATED; - - /** - * @deprecated. Use the function above instead. - */ - static bool exists(const KURL& url) KDE_DEPRECATED; - - /** - * @deprecated. Use the function above instead. - */ - static bool exists(const KURL& url, bool source) KDE_DEPRECATED; // KDE4: merge - - /** - * Tests whether a URL exists and return information on it. - * - * This is a convenience function for TDEIO::stat - * (it saves creating a slot and testing for the job result). - * - * @param url The URL we are testing. - * @param entry The result of the stat. Iterate over the list - * of atoms to get hold of name, type, size, etc., or use KFileItem. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be - * cached only for a short duration after which the user will - * again be prompted for passwords as needed. - * @return true if successful, false for failure - */ - static bool stat(const KURL& url, TDEIO::UDSEntry & entry, TQWidget* window); - - /** - * @deprecated. Use the function above instead. - */ - static bool stat(const KURL& url, TDEIO::UDSEntry & entry) KDE_DEPRECATED; - - /** - * Tries to map a local URL for the given URL. - * - * This is a convenience function for TDEIO::stat + parsing the - * resulting UDSEntry. - * - * @param url The URL we are testing. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be - * cached only for a short duration after which the user will - * again be prompted for passwords as needed. - * @return a local URL corresponding to the same ressource than the - * original URL, or the original URL if no local URL can be mapped - * @since 3.5 - */ - static KURL mostLocalURL(const KURL& url, TQWidget* window); - - /** - * Deletes a file or a directory in a synchronous way. - * - * This is a convenience function for TDEIO::del - * (it saves creating a slot and testing for the job result). - * - * @param url The file or directory to delete. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be - * cached only for a short duration after which the user will - * again be prompted for passwords as needed. - * @return true on success, false on failure. - */ - static bool del( const KURL & url, TQWidget* window ); - - /** - * @deprecated. Use the function above instead. Passing NULL as the - * additional argument will give the same behaviour, but - * you should try to identify a suitable parent widget - * if at all possible. - */ - static bool del( const KURL & url ) KDE_DEPRECATED; - - /** - * Creates a directory in a synchronous way. - * - * This is a convenience function for @p TDEIO::mkdir - * (it saves creating a slot and testing for the job result). - * - * @param url The directory to create. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be - * cached only for a short duration after which the user will - * again be prompted for passwords as needed. - * @param permissions directory permissions. - * @return true on success, false on failure. - */ - static bool mkdir( const KURL & url, TQWidget* window, int permissions = -1 ); - - /** - * @deprecated. Use the function above instead. Passing NULL as the - * additional argument will give the same behaviour, but - * you should try to identify a suitable parent widget - * if at all possible. - */ - static bool mkdir( const KURL & url, int permissions = -1 ) KDE_DEPRECATED; - - /** - * Executes a remote process via the fish ioslave in a synchronous way. - * - * @param url The remote machine where the command should be executed. - * e.g. fish://someuser\@somehost:sshport/ - * some special cases exist. - * fish://someuser\@localhost/ - * will use su instead of ssh to connect and execute the command. - * fish://someuser\@localhost:port/ - * will use ssh to connect and execute the command. - * @param command The command to be executed. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be - * cached only for a short duration after which the user will - * again be prompted for passwords as needed. - * @return The resulting output of the @p command that is executed. - */ - static TQString fish_execute( const KURL & url, const TQString command, TQWidget* window ); - - /** - * This function executes a job in a synchronous way. - * If a job fetches some data, pass a TQByteArray pointer as data parameter to this function - * and after the function returns it will contain all the data fetched by this job. - * - * <code> - * TDEIO::Job *job = TDEIO::get( url, false, false ); - * TQMap<TQString, TQString> metaData; - * metaData.insert( "PropagateHttpHeader", "true" ); - * if ( NetAccess::synchronousRun( job, 0, &data, &url, &metaData ) ) { - * TQString responseHeaders = metaData[ "HTTP-Headers" ]; - * kdDebug()<<"Response header = "<< responseHeaders << endl; - * } - * </code> - * - * @param job job which the function will run. Note that after this function - * finishes running, job is deleted and you can't access it anymore! - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be - * cached only for a short duration after which the user will - * again be prompted for passwords as needed. - * @param data if passed and relevant to this job then it will contain the data - * that was fetched by the job - * @param finalURL if passed will contain the final url of this job (it might differ - * from the one it was created with if there was a redirection) - * @param metaData you can pass a pointer to the map with meta data you wish to - * set on the job. After the job finishes this map will hold all the - * meta data from the job. - * - * @return true on success, false on failure. - * - * @since 3.4 - */ - static bool synchronousRun( Job* job, TQWidget* window, TQByteArray* data=0, - KURL* finalURL=0, TQMap<TQString,TQString>* metaData=0 ); - - /** - * @internal - * This function is not implemented!? - * (only mimetypeInternal) - * - * Determines the mimetype of a given URL. - * - * This is a convenience function for TDEIO::mimetype. You - * should call this only when really necessary. - * KMimeType::findByURL can determine extension a lot faster, but - * less reliably for remote files. Only when findByURL() returns - * unknown (application/octet-stream) then this one should be - * used. - * - * @param url The URL whose mimetype we are interested in. - * @param window main window associated with this job. This is used to - * automatically cache and discard authentication information - * as needed. If NULL, authentication information will be - * cached only for a short duration after which the user will - * again be prompted for passwords as needed. - * @return The mimetype name. - */ - static TQString mimetype( const KURL & url, TQWidget* window ); - - /** - * @deprecated. Use the function above instead. Passing NULL as the - * additional argument will give the same behaviour, but - * you should try to identify a suitable parent widget - * if at all possible. - */ - static TQString mimetype( const KURL & url ) KDE_DEPRECATED; - - /** - * Returns the error string for the last job, in case it failed. - * Note that this is already translated. - * @return the last error string, or TQString::null - */ - static TQString lastErrorString() { return lastErrorMsg ? *lastErrorMsg : TQString::null; } - - /** - * Returns the error code for the last job, in case it failed. - * @return the last error code - * @since 3.3 - */ - static int lastError() { return lastErrorCode; } - -private: - /** - * Private constructor - */ - NetAccess() : m_metaData(0), d(0) {} - - /** - * Private destructor - */ - ~NetAccess() {} - - /** - * Internal methods - */ - bool filecopyInternal(const KURL& src, const KURL& target, int permissions, - bool overwrite, bool resume, TQWidget* window, bool move); - bool dircopyInternal(const KURL::List& src, const KURL& target, - TQWidget* window, bool move); - bool statInternal(const KURL & url, int details, bool source, TQWidget* window = 0); - - bool delInternal(const KURL & url, TQWidget* window = 0); - bool mkdirInternal(const KURL & url, int permissions, TQWidget* window = 0); - TQString fish_executeInternal(const KURL & url, const TQString command, TQWidget* window = 0); - bool synchronousRunInternal( Job* job, TQWidget* window, TQByteArray* data, - KURL* finalURL, TQMap<TQString,TQString>* metaData ); - - TQString mimetypeInternal(const KURL & url, TQWidget* window = 0); - void enter_loop(); - - /** - * List of temporary files - */ - static TQStringList* tmpfiles; - - static TQString* lastErrorMsg; - static int lastErrorCode; - - friend class I_like_this_class; - -private slots: - void slotResult( TDEIO::Job * job ); - void slotMimetype( TDEIO::Job * job, const TQString & type ); - void slotData( TDEIO::Job*, const TQByteArray& ); - void slotRedirection( TDEIO::Job*, const KURL& ); - -private: - UDSEntry m_entry; - TQString m_mimetype; - TQByteArray m_data; - KURL m_url; - TQMap<TQString, TQString> *m_metaData; - - /** - * Whether the download succeeded or not - */ - bool bJobOK; - -private: - class NetAccessPrivate* d; // not really needed, the ctor is private already. -}; - -} - -#endif diff --git a/kio/kio/observer.cpp b/kio/kio/observer.cpp deleted file mode 100644 index 347db9df9..000000000 --- a/kio/kio/observer.cpp +++ /dev/null @@ -1,417 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Matej Koss <koss@miesto.sk> - David Faure <faure@kde.org> - - $Id$ - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <assert.h> - -#include <kdebug.h> -#include <kapplication.h> -#include <dcopclient.h> -#include <kurl.h> - -#include "jobclasses.h" -#include "observer.h" - -#include "uiserver_stub.h" - -#include "passdlg.h" -#include "slavebase.h" -#include "observer_stub.h" -#include <kmessagebox.h> -#include <ksslinfodlg.h> -#include <ksslcertdlg.h> -#include <ksslcertificate.h> -#include <ksslcertchain.h> -#include <klocale.h> - -using namespace TDEIO; - -template class TQIntDict<TDEIO::Job>; - -Observer * Observer::s_pObserver = 0L; - -const int KDEBUG_OBSERVER = 7007; // Should be 7028 - -Observer::Observer() : DCOPObject("TDEIO::Observer") -{ - // Register app as able to receive DCOP messages - if (kapp && !kapp->dcopClient()->isAttached()) - { - kapp->dcopClient()->attach(); - } - - if ( !kapp->dcopClient()->isApplicationRegistered( "kio_uiserver" ) ) - { - kdDebug(KDEBUG_OBSERVER) << "Starting kio_uiserver" << endl; - TQString error; - int ret = TDEApplication::startServiceByDesktopPath( "kio_uiserver.desktop", - TQStringList(), &error ); - if ( ret > 0 ) - { - kdError() << "Couldn't start kio_uiserver from kio_uiserver.desktop: " << error << endl; - } else - kdDebug(KDEBUG_OBSERVER) << "startServiceByDesktopPath returned " << ret << endl; - - } - if ( !kapp->dcopClient()->isApplicationRegistered( "kio_uiserver" ) ) - kdDebug(KDEBUG_OBSERVER) << "The application kio_uiserver is STILL NOT REGISTERED" << endl; - else - kdDebug(KDEBUG_OBSERVER) << "kio_uiserver registered" << endl; - - m_uiserver = new UIServer_stub( "kio_uiserver", "UIServer" ); -} - -int Observer::newJob( TDEIO::Job * job, bool showProgress ) -{ - // Tell the UI Server about this new job, and give it the application id - // at the same time - int progressId = m_uiserver->newJob( kapp->dcopClient()->appId(), showProgress ); - - // Keep the result in a dict - m_dctJobs.insert( progressId, job ); - - return progressId; -} - -void Observer::jobFinished( int progressId ) -{ - m_uiserver->jobFinished( progressId ); - m_dctJobs.remove( progressId ); -} - -void Observer::killJob( int progressId ) -{ - TDEIO::Job * job = m_dctJobs[ progressId ]; - if (!job) - { - kdWarning() << "Can't find job to kill ! There is no job with progressId=" << progressId << " in this process" << endl; - return; - } - job->kill( false /* not quietly */ ); -} - -MetaData Observer::metadata( int progressId ) -{ - TDEIO::Job * job = m_dctJobs[ progressId ]; - assert(job); - return job->metaData(); -} - -void Observer::slotTotalSize( TDEIO::Job* job, TDEIO::filesize_t size ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotTotalSize " << job << " " << TDEIO::number(size) << endl; - m_uiserver->totalSize64( job->progressId(), size ); -} - -void Observer::slotTotalFiles( TDEIO::Job* job, unsigned long files ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotTotalFiles " << job << " " << files << endl; - m_uiserver->totalFiles( job->progressId(), files ); -} - -void Observer::slotTotalDirs( TDEIO::Job* job, unsigned long dirs ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotTotalDirs " << job << " " << dirs << endl; - m_uiserver->totalDirs( job->progressId(), dirs ); -} - -void Observer::slotProcessedSize( TDEIO::Job* job, TDEIO::filesize_t size ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotProcessedSize " << job << " " << job->progressId() << " " << TDEIO::number(size) << endl; - m_uiserver->processedSize64( job->progressId(), size ); -} - -void Observer::slotProcessedFiles( TDEIO::Job* job, unsigned long files ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotProcessedFiles " << job << " " << files << endl; - m_uiserver->processedFiles( job->progressId(), files ); -} - -void Observer::slotProcessedDirs( TDEIO::Job* job, unsigned long dirs ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotProcessedDirs " << job << " " << dirs << endl; - m_uiserver->processedDirs( job->progressId(), dirs ); -} - -void Observer::slotSpeed( TDEIO::Job* job, unsigned long speed ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotSpeed " << job << " " << speed << endl; - m_uiserver->speed( job->progressId(), speed ); -} - -void Observer::slotPercent( TDEIO::Job* job, unsigned long percent ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotPercent " << job << " " << percent << endl; - m_uiserver->percent( job->progressId(), percent ); -} - -void Observer::slotInfoMessage( TDEIO::Job* job, const TQString & msg ) -{ - m_uiserver->infoMessage( job->progressId(), msg ); -} - -void Observer::slotCopying( TDEIO::Job* job, const KURL& from, const KURL& to ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotCopying " << job << " " << from.url() << " " << to.url() << endl; - m_uiserver->copying( job->progressId(), from, to ); -} - -void Observer::slotMoving( TDEIO::Job* job, const KURL& from, const KURL& to ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotMoving " << job << " " << from.url() << " " << to.url() << endl; - m_uiserver->moving( job->progressId(), from, to ); -} - -void Observer::slotDeleting( TDEIO::Job* job, const KURL& url ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotDeleting " << job << " " << url.url() << endl; - m_uiserver->deleting( job->progressId(), url ); -} - -void Observer::slotTransferring( TDEIO::Job* job, const KURL& url ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotTransferring " << job << " " << url.url() << endl; - m_uiserver->transferring( job->progressId(), url ); -} - -void Observer::slotCreatingDir( TDEIO::Job* job, const KURL& dir ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotCreatingDir " << job << " " << dir.url() << endl; - m_uiserver->creatingDir( job->progressId(), dir ); -} - -void Observer::slotCanResume( TDEIO::Job* job, TDEIO::filesize_t offset ) -{ - //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotCanResume " << job << " " << TDEIO::number(offset) << endl; - m_uiserver->canResume64( job->progressId(), offset ); -} - -void Observer::stating( TDEIO::Job* job, const KURL& url ) -{ - m_uiserver->stating( job->progressId(), url ); -} - -void Observer::mounting( TDEIO::Job* job, const TQString & dev, const TQString & point ) -{ - m_uiserver->mounting( job->progressId(), dev, point ); -} - -void Observer::unmounting( TDEIO::Job* job, const TQString & point ) -{ - m_uiserver->unmounting( job->progressId(), point ); -} - -bool Observer::openPassDlg( const TQString& prompt, TQString& user, - TQString& pass, bool readOnly ) -{ - AuthInfo info; - info.prompt = prompt; - info.username = user; - info.password = pass; - info.readOnly = readOnly; - bool result = openPassDlg ( info ); - if ( result ) - { - user = info.username; - pass = info.password; - } - return result; -} - -bool Observer::openPassDlg( TDEIO::AuthInfo& info ) -{ - kdDebug(KDEBUG_OBSERVER) << "Observer::openPassDlg: User= " << info.username - << ", Message= " << info.prompt << endl; - int result = TDEIO::PasswordDialog::getNameAndPassword( info.username, info.password, - &info.keepPassword, info.prompt, - info.readOnly, info.caption, - info.comment, info.commentLabel ); - if ( result == TQDialog::Accepted ) - { - info.setModified( true ); - return true; - } - return false; -} - -int Observer::messageBox( int progressId, int type, const TQString &text, - const TQString &caption, const TQString &buttonYes, - const TQString &buttonNo ) -{ - return messageBox( progressId, type, text, caption, buttonYes, buttonNo, TQString::null ); -} - -int Observer::messageBox( int progressId, int type, const TQString &text, - const TQString &caption, const TQString &buttonYes, - const TQString &buttonNo, const TQString &dontAskAgainName ) -{ - kdDebug() << "Observer::messageBox " << type << " " << text << " - " << caption << endl; - int result = -1; - TDEConfig *config = new TDEConfig("kioslaverc"); - KMessageBox::setDontShowAskAgainConfig(config); - - switch (type) { - case TDEIO::SlaveBase::QuestionYesNo: - result = KMessageBox::questionYesNo( 0L, // parent ? - text, caption, buttonYes, buttonNo, dontAskAgainName ); - break; - case TDEIO::SlaveBase::WarningYesNo: - result = KMessageBox::warningYesNo( 0L, // parent ? - text, caption, buttonYes, buttonNo, dontAskAgainName ); - break; - case TDEIO::SlaveBase::WarningContinueCancel: - result = KMessageBox::warningContinueCancel( 0L, // parent ? - text, caption, buttonYes, dontAskAgainName ); - break; - case TDEIO::SlaveBase::WarningYesNoCancel: - result = KMessageBox::warningYesNoCancel( 0L, // parent ? - text, caption, buttonYes, buttonNo, dontAskAgainName ); - break; - case TDEIO::SlaveBase::Information: - KMessageBox::information( 0L, // parent ? - text, caption, dontAskAgainName ); - result = 1; // whatever - break; - case TDEIO::SlaveBase::SSLMessageBox: - { - TQCString observerAppId = caption.utf8(); // hack, see slaveinterface.cpp - // Contact the object "TDEIO::Observer" in the application <appId> - // Yes, this could be the same application we are, but not necessarily. - Observer_stub observer( observerAppId, "TDEIO::Observer" ); - - TDEIO::MetaData meta = observer.metadata( progressId ); - KSSLInfoDlg *kid = new KSSLInfoDlg(meta["ssl_in_use"].upper()=="TRUE", 0L /*parent?*/, 0L, true); - KSSLCertificate *x = KSSLCertificate::fromString(meta["ssl_peer_certificate"].local8Bit()); - if (x) { - // Set the chain back onto the certificate - TQStringList cl = - TQStringList::split(TQString("\n"), meta["ssl_peer_chain"]); - TQPtrList<KSSLCertificate> ncl; - - ncl.setAutoDelete(true); - for (TQStringList::Iterator it = cl.begin(); it != cl.end(); ++it) { - KSSLCertificate *y = KSSLCertificate::fromString((*it).local8Bit()); - if (y) ncl.append(y); - } - - if (ncl.count() > 0) - x->chain().setChain(ncl); - - kid->setup( x, - meta["ssl_peer_ip"], - text, // the URL - meta["ssl_cipher"], - meta["ssl_cipher_desc"], - meta["ssl_cipher_version"], - meta["ssl_cipher_used_bits"].toInt(), - meta["ssl_cipher_bits"].toInt(), - KSSLCertificate::KSSLValidation(meta["ssl_cert_state"].toInt())); - kdDebug(7024) << "Showing SSL Info dialog" << endl; - kid->exec(); - delete x; - kdDebug(7024) << "SSL Info dialog closed" << endl; - } else { - KMessageBox::information( 0L, // parent ? - i18n("The peer SSL certificate appears to be corrupt."), i18n("SSL") ); - } - // This doesn't have to get deleted. It deletes on it's own. - result = 1; // whatever - break; - } - default: - kdWarning() << "Observer::messageBox: unknown type " << type << endl; - result = 0; - break; - } - KMessageBox::setDontShowAskAgainConfig(0); - delete config; - return result; -#if 0 - TQByteArray data, replyData; - TQCString replyType; - TQDataStream arg( data, IO_WriteOnly ); - arg << progressId; - arg << type; - arg << text; - arg << caption; - arg << buttonYes; - arg << buttonNo; - if ( kapp->dcopClient()->call( "kio_uiserver", "UIServer", "messageBox(int,int,TQString,TQString,TQString,TQString)", data, replyType, replyData, true ) - && replyType == "int" ) - { - int result; - TQDataStream _reply_stream( replyData, IO_ReadOnly ); - _reply_stream >> result; - kdDebug(KDEBUG_OBSERVER) << "Observer::messageBox got result " << result << endl; - return result; - } - kdDebug(KDEBUG_OBSERVER) << "Observer::messageBox call failed" << endl; - return 0; -#endif -} - -RenameDlg_Result Observer::open_RenameDlg( TDEIO::Job* job, - const TQString & caption, - const TQString& src, const TQString & dest, - RenameDlg_Mode mode, TQString& newDest, - TDEIO::filesize_t sizeSrc, - TDEIO::filesize_t sizeDest, - time_t ctimeSrc, - time_t ctimeDest, - time_t mtimeSrc, - time_t mtimeDest - ) -{ - kdDebug(KDEBUG_OBSERVER) << "Observer::open_RenameDlg job=" << job << endl; - if (job) - kdDebug(KDEBUG_OBSERVER) << " progressId=" << job->progressId() << endl; - // Hide existing dialog box if any - if (job && job->progressId()) - m_uiserver->setJobVisible( job->progressId(), false ); - // We now do it in process => KDE4: move this code out of Observer (back to job.cpp), so that - // opening the rename dialog doesn't start uiserver for nothing if progressId=0 (e.g. F2 in konq) - RenameDlg_Result res = TDEIO::open_RenameDlg( caption, src, dest, mode, - newDest, sizeSrc, sizeDest, - ctimeSrc, ctimeDest, mtimeSrc, - mtimeDest ); - if (job && job->progressId()) - m_uiserver->setJobVisible( job->progressId(), true ); - return res; -} - -SkipDlg_Result Observer::open_SkipDlg( TDEIO::Job* job, - bool _multi, - const TQString& _error_text ) -{ - kdDebug(KDEBUG_OBSERVER) << "Observer::open_SkipDlg job=" << job << " progressId=" << job->progressId() << endl; - // Hide existing dialog box if any - if (job && job->progressId()) - m_uiserver->setJobVisible( job->progressId(), false ); - // We now do it in process. So this method is a useless wrapper around TDEIO::open_RenameDlg. - SkipDlg_Result res = TDEIO::open_SkipDlg( _multi, _error_text ); - if (job && job->progressId()) - m_uiserver->setJobVisible( job->progressId(), true ); - return res; -} - -void Observer::virtual_hook( int id, void* data ) -{ DCOPObject::virtual_hook( id, data ); } - -#include "observer.moc" diff --git a/kio/kio/observer.h b/kio/kio/observer.h deleted file mode 100644 index 1869e5638..000000000 --- a/kio/kio/observer.h +++ /dev/null @@ -1,213 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Matej Koss <koss@miesto.sk> - David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __kio_observer_h__ -#define __kio_observer_h__ - -#include <tqobject.h> -#include <dcopobject.h> -#include <tqintdict.h> - -#include <kio/global.h> -#include <kio/authinfo.h> -#include "kio/job.h" -#include "kio/skipdlg.h" -#include "kio/renamedlg.h" - -class UIServer_stub; -class KURL; - -namespace TDEIO { - class Job; -} - -/** - * Observer for TDEIO::Job progress information. - * - * This class, of which there is always only one instance, - * "observes" what jobs do and forwards this information - * to the progress-info server. - * - * It is a DCOP object so that the UI server can call the - * kill method when the user presses Cancel. - * - * Usually jobs are automatically registered by the - * TDEIO::Scheduler, so you do not have to care about that. - * - * @short Observer for TDEIO::Job progress information - * @author David Faure <faure@kde.org> - */ -class TDEIO_EXPORT Observer : public TQObject, public DCOPObject { - - K_DCOP - Q_OBJECT - -public: - - /** - * Returns the unique observer object. - * @return the observer object - */ - static Observer * self() { - if (!s_pObserver) s_pObserver = new Observer; - return s_pObserver; - } - - /** - * Called by the job constructor, to signal its presence to the - * UI Server. - * @param job the new job - * @param showProgress true to show progress, false otherwise - * @return the progress ID assigned by the UI Server to the Job. - */ - int newJob( TDEIO::Job * job, bool showProgress ); - - /** - * Called by the job destructor, to tell the UI Server that - * the job ended. - * @param progressId the progress ID of the job, as returned by newJob() - */ - void jobFinished( int progressId ); - - /** - * @deprecated use TDEIO::AutoInfo - */ - bool openPassDlg( const TQString& prompt, TQString& user, TQString& pass, - bool readOnly ); - - /** - * Opens a password dialog. - * @param info the authentication information - * @return true if successful ("ok" clicked), false otherwise - */ - bool openPassDlg( TDEIO::AuthInfo& info ); - - /** - * Popup a message box. See TDEIO::SlaveBase. - * This doesn't use DCOP anymore, it shows the dialog in the application's process. - * Otherwise, other apps would block when trying to communicate with UIServer. - * @param progressId the progress ID of the job, as returned by newJob() - * @param type the type of the message box - * @param text the text to show - * @param caption the window caption - * @param buttonYes the text of the "Yes" button - * @param buttonNo the text of the "No button - */ - static int messageBox( int progressId, int type, const TQString &text, const TQString &caption, - const TQString &buttonYes, const TQString &buttonNo ); - - /** - * Popup a message box. See TDEIO::SlaveBase. - * This doesn't use DCOP anymore, it shows the dialog in the application's process. - * Otherwise, other apps would block when trying to communicate with UIServer. - * @param progressId the progress ID of the job, as returned by newJob() - * @param type the type of the message box - * @param text the text to show - * @param caption the window caption - * @param buttonYes the text of the "Yes" button - * @param buttonNo the text of the "No button - * @param dontAskAgainName A checkbox is added with which further confirmation can be turned off. - * The string is used to lookup and store the setting in kioslaverc. - * @since 3.3 - */ - static int messageBox( int progressId, int type, const TQString &text, const TQString &caption, - const TQString &buttonYes, const TQString &buttonNo, const TQString &dontAskAgainName ); - - /** - * @internal - * See renamedlg.h - */ - TDEIO::RenameDlg_Result open_RenameDlg( TDEIO::Job * job, - const TQString & caption, - const TQString& src, const TQString & dest, - TDEIO::RenameDlg_Mode mode, - TQString& newDest, - TDEIO::filesize_t sizeSrc = (TDEIO::filesize_t) -1, - TDEIO::filesize_t sizeDest = (TDEIO::filesize_t) -1, - time_t ctimeSrc = (time_t) -1, - time_t ctimeDest = (time_t) -1, - time_t mtimeSrc = (time_t) -1, - time_t mtimeDest = (time_t) -1 - ); - - /** - * @internal - * See skipdlg.h - */ - TDEIO::SkipDlg_Result open_SkipDlg( TDEIO::Job * job, - bool multi, - const TQString & error_text ); - -k_dcop: - /** - * Called by the UI Server (using DCOP) if the user presses cancel. - * @param progressId the progress ID of the job, as returned by newJob() - */ - void killJob( int progressId ); - - /** - * Called by the UI Server (using DCOP) to get all the metadata of the job - * @param progressId the progress IDof the job, as returned by newJob() - */ - TDEIO::MetaData metadata( int progressId ); - -protected: - - static Observer * s_pObserver; - Observer(); - ~Observer() {} - - UIServer_stub * m_uiserver; - - TQIntDict< TDEIO::Job > m_dctJobs; - -public slots: - - void slotTotalSize( TDEIO::Job*, TDEIO::filesize_t size ); - void slotTotalFiles( TDEIO::Job*, unsigned long files ); - void slotTotalDirs( TDEIO::Job*, unsigned long dirs ); - - void slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t size ); - void slotProcessedFiles( TDEIO::Job*, unsigned long files ); - void slotProcessedDirs( TDEIO::Job*, unsigned long dirs ); - - void slotSpeed( TDEIO::Job*, unsigned long speed ); - void slotPercent( TDEIO::Job*, unsigned long percent ); - void slotInfoMessage( TDEIO::Job*, const TQString & msg ); - - void slotCopying( TDEIO::Job*, const KURL& from, const KURL& to ); - void slotMoving( TDEIO::Job*, const KURL& from, const KURL& to ); - void slotDeleting( TDEIO::Job*, const KURL& url ); - /// @since 3.1 - void slotTransferring( TDEIO::Job*, const KURL& url ); - void slotCreatingDir( TDEIO::Job*, const KURL& dir ); - // currently unused - void slotCanResume( TDEIO::Job*, TDEIO::filesize_t offset ); - -public: - void stating( TDEIO::Job*, const KURL& url ); - void mounting( TDEIO::Job*, const TQString & dev, const TQString & point ); - void unmounting( TDEIO::Job*, const TQString & point ); -protected: - virtual void virtual_hook( int id, void* data ); -private: - class ObserverPrivate* d; -}; - -// -*- mode: c++; c-basic-offset: 2 -*- -#endif diff --git a/kio/kio/passdlg.cpp b/kio/kio/passdlg.cpp deleted file mode 100644 index 1b5679028..000000000 --- a/kio/kio/passdlg.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "passdlg.h" - -#include <tqapplication.h> -#include <tqcheckbox.h> -#include <tqhbox.h> -#include <tqlabel.h> -#include <tqlayout.h> -#include <tqsimplerichtext.h> -#include <tqstylesheet.h> - -#include <kcombobox.h> -#include <kconfig.h> -#include <kiconloader.h> -#include <klineedit.h> -#include <klocale.h> -#include <kstandarddirs.h> - -using namespace TDEIO; - -struct PasswordDialog::PasswordDialogPrivate -{ - TQGridLayout *layout; - TQLineEdit* userEdit; - KLineEdit* passEdit; - TQLabel* userNameLabel; - TQLabel* prompt; - TQCheckBox* keepCheckBox; - TQMap<TQString,TQString> knownLogins; - KComboBox* userEditCombo; - TQHBox* userNameHBox; - - bool keep; - short unsigned int nRow; -}; - -PasswordDialog::PasswordDialog( const TQString& prompt, const TQString& user, - bool enableKeep, bool modal, TQWidget* parent, - const char* name ) - :KDialogBase( parent, name, modal, i18n("Password"), Ok|Cancel, Ok, true) -{ - init ( prompt, user, enableKeep ); -} - -PasswordDialog::~PasswordDialog() -{ - delete d; -} - -void PasswordDialog::init( const TQString& prompt, const TQString& user, - bool enableKeep ) -{ - TQWidget *main = makeMainWidget(); - - d = new PasswordDialogPrivate; - d->keep = false; - d->nRow = 0; - d->keepCheckBox = 0; - - TDEConfig* cfg = TDEGlobal::config(); - TDEConfigGroupSaver saver( cfg, "Passwords" ); - - d->layout = new TQGridLayout( main, 9, 3, spacingHint(), marginHint()); - d->layout->addColSpacing(1, 5); - - // Row 0: pixmap prompt - TQLabel* lbl; - TQPixmap pix( TDEGlobal::iconLoader()->loadIcon( "password", KIcon::NoGroup, KIcon::SizeHuge, 0, 0, true)); - if ( !pix.isNull() ) - { - lbl = new TQLabel( main ); - lbl->setPixmap( pix ); - lbl->setAlignment( Qt::AlignLeft|Qt::AlignVCenter ); - lbl->setFixedSize( lbl->sizeHint() ); - d->layout->addWidget( lbl, 0, 0, Qt::AlignLeft ); - } - d->prompt = new TQLabel( main ); - d->prompt->setAlignment( Qt::AlignLeft|Qt::AlignVCenter|TQt::WordBreak ); - d->layout->addWidget( d->prompt, 0, 2, Qt::AlignLeft ); - if ( prompt.isEmpty() ) - setPrompt( i18n( "You need to supply a username and a password" ) ); - else - setPrompt( prompt ); - - // Row 1: Row Spacer - d->layout->addRowSpacing( 1, 7 ); - - // Row 2-3: Reserved for an additional comment - - // Row 4: Username field - d->userNameLabel = new TQLabel( i18n("&Username:"), main ); - d->userNameLabel->setAlignment( Qt::AlignVCenter | Qt::AlignLeft ); - d->userNameLabel->setFixedSize( d->userNameLabel->sizeHint() ); - d->userNameHBox = new TQHBox( main ); - - d->userEdit = new KLineEdit( d->userNameHBox ); - TQSize s = d->userEdit->sizeHint(); - d->userEdit->setFixedHeight( s.height() ); - d->userEdit->setMinimumWidth( s.width() ); - d->userNameLabel->setBuddy( d->userEdit ); - d->layout->addWidget( d->userNameLabel, 4, 0 ); - d->layout->addWidget( d->userNameHBox, 4, 2 ); - - // Row 5: Row spacer - d->layout->addRowSpacing( 5, 4 ); - - // Row 6: Password field - lbl = new TQLabel( i18n("&Password:"), main ); - lbl->setAlignment( Qt::AlignVCenter | Qt::AlignLeft ); - lbl->setFixedSize( lbl->sizeHint() ); - TQHBox* hbox = new TQHBox( main ); - d->passEdit = new KLineEdit( hbox ); - if ( cfg->readEntry("EchoMode", "OneStar") == "NoEcho" ) - d->passEdit->setEchoMode( TQLineEdit::NoEcho ); - else - d->passEdit->setEchoMode( TQLineEdit::Password ); - s = d->passEdit->sizeHint(); - d->passEdit->setFixedHeight( s.height() ); - d->passEdit->setMinimumWidth( s.width() ); - lbl->setBuddy( d->passEdit ); - d->layout->addWidget( lbl, 6, 0 ); - d->layout->addWidget( hbox, 6, 2 ); - - if ( enableKeep ) - { - // Row 7: Add spacer - d->layout->addRowSpacing( 7, 4 ); - // Row 8: Keep Password - hbox = new TQHBox( main ); - d->keepCheckBox = new TQCheckBox( i18n("&Keep password"), hbox ); - d->keepCheckBox->setFixedSize( d->keepCheckBox->sizeHint() ); - d->keep = cfg->readBoolEntry("Keep", false ); - d->keepCheckBox->setChecked( d->keep ); - connect(d->keepCheckBox, TQT_SIGNAL(toggled( bool )), TQT_SLOT(slotKeep( bool ))); - d->layout->addWidget( hbox, 8, 2 ); - } - - // Configure necessary key-bindings and connect necessar slots and signals - connect( d->userEdit, TQT_SIGNAL(returnPressed()), d->passEdit, TQT_SLOT(setFocus()) ); - connect( d->passEdit, TQT_SIGNAL(returnPressed()), TQT_SLOT(slotOk()) ); - - if ( !user.isEmpty() ) - { - d->userEdit->setText( user ); - d->passEdit->setFocus(); - } - else - d->userEdit->setFocus(); - - d->userEditCombo = 0; -// setFixedSize( sizeHint() ); -} - -TQString PasswordDialog::username() const -{ - return d->userEdit->text(); -} - -TQString PasswordDialog::password() const -{ - return d->passEdit->text(); -} - -void PasswordDialog::setKeepPassword( bool b ) -{ - if ( d->keepCheckBox ) - d->keepCheckBox->setChecked( b ); -} - -bool PasswordDialog::keepPassword() const -{ - return d->keep; -} - -static void calculateLabelSize(TQLabel *label) -{ - TQString qt_text = label->text(); - - int pref_width = 0; - int pref_height = 0; - // Calculate a proper size for the text. - { - TQSimpleRichText rt(qt_text, label->font()); - TQRect d = TDEGlobalSettings::desktopGeometry(label->topLevelWidget()); - - pref_width = d.width() / 4; - rt.setWidth(pref_width-10); - int used_width = rt.widthUsed(); - pref_height = rt.height(); - if (used_width <= pref_width) - { - while(true) - { - int new_width = (used_width * 9) / 10; - rt.setWidth(new_width-10); - int new_height = rt.height(); - if (new_height > pref_height) - break; - used_width = rt.widthUsed(); - if (used_width > new_width) - break; - } - pref_width = used_width; - } - else - { - if (used_width > (pref_width *2)) - pref_width = pref_width *2; - else - pref_width = used_width; - } - } - label->setFixedSize(TQSize(pref_width+10, pref_height)); -} - -void PasswordDialog::addCommentLine( const TQString& label, - const TQString comment ) -{ - if (d->nRow > 0) - return; - - TQWidget *main = mainWidget(); - - TQLabel* lbl = new TQLabel( label, main); - lbl->setAlignment( Qt::AlignVCenter|Qt::AlignRight ); - lbl->setFixedSize( lbl->sizeHint() ); - d->layout->addWidget( lbl, d->nRow+2, 0, Qt::AlignLeft ); - lbl = new TQLabel( comment, main); - lbl->setAlignment( Qt::AlignVCenter|Qt::AlignLeft|TQt::WordBreak ); - calculateLabelSize(lbl); - d->layout->addWidget( lbl, d->nRow+2, 2, Qt::AlignLeft ); - d->layout->addRowSpacing( 3, 10 ); // Add a spacer - d->nRow++; -} - -void PasswordDialog::slotKeep( bool keep ) -{ - d->keep = keep; -} - -static TQString qrichtextify( const TQString& text ) -{ - if ( text.isEmpty() || text[0] == '<' ) - return text; - - TQStringList lines = TQStringList::split('\n', text); - for(TQStringList::Iterator it = lines.begin(); it != lines.end(); ++it) - { - *it = TQStyleSheet::convertFromPlainText( *it, TQStyleSheetItem::WhiteSpaceNormal ); - } - - return lines.join(TQString::null); -} - -void PasswordDialog::setPrompt(const TQString& prompt) -{ - TQString text = qrichtextify(prompt); - d->prompt->setText(text); - calculateLabelSize(d->prompt); -} - -void PasswordDialog::setPassword(const TQString &p) -{ - d->passEdit->setText(p); -} - -void PasswordDialog::setUserReadOnly( bool readOnly ) -{ - d->userEdit->setReadOnly( readOnly ); - if ( readOnly && d->userEdit->hasFocus() ) - d->passEdit->setFocus(); -} - -void PasswordDialog::setKnownLogins( const TQMap<TQString, TQString>& knownLogins ) -{ - const int nr = knownLogins.count(); - if ( nr == 0 ) - return; - if ( nr == 1 ) { - d->userEdit->setText( knownLogins.begin().key() ); - setPassword( knownLogins.begin().data() ); - return; - } - - Q_ASSERT( !d->userEdit->isReadOnly() ); - if ( !d->userEditCombo ) { - delete d->userEdit; - d->userEditCombo = new KComboBox( true, d->userNameHBox ); - d->userEdit = d->userEditCombo->lineEdit(); - TQSize s = d->userEditCombo->sizeHint(); - d->userEditCombo->setFixedHeight( s.height() ); - d->userEditCombo->setMinimumWidth( s.width() ); - d->userNameLabel->setBuddy( d->userEditCombo ); - d->layout->addWidget( d->userNameHBox, 4, 2 ); - } - - d->knownLogins = knownLogins; - d->userEditCombo->insertStringList( knownLogins.keys() ); - d->userEditCombo->setFocus(); - - connect( d->userEditCombo, TQT_SIGNAL( activated( const TQString& ) ), - this, TQT_SLOT( slotActivated( const TQString& ) ) ); -} - -void PasswordDialog::slotActivated( const TQString& userName ) -{ - TQMap<TQString, TQString>::ConstIterator it = d->knownLogins.find( userName ); - if ( it != d->knownLogins.end() ) - setPassword( it.data() ); -} - - -int PasswordDialog::getNameAndPassword( TQString& user, TQString& pass, bool* keep, - const TQString& prompt, bool readOnly, - const TQString& caption, - const TQString& comment, - const TQString& label ) -{ - PasswordDialog* dlg; - if( keep ) - dlg = new PasswordDialog( prompt, user, (*keep) ); - else - dlg = new PasswordDialog( prompt, user ); - - if ( !caption.isEmpty() ) - dlg->setPlainCaption( caption ); - else - dlg->setPlainCaption( i18n("Authorization Dialog") ); - - if ( !comment.isEmpty() ) - dlg->addCommentLine( label, comment ); - - if ( readOnly ) - dlg->setUserReadOnly( readOnly ); - - int ret = dlg->exec(); - if ( ret == Accepted ) - { - user = dlg->username(); - pass = dlg->password(); - if ( keep ) { (*keep) = dlg->keepPassword(); } - } - delete dlg; - return ret; - } - -void PasswordDialog::virtual_hook( int id, void* data ) -{ KDialogBase::virtual_hook( id, data ); } - -#include "passdlg.moc" diff --git a/kio/kio/passdlg.h b/kio/kio/passdlg.h deleted file mode 100644 index 864023398..000000000 --- a/kio/kio/passdlg.h +++ /dev/null @@ -1,175 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - Copyright (C) 2000 Dawit Alemayehu <adawit@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; see the file COPYING.LIB. If - not, write to the Free Software Foundation, Inc., 51 Franklin Street, - Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_pass_dlg_h__ -#define __kio_pass_dlg_h__ - -#include <kdialogbase.h> - -class TQGridLayout; - -namespace TDEIO { - -/** - * A dialog for requesting a login and a password from the end user. - * - * KIO-Slave authors are encouraged to use SlaveBase::openPassDlg - * instead of directly instantiating this dialog. - * @short dialog for requesting login and password from the end user - */ -class TDEIO_EXPORT PasswordDialog : public KDialogBase -{ - Q_OBJECT - -public: - /** - * Create a password dialog. - * - * @param prompt instructional text to be shown. - * @param user username, if known initially. - * @param enableKeep if true, shows checkbox that makes password persistent until KDE is shutdown. - * @param modal if true, the dialog will be modal (default:true). - * @param parent the parent widget (default:NULL). - * @param name the dialog name (default:NULL). - */ - PasswordDialog( const TQString& prompt, const TQString& user, - bool enableKeep = false, bool modal=true, - TQWidget* parent=0, const char* name=0 ); - - /** - * Destructor - */ - ~PasswordDialog(); - - /** - * Sets the prompt to show to the user. - * @param prompt instructional text to be shown. - */ - void setPrompt( const TQString& prompt ); - - /** - * Adds a comment line to the dialog. - * - * This function allows you to add one additional comment - * line to this widget. Calling this function after a - * comment has already been added will not have any effect. - * - * @param label label for comment (ex:"Command:") - * @param comment the actual comment text. - */ - void addCommentLine( const TQString& label, const TQString comment ); - - /** - * Returns the password entered by the user. - * @return the password - */ - TQString password() const; - - /** - * Returns the username entered by the user. - * @return the user name - */ - TQString username() const; - - /** - * Determines whether supplied authorization should - * persist even after the application has been closed. - * @return true to keep the password - */ - bool keepPassword() const; - - /** - * Check or uncheck the "keep password" checkbox. - * This can be used to check it before showing the dialog, to tell - * the user that the password is stored already (e.g. in the wallet). - * enableKeep must have been set to true in the constructor. - */ - void setKeepPassword( bool b ); - - /** - * Sets the username field read-only and sets the - * focus to the password field. - * - * @param readOnly true to set the user field to read-only - */ - void setUserReadOnly( bool readOnly ); - - /** - * @deprecated. Use setUserReadOnly(bool). - */ - KDE_DEPRECATED void setEnableUserField( bool enable, bool=false ) { - setUserReadOnly( !enable ); - }; - - /** - * Presets the password. - * @param password the password to set - * @since 3.1 - */ - void setPassword( const TQString& password ); - - /** - * Presets a number of login+password pairs that the user can choose from. - * The passwords can be empty if you simply want to offer usernames to choose from. - * This is incompatible with setUserReadOnly(true). - * @param knownLogins map of known logins: the keys are usernames, the values are passwords. - * @since 3.4 - */ - void setKnownLogins( const TQMap<TQString, TQString>& knownLogins ); - - /** - * A convienence static method for obtaining authorization - * information from the end user. - * - * - * @param user username - * @param pass password - * @param keep pointer to flag that indicates whether to keep password (can be null) - * @param prompt text to display to user. - * @param readOnly make the username field read-only. - * @param caption set the title bar to given text. - * @param comment extra comment to display to user. - * @param label optinal label for extra comment. - * - * @return Accepted/Rejected based on the user choice. - */ - static int getNameAndPassword( TQString& user, TQString& pass, bool* keep, - const TQString& prompt = TQString::null, - bool readOnly = false, - const TQString& caption = TQString::null, - const TQString& comment = TQString::null, - const TQString& label = TQString::null ); - -private slots: - void slotKeep( bool ); - void slotActivated( const TQString& userName ); - -private: - void init( const TQString&, const TQString&, bool ); - -protected: - virtual void virtual_hook( int id, void* data ); -private: - struct PasswordDialogPrivate; - PasswordDialogPrivate* d; -}; - -} - -#endif diff --git a/kio/kio/paste.cpp b/kio/kio/paste.cpp deleted file mode 100644 index 472f4e313..000000000 --- a/kio/kio/paste.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "paste.h" -#include "pastedialog.h" - -#include "kio/job.h" -#include "kio/global.h" -#include "kio/netaccess.h" -#include "kio/observer.h" -#include "kio/renamedlg.h" -#include "kio/kprotocolmanager.h" - -#include <kurl.h> -#include <kurldrag.h> -#include <kdebug.h> -#include <klocale.h> -#include <kinputdialog.h> -#include <kmessagebox.h> -#include <kmimetype.h> -#include <ktempfile.h> - -#include <tqapplication.h> -#include <tqclipboard.h> -#include <tqdragobject.h> -#include <tqtextstream.h> -#include <tqvaluevector.h> - -static KURL getNewFileName( const KURL &u, const TQString& text ) -{ - bool ok; - TQString dialogText( text ); - if ( dialogText.isEmpty() ) - dialogText = i18n( "Filename for clipboard content:" ); - TQString file = KInputDialog::getText( TQString::null, dialogText, TQString::null, &ok ); - if ( !ok ) - return KURL(); - - KURL myurl(u); - myurl.addPath( file ); - - if (TDEIO::NetAccess::exists(myurl, false, 0)) - { - kdDebug(7007) << "Paste will overwrite file. Prompting..." << endl; - TDEIO::RenameDlg_Result res = TDEIO::R_OVERWRITE; - - TQString newPath; - // Ask confirmation about resuming previous transfer - res = Observer::self()->open_RenameDlg( - 0L, i18n("File Already Exists"), - u.pathOrURL(), - myurl.pathOrURL(), - (TDEIO::RenameDlg_Mode) (TDEIO::M_OVERWRITE | TDEIO::M_SINGLE), newPath); - - if ( res == TDEIO::R_RENAME ) - { - myurl = newPath; - } - else if ( res == TDEIO::R_CANCEL ) - { - return KURL(); - } - } - - return myurl; -} - -// The finaly step: write _data to tempfile and move it to neW_url -static TDEIO::CopyJob* pasteDataAsyncTo( const KURL& new_url, const TQByteArray& _data ) -{ - KTempFile tempFile; - tempFile.dataStream()->writeRawBytes( _data.data(), _data.size() ); - tempFile.close(); - - KURL orig_url; - orig_url.setPath(tempFile.name()); - - return TDEIO::move( orig_url, new_url ); -} - -#ifndef QT_NO_MIMECLIPBOARD -static TDEIO::CopyJob* chooseAndPaste( const KURL& u, TQMimeSource* data, - const TQValueVector<TQCString>& formats, - const TQString& text, - TQWidget* widget, - bool clipboard ) -{ - TQStringList formatLabels; - for ( uint i = 0; i < formats.size(); ++i ) { - const TQCString& fmt = formats[i]; - KMimeType::Ptr mime = KMimeType::mimeType( fmt ); - if ( mime != KMimeType::defaultMimeTypePtr() ) - formatLabels.append( i18n( "%1 (%2)" ).arg( mime->comment() ).arg( fmt.data() ) ); - else - formatLabels.append( fmt ); - } - - TQString dialogText( text ); - if ( dialogText.isEmpty() ) - dialogText = i18n( "Filename for clipboard content:" ); - TDEIO::PasteDialog dlg( TQString::null, dialogText, TQString::null, formatLabels, widget, clipboard ); - - if ( dlg.exec() != KDialogBase::Accepted ) - return 0; - - if ( clipboard && dlg.clipboardChanged() ) { - KMessageBox::sorry( widget, - i18n( "The clipboard has changed since you used 'paste': " - "the chosen data format is no longer applicable. " - "Please copy again what you wanted to paste." ) ); - return 0; - } - - const TQString result = dlg.lineEditText(); - const TQCString chosenFormat = formats[ dlg.comboItem() ]; - - kdDebug() << " result=" << result << " chosenFormat=" << chosenFormat << endl; - KURL new_url( u ); - new_url.addPath( result ); - // if "data" came from TQClipboard, then it was deleted already - by a nice 0-seconds timer - // In that case, get it again. Let's hope the user didn't copy something else meanwhile :/ - if ( clipboard ) { - data = TQApplication::clipboard()->data(); - } - const TQByteArray ba = data->encodedData( chosenFormat ); - return pasteDataAsyncTo( new_url, ba ); -} -#endif - -// KDE4: remove -TDEIO_EXPORT bool TDEIO::isClipboardEmpty() -{ -#ifndef QT_NO_MIMECLIPBOARD - TQMimeSource *data = TQApplication::clipboard()->data(); - if ( data->provides( "text/uri-list" ) && data->encodedData( "text/uri-list" ).size() > 0 ) - return false; -#else - // Happens with some versions of Qt Embedded... :/ - // Guess. - TQString data = TQApplication::clipboard()->text(); - if(data.contains("://")) - return false; -#endif - return true; -} - -#ifndef QT_NO_MIMECLIPBOARD -// The main method for dropping -TDEIO::CopyJob* TDEIO::pasteMimeSource( TQMimeSource* data, const KURL& dest_url, - const TQString& dialogText, TQWidget* widget, bool clipboard ) -{ - TQByteArray ba; - - // Now check for plain text - // We don't want to display a mimetype choice for a TQTextDrag, those mimetypes look ugly. - TQString text; - if ( TQTextDrag::canDecode( data ) && TQTextDrag::decode( data, text ) ) - { - TQTextStream txtStream( ba, IO_WriteOnly ); - txtStream << text; - } - else - { - TQValueVector<TQCString> formats; - const char* fmt; - for ( int i = 0; ( fmt = data->format( i ) ); ++i ) { - if ( qstrcmp( fmt, "application/x-qiconlist" ) == 0 ) // see QIconDrag - continue; - if ( qstrcmp( fmt, "application/x-kde-cutselection" ) == 0 ) // see KonqDrag - continue; - if ( strchr( fmt, '/' ) == 0 ) // e.g. TARGETS, MULTIPLE, TIMESTAMP - continue; - formats.append( fmt ); - } - - if ( formats.size() == 0 ) - return 0; - - if ( formats.size() > 1 ) { - return chooseAndPaste( dest_url, data, formats, dialogText, widget, clipboard ); - } - ba = data->encodedData( formats.first() ); - } - if ( ba.size() == 0 ) - { - KMessageBox::sorry(0, i18n("The clipboard is empty")); - return 0; - } - - return pasteDataAsync( dest_url, ba, dialogText ); -} -#endif - -// The main method for pasting -TDEIO_EXPORT TDEIO::Job *TDEIO::pasteClipboard( const KURL& dest_url, bool move ) -{ - if ( !dest_url.isValid() ) { - KMessageBox::error( 0L, i18n( "Malformed URL\n%1" ).arg( dest_url.url() ) ); - return 0; - } - -#ifndef QT_NO_MIMECLIPBOARD - TQMimeSource *data = TQApplication::clipboard()->data(); - - // First check for URLs. - KURL::List urls; - if ( KURLDrag::canDecode( data ) && KURLDrag::decode( data, urls ) ) { - if ( urls.count() == 0 ) { - KMessageBox::error( 0L, i18n("The clipboard is empty")); - return 0; - } - - TDEIO::Job *res = 0; - if ( move ) - res = TDEIO::move( urls, dest_url ); - else - res = TDEIO::copy( urls, dest_url ); - - // If moving, erase the clipboard contents, the original files don't exist anymore - if ( move ) - TQApplication::clipboard()->clear(); - return res; - } - return pasteMimeSource( data, dest_url, TQString::null, 0 /*TODO parent widget*/, true /*clipboard*/ ); -#else - TQByteArray ba; - TQTextStream txtStream( ba, IO_WriteOnly ); - TQStringList data = TQStringList::split("\n", TQApplication::clipboard()->text()); - KURL::List urls; - KURLDrag::decode(data, urls); - TQStringList::Iterator end(data.end()); - for(TQStringList::Iterator it=data.begin(); it!=end; ++it) - txtStream << *it; - if ( ba.size() == 0 ) - { - KMessageBox::sorry(0, i18n("The clipboard is empty")); - return 0; - } - return pasteDataAsync( dest_url, ba ); -#endif -} - - -TDEIO_EXPORT void TDEIO::pasteData( const KURL& u, const TQByteArray& _data ) -{ - KURL new_url = getNewFileName( u, TQString::null ); - // We could use TDEIO::put here, but that would require a class - // for the slotData call. With NetAccess, we can do a synchronous call. - - if (new_url.isEmpty()) - return; - - KTempFile tempFile; - tempFile.setAutoDelete( true ); - tempFile.dataStream()->writeRawBytes( _data.data(), _data.size() ); - tempFile.close(); - - (void) TDEIO::NetAccess::upload( tempFile.name(), new_url, 0 ); -} - -TDEIO_EXPORT TDEIO::CopyJob* TDEIO::pasteDataAsync( const KURL& u, const TQByteArray& _data ) -{ - return pasteDataAsync( u, _data, TQString::null ); -} - -TDEIO_EXPORT TDEIO::CopyJob* TDEIO::pasteDataAsync( const KURL& u, const TQByteArray& _data, const TQString& text ) -{ - KURL new_url = getNewFileName( u, text ); - - if (new_url.isEmpty()) - return 0; - - return pasteDataAsyncTo( new_url, _data ); -} - -TDEIO_EXPORT TQString TDEIO::pasteActionText() -{ - TQMimeSource *data = TQApplication::clipboard()->data(); - KURL::List urls; - if ( KURLDrag::canDecode( data ) && KURLDrag::decode( data, urls ) ) { - if ( urls.isEmpty() ) - return TQString::null; // nothing to paste - else if ( urls.first().isLocalFile() ) - return i18n( "&Paste File", "&Paste %n Files", urls.count() ); - else - return i18n( "&Paste URL", "&Paste %n URLs", urls.count() ); - } else if ( data->format(0) != 0 ) { - return i18n( "&Paste Clipboard Contents" ); - } else { - return TQString::null; - } -} - diff --git a/kio/kio/paste.h b/kio/kio/paste.h deleted file mode 100644 index 66579831a..000000000 --- a/kio/kio/paste.h +++ /dev/null @@ -1,125 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000-2005 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_paste_h__ -#define __kio_paste_h__ - -#include <tqstring.h> -#include <tqmemarray.h> -#include <kurl.h> -class TQWidget; -class TQMimeSource; - -// KDE4 TODO pass a parent widget to all methods that will display a message box - -namespace TDEIO { - class Job; - class CopyJob; - - /** - * Pastes the content of the clipboard to the given destination URL. - * URLs are treated separately (performing a file copy) - * from other data (which is saved into a file after asking the user - * to choose a filename and the preferred data format) - * - * @param destURL the URL to receive the data - * @param move true to move the data, false to copy - * @return the job that handles the operation - * @see pasteData() - */ - TDEIO_EXPORT Job *pasteClipboard( const KURL& destURL, bool move = false ); - - /** - * Pastes the given @p data to the given destination URL. - * NOTE: This method is blocking (uses NetAccess for saving the data). - * Please consider using pasteDataAsync instead. - * - * @param destURL the URL of the directory where the data will be pasted. - * The filename to use in that directory is prompted by this method. - * @param data the data to copy - * @see pasteClipboard() - */ - TDEIO_EXPORT void pasteData( const KURL& destURL, const TQByteArray& data ); - - /** - * Pastes the given @p data to the given destination URL. - * Note that this method requires the caller to have chosen the QByteArray - * to paste before hand, unlike pasteClipboard and pasteMimeSource. - * - * @param destURL the URL of the directory where the data will be pasted. - * The filename to use in that directory is prompted by this method. - * @param data the data to copy - * @see pasteClipboard() - */ - TDEIO_EXPORT CopyJob *pasteDataAsync( const KURL& destURL, const TQByteArray& data ); - - /** - * Pastes the given @p data to the given destination URL. - * Note that this method requires the caller to have chosen the QByteArray - * to paste before hand, unlike pasteClipboard and pasteMimeSource. - * - * @param destURL the URL of the directory where the data will be pasted. - * The filename to use in that directory is prompted by this method. - * @param data the data to copy - * @param dialogText the text to show in the dialog - * @see pasteClipboard() - */ - TDEIO_EXPORT CopyJob *pasteDataAsync( const KURL& destURL, const TQByteArray& data, const TQString& dialogText ); // KDE4: merge with above - - - /** - * Save the given mimesource @p data to the given destination URL - * after offering the user to choose a data format. - * This is the method used when handling drops (of anything else than URLs) - * onto kdesktop and konqueror. - * - * @param data the TQMimeSource (e.g. a TQDropEvent) - * @param destURL the URL of the directory where the data will be pasted. - * The filename to use in that directory is prompted by this method. - * @param dialogText the text to show in the dialog - * @param widget parent widget to use for dialogs - * @param clipboard whether the TQMimeSource comes from TQClipboard. If you - * use pasteClipboard for that case, you never have to worry about this parameter. - * - * @see pasteClipboard() - * - * @since 3.5 - */ - TDEIO_EXPORT CopyJob* pasteMimeSource( TQMimeSource* data, const KURL& destURL, - const TQString& dialogText, TQWidget* widget, - bool clipboard = false ); - - /** - * Checks whether the clipboard contains any URLs. - * @return true if not - * Not used anymore, wrong method name, so it will disappear in KDE4. - */ - TDEIO_EXPORT_DEPRECATED bool isClipboardEmpty(); - - /** - * Returns the text to use for the Paste action, when the application supports - * pasting files, urls, and clipboard data, using pasteClipboard(). - * @return a string suitable for KAction::setText, or an empty string if pasting - * isn't possible right now. - * - * @since 3.5 - */ - TDEIO_EXPORT TQString pasteActionText(); -} - -#endif diff --git a/kio/kio/pastedialog.cpp b/kio/kio/pastedialog.cpp deleted file mode 100644 index 0252baff1..000000000 --- a/kio/kio/pastedialog.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2005 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "pastedialog.h" - -#include <klineedit.h> -#include <kmimetype.h> -#include <klocale.h> - -#include <tqlayout.h> -#include <tqlabel.h> -#include <tqcombobox.h> -#include <tqapplication.h> -#include <tqclipboard.h> - -TDEIO::PasteDialog::PasteDialog( const TQString &caption, const TQString &label, - const TQString &value, const TQStringList& items, - TQWidget *parent, - bool clipboard ) - : KDialogBase( parent, 0 /*name*/, true, caption, Ok|Cancel, Ok, true ) -{ - TQFrame *frame = makeMainWidget(); - TQVBoxLayout *layout = new TQVBoxLayout( frame, 0, spacingHint() ); - - m_label = new TQLabel( label, frame ); - layout->addWidget( m_label ); - - m_lineEdit = new KLineEdit( value, frame ); - layout->addWidget( m_lineEdit ); - - m_lineEdit->setFocus(); - m_label->setBuddy( m_lineEdit ); - - layout->addWidget( new TQLabel( i18n( "Data format:" ), frame ) ); - m_comboBox = new TQComboBox( frame ); - m_comboBox->insertStringList( items ); - layout->addWidget( m_comboBox ); - - layout->addStretch(); - - //connect( m_lineEdit, TQT_SIGNAL( textChanged( const TQString & ) ), - // TQT_SLOT( slotEditTextChanged( const TQString & ) ) ); - //connect( this, TQT_SIGNAL( user1Clicked() ), m_lineEdit, TQT_SLOT( clear() ) ); - - //slotEditTextChanged( value ); - setMinimumWidth( 350 ); - - m_clipboardChanged = false; - if ( clipboard ) - connect( TQApplication::clipboard(), TQT_SIGNAL( dataChanged() ), - this, TQT_SLOT( slotClipboardDataChanged() ) ); -} - -void TDEIO::PasteDialog::slotClipboardDataChanged() -{ - m_clipboardChanged = true; -} - -TQString TDEIO::PasteDialog::lineEditText() const -{ - return m_lineEdit->text(); -} - -int TDEIO::PasteDialog::comboItem() const -{ - return m_comboBox->currentItem(); -} - -#include "pastedialog.moc" diff --git a/kio/kio/pastedialog.h b/kio/kio/pastedialog.h deleted file mode 100644 index 2e7bdfda1..000000000 --- a/kio/kio/pastedialog.h +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2005 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef PASTEDIALOG_H -#define PASTEDIALOG_H - -#include <kdialogbase.h> - -class TQComboBox; -class KLineEdit; -class TQLabel; - -namespace TDEIO { - -/** - * @internal - * Internal class used by paste.h. DO NOT USE. - * @since 3.5 - */ -class PasteDialog : public KDialogBase -{ - Q_OBJECT -public: - PasteDialog( const TQString &caption, const TQString &label, - const TQString &value, const TQStringList& items, - TQWidget *parent, bool clipboard ); - - TQString lineEditText() const; - int comboItem() const; - bool clipboardChanged() const { return m_clipboardChanged; } - -private slots: - void slotClipboardDataChanged(); - -private: - TQLabel* m_label; - KLineEdit* m_lineEdit; - TQComboBox* m_comboBox; - bool m_clipboardChanged; - - class Private; - Private* d; -}; - -} // namespace - - -#endif /* PASTEDIALOG_H */ - diff --git a/kio/kio/posixacladdons.cpp b/kio/kio/posixacladdons.cpp deleted file mode 100644 index bae51592b..000000000 --- a/kio/kio/posixacladdons.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Markus Brueffer <markus@brueffer.de> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library 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 "posixacladdons.h" - -#if defined(USE_POSIX_ACL) && !defined(HAVE_NON_POSIX_ACL_EXTENSIONS) - -#include <errno.h> -#include <sys/stat.h> - -#include <tqptrlist.h> - -class SortedEntryList : public TQPtrList<acl_entry_t> -{ -protected: - int compareItems( TQPtrCollection::Item i1, - TQPtrCollection::Item i2 ) - { - acl_entry_t *e1 = static_cast<acl_entry_t*>( i1 ); - acl_entry_t *e2 = static_cast<acl_entry_t*>( i2 ); - - acl_tag_t tag1, tag2; - uid_t uid1 = 0, uid2 = 0; - - acl_get_tag_type( *e1, &tag1 ); - acl_get_tag_type( *e2, &tag2 ); - - if ( tag1 == ACL_USER || tag1 == ACL_GROUP ) - uid1 = *( (uid_t*) acl_get_qualifier( *e1 ) ); - - if ( tag2 == ACL_USER || tag2 == ACL_GROUP ) - uid2 = *( (uid_t*) acl_get_qualifier( *e2 ) ); - - if ( tag1 < tag2 ) - return -1; - else if ( tag1 > tag2 ) - return 1; - - if ( uid1 < uid2 ) - return -1; - else if ( uid1 > uid2 ) - return 1; - - return 0; - } -}; - -int acl_cmp(acl_t acl1, acl_t acl2) -{ - if ( !acl1 || !acl2 ) - return -1; - - SortedEntryList entries1, entries2; - entries1.setAutoDelete( true ); - entries2.setAutoDelete( true ); - - /* Add ACL entries to vectors */ - acl_entry_t *entry = new acl_entry_t; - int ret = acl_get_entry( acl1, ACL_FIRST_ENTRY, entry ); - while( ret == 1 ) { - entries1.append( entry ); - entry = new acl_entry_t; - ret = acl_get_entry( acl1, ACL_NEXT_ENTRY, entry ); - } - delete entry; - - entry = new acl_entry_t; - ret = acl_get_entry( acl2, ACL_FIRST_ENTRY, entry ); - while ( ret == 1 ) { - entries2.append( entry ); - entry = new acl_entry_t; - ret = acl_get_entry( acl2, ACL_NEXT_ENTRY, entry ); - } - delete entry; - - /* If the entry count differs, we are done */ - if ( entries1.count() != entries2.count() ) - return 1; - - /* Sort vectors */ - entries1.sort(); - entries2.sort(); - - /* Compare all entries */ - acl_permset_t permset1, permset2; - acl_tag_t tag1, tag2; - uid_t uid1, uid2; - acl_entry_t *e1, *e2; - - for ( e1 = entries1.first(), e2 = entries2.first(); e1; e1 = entries1.next(), e2 = entries2.next() ) { - /* Compare tag */ - if ( acl_get_tag_type( *e1, &tag1 ) != 0 ) return 1; - if ( acl_get_tag_type( *e2, &tag2 ) != 0 ) return 1; - if ( tag1 != tag2 ) return 1; - - /* Compare permissions */ - if ( acl_get_permset( *e1, &permset1 ) != 0 ) return 1; - if ( acl_get_permset( *e2, &permset2 ) != 0 ) return 1; - if ( *permset1 != *permset2) return 1; - - /* Compare uid */ - switch( tag1 ) { - case ACL_USER: - case ACL_GROUP: - uid1 = *( (uid_t*) acl_get_qualifier( *e1 ) ); - uid2 = *( (uid_t*) acl_get_qualifier( *e2 ) ); - if ( uid1 != uid2 ) return 1; - } - } - - return 0; -} - -acl_t acl_from_mode(mode_t mode) -{ - acl_t newACL = acl_init( 3 ); - acl_entry_t entry; - acl_permset_t permset; - int error = 0; - - /* Add owner entry */ - if ( ( error = acl_create_entry( &newACL, &entry ) ) == 0 ) { - /* Set owner permissions */ - acl_set_tag_type( entry, ACL_USER_OBJ ); - acl_get_permset( entry, &permset ); - acl_clear_perms( permset ); - if ( mode & S_IRUSR ) acl_add_perm( permset, ACL_READ ); - if ( mode & S_IWUSR ) acl_add_perm( permset, ACL_WRITE ); - if ( mode & S_IXUSR ) acl_add_perm( permset, ACL_EXECUTE ); - acl_set_permset( entry, permset ); - - /* Add group entry */ - if ( ( error = acl_create_entry( &newACL, &entry ) ) == 0 ) { - /* Set group permissions */ - acl_set_tag_type( entry, ACL_GROUP_OBJ ); - acl_get_permset( entry, &permset ); - acl_clear_perms( permset ); - if ( mode & S_IRGRP ) acl_add_perm( permset, ACL_READ ); - if ( mode & S_IWGRP ) acl_add_perm( permset, ACL_WRITE ); - if ( mode & S_IXGRP ) acl_add_perm( permset, ACL_EXECUTE ); - acl_set_permset( entry, permset ); - - /* Add other entry */ - if ( ( error = acl_create_entry( &newACL, &entry ) ) == 0) { - /* Set other permissions */ - acl_set_tag_type( entry, ACL_OTHER ); - acl_get_permset( entry, &permset ); - acl_clear_perms( permset ); - if ( mode & S_IROTH ) acl_add_perm( permset, ACL_READ ); - if ( mode & S_IWOTH ) acl_add_perm( permset, ACL_WRITE ); - if ( mode & S_IXOTH ) acl_add_perm( permset, ACL_EXECUTE ); - acl_set_permset( entry, permset ); - } - } - } - - if ( error ) { - acl_free ( &newACL ); - return NULL; - } - - return newACL; -} - -int acl_equiv_mode(acl_t acl, mode_t *mode_p) -{ - acl_entry_t entry; - acl_tag_t tag; - acl_permset_t permset; - mode_t mode = 0; - int notEquiv = 0; - - if ( !acl ) - return -1; - - int ret = acl_get_entry( acl, ACL_FIRST_ENTRY, &entry ); - while ( ret == 1 ) { - acl_get_tag_type( entry, &tag ); - acl_get_permset( entry, &permset ); - - switch( tag ) { - case ACL_USER_OBJ: - if ( acl_get_perm( permset, ACL_READ ) ) mode |= S_IRUSR; - if ( acl_get_perm( permset, ACL_WRITE ) ) mode |= S_IWUSR; - if ( acl_get_perm( permset, ACL_EXECUTE ) ) mode |= S_IXUSR; - break; - - case ACL_GROUP_OBJ: - if ( acl_get_perm( permset, ACL_READ ) ) mode |= S_IRGRP; - if ( acl_get_perm( permset, ACL_WRITE ) ) mode |= S_IWGRP; - if ( acl_get_perm( permset, ACL_EXECUTE ) ) mode |= S_IXGRP; - break; - - case ACL_OTHER: - if ( acl_get_perm( permset, ACL_READ ) ) mode |= S_IROTH; - if ( acl_get_perm( permset, ACL_WRITE ) ) mode |= S_IWOTH; - if ( acl_get_perm( permset, ACL_EXECUTE ) ) mode |= S_IXOTH; - break; - - case ACL_USER: - case ACL_GROUP: - case ACL_MASK: - notEquiv = 1; - break; - - default: - errno = EINVAL; - return -1; - } - - ret = acl_get_entry( acl, ACL_NEXT_ENTRY, &entry ); - } - - if (mode_p) - *mode_p = mode; - - return notEquiv; -} - -#endif // USE_POSIX_ACL diff --git a/kio/kio/posixacladdons.h b/kio/kio/posixacladdons.h deleted file mode 100644 index 45c4af245..000000000 --- a/kio/kio/posixacladdons.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Markus Brueffer <markus@brueffer.de> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Library 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. * - ***************************************************************************/ - -#ifndef __posixacladdons_h__ -#define __posixacladdons_h__ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <tqglobal.h> - -#if defined(USE_POSIX_ACL) && !defined(HAVE_NON_POSIX_ACL_EXTENSIIONS) - -#ifdef Q_OS_FREEBSD -#include <sys/types.h> -#endif - -#include <sys/acl.h> - -#ifdef Q_OS_FREEBSD -#define acl_get_perm acl_get_perm_np -#endif - -int acl_cmp(acl_t acl1, acl_t acl2); -acl_t acl_from_mode(mode_t mode); -int acl_equiv_mode(acl_t acl, mode_t *mode_p); - -#endif // USE_POSIX_ACL - -#endif // __posixacladdons_h__ diff --git a/kio/kio/previewjob.cpp b/kio/kio/previewjob.cpp deleted file mode 100644 index de4800ab1..000000000 --- a/kio/kio/previewjob.cpp +++ /dev/null @@ -1,597 +0,0 @@ -// -*- c++ -*- -// vim: ts=4 sw=4 et -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - 2000 Carsten Pfeiffer <pfeiffer@kde.org> - 2001 Malte Starostik <malte.starostik@t-online.de> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "previewjob.h" - -#include <sys/stat.h> -#ifdef __FreeBSD__ - #include <machine/param.h> -#endif -#include <sys/types.h> - -#ifdef Q_OS_UNIX -#include <sys/ipc.h> -#include <sys/shm.h> -#endif - -#include <tqdir.h> -#include <tqfile.h> -#include <tqimage.h> -#include <tqtimer.h> -#include <tqregexp.h> - -#include <kdatastream.h> // Do not remove, needed for correct bool serialization -#include <kfileitem.h> -#include <kapplication.h> -#include <ktempfile.h> -#include <ktrader.h> -#include <kmdcodec.h> -#include <kglobal.h> -#include <kstandarddirs.h> - -#include <kio/kservice.h> - -#include "previewjob.moc" - -namespace TDEIO { struct PreviewItem; } -using namespace TDEIO; - -struct TDEIO::PreviewItem -{ - KFileItem *item; - KService::Ptr plugin; -}; - -struct TDEIO::PreviewJobPrivate -{ - enum { STATE_STATORIG, // if the thumbnail exists - STATE_GETORIG, // if we create it - STATE_CREATETHUMB // thumbnail:/ slave - } state; - KFileItemList initialItems; - const TQStringList *enabledPlugins; - // Our todo list :) - TQValueList<PreviewItem> items; - // The current item - PreviewItem currentItem; - // The modification time of that URL - time_t tOrig; - // Path to thumbnail cache for the current size - TQString thumbPath; - // Original URL of current item in TMS format - // (file:///path/to/file instead of file:/path/to/file) - TQString origName; - // Thumbnail file name for current item - TQString thumbName; - // Size of thumbnail - int width; - int height; - // Unscaled size of thumbnail (128 or 256 if cache is enabled) - int cacheWidth; - int cacheHeight; - // Whether the thumbnail should be scaled - bool bScale; - // Whether we should save the thumbnail - bool bSave; - // If the file to create a thumb for was a temp file, this is its name - TQString tempName; - // Over that, it's too much - unsigned long maximumSize; - // the size for the icon overlay - int iconSize; - // the transparency of the blended mimetype icon - int iconAlpha; - // Shared memory segment Id. The segment is allocated to a size - // of extent x extent x 4 (32 bit image) on first need. - int shmid; - // And the data area - uchar *shmaddr; - // Delete the KFileItems when done? - bool deleteItems; - bool succeeded; - // Root of thumbnail cache - TQString thumbRoot; - bool ignoreMaximumSize; - TQTimer startPreviewTimer; -}; - -PreviewJob::PreviewJob( const KFileItemList &items, int width, int height, - int iconSize, int iconAlpha, bool scale, bool save, - const TQStringList *enabledPlugins, bool deleteItems ) - : TDEIO::Job( false /* no GUI */ ) -{ - d = new PreviewJobPrivate; - d->tOrig = 0; - d->shmid = -1; - d->shmaddr = 0; - d->initialItems = items; - d->enabledPlugins = enabledPlugins; - d->width = width; - d->height = height ? height : width; - d->cacheWidth = d->width; - d->cacheHeight = d->height; - d->iconSize = iconSize; - d->iconAlpha = iconAlpha; - d->deleteItems = deleteItems; - d->bScale = scale; - d->bSave = save && scale; - d->succeeded = false; - d->currentItem.item = 0; - d->thumbRoot = TQDir::homeDirPath() + "/.thumbnails/"; - d->ignoreMaximumSize = false; - - // Return to event loop first, determineNextFile() might delete this; - connect(&d->startPreviewTimer, TQT_SIGNAL(timeout()), TQT_SLOT(startPreview()) ); - d->startPreviewTimer.start(0, true); -} - -PreviewJob::~PreviewJob() -{ -#ifdef Q_OS_UNIX - if (d->shmaddr) { - shmdt((char*)d->shmaddr); - shmctl(d->shmid, IPC_RMID, 0); - } -#endif - delete d; -} - -void PreviewJob::startPreview() -{ - // Load the list of plugins to determine which mimetypes are supported - KTrader::OfferList plugins = KTrader::self()->query("ThumbCreator"); - TQMap<TQString, KService::Ptr> mimeMap; - - for (KTrader::OfferList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it) - if (!d->enabledPlugins || d->enabledPlugins->contains((*it)->desktopEntryName())) - { - TQStringList mimeTypes = (*it)->property("MimeTypes").toStringList(); - for (TQStringList::ConstIterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt) - mimeMap.insert(*mt, *it); - } - - // Look for images and store the items in our todo list :) - bool bNeedCache = false; - for (KFileItemListIterator it(d->initialItems); it.current(); ++it ) - { - PreviewItem item; - item.item = it.current(); - TQMap<TQString, KService::Ptr>::ConstIterator plugin = mimeMap.find(it.current()->mimetype()); - if (plugin == mimeMap.end() - && (it.current()->mimetype() != "application/x-desktop") - && (it.current()->mimetype() != "media/builtin-mydocuments") - && (it.current()->mimetype() != "media/builtin-mycomputer") - && (it.current()->mimetype() != "media/builtin-mynetworkplaces") - && (it.current()->mimetype() != "media/builtin-printers") - && (it.current()->mimetype() != "media/builtin-trash") - && (it.current()->mimetype() != "media/builtin-webbrowser")) - { - TQString mimeType = it.current()->mimetype(); - plugin = mimeMap.find(mimeType.replace(TQRegExp("/.*"), "/*")); - - if (plugin == mimeMap.end()) - { - // check mime type inheritance - KMimeType::Ptr mimeInfo = KMimeType::mimeType(it.current()->mimetype()); - TQString parentMimeType = mimeInfo->parentMimeType(); - while (!parentMimeType.isEmpty()) - { - plugin = mimeMap.find(parentMimeType); - if (plugin != mimeMap.end()) break; - - KMimeType::Ptr parentMimeInfo = KMimeType::mimeType(parentMimeType); - if (!parentMimeInfo) break; - - parentMimeType = parentMimeInfo->parentMimeType(); - } - } - - if (plugin == mimeMap.end()) - { - // check X-TDE-Text property - KMimeType::Ptr mimeInfo = KMimeType::mimeType(it.current()->mimetype()); - TQVariant textProperty = mimeInfo->property("X-TDE-text"); - if (textProperty.isValid() && textProperty.type() == TQVariant::Bool) - { - if (textProperty.toBool()) - { - plugin = mimeMap.find("text/plain"); - if (plugin == mimeMap.end()) - { - plugin = mimeMap.find( "text/*" ); - } - } - } - } - } - - if (plugin != mimeMap.end()) - { - item.plugin = *plugin; - d->items.append(item); - if (!bNeedCache && d->bSave && - (it.current()->url().protocol() != "file" || - !it.current()->url().directory( false ).startsWith(d->thumbRoot)) && - (*plugin)->property("CacheThumbnail").toBool()) - bNeedCache = true; - } - else - { - emitFailed(it.current()); - if (d->deleteItems) - delete it.current(); - } - } - - // Read configuration value for the maximum allowed size - TDEConfig * config = TDEGlobal::config(); - TDEConfigGroupSaver cgs( config, "PreviewSettings" ); - d->maximumSize = config->readNumEntry( "MaximumSize", 1024*1024 /* 1MB */ ); - - if (bNeedCache) - { - if (d->width <= 128 && d->height <= 128) d->cacheWidth = d->cacheHeight = 128; - else d->cacheWidth = d->cacheHeight = 256; - d->thumbPath = d->thumbRoot + (d->cacheWidth == 128 ? "normal/" : "large/"); - KStandardDirs::makeDir(d->thumbPath, 0700); - } - else - d->bSave = false; - determineNextFile(); -} - -void PreviewJob::removeItem( const KFileItem *item ) -{ - for (TQValueList<PreviewItem>::Iterator it = d->items.begin(); it != d->items.end(); ++it) - if ((*it).item == item) - { - d->items.remove(it); - break; - } - - if (d->currentItem.item == item) - { - subjobs.first()->kill(); - subjobs.removeFirst(); - determineNextFile(); - } -} - -void PreviewJob::setIgnoreMaximumSize(bool ignoreSize) -{ - d->ignoreMaximumSize = ignoreSize; -} - -void PreviewJob::determineNextFile() -{ - if (d->currentItem.item) - { - if (!d->succeeded) - emitFailed(); - if (d->deleteItems) { - delete d->currentItem.item; - d->currentItem.item = 0L; - } - } - // No more items ? - if ( d->items.isEmpty() ) - { - emitResult(); - return; - } - else - { - // First, stat the orig file - d->state = PreviewJobPrivate::STATE_STATORIG; - d->currentItem = d->items.first(); - d->succeeded = false; - d->items.remove(d->items.begin()); - TDEIO::Job *job = TDEIO::stat( d->currentItem.item->url(), false ); - job->addMetaData( "no-auth-prompt", "true" ); - addSubjob(job); - } -} - -void PreviewJob::slotResult( TDEIO::Job *job ) -{ - subjobs.remove( job ); - Q_ASSERT ( subjobs.isEmpty() ); // We should have only one job at a time ... - switch ( d->state ) - { - case PreviewJobPrivate::STATE_STATORIG: - { - if (job->error()) // that's no good news... - { - // Drop this one and move on to the next one - determineNextFile(); - return; - } - TDEIO::UDSEntry entry = ((TDEIO::StatJob*)job)->statResult(); - TDEIO::UDSEntry::ConstIterator it = entry.begin(); - d->tOrig = 0; - int found = 0; - for( ; it != entry.end() && found < 2; it++ ) - { - if ( (*it).m_uds == TDEIO::UDS_MODIFICATION_TIME ) - { - d->tOrig = (time_t)((*it).m_long); - found++; - } - else if ( (*it).m_uds == TDEIO::UDS_SIZE ) - { - if ( filesize_t((*it).m_long) > d->maximumSize && - !d->ignoreMaximumSize && - !d->currentItem.plugin->property("IgnoreMaximumSize").toBool() ) - { - determineNextFile(); - return; - } - found++; - } - } - - if ( !d->currentItem.plugin->property( "CacheThumbnail" ).toBool() ) - { - // This preview will not be cached, no need to look for a saved thumbnail - // Just create it, and be done - getOrCreateThumbnail(); - return; - } - - if ( statResultThumbnail() ) - return; - - getOrCreateThumbnail(); - return; - } - case PreviewJobPrivate::STATE_GETORIG: - { - if (job->error()) - { - determineNextFile(); - return; - } - - createThumbnail( static_cast<TDEIO::FileCopyJob*>(job)->destURL().path() ); - return; - } - case PreviewJobPrivate::STATE_CREATETHUMB: - { - if (!d->tempName.isEmpty()) - { - TQFile::remove(d->tempName); - d->tempName = TQString::null; - } - determineNextFile(); - return; - } - } -} - -bool PreviewJob::statResultThumbnail() -{ - if ( d->thumbPath.isEmpty() ) - return false; - - KURL url = d->currentItem.item->url(); - // Don't include the password if any - url.setPass(TQString::null); - // The TMS defines local files as file:///path/to/file instead of KDE's - // way (file:/path/to/file) -#ifdef KURL_TRIPLE_SLASH_FILE_PROT - d->origName = url.url(); -#else - if (url.protocol() == "file") d->origName = "file://" + url.path(); - else d->origName = url.url(); -#endif - - KMD5 md5( TQFile::encodeName( d->origName ).data() ); - d->thumbName = TQFile::encodeName( md5.hexDigest() ) + ".png"; - - TQImage thumb; - if ( !thumb.load( d->thumbPath + d->thumbName ) ) return false; - - if ( thumb.text( "Thumb::URI", 0 ) != d->origName || - thumb.text( "Thumb::MTime", 0 ).toInt() != d->tOrig ) return false; - - // Found it, use it - emitPreview( thumb ); - d->succeeded = true; - determineNextFile(); - return true; -} - - -void PreviewJob::getOrCreateThumbnail() -{ - // We still need to load the orig file ! (This is getting tedious) :) - const KFileItem* item = d->currentItem.item; - const TQString localPath = item->localPath(); - if ( !localPath.isEmpty() ) - createThumbnail( localPath ); - else - { - d->state = PreviewJobPrivate::STATE_GETORIG; - KTempFile localFile; - KURL localURL; - localURL.setPath( d->tempName = localFile.name() ); - const KURL currentURL = item->url(); - TDEIO::Job * job = TDEIO::file_copy( currentURL, localURL, -1, true, - false, false /* No GUI */ ); - job->addMetaData("thumbnail","1"); - addSubjob(job); - } -} - -// KDE 4: Make it const TQString & -void PreviewJob::createThumbnail( TQString pixPath ) -{ - d->state = PreviewJobPrivate::STATE_CREATETHUMB; - KURL thumbURL; - thumbURL.setProtocol("thumbnail"); - thumbURL.setPath(pixPath); - TDEIO::TransferJob *job = TDEIO::get(thumbURL, false, false); - addSubjob(job); - connect(job, TQT_SIGNAL(data(TDEIO::Job *, const TQByteArray &)), TQT_SLOT(slotThumbData(TDEIO::Job *, const TQByteArray &))); - bool save = d->bSave && d->currentItem.plugin->property("CacheThumbnail").toBool(); - job->addMetaData("mimeType", d->currentItem.item->mimetype()); - job->addMetaData("width", TQString().setNum(save ? d->cacheWidth : d->width)); - job->addMetaData("height", TQString().setNum(save ? d->cacheHeight : d->height)); - job->addMetaData("iconSize", TQString().setNum(save ? 64 : d->iconSize)); - job->addMetaData("iconAlpha", TQString().setNum(d->iconAlpha)); - job->addMetaData("plugin", d->currentItem.plugin->library()); -#ifdef Q_OS_UNIX - if (d->shmid == -1) - { - if (d->shmaddr) { - shmdt((char*)d->shmaddr); - shmctl(d->shmid, IPC_RMID, 0); - } - d->shmid = shmget(IPC_PRIVATE, d->cacheWidth * d->cacheHeight * 4, IPC_CREAT|0600); - if (d->shmid != -1) - { - d->shmaddr = (uchar *)(shmat(d->shmid, 0, SHM_RDONLY)); - if (d->shmaddr == (uchar *)-1) - { - shmctl(d->shmid, IPC_RMID, 0); - d->shmaddr = 0; - d->shmid = -1; - } - } - else - d->shmaddr = 0; - } - if (d->shmid != -1) - job->addMetaData("shmid", TQString().setNum(d->shmid)); -#endif -} - -void PreviewJob::slotThumbData(TDEIO::Job *, const TQByteArray &data) -{ - bool save = d->bSave && - d->currentItem.plugin->property("CacheThumbnail").toBool() && - (d->currentItem.item->url().protocol() != "file" || - !d->currentItem.item->url().directory( false ).startsWith(d->thumbRoot)); - TQImage thumb; -#ifdef Q_OS_UNIX - if (d->shmaddr) - { - TQDataStream str(data, IO_ReadOnly); - int width, height, depth; - bool alpha; - str >> width >> height >> depth >> alpha; - thumb = TQImage(d->shmaddr, width, height, depth, 0, 0, TQImage::IgnoreEndian); - thumb.setAlphaBuffer(alpha); - } - else -#endif - thumb.loadFromData(data); - - if (save) - { - thumb.setText("Thumb::URI", 0, d->origName); - thumb.setText("Thumb::MTime", 0, TQString::number(d->tOrig)); - thumb.setText("Thumb::Size", 0, number(d->currentItem.item->size())); - thumb.setText("Thumb::Mimetype", 0, d->currentItem.item->mimetype()); - thumb.setText("Software", 0, "KDE Thumbnail Generator"); - KTempFile temp(d->thumbPath + "kde-tmp-", ".png"); - if (temp.status() == 0) //Only try to write out the thumbnail if we - { //actually created the temp file. - thumb.save(temp.name(), "PNG"); - rename(TQFile::encodeName(temp.name()), TQFile::encodeName(d->thumbPath + d->thumbName)); - } - } - emitPreview( thumb ); - d->succeeded = true; -} - -void PreviewJob::emitPreview(const TQImage &thumb) -{ - TQPixmap pix; - if (thumb.width() > d->width || thumb.height() > d->height) - { - double imgRatio = (double)thumb.height() / (double)thumb.width(); - if (imgRatio > (double)d->height / (double)d->width) - pix.convertFromImage( - thumb.smoothScale((int)TQMAX((double)d->height / imgRatio, 1), d->height)); - else pix.convertFromImage( - thumb.smoothScale(d->width, (int)TQMAX((double)d->width * imgRatio, 1))); - } - else pix.convertFromImage(thumb); - emit gotPreview(d->currentItem.item, pix); -} - -void PreviewJob::emitFailed(const KFileItem *item) -{ - if (!item) - item = d->currentItem.item; - emit failed(item); -} - -TQStringList PreviewJob::availablePlugins() -{ - TQStringList result; - KTrader::OfferList plugins = KTrader::self()->query("ThumbCreator"); - for (KTrader::OfferList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it) - if (!result.contains((*it)->desktopEntryName())) - result.append((*it)->desktopEntryName()); - return result; -} - -TQStringList PreviewJob::supportedMimeTypes() -{ - TQStringList result; - KTrader::OfferList plugins = KTrader::self()->query("ThumbCreator"); - for (KTrader::OfferList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it) - result += (*it)->property("MimeTypes").toStringList(); - return result; -} - -void PreviewJob::kill( bool quietly ) -{ - d->startPreviewTimer.stop(); - Job::kill( quietly ); -} - -PreviewJob *TDEIO::filePreview( const KFileItemList &items, int width, int height, - int iconSize, int iconAlpha, bool scale, bool save, - const TQStringList *enabledPlugins ) -{ - return new PreviewJob(items, width, height, iconSize, iconAlpha, - scale, save, enabledPlugins); -} - -PreviewJob *TDEIO::filePreview( const KURL::List &items, int width, int height, - int iconSize, int iconAlpha, bool scale, bool save, - const TQStringList *enabledPlugins ) -{ - KFileItemList fileItems; - for (KURL::List::ConstIterator it = items.begin(); it != items.end(); ++it) - fileItems.append(new KFileItem(KFileItem::Unknown, KFileItem::Unknown, *it, true)); - return new PreviewJob(fileItems, width, height, iconSize, iconAlpha, - scale, save, enabledPlugins, true); -} - -void PreviewJob::virtual_hook( int id, void* data ) -{ TDEIO::Job::virtual_hook( id, data ); } - diff --git a/kio/kio/previewjob.h b/kio/kio/previewjob.h deleted file mode 100644 index fe8e16c0f..000000000 --- a/kio/kio/previewjob.h +++ /dev/null @@ -1,182 +0,0 @@ -// -*- c++ -*- -// vim: ts=4 sw=4 et -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - 2000 Carsten Pfeiffer <pfeiffer@kde.org> - 2001 Malte Starostik <malte.starostik@t-online.de> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_previewjob_h__ -#define __kio_previewjob_h__ - -#include <kfileitem.h> -#include <kio/job.h> - -class TQPixmap; - -namespace TDEIO { - /*! - * This class catches a preview (thumbnail) for files. - * @short KIO Job to get a thumbnail picture - */ - class TDEIO_EXPORT PreviewJob : public TDEIO::Job - { - Q_OBJECT - public: - /** - * Creates a new PreviewJob. - * @param items a list of files to create previews for - * @param width the desired width - * @param height the desired height, 0 to use the @p width - * @param iconSize the size of the mimetype icon to overlay over the - * preview or zero to not overlay an icon. This has no effect if the - * preview plugin that will be used doesn't use icon overlays. - * @param iconAlpha transparency to use for the icon overlay - * @param scale if the image is to be scaled to the requested size or - * returned in its original size - * @param save if the image should be cached for later use - * @param enabledPlugins if non-zero, this points to a list containing - * the names of the plugins that may be used. - * @param deleteItems true to delete the items when done - */ - PreviewJob( const KFileItemList &items, int width, int height, - int iconSize, int iconAlpha, bool scale, bool save, - const TQStringList *enabledPlugins, bool deleteItems = false ); - virtual ~PreviewJob(); - - /** - * Removes an item from preview processing. Use this if you passed - * an item to filePreview and want to delete it now. - * - * @param item the item that should be removed from the preview queue - */ - void removeItem( const KFileItem *item ); - - /** - * If @p ignoreSize is true, then the preview is always - * generated regardless of the settings - * - * @since KDE 3.4 - **/ - void setIgnoreMaximumSize(bool ignoreSize = true); - - /** - * Returns a list of all available preview plugins. The list - * contains the basenames of the plugins' .desktop files (no path, - * no .desktop). - * @return the list of plugins - */ - static TQStringList availablePlugins(); - - /** - * Returns a list of all supported MIME types. The list can - * contain entries like text/ * (without the space). - * @return the list of mime types - */ - static TQStringList supportedMimeTypes(); - - /** - * Reimplemented for internal reasons - */ - virtual void kill( bool quietly = true ); - - signals: - /** - * Emitted when a thumbnail picture for @p item has been successfully - * retrieved. - * @param item the file of the preview - * @param preview the preview image - */ - void gotPreview( const KFileItem *item, const TQPixmap &preview ); - /** - * Emitted when a thumbnail for @p item could not be created, - * either because a ThumbCreator for its MIME type does not - * exist, or because something went wrong. - * @param item the file that failed - */ - void failed( const KFileItem *item ); - - protected: - void getOrCreateThumbnail(); - bool statResultThumbnail(); - void createThumbnail( TQString ); - - protected slots: - virtual void slotResult( TDEIO::Job *job ); - - private slots: - void startPreview(); - void slotThumbData(TDEIO::Job *, const TQByteArray &); - - private: - void determineNextFile(); - void emitPreview(const TQImage &thumb); - void emitFailed(const KFileItem *item = 0); - - protected: - virtual void virtual_hook( int id, void* data ); - private: - struct PreviewJobPrivate *d; - }; - - /** - * Creates a PreviewJob to generate or retrieve a preview image - * for the given URL. - * - * @param items files to get previews for - * @param width the maximum width to use - * @param height the maximum height to use, if this is 0, the same - * value as width is used. - * @param iconSize the size of the mimetype icon to overlay over the - * preview or zero to not overlay an icon. This has no effect if the - * preview plugin that will be used doesn't use icon overlays. - * @param iconAlpha transparency to use for the icon overlay - * @param scale if the image is to be scaled to the requested size or - * returned in its original size - * @param save if the image should be cached for later use - * @param enabledPlugins if non-zero, this points to a list containing - * the names of the plugins that may be used. - * @return the new PreviewJob - * @see PreviewJob::availablePlugins() - */ - TDEIO_EXPORT PreviewJob *filePreview( const KFileItemList &items, int width, int height = 0, int iconSize = 0, int iconAlpha = 70, bool scale = true, bool save = true, const TQStringList *enabledPlugins = 0 ); - - /** - * Creates a PreviewJob to generate or retrieve a preview image - * for the given URL. - * - * @param items files to get previews for - * @param width the maximum width to use - * @param height the maximum height to use, if this is 0, the same - * value as width is used. - * @param iconSize the size of the mimetype icon to overlay over the - * preview or zero to not overlay an icon. This has no effect if the - * preview plugin that will be used doesn't use icon overlays. - * @param iconAlpha transparency to use for the icon overlay - * @param scale if the image is to be scaled to the requested size or - * returned in its original size - * @param save if the image should be cached for later use - * @param enabledPlugins if non-zero, this points to a list containing - * the names of the plugins that may be used. - * @return the new PreviewJob - * @see PreviewJob::availablePlugins() - */ - TDEIO_EXPORT PreviewJob *filePreview( const KURL::List &items, int width, int height = 0, int iconSize = 0, int iconAlpha = 70, bool scale = true, bool save = true, const TQStringList *enabledPlugins = 0 ); -} - -#endif diff --git a/kio/kio/progressbase.cpp b/kio/kio/progressbase.cpp deleted file mode 100644 index 146f4182e..000000000 --- a/kio/kio/progressbase.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Matej Koss <koss@miesto.sk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "jobclasses.h" -#include "progressbase.h" - -namespace TDEIO { - -ProgressBase::ProgressBase( TQWidget *parent ) - : TQWidget( parent ) -{ - m_pJob = 0; - - // delete dialog after the job is finished / canceled - m_bOnlyClean = false; - - // stop job on close - m_bStopOnClose = true; -} - - -void ProgressBase::setJob( TDEIO::Job *job ) -{ - // first connect all slots - connect( job, TQT_SIGNAL( percent( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotPercent( TDEIO::Job*, unsigned long ) ) ); - - connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ), - TQT_SLOT( slotFinished( TDEIO::Job* ) ) ); - - connect( job, TQT_SIGNAL( canceled( TDEIO::Job* ) ), - TQT_SLOT( slotFinished( TDEIO::Job* ) ) ); - - // then assign job - m_pJob = job; -} - - -void ProgressBase::setJob( TDEIO::CopyJob *job ) -{ - // first connect all slots - connect( job, TQT_SIGNAL( totalSize( TDEIO::Job*, TDEIO::filesize_t ) ), - TQT_SLOT( slotTotalSize( TDEIO::Job*, TDEIO::filesize_t ) ) ); - connect( job, TQT_SIGNAL( totalFiles( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotTotalFiles( TDEIO::Job*, unsigned long ) ) ); - connect( job, TQT_SIGNAL( totalDirs( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotTotalDirs( TDEIO::Job*, unsigned long ) ) ); - - connect( job, TQT_SIGNAL( processedSize( TDEIO::Job*, TDEIO::filesize_t ) ), - TQT_SLOT( slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t ) ) ); - connect( job, TQT_SIGNAL( processedFiles( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotProcessedFiles( TDEIO::Job*, unsigned long ) ) ); - connect( job, TQT_SIGNAL( processedDirs( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotProcessedDirs( TDEIO::Job*, unsigned long ) ) ); - - connect( job, TQT_SIGNAL( speed( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotSpeed( TDEIO::Job*, unsigned long ) ) ); - connect( job, TQT_SIGNAL( percent( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotPercent( TDEIO::Job*, unsigned long ) ) ); - - connect( job, TQT_SIGNAL( copying( TDEIO::Job*, const KURL& , const KURL& ) ), - TQT_SLOT( slotCopying( TDEIO::Job*, const KURL&, const KURL& ) ) ); - connect( job, TQT_SIGNAL( moving( TDEIO::Job*, const KURL& , const KURL& ) ), - TQT_SLOT( slotMoving( TDEIO::Job*, const KURL&, const KURL& ) ) ); - connect( job, TQT_SIGNAL( creatingDir( TDEIO::Job*, const KURL& ) ), - TQT_SLOT( slotCreatingDir( TDEIO::Job*, const KURL& ) ) ); - - connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ), - TQT_SLOT( slotFinished( TDEIO::Job* ) ) ); - - connect( job, TQT_SIGNAL( canceled( TDEIO::Job* ) ), - TQT_SLOT( slotFinished( TDEIO::Job* ) ) ); - - // then assign job - m_pJob = job; -} - - -void ProgressBase::setJob( TDEIO::DeleteJob *job ) -{ - // first connect all slots - connect( job, TQT_SIGNAL( totalSize( TDEIO::Job*, TDEIO::filesize_t ) ), - TQT_SLOT( slotTotalSize( TDEIO::Job*, TDEIO::filesize_t ) ) ); - connect( job, TQT_SIGNAL( totalFiles( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotTotalFiles( TDEIO::Job*, unsigned long ) ) ); - connect( job, TQT_SIGNAL( totalDirs( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotTotalDirs( TDEIO::Job*, unsigned long ) ) ); - - connect( job, TQT_SIGNAL( processedSize( TDEIO::Job*, TDEIO::filesize_t ) ), - TQT_SLOT( slotProcessedSize( TDEIO::Job*, TDEIO::filesize_t ) ) ); - connect( job, TQT_SIGNAL( processedFiles( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotProcessedFiles( TDEIO::Job*, unsigned long ) ) ); - connect( job, TQT_SIGNAL( processedDirs( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotProcessedDirs( TDEIO::Job*, unsigned long ) ) ); - - connect( job, TQT_SIGNAL( speed( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotSpeed( TDEIO::Job*, unsigned long ) ) ); - connect( job, TQT_SIGNAL( percent( TDEIO::Job*, unsigned long ) ), - TQT_SLOT( slotPercent( TDEIO::Job*, unsigned long ) ) ); - - connect( job, TQT_SIGNAL( deleting( TDEIO::Job*, const KURL& ) ), - TQT_SLOT( slotDeleting( TDEIO::Job*, const KURL& ) ) ); - - connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ), - TQT_SLOT( slotFinished( TDEIO::Job* ) ) ); - - connect( job, TQT_SIGNAL( canceled( TDEIO::Job* ) ), - TQT_SLOT( slotFinished( TDEIO::Job* ) ) ); - - // then assign job - m_pJob = job; -} - - -void ProgressBase::closeEvent( TQCloseEvent* ) { - // kill job when desired - if ( m_bStopOnClose ) { - slotStop(); - } else { - // clean or delete dialog - if ( m_bOnlyClean ) { - slotClean(); - } else { - delete this; - } - } -} - -void ProgressBase::finished() { - // clean or delete dialog - if ( m_bOnlyClean ) { - slotClean(); - } else { - deleteLater(); - } -} - -void ProgressBase::slotFinished( TDEIO::Job* ) { - finished(); -} - - -void ProgressBase::slotStop() { - if ( m_pJob ) { - m_pJob->kill(); // this will call slotFinished - m_pJob = 0L; - } else { - slotFinished( 0 ); // here we call it ourselves - } - - emit stopped(); -} - - -void ProgressBase::slotClean() { - hide(); -} - -void ProgressBase::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -} /* namespace */ - -#include "progressbase.moc" - diff --git a/kio/kio/progressbase.h b/kio/kio/progressbase.h deleted file mode 100644 index 2be545621..000000000 --- a/kio/kio/progressbase.h +++ /dev/null @@ -1,271 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Matej Koss <koss@miesto.sk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __progressbase_h__ -#define __progressbase_h__ - - -#include <tqwidget.h> - -#include <kio/global.h> - -class KURL; -namespace TDEIO { - class Job; - class CopyJob; - class DeleteJob; -} - -namespace TDEIO -{ - enum Progress { - DEFAULT = 1, - STATUSBAR = 2, - LIST = 3 - }; - -/** -* This class does all initialization stuff for progress, -* like connecting signals to slots. -* All slots are implemented as pure virtual methods. -* -* All custom IO progress dialog should inherit this class. -* Add your GUI code to the constructor and implemement those virtual -* methods which you need in order to display progress. -* -* E.g. StatusbarProgress only implements slotTotalSize(), -* slotPercent() and slotSpeed(). -* -* Custom progress dialog will be used like this : -* \code -* // create job -* CopyJob* job = TDEIO::copy(...); -* // create a dialog -* MyCustomProgress *customProgress; -* customProgress = new MyCustomProgress(); -* // connect progress with job -* customProgress->setJob( job ); -* ... -* \endcode -* -* There is a special method setStopOnClose() that controls the behavior of -* the dialog. -* @short Base class for IO progress dialogs. -* @author Matej Koss <koss@miesto.sk> -*/ -class TDEIO_EXPORT ProgressBase : public TQWidget { - - Q_OBJECT - -public: - - /** - * Creates a new progress dialog. - * @param parent the parent of this dialog window, or 0 - */ - ProgressBase( TQWidget *parent ); - ~ProgressBase() {} - - /** - * Assign a TDEIO::Job to this progress dialog. - * @param job the job to assign - */ - void setJob( TDEIO::Job *job ); - /** - * Assign a TDEIO::Job to this progress dialog. - * @param job the job to assign - */ - void setJob( TDEIO::CopyJob *job ); - /** - * Assign a TDEIO::Job to this progress dialog. - * @param job the job to assign - */ - void setJob( TDEIO::DeleteJob *job ); - - // should we stop the job when the dialog is closed ? - void setStopOnClose( bool stopOnClose ) { m_bStopOnClose = stopOnClose; } - bool stopOnClose() const { return m_bStopOnClose; } - - // should we delete the dialog or just clean it when the job is finished ? - /** - * This controls whether the dialog should be deleted or only cleaned when - * the TDEIO::Job is finished (or canceled). - * - * If your dialog is an embedded widget and not a separate window, you should - * setOnlyClean(true) in the constructor of your custom dialog. - * - * @param onlyClean If true the dialog will only call method slotClean. - * If false the dialog will be deleted. - * @see onlyClean() - */ - void setOnlyClean( bool onlyClean ) { m_bOnlyClean = onlyClean; } - - /** - * Checks whether the dialog should be deleted or cleaned. - * @return true if the dialog only calls slotClean, false if it will be - * deleted - * @see setOnlyClean() - */ - bool onlyClean() const { return m_bOnlyClean; } - - /** - * Call when the operation finished. - * @since 3.1 - */ - void finished(); - -public slots: - /** - * This method should be called for correct cancellation of IO operation - * Connect this to the progress widgets buttons etc. - */ - void slotStop(); - /** - * This method is called when the widget should be cleaned (after job is finished). - * redefine this for custom behavior. - */ - virtual void slotClean(); - - // progress slots - /** - * Called to set the total size. - * @param job the TDEIO::Job - * @param size the total size in bytes - */ - virtual void slotTotalSize( TDEIO::Job* job, TDEIO::filesize_t size ) { - Q_UNUSED(job);Q_UNUSED(size);} - /** - * Called to set the total number of files. - * @param job the TDEIO::Job - * @param files the number of files - */ - virtual void slotTotalFiles( TDEIO::Job* job, unsigned long files ) { - Q_UNUSED(job);Q_UNUSED(files);} - /** - * Called to set the total number of directories. - * @param job the TDEIO::Job - * @param dirs the number of directories - */ - virtual void slotTotalDirs( TDEIO::Job* job, unsigned long dirs ) { - Q_UNUSED(job);Q_UNUSED(dirs);} - - /** - * Called to set the processed size. - * @param job the TDEIO::Job - * @param bytes the processed size in bytes - */ - virtual void slotProcessedSize( TDEIO::Job* job, TDEIO::filesize_t bytes ) { - Q_UNUSED(job);Q_UNUSED(bytes);} - /** - * Called to set the number of processed files. - * @param job the TDEIO::Job - * @param files the number of files - */ - virtual void slotProcessedFiles( TDEIO::Job* job, unsigned long files ) { - Q_UNUSED(job);Q_UNUSED(files);} - /** - * Called to set the number of processed directories. - * @param job the TDEIO::Job - * @param dirs the number of directories - */ - virtual void slotProcessedDirs( TDEIO::Job* job, unsigned long dirs ) { - Q_UNUSED(job);Q_UNUSED(dirs);} - - /** - * Called to set the speed. - * @param job the TDEIO::Job - * @param speed the speed in bytes/second - */ - virtual void slotSpeed( TDEIO::Job* job, unsigned long speed ) { - Q_UNUSED(job);Q_UNUSED(speed);} - - /** - * Called to set the percentage. - * @param job the TDEIO::Job - * @param percent the percentage - */ - virtual void slotPercent( TDEIO::Job* job, unsigned long percent ) { - Q_UNUSED(job);Q_UNUSED(percent);} - - /** - * Called when the job is copying. - * @param job the TDEIO::Job - * @param src the source of the operation - * @param dest the destination of the operation - */ - virtual void slotCopying( TDEIO::Job* job, const KURL& src, const KURL& dest ) { - Q_UNUSED(job);Q_UNUSED(src);Q_UNUSED(dest);} - /** - * Called when the job is moving. - * @param job the TDEIO::Job - * @param src the source of the operation - * @param dest the destination of the operation - */ - virtual void slotMoving( TDEIO::Job* job, const KURL& src, const KURL& dest ) { - Q_UNUSED(job);Q_UNUSED(src);Q_UNUSED(dest);} - /** - * Called when the job is deleting. - * @param job the TDEIO::Job - * @param url the URL to delete - */ - virtual void slotDeleting( TDEIO::Job* job, const KURL& url) { - Q_UNUSED(job);Q_UNUSED(url);} - /** - * Called when the job is creating a directory. - * @param job the TDEIO::Job - * @param dir the URL of the directory to create - */ - virtual void slotCreatingDir( TDEIO::Job* job, const KURL& dir ) { - Q_UNUSED(job);Q_UNUSED(dir);} - - /** - * Called when the job is resuming.. - * @param job the TDEIO::Job - * @param from the position to resume from in bytes - */ - virtual void slotCanResume( TDEIO::Job* job, TDEIO::filesize_t from) { - Q_UNUSED(job);Q_UNUSED(from);} - -signals: - /** - * Called when the operation stopped. - */ - void stopped(); - -protected slots: - void slotFinished( TDEIO::Job* ); - -protected: - - virtual void closeEvent( TQCloseEvent * ); - - TDEIO::Job* m_pJob; - -private: - bool m_bOnlyClean; - bool m_bStopOnClose; - - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class ProgressBasePrivate* d; -}; - -} /* namespace */ - -#endif // __progressbase_h__ diff --git a/kio/kio/renamedlg.cpp b/kio/kio/renamedlg.cpp deleted file mode 100644 index 7bba95460..000000000 --- a/kio/kio/renamedlg.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Stephan Kulow <coolo@kde.org> - David Faure <faure@kde.org> - 2001 Holger Freyther <freyther@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kio/renamedlg.h" -#include "kio/renamedlgplugin.h" -#include <stdio.h> -#include <assert.h> - -#include <tqfileinfo.h> -#include <tqlabel.h> -#include <tqlayout.h> -#include <tqlineedit.h> -#include <tqdir.h> - -#include <kmessagebox.h> -#include <kpushbutton.h> -#include <kapplication.h> -#include <kio/global.h> -#include <ktrader.h> -#include <klibloader.h> -#include <kdialog.h> -#include <klocale.h> -#include <kglobal.h> -#include <kdebug.h> -#include <kurl.h> -#include <kmimetype.h> -#include <kseparator.h> -#include <kstringhandler.h> -#include <kstdguiitem.h> -#include <kguiitem.h> -#include <ksqueezedtextlabel.h> - -#ifdef Q_WS_X11 -#include <twin.h> -#endif - -using namespace TDEIO; - -class RenameDlg::RenameDlgPrivate -{ - public: - RenameDlgPrivate(){ - bCancel = 0; - bRename = bSkip = bAutoSkip = bOverwrite = bOverwriteAll = 0; - bResume = bResumeAll = bSuggestNewName = 0; - m_pLineEdit = 0; - } - KPushButton *bCancel; - TQPushButton *bRename; - TQPushButton *bSkip; - TQPushButton *bAutoSkip; - TQPushButton *bOverwrite; - TQPushButton *bOverwriteAll; - TQPushButton *bResume; - TQPushButton *bResumeAll; - TQPushButton *bSuggestNewName; - TQLineEdit* m_pLineEdit; - KURL src; - KURL dest; - TQString mimeSrc; - TQString mimeDest; - bool modal; - bool plugin; -}; - -RenameDlg::RenameDlg(TQWidget *parent, const TQString & _caption, - const TQString &_src, const TQString &_dest, - RenameDlg_Mode _mode, - TDEIO::filesize_t sizeSrc, - TDEIO::filesize_t sizeDest, - time_t ctimeSrc, - time_t ctimeDest, - time_t mtimeSrc, - time_t mtimeDest, - bool _modal) - : TQDialog ( parent, "TDEIO::RenameDialog" , _modal ) -{ - d = new RenameDlgPrivate( ); - d->modal = _modal; -#if 0 - // Set "StaysOnTop", because this dialog is typically used in kio_uiserver, - // i.e. in a separate process. - // ####### This isn't the case anymore - remove? -#if !defined(Q_WS_QWS) && !defined(Q_WS_WIN) //FIXME(E): Implement for QT Embedded & win32 - if (d->modal) - KWin::setState( winId(), NET::StaysOnTop ); -#endif -#endif - - d->src = _src; - d->dest = _dest; - d->plugin = false; - - - setCaption( _caption ); - - d->bCancel = new KPushButton( KStdGuiItem::cancel(), this ); - connect(d->bCancel, TQT_SIGNAL(clicked()), this, TQT_SLOT(b0Pressed())); - - if ( ! (_mode & M_NORENAME ) ) { - d->bRename = new TQPushButton( i18n( "&Rename" ), this ); - d->bRename->setEnabled(false); - d->bSuggestNewName = new TQPushButton( i18n( "Suggest New &Name" ), this ); - connect(d->bSuggestNewName, TQT_SIGNAL(clicked()), this, TQT_SLOT(b8Pressed())); - connect(d->bRename, TQT_SIGNAL(clicked()), this, TQT_SLOT(b1Pressed())); - } - - if ( ( _mode & M_MULTI ) && ( _mode & M_SKIP ) ) { - d->bSkip = new TQPushButton( i18n( "&Skip" ), this ); - connect(d->bSkip, TQT_SIGNAL(clicked()), this, TQT_SLOT(b2Pressed())); - - d->bAutoSkip = new TQPushButton( i18n( "&Auto Skip" ), this ); - connect(d->bAutoSkip, TQT_SIGNAL(clicked()), this, TQT_SLOT(b3Pressed())); - } - - if ( _mode & M_OVERWRITE ) { - d->bOverwrite = new TQPushButton( i18n( "&Overwrite" ), this ); - connect(d->bOverwrite, TQT_SIGNAL(clicked()), this, TQT_SLOT(b4Pressed())); - - if ( _mode & M_MULTI ) { - d->bOverwriteAll = new TQPushButton( i18n( "O&verwrite All" ), this ); - connect(d->bOverwriteAll, TQT_SIGNAL(clicked()), this, TQT_SLOT(b5Pressed())); - } - } - - if ( _mode & M_RESUME ) { - d->bResume = new TQPushButton( i18n( "&Resume" ), this ); - connect(d->bResume, TQT_SIGNAL(clicked()), this, TQT_SLOT(b6Pressed())); - - if ( _mode & M_MULTI ) - { - d->bResumeAll = new TQPushButton( i18n( "R&esume All" ), this ); - connect(d->bResumeAll, TQT_SIGNAL(clicked()), this, TQT_SLOT(b7Pressed())); - } - } - - TQVBoxLayout* pLayout = new TQVBoxLayout( this, KDialog::marginHint(), - KDialog::spacingHint() ); - pLayout->addStrut( 360 ); // makes dlg at least that wide - - // User tries to overwrite a file with itself ? - if ( _mode & M_OVERWRITE_ITSELF ) { - TQLabel *lb = new TQLabel( i18n( "This action would overwrite '%1' with itself.\n" - "Please enter a new file name:" ).arg( KStringHandler::csqueeze( d->src.pathOrURL(),100 ) ), this ); - d->bRename->setText(i18n("C&ontinue")); - pLayout->addWidget( lb ); - } - else if ( _mode & M_OVERWRITE ) { - - // Figure out the mimetype and load one plugin - // (This is the only mode that is handled by plugins) - pluginHandling(); - KTrader::OfferList plugin_offers; - if( d->mimeSrc != KMimeType::defaultMimeType() ){ - plugin_offers = KTrader::self()->query(d->mimeSrc, "'RenameDlg/Plugin' in ServiceTypes"); - - }else if(d->mimeDest != KMimeType::defaultMimeType() ) { - plugin_offers = KTrader::self()->query(d->mimeDest, "'RenameDlg/Plugin' in ServiceTypes"); - } - if(!plugin_offers.isEmpty() ){ - kdDebug(7024) << "Offers" << endl; - KTrader::OfferList::ConstIterator it = plugin_offers.begin(); - KTrader::OfferList::ConstIterator end = plugin_offers.end(); - for( ; it != end; ++it ){ - TQString libName = (*it)->library(); - if( libName.isEmpty() ){ - kdDebug(7024) << "lib is empty" << endl; - continue; - } - KLibrary *lib = KLibLoader::self()->library(libName.local8Bit() ); - if(!lib) { - continue; - } - KLibFactory *factory = lib->factory(); - if(!factory){ - lib->unload(); - continue; - } - TQObject *obj = factory->create( TQT_TQOBJECT(this), (*it)->name().latin1() ); - if(!obj) { - lib->unload(); - continue; - } - RenameDlgPlugin *plugin = static_cast<RenameDlgPlugin *>(TQT_TQWIDGET(obj)); - if(!plugin ){ - delete obj; - continue; - } - if( plugin->initialize( _mode, _src, _dest, d->mimeSrc, - d->mimeDest, sizeSrc, sizeDest, - ctimeSrc, ctimeDest, - mtimeSrc, mtimeDest ) ) { - d->plugin = true; - pLayout->addWidget(plugin ); - kdDebug(7024) << "RenameDlgPlugin" << endl; - break; - } else { - delete obj; - } - } - - } - - if( !d->plugin ){ - // No plugin found, build default dialog - TQGridLayout * gridLayout = new TQGridLayout( 0L, 9, 2, KDialog::marginHint(), - KDialog::spacingHint() ); - pLayout->addLayout(TQT_TQLAYOUT(gridLayout)); - gridLayout->setColStretch(0,0); - gridLayout->setColStretch(1,10); - - TQString sentence1; - if (mtimeDest < mtimeSrc) - sentence1 = i18n("An older item named '%1' already exists."); - else if (mtimeDest == mtimeSrc) - sentence1 = i18n("A similar file named '%1' already exists."); - else - sentence1 = i18n("A newer item named '%1' already exists."); - - TQLabel * lb1 = new KSqueezedTextLabel( sentence1.arg(d->dest.pathOrURL() ), this ); - gridLayout->addMultiCellWidget( lb1, 0, 0, 0, 1 ); // takes the complete first line - - lb1 = new TQLabel( this ); - lb1->setPixmap( KMimeType::pixmapForURL( d->dest ) ); - gridLayout->addMultiCellWidget( lb1, 1, 3, 0, 0 ); // takes the first column on rows 1-3 - - int row = 1; - if ( sizeDest != (TDEIO::filesize_t)-1 ) - { - TQLabel * lb = new TQLabel( i18n("size %1").arg( TDEIO::convertSize(sizeDest) ), this ); - gridLayout->addWidget( lb, row, 1 ); - row++; - - } - if ( ctimeDest != (time_t)-1 ) - { - TQDateTime dctime; dctime.setTime_t( ctimeDest ); - TQLabel * lb = new TQLabel( i18n("created on %1").arg( TDEGlobal::locale()->formatDateTime(dctime) ), this ); - gridLayout->addWidget( lb, row, 1 ); - row++; - } - if ( mtimeDest != (time_t)-1 ) - { - TQDateTime dmtime; dmtime.setTime_t( mtimeDest ); - TQLabel * lb = new TQLabel( i18n("modified on %1").arg( TDEGlobal::locale()->formatDateTime(dmtime) ), this ); - gridLayout->addWidget( lb, row, 1 ); - row++; - } - - if ( !d->src.isEmpty() ) - { - // rows 1 to 3 are the details (size/ctime/mtime), row 4 is empty - gridLayout->addRowSpacing( 4, 20 ); - - TQLabel * lb2 = new KSqueezedTextLabel( i18n("The source file is '%1'").arg(d->src.pathOrURL()), this ); - gridLayout->addMultiCellWidget( lb2, 5, 5, 0, 1 ); // takes the complete first line - - lb2 = new TQLabel( this ); - lb2->setPixmap( KMimeType::pixmapForURL( d->src ) ); - gridLayout->addMultiCellWidget( lb2, 6, 8, 0, 0 ); // takes the first column on rows 6-8 - - row = 6; - - if ( sizeSrc != (TDEIO::filesize_t)-1 ) - { - TQLabel * lb = new TQLabel( i18n("size %1").arg( TDEIO::convertSize(sizeSrc) ), this ); - gridLayout->addWidget( lb, row, 1 ); - row++; - } - if ( ctimeSrc != (time_t)-1 ) - { - TQDateTime dctime; dctime.setTime_t( ctimeSrc ); - TQLabel * lb = new TQLabel( i18n("created on %1").arg( TDEGlobal::locale()->formatDateTime(dctime) ), this ); - gridLayout->addWidget( lb, row, 1 ); - row++; - } - if ( mtimeSrc != (time_t)-1 ) - { - TQDateTime dmtime; dmtime.setTime_t( mtimeSrc ); - TQLabel * lb = new TQLabel( i18n("modified on %1").arg( TDEGlobal::locale()->formatDateTime(dmtime) ), this ); - gridLayout->addWidget( lb, row, 1 ); - row++; - } - } - } - } - else - { - // This is the case where we don't want to allow overwriting, the existing - // file must be preserved (e.g. when renaming). - TQString sentence1; - if (mtimeDest < mtimeSrc) - sentence1 = i18n("An older item named '%1' already exists."); - else if (mtimeDest == mtimeSrc) - sentence1 = i18n("A similar file named '%1' already exists."); - else - sentence1 = i18n("A newer item named '%1' already exists."); - - TQLabel *lb = new KSqueezedTextLabel( sentence1.arg(d->dest.pathOrURL()), this ); - pLayout->addWidget(lb); - } - TQHBoxLayout* layout2 = new TQHBoxLayout(); - pLayout->addLayout( layout2 ); - - d->m_pLineEdit = new TQLineEdit( this ); - layout2->addWidget( d->m_pLineEdit ); - TQString fileName = d->dest.fileName(); - d->m_pLineEdit->setText( TDEIO::decodeFileName( fileName ) ); - if ( d->bRename || d->bOverwrite ) - connect(d->m_pLineEdit, TQT_SIGNAL(textChanged(const TQString &)), - TQT_SLOT(enableRenameButton(const TQString &))); - if ( d->bSuggestNewName ) - { - layout2->addWidget( d->bSuggestNewName ); - setTabOrder( d->m_pLineEdit, d->bSuggestNewName ); - } - - KSeparator* separator = new KSeparator( this ); - pLayout->addWidget( separator ); - - TQHBoxLayout* layout = new TQHBoxLayout(); - pLayout->addLayout( layout ); - - layout->addStretch(1); - - if ( d->bRename ) - { - layout->addWidget( d->bRename ); - setTabOrder( d->bRename, d->bCancel ); - } - if ( d->bSkip ) - { - layout->addWidget( d->bSkip ); - setTabOrder( d->bSkip, d->bCancel ); - } - if ( d->bAutoSkip ) - { - layout->addWidget( d->bAutoSkip ); - setTabOrder( d->bAutoSkip, d->bCancel ); - } - if ( d->bOverwrite ) - { - layout->addWidget( d->bOverwrite ); - setTabOrder( d->bOverwrite, d->bCancel ); - } - if ( d->bOverwriteAll ) - { - layout->addWidget( d->bOverwriteAll ); - setTabOrder( d->bOverwriteAll, d->bCancel ); - } - if ( d->bResume ) - { - layout->addWidget( d->bResume ); - setTabOrder( d->bResume, d->bCancel ); - } - if ( d->bResumeAll ) - { - layout->addWidget( d->bResumeAll ); - setTabOrder( d->bResumeAll, d->bCancel ); - } - - d->bCancel->setDefault( true ); - layout->addWidget( d->bCancel ); - - resize( sizeHint() ); -} - -RenameDlg::~RenameDlg() -{ - delete d; - // no need to delete Pushbuttons,... qt will do this -} - -void RenameDlg::enableRenameButton(const TQString &newDest) -{ - if ( newDest != TDEIO::decodeFileName( d->dest.fileName() ) && !newDest.isEmpty() ) - { - d->bRename->setEnabled( true ); - d->bRename->setDefault( true ); - if ( d->bOverwrite ) - d->bOverwrite->setEnabled( false ); // prevent confusion (#83114) - } - else - { - d->bRename->setEnabled( false ); - if ( d->bOverwrite ) - d->bOverwrite->setEnabled( true ); - } -} - -KURL RenameDlg::newDestURL() -{ - KURL newDest( d->dest ); - TQString fileName = d->m_pLineEdit->text(); - newDest.setFileName( TDEIO::encodeFileName( fileName ) ); - return newDest; -} - -void RenameDlg::b0Pressed() -{ - done( 0 ); -} - -// Rename -void RenameDlg::b1Pressed() -{ - if ( d->m_pLineEdit->text().isEmpty() ) - return; - - KURL u = newDestURL(); - if ( !u.isValid() ) - { - KMessageBox::error( this, i18n( "Malformed URL\n%1" ).arg( u.url() ) ); - return; - } - - done( 1 ); -} - -TQString RenameDlg::suggestName(const KURL& baseURL, const TQString& oldName) -{ - TQString dotSuffix, suggestedName; - TQString basename = oldName; - - int index = basename.find( '.' ); - if ( index != -1 ) { - dotSuffix = basename.mid( index ); - basename.truncate( index ); - } - - int pos = basename.findRev( '_' ); - if(pos != -1 ){ - TQString tmp = basename.mid( pos+1 ); - bool ok; - int number = tmp.toInt( &ok ); - if ( !ok ) {// ok there is no number - suggestedName = basename + "1" + dotSuffix; - } - else { - // yes there's already a number behind the _ so increment it by one - basename.replace( pos+1, tmp.length(), TQString::number(number+1) ); - suggestedName = basename + dotSuffix; - } - } - else // no underscore yet - suggestedName = basename + "_1" + dotSuffix ; - - // Check if suggested name already exists - bool exists = false; - // TODO: network transparency. However, using NetAccess from a modal dialog - // could be a problem, no? (given that it uses a modal widget itself....) - if ( baseURL.isLocalFile() ) - exists = TQFileInfo( baseURL.path(+1) + suggestedName ).exists(); - - if ( !exists ) - return suggestedName; - else // already exists -> recurse - return suggestName( baseURL, suggestedName ); -} - -// Propose button clicked -void RenameDlg::b8Pressed() -{ - /* no name to play with */ - if ( d->m_pLineEdit->text().isEmpty() ) - return; - - KURL destDirectory( d->dest ); - destDirectory.setPath( destDirectory.directory() ); - d->m_pLineEdit->setText( suggestName( destDirectory, d->m_pLineEdit->text() ) ); - return; -} - -void RenameDlg::b2Pressed() -{ - done( 2 ); -} - -void RenameDlg::b3Pressed() -{ - done( 3 ); -} - -void RenameDlg::b4Pressed() -{ - done( 4 ); -} - -void RenameDlg::b5Pressed() -{ - done( 5 ); -} - -void RenameDlg::b6Pressed() -{ - done( 6 ); -} - -void RenameDlg::b7Pressed() -{ - done( 7 ); -} - -static TQString mime( const KURL& src ) -{ - KMimeType::Ptr type = KMimeType::findByURL( src ); - //if( type->name() == KMimeType::defaultMimeType() ){ // ok no mimetype - // TQString ty = TDEIO::NetAccess::mimetype(d->src ); - // return ty; - return type->name(); -} - -/** This will figure out the mimetypes and query for a plugin - * Loads it then and asks the plugin if it wants to do the job - * We'll take the first available mimetype - * The scanning for a mimetype will be done in 2 ways - * - */ -void RenameDlg::pluginHandling() -{ - d->mimeSrc = mime( d->src ); - d->mimeDest = mime(d->dest ); - - kdDebug(7024) << "Source Mimetype: "<< d->mimeSrc << endl; - kdDebug(7024) << "Dest Mimetype: "<< d->mimeDest << endl; -} - - -RenameDlg_Result TDEIO::open_RenameDlg( const TQString & _caption, - const TQString & _src, const TQString & _dest, - RenameDlg_Mode _mode, - TQString& _new, - TDEIO::filesize_t sizeSrc, - TDEIO::filesize_t sizeDest, - time_t ctimeSrc, - time_t ctimeDest, - time_t mtimeSrc, - time_t mtimeDest) -{ - Q_ASSERT(kapp); - - RenameDlg dlg( 0L, _caption, _src, _dest, _mode, - sizeSrc, sizeDest, ctimeSrc, ctimeDest, mtimeSrc, mtimeDest, - true /*modal*/ ); - int i = dlg.exec(); - _new = dlg.newDestURL().path(); - - return (RenameDlg_Result)i; -} - -#include "renamedlg.moc" - - - - - diff --git a/kio/kio/renamedlg.h b/kio/kio/renamedlg.h deleted file mode 100644 index 38dcac925..000000000 --- a/kio/kio/renamedlg.h +++ /dev/null @@ -1,153 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Stephan Kulow <coolo@kde.org> - David Faure <faure@kde.org> - 2001 Holger Freyther <freyther@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_rename_dlg__ -#define __kio_rename_dlg__ - -#include <kurl.h> -#include <tqdialog.h> -#include <tqstring.h> -#include <sys/types.h> - -#include <kio/global.h> - -namespace TDEIO { - -// KDE4: get rid of M_OVERWRITE_ITSELF, trigger it internally if src==dest -enum RenameDlg_Mode { M_OVERWRITE = 1, M_OVERWRITE_ITSELF = 2, M_SKIP = 4, M_SINGLE = 8, M_MULTI = 16, M_RESUME = 32, M_NORENAME = 64 }; - -/** - * The result of open_RenameDlg(). - */ -enum RenameDlg_Result { R_RESUME = 6, R_RESUME_ALL = 7, R_OVERWRITE = 4, R_OVERWRITE_ALL = 5, R_SKIP = 2, R_AUTO_SKIP = 3, R_RENAME = 1, R_CANCEL = 0 }; - - -/** - * A dialog for the options to rename two files. - * @short A dialog for renaming files. - * @since 3.1 - */ -class TDEIO_EXPORT RenameDlg : public TQDialog -{ - Q_OBJECT -public: - /** - * Construct a "rename" dialog. - * @param parent parent widget (often 0) - * @param caption the caption for the dialog box - * @param src the url to the file/dir we're trying to copy, as it's part of the text message - * @param dest the path to destination file/dir, i.e. the one that already exists - * @param mode parameters for the dialog (which buttons to show...), - * @param sizeSrc size of source file - * @param sizeDest size of destination file - * @param ctimeSrc creation time of source file - * @param ctimeDest creation time of destination file - * @param mtimeSrc modification time of source file - * @param mtimeDest modification time of destination file - * @param modal set to true for a modal dialog - * @see RenameDlg_Mode - */ - RenameDlg( TQWidget *parent, const TQString & caption, - // KDE4: make those KURLs, and use pathOrURL() internally. - const TQString & src, const TQString & dest, - RenameDlg_Mode mode, - TDEIO::filesize_t sizeSrc = (TDEIO::filesize_t) -1, - TDEIO::filesize_t sizeDest = (TDEIO::filesize_t) -1, - time_t ctimeSrc = (time_t) -1, - time_t ctimeDest = (time_t) -1, - time_t mtimeSrc = (time_t) -1, - time_t mtimeDest = (time_t) -1, - bool modal = false ); - ~RenameDlg(); - - /** - * @return the new destination - * valid only if RENAME was chosen - */ - KURL newDestURL(); - - /** - * Given a directory path and a filename (which usually exists already), - * this function returns a suggested name for a file that doesn't exist - * in that directory. The existence is only checked for local urls though. - * The suggested file name is of the form foo_1 foo_2 etc. - * @since 3.4 - */ - static TQString suggestName(const KURL& baseURL, const TQString& oldName); - -public slots: - /// KDE4: rename to cancelPressed(), renamePressed() etc. - void b0Pressed(); - void b1Pressed(); - void b2Pressed(); - void b3Pressed(); - void b4Pressed(); - void b5Pressed(); - void b6Pressed(); - void b7Pressed(); - void b8Pressed(); - -protected slots: - void enableRenameButton(const TQString &); -private: - class RenameDlgPrivate; - RenameDlgPrivate *d; - void pluginHandling( ); -}; - - /** - * \addtogroup renamedlg "RenameDlg related Functions" - * @{ - * \relates TDEIO::RenameDlg - * Construct a modal, parent-less "rename" dialog, and return - * a result code, as well as the new dest. Much easier to use than the - * class RenameDlg directly. - - * @param caption the caption for the dialog box - * @param src the URL of the file/dir we're trying to copy, as it's part of the text message - * @param dest the URL of the destination file/dir, i.e. the one that already exists - * @param mode parameters for the dialog (which buttons to show...), - * see RenameDlg_Mode - * @param newDest the new destination path, valid if R_RENAME was returned. - * @param sizeSrc size of source file - * @param sizeDest size of destination file - * @param ctimeSrc creation time of source file - * @param ctimeDest creation time of destination file - * @param mtimeSrc modification time of source file - * @param mtimeDest modification time of destination file - * @return the result - */ -TDEIO_EXPORT RenameDlg_Result open_RenameDlg( const TQString & caption, - // KDE4: make those KURLs - const TQString& src, const TQString & dest, - RenameDlg_Mode mode, TQString& newDestPath, - TDEIO::filesize_t sizeSrc = (TDEIO::filesize_t) -1, - TDEIO::filesize_t sizeDest = (TDEIO::filesize_t) -1, - time_t ctimeSrc = (time_t) -1, - time_t ctimeDest = (time_t) -1, - time_t mtimeSrc = (time_t) -1, - time_t mtimeDest = (time_t) -1 - ); - -/*! @} */ - -} -#endif diff --git a/kio/kio/renamedlgplugin.h b/kio/kio/renamedlgplugin.h deleted file mode 100644 index b3604b084..000000000 --- a/kio/kio/renamedlgplugin.h +++ /dev/null @@ -1,59 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2001 Holger Freyther <freyther@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef renamedlgplugin_h -#define renamedlgplugin_h - -#include <kio/renamedlg.h> -#include <tqdialog.h> -#include <sys/types.h> -#include <tqstring.h> -#include <tqstringlist.h> - -/** - * This is the base class for all RenameDlg plugins. - * @short Base class for RenameDlg plugins. - * @since 3.1 - */ -class TDEIO_EXPORT RenameDlgPlugin : public TQWidget -{ -public: - /** - * This is the c'tor. - */ - RenameDlgPlugin(TQDialog *dialog, const char *name, const TQStringList &/*list*/ = TQStringList() ): TQWidget(dialog, name ) {}; - - /** - * This function will be called by RenameDlg. The params are infos about the files. - * @return If the plugin want's to display it return true, if not return false - */ - virtual bool initialize(TDEIO::RenameDlg_Mode /*mod*/ , const TQString &/*_src*/, const TQString &/*_dest*/, - const TQString &/*mimeSrc*/, - const TQString &/*mimeDest*/, - TDEIO::filesize_t /*sizeSrc*/, - TDEIO::filesize_t /*sizeDest*/, - time_t /*ctimeSrc*/, - time_t /*ctimeDest*/, - time_t /*mtimeSrc*/, - time_t /*mtimeDest*/ ) {return false;}; - -}; - -#endif - diff --git a/kio/kio/scheduler.cpp b/kio/kio/scheduler.cpp deleted file mode 100644 index 09560cb8b..000000000 --- a/kio/kio/scheduler.cpp +++ /dev/null @@ -1,922 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Stephan Kulow <coolo@kde.org> - Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kio/sessiondata.h" -#include "kio/slaveconfig.h" -#include "kio/scheduler.h" -#include "kio/authinfo.h" -#include "kio/slave.h" -#include <tqptrlist.h> -#include <tqdict.h> - -#include <dcopclient.h> - -#include <kdebug.h> -#include <kglobal.h> -#include <kprotocolmanager.h> -#include <kprotocolinfo.h> -#include <assert.h> -#include <kstaticdeleter.h> -#include <tdesu/client.h> - - -// Slaves may be idle for MAX_SLAVE_IDLE time before they are being returned -// to the system wide slave pool. (3 minutes) -#define MAX_SLAVE_IDLE (3*60) - -using namespace TDEIO; - -template class TQDict<TDEIO::Scheduler::ProtocolInfo>; - -Scheduler *Scheduler::instance = 0; - -class TDEIO::SlaveList: public TQPtrList<Slave> -{ - public: - SlaveList() { } -}; - -// -// There are two kinds of protocol: -// (1) The protocol of the url -// (2) The actual protocol that the io-slave uses. -// -// These two often match, but not necasserily. Most notably, they don't -// match when doing ftp via a proxy. -// In that case (1) is ftp, but (2) is http. -// -// JobData::protocol stores (2) while Job::url().protocol() returns (1). -// The ProtocolInfoDict is indexed with (2). -// -// We schedule slaves based on (2) but tell the slave about (1) via -// Slave::setProtocol(). - -class TDEIO::Scheduler::JobData -{ -public: - JobData() : checkOnHold(false) { } - -public: - TQString protocol; - TQString proxy; - bool checkOnHold; -}; - -class TDEIO::Scheduler::ExtraJobData: public TQPtrDict<TDEIO::Scheduler::JobData> -{ -public: - ExtraJobData() { setAutoDelete(true); } -}; - -class TDEIO::Scheduler::ProtocolInfo -{ -public: - ProtocolInfo() : maxSlaves(1), skipCount(0) - { - joblist.setAutoDelete(false); - } - - TQPtrList<SimpleJob> joblist; - SlaveList activeSlaves; - int maxSlaves; - int skipCount; - TQString protocol; -}; - -class TDEIO::Scheduler::ProtocolInfoDict : public TQDict<TDEIO::Scheduler::ProtocolInfo> -{ - public: - ProtocolInfoDict() { } - - TDEIO::Scheduler::ProtocolInfo *get( const TQString &protocol); -}; - -TDEIO::Scheduler::ProtocolInfo * -TDEIO::Scheduler::ProtocolInfoDict::get(const TQString &protocol) -{ - ProtocolInfo *info = find(protocol); - if (!info) - { - info = new ProtocolInfo; - info->protocol = protocol; - info->maxSlaves = KProtocolInfo::maxSlaves( protocol ); - - insert(protocol, info); - } - return info; -} - - -Scheduler::Scheduler() - : DCOPObject( "TDEIO::Scheduler" ), - TQObject(kapp, "scheduler"), - slaveTimer(0, "Scheduler::slaveTimer"), - coSlaveTimer(0, "Scheduler::coSlaveTimer"), - cleanupTimer(0, "Scheduler::cleanupTimer") -{ - checkOnHold = true; // !! Always check with KLauncher for the first request. - slaveOnHold = 0; - protInfoDict = new ProtocolInfoDict; - slaveList = new SlaveList; - idleSlaves = new SlaveList; - coIdleSlaves = new SlaveList; - extraJobData = new ExtraJobData; - sessionData = new SessionData; - slaveConfig = SlaveConfig::self(); - connect(&slaveTimer, TQT_SIGNAL(timeout()), TQT_SLOT(startStep())); - connect(&coSlaveTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotScheduleCoSlave())); - connect(&cleanupTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotCleanIdleSlaves())); - busy = false; -} - -Scheduler::~Scheduler() -{ - protInfoDict->setAutoDelete(true); - delete protInfoDict; protInfoDict = 0; - delete idleSlaves; idleSlaves = 0; - delete coIdleSlaves; coIdleSlaves = 0; - slaveList->setAutoDelete(true); - delete slaveList; slaveList = 0; - delete extraJobData; extraJobData = 0; - delete sessionData; sessionData = 0; - instance = 0; -} - -void -Scheduler::debug_info() -{ -} - -bool Scheduler::process(const TQCString &fun, const TQByteArray &data, TQCString &replyType, TQByteArray &replyData ) -{ - if ( fun != "reparseSlaveConfiguration(TQString)" ) - return DCOPObject::process( fun, data, replyType, replyData ); - - slaveConfig = SlaveConfig::self(); - replyType = "void"; - TQDataStream stream( data, IO_ReadOnly ); - TQString proto; - stream >> proto; - - kdDebug( 7006 ) << "reparseConfiguration( " << proto << " )" << endl; - KProtocolManager::reparseConfiguration(); - slaveConfig->reset(); - sessionData->reset(); - NetRC::self()->reload(); - - Slave *slave = slaveList->first(); - for (; slave; slave = slaveList->next() ) - if ( slave->slaveProtocol() == proto || proto.isEmpty() ) - { - slave->send( CMD_REPARSECONFIGURATION ); - slave->resetHost(); - } - return true; -} - -QCStringList Scheduler::functions() -{ - QCStringList funcs = DCOPObject::functions(); - funcs << "void reparseSlaveConfiguration(TQString)"; - return funcs; -} - -void Scheduler::_doJob(SimpleJob *job) { - JobData *jobData = new JobData; - jobData->protocol = KProtocolManager::slaveProtocol(job->url(), jobData->proxy); -// kdDebug(7006) << "Scheduler::_doJob protocol=" << jobData->protocol << endl; - if (job->command() == CMD_GET) - { - jobData->checkOnHold = checkOnHold; - checkOnHold = false; - } - extraJobData->replace(job, jobData); - newJobs.append(job); - slaveTimer.start(0, true); -#ifndef NDEBUG - if (newJobs.count() > 150) - kdDebug() << "WARNING - TDEIO::Scheduler got more than 150 jobs! This shows a misuse in your app (yes, a job is a TQObject)." << endl; -#endif -} - -void Scheduler::_scheduleJob(SimpleJob *job) { - newJobs.removeRef(job); - JobData *jobData = extraJobData->find(job); - if (!jobData) -{ - kdFatal(7006) << "BUG! _ScheduleJob(): No extraJobData for job!" << endl; - return; -} - TQString protocol = jobData->protocol; -// kdDebug(7006) << "Scheduler::_scheduleJob protocol=" << protocol << endl; - ProtocolInfo *protInfo = protInfoDict->get(protocol); - protInfo->joblist.append(job); - - slaveTimer.start(0, true); -} - -void Scheduler::_cancelJob(SimpleJob *job) { -// kdDebug(7006) << "Scheduler: canceling job " << job << endl; - Slave *slave = job->slave(); - if ( !slave ) - { - // was not yet running (don't call this on a finished job!) - JobData *jobData = extraJobData->find(job); - if (!jobData) - return; // I said: "Don't call this on a finished job!" - - newJobs.removeRef(job); - ProtocolInfo *protInfo = protInfoDict->get(jobData->protocol); - protInfo->joblist.removeRef(job); - - // Search all slaves to see if job is in the queue of a coSlave - slave = slaveList->first(); - for(; slave; slave = slaveList->next()) - { - JobList *list = coSlaves.find(slave); - if (list && list->removeRef(job)) - break; // Job was found and removed. - // Fall through to kill the slave as well! - } - if (!slave) - { - extraJobData->remove(job); - return; // Job was not yet running and not in a coSlave queue. - } - } - kdDebug(7006) << "Scheduler: killing slave " << slave->slave_pid() << endl; - slave->kill(); - _jobFinished( job, slave ); - slotSlaveDied( slave); -} - -void Scheduler::startStep() -{ - while(newJobs.count()) - { - (void) startJobDirect(); - } - TQDictIterator<TDEIO::Scheduler::ProtocolInfo> it(*protInfoDict); - while(it.current()) - { - if (startJobScheduled(it.current())) return; - ++it; - } -} - -void Scheduler::setupSlave(TDEIO::Slave *slave, const KURL &url, const TQString &protocol, const TQString &proxy , bool newSlave, const TDEIO::MetaData *config) -{ - TQString host = url.host(); - int port = url.port(); - TQString user = url.user(); - TQString passwd = url.pass(); - - if ((newSlave) || - (slave->host() != host) || - (slave->port() != port) || - (slave->user() != user) || - (slave->passwd() != passwd)) - { - slaveConfig = SlaveConfig::self(); - - MetaData configData = slaveConfig->configData(protocol, host); - sessionData->configDataFor( configData, protocol, host ); - - configData["UseProxy"] = proxy; - - TQString autoLogin = configData["EnableAutoLogin"].lower(); - if ( autoLogin == "true" ) - { - NetRC::AutoLogin l; - l.login = user; - bool usern = (protocol == "ftp"); - if ( NetRC::self()->lookup( url, l, usern) ) - { - configData["autoLoginUser"] = l.login; - configData["autoLoginPass"] = l.password; - if ( usern ) - { - TQString macdef; - TQMap<TQString, TQStringList>::ConstIterator it = l.macdef.begin(); - for ( ; it != l.macdef.end(); ++it ) - macdef += it.key() + '\\' + it.data().join( "\\" ) + '\n'; - configData["autoLoginMacro"] = macdef; - } - } - } - if (config) - configData += *config; - slave->setConfig(configData); - slave->setProtocol(url.protocol()); - slave->setHost(host, port, user, passwd); - } -} - -bool Scheduler::startJobScheduled(ProtocolInfo *protInfo) -{ - if (protInfo->joblist.isEmpty()) - return false; - -// kdDebug(7006) << "Scheduling job" << endl; - debug_info(); - bool newSlave = false; - - SimpleJob *job = 0; - Slave *slave = 0; - - if (protInfo->skipCount > 2) - { - bool dummy; - // Prevent starvation. We skip the first entry in the queue at most - // 2 times in a row. The - protInfo->skipCount = 0; - job = protInfo->joblist.at(0); - slave = findIdleSlave(protInfo, job, dummy ); - } - else - { - bool exact=false; - SimpleJob *firstJob = 0; - Slave *firstSlave = 0; - for(uint i = 0; (i < protInfo->joblist.count()) && (i < 10); i++) - { - job = protInfo->joblist.at(i); - slave = findIdleSlave(protInfo, job, exact); - if (!firstSlave) - { - firstJob = job; - firstSlave = slave; - } - if (!slave) break; - if (exact) break; - } - - if (!exact) - { - slave = firstSlave; - job = firstJob; - } - if (job == firstJob) - protInfo->skipCount = 0; - else - protInfo->skipCount++; - } - - if (!slave) - { - if ( protInfo->maxSlaves > static_cast<int>(protInfo->activeSlaves.count()) ) - { - newSlave = true; - slave = createSlave(protInfo, job, job->url()); - if (!slave) - slaveTimer.start(0, true); - } - } - - if (!slave) - { -// kdDebug(7006) << "No slaves available" << endl; -// kdDebug(7006) << " -- active: " << protInfo->activeSlaves.count() << endl; - return false; - } - - protInfo->activeSlaves.append(slave); - idleSlaves->removeRef(slave); - protInfo->joblist.removeRef(job); -// kdDebug(7006) << "scheduler: job started " << job << endl; - - - JobData *jobData = extraJobData->find(job); - setupSlave(slave, job->url(), jobData->protocol, jobData->proxy, newSlave); - job->start(slave); - - slaveTimer.start(0, true); - return true; -} - -bool Scheduler::startJobDirect() -{ - debug_info(); - SimpleJob *job = newJobs.take(0); - JobData *jobData = extraJobData->find(job); - if (!jobData) - { - kdFatal(7006) << "BUG! startjobDirect(): No extraJobData for job!" - << endl; - return false; - } - TQString protocol = jobData->protocol; - ProtocolInfo *protInfo = protInfoDict->get(protocol); - - bool newSlave = false; - bool dummy; - - // Look for matching slave - Slave *slave = findIdleSlave(protInfo, job, dummy); - - if (!slave) - { - newSlave = true; - slave = createSlave(protInfo, job, job->url()); - } - - if (!slave) - return false; - - idleSlaves->removeRef(slave); -// kdDebug(7006) << "scheduler: job started " << job << endl; - - setupSlave(slave, job->url(), protocol, jobData->proxy, newSlave); - job->start(slave); - return true; -} - -static Slave *searchIdleList(SlaveList *idleSlaves, const KURL &url, const TQString &protocol, bool &exact) -{ - TQString host = url.host(); - int port = url.port(); - TQString user = url.user(); - exact = true; - - for( Slave *slave = idleSlaves->first(); - slave; - slave = idleSlaves->next()) - { - if ((protocol == slave->slaveProtocol()) && - (host == slave->host()) && - (port == slave->port()) && - (user == slave->user())) - return slave; - } - - exact = false; - - // Look for slightly matching slave - for( Slave *slave = idleSlaves->first(); - slave; - slave = idleSlaves->next()) - { - if (protocol == slave->slaveProtocol()) - return slave; - } - return 0; -} - -Slave *Scheduler::findIdleSlave(ProtocolInfo *, SimpleJob *job, bool &exact) -{ - Slave *slave = 0; - JobData *jobData = extraJobData->find(job); - if (!jobData) - { - kdFatal(7006) << "BUG! findIdleSlave(): No extraJobData for job!" << endl; - return 0; - } - if (jobData->checkOnHold) - { - slave = Slave::holdSlave(jobData->protocol, job->url()); - if (slave) - return slave; - } - if (slaveOnHold) - { - // Make sure that the job wants to do a GET or a POST, and with no offset - bool bCanReuse = (job->command() == CMD_GET); - TDEIO::TransferJob * tJob = dynamic_cast<TDEIO::TransferJob *>(job); - if ( tJob ) - { - bCanReuse = (job->command() == CMD_GET || job->command() == CMD_SPECIAL); - if ( bCanReuse ) - { - TDEIO::MetaData outgoing = tJob->outgoingMetaData(); - TQString resume = (!outgoing.contains("resume")) ? TQString() : outgoing["resume"]; - kdDebug(7006) << "Resume metadata is '" << resume << "'" << endl; - bCanReuse = (resume.isEmpty() || resume == "0"); - } - } -// kdDebug(7006) << "bCanReuse = " << bCanReuse << endl; - if (bCanReuse) - { - if (job->url() == urlOnHold) - { - kdDebug(7006) << "HOLD: Reusing held slave for " << urlOnHold.prettyURL() << endl; - slave = slaveOnHold; - } - else - { - kdDebug(7006) << "HOLD: Discarding held slave (" << urlOnHold.prettyURL() << ")" << endl; - slaveOnHold->kill(); - } - slaveOnHold = 0; - urlOnHold = KURL(); - } - if (slave) - return slave; - } - - return searchIdleList(idleSlaves, job->url(), jobData->protocol, exact); -} - -Slave *Scheduler::createSlave(ProtocolInfo *protInfo, SimpleJob *job, const KURL &url) -{ - int error; - TQString errortext; - Slave *slave = Slave::createSlave(protInfo->protocol, url, error, errortext); - if (slave) - { - slaveList->append(slave); - idleSlaves->append(slave); - connect(slave, TQT_SIGNAL(slaveDied(TDEIO::Slave *)), - TQT_SLOT(slotSlaveDied(TDEIO::Slave *))); - connect(slave, TQT_SIGNAL(slaveStatus(pid_t,const TQCString &,const TQString &, bool)), - TQT_SLOT(slotSlaveStatus(pid_t,const TQCString &, const TQString &, bool))); - - connect(slave,TQT_SIGNAL(authorizationKey(const TQCString&, const TQCString&, bool)), - sessionData,TQT_SLOT(slotAuthData(const TQCString&, const TQCString&, bool))); - connect(slave,TQT_SIGNAL(delAuthorization(const TQCString&)), sessionData, - TQT_SLOT(slotDelAuthData(const TQCString&))); - } - else - { - kdError() <<": couldn't create slave : " << errortext << endl; - if (job) - { - protInfo->joblist.removeRef(job); - extraJobData->remove(job); - job->slotError( error, errortext ); - } - } - return slave; -} - -void Scheduler::slotSlaveStatus(pid_t, const TQCString &, const TQString &, bool) -{ -} - -void Scheduler::_jobFinished(SimpleJob *job, Slave *slave) -{ - JobData *jobData = extraJobData->take(job); - if (!jobData) - { - kdFatal(7006) << "BUG! _jobFinished(): No extraJobData for job!" << endl; - return; - } - ProtocolInfo *protInfo = protInfoDict->get(jobData->protocol); - delete jobData; - slave->disconnect(job); - protInfo->activeSlaves.removeRef(slave); - if (slave->isAlive()) - { - JobList *list = coSlaves.find(slave); - if (list) - { - assert(slave->isConnected()); - assert(!coIdleSlaves->contains(slave)); - coIdleSlaves->append(slave); - if (!list->isEmpty()) - coSlaveTimer.start(0, true); - return; - } - else - { - assert(!slave->isConnected()); - idleSlaves->append(slave); - slave->setIdle(); - _scheduleCleanup(); -// slave->send( CMD_SLAVE_STATUS ); - } - } - if (protInfo->joblist.count()) - { - slaveTimer.start(0, true); - } -} - -void Scheduler::slotSlaveDied(TDEIO::Slave *slave) -{ - assert(!slave->isAlive()); - ProtocolInfo *protInfo = protInfoDict->get(slave->slaveProtocol()); - protInfo->activeSlaves.removeRef(slave); - if (slave == slaveOnHold) - { - slaveOnHold = 0; - urlOnHold = KURL(); - } - idleSlaves->removeRef(slave); - JobList *list = coSlaves.find(slave); - if (list) - { - // coSlave dies, kill jobs waiting in queue - disconnectSlave(slave); - } - - if (!slaveList->removeRef(slave)) - kdDebug(7006) << "Scheduler: BUG!! Slave " << slave << "/" << slave->slave_pid() << " died, but is NOT in slaveList!!!\n" << endl; - else - slave->deref(); // Delete slave -} - -void Scheduler::slotCleanIdleSlaves() -{ - for(Slave *slave = idleSlaves->first();slave;) - { - if (slave->idleTime() >= MAX_SLAVE_IDLE) - { - // kdDebug(7006) << "Removing idle slave: " << slave->slaveProtocol() << " " << slave->host() << endl; - Slave *removeSlave = slave; - slave = idleSlaves->next(); - idleSlaves->removeRef(removeSlave); - slaveList->removeRef(removeSlave); - removeSlave->connection()->close(); - removeSlave->deref(); - } - else - { - slave = idleSlaves->next(); - } - } - _scheduleCleanup(); -} - -void Scheduler::_scheduleCleanup() -{ - if (idleSlaves->count()) - { - if (!cleanupTimer.isActive()) - cleanupTimer.start( MAX_SLAVE_IDLE*1000, true ); - } -} - -void Scheduler::_putSlaveOnHold(TDEIO::SimpleJob *job, const KURL &url) -{ - Slave *slave = job->slave(); - slave->disconnect(job); - - if (slaveOnHold) - { - slaveOnHold->kill(); - } - slaveOnHold = slave; - urlOnHold = url; - slaveOnHold->suspend(); -} - -void Scheduler::_publishSlaveOnHold() -{ - if (!slaveOnHold) - return; - - slaveOnHold->hold(urlOnHold); -} - -void Scheduler::_removeSlaveOnHold() -{ - if (slaveOnHold) - { - slaveOnHold->kill(); - } - slaveOnHold = 0; - urlOnHold = KURL(); -} - -Slave * -Scheduler::_getConnectedSlave(const KURL &url, const TDEIO::MetaData &config ) -{ - TQString proxy; - TQString protocol = KProtocolManager::slaveProtocol(url, proxy); - bool dummy; - Slave *slave = searchIdleList(idleSlaves, url, protocol, dummy); - if (!slave) - { - ProtocolInfo *protInfo = protInfoDict->get(protocol); - slave = createSlave(protInfo, 0, url); - } - if (!slave) - return 0; // Error - idleSlaves->removeRef(slave); - - setupSlave(slave, url, protocol, proxy, true, &config); - - slave->send( CMD_CONNECT ); - connect(slave, TQT_SIGNAL(connected()), - TQT_SLOT(slotSlaveConnected())); - connect(slave, TQT_SIGNAL(error(int, const TQString &)), - TQT_SLOT(slotSlaveError(int, const TQString &))); - - coSlaves.insert(slave, new TQPtrList<SimpleJob>()); -// kdDebug(7006) << "_getConnectedSlave( " << slave << ")" << endl; - return slave; -} - -void -Scheduler::slotScheduleCoSlave() -{ - Slave *nextSlave; - slaveConfig = SlaveConfig::self(); - for(Slave *slave = coIdleSlaves->first(); - slave; - slave = nextSlave) - { - nextSlave = coIdleSlaves->next(); - JobList *list = coSlaves.find(slave); - assert(list); - if (list && !list->isEmpty()) - { - SimpleJob *job = list->take(0); - coIdleSlaves->removeRef(slave); -// kdDebug(7006) << "scheduler: job started " << job << endl; - - assert(!coIdleSlaves->contains(slave)); - - KURL url =job->url(); - TQString host = url.host(); - int port = url.port(); - - if (slave->host() == "<reset>") - { - TQString user = url.user(); - TQString passwd = url.pass(); - - MetaData configData = slaveConfig->configData(url.protocol(), url.host()); - slave->setConfig(configData); - slave->setProtocol(url.protocol()); - slave->setHost(host, port, user, passwd); - } - - assert(slave->protocol() == url.protocol()); - assert(slave->host() == host); - assert(slave->port() == port); - job->start(slave); - } - } -} - -void -Scheduler::slotSlaveConnected() -{ - Slave *slave = (Slave *)sender(); -// kdDebug(7006) << "slotSlaveConnected( " << slave << ")" << endl; - slave->setConnected(true); - disconnect(slave, TQT_SIGNAL(connected()), - this, TQT_SLOT(slotSlaveConnected())); - emit slaveConnected(slave); - assert(!coIdleSlaves->contains(slave)); - coIdleSlaves->append(slave); - coSlaveTimer.start(0, true); -} - -void -Scheduler::slotSlaveError(int errorNr, const TQString &errorMsg) -{ - Slave *slave = (Slave *)sender(); - if (!slave->isConnected() || (coIdleSlaves->find(slave) != -1)) - { - // Only forward to application if slave is idle or still connecting. - emit slaveError(slave, errorNr, errorMsg); - } -} - -bool -Scheduler::_assignJobToSlave(TDEIO::Slave *slave, SimpleJob *job) -{ -// kdDebug(7006) << "_assignJobToSlave( " << job << ", " << slave << ")" << endl; - TQString dummy; - if ((slave->slaveProtocol() != KProtocolManager::slaveProtocol( job->url(), dummy )) - || - (!newJobs.removeRef(job))) - { - kdDebug(7006) << "_assignJobToSlave(): ERROR, nonmatching or unknown job." << endl; - job->kill(); - return false; - } - - JobList *list = coSlaves.find(slave); - assert(list); - if (!list) - { - kdDebug(7006) << "_assignJobToSlave(): ERROR, unknown slave." << endl; - job->kill(); - return false; - } - - assert(list->contains(job) == 0); - list->append(job); - coSlaveTimer.start(0, true); // Start job on timer event - - return true; -} - -bool -Scheduler::_disconnectSlave(TDEIO::Slave *slave) -{ -// kdDebug(7006) << "_disconnectSlave( " << slave << ")" << endl; - JobList *list = coSlaves.take(slave); - assert(list); - if (!list) - return false; - // Kill jobs still in queue. - while(!list->isEmpty()) - { - Job *job = list->take(0); - job->kill(); - } - delete list; - coIdleSlaves->removeRef(slave); - assert(!coIdleSlaves->contains(slave)); - disconnect(slave, TQT_SIGNAL(connected()), - this, TQT_SLOT(slotSlaveConnected())); - disconnect(slave, TQT_SIGNAL(error(int, const TQString &)), - this, TQT_SLOT(slotSlaveError(int, const TQString &))); - if (slave->isAlive()) - { - idleSlaves->append(slave); - slave->send( CMD_DISCONNECT ); - slave->setIdle(); - slave->setConnected(false); - _scheduleCleanup(); - } - return true; -} - -void -Scheduler::_checkSlaveOnHold(bool b) -{ - checkOnHold = b; -} - -void -Scheduler::_registerWindow(TQWidget *wid) -{ - if (!wid) - return; - - TQObject *obj = TQT_TQOBJECT(wid); - if (!m_windowList.contains(obj)) - { - // We must store the window Id because by the time - // the destroyed signal is emitted we can no longer - // access TQWidget::winId() (already destructed) - WId windowId = wid->winId(); - m_windowList.insert(obj, windowId); - connect(TQT_TQOBJECT(wid), TQT_SIGNAL(destroyed(TQObject *)), - this, TQT_SLOT(slotUnregisterWindow(TQObject*))); - TQByteArray params; - TQDataStream stream(params, IO_WriteOnly); - stream << windowId; - if( !kapp->dcopClient()->send( "kded", "kded", - "registerWindowId(long int)", params ) ) - kdDebug(7006) << "Could not register window with kded!" << endl; - } -} - -void -Scheduler::slotUnregisterWindow(TQObject *obj) -{ - if (!obj) - return; - - TQMap<TQObject *, WId>::Iterator it = m_windowList.find(obj); - if (it == m_windowList.end()) - return; - WId windowId = it.data(); - disconnect( it.key(), TQT_SIGNAL(destroyed(TQObject *)), - this, TQT_SLOT(slotUnregisterWindow(TQObject*))); - m_windowList.remove( it ); - if (kapp) - { - TQByteArray params; - TQDataStream stream(params, IO_WriteOnly); - stream << windowId; - kapp->dcopClient()->send( "kded", "kded", - "unregisterWindowId(long int)", params ); - } -} - -Scheduler* Scheduler::self() { - if ( !instance ) { - instance = new Scheduler; - } - return instance; -} - -void Scheduler::virtual_hook( int id, void* data ) -{ DCOPObject::virtual_hook( id, data ); } - - - -#include "scheduler.moc" diff --git a/kio/kio/scheduler.h b/kio/kio/scheduler.h deleted file mode 100644 index ac0764dc4..000000000 --- a/kio/kio/scheduler.h +++ /dev/null @@ -1,364 +0,0 @@ -// -*- c++ -*- -/* This file is part of the KDE libraries - Copyright (C) 2000 Stephan Kulow <coolo@kde.org> - Waldo Bastian <bastian@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef _kio_scheduler_h -#define _kio_scheduler_h - -#include "kio/job.h" -#include "kio/jobclasses.h" -#include <tqtimer.h> -#include <tqptrdict.h> -#include <tqmap.h> - -#include <dcopobject.h> - -namespace TDEIO { - - class Slave; - class SlaveList; - class SlaveConfig; - class SessionData; - - /** - * The TDEIO::Scheduler manages io-slaves for the application. - * It also queues jobs and assigns the job to a slave when one - * becomes available. - * - * There are 3 possible ways for a job to get a slave: - * - * <h3>1. Direct</h3> - * This is the default. When you create a job the - * TDEIO::Scheduler will be notified and will find either an existing - * slave that is idle or it will create a new slave for the job. - * - * Example: - * \code - * TransferJob *job = TDEIO::get(KURL("http://www.kde.org")); - * \endcode - * - * - * <h3>2. Scheduled</h3> - * If you create a lot of jobs, you might want not want to have a - * slave for each job. If you schedule a job, a maximum number - * of slaves will be created. When more jobs arrive, they will be - * queued. When a slave is finished with a job, it will be assigned - * a job from the queue. - * - * Example: - * \code - * TransferJob *job = TDEIO::get(KURL("http://www.kde.org")); - * TDEIO::Scheduler::scheduleJob(job); - * \endcode - * - * <h3>3. Connection Oriented</h3> - * For some operations it is important that multiple jobs use - * the same connection. This can only be ensured if all these jobs - * use the same slave. - * - * You can ask the scheduler to open a slave for connection oriented - * operations. You can then use the scheduler to assign jobs to this - * slave. The jobs will be queued and the slave will handle these jobs - * one after the other. - * - * Example: - * \code - * Slave *slave = TDEIO::Scheduler::getConnectedSlave( - * KURL("pop3://bastian:password@mail.kde.org")); - * TransferJob *job1 = TDEIO::get( - * KURL("pop3://bastian:password@mail.kde.org/msg1")); - * TDEIO::Scheduler::assignJobToSlave(slave, job1); - * TransferJob *job2 = TDEIO::get( - * KURL("pop3://bastian:password@mail.kde.org/msg2")); - * TDEIO::Scheduler::assignJobToSlave(slave, job2); - * TransferJob *job3 = TDEIO::get( - * KURL("pop3://bastian:password@mail.kde.org/msg3")); - * TDEIO::Scheduler::assignJobToSlave(slave, job3); - * - * // ... Wait for jobs to finish... - * - * TDEIO::Scheduler::disconnectSlave(slave); - * \endcode - * - * Note that you need to explicitly disconnect the slave when the - * connection goes down, so your error handler should contain: - * \code - * if (error == TDEIO::ERR_CONNECTION_BROKEN) - * TDEIO::Scheduler::disconnectSlave(slave); - * \endcode - * - * @see TDEIO::Slave - * @see TDEIO::Job - **/ - - class TDEIO_EXPORT Scheduler : public TQObject, virtual public DCOPObject { - Q_OBJECT - - public: - typedef TQPtrList<SimpleJob> JobList; - - // InfoDict needs Info, so we can't declare it private - class ProtocolInfo; - class JobData; - - ~Scheduler(); - - /** - * Register @p job with the scheduler. - * The default is to create a new slave for the job if no slave - * is available. This can be changed by calling scheduleJob. - * @param job the job to register - */ - static void doJob(SimpleJob *job) - { self()->_doJob(job); } - - /** - * Calling ths function makes that @p job gets scheduled for later - * execution, if multiple jobs are registered it might wait for - * other jobs to finish. - * @param job the job to schedule - */ - static void scheduleJob(SimpleJob *job) - { self()->_scheduleJob(job); } - - /** - * Stop the execution of a job. - * @param job the job to cancel - */ - static void cancelJob(SimpleJob *job) - { self()->_cancelJob(job); } - - /** - * Called when a job is done. - * @param job the finished job - * @param slave the slave that executed the @p job - */ - static void jobFinished(TDEIO::SimpleJob *job, TDEIO::Slave *slave) - { self()->_jobFinished(job, slave); } - - /** - * Puts a slave on notice. A next job may reuse this slave if it - * requests the same URL. - * - * A job can be put on hold after it has emit'ed its mimetype. - * Based on the mimetype, the program can give control to another - * component in the same process which can then resume the job - * by simply asking for the same URL again. - * @param job the job that should be stopped - * @param url the URL that is handled by the @p url - */ - static void putSlaveOnHold(TDEIO::SimpleJob *job, const KURL &url) - { self()->_putSlaveOnHold(job, url); } - - /** - * Removes any slave that might have been put on hold. If a slave - * was put on hold it will be killed. - */ - static void removeSlaveOnHold() - { self()->_removeSlaveOnHold(); } - - /** - * Send the slave that was put on hold back to KLauncher. This - * allows another process to take over the slave and resume the job - * that was started. - */ - static void publishSlaveOnHold() - { self()->_publishSlaveOnHold(); } - - /** - * Requests a slave for use in connection-oriented mode. - * - * @param url This defines the username,password,host & port to - * connect with. - * @param config Configuration data for the slave. - * - * @return A pointer to a connected slave or 0 if an error occurred. - * @see assignJobToSlave() - * @see disconnectSlave() - */ - static TDEIO::Slave *getConnectedSlave(const KURL &url, const TDEIO::MetaData &config = MetaData() ) - { return self()->_getConnectedSlave(url, config); } - - /* - * Uses @p slave to do @p job. - * This function should be called immediately after creating a Job. - * - * @param slave The slave to use. The slave must have been obtained - * with a call to getConnectedSlave and must not - * be currently assigned to any other job. - * @param job The job to do. - * - * @return true is successful, false otherwise. - * - * @see getConnectedSlave() - * @see disconnectSlave() - * @see slaveConnected() - * @see slaveError() - */ - static bool assignJobToSlave(TDEIO::Slave *slave, TDEIO::SimpleJob *job) - { return self()->_assignJobToSlave(slave, job); } - - /* - * Disconnects @p slave. - * - * @param slave The slave to disconnect. The slave must have been - * obtained with a call to getConnectedSlave - * and must not be assigned to any job. - * - * @return true is successful, false otherwise. - * - * @see getConnectedSlave - * @see assignJobToSlave - */ - static bool disconnectSlave(TDEIO::Slave *slave) - { return self()->_disconnectSlave(slave); } - - /** - * Send the slave that was put on hold back to KLauncher. This - * allows another process to take over the slave and resume the job - * the that was started. - * Register the mainwindow @p wid with the KIO subsystem - * Do not call this, it is called automatically from - * void TDEIO::Job::setWindow(TQWidget*). - * @param wid the window to register - * @since 3.1 - */ - static void registerWindow(TQWidget *wid) - { self()->_registerWindow(wid); } - - /** - * @internal - * Unregisters the window registered by registerWindow(). - */ - static void unregisterWindow(TQObject *wid) - { self()->slotUnregisterWindow(wid); } - - /** - * Function to connect signals emitted by the scheduler. - * - * @see slaveConnected() - * @see slaveError() - */ - static bool connect( const char *signal, const TQObject *receiver, - const char *member) - { return TQObject::connect(self(), signal, receiver, member); } - - static bool connect( const TQObject* sender, const char* signal, - const TQObject* receiver, const char* member ) - { return TQObject::connect(sender, signal, receiver, member); } - - static bool disconnect( const TQObject* sender, const char* signal, - const TQObject* receiver, const char* member ) - { return TQObject::disconnect(sender, signal, receiver, member); } - - bool connect( const TQObject *sender, const char *signal, - const char *member ) - { return TQObject::connect(sender, signal, member); } - - /** - * When true, the next job will check whether KLauncher has a slave - * on hold that is suitable for the job. - * @param b true when KLauncher has a job on hold - */ - static void checkSlaveOnHold(bool b) { self()->_checkSlaveOnHold(b); } - - void debug_info(); - - virtual bool process(const TQCString &fun, const TQByteArray &data, - TQCString& replyType, TQByteArray &replyData); - - virtual QCStringList functions(); - - public slots: - void slotSlaveDied(TDEIO::Slave *slave); - void slotSlaveStatus(pid_t pid, const TQCString &protocol, - const TQString &host, bool connected); - signals: - void slaveConnected(TDEIO::Slave *slave); - void slaveError(TDEIO::Slave *slave, int error, const TQString &errorMsg); - - protected: - void setupSlave(TDEIO::Slave *slave, const KURL &url, const TQString &protocol, const TQString &proxy , bool newSlave, const TDEIO::MetaData *config=0); - bool startJobScheduled(ProtocolInfo *protInfo); - bool startJobDirect(); - Scheduler(); - - protected slots: - void startStep(); - void slotCleanIdleSlaves(); - void slotSlaveConnected(); - void slotSlaveError(int error, const TQString &errorMsg); - void slotScheduleCoSlave(); - /// @since 3.1 - void slotUnregisterWindow(TQObject *); - - private: - class ProtocolInfoDict; - class ExtraJobData; - - Scheduler(const Scheduler&); - static Scheduler *self(); - static Scheduler *instance; - void _doJob(SimpleJob *job); - void _scheduleJob(SimpleJob *job); - void _cancelJob(SimpleJob *job); - void _jobFinished(TDEIO::SimpleJob *job, TDEIO::Slave *slave); - void _scheduleCleanup(); - void _putSlaveOnHold(TDEIO::SimpleJob *job, const KURL &url); - void _removeSlaveOnHold(); - Slave *_getConnectedSlave(const KURL &url, const TDEIO::MetaData &metaData ); - bool _assignJobToSlave(TDEIO::Slave *slave, TDEIO::SimpleJob *job); - bool _disconnectSlave(TDEIO::Slave *slave); - void _checkSlaveOnHold(bool b); - void _publishSlaveOnHold(); - void _registerWindow(TQWidget *wid); - - Slave *findIdleSlave(ProtocolInfo *protInfo, SimpleJob *job, bool &exact); - Slave *createSlave(ProtocolInfo *protInfo, SimpleJob *job, const KURL &url); - - - TQTimer slaveTimer; - TQTimer coSlaveTimer; - TQTimer cleanupTimer; - bool busy; - - SlaveList *slaveList; - SlaveList *idleSlaves; - SlaveList *coIdleSlaves; - - ProtocolInfoDict *protInfoDict; - Slave *slaveOnHold; - KURL urlOnHold; - JobList newJobs; - - TQPtrDict<JobList> coSlaves; - ExtraJobData *extraJobData; - SlaveConfig *slaveConfig; - SessionData *sessionData; - bool checkOnHold; - TQMap<TQObject *,WId> m_windowList; - protected: - virtual void virtual_hook( int id, void* data ); - private: - class SchedulerPrivate* d; -}; - -} -#endif diff --git a/kio/kio/sessiondata.cpp b/kio/kio/sessiondata.cpp deleted file mode 100644 index e2517cc73..000000000 --- a/kio/kio/sessiondata.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2000 Dawit Alemayehu <adawit@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License (LGPL) as published by the Free Software Foundation; - either version 2 of the License, or (at your option) any - later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, - Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include <tqptrlist.h> -#include <tqtextcodec.h> - -#include <kdebug.h> -#include <kconfig.h> -#include <kglobal.h> -#include <klocale.h> -#include <kcharsets.h> -#include <dcopclient.h> -#include <kprotocolmanager.h> -#include <kstandarddirs.h> - -#include <tdesu/client.h> -#include <kio/slaveconfig.h> -#include <kio/http_slave_defaults.h> - -#include "sessiondata.h" -#include "sessiondata.moc" - -namespace TDEIO { - -/***************************** SessionData::AuthData ************************/ -struct SessionData::AuthData -{ - -public: - AuthData() {} - - AuthData(const TQCString& k, const TQCString& g, bool p) { - key = k; - group = g; - persist = p; - } - - bool isKeyMatch( const TQCString& val ) const { - return (val==key); - } - - bool isGroupMatch( const TQCString& val ) const { - return (val==group); - } - - TQCString key; - TQCString group; - bool persist; -}; - -/************************* SessionData::AuthDataList ****************************/ -class SessionData::AuthDataList : public TQPtrList<SessionData::AuthData> -{ -public: - AuthDataList(); - ~AuthDataList(); - - void addData( SessionData::AuthData* ); - void removeData( const TQCString& ); - - bool pingCacheDaemon(); - void registerAuthData( SessionData::AuthData* ); - void unregisterAuthData( SessionData::AuthData* ); - void purgeCachedData(); - -private: -#ifdef Q_OS_UNIX - KDEsuClient * m_tdesuClient; -#endif -}; - -SessionData::AuthDataList::AuthDataList() -{ -#ifdef Q_OS_UNIX - m_tdesuClient = new KDEsuClient; -#endif - setAutoDelete(true); -} - -SessionData::AuthDataList::~AuthDataList() -{ - purgeCachedData(); -#ifdef Q_OS_UNIX - delete m_tdesuClient; - m_tdesuClient = 0; -#endif -} - -void SessionData::AuthDataList::addData( SessionData::AuthData* d ) -{ - TQPtrListIterator<SessionData::AuthData> it ( *this ); - for ( ; it.current(); ++it ) - { - if ( it.current()->isKeyMatch( d->key ) ) - return; - } - registerAuthData( d ); - append( d ); -} - -void SessionData::AuthDataList::removeData( const TQCString& gkey ) -{ - TQPtrListIterator<SessionData::AuthData> it( *this ); - for( ; it.current(); ++it ) - { - if ( it.current()->isGroupMatch(gkey) && pingCacheDaemon() ) - { - unregisterAuthData( it.current() ); - remove( it.current() ); - } - } -} - -bool SessionData::AuthDataList::pingCacheDaemon() -{ -#ifdef Q_OS_UNIX - Q_ASSERT(m_tdesuClient); - - int success = m_tdesuClient->ping(); - if( success == -1 ) - { - success = m_tdesuClient->startServer(); - if( success == -1 ) - return false; - } - return true; -#else - return false; -#endif -} - -void SessionData::AuthDataList::registerAuthData( SessionData::AuthData* d ) -{ - if( !pingCacheDaemon() ) - return; - -#ifdef Q_OS_UNIX - bool ok; - TQCString ref_key = d->key + "-refcount"; - int count = m_tdesuClient->getVar(ref_key).toInt( &ok ); - if( ok ) - { - TQCString val; - val.setNum( count+1 ); - m_tdesuClient->setVar( ref_key, val, 0, d->group ); - } - else - m_tdesuClient->setVar( ref_key, "1", 0, d->group ); -#endif -} - -void SessionData::AuthDataList::unregisterAuthData( SessionData::AuthData* d ) -{ - if ( !d || d->persist ) - return; - - bool ok; - int count; - TQCString ref_key = d->key + "-refcount"; - -#ifdef Q_OS_UNIX - count = m_tdesuClient->getVar( ref_key ).toInt( &ok ); - if ( ok ) - { - if ( count > 1 ) - { - TQCString val; - val.setNum(count-1); - m_tdesuClient->setVar( ref_key, val, 0, d->group ); - } - else - { - m_tdesuClient->delVars(d->key); - } - } -#endif -} - -void SessionData::AuthDataList::purgeCachedData() -{ - if ( !isEmpty() && pingCacheDaemon() ) - { - TQPtrListIterator<SessionData::AuthData> it( *this ); - for ( ; it.current(); ++it ) - unregisterAuthData( it.current() ); - } -} - -/********************************* SessionData ****************************/ - -class SessionData::SessionDataPrivate -{ -public: - SessionDataPrivate() { - useCookie = true; - initDone = false; - } - - bool initDone; - bool useCookie; - TQString charsets; - TQString language; -}; - -SessionData::SessionData() -{ - authData = 0; - d = new SessionDataPrivate; -} - -SessionData::~SessionData() -{ - delete d; - delete authData; - d = 0L; - authData = 0L; -} - -void SessionData::configDataFor( MetaData &configData, const TQString &proto, - const TQString & ) -{ - if ( (proto.find("http", 0, false) == 0 ) || - (proto.find("webdav", 0, false) == 0) ) - { - if (!d->initDone) - reset(); - - // These might have already been set so check first - // to make sure that we do not trumpt settings sent - // by apps or end-user. - if ( configData["Cookies"].isEmpty() ) - configData["Cookies"] = d->useCookie ? "true" : "false"; - if ( configData["Languages"].isEmpty() ) - configData["Languages"] = d->language; - if ( configData["Charsets"].isEmpty() ) - configData["Charsets"] = d->charsets; - if ( configData["CacheDir"].isEmpty() ) - configData["CacheDir"] = TDEGlobal::dirs()->saveLocation("cache", "http"); - if ( configData["UserAgent"].isEmpty() ) - { - configData["UserAgent"] = KProtocolManager::defaultUserAgent(); - } - } -} - -void SessionData::reset() -{ - d->initDone = true; - // Get Cookie settings... - TDEConfig* cfg = new TDEConfig("kcookiejarrc", true, false); - cfg->setGroup( "Cookie Policy" ); - d->useCookie = cfg->readBoolEntry( "Cookies", true ); - delete cfg; - - static const TQString & english = TDEGlobal::staticQString( "en" ); - - // Get language settings... - TQStringList languageList = TDEGlobal::locale()->languagesTwoAlpha(); - TQStringList::Iterator it = languageList.find( TQString::fromLatin1("C") ); - if ( it != languageList.end() ) - { - if ( languageList.contains( english ) > 0 ) - languageList.remove( it ); - else - (*it) = english; - } - if ( !languageList.contains( english ) ) - languageList.append( english ); - - d->language = languageList.join( ", " ); - - d->charsets = TQString::fromLatin1(TQTextCodec::codecForLocale()->mimeName()).lower(); - KProtocolManager::reparseConfiguration(); -} - -void SessionData::slotAuthData( const TQCString& key, const TQCString& gkey, - bool keep ) -{ - if (!authData) - authData = new AuthDataList; - authData->addData( new SessionData::AuthData(key, gkey, keep) ); -} - -void SessionData::slotDelAuthData( const TQCString& gkey ) -{ - if (!authData) - return; - authData->removeData( gkey ); -} - -void SessionData::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -} diff --git a/kio/kio/sessiondata.h b/kio/kio/sessiondata.h deleted file mode 100644 index 4fef02161..000000000 --- a/kio/kio/sessiondata.h +++ /dev/null @@ -1,67 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2000 Dawit Alemayehu <adawit@kde.org - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License (LGPL) as published by the Free Software Foundation; - either version 2 of the License, or (at your option) any - later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 51 Franklin Street, - Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef __KIO_SESSIONDATA_H -#define __KIO_SESSIONDATA_H - -#include <tqobject.h> -#include <kio/global.h> - -namespace TDEIO { - -class SlaveConfig; - - -/** - * @internal - */ -class TDEIO_EXPORT SessionData : public TQObject -{ - Q_OBJECT - -public: - SessionData(); - ~SessionData(); - - virtual void configDataFor( TDEIO::MetaData &configData, const TQString &proto, - const TQString &host ); - virtual void reset(); - - /// @since 3.1 - struct AuthData; -public slots: - void slotAuthData( const TQCString&, const TQCString&, bool ); - void slotDelAuthData( const TQCString& ); - -private: - class AuthDataList; - friend class AuthDataList; - AuthDataList* authData; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class SessionDataPrivate; - SessionDataPrivate* d; -}; - -} // namespace - -#endif diff --git a/kio/kio/skipdlg.cpp b/kio/kio/skipdlg.cpp deleted file mode 100644 index f4a14a229..000000000 --- a/kio/kio/skipdlg.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kio/skipdlg.h" - -#include <stdio.h> -#include <assert.h> - -#include <tqmessagebox.h> -#include <tqwidget.h> -#include <tqlayout.h> -#include <tqlabel.h> - -#include <kapplication.h> -#include <klocale.h> -#include <kurl.h> -#include <kpushbutton.h> -#include <kstdguiitem.h> - -#ifdef Q_WS_X11 -#include <twin.h> -#endif - -using namespace TDEIO; - -SkipDlg::SkipDlg(TQWidget *parent, bool _multi, const TQString& _error_text, bool _modal ) : - KDialog ( parent, "" , _modal ) -{ - // TODO : port to KDialogBase - modal = _modal; - - // Set "StaysOnTop", because this dialog is typically used in kio_uiserver, - // i.e. in a separate process. -#ifdef Q_WS_X11 //FIXME(E): Implement for QT Embedded, mac & win32 - if (modal) - KWin::setState( winId(), NET::StaysOnTop ); -#endif - - b0 = b1 = b2 = 0L; - - setCaption( i18n( "Information" ) ); - - b0 = new KPushButton( KStdGuiItem::cancel(), this ); - connect(b0, TQT_SIGNAL(clicked()), this, TQT_SLOT(b0Pressed())); - - if ( _multi ) - { - b1 = new TQPushButton( i18n( "Skip" ), this ); - connect(b1, TQT_SIGNAL(clicked()), this, TQT_SLOT(b1Pressed())); - - b2 = new TQPushButton( i18n( "Auto Skip" ), this ); - connect(b2, TQT_SIGNAL(clicked()), this, TQT_SLOT(b2Pressed())); - } - - TQVBoxLayout *vlayout = new TQVBoxLayout( this, 10, 0 ); - // vlayout->addStrut( 360 ); makes dlg at least that wide - - TQLabel * lb = new TQLabel( _error_text, this ); - lb->setFixedHeight( lb->sizeHint().height() ); - lb->setMinimumWidth( lb->sizeHint().width() ); - vlayout->addWidget( lb ); - - vlayout->addSpacing( 10 ); - - TQHBoxLayout* layout = new TQHBoxLayout(); - vlayout->addLayout( layout ); - if ( b0 ) - { - b0->setDefault( true ); - b0->setFixedSize( b0->sizeHint() ); - layout->addWidget( b0 ); - layout->addSpacing( 5 ); - } - if ( b1 ) - { - b1->setFixedSize( b1->sizeHint() ); - layout->addWidget( b1 ); - layout->addSpacing( 5 ); - } - if ( b2 ) - { - b2->setFixedSize( b2->sizeHint() ); - layout->addWidget( b2 ); - layout->addSpacing( 5 ); - } - - vlayout->addStretch( 10 ); - vlayout->activate(); - resize( sizeHint() ); -} - -SkipDlg::~SkipDlg() -{ -} - -void SkipDlg::b0Pressed() -{ - if ( modal ) - done( 0 ); - else - emit result( this, 0 ); -} - -void SkipDlg::b1Pressed() -{ - if ( modal ) - done( 1 ); - else - emit result( this, 1 ); -} - -void SkipDlg::b2Pressed() -{ - if ( modal ) - done( 2 ); - else - emit result( this, 2 ); -} - -SkipDlg_Result TDEIO::open_SkipDlg( bool _multi, const TQString& _error_text ) -{ - Q_ASSERT(kapp); - - SkipDlg dlg( 0L, _multi, _error_text, true ); - return (SkipDlg_Result) dlg.exec(); -} - -#include "skipdlg.moc" diff --git a/kio/kio/skipdlg.h b/kio/kio/skipdlg.h deleted file mode 100644 index 56252dace..000000000 --- a/kio/kio/skipdlg.h +++ /dev/null @@ -1,61 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_skip_dlg__ -#define __kio_skip_dlg__ - -#include <tdelibs_export.h> -#include <kdialog.h> - -class TQPushButton; -class TQWidget; - -namespace TDEIO { - - enum SkipDlg_Result { S_SKIP = 1, S_AUTO_SKIP = 2, S_CANCEL = 0 }; - - TDEIO_EXPORT SkipDlg_Result open_SkipDlg( bool _multi, const TQString& _error_text = TQString::null ); - -/** - * @internal - */ -class TDEIO_EXPORT SkipDlg : public KDialog -{ - Q_OBJECT -public: - SkipDlg( TQWidget *parent, bool _multi, const TQString& _error_text, bool _modal = false ); - ~SkipDlg(); - -protected: - TQPushButton *b0; - TQPushButton *b1; - TQPushButton *b2; - - bool modal; - -public slots: - void b0Pressed(); - void b1Pressed(); - void b2Pressed(); - -signals: - void result( SkipDlg *_this, int _button ); -}; - -} -#endif diff --git a/kio/kio/slave.cpp b/kio/kio/slave.cpp deleted file mode 100644 index 6e834f5fa..000000000 --- a/kio/kio/slave.cpp +++ /dev/null @@ -1,519 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (c) 2000 Waldo Bastian <bastian@kde.org> - * 2000 Stephan Kulow <coolo@kde.org> - * - * $Id$ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include <config.h> - -#include <time.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <signal.h> -#include <sys/types.h> - -#include <tqfile.h> -#include <tqtimer.h> - -#include <dcopclient.h> -#include <kdebug.h> -#include <klocale.h> -#include <kglobal.h> -#include <kstandarddirs.h> -#include <kapplication.h> -#include <ktempfile.h> -#include <ksock.h> -#include <kprocess.h> -#include <klibloader.h> - -#include "kio/dataprotocol.h" -#include "kio/slave.h" -#include "kio/kservice.h" -#include <kio/global.h> -#include <kprotocolmanager.h> -#include <kprotocolinfo.h> - -#ifdef HAVE_PATHS_H -#include <paths.h> -#endif - -#ifndef _PATH_TMP -#define _PATH_TMP "/tmp" -#endif - -using namespace TDEIO; - -#define SLAVE_CONNECTION_TIMEOUT_MIN 2 - -// Without debug info we consider it an error if the slave doesn't connect -// within 10 seconds. -// With debug info we give the slave an hour so that developers have a chance -// to debug their slave. -#ifdef NDEBUG -#define SLAVE_CONNECTION_TIMEOUT_MAX 10 -#else -#define SLAVE_CONNECTION_TIMEOUT_MAX 3600 -#endif - -namespace TDEIO { - - /** - * @internal - */ - class SlavePrivate { - public: - bool derived; // true if this instance of Slave is actually an - // instance of a derived class. - - SlavePrivate(bool derived) : derived(derived) {} - }; -} - -void Slave::accept(TDESocket *socket) -{ -#ifndef Q_WS_WIN - slaveconn.init(socket); -#endif - delete serv; - serv = 0; - slaveconn.connect(this, TQT_SLOT(gotInput())); - unlinkSocket(); -} - -void Slave::unlinkSocket() -{ - if (m_socket.isEmpty()) return; - TQCString filename = TQFile::encodeName(m_socket); - unlink(filename.data()); - m_socket = TQString::null; -} - -void Slave::timeout() -{ - if (!serv) return; - kdDebug(7002) << "slave failed to connect to application pid=" << m_pid << " protocol=" << m_protocol << endl; - if (m_pid && (::kill(m_pid, 0) == 0)) - { - int delta_t = (int) difftime(time(0), contact_started); - kdDebug(7002) << "slave is slow... pid=" << m_pid << " t=" << delta_t << endl; - if (delta_t < SLAVE_CONNECTION_TIMEOUT_MAX) - { - TQTimer::singleShot(1000*SLAVE_CONNECTION_TIMEOUT_MIN, this, TQT_SLOT(timeout())); - return; - } - } - kdDebug(7002) << "Houston, we lost our slave, pid=" << m_pid << endl; - delete serv; - serv = 0; - unlinkSocket(); - dead = true; - TQString arg = m_protocol; - if (!m_host.isEmpty()) - arg += "://"+m_host; - kdDebug(7002) << "slave died pid = " << m_pid << endl; - ref(); - // Tell the job about the problem. - emit error(ERR_SLAVE_DIED, arg); - // Tell the scheduler about the problem. - emit slaveDied(this); - // After the above signal we're dead!! - deref(); -} - -Slave::Slave(TDEServerSocket *socket, const TQString &protocol, const TQString &socketname) - : SlaveInterface(&slaveconn), serv(socket), contacted(false), - d(new SlavePrivate(false)) -{ - m_refCount = 1; - m_protocol = protocol; - m_slaveProtocol = protocol; - m_socket = socketname; - dead = false; - contact_started = time(0); - idle_since = contact_started; - m_pid = 0; - m_port = 0; -#ifndef Q_WS_WIN - connect(serv, TQT_SIGNAL(accepted( TDESocket* )), - TQT_SLOT(accept(TDESocket*) ) ); -#endif -} - -Slave::Slave(bool /*derived*/, TDEServerSocket *socket, const TQString &protocol, - const TQString &socketname) - : SlaveInterface(&slaveconn), serv(socket), contacted(false), - d(new SlavePrivate(true)) -{ - // FIXME: hmm, duplicating code here from public ctor, no good (LS) - m_refCount = 1; - m_protocol = protocol; - m_slaveProtocol = protocol; - m_socket = socketname; - dead = false; - contact_started = time(0); - idle_since = contact_started; - m_pid = 0; - m_port = 0; - if (serv != 0) { -#ifndef Q_WS_WIN - connect(serv, TQT_SIGNAL(accepted( TDESocket* )), - TQT_SLOT(accept(TDESocket*) ) ); -#endif - } -} - -Slave::~Slave() -{ - // kdDebug(7002) << "destructing slave object pid = " << m_pid << endl; - if (serv != 0) { - delete serv; - serv = 0; - } - unlinkSocket(); - m_pid = 99999; - delete d; - d = 0; -} - -void Slave::setProtocol(const TQString & protocol) -{ - m_protocol = protocol; -} - -void Slave::setIdle() -{ - idle_since = time(0); -} - -time_t Slave::idleTime() -{ - return (time_t) difftime(time(0), idle_since); -} - -void Slave::setPID(pid_t pid) -{ - m_pid = pid; -} - -void Slave::hold(const KURL &url) -{ - if (d->derived) { // TODO: clean up before KDE 4 - HoldParams params; - params.url = &url; - virtual_hook(VIRTUAL_HOLD, ¶ms); - return; - }/*end if*/ - - ref(); - { - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - stream << url; - slaveconn.send( CMD_SLAVE_HOLD, data ); - slaveconn.close(); - dead = true; - emit slaveDied(this); - } - deref(); - // Call KLauncher::waitForSlave(pid); - { - DCOPClient *client = kapp->dcopClient(); - if (!client->isAttached()) - client->attach(); - - TQByteArray params, reply; - TQCString replyType; - TQDataStream stream(params, IO_WriteOnly); - pid_t pid = m_pid; - stream << pid; - - TQCString launcher = TDEApplication::launcher(); - client->call(launcher, launcher, "waitForSlave(pid_t)", - params, replyType, reply); - } -} - -void Slave::suspend() -{ - if (d->derived) { // TODO: clean up before KDE 4 - virtual_hook(VIRTUAL_SUSPEND, 0); - return; - }/*end if*/ - - slaveconn.suspend(); -} - -void Slave::resume() -{ - if (d->derived) { // TODO: clean up before KDE 4 - virtual_hook(VIRTUAL_RESUME, 0); - return; - }/*end if*/ - - slaveconn.resume(); -} - -bool Slave::suspended() -{ - if (d->derived) { // TODO: clean up before KDE 4 - SuspendedParams params; - virtual_hook(VIRTUAL_SUSPENDED, ¶ms); - return params.retval; - }/*end if*/ - - return slaveconn.suspended(); -} - -void Slave::send(int cmd, const TQByteArray &arr) { - if (d->derived) { // TODO: clean up before KDE 4 - SendParams params; - params.cmd = cmd; - params.arr = &arr; - virtual_hook(VIRTUAL_SEND, ¶ms); - return; - }/*end if*/ - - slaveconn.send(cmd, arr); -} - -void Slave::gotInput() -{ - ref(); - if (!dispatch()) - { - slaveconn.close(); - dead = true; - TQString arg = m_protocol; - if (!m_host.isEmpty()) - arg += "://"+m_host; - kdDebug(7002) << "slave died pid = " << m_pid << endl; - // Tell the job about the problem. - emit error(ERR_SLAVE_DIED, arg); - // Tell the scheduler about the problem. - emit slaveDied(this); - } - deref(); - // Here we might be dead!! -} - -void Slave::kill() -{ - dead = true; // OO can be such simple. - kdDebug(7002) << "killing slave pid=" << m_pid << " (" << m_protocol << "://" - << m_host << ")" << endl; - if (m_pid) - { - ::kill(m_pid, SIGTERM); - } -} - -void Slave::setHost( const TQString &host, int port, - const TQString &user, const TQString &passwd) -{ - m_host = host; - m_port = port; - m_user = user; - m_passwd = passwd; - - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - stream << m_host << m_port << m_user << m_passwd; - slaveconn.send( CMD_HOST, data ); -} - -void Slave::resetHost() -{ - m_host = "<reset>"; -} - -void Slave::setConfig(const MetaData &config) -{ - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - stream << config; - slaveconn.send( CMD_CONFIG, data ); -} - -Slave* Slave::createSlave( const TQString &protocol, const KURL& url, int& error, TQString& error_text ) -{ - //kdDebug(7002) << "createSlave '" << protocol << "' for " << url.prettyURL() << endl; - // Firstly take into account all special slaves - if (protocol == "data") - return new DataProtocol(); - - DCOPClient *client = kapp->dcopClient(); - if (!client->isAttached()) - client->attach(); - - TQString prefix = locateLocal("socket", TDEGlobal::instance()->instanceName()); - KTempFile socketfile(prefix, TQString::fromLatin1(".slave-socket")); - if ( socketfile.status() != 0 ) - { - error_text = i18n("Unable to create io-slave: %1").arg(strerror(errno)); - error = TDEIO::ERR_CANNOT_LAUNCH_PROCESS; - return 0; - } - -#ifdef __CYGWIN__ - socketfile.close(); -#endif - -#ifndef Q_WS_WIN - TDEServerSocket *kss = new TDEServerSocket(TQFile::encodeName(socketfile.name()).data()); - - Slave *slave = new Slave(kss, protocol, socketfile.name()); -#else - Slave *slave = 0; -#endif - - // WABA: if the dcopserver is running under another uid we don't ask - // klauncher for a slave, because the slave might have that other uid - // as well, which might either be a) undesired or b) make it impossible - // for the slave to connect to the application. - // In such case we start the slave via TDEProcess. - // It's possible to force this by setting the env. variable - // TDE_FORK_SLAVES, Clearcase seems to require this. - static bool bForkSlaves = !TQCString(getenv("TDE_FORK_SLAVES")).isEmpty(); - - if (bForkSlaves || !client->isAttached() || client->isAttachedToForeignServer()) - { - TQString _name = KProtocolInfo::exec(protocol); - if (_name.isEmpty()) - { - error_text = i18n("Unknown protocol '%1'.").arg(protocol); - error = TDEIO::ERR_CANNOT_LAUNCH_PROCESS; - delete slave; - return 0; - } - TQString lib_path = KLibLoader::findLibrary(_name.latin1()); - if (lib_path.isEmpty()) - { - error_text = i18n("Can not find io-slave for protocol '%1'.").arg(protocol); - error = TDEIO::ERR_CANNOT_LAUNCH_PROCESS; - return 0; - } - - TDEProcess proc; - - proc << locate("exe", "kioslave") << lib_path << protocol << "" << socketfile.name(); - kdDebug(7002) << "kioslave" << ", " << lib_path << ", " << protocol << ", " << TQString::null << ", " << socketfile.name() << endl; - - proc.start(TDEProcess::DontCare); - -#ifndef Q_WS_WIN - slave->setPID(proc.pid()); - TQTimer::singleShot(1000*SLAVE_CONNECTION_TIMEOUT_MIN, slave, TQT_SLOT(timeout())); -#endif - return slave; - } - - - TQByteArray params, reply; - TQCString replyType; - TQDataStream stream(params, IO_WriteOnly); - stream << protocol << url.host() << socketfile.name(); - - TQCString launcher = TDEApplication::launcher(); - if (!client->call(launcher, launcher, "requestSlave(TQString,TQString,TQString)", - params, replyType, reply)) { - error_text = i18n("Cannot talk to klauncher"); - error = TDEIO::ERR_SLAVE_DEFINED; - delete slave; - return 0; - } - TQDataStream stream2(reply, IO_ReadOnly); - TQString errorStr; - pid_t pid; - stream2 >> pid >> errorStr; - if (!pid) - { - error_text = i18n("Unable to create io-slave:\nklauncher said: %1").arg(errorStr); - error = TDEIO::ERR_CANNOT_LAUNCH_PROCESS; - delete slave; - return 0; - } -#ifndef Q_WS_WIN - slave->setPID(pid); - TQTimer::singleShot(1000*SLAVE_CONNECTION_TIMEOUT_MIN, slave, TQT_SLOT(timeout())); -#endif - return slave; -} - -Slave* Slave::holdSlave( const TQString &protocol, const KURL& url ) -{ - //kdDebug(7002) << "holdSlave '" << protocol << "' for " << url.prettyURL() << endl; - // Firstly take into account all special slaves - if (protocol == "data") - return 0; - - DCOPClient *client = kapp->dcopClient(); - if (!client->isAttached()) - client->attach(); - - TQString prefix = locateLocal("socket", TDEGlobal::instance()->instanceName()); - KTempFile socketfile(prefix, TQString::fromLatin1(".slave-socket")); - if ( socketfile.status() != 0 ) - return 0; - -#ifdef __CYGWIN__ - socketfile.close(); - socketfile.unlink(); -#endif - -#ifndef Q_WS_WIN - TDEServerSocket *kss = new TDEServerSocket(TQFile::encodeName(socketfile.name()).data()); - - Slave *slave = new Slave(kss, protocol, socketfile.name()); -#else - Slave *slave = 0; -#endif - - TQByteArray params, reply; - TQCString replyType; - TQDataStream stream(params, IO_WriteOnly); - stream << url << socketfile.name(); - - TQCString launcher = TDEApplication::launcher(); - if (!client->call(launcher, launcher, "requestHoldSlave(KURL,TQString)", - params, replyType, reply)) { - delete slave; - return 0; - } - TQDataStream stream2(reply, IO_ReadOnly); - pid_t pid; - stream2 >> pid; - if (!pid) - { - delete slave; - return 0; - } -#ifndef Q_WS_WIN - slave->setPID(pid); - TQTimer::singleShot(1000*SLAVE_CONNECTION_TIMEOUT_MIN, slave, TQT_SLOT(timeout())); -#endif - return slave; -} - -void Slave::virtual_hook( int id, void* data ) { - TDEIO::SlaveInterface::virtual_hook( id, data ); -} - -#include "slave.moc" diff --git a/kio/kio/slave.h b/kio/kio/slave.h deleted file mode 100644 index 6f9f02a2f..000000000 --- a/kio/kio/slave.h +++ /dev/null @@ -1,270 +0,0 @@ -// -*- c++ -*- -/* - * This file is part of the KDE libraries - * Copyright (c) 2000 Waldo Bastian <bastian@kde.org> - * 2000 Stephan Kulow <coolo@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#ifndef KIO_SLAVE_H -#define KIO_SLAVE_H - -#include <time.h> -#include <unistd.h> - -#include <tqobject.h> - -#include <kurl.h> - -#include "kio/slaveinterface.h" -#include "kio/connection.h" - -class TDEServerSocket; -class TDESocket; - -namespace TDEIO { - - /** Attention developers: If you change the implementation of TDEIO::Slave, - * do *not* use connection() or slaveconn but the respective TDEIO::Slave - * accessor methods. Otherwise classes derived from Slave might break. (LS) - */ - class TDEIO_EXPORT Slave : public TDEIO::SlaveInterface - { - Q_OBJECT - - - protected: - /** - * Use this constructor if you derive your own class from Slave - * @p derived must be true in any case - * @internal - * @since 3.2 - */ - Slave(bool derived, TDEServerSocket *unixdomain, const TQString &protocol, - const TQString &socketname); // TODO(BIC): Remove in KDE 4 - - public: - Slave(TDEServerSocket *unixdomain, - const TQString &protocol, const TQString &socketname); - - virtual ~Slave(); - - void setPID(pid_t); - - int slave_pid() { return m_pid; } - - /** - * Force termination - */ - void kill(); - - /** - * @return true if the slave survived the last mission. - */ - bool isAlive() { return !dead; } - - /** - * Set host for url - * @param host to connect to. - * @param port to connect to. - * @param user to login as - * @param passwd to login with - */ - void setHost( const TQString &host, int port, - const TQString &user, const TQString &passwd); // TODO(BIC): make virtual - - /** - * Clear host info. - */ - void resetHost(); - - /** - * Configure slave - */ - void setConfig(const MetaData &config); // TODO(BIC): make virtual - - /** - * The protocol this slave handles. - * - * @return name of protocol handled by this slave, as seen by the user - */ - TQString protocol() { return m_protocol; } - - void setProtocol(const TQString & protocol); - /** - * The actual protocol used to handle the request. - * - * This method will return a different protocol than - * the one obtained by using protocol() if a - * proxy-server is used for the given protocol. This - * usually means that this method will return "http" - * when the actuall request was to retrieve a resource - * from an "ftp" server by going through a proxy server. - * - * @return the actual protocol (io-slave) that handled the request - */ - TQString slaveProtocol() { return m_slaveProtocol; } - - /** - * @return Host this slave is (was?) connected to - */ - TQString host() { return m_host; } - - /** - * @return port this slave is (was?) connected to - */ - int port() { return m_port; } - - /** - * @return User this slave is (was?) logged in as - */ - TQString user() { return m_user; } - - /** - * @return Passwd used to log in - */ - TQString passwd() { return m_passwd; } - - /** - * Creates a new slave. - * - * @param protocol protocol the slave is for. - * @param url URL the slave should operate on. - * @param error is the error code on failure and undefined else. - * @param error_text is the error text on failure and undefined else. - * - * @return 0 on failure, or a pointer to a slave otherwise. - * @todo What are legal @p protocol values? - */ - static Slave* createSlave( const TQString &protocol, const KURL& url, int& error, TQString& error_text ); - - static Slave* holdSlave( const TQString &protocol, const KURL& url ); - - // == communication with connected kioslave == - // whenever possible prefer these methods over the respective - // methods in connection() - /** - * Suspends the operation of the attached kioslave. - */ - void suspend(); // TODO(BIC): make virtual - /** - * Resumes the operation of the attached kioslave. - */ - void resume(); // TODO(BIC): make virtual - /** - * Tells wether the kioslave is suspended. - * @return true if the kioslave is suspended. - * @since 3.2 - */ - bool suspended(); // TODO(BIC): make virtual - /** - * Sends the given command to the kioslave. - * @param cmd command id - * @param data byte array containing data - * @since 3.2 - */ - void send(int cmd, const TQByteArray &data = TQByteArray());// TODO(BIC): make virtual - // == end communication with connected kioslave == - - /** - * Puts the kioslave associated with @p url at halt. - */ - void hold(const KURL &url); // TODO(BIC): make virtual - - /** - * @return The time this slave has been idle. - */ - time_t idleTime(); - - /** - * Marks this slave as idle. - */ - void setIdle(); - - /* - * @returns Whether the slave is connected - * (Connection oriented slaves only) - */ - bool isConnected() { return contacted; } - void setConnected(bool c) { contacted = c; } - - /** @deprecated This method is obsolete, use the accessor methods - * within TDEIO::Slave instead. Old code directly accessing connection() - * will not be able to access special protocols. - */ - KDE_DEPRECATED Connection *connection() { return &slaveconn; } // TODO(BIC): remove before KDE 4 - - void ref() { m_refCount++; } - void deref() { m_refCount--; if (!m_refCount) delete this; } - - public slots: - void accept(TDESocket *socket); - void gotInput(); - void timeout(); - signals: - void slaveDied(TDEIO::Slave *slave); - - protected: - void unlinkSocket(); - - private: - TQString m_protocol; - TQString m_slaveProtocol; - TQString m_host; - int m_port; - TQString m_user; - TQString m_passwd; - TDEServerSocket *serv; - TQString m_socket; - pid_t m_pid; - bool contacted; - bool dead; - time_t contact_started; - time_t idle_since; - TDEIO::Connection slaveconn; - int m_refCount; - protected: - virtual void virtual_hook( int id, void* data ); - // grant SlaveInterface all IDs < 0x200 - enum { VIRTUAL_SUSPEND = 0x200, VIRTUAL_RESUME, VIRTUAL_SEND, - VIRTUAL_HOLD, VIRTUAL_SUSPENDED, - VIRTUAL_SET_HOST, VIRTUAL_SET_CONFIG }; - struct SendParams { - int cmd; - const TQByteArray *arr; - }; - struct HoldParams { - const KURL *url; - }; - struct SuspendedParams { - bool retval; - }; - struct SetHostParams { - const TQString *host; - int port; - const TQString *user; - const TQString *passwd; - }; - struct SetConfigParams { - const MetaData *config; - }; - private: - class SlavePrivate* d; - }; - -} - -#endif diff --git a/kio/kio/slavebase.cpp b/kio/kio/slavebase.cpp deleted file mode 100644 index 07d784527..000000000 --- a/kio/kio/slavebase.cpp +++ /dev/null @@ -1,1315 +0,0 @@ -/* - * - * This file is part of the KDE libraries - * Copyright (c) 2000 Waldo Bastian <bastian@kde.org> - * Copyright (c) 2000 David Faure <faure@kde.org> - * Copyright (c) 2000 Stephan Kulow <coolo@kde.org> - * - * $Id$ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - **/ - -#include "slavebase.h" - -#include <config.h> - -#include <sys/time.h> -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> // Needed on some systems. -#endif - -#include <assert.h> -#include <kdebug.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> -#include <time.h> - -#include <tqfile.h> - -#include <dcopclient.h> - -#include <kapplication.h> -#include <ksock.h> -#include <kcrash.h> -#include <tdesu/client.h> -#include <klocale.h> -#include <ksocks.h> - -#include "kremoteencoding.h" - -#include "kio/slavebase.h" -#include "kio/connection.h" -#include "kio/ioslave_defaults.h" -#include "kio/slaveinterface.h" - -#include "uiserver_stub.h" - -#ifndef NDEBUG -#ifdef HAVE_BACKTRACE -#include <execinfo.h> -#endif -#endif - -using namespace TDEIO; - -template class TQPtrList<TQValueList<UDSAtom> >; -typedef TQValueList<TQCString> AuthKeysList; -typedef TQMap<TQString,TQCString> AuthKeysMap; -#define KIO_DATA TQByteArray data; TQDataStream stream( data, IO_WriteOnly ); stream -#define KIO_FILESIZE_T(x) (unsigned long)(x & 0xffffffff) << (unsigned long)(x >> 32) - -namespace TDEIO { - -class SlaveBaseConfig : public TDEConfigBase -{ -public: - SlaveBaseConfig(SlaveBase *_slave) - : slave(_slave) { } - - bool internalHasGroup(const TQCString &) const { tqWarning("hasGroup(const TQCString &)"); -return false; } - - TQStringList groupList() const { return TQStringList(); } - - TQMap<TQString,TQString> entryMap(const TQString &group) const - { Q_UNUSED(group); return TQMap<TQString,TQString>(); } - - void reparseConfiguration() { } - - KEntryMap internalEntryMap( const TQString &pGroup) const { Q_UNUSED(pGroup); return KEntryMap(); } - - KEntryMap internalEntryMap() const { return KEntryMap(); } - - void putData(const KEntryKey &_key, const KEntry&_data, bool _checkGroup) - { Q_UNUSED(_key); Q_UNUSED(_data); Q_UNUSED(_checkGroup); } - - KEntry lookupData(const KEntryKey &_key) const - { - KEntry entry; - TQString value = slave->metaData(_key.c_key); - if (!value.isNull()) - entry.mValue = value.utf8(); - return entry; - } -protected: - SlaveBase *slave; -}; - - -class SlaveBasePrivate { -public: - TQString slaveid; - bool resume:1; - bool needSendCanResume:1; - bool onHold:1; - bool wasKilled:1; - MetaData configData; - SlaveBaseConfig *config; - KURL onHoldUrl; - - struct timeval last_tv; - TDEIO::filesize_t totalSize; - TDEIO::filesize_t sentListEntries; - DCOPClient *dcopClient; - KRemoteEncoding *remotefile; - time_t timeout; - TQByteArray timeoutData; -}; - -} - -static SlaveBase *globalSlave; -long SlaveBase::s_seqNr; - -static volatile bool slaveWriteError = false; - -static const char *s_protocol; - -#ifdef Q_OS_UNIX -static void genericsig_handler(int sigNumber) -{ - signal(sigNumber,SIG_IGN); - //WABA: Don't do anything that requires malloc, we can deadlock on it since - //a SIGTERM signal can come in while we are in malloc/free. - //kdDebug()<<"kioslave : exiting due to signal "<<sigNumber<<endl; - //set the flag which will be checked in dispatchLoop() and which *should* be checked - //in lengthy operations in the various slaves - if (globalSlave!=0) - globalSlave->setKillFlag(); - signal(SIGALRM,SIG_DFL); - alarm(5); //generate an alarm signal in 5 seconds, in this time the slave has to exit -} -#endif - -////////////// - -SlaveBase::SlaveBase( const TQCString &protocol, - const TQCString &pool_socket, - const TQCString &app_socket ) - : mProtocol(protocol), m_pConnection(0), - mPoolSocket( TQFile::decodeName(pool_socket)), - mAppSocket( TQFile::decodeName(app_socket)) -{ - s_protocol = protocol.data(); -#ifdef Q_OS_UNIX - if (!getenv("TDE_DEBUG")) - { - KCrash::setCrashHandler( sigsegv_handler ); - signal(SIGILL,&sigsegv_handler); - signal(SIGTRAP,&sigsegv_handler); - signal(SIGABRT,&sigsegv_handler); - signal(SIGBUS,&sigsegv_handler); - signal(SIGALRM,&sigsegv_handler); - signal(SIGFPE,&sigsegv_handler); -#ifdef SIGPOLL - signal(SIGPOLL, &sigsegv_handler); -#endif -#ifdef SIGSYS - signal(SIGSYS, &sigsegv_handler); -#endif -#ifdef SIGVTALRM - signal(SIGVTALRM, &sigsegv_handler); -#endif -#ifdef SIGXCPU - signal(SIGXCPU, &sigsegv_handler); -#endif -#ifdef SIGXFSZ - signal(SIGXFSZ, &sigsegv_handler); -#endif - } - - struct sigaction act; - act.sa_handler = sigpipe_handler; - sigemptyset( &act.sa_mask ); - act.sa_flags = 0; - sigaction( SIGPIPE, &act, 0 ); - - signal(SIGINT,&genericsig_handler); - signal(SIGQUIT,&genericsig_handler); - signal(SIGTERM,&genericsig_handler); -#endif - - globalSlave=this; - - appconn = new Connection(); - listEntryCurrentSize = 100; - struct timeval tp; - gettimeofday(&tp, 0); - listEntry_sec = tp.tv_sec; - listEntry_usec = tp.tv_usec; - mConnectedToApp = true; - - d = new SlaveBasePrivate; - // by kahl for netmgr (need a way to identify slaves) - d->slaveid = protocol; - d->slaveid += TQString::number(getpid()); - d->resume = false; - d->needSendCanResume = false; - d->config = new SlaveBaseConfig(this); - d->onHold = false; - d->wasKilled=false; - d->last_tv.tv_sec = 0; - d->last_tv.tv_usec = 0; -// d->processed_size = 0; - d->totalSize=0; - d->sentListEntries=0; - d->timeout = 0; - connectSlave(mAppSocket); - - d->dcopClient = 0; - d->remotefile = 0; -} - -SlaveBase::~SlaveBase() -{ - delete d; - s_protocol = ""; -} - -DCOPClient *SlaveBase::dcopClient() -{ - if (!d->dcopClient) - { - d->dcopClient = TDEApplication::dcopClient(); - if (!d->dcopClient->isAttached()) - d->dcopClient->attach(); - d->dcopClient->setDaemonMode( true ); - } - return d->dcopClient; -} - -void SlaveBase::dispatchLoop() -{ -#ifdef Q_OS_UNIX //TODO: WIN32 - fd_set rfds; - int retval; - - while (true) - { - if (d->timeout && (d->timeout < time(0))) - { - TQByteArray data = d->timeoutData; - d->timeout = 0; - d->timeoutData = TQByteArray(); - special(data); - } - FD_ZERO(&rfds); - - assert(appconn->inited()); - int maxfd = appconn->fd_from(); - FD_SET(appconn->fd_from(), &rfds); - if( d->dcopClient ) - { - FD_SET( d->dcopClient->socket(), &rfds ); - if( d->dcopClient->socket() > maxfd ) - maxfd = d->dcopClient->socket(); - } - - if (!d->timeout) // we can wait forever - { - retval = select( maxfd + 1, &rfds, NULL, NULL, NULL); - } - else - { - struct timeval tv; - tv.tv_sec = kMax(d->timeout-time(0),(time_t) 1); - tv.tv_usec = 0; - retval = select( maxfd + 1, &rfds, NULL, NULL, &tv); - } - if ((retval>0) && FD_ISSET(appconn->fd_from(), &rfds)) - { // dispatch application messages - int cmd; - TQByteArray data; - if ( appconn->read(&cmd, data) != -1 ) - { - dispatch(cmd, data); - } - else // some error occurred, perhaps no more application - { - // When the app exits, should the slave be put back in the pool ? - if (mConnectedToApp && !mPoolSocket.isEmpty()) - { - disconnectSlave(); - mConnectedToApp = false; - closeConnection(); - connectSlave(mPoolSocket); - } - else - { - return; - } - } - } - if( retval > 0 && d->dcopClient && FD_ISSET( d->dcopClient->socket(), &rfds )) - { - d->dcopClient->processSocketData( d->dcopClient->socket()); - } - if ((retval<0) && (errno != EINTR)) - { - kdDebug(7019) << "dispatchLoop(): select returned " << retval << " " - << (errno==EBADF?"EBADF":errno==EINTR?"EINTR":errno==EINVAL?"EINVAL":errno==ENOMEM?"ENOMEM":"unknown") - << " (" << errno << ")" << endl; - return; - } - //I think we get here when we were killed in dispatch() and not in select() - if (wasKilled()) - { - kdDebug(7019)<<" dispatchLoop() slave was killed, returning"<<endl; - return; - } - } -#else -#error The KIO slave system only works under UNIX -#endif -} - -void SlaveBase::connectSlave(const TQString& path) -{ -#ifdef Q_OS_UNIX //TODO: TDESocket not yet available on WIN32 - appconn->init(new TDESocket(TQFile::encodeName(path).data())); - if (!appconn->inited()) - { - kdDebug(7019) << "SlaveBase: failed to connect to " << path << endl; - exit(); - } - - setConnection(appconn); -#endif -} - -void SlaveBase::disconnectSlave() -{ - appconn->close(); -} - -void SlaveBase::setMetaData(const TQString &key, const TQString &value) -{ - mOutgoingMetaData.replace(key, value); -} - -TQString SlaveBase::metaData(const TQString &key) const -{ - if (mIncomingMetaData.contains(key)) - return mIncomingMetaData[key]; - if (d->configData.contains(key)) - return d->configData[key]; - return TQString::null; -} - -bool SlaveBase::hasMetaData(const TQString &key) const -{ - if (mIncomingMetaData.contains(key)) - return true; - if (d->configData.contains(key)) - return true; - return false; -} - -// ### remove the next two methods for KDE4 (they miss the const) -TQString SlaveBase::metaData(const TQString &key) { - return const_cast<const SlaveBase*>(this)->metaData( key ); -} -bool SlaveBase::hasMetaData(const TQString &key) { - return const_cast<const SlaveBase*>(this)->hasMetaData( key ); -} - -TDEConfigBase *SlaveBase::config() -{ - return d->config; -} - -void SlaveBase::sendMetaData() -{ - KIO_DATA << mOutgoingMetaData; - - slaveWriteError = false; - m_pConnection->send( INF_META_DATA, data ); - if (slaveWriteError) exit(); - mOutgoingMetaData.clear(); // Clear -} - -KRemoteEncoding *SlaveBase::remoteEncoding() -{ - if (d->remotefile != 0) - return d->remotefile; - - return d->remotefile = new KRemoteEncoding(metaData("Charset").latin1()); -} - -void SlaveBase::data( const TQByteArray &data ) -{ - if (!mOutgoingMetaData.isEmpty()) - sendMetaData(); - slaveWriteError = false; - m_pConnection->send( MSG_DATA, data ); - if (slaveWriteError) exit(); -} - -void SlaveBase::dataReq( ) -{ -/* - if (!mOutgoingMetaData.isEmpty()) - sendMetaData(); -*/ - if (d->needSendCanResume) - canResume(0); - m_pConnection->send( MSG_DATA_REQ ); -} - -void SlaveBase::error( int _errid, const TQString &_text ) -{ - mIncomingMetaData.clear(); // Clear meta data - mOutgoingMetaData.clear(); - KIO_DATA << (TQ_INT32) _errid << _text; - - m_pConnection->send( MSG_ERROR, data ); - //reset - listEntryCurrentSize = 100; - d->sentListEntries=0; - d->totalSize=0; -} - -void SlaveBase::connected() -{ - slaveWriteError = false; - m_pConnection->send( MSG_CONNECTED ); - if (slaveWriteError) exit(); -} - -void SlaveBase::finished() -{ - mIncomingMetaData.clear(); // Clear meta data - if (!mOutgoingMetaData.isEmpty()) - sendMetaData(); - m_pConnection->send( MSG_FINISHED ); - - // reset - listEntryCurrentSize = 100; - d->sentListEntries=0; - d->totalSize=0; -} - -void SlaveBase::needSubURLData() -{ - m_pConnection->send( MSG_NEED_SUBURL_DATA ); -} - -void SlaveBase::slaveStatus( const TQString &host, bool connected ) -{ - pid_t pid = getpid(); - TQ_INT8 b = connected ? 1 : 0; - KIO_DATA << pid << mProtocol << host << b; - if (d->onHold) - stream << d->onHoldUrl; - m_pConnection->send( MSG_SLAVE_STATUS, data ); -} - -void SlaveBase::canResume() -{ - m_pConnection->send( MSG_CANRESUME ); -} - -void SlaveBase::totalSize( TDEIO::filesize_t _bytes ) -{ - KIO_DATA << KIO_FILESIZE_T(_bytes); - slaveWriteError = false; - m_pConnection->send( INF_TOTAL_SIZE, data ); - if (slaveWriteError) exit(); - - //this one is usually called before the first item is listed in listDir() - struct timeval tp; - gettimeofday(&tp, 0); - listEntry_sec = tp.tv_sec; - listEntry_usec = tp.tv_usec; - d->totalSize=_bytes; - d->sentListEntries=0; -} - -void SlaveBase::processedSize( TDEIO::filesize_t _bytes ) -{ - bool emitSignal=false; - struct timeval tv; - int gettimeofday_res=gettimeofday( &tv, 0L ); - - if( _bytes == d->totalSize ) - emitSignal=true; - else if ( gettimeofday_res == 0 ) { - time_t msecdiff = 2000; - if (d->last_tv.tv_sec) { - // Compute difference, in ms - msecdiff = 1000 * ( tv.tv_sec - d->last_tv.tv_sec ); - time_t usecdiff = tv.tv_usec - d->last_tv.tv_usec; - if ( usecdiff < 0 ) { - msecdiff--; - msecdiff += 1000; - } - msecdiff += usecdiff / 1000; - } - emitSignal=msecdiff >= 100; // emit size 10 times a second - } - - if( emitSignal ) { - KIO_DATA << KIO_FILESIZE_T(_bytes); - slaveWriteError = false; - m_pConnection->send( INF_PROCESSED_SIZE, data ); - if (slaveWriteError) exit(); - if ( gettimeofday_res == 0 ) { - d->last_tv.tv_sec = tv.tv_sec; - d->last_tv.tv_usec = tv.tv_usec; - } - } -// d->processed_size = _bytes; -} - -void SlaveBase::processedPercent( float /* percent */ ) -{ - kdDebug(7019) << "SlaveBase::processedPercent: STUB" << endl; -} - - -void SlaveBase::speed( unsigned long _bytes_per_second ) -{ - KIO_DATA << (TQ_UINT32) _bytes_per_second; - slaveWriteError = false; - m_pConnection->send( INF_SPEED, data ); - if (slaveWriteError) exit(); -} - -void SlaveBase::redirection( const KURL& _url ) -{ - KIO_DATA << _url; - m_pConnection->send( INF_REDIRECTION, data ); -} - -void SlaveBase::errorPage() -{ - m_pConnection->send( INF_ERROR_PAGE ); -} - -static bool isSubCommand(int cmd) -{ - return ( (cmd == CMD_REPARSECONFIGURATION) || - (cmd == CMD_META_DATA) || - (cmd == CMD_CONFIG) || - (cmd == CMD_SUBURL) || - (cmd == CMD_SLAVE_STATUS) || - (cmd == CMD_SLAVE_CONNECT) || - (cmd == CMD_SLAVE_HOLD) || - (cmd == CMD_MULTI_GET)); -} - -void SlaveBase::mimeType( const TQString &_type) -{ - // kdDebug(7019) << "(" << getpid() << ") SlaveBase::mimeType '" << _type << "'" << endl; - int cmd; - do - { - // Send the meta-data each time we send the mime-type. - if (!mOutgoingMetaData.isEmpty()) - { - // kdDebug(7019) << "(" << getpid() << ") mimeType: emitting meta data" << endl; - KIO_DATA << mOutgoingMetaData; - m_pConnection->send( INF_META_DATA, data ); - } - KIO_DATA << _type; - m_pConnection->send( INF_MIME_TYPE, data ); - while(true) - { - cmd = 0; - if ( m_pConnection->read( &cmd, data ) == -1 ) { - kdDebug(7019) << "SlaveBase: mimetype: read error" << endl; - exit(); - } - // kdDebug(7019) << "(" << getpid() << ") Slavebase: mimetype got " << cmd << endl; - if ( cmd == CMD_HOST) // Ignore. - continue; - if ( isSubCommand(cmd) ) - { - dispatch( cmd, data ); - continue; // Disguised goto - } - break; - } - } - while (cmd != CMD_NONE); - mOutgoingMetaData.clear(); -} - -void SlaveBase::exit() -{ - this->~SlaveBase(); - ::exit(255); -} - -void SlaveBase::warning( const TQString &_msg) -{ - KIO_DATA << _msg; - m_pConnection->send( INF_WARNING, data ); -} - -void SlaveBase::infoMessage( const TQString &_msg) -{ - KIO_DATA << _msg; - m_pConnection->send( INF_INFOMESSAGE, data ); -} - -bool SlaveBase::requestNetwork(const TQString& host) -{ - KIO_DATA << host << d->slaveid; - m_pConnection->send( MSG_NET_REQUEST, data ); - - if ( waitForAnswer( INF_NETWORK_STATUS, 0, data ) != -1 ) - { - bool status; - TQDataStream stream( data, IO_ReadOnly ); - stream >> status; - return status; - } else - return false; -} - -void SlaveBase::dropNetwork(const TQString& host) -{ - KIO_DATA << host << d->slaveid; - m_pConnection->send( MSG_NET_DROP, data ); -} - -void SlaveBase::statEntry( const UDSEntry& entry ) -{ - KIO_DATA << entry; - slaveWriteError = false; - m_pConnection->send( MSG_STAT_ENTRY, data ); - if (slaveWriteError) exit(); -} - -void SlaveBase::listEntry( const UDSEntry& entry, bool _ready ) -{ - static struct timeval tp; - static const int maximum_updatetime = 300; - static const int minimum_updatetime = 100; - - if (!_ready) { - pendingListEntries.append(entry); - - if (pendingListEntries.count() > listEntryCurrentSize) { - gettimeofday(&tp, 0); - - long diff = ((tp.tv_sec - listEntry_sec) * 1000000 + - tp.tv_usec - listEntry_usec) / 1000; - if (diff==0) diff=1; - - if (diff > maximum_updatetime) { - listEntryCurrentSize = listEntryCurrentSize * 3 / 4; - _ready = true; - } -//if we can send all list entries of this dir which have not yet been sent -//within maximum_updatetime, then make listEntryCurrentSize big enough for all of them - else if (((pendingListEntries.count()*maximum_updatetime)/diff) > (d->totalSize-d->sentListEntries)) - listEntryCurrentSize=d->totalSize-d->sentListEntries+1; -//if we are below minimum_updatetime, estimate how much we will get within -//maximum_updatetime - else if (diff < minimum_updatetime) - listEntryCurrentSize = (pendingListEntries.count() * maximum_updatetime) / diff; - else - _ready=true; - } - } - if (_ready) { // may happen when we started with !ready - listEntries( pendingListEntries ); - pendingListEntries.clear(); - - gettimeofday(&tp, 0); - listEntry_sec = tp.tv_sec; - listEntry_usec = tp.tv_usec; - } -} - -void SlaveBase::listEntries( const UDSEntryList& list ) -{ - KIO_DATA << (TQ_UINT32)list.count(); - UDSEntryListConstIterator it = list.begin(); - UDSEntryListConstIterator end = list.end(); - for (; it != end; ++it) - stream << *it; - slaveWriteError = false; - m_pConnection->send( MSG_LIST_ENTRIES, data); - if (slaveWriteError) exit(); - d->sentListEntries+=(uint)list.count(); -} - -void SlaveBase::sendAuthenticationKey( const TQCString& key, - const TQCString& group, - bool keepPass ) -{ - KIO_DATA << key << group << keepPass; - m_pConnection->send( MSG_AUTH_KEY, data ); -} - -void SlaveBase::delCachedAuthentication( const TQString& key ) -{ - KIO_DATA << key.utf8() ; - m_pConnection->send( MSG_DEL_AUTH_KEY, data ); -} - -void SlaveBase::sigsegv_handler(int sig) -{ -#ifdef Q_OS_UNIX - signal(sig,SIG_DFL); // Next one kills - - //Kill us if we deadlock - signal(SIGALRM,SIG_DFL); - alarm(5); //generate an alarm signal in 5 seconds, in this time the slave has to exit - - // Debug and printf should be avoided because they might - // call malloc.. and get in a nice recursive malloc loop - char buffer[120]; - snprintf(buffer, sizeof(buffer), "kioslave: ####### CRASH ###### protocol = %s pid = %d signal = %d\n", s_protocol, getpid(), sig); - write(2, buffer, strlen(buffer)); -#ifndef NDEBUG -#ifdef HAVE_BACKTRACE - void* trace[256]; - int n = backtrace(trace, 256); - if (n) - backtrace_symbols_fd(trace, n, 2); -#endif -#endif - ::exit(1); -#endif -} - -void SlaveBase::sigpipe_handler (int) -{ - // We ignore a SIGPIPE in slaves. - // A SIGPIPE can happen in two cases: - // 1) Communication error with application. - // 2) Communication error with network. - slaveWriteError = true; - - // Don't add anything else here, especially no debug output -} - -void SlaveBase::setHost(TQString const &, int, TQString const &, TQString const &) -{ -} - -void SlaveBase::openConnection(void) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_CONNECT)); } -void SlaveBase::closeConnection(void) -{ } // No response! -void SlaveBase::stat(KURL const &) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_STAT)); } -void SlaveBase::put(KURL const &, int, bool, bool) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_PUT)); } -void SlaveBase::special(const TQByteArray &) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_SPECIAL)); } -void SlaveBase::listDir(KURL const &) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_LISTDIR)); } -void SlaveBase::get(KURL const & ) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_GET)); } -void SlaveBase::mimetype(KURL const &url) -{ get(url); } -void SlaveBase::rename(KURL const &, KURL const &, bool) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_RENAME)); } -void SlaveBase::symlink(TQString const &, KURL const &, bool) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_SYMLINK)); } -void SlaveBase::copy(KURL const &, KURL const &, int, bool) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_COPY)); } -void SlaveBase::del(KURL const &, bool) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_DEL)); } -void SlaveBase::mkdir(KURL const &, int) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_MKDIR)); } -void SlaveBase::chmod(KURL const &, int) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_CHMOD)); } -void SlaveBase::setSubURL(KURL const &) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_SUBURL)); } -void SlaveBase::multiGet(const TQByteArray &) -{ error( ERR_UNSUPPORTED_ACTION, unsupportedActionErrorString(mProtocol, CMD_MULTI_GET)); } - - -void SlaveBase::slave_status() -{ slaveStatus( TQString::null, false ); } - -void SlaveBase::reparseConfiguration() -{ -} - -void SlaveBase::localURL(const KURL& remoteURL) -{ - bool local = remoteURL.isLocalFile(); - TQ_INT8 islocal; - KURL retURL; - if (local) { - islocal = true; - retURL = remoteURL; - } - else { - islocal = false; - retURL = remoteURL; - } - KIO_DATA << islocal << retURL; - m_pConnection->send( INF_LOCALURL, data ); -} - -bool SlaveBase::dispatch() -{ - assert( m_pConnection ); - - int cmd; - TQByteArray data; - if ( m_pConnection->read( &cmd, data ) == -1 ) - { - kdDebug(7019) << "SlaveBase::dispatch() has read error." << endl; - return false; - } - - dispatch( cmd, data ); - return true; -} - -bool SlaveBase::openPassDlg( AuthInfo& info ) -{ - return openPassDlg(info, TQString::null); -} - -bool SlaveBase::openPassDlg( AuthInfo& info, const TQString &errorMsg ) -{ - TQCString replyType; - TQByteArray params; - TQByteArray reply; - AuthInfo authResult; - long windowId = metaData("window-id").toLong(); - long progressId = metaData("progress-id").toLong(); - unsigned long userTimestamp = metaData("user-timestamp").toULong(); - - kdDebug(7019) << "SlaveBase::openPassDlg window-id=" << windowId << " progress-id=" << progressId << endl; - - (void) dcopClient(); // Make sure to have a dcop client. - - UIServer_stub uiserver( "kio_uiserver", "UIServer" ); - if (progressId) - uiserver.setJobVisible( progressId, false ); - - TQDataStream stream(params, IO_WriteOnly); - - if (metaData("no-auth-prompt").lower() == "true") - stream << info << TQString("<NoAuthPrompt>") << windowId << s_seqNr << userTimestamp; - else - stream << info << errorMsg << windowId << s_seqNr << userTimestamp; - - bool callOK = d->dcopClient->call( "kded", "kpasswdserver", "queryAuthInfo(TDEIO::AuthInfo, TQString, long int, long int, unsigned long int)", - params, replyType, reply ); - - if (progressId) - uiserver.setJobVisible( progressId, true ); - - if (!callOK) - { - kdWarning(7019) << "Can't communicate with kded_kpasswdserver!" << endl; - return false; - } - - if ( replyType == "TDEIO::AuthInfo" ) - { - TQDataStream stream2( reply, IO_ReadOnly ); - stream2 >> authResult >> s_seqNr; - } - else - { - kdError(7019) << "DCOP function queryAuthInfo(...) returns " - << replyType << ", expected TDEIO::AuthInfo" << endl; - return false; - } - - if (!authResult.isModified()) - return false; - - info = authResult; - - kdDebug(7019) << "SlaveBase::openPassDlg: username=" << info.username << endl; - kdDebug(7019) << "SlaveBase::openPassDlg: password=[hidden]" << endl; - - return true; -} - -int SlaveBase::messageBox( MessageBoxType type, const TQString &text, const TQString &caption, - const TQString &buttonYes, const TQString &buttonNo ) -{ - return messageBox( text, type, caption, buttonYes, buttonNo, TQString::null ); -} - -int SlaveBase::messageBox( const TQString &text, MessageBoxType type, const TQString &caption, - const TQString &buttonYes, const TQString &buttonNo, const TQString &dontAskAgainName ) -{ - kdDebug(7019) << "messageBox " << type << " " << text << " - " << caption << buttonYes << buttonNo << endl; - KIO_DATA << (TQ_INT32)type << text << caption << buttonYes << buttonNo << dontAskAgainName; - m_pConnection->send( INF_MESSAGEBOX, data ); - if ( waitForAnswer( CMD_MESSAGEBOXANSWER, 0, data ) != -1 ) - { - TQDataStream stream( data, IO_ReadOnly ); - int answer; - stream >> answer; - kdDebug(7019) << "got messagebox answer" << answer << endl; - return answer; - } else - return 0; // communication failure -} - -bool SlaveBase::canResume( TDEIO::filesize_t offset ) -{ - kdDebug(7019) << "SlaveBase::canResume offset=" << TDEIO::number(offset) << endl; - d->needSendCanResume = false; - KIO_DATA << KIO_FILESIZE_T(offset); - m_pConnection->send( MSG_RESUME, data ); - if ( offset ) - { - int cmd; - if ( waitForAnswer( CMD_RESUMEANSWER, CMD_NONE, data, &cmd ) != -1 ) - { - kdDebug(7019) << "SlaveBase::canResume returning " << (cmd == CMD_RESUMEANSWER) << endl; - return cmd == CMD_RESUMEANSWER; - } else - return false; - } - else // No resuming possible -> no answer to wait for - return true; -} - - - -int SlaveBase::waitForAnswer( int expected1, int expected2, TQByteArray & data, int *pCmd ) -{ - int cmd, result; - for (;;) - { - result = m_pConnection->read( &cmd, data ); - if ( result == -1 ) - { - kdDebug(7019) << "SlaveBase::waitForAnswer has read error." << endl; - return -1; - } - if ( cmd == expected1 || cmd == expected2 ) - { - if ( pCmd ) *pCmd = cmd; - return result; - } - if ( isSubCommand(cmd) ) - { - dispatch( cmd, data ); - } - else - { - kdWarning() << "Got cmd " << cmd << " while waiting for an answer!" << endl; - } - } -} - - -int SlaveBase::readData( TQByteArray &buffer) -{ - int result = waitForAnswer( MSG_DATA, 0, buffer ); - //kdDebug(7019) << "readData: length = " << result << " " << endl; - return result; -} - -void SlaveBase::setTimeoutSpecialCommand(int timeout, const TQByteArray &data) -{ - if (timeout > 0) - d->timeout = time(0)+(time_t)timeout; - else if (timeout == 0) - d->timeout = 1; // Immediate timeout - else - d->timeout = 0; // Canceled - - d->timeoutData = data; -} - -void SlaveBase::dispatch( int command, const TQByteArray &data ) -{ - TQDataStream stream( data, IO_ReadOnly ); - - KURL url; - int i; - - switch( command ) { - case CMD_HOST: { - // Reset s_seqNr, see kpasswdserver/DESIGN - s_seqNr = 0; - TQString passwd; - TQString host, user; - stream >> host >> i >> user >> passwd; - setHost( host, i, user, passwd ); - } - break; - case CMD_CONNECT: - openConnection( ); - break; - case CMD_DISCONNECT: - closeConnection( ); - break; - case CMD_SLAVE_STATUS: - slave_status(); - break; - case CMD_SLAVE_CONNECT: - { - d->onHold = false; - TQString app_socket; - TQDataStream stream( data, IO_ReadOnly); - stream >> app_socket; - appconn->send( MSG_SLAVE_ACK ); - disconnectSlave(); - mConnectedToApp = true; - connectSlave(app_socket); - } break; - case CMD_SLAVE_HOLD: - { - KURL url; - TQDataStream stream( data, IO_ReadOnly); - stream >> url; - d->onHoldUrl = url; - d->onHold = true; - disconnectSlave(); - mConnectedToApp = false; - // Do not close connection! - connectSlave(mPoolSocket); - } break; - case CMD_REPARSECONFIGURATION: - reparseConfiguration(); - break; - case CMD_CONFIG: - stream >> d->configData; -#ifdef Q_OS_UNIX //TODO: not yet available on WIN32 - KSocks::setConfig(d->config); -#endif - delete d->remotefile; - d->remotefile = 0; - break; - case CMD_GET: - { - stream >> url; - get( url ); - } break; - case CMD_PUT: - { - int permissions; - TQ_INT8 iOverwrite, iResume; - stream >> url >> iOverwrite >> iResume >> permissions; - bool overwrite = ( iOverwrite != 0 ); - bool resume = ( iResume != 0 ); - - // Remember that we need to send canResume(), TransferJob is expecting - // it. Well, in theory this shouldn't be done if resume is true. - // (the resume bool is currently unused) - d->needSendCanResume = true /* !resume */; - - put( url, permissions, overwrite, resume); - } break; - case CMD_STAT: - stream >> url; - stat( url ); - break; - case CMD_MIMETYPE: - stream >> url; - mimetype( url ); - break; - case CMD_LISTDIR: - stream >> url; - listDir( url ); - break; - case CMD_MKDIR: - stream >> url >> i; - mkdir( url, i ); - break; - case CMD_RENAME: - { - TQ_INT8 iOverwrite; - KURL url2; - stream >> url >> url2 >> iOverwrite; - bool overwrite = (iOverwrite != 0); - rename( url, url2, overwrite ); - } break; - case CMD_SYMLINK: - { - TQ_INT8 iOverwrite; - TQString target; - stream >> target >> url >> iOverwrite; - bool overwrite = (iOverwrite != 0); - symlink( target, url, overwrite ); - } break; - case CMD_COPY: - { - int permissions; - TQ_INT8 iOverwrite; - KURL url2; - stream >> url >> url2 >> permissions >> iOverwrite; - bool overwrite = (iOverwrite != 0); - copy( url, url2, permissions, overwrite ); - } break; - case CMD_DEL: - { - TQ_INT8 isFile; - stream >> url >> isFile; - del( url, isFile != 0); - } break; - case CMD_CHMOD: - stream >> url >> i; - chmod( url, i); - break; - case CMD_SPECIAL: - special( data ); - break; - case CMD_META_DATA: - //kdDebug(7019) << "(" << getpid() << ") Incoming meta-data..." << endl; - stream >> mIncomingMetaData; - break; - case CMD_SUBURL: - stream >> url; - setSubURL(url); - break; - case CMD_NONE: - fprintf(stderr, "Got unexpected CMD_NONE!\n"); - break; - case CMD_MULTI_GET: - multiGet( data ); - break; - case CMD_LOCALURL: - { - stream >> url; - localURL( url ); - } break; - default: - // Some command we don't understand. - // Just ignore it, it may come from some future version of KDE. - break; - } -} - -TQString SlaveBase::createAuthCacheKey( const KURL& url ) -{ - if( !url.isValid() ) - return TQString::null; - - // Generate the basic key sequence. - TQString key = url.protocol(); - key += '-'; - key += url.host(); - int port = url.port(); - if( port ) - { - key += ':'; - key += TQString::number(port); - } - - return key; -} - -bool SlaveBase::pingCacheDaemon() const -{ -#ifdef Q_OS_UNIX - // TODO: Ping kded / kpasswdserver - KDEsuClient client; - int success = client.ping(); - if( success == -1 ) - { - success = client.startServer(); - if( success == -1 ) - { - kdDebug(7019) << "Cannot start a new deamon!!" << endl; - return false; - } - kdDebug(7019) << "Sucessfully started new cache deamon!!" << endl; - } - return true; -#else - return false; -#endif -} - -bool SlaveBase::checkCachedAuthentication( AuthInfo& info ) -{ - TQCString replyType; - TQByteArray params; - TQByteArray reply; - AuthInfo authResult; - long windowId = metaData("window-id").toLong(); - unsigned long userTimestamp = metaData("user-timestamp").toULong(); - - kdDebug(7019) << "SlaveBase::checkCachedAuthInfo window = " << windowId << " url = " << info.url.url() << endl; - - (void) dcopClient(); // Make sure to have a dcop client. - - TQDataStream stream(params, IO_WriteOnly); - stream << info << windowId << userTimestamp; - - if ( !d->dcopClient->call( "kded", "kpasswdserver", "checkAuthInfo(TDEIO::AuthInfo, long int, unsigned long int)", - params, replyType, reply ) ) - { - kdWarning(7019) << "Can't communicate with kded_kpasswdserver!" << endl; - return false; - } - - if ( replyType == "TDEIO::AuthInfo" ) - { - TQDataStream stream2( reply, IO_ReadOnly ); - stream2 >> authResult; - } - else - { - kdError(7019) << "DCOP function checkAuthInfo(...) returns " - << replyType << ", expected TDEIO::AuthInfo" << endl; - return false; - } - if (!authResult.isModified()) - { - return false; - } - - info = authResult; - return true; -} - -bool SlaveBase::cacheAuthentication( const AuthInfo& info ) -{ - TQByteArray params; - long windowId = metaData("window-id").toLong(); - - (void) dcopClient(); // Make sure to have a dcop client. - - TQDataStream stream(params, IO_WriteOnly); - stream << info << windowId; - - d->dcopClient->send( "kded", "kpasswdserver", "addAuthInfo(TDEIO::AuthInfo, long int)", params ); - - return true; -} - -int SlaveBase::connectTimeout() -{ - bool ok; - TQString tmp = metaData("ConnectTimeout"); - int result = tmp.toInt(&ok); - if (ok) - return result; - return DEFAULT_CONNECT_TIMEOUT; -} - -int SlaveBase::proxyConnectTimeout() -{ - bool ok; - TQString tmp = metaData("ProxyConnectTimeout"); - int result = tmp.toInt(&ok); - if (ok) - return result; - return DEFAULT_PROXY_CONNECT_TIMEOUT; -} - - -int SlaveBase::responseTimeout() -{ - bool ok; - TQString tmp = metaData("ResponseTimeout"); - int result = tmp.toInt(&ok); - if (ok) - return result; - return DEFAULT_RESPONSE_TIMEOUT; -} - - -int SlaveBase::readTimeout() -{ - bool ok; - TQString tmp = metaData("ReadTimeout"); - int result = tmp.toInt(&ok); - if (ok) - return result; - return DEFAULT_READ_TIMEOUT; -} - -bool SlaveBase::wasKilled() const -{ - return d->wasKilled; -} - -void SlaveBase::setKillFlag() -{ - d->wasKilled=true; -} - -void SlaveBase::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - diff --git a/kio/kio/slavebase.h b/kio/kio/slavebase.h deleted file mode 100644 index a65a1f94f..000000000 --- a/kio/kio/slavebase.h +++ /dev/null @@ -1,847 +0,0 @@ -/* - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __slavebase_h -#define __slavebase_h - -#include <kurl.h> -#include <kconfigbase.h> -#include <kio/global.h> -#include <kio/authinfo.h> - -class DCOPClient; -class KRemoteEncoding; - -namespace TDEIO { - -class Connection; -class SlaveBasePrivate; - -/** - * There are two classes that specifies the protocol between application (job) - * and kioslave. SlaveInterface is the class to use on the application end, - * SlaveBase is the one to use on the slave end. - * - * Slave implementations should simply inherit SlaveBase - * - * A call to foo() results in a call to slotFoo() on the other end. - */ -class TDEIO_EXPORT SlaveBase -{ -public: - SlaveBase( const TQCString &protocol, const TQCString &pool_socket, const TQCString &app_socket); - virtual ~SlaveBase(); - - /** - * @internal - * Terminate the slave by calling the destructor and then ::exit() - */ - void exit(); - - /** - * @internal - */ - void dispatchLoop(); - - /** - * @internal - */ - void setConnection( Connection* connection ) { m_pConnection = connection; } - /** - * @internal - */ - Connection *connection() const { return m_pConnection; } - - - /////////// - // Message Signals to send to the job - /////////// - - /** - * Sends data in the slave to the job (i.e. in get). - * - * To signal end of data, simply send an empty - * TQByteArray(). - * - * @param data the data read by the slave - */ - void data( const TQByteArray &data ); - - /** - * Asks for data from the job. - * @see readData - */ - void dataReq( ); - - /** - * Call to signal an error. - * This also finishes the job, no need to call finished. - * - * If the Error code is TDEIO::ERR_SLAVE_DEFINED then the - * _text should contain the complete translated text of - * of the error message. This message will be displayed - * in an KTextBrowser which allows rich text complete - * with hyper links. Email links will call the default - * mailer, "exec:/command arg1 arg2" will be forked and - * all other links will call the default browser. - * - * @see TDEIO::Error - * @see KTextBrowser - * @param _errid the error code from TDEIO::Error - * @param _text the rich text error message - */ - void error( int _errid, const TQString &_text ); - - /** - * Call in openConnection, if you reimplement it, when you're done. - */ - void connected(); - - /** - * Call to signal successful completion of any command - * (besides openConnection and closeConnection) - */ - void finished(); - - /** - * Call to signal that data from the sub-URL is needed - */ - void needSubURLData(); - - /** - * Used to report the status of the slave. - * @param host the slave is currently connected to. (Should be - * empty if not connected) - * @param connected Whether an actual network connection exists. - **/ - void slaveStatus(const TQString &host, bool connected); - - /** - * Call this from stat() to express details about an object, the - * UDSEntry customarily contains the atoms describing file name, size, - * mimetype, etc. - * @param _entry The UDSEntry containing all of the object attributes. - */ - void statEntry( const UDSEntry& _entry ); - - /** - * Call this in listDir, each time you have a bunch of entries - * to report. - * @param _entry The UDSEntry containing all of the object attributes. - */ - void listEntries( const UDSEntryList& _entry ); - - /** - * Call this at the beginning of put(), to give the size of the existing - * partial file, if there is one. The @p offset argument notifies the - * other job (the one that gets the data) about the offset to use. - * In this case, the boolean returns whether we can indeed resume or not - * (we can't if the protocol doing the get() doesn't support setting an offset) - */ - bool canResume( TDEIO::filesize_t offset ); - - /* - * Call this at the beginning of get(), if the "resume" metadata was set - * and resuming is implemented by this protocol. - */ - void canResume(); - - /////////// - // Info Signals to send to the job - /////////// - - /** - * Call this in get and copy, to give the total size - * of the file - * Call in listDir too, when you know the total number of items. - */ - void totalSize( TDEIO::filesize_t _bytes ); - /** - * Call this during get and copy, once in a while, - * to give some info about the current state. - * Don't emit it in listDir, listEntries speaks for itself. - */ - void processedSize( TDEIO::filesize_t _bytes ); - - /** - * Only use this if you can't know in advance the size of the - * copied data. For example, if you're doing variable bitrate - * compression of the source. - * - * STUB ! Currently unimplemented. Here now for binary compatibility. - * - * Call this during get and copy, once in a while, - * to give some info about the current state. - * Don't emit it in listDir, listEntries speaks for itself. - */ - void processedPercent( float percent ); - - /** - * Call this in get and copy, to give the current transfer - * speed, but only if it can't be calculated out of the size you - * passed to processedSize (in most cases you don't want to call it) - */ - void speed( unsigned long _bytes_per_second ); - - /** - * Call this to signal a redirection - * The job will take care of going to that url. - */ - void redirection( const KURL &_url ); - - /** - * Tell that we will only get an error page here. - * This means: the data you'll get isn't the data you requested, - * but an error page (usually HTML) that describes an error. - */ - void errorPage(); - - /** - * Call this in mimetype() and in get(), when you know the mimetype. - * See mimetype about other ways to implement it. - */ - void mimeType( const TQString &_type ); - - /** - * Call to signal a warning, to be displayed in a dialog box. - */ - void warning( const TQString &msg ); - - /** - * Call to signal a message, to be displayed if the application wants to, - * for instance in a status bar. Usual examples are "connecting to host xyz", etc. - */ - void infoMessage( const TQString &msg ); - - enum MessageBoxType { QuestionYesNo = 1, WarningYesNo = 2, WarningContinueCancel = 3, WarningYesNoCancel = 4, Information = 5, SSLMessageBox = 6 }; - - /** - * Call this to show a message box from the slave - * @param type type of message box: QuestionYesNo, WarningYesNo, WarningContinueCancel... - * @param text Message string. May contain newlines. - * @param caption Message box title. - * @param buttonYes The text for the first button. - * The default is i18n("&Yes"). - * @param buttonNo The text for the second button. - * The default is i18n("&No"). - * Note: for ContinueCancel, buttonYes is the continue button and buttonNo is unused. - * and for Information, none is used. - * @return a button code, as defined in KMessageBox, or 0 on communication error. - */ - int messageBox( MessageBoxType type, const TQString &text, - const TQString &caption = TQString::null, - const TQString &buttonYes = TQString::null, - const TQString &buttonNo = TQString::null ); - - /** - * Call this to show a message box from the slave - * @param text Message string. May contain newlines. - * @param type type of message box: QuestionYesNo, WarningYesNo, WarningContinueCancel... - * @param caption Message box title. - * @param buttonYes The text for the first button. - * The default is i18n("&Yes"). - * @param buttonNo The text for the second button. - * The default is i18n("&No"). - * Note: for ContinueCancel, buttonYes is the continue button and buttonNo is unused. - * and for Information, none is used. - * @param dontAskAgainName A checkbox is added with which further confirmation can be turned off. - * The string is used to lookup and store the setting in kioslaverc. - * @return a button code, as defined in KMessageBox, or 0 on communication error. - * @since 3.3 - */ - int messageBox( const TQString &text, MessageBoxType type, - const TQString &caption = TQString::null, - const TQString &buttonYes = TQString::null, - const TQString &buttonNo = TQString::null, - const TQString &dontAskAgainName = TQString::null ); - - /** - * Sets meta-data to be send to the application before the first - * data() or finished() signal. - */ - void setMetaData(const TQString &key, const TQString &value); - - /** - * Queries for the existence of a certain config/meta-data entry - * send by the application to the slave. - * @since 3.2 - */ - bool hasMetaData(const TQString &key) const; - - /** - * Queries for config/meta-data send by the application to the slave. - * @since 3.2 - */ - TQString metaData(const TQString &key) const; - - /** - * @obsolete kept for binary compatibility - * Queries for the existence of a certain config/meta-data entry - * send by the application to the slave. - */ - bool hasMetaData(const TQString &key); - - /** - * @obsolete kept for binary compatibility - * Queries for config/meta-data sent by the application to the slave. - */ - TQString metaData(const TQString &key); - - /** - * @internal for ForwardingSlaveBase - * Contains all metadata (but no config) sent by the application to the slave. - * @since 3.5.2 - */ - MetaData allMetaData() const { return mIncomingMetaData; } - - /** - * Returns a configuration object to query config/meta-data information - * from. - * - * The application provides the slave with all configuration information - * relevant for the current protocol and host. - */ - TDEConfigBase* config(); - - /** - * Returns an object that can translate remote filenames into proper - * Unicode forms. This encoding can be set by the user. - * - * @since 3.3 - */ - KRemoteEncoding* remoteEncoding(); - - - /////////// - // Commands sent by the job, the slave has to - // override what it wants to implement - /////////// - - /** - * Set the host - * @param host - * @param port - * @param user - * @param pass - * Called directly by createSlave, this is why there is no equivalent in - * SlaveInterface, unlike the other methods. - * - * This method is called whenever a change in host, port or user occurs. - */ - virtual void setHost(const TQString& host, int port, const TQString& user, const TQString& pass); - - /** - * Prepare slave for streaming operation - */ - virtual void setSubURL(const KURL&url); - - /** - * Opens the connection (forced) - * When this function gets called the slave is operating in - * connection-oriented mode. - * When a connection gets lost while the slave operates in - * connection oriented mode, the slave should report - * ERR_CONNECTION_BROKEN instead of reconnecting. The user is - * expected to disconnect the slave in the error handler. - */ - virtual void openConnection(); - - /** - * Closes the connection (forced) - * Called when the application disconnects the slave to close - * any open network connections. - * - * When the slave was operating in connection-oriented mode, - * it should reset itself to connectionless (default) mode. - */ - virtual void closeConnection(); - - /** - * get, aka read. - * @param url the full url for this request. Host, port and user of the URL - * can be assumed to be the same as in the last setHost() call. - * The slave emits the data through data - */ - virtual void get( const KURL& url ); - - /** - * put, i.e. write data into a file. - * - * @param url where to write the file - * @param permissions may be -1. In this case no special permission mode is set. - * @param overwrite if true, any existing file will be overwritten. - * If the file indeed already exists, the slave should NOT apply the - * permissions change to it. - * @param resume currently unused, please ignore. - * The support for resuming using .part files is done by calling canResume(). - * - * IMPORTANT: Use the "modified" metadata in order to set the modification time of the file. - * - * @see canResume() - */ - virtual void put( const KURL& url, int permissions, bool overwrite, bool resume ); - - /** - * Finds all details for one file or directory. - * The information returned is the same as what listDir returns, - * but only for one file or directory. - */ - virtual void stat( const KURL& url ); - - /** - * Finds mimetype for one file or directory. - * - * This method should either emit 'mimeType' or it - * should send a block of data big enough to be able - * to determine the mimetype. - * - * If the slave doesn't reimplement it, a get will - * be issued, i.e. the whole file will be downloaded before - * determining the mimetype on it - this is obviously not a - * good thing in most cases. - */ - virtual void mimetype( const KURL& url ); - - /** - * Lists the contents of @p url. - * The slave should emit ERR_CANNOT_ENTER_DIRECTORY if it doesn't exist, - * if we don't have enough permissions, or if it is a file - * It should also emit totalFiles as soon as it knows how many - * files it will list. - */ - virtual void listDir( const KURL& url ); - - /** - * Create a directory - * @param url path to the directory to create - * @param permissions the permissions to set after creating the directory - * (-1 if no permissions to be set) - * The slave emits ERR_COULD_NOT_MKDIR if failure. - */ - virtual void mkdir( const KURL&url, int permissions ); - - /** - * Rename @p oldname into @p newname. - * If the slave returns an error ERR_UNSUPPORTED_ACTION, the job will - * ask for copy + del instead. - * @param src where to move the file from - * @param dest where to move the file to - * @param overwrite if true, any existing file will be overwritten - */ - virtual void rename( const KURL& src, const KURL& dest, bool overwrite ); - - /** - * Creates a symbolic link named @p dest, pointing to @p target, which - * may be a relative or an absolute path. - * @param target The string that will become the "target" of the link (can be relative) - * @param dest The symlink to create. - * @param overwrite whether to automatically overwrite if the dest exists - */ - virtual void symlink( const TQString& target, const KURL& dest, bool overwrite ); - - /** - * Change permissions on @p path - * The slave emits ERR_DOES_NOT_EXIST or ERR_CANNOT_CHMOD - */ - virtual void chmod( const KURL& url, int permissions ); - - /** - * Copy @p src into @p dest. - * If the slave returns an error ERR_UNSUPPORTED_ACTION, the job will - * ask for get + put instead. - * @param src where to copy the file from (decoded) - * @param dest where to copy the file to (decoded) - * @param permissions may be -1. In this case no special permission mode is set. - * @param overwrite if true, any existing file will be overwritten - * - */ - virtual void copy( const KURL &src, const KURL &dest, int permissions, bool overwrite ); - - /** - * Delete a file or directory. - * @param url file/directory to delete - * @param isfile if true, a file should be deleted. - * if false, a directory should be deleted. - */ - virtual void del( const KURL &url, bool isfile); - - // TODO KDE4: add setLinkDest() or something, to modify symlink targets. - // Will be used for kio_file but also kio_remote (#97129) - - /** - * Used for any command that is specific to this slave (protocol) - * Examples are : HTTP POST, mount and unmount (kio_file) - * - * @param data packed data; the meaning is completely dependent on the - * slave, but usually starts with an int for the command number. - * Document your slave's commands, at least in its header file. - */ - virtual void special( const TQByteArray & data ); - - /** - * Used for multiple get. Currently only used foir HTTP pielining - * support. - * - * @param data packed data; Contains number of URLs to fetch, and for - * each URL the URL itself and its associated MetaData. - */ - virtual void multiGet( const TQByteArray & data ); - - /** - * Called to get the status of the slave. Slave should respond - * by calling slaveStatus(...) - */ - virtual void slave_status(); - - /** - * Called by the scheduler to tell the slave that the configuration - * changed (i.e. proxy settings) . - */ - virtual void reparseConfiguration(); - - /** - * For use with for ForwardingSlaveBase - * Returns the local URL of the given remote URL if possible - * @since R14.0.0 - */ - virtual void localURL( const KURL& remoteURL ); - - /** - * @return timeout value for connecting to remote host. - */ - int connectTimeout(); - - /** - * @return timeout value for connecting to proxy in secs. - */ - int proxyConnectTimeout(); - - /** - * @return timeout value for read from first data from - * remote host in seconds. - */ - int responseTimeout(); - - /** - * @return timeout value for read from subsequent data from - * remote host in secs. - */ - int readTimeout(); - - /** - * This function sets a timeout of @p timeout seconds and calls - * special(data) when the timeout occurs as if it was called by the - * application. - * - * A timeout can only occur when the slave is waiting for a command - * from the application. - * - * Specifying a negative timeout cancels a pending timeout. - * - * Only one timeout at a time is supported, setting a timeout - * cancels any pending timeout. - * @since 3.1 - */ - void setTimeoutSpecialCommand(int timeout, const TQByteArray &data=TQByteArray()); - - /** - * @internal - */ - static void sigsegv_handler(int); - /** - * @internal - */ - static void sigpipe_handler(int); - - ///////////////// - // Dispatching (internal) - //////////////// - - /** - * @internal - */ - virtual bool dispatch(); - /** - * @internal - */ - virtual void dispatch( int command, const TQByteArray &data ); - - /** - * Read data send by the job, after a dataReq - * - * @param buffer buffer where data is stored - * @return 0 on end of data, - * > 0 bytes read - * < 0 error - **/ - int readData( TQByteArray &buffer ); - - /** - * internal function to be called by the slave. - * It collects entries and emits them via listEntries - * when enough of them are there or a certain time - * frame exceeded (to make sure the app gets some - * items in time but not too many items one by one - * as this will cause a drastic performance penalty) - * @param _entry The UDSEntry containing all of the object attributes. - * @param ready set to true after emitting all items. @p _entry is not - * used in this case - */ - void listEntry( const UDSEntry& _entry, bool ready); - - /** - * internal function to connect a slave to/ disconnect from - * either the slave pool or the application - */ - void connectSlave(const TQString& path); - void disconnectSlave(); - - /** - * Prompt the user for Authorization info (login & password). - * - * Use this function to request authorization information from - * the end user. You can also pass an error message which explains - * why a previous authorization attempt failed. Here is a very - * simple example: - * - * \code - * TDEIO::AuthInfo authInfo; - * if ( openPassDlg( authInfo ) ) - * { - * kdDebug() << TQString::fromLatin1("User: ") - * << authInfo.username << endl; - * kdDebug() << TQString::fromLatin1("Password: ") - * << TQString::fromLatin1("Not displayed here!") << endl; - * } - * \endcode - * - * You can also preset some values like the username, caption or - * comment as follows: - * - * \code - * TDEIO::AuthInfo authInfo; - * authInfo.caption= "Acme Password Dialog"; - * authInfo.username= "Wile E. Coyote"; - * TQString errorMsg = "You entered an incorrect password."; - * if ( openPassDlg( authInfo, errorMsg ) ) - * { - * kdDebug() << TQString::fromLatin1("User: ") - * << authInfo.username << endl; - * kdDebug() << TQString::fromLatin1("Password: ") - * << TQString::fromLatin1("Not displayed here!") << endl; - * } - * \endcode - * - * \note You should consider using checkCachedAuthentication() to - * see if the password is available in kpasswdserver before calling - * this function. - * - * \note A call to this function can fail and return @p false, - * if the UIServer could not be started for whatever reason. - * - * @see checkCachedAuthentication - * @param info See AuthInfo. - * @param errorMsg Error message to show - * @return @p true if user clicks on "OK", @p false otherwsie. - * @since 3.1 - */ - bool openPassDlg( TDEIO::AuthInfo& info, const TQString &errorMsg ); - - /** - * Same as above function except it does not need error message. - * BIC: Combine this function with the above for KDE4. - */ - bool openPassDlg( TDEIO::AuthInfo& info ); - - /** - * Checks for cached authentication based on parameters - * given by @p info. - * - * Use this function to check if any cached password exists - * for the URL given by @p info. If @p AuthInfo::realmValue - * and/or @p AuthInfo::verifyPath flag is specified, then - * they will also be factored in determining the presence - * of a cached password. Note that @p Auth::url is a required - * parameter when attempting to check for cached authorization - * info. Here is a simple example: - * - * \code - * AuthInfo info; - * info.url = KURL("http://www.foobar.org/foo/bar"); - * info.username = "somename"; - * info.verifyPath = true; - * if ( !checkCachedAuthentication( info ) ) - * { - * if ( !openPassDlg(info) ) - * .... - * } - * \endcode - * - * @param info See AuthInfo. - * @return @p true if cached Authorization is found, false otherwise. - */ - bool checkCachedAuthentication( AuthInfo& info ); - - /** - * Explicitly store authentication information. openPassDlg already - * stores password information automatically, you only need to call - * this function if you want to store authentication information that - * is different from the information returned by openPassDlg. - */ - bool cacheAuthentication( const AuthInfo& info ); - - /** - * @obsolete as of 3.1. - * TODO: Remove before KDE 4.0 - */ - bool pingCacheDaemon() const; - - /** - * @obsolete as of 3.1. Use openPassDlg instead. - * TODO: Remove before KDE 4.0 - * Creates a basic key to be used to cache the password. - * @param url the url from which the key is supposed to be generated - */ - TQString createAuthCacheKey( const KURL& url ); - - /** - * @obsolete as of 3.1. Use openPassDlg instead. - * TODO: Remove before KDE 4.0 - * - * Cache authentication information is now stored automatically - * by openPassDlg. - */ - void sendAuthenticationKey( const TQCString& gKey, const TQCString& key, bool keep ); - - /** - * @obsolete as of 3.1. Use openPassDlg instead. - * TODO: Remove before KDE 4.0 - * - * Cached authentication information is now session based and - * removed automatically when a given session ends, i.e. the - * application is closed. - */ - void delCachedAuthentication( const TQString& key ); - - /** - * @obsolete as of 3.1. Use openPassDlg instead. - * TODO: Remove before KDE 4.0 - */ - void setMultipleAuthCaching( bool ) {}; - - /** - * @obsolete as of 3.1. Use openPassDlg instead. - * TODO: Remove before KDE 4.0 - */ - bool multipleAuthCaching() const { return false; } - - /** - * Used by the slave to check if it can connect - * to a given host. This should be called where the slave is ready - * to do a ::connect() on a socket. For each call to - * requestNetwork must exist a matching call to - * dropNetwork, or the system will stay online until - * KNetMgr gets closed (or the SlaveBase gets destructed)! - * - * If KNetMgr is not running, then this is a no-op and returns true - * - * @param host tells the netmgr the host the slave wants to connect - * to. As this could also be a proxy, we can't just take - * the host currenctly connected to (but that's the default - * value) - * - * @return true in theorie, the host is reachable - * false the system is offline and the host is in a remote network. - */ - bool requestNetwork(const TQString& host = TQString::null); - - /** - * Used by the slave to withdraw a connection requested by - * requestNetwork. This function cancels the last call to - * requestNetwork. If a client uses more than one internet - * connection, it must use dropNetwork(host) to - * stop each request. - * - * If KNetMgr is not running, then this is a no-op. - * - * @param host the host passed to requestNetwork - * - * A slave should call this function every time it disconnect from a host. - * */ - void dropNetwork(const TQString& host = TQString::null); - - /** - * Return the dcop client used by this slave. - * @since 3.1 - */ - DCOPClient *dcopClient(); - - /** - * Wait for an answer to our request, until we get @p expected1 or @p expected2 - * @return the result from readData, as well as the cmd in *pCmd if set, and the data in @p data - */ - int waitForAnswer( int expected1, int expected2, TQByteArray & data, int * pCmd = 0 ); - - /** - * Internal function to transmit meta data to the application. - */ - void sendMetaData(); - - /** - * Name of the protocol supported by this slave - */ - TQCString mProtocol; - - Connection * m_pConnection; - - MetaData mOutgoingMetaData; - MetaData mIncomingMetaData; - - /** If your ioslave was killed by a signal, wasKilled() returns true. - Check it regularly in lengthy functions (e.g. in get();) and return - as fast as possible from this function if wasKilled() returns true. - This will ensure that your slave destructor will be called correctly. - @since 3.1 - */ - bool wasKilled() const; - - /** Internally used. - * @internal - * @since 3.1 - */ - void setKillFlag(); - -protected: - UDSEntryList pendingListEntries; - uint listEntryCurrentSize; - long listEntry_sec, listEntry_usec; - Connection *appconn; - TQString mPoolSocket; - TQString mAppSocket; - bool mConnectedToApp; - static long s_seqNr; - virtual void virtual_hook( int id, void* data ); - -private: - SlaveBasePrivate *d; -}; - -} - -#endif diff --git a/kio/kio/slaveconfig.cpp b/kio/kio/slaveconfig.cpp deleted file mode 100644 index c0ec44779..000000000 --- a/kio/kio/slaveconfig.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// -*- c++ -*- -/* - * This file is part of the KDE libraries - * Copyright (c) 2001 Waldo Bastian <bastian@kde.org> - * - * $Id$ - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#include <assert.h> - -#include <tqdict.h> - -#include <kconfig.h> -#include <kstaticdeleter.h> -#include <kprotocolinfo.h> -#include <kprotocolmanager.h> - -#include "slaveconfig.h" - -using namespace TDEIO; - -namespace TDEIO { - -class SlaveConfigProtocol -{ -public: - SlaveConfigProtocol() { host.setAutoDelete(true); } - ~SlaveConfigProtocol() - { - delete configFile; - } - -public: - MetaData global; - TQDict<MetaData> host; - TDEConfig *configFile; -}; - -static void readConfig(TDEConfig *config, const TQString & group, MetaData *metaData) -{ - *metaData += config->entryMap(group); -} - -class SlaveConfigPrivate -{ - public: - void readGlobalConfig(); - SlaveConfigProtocol *readProtocolConfig(const TQString &_protocol); - SlaveConfigProtocol *findProtocolConfig(const TQString &_protocol); - void readConfigProtocolHost(const TQString &_protocol, SlaveConfigProtocol *scp, const TQString &host); - public: - MetaData global; - TQDict<SlaveConfigProtocol> protocol; -}; - -void SlaveConfigPrivate::readGlobalConfig() -{ - global.clear(); - // Read stuff... - TDEConfig *config = KProtocolManager::config(); - readConfig(TDEGlobal::config(), "Socks", &global); // Socks settings. - if ( config ) - readConfig(config, "<default>", &global); -} - -SlaveConfigProtocol* SlaveConfigPrivate::readProtocolConfig(const TQString &_protocol) -{ - SlaveConfigProtocol *scp = protocol.find(_protocol); - if (!scp) - { - TQString filename = KProtocolInfo::config(_protocol); - scp = new SlaveConfigProtocol; - scp->configFile = new TDEConfig(filename, true, false); - protocol.insert(_protocol, scp); - } - // Read global stuff... - readConfig(scp->configFile, "<default>", &(scp->global)); - return scp; -} - -SlaveConfigProtocol* SlaveConfigPrivate::findProtocolConfig(const TQString &_protocol) -{ - SlaveConfigProtocol *scp = protocol.find(_protocol); - if (!scp) - scp = readProtocolConfig(_protocol); - return scp; -} - -void SlaveConfigPrivate::readConfigProtocolHost(const TQString &, SlaveConfigProtocol *scp, const TQString &host) -{ - MetaData *metaData = new MetaData; - scp->host.replace(host, metaData); - - // Read stuff - // Break host into domains - TQString domain = host; - - if (!domain.contains('.')) - { - // Host without domain. - if (scp->configFile->hasGroup("<local>")) - readConfig(scp->configFile, "<local>", metaData); - } - - int pos = 0; - do - { - pos = host.findRev('.', pos-1); - - if (pos < 0) - domain = host; - else - domain = host.mid(pos+1); - - if (scp->configFile->hasGroup(domain)) - readConfig(scp->configFile, domain.lower(), metaData); - } - while (pos > 0); -} - - -SlaveConfig *SlaveConfig::_self = 0; -static KStaticDeleter<SlaveConfig> slaveconfigsd; - -SlaveConfig *SlaveConfig::self() -{ - if (!_self) - _self = slaveconfigsd.setObject(_self, new SlaveConfig); - return _self; -} - -SlaveConfig::SlaveConfig() -{ - d = new SlaveConfigPrivate; - d->protocol.setAutoDelete(true); - d->readGlobalConfig(); -} - -SlaveConfig::~SlaveConfig() -{ - delete d; d = 0; - _self = 0; -} - -void SlaveConfig::setConfigData(const TQString &protocol, - const TQString &host, - const TQString &key, - const TQString &value ) -{ - MetaData config; - config.insert(key, value); - setConfigData(protocol, host, config); -} - -void SlaveConfig::setConfigData(const TQString &protocol, const TQString &host, const MetaData &config ) -{ - if (protocol.isEmpty()) - d->global += config; - else { - SlaveConfigProtocol *scp = d->findProtocolConfig(protocol); - if (host.isEmpty()) - { - scp->global += config; - } - else - { - MetaData *hostConfig = scp->host.find(host); - if (!hostConfig) - { - d->readConfigProtocolHost(protocol, scp, host); - hostConfig = scp->host.find(host); - assert(hostConfig); - } - *hostConfig += config; - } - } -} - -MetaData SlaveConfig::configData(const TQString &protocol, const TQString &host) -{ - MetaData config = d->global; - SlaveConfigProtocol *scp = d->findProtocolConfig(protocol); - config += scp->global; - if (host.isEmpty()) - return config; - MetaData *hostConfig = scp->host.find(host); - if (!hostConfig) - { - d->readConfigProtocolHost(protocol, scp, host); - emit configNeeded(protocol, host); - hostConfig = scp->host.find(host); - assert(hostConfig); - } - config += *hostConfig; - return config; -} - -TQString SlaveConfig::configData(const TQString &protocol, const TQString &host, const TQString &key) -{ - return configData(protocol, host)[key]; -} - -void SlaveConfig::reset() -{ - d->protocol.clear(); - d->readGlobalConfig(); -} - -} - -#include "slaveconfig.moc" diff --git a/kio/kio/slaveconfig.h b/kio/kio/slaveconfig.h deleted file mode 100644 index 5bdc6cda8..000000000 --- a/kio/kio/slaveconfig.h +++ /dev/null @@ -1,106 +0,0 @@ -// -*- c++ -*- -/* - * This file is part of the KDE libraries - * Copyright (c) 2001 Waldo Bastian <bastian@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - **/ - -#ifndef KIO_SLAVE_CONFIG_H -#define KIO_SLAVE_CONFIG_H - -#include <tqobject.h> -#include <kio/global.h> - -namespace TDEIO { - - class SlaveConfigPrivate; - /** - * SlaveConfig - * - * This class manages the configuration for io-slaves based on protocol - * and host. The Scheduler makes use of this class to configure the slave - * whenever it has to connect to a new host. - * - * You only need to use this class if you want to override specific - * configuration items of an io-slave when the io-slave is used by - * your application. - * - * Normally io-slaves are being configured by "kio_<protocol>rc" - * configuration files. Groups defined in such files are treated as host - * or domain specification. Configuration items defined in a group are - * only applied when the slave is connecting with a host that matches with - * the host and/or domain specified by the group. - */ - class TDEIO_EXPORT SlaveConfig : public TQObject - { - Q_OBJECT - public: - static SlaveConfig *self(); - ~SlaveConfig(); - /** - * Configure slaves of type @p protocol by setting @p key to @p value. - * If @p host is specified the configuration only applies when dealing - * with @p host. - * - * Changes made to the slave configuration only apply to slaves - * used by the current process. - */ - void setConfigData(const TQString &protocol, const TQString &host, const TQString &key, const TQString &value ); - - /** - * Configure slaves of type @p protocol with @p config. - * If @p host is specified the configuration only applies when dealing - * with @p host. - * - * Changes made to the slave configuration only apply to slaves - * used by the current process. - */ - void setConfigData(const TQString &protocol, const TQString &host, const MetaData &config ); - - /** - * Query slave configuration for slaves of type @p protocol when - * dealing with @p host. - */ - MetaData configData(const TQString &protocol, const TQString &host); - - /** - * Query a specific configuration key for slaves of type @p protocol when - * dealing with @p host. - */ - TQString configData(const TQString &protocol, const TQString &host, const TQString &key); - - /** - * Undo any changes made by calls to setConfigData. - */ - void reset(); - signals: - /** - * This signal is raised when a slave of type @p protocol deals - * with @p host for the first time. - * - * Your application can use this signal to make some last minute - * configuration changes with setConfigData based on the - * host. - */ - void configNeeded(const TQString &protocol, const TQString &host); - protected: - SlaveConfig(); - static SlaveConfig *_self; - SlaveConfigPrivate *d; - }; -} - -#endif diff --git a/kio/kio/slaveinterface.cpp b/kio/kio/slaveinterface.cpp deleted file mode 100644 index 5ba2f6e86..000000000 --- a/kio/kio/slaveinterface.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kio/slaveinterface.h" -#include "kio/slavebase.h" -#include "kio/connection.h" -#include <errno.h> -#include <assert.h> -#include <kdebug.h> -#include <stdlib.h> -#include <sys/time.h> -#include <unistd.h> -#include <signal.h> -#include <kio/observer.h> -#include <kapplication.h> -#include <dcopclient.h> -#include <time.h> -#include <tqtimer.h> - -using namespace TDEIO; - - -TQDataStream &operator <<(TQDataStream &s, const TDEIO::UDSEntry &e ) -{ - // On 32-bit platforms we send UDS_SIZE with UDS_SIZE_LARGE in front - // of it to carry the 32 msb. We can't send a 64 bit UDS_SIZE because - // that would break the compatibility of the wire-protocol with KDE 2. - // We do the same on 64-bit platforms in case we run in a mixed 32/64bit - // environment. - - TQ_UINT32 size = 0; - TDEIO::UDSEntry::ConstIterator it = e.begin(); - for( ; it != e.end(); ++it ) - { - size++; - if ((*it).m_uds == TDEIO::UDS_SIZE) - size++; - } - s << size; - it = e.begin(); - for( ; it != e.end(); ++it ) - { - if ((*it).m_uds == TDEIO::UDS_SIZE) - { - TDEIO::UDSAtom a; - a.m_uds = TDEIO::UDS_SIZE_LARGE; - a.m_long = (*it).m_long >> 32; - s << a; - } - s << *it; - } - return s; -} - -TQDataStream &operator >>(TQDataStream &s, TDEIO::UDSEntry &e ) -{ - e.clear(); - TQ_UINT32 size; - s >> size; - - // On 32-bit platforms we send UDS_SIZE with UDS_SIZE_LARGE in front - // of it to carry the 32 msb. We can't send a 64 bit UDS_SIZE because - // that would break the compatibility of the wire-protocol with KDE 2. - // We do the same on 64-bit platforms in case we run in a mixed 32/64bit - // environment. - TQ_LLONG msb = 0; - for(TQ_UINT32 i = 0; i < size; i++) - { - TDEIO::UDSAtom a; - s >> a; - if (a.m_uds == TDEIO::UDS_SIZE_LARGE) - { - msb = a.m_long; - } - else - { - if (a.m_uds == TDEIO::UDS_SIZE) - { - if (a.m_long < 0) - a.m_long += (TQ_LLONG) 1 << 32; - a.m_long += msb << 32; - } - e.append(a); - msb = 0; - } - } - return s; -} - -static const unsigned int max_nums = 8; - -class TDEIO::SlaveInterfacePrivate -{ -public: - SlaveInterfacePrivate() { - slave_calcs_speed = false; - start_time.tv_sec = 0; - start_time.tv_usec = 0; - last_time = 0; - nums = 0; - filesize = 0; - offset = 0; - } - bool slave_calcs_speed; - struct timeval start_time; - uint nums; - long times[max_nums]; - TDEIO::filesize_t sizes[max_nums]; - size_t last_time; - TDEIO::filesize_t filesize, offset; - - TQTimer speed_timer; -}; - -////////////// - -SlaveInterface::SlaveInterface( Connection * connection ) -{ - m_pConnection = connection; - m_progressId = 0; - - d = new SlaveInterfacePrivate; - connect(&d->speed_timer, TQT_SIGNAL(timeout()), TQT_SLOT(calcSpeed())); -} - -SlaveInterface::~SlaveInterface() -{ - // Note: no kdDebug() here (scheduler is deleted very late) - m_pConnection = 0; // a bit like the "wasDeleted" of TQObject... - - delete d; -} - -static TDEIO::filesize_t readFilesize_t(TQDataStream &stream) -{ - TDEIO::filesize_t result; - unsigned long ul; - stream >> ul; - result = ul; - if (stream.atEnd()) - return result; - stream >> ul; - result += ((TDEIO::filesize_t)ul) << 32; - return result; -} - - -bool SlaveInterface::dispatch() -{ - assert( m_pConnection ); - - int cmd; - TQByteArray data; - - if (m_pConnection->read( &cmd, data ) == -1) - return false; - - return dispatch( cmd, data ); -} - -void SlaveInterface::calcSpeed() -{ - if (d->slave_calcs_speed) { - d->speed_timer.stop(); - return; - } - - struct timeval tv; - gettimeofday(&tv, 0); - - long diff = ((tv.tv_sec - d->start_time.tv_sec) * 1000000 + - tv.tv_usec - d->start_time.tv_usec) / 1000; - if (diff - d->last_time >= 900) { - d->last_time = diff; - if (d->nums == max_nums) { - // let's hope gcc can optimize that well enough - // otherwise I'd try memcpy :) - for (unsigned int i = 1; i < max_nums; ++i) { - d->times[i-1] = d->times[i]; - d->sizes[i-1] = d->sizes[i]; - } - d->nums--; - } - d->times[d->nums] = diff; - d->sizes[d->nums++] = d->filesize - d->offset; - - TDEIO::filesize_t lspeed = 1000 * (d->sizes[d->nums-1] - d->sizes[0]) / (d->times[d->nums-1] - d->times[0]); - -// kdDebug() << "proceeed " << (long)d->filesize << " " << diff << " " -// << long(d->sizes[d->nums-1] - d->sizes[0]) << " " -// << d->times[d->nums-1] - d->times[0] << " " -// << long(lspeed) << " " << double(d->filesize) / diff -// << " " << convertSize(lspeed) << " " -// << convertSize(long(double(d->filesize) / diff) * 1000) << " " -// << endl ; - - if (!lspeed) { - d->nums = 1; - d->times[0] = diff; - d->sizes[0] = d->filesize - d->offset; - } - emit speed(lspeed); - } -} - -bool SlaveInterface::dispatch( int _cmd, const TQByteArray &rawdata ) -{ - //kdDebug(7007) << "dispatch " << _cmd << endl; - - TQDataStream stream( rawdata, IO_ReadOnly ); - - TQString str1; - TQ_INT32 i; - TQ_INT8 b; - TQ_UINT32 ul; - - switch( _cmd ) { - case MSG_DATA: - emit data( rawdata ); - break; - case MSG_DATA_REQ: - emit dataReq(); - break; - case MSG_FINISHED: - //kdDebug(7007) << "Finished [this = " << this << "]" << endl; - d->offset = 0; - d->speed_timer.stop(); - emit finished(); - break; - case MSG_STAT_ENTRY: - { - UDSEntry entry; - stream >> entry; - emit statEntry(entry); - } - break; - case MSG_LIST_ENTRIES: - { - TQ_UINT32 count; - stream >> count; - - UDSEntryList list; - UDSEntry entry; - for (uint i = 0; i < count; i++) { - stream >> entry; - list.append(entry); - } - emit listEntries(list); - - } - break; - case MSG_RESUME: // From the put job - { - d->offset = readFilesize_t(stream); - emit canResume( d->offset ); - } - break; - case MSG_CANRESUME: // From the get job - d->filesize = d->offset; - emit canResume(0); // the arg doesn't matter - break; - case MSG_ERROR: - stream >> i >> str1; - kdDebug(7007) << "error " << i << " " << str1 << endl; - emit error( i, str1 ); - break; - case MSG_SLAVE_STATUS: - { - pid_t pid; - TQCString protocol; - stream >> pid >> protocol >> str1 >> b; - emit slaveStatus(pid, protocol, str1, (b != 0)); - } - break; - case MSG_CONNECTED: - emit connected(); - break; - - case INF_TOTAL_SIZE: - { - TDEIO::filesize_t size = readFilesize_t(stream); - gettimeofday(&d->start_time, 0); - d->last_time = 0; - d->filesize = d->offset; - d->sizes[0] = d->filesize - d->offset; - d->times[0] = 0; - d->nums = 1; - d->speed_timer.start(1000); - d->slave_calcs_speed = false; - emit totalSize( size ); - } - break; - case INF_PROCESSED_SIZE: - { - TDEIO::filesize_t size = readFilesize_t(stream); - emit processedSize( size ); - d->filesize = size; - } - break; - case INF_SPEED: - stream >> ul; - d->slave_calcs_speed = true; - d->speed_timer.stop(); - - emit speed( ul ); - break; - case INF_GETTING_FILE: - break; - case INF_ERROR_PAGE: - emit errorPage(); - break; - case INF_REDIRECTION: - { - KURL url; - stream >> url; - - emit redirection( url ); - } - break; - case INF_MIME_TYPE: - stream >> str1; - - emit mimeType( str1 ); - if (!m_pConnection->suspended()) - m_pConnection->sendnow( CMD_NONE, TQByteArray() ); - break; - case INF_WARNING: - stream >> str1; - - emit warning( str1 ); - break; - case INF_NEED_PASSWD: { - AuthInfo info; - stream >> info; - openPassDlg( info ); - break; - } - case INF_MESSAGEBOX: { - kdDebug(7007) << "needs a msg box" << endl; - TQString text, caption, buttonYes, buttonNo, dontAskAgainName; - int type; - stream >> type >> text >> caption >> buttonYes >> buttonNo; - if (stream.atEnd()) - messageBox(type, text, caption, buttonYes, buttonNo); - else { - stream >> dontAskAgainName; - messageBox(type, text, caption, buttonYes, buttonNo, dontAskAgainName); - } - break; - } - case INF_INFOMESSAGE: { - TQString msg; - stream >> msg; - infoMessage(msg); - break; - } - case INF_META_DATA: { - MetaData meta_data; - stream >> meta_data; - metaData(meta_data); - break; - } - case INF_LOCALURL: { - TQ_INT8 islocal; - KURL url; - stream >> islocal >> url; - emit localURL( url, islocal ); - break; - } - case MSG_NET_REQUEST: { - TQString host; - TQString slaveid; - stream >> host >> slaveid; - requestNetwork(host, slaveid); - break; - } - case MSG_NET_DROP: { - TQString host; - TQString slaveid; - stream >> host >> slaveid; - dropNetwork(host, slaveid); - break; - } - case MSG_NEED_SUBURL_DATA: { - emit needSubURLData(); - break; - } - case MSG_AUTH_KEY: { - bool keep; - TQCString key, group; - stream >> key >> group >> keep; - kdDebug(7007) << "Got auth-key: " << key << endl - << " group-key: " << group << endl - << " keep password: " << keep << endl; - emit authorizationKey( key, group, keep ); - break; - } - case MSG_DEL_AUTH_KEY: { - TQCString key; - stream >> key; - kdDebug(7007) << "Delete auth-key: " << key << endl; - emit delAuthorization( key ); - } - default: - kdWarning(7007) << "Slave sends unknown command (" << _cmd << "), dropping slave" << endl; - return false; - } - return true; -} - -void SlaveInterface::setOffset( TDEIO::filesize_t o) -{ - d->offset = o; -} - -TDEIO::filesize_t SlaveInterface::offset() const { return d->offset; } - -void SlaveInterface::requestNetwork(const TQString &host, const TQString &slaveid) -{ - kdDebug(7007) << "requestNetwork " << host << slaveid << endl; - TQByteArray packedArgs; - TQDataStream stream( packedArgs, IO_WriteOnly ); - stream << true; - m_pConnection->sendnow( INF_NETWORK_STATUS, packedArgs ); -} - -void SlaveInterface::dropNetwork(const TQString &host, const TQString &slaveid) -{ - kdDebug(7007) << "dropNetwork " << host << slaveid << endl; -} - -void SlaveInterface::sendResumeAnswer( bool resume ) -{ - kdDebug(7007) << "SlaveInterface::sendResumeAnswer ok for resuming :" << resume << endl; - m_pConnection->sendnow( resume ? CMD_RESUMEANSWER : CMD_NONE, TQByteArray() ); -} - -void SlaveInterface::openPassDlg( const TQString& prompt, const TQString& user, bool readOnly ) -{ - AuthInfo info; - info.prompt = prompt; - info.username = user; - info.readOnly = readOnly; - openPassDlg( info ); -} - -void SlaveInterface::openPassDlg( const TQString& prompt, const TQString& user, - const TQString& caption, const TQString& comment, - const TQString& label, bool readOnly ) -{ - AuthInfo info; - info.prompt = prompt; - info.username = user; - info.caption = caption; - info.comment = comment; - info.commentLabel = label; - info.readOnly = readOnly; - openPassDlg( info ); -} - -void SlaveInterface::openPassDlg( AuthInfo& info ) -{ - kdDebug(7007) << "SlaveInterface::openPassDlg: " - << "User= " << info.username - << ", Message= " << info.prompt << endl; - bool result = Observer::self()->openPassDlg( info ); - if ( m_pConnection ) - { - TQByteArray data; - TQDataStream stream( data, IO_WriteOnly ); - if ( result ) - { - stream << info; - kdDebug(7007) << "SlaveInterface:::openPassDlg got: " - << "User= " << info.username - << ", Password= [hidden]" << endl; - m_pConnection->sendnow( CMD_USERPASS, data ); - } - else - m_pConnection->sendnow( CMD_NONE, data ); - } -} - -void SlaveInterface::messageBox( int type, const TQString &text, const TQString &_caption, - const TQString &buttonYes, const TQString &buttonNo ) -{ - messageBox( type, text, _caption, buttonYes, buttonNo, TQString::null ); -} - -void SlaveInterface::messageBox( int type, const TQString &text, const TQString &_caption, - const TQString &buttonYes, const TQString &buttonNo, const TQString &dontAskAgainName ) -{ - kdDebug(7007) << "messageBox " << type << " " << text << " - " << _caption << " " << dontAskAgainName << endl; - TQByteArray packedArgs; - TQDataStream stream( packedArgs, IO_WriteOnly ); - - TQString caption( _caption ); - if ( type == TDEIO::SlaveBase::SSLMessageBox ) - caption = TQString::fromUtf8(kapp->dcopClient()->appId()); // hack, see observer.cpp - - emit needProgressId(); - kdDebug(7007) << "SlaveInterface::messageBox m_progressId=" << m_progressId << endl; - TQGuardedPtr<SlaveInterface> me = this; - m_pConnection->suspend(); - int result = Observer::/*self()->*/messageBox( m_progressId, type, text, caption, buttonYes, buttonNo, dontAskAgainName ); - if ( me && m_pConnection ) // Don't do anything if deleted meanwhile - { - m_pConnection->resume(); - kdDebug(7007) << this << " SlaveInterface result=" << result << endl; - stream << result; - m_pConnection->sendnow( CMD_MESSAGEBOXANSWER, packedArgs ); - } -} - -// No longer used. -// Remove in KDE 4.0 -void SlaveInterface::sigpipe_handler(int) -{ - int saved_errno = errno; - // Using kdDebug from a signal handler is not a good idea. -#ifndef NDEBUG - char msg[1000]; - sprintf(msg, "*** SIGPIPE *** (ignored, pid = %ld)\n", (long) getpid()); - write(2, msg, strlen(msg)); -#endif - - // Do nothing. - // dispatch will return false and that will trigger ERR_SLAVE_DIED in slave.cpp - errno = saved_errno; -} - -void SlaveInterface::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -#include "slaveinterface.moc" diff --git a/kio/kio/slaveinterface.h b/kio/kio/slaveinterface.h deleted file mode 100644 index 8ac7b683e..000000000 --- a/kio/kio/slaveinterface.h +++ /dev/null @@ -1,290 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 2000 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kio_slaveinterface_h -#define __kio_slaveinterface_h - -#include <unistd.h> -#include <sys/types.h> - -#include <tqobject.h> - -#include <kurl.h> -#include <kio/global.h> -#include <kio/authinfo.h> -#include <kdatastream.h> - -namespace TDEIO { - -class Connection; -// better there is one ... -class SlaveInterfacePrivate; - - // Definition of enum Command has been moved to global.h - - /** - * Identifiers for KIO informational messages. - */ - enum Info { - INF_TOTAL_SIZE = 10, - INF_PROCESSED_SIZE = 11, - INF_SPEED, - INF_REDIRECTION = 20, - INF_MIME_TYPE = 21, - INF_ERROR_PAGE = 22, - INF_WARNING = 23, - INF_GETTING_FILE, // Deprecated - INF_NEED_PASSWD = 25, - INF_INFOMESSAGE, - INF_META_DATA, - INF_NETWORK_STATUS, - INF_MESSAGEBOX, - INF_LOCALURL - // add new ones here once a release is done, to avoid breaking binary compatibility - }; - - /** - * Identifiers for KIO data messages. - */ - enum Message { - MSG_DATA = 100, - MSG_DATA_REQ, - MSG_ERROR, - MSG_CONNECTED, - MSG_FINISHED, - MSG_STAT_ENTRY, - MSG_LIST_ENTRIES, - MSG_RENAMED, // unused - MSG_RESUME, - MSG_SLAVE_STATUS, - MSG_SLAVE_ACK, - MSG_NET_REQUEST, - MSG_NET_DROP, - MSG_NEED_SUBURL_DATA, - MSG_CANRESUME, - MSG_AUTH_KEY, // deprecated. - MSG_DEL_AUTH_KEY // deprecated. - // add new ones here once a release is done, to avoid breaking binary compatibility - }; - -/** - * There are two classes that specifies the protocol between application - * (TDEIO::Job) and kioslave. SlaveInterface is the class to use on the application - * end, SlaveBase is the one to use on the slave end. - * - * A call to foo() results in a call to slotFoo() on the other end. - */ -class TDEIO_EXPORT SlaveInterface : public TQObject -{ - Q_OBJECT - -public: - SlaveInterface( Connection *connection ); - virtual ~SlaveInterface(); - - void setConnection( Connection* connection ) { m_pConnection = connection; } - Connection *connection() const { return m_pConnection; } - - void setProgressId( int id ) { m_progressId = id; } - int progressId() const { return m_progressId; } - - /** Send our answer to the MSG_RESUME (canResume) request - * (to tell the "put" job whether to resume or not) - */ - void sendResumeAnswer( bool resume ); - - void setOffset( TDEIO::filesize_t offset ); - TDEIO::filesize_t offset() const; - -signals: - /////////// - // Messages sent by the slave - /////////// - - void data( const TQByteArray & ); - void dataReq( ); - void error( int , const TQString & ); - void connected(); - void finished(); - void slaveStatus(pid_t, const TQCString &, const TQString &, bool); - void listEntries( const TDEIO::UDSEntryList& ); - void statEntry( const TDEIO::UDSEntry& ); - void needSubURLData(); - void needProgressId(); - - void canResume( TDEIO::filesize_t ) ; - - /////////// - // Info sent by the slave - ////////// - void metaData( const TDEIO::MetaData & ); - void totalSize( TDEIO::filesize_t ) ; - void processedSize( TDEIO::filesize_t ) ; - void redirection( const KURL& ) ; - void localURL( const KURL&, bool ) ; - - void speed( unsigned long ) ; - void errorPage() ; - void mimeType( const TQString & ) ; - void warning( const TQString & ) ; - void infoMessage( const TQString & ) ; - void connectFinished(); - - /** - * @deprecated. Obsolete as of 3.1. Replaced by kpassword, a kded module. - */ - void authorizationKey( const TQCString&, const TQCString&, bool ); - - /** - * @deprecated. Obsolete as of 3.1. Replaced by kpassword, a kded module. - */ - void delAuthorization( const TQCString& grpkey ); - -protected: - ///////////////// - // Dispatching - //////////////// - - virtual bool dispatch(); - virtual bool dispatch( int _cmd, const TQByteArray &data ); - - /** - * Prompt the user for authrization info (login & password). - * - * Use this function to request authorization info from the - * the end user. For example to open an empty password dialog - * using default values: - * - * \code - * TDEIO::AuthInfo authInfo; - * bool result = openPassDlg( authInfo ); - * if ( result ) - * { - * printf( "Username: %s", result.username.latin1() ); - * printf( "Username: %s", result.username.latin1() ); - * } - * \endcode - * - * You can also pre-set some values like the username before hand - * if it is known as well as the comment and caption to be displayed: - * - * \code - * authInfo.comment= "Enter username and password to access acmeone"; - * authInfo.caption= "Acme Password Dialog"; - * authInfo.username= "Wily E. kaiody"; - * bool result = openPassDlg( authInfo ); - * if ( result ) - * { - * printf( "Username: %s", result.username.latin1() ); - * printf( "Username: %s", result.username.latin1() ); - * } - * \endcode - * - * NOTE: A call to this function can also fail and result - * in a return value of @p false, if the UIServer could not - * be started for whatever reason. - * - * @param info See AuthInfo. - * @return true if user clicks on "OK", false otherwsie. - */ - void openPassDlg( TDEIO::AuthInfo& info ); - - /** - * @deprecated. Use openPassDlg( AuthInfo& ) instead. - */ - void openPassDlg( const TQString& prompt, const TQString& user, - const TQString& caption, const TQString& comment, - const TQString& label, bool readOnly ) KDE_DEPRECATED; - - /** - * @deprecated. Use openPassDlg( AuthInfo& ) instead. - */ - void openPassDlg( const TQString& prompt, const TQString& user, bool readOnly ) KDE_DEPRECATED; - - void messageBox( int type, const TQString &text, const TQString &caption, - const TQString &buttonYes, const TQString &buttonNo ); - - /** - * @since 3.3 - */ - void messageBox( int type, const TQString &text, const TQString &caption, - const TQString &buttonYes, const TQString &buttonNo, const TQString &dontAskAgainName ); - - // I need to identify the slaves - void requestNetwork( const TQString &, const TQString &); - void dropNetwork( const TQString &, const TQString &); - - /** - * @internal - * KDE 4.0: Remove - */ - static void sigpipe_handler(int); - -protected slots: - void calcSpeed(); - -protected: - Connection * m_pConnection; - -private: - int m_progressId; -protected: - virtual void virtual_hook( int id, void* data ); -private: - SlaveInterfacePrivate *d; -}; - -} - -inline TQDataStream &operator >>(TQDataStream &s, TDEIO::UDSAtom &a ) -{ - TQ_INT32 l; - s >> a.m_uds; - - if ( a.m_uds & TDEIO::UDS_LONG ) { - s >> l; - a.m_long = l; - a.m_str = TQString::null; - } else if ( a.m_uds & TDEIO::UDS_STRING ) { - s >> a.m_str; - a.m_long = 0; - } else {} // DIE! - // assert( 0 ); - - return s; -} - -inline TQDataStream &operator <<(TQDataStream &s, const TDEIO::UDSAtom &a ) -{ - s << a.m_uds; - - if ( a.m_uds & TDEIO::UDS_LONG ) - s << (TQ_INT32) a.m_long; - else if ( a.m_uds & TDEIO::UDS_STRING ) - s << a.m_str; - else {} // DIE! - // assert( 0 ); - - return s; -} - -TDEIO_EXPORT TQDataStream &operator <<(TQDataStream &s, const TDEIO::UDSEntry &e ); -TDEIO_EXPORT TQDataStream &operator >>(TQDataStream &s, TDEIO::UDSEntry &e ); - -#endif diff --git a/kio/kio/statusbarprogress.cpp b/kio/kio/statusbarprogress.cpp deleted file mode 100644 index 66517ca03..000000000 --- a/kio/kio/statusbarprogress.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Matej Koss <koss@miesto.sk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqtooltip.h> -#include <tqlayout.h> -#include <tqwidgetstack.h> -#include <tqpushbutton.h> -#include <tqlabel.h> - -#include <kapplication.h> -#include <klocale.h> -#include <kdebug.h> -#include <kprogress.h> - -#include "jobclasses.h" -#include "statusbarprogress.h" - -namespace TDEIO { - -StatusbarProgress::StatusbarProgress( TQWidget* parent, bool button ) - : ProgressBase( parent ) { - - m_bShowButton = button; - - // only clean this dialog - setOnlyClean(true); - // TODO : is this really needed ? - setStopOnClose(false); - - int w = fontMetrics().width( " 999.9 kB/s 00:00:01 " ) + 8; - box = new TQHBoxLayout( this, 0, 0 ); - - m_pButton = new TQPushButton( "X", this ); - box->addWidget( m_pButton ); - stack = new TQWidgetStack( this ); - box->addWidget( stack ); - connect( m_pButton, TQT_SIGNAL( clicked() ), this, TQT_SLOT( slotStop() ) ); - - m_pProgressBar = new KProgress( this ); - m_pProgressBar->setFrameStyle( TQFrame::Box | TQFrame::Raised ); - m_pProgressBar->setLineWidth( 1 ); - m_pProgressBar->setBackgroundMode( TQWidget::PaletteBackground ); - m_pProgressBar->installEventFilter( this ); - m_pProgressBar->setMinimumWidth( w ); - stack->addWidget( m_pProgressBar, 1 ); - - m_pLabel = new TQLabel( "", this ); - m_pLabel->setAlignment( AlignHCenter | AlignVCenter ); - m_pLabel->installEventFilter( this ); - m_pLabel->setMinimumWidth( w ); - stack->addWidget( m_pLabel, 2 ); - setMinimumSize( sizeHint() ); - - mode = None; - setMode(); -} - - -void StatusbarProgress::setJob( TDEIO::Job *job ) -{ - ProgressBase::setJob( job ); - - mode = Progress; - setMode(); -} - - -void StatusbarProgress::setMode() { - switch ( mode ) { - case None: - if ( m_bShowButton ) { - m_pButton->hide(); - } - stack->hide(); - break; - - case Label: - if ( m_bShowButton ) { - m_pButton->show(); - } - stack->show(); - stack->raiseWidget( m_pLabel ); - break; - - case Progress: - if ( m_bShowButton ) { - m_pButton->show(); - } - stack->show(); - stack->raiseWidget( m_pProgressBar ); - break; - } -} - - -void StatusbarProgress::slotClean() { - // we don't want to delete this widget, only clean - m_pProgressBar->setValue( 0 ); - m_pLabel->clear(); - - mode = None; - setMode(); -} - - -void StatusbarProgress::slotTotalSize( TDEIO::Job*, TDEIO::filesize_t size ) { - m_iTotalSize = size; // size is measured in bytes -} - -void StatusbarProgress::slotPercent( TDEIO::Job*, unsigned long percent ) { - m_pProgressBar->setValue( percent ); -} - - -void StatusbarProgress::slotSpeed( TDEIO::Job*, unsigned long speed ) { - if ( speed == 0 ) { // spped is measured in bytes-per-second - m_pLabel->setText( i18n( " Stalled ") ); - } else { - m_pLabel->setText( i18n( " %1/s ").arg( TDEIO::convertSize( speed )) ); - } -} - - -bool StatusbarProgress::eventFilter( TQObject *, TQEvent *ev ) { - if ( ! m_pJob ) { // don't react when there isn't any job doing IO - return true; - } - - if ( ev->type() == TQEvent::MouseButtonPress ) { - TQMouseEvent *e = (TQMouseEvent*)ev; - - if ( e->button() == Qt::LeftButton ) { // toggle view on left mouse button - if ( mode == Label ) { - mode = Progress; - } else if ( mode == Progress ) { - mode = Label; - } - setMode(); - return true; - - } - } - - return false; -} - -void StatusbarProgress::virtual_hook( int id, void* data ) -{ ProgressBase::virtual_hook( id, data ); } - -} /* namespace */ -#include "statusbarprogress.moc" diff --git a/kio/kio/statusbarprogress.h b/kio/kio/statusbarprogress.h deleted file mode 100644 index d1d591fbe..000000000 --- a/kio/kio/statusbarprogress.h +++ /dev/null @@ -1,112 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Matej Koss <koss@miesto.sk> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __statusbarprogress_h__ -#define __statusbarprogress_h__ - -#include "progressbase.h" - -class TQWidgetStack; -class TQBoxLayout; -class TQPushButton; -class TQLabel; -class KProgress; - -namespace TDEIO { - -class Job; - -/** -* This is a special IO progress widget. -* -* Similarly to DefaultProgress, -* it's purpose is to show a progress of the IO operation. -* -* Instead of creating a separate window, this is only a widget that can be -* easily embedded in a statusbar. -* -* Usage of StatusbarProgress is little different. -* This dialog will be a part of some application. -* \code -* // create a dialog -* StatusbarProgress *statusProgress; -* statusProgress = new StatusbarProgress( statusBar() ); -* statusBar()->insertWidget( statusProgress, statusProgress->width() , 0 ); -* ... -* // create job and connect it to the progress -* CopyJob* job = TDEIO::copy(...); -* statusProgress->setJob( job ); -* ... -* \endcode -* -* @short IO progress widget for embedding in a statusbar. -* @author Matej Koss <koss@miesto.sk> -*/ -class TDEIO_EXPORT StatusbarProgress : public ProgressBase { - - Q_OBJECT - -public: - - /** - * Creates a new StatusbarProgress. - * @param parent the parent of this widget - * @param button true to add an abort button. The button will be - * connected to ProgressBase::slotStop() - */ - StatusbarProgress( TQWidget* parent, bool button = true ); - ~StatusbarProgress() {} - - /** - * Sets the job to monitor. - * @param job the job to monitor - */ - void setJob( TDEIO::Job *job ); - -public slots: - virtual void slotClean(); - virtual void slotTotalSize( TDEIO::Job* job, TDEIO::filesize_t size ); - virtual void slotPercent( TDEIO::Job* job, unsigned long percent ); - virtual void slotSpeed( TDEIO::Job* job, unsigned long speed ); - -protected: - KProgress* m_pProgressBar; - TQLabel* m_pLabel; - TQPushButton* m_pButton; - - TDEIO::filesize_t m_iTotalSize; - - enum Mode { None, Label, Progress }; - - uint mode; - bool m_bShowButton; - - void setMode(); - - virtual bool eventFilter( TQObject *, TQEvent * ); - TQBoxLayout *box; - TQWidgetStack *stack; -protected: - virtual void virtual_hook( int id, void* data ); -private: - class StatusbarProgressPrivate* d; -}; - -} /* namespace */ - -#endif // __statusbarprogress_h__ diff --git a/kio/kio/tcpslavebase.cpp b/kio/kio/tcpslavebase.cpp deleted file mode 100644 index 8d3cc49ff..000000000 --- a/kio/kio/tcpslavebase.cpp +++ /dev/null @@ -1,1343 +0,0 @@ -/* - * $Id$ - * - * Copyright (C) 2000 Alex Zepeda <zipzippy@sonic.net - * Copyright (C) 2001-2003 George Staikos <staikos@kde.org> - * Copyright (C) 2001 Dawit Alemayehu <adawit@kde.org> - * - * This file is part of the KDE project - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> - -#include <time.h> -#include <netdb.h> -#include <unistd.h> -#include <errno.h> - -#include <ksocks.h> -#include <kdebug.h> -#include <ksslall.h> -#include <ksslcertdlg.h> -#include <kmessagebox.h> -#ifndef Q_WS_WIN //temporary -#include <kresolver.h> -#endif - -#include <klocale.h> -#include <dcopclient.h> -#include <tqcstring.h> -#include <tqdatastream.h> - -#include <kapplication.h> - -#include <kprotocolmanager.h> -#include <kde_file.h> - -#include "kio/tcpslavebase.h" - -using namespace TDEIO; - -class TCPSlaveBase::TcpSlaveBasePrivate -{ -public: - - TcpSlaveBasePrivate() : rblockSz(256), militantSSL(false), userAborted(false) {} - ~TcpSlaveBasePrivate() {} - - KSSL *kssl; - bool usingTLS; - KSSLCertificateCache *cc; - TQString host; - TQString realHost; - TQString ip; - DCOPClient *dcc; - KSSLPKCS12 *pkcs; - - int status; - int timeout; - int rblockSz; // Size for reading blocks in readLine() - bool block; - bool useSSLTunneling; - bool needSSLHandShake; - bool militantSSL; // If true, we just drop a connection silently - // if SSL certificate check fails in any way. - bool userAborted; - MetaData savedMetaData; -}; - - -TCPSlaveBase::TCPSlaveBase(unsigned short int defaultPort, - const TQCString &protocol, - const TQCString &poolSocket, - const TQCString &appSocket) - :SlaveBase (protocol, poolSocket, appSocket), - m_iSock(-1), - m_iDefaultPort(defaultPort), - m_sServiceName(protocol), - fp(0) -{ - // We have to have two constructors, so don't add anything - // else in here. Put it in doConstructorStuff() instead. - doConstructorStuff(); - m_bIsSSL = false; -} - -TCPSlaveBase::TCPSlaveBase(unsigned short int defaultPort, - const TQCString &protocol, - const TQCString &poolSocket, - const TQCString &appSocket, - bool useSSL) - :SlaveBase (protocol, poolSocket, appSocket), - m_iSock(-1), - m_bIsSSL(useSSL), - m_iDefaultPort(defaultPort), - m_sServiceName(protocol), - fp(0) -{ - doConstructorStuff(); - if (useSSL) - m_bIsSSL = initializeSSL(); -} - -// The constructor procedures go here now. -void TCPSlaveBase::doConstructorStuff() -{ - d = new TcpSlaveBasePrivate; - d->kssl = 0L; - d->ip = ""; - d->cc = 0L; - d->usingTLS = false; - d->dcc = 0L; - d->pkcs = 0L; - d->status = -1; - d->timeout = KProtocolManager::connectTimeout(); - d->block = false; - d->useSSLTunneling = false; -} - -TCPSlaveBase::~TCPSlaveBase() -{ - cleanSSL(); - if (d->usingTLS) delete d->kssl; - if (d->dcc) delete d->dcc; - if (d->pkcs) delete d->pkcs; - delete d; -} - -ssize_t TCPSlaveBase::write(const void *data, ssize_t len) -{ -#ifdef Q_OS_UNIX - if ( (m_bIsSSL || d->usingTLS) && !d->useSSLTunneling ) - { - if ( d->needSSLHandShake ) - (void) doSSLHandShake( true ); - return d->kssl->write(data, len); - } - return KSocks::self()->write(m_iSock, data, len); -#else - return 0; -#endif -} - -ssize_t TCPSlaveBase::read(void *data, ssize_t len) -{ -#ifdef Q_OS_UNIX - if ( (m_bIsSSL || d->usingTLS) && !d->useSSLTunneling ) - { - if ( d->needSSLHandShake ) - (void) doSSLHandShake( true ); - return d->kssl->read(data, len); - } - return KSocks::self()->read(m_iSock, data, len); -#else - return 0; -#endif -} - - -void TCPSlaveBase::setBlockSize(int sz) -{ - if (sz <= 0) - sz = 1; - - d->rblockSz = sz; -} - - -ssize_t TCPSlaveBase::readLine(char *data, ssize_t len) -{ -// Optimization: -// It's small, but it probably results in a gain on very high -// speed connections. I moved 3 if statements out of the while loop -// so that the while loop is as small as possible. (GS) - - // let's not segfault! - if (!data) - return -1; - - char tmpbuf[1024]; // 1kb temporary buffer for peeking - *data = 0; - ssize_t clen = 0; - char *buf = data; - int rc = 0; - -if ((m_bIsSSL || d->usingTLS) && !d->useSSLTunneling) { // SSL CASE - if ( d->needSSLHandShake ) - (void) doSSLHandShake( true ); - - while (clen < len-1) { - rc = d->kssl->pending(); - if (rc > 0) { // Read a chunk - int bytes = rc; - if (bytes > d->rblockSz) - bytes = d->rblockSz; - - rc = d->kssl->peek(tmpbuf, bytes); - if (rc <= 0) { - // FIXME: this doesn't cover rc == 0 case - return -1; - } - - bytes = rc; // in case it contains no \n - for (int i = 0; i < rc; i++) { - if (tmpbuf[i] == '\n') { - bytes = i+1; - break; - } - } - - if (bytes+clen >= len) // don't read too much! - bytes = len - clen - 1; - - rc = d->kssl->read(buf, bytes); - if (rc > 0) { - clen += rc; - buf += (rc-1); - if (*buf++ == '\n') - break; - } else { - // FIXME: different case if rc == 0; - return -1; - } - } else { // Read a byte - rc = d->kssl->read(buf, 1); - if (rc <= 0) { - return -1; - // hm rc = 0 then - // SSL_read says to call SSL_get_error to see if - // this was an error. FIXME - } else { - clen++; - if (*buf++ == '\n') - break; - } - } - } -} else { // NON SSL CASE - while (clen < len-1) { -#ifdef Q_OS_UNIX - rc = KSocks::self()->read(m_iSock, buf, 1); -#else - rc = 0; -#endif - if (rc <= 0) { - // FIXME: this doesn't cover rc == 0 case - return -1; - } else { - clen++; - if (*buf++ == '\n') - break; - } - } -} - - // Both cases fall through to here - *buf = 0; -return clen; -} - -unsigned short int TCPSlaveBase::port(unsigned short int _p) -{ - unsigned short int p = _p; - - if (_p <= 0) - { - p = m_iDefaultPort; - } - - return p; -} - -// This function is simply a wrapper to establish the connection -// to the server. It's a bit more complicated than ::connect -// because we first have to check to see if the user specified -// a port, and if so use it, otherwise we check to see if there -// is a port specified in /etc/services, and if so use that -// otherwise as a last resort use the supplied default port. -bool TCPSlaveBase::connectToHost( const TQString &host, - unsigned int _port, - bool sendError ) -{ -#ifdef Q_OS_UNIX - unsigned short int p; - KExtendedSocket ks; - - d->userAborted = false; - - // - leaving SSL - warn before we even connect - if (metaData("main_frame_request") == "TRUE" && - metaData("ssl_activate_warnings") == "TRUE" && - metaData("ssl_was_in_use") == "TRUE" && - !m_bIsSSL) { - KSSLSettings kss; - if (kss.warnOnLeave()) { - int result = messageBox( i18n("You are about to leave secure " - "mode. Transmissions will no " - "longer be encrypted.\nThis " - "means that a third party could " - "observe your data in transit."), - WarningContinueCancel, - i18n("Security Information"), - i18n("C&ontinue Loading"), TQString::null, - "WarnOnLeaveSSLMode" ); - - // Move this setting into KSSL instead - TDEConfig *config = new TDEConfig("kioslaverc"); - config->setGroup("Notification Messages"); - - if (!config->readBoolEntry("WarnOnLeaveSSLMode", true)) { - config->deleteEntry("WarnOnLeaveSSLMode"); - config->sync(); - kss.setWarnOnLeave(false); - kss.save(); - } - delete config; - - if ( result == KMessageBox::Cancel ) { - d->userAborted = true; - return false; - } - } - } - - d->status = -1; - d->host = host; - d->needSSLHandShake = m_bIsSSL; - p = port(_port); - ks.setAddress(host, p); - if ( d->timeout > -1 ) - ks.setTimeout( d->timeout ); - - if (ks.connect() < 0) - { - d->status = ks.status(); - if ( sendError ) - { - if (d->status == IO_LookupError) - error( ERR_UNKNOWN_HOST, host); - else if ( d->status != -1 ) - error( ERR_COULD_NOT_CONNECT, host); - } - return false; - } - - m_iSock = ks.fd(); - - // store the IP for later - const TDESocketAddress *sa = ks.peerAddress(); - if (sa) - d->ip = sa->nodeName(); - else - d->ip = ""; - - ks.release(); // KExtendedSocket no longer applicable - - if ( d->block != ks.blockingMode() ) - ks.setBlockingMode( d->block ); - - m_iPort=p; - - if (m_bIsSSL && !d->useSSLTunneling) { - if ( !doSSLHandShake( sendError ) ) - return false; - } - else - setMetaData("ssl_in_use", "FALSE"); - - // Since we want to use stdio on the socket, - // we must fdopen it to get a file pointer, - // if it fails, close everything up - if ((fp = KDE_fdopen(m_iSock, "w+")) == 0) { - closeDescriptor(); - return false; - } - - return true; -#else //!Q_OS_UNIX - return false; -#endif //Q_OS_UNIX -} - -void TCPSlaveBase::closeDescriptor() -{ - stopTLS(); - if (fp) { - fclose(fp); - fp=0; - m_iSock=-1; - if (m_bIsSSL) - d->kssl->close(); - } - if (m_iSock != -1) { - close(m_iSock); - m_iSock=-1; - } - d->ip = ""; - d->host = ""; -} - -bool TCPSlaveBase::initializeSSL() -{ - if (m_bIsSSL) { - if (KSSL::doesSSLWork()) { - d->kssl = new KSSL; - return true; - } - } -return false; -} - -void TCPSlaveBase::cleanSSL() -{ - delete d->cc; - - if (m_bIsSSL) { - delete d->kssl; - d->kssl = 0; - } - d->militantSSL = false; -} - -bool TCPSlaveBase::atEnd() -{ - return feof(fp); -} - -int TCPSlaveBase::startTLS() -{ - if (d->usingTLS || d->useSSLTunneling || m_bIsSSL || !KSSL::doesSSLWork()) - return false; - - d->kssl = new KSSL(false); - if (!d->kssl->TLSInit()) { - delete d->kssl; - return -1; - } - - if ( !d->realHost.isEmpty() ) - { - kdDebug(7029) << "Setting real hostname: " << d->realHost << endl; - d->kssl->setPeerHost(d->realHost); - } else { - kdDebug(7029) << "Setting real hostname: " << d->host << endl; - d->kssl->setPeerHost(d->host); - } - - if (hasMetaData("ssl_session_id")) { - KSSLSession *s = KSSLSession::fromString(metaData("ssl_session_id")); - if (s) { - d->kssl->setSession(s); - delete s; - } - } - certificatePrompt(); - - int rc = d->kssl->connect(m_iSock); - if (rc < 0) { - delete d->kssl; - return -2; - } - - setMetaData("ssl_session_id", d->kssl->session()->toString()); - - d->usingTLS = true; - setMetaData("ssl_in_use", "TRUE"); - - if (!d->kssl->reusingSession()) { - rc = verifyCertificate(); - if (rc != 1) { - setMetaData("ssl_in_use", "FALSE"); - d->usingTLS = false; - delete d->kssl; - return -3; - } - } - - d->savedMetaData = mOutgoingMetaData; - return (d->usingTLS ? 1 : 0); -} - - -void TCPSlaveBase::stopTLS() -{ - if (d->usingTLS) { - delete d->kssl; - d->usingTLS = false; - setMetaData("ssl_in_use", "FALSE"); - } -} - - -void TCPSlaveBase::setSSLMetaData() { - if (!(d->usingTLS || d->useSSLTunneling || m_bIsSSL)) - return; - - mOutgoingMetaData = d->savedMetaData; -} - - -bool TCPSlaveBase::canUseTLS() -{ - if (m_bIsSSL || d->needSSLHandShake || !KSSL::doesSSLWork()) - return false; - - KSSLSettings kss; - return kss.tlsv1(); -} - - -void TCPSlaveBase::certificatePrompt() -{ -TQString certname; // the cert to use this session -bool send = false, prompt = false, save = false, forcePrompt = false; -KSSLCertificateHome::KSSLAuthAction aa; - - setMetaData("ssl_using_client_cert", "FALSE"); // we change this if needed - - if (metaData("ssl_no_client_cert") == "TRUE") return; - forcePrompt = (metaData("ssl_force_cert_prompt") == "TRUE"); - - // Delete the old cert since we're certainly done with it now - if (d->pkcs) { - delete d->pkcs; - d->pkcs = NULL; - } - - if (!d->kssl) return; - - // Look for a general certificate - if (!forcePrompt) { - certname = KSSLCertificateHome::getDefaultCertificateName(&aa); - switch(aa) { - case KSSLCertificateHome::AuthSend: - send = true; prompt = false; - break; - case KSSLCertificateHome::AuthDont: - send = false; prompt = false; - certname = TQString::null; - break; - case KSSLCertificateHome::AuthPrompt: - send = false; prompt = true; - break; - default: - break; - } - } - - TQString ourHost; - if (!d->realHost.isEmpty()) { - ourHost = d->realHost; - } else { - ourHost = d->host; - } - - // Look for a certificate on a per-host basis as an override - TQString tmpcn = KSSLCertificateHome::getDefaultCertificateName(ourHost, &aa); - if (aa != KSSLCertificateHome::AuthNone) { // we must override - switch (aa) { - case KSSLCertificateHome::AuthSend: - send = true; - prompt = false; - certname = tmpcn; - break; - case KSSLCertificateHome::AuthDont: - send = false; - prompt = false; - certname = TQString::null; - break; - case KSSLCertificateHome::AuthPrompt: - send = false; - prompt = true; - certname = tmpcn; - break; - default: - break; - } - } - - // Finally, we allow the application to override anything. - if (hasMetaData("ssl_demand_certificate")) { - certname = metaData("ssl_demand_certificate"); - if (!certname.isEmpty()) { - forcePrompt = false; - prompt = false; - send = true; - } - } - - if (certname.isEmpty() && !prompt && !forcePrompt) return; - - // Ok, we're supposed to prompt the user.... - if (prompt || forcePrompt) { - TQStringList certs = KSSLCertificateHome::getCertificateList(); - - for (TQStringList::Iterator it = certs.begin(); it != certs.end(); ++it) { - KSSLPKCS12 *pkcs = KSSLCertificateHome::getCertificateByName(*it); - if (pkcs && (!pkcs->getCertificate() || - !pkcs->getCertificate()->x509V3Extensions().certTypeSSLClient())) { - certs.remove(*it); - } - delete pkcs; - } - - if (certs.isEmpty()) return; // we had nothing else, and prompt failed - - if (!d->dcc) { - d->dcc = new DCOPClient; - d->dcc->attach(); - if (!d->dcc->isApplicationRegistered("kio_uiserver")) { - TDEApplication::startServiceByDesktopPath("kio_uiserver.desktop", - TQStringList() ); - } - } - - TQByteArray data, retval; - TQCString rettype; - TQDataStream arg(data, IO_WriteOnly); - arg << ourHost; - arg << certs; - arg << metaData("window-id").toInt(); - bool rc = d->dcc->call("kio_uiserver", "UIServer", - "showSSLCertDialog(TQString, TQStringList,int)", - data, rettype, retval); - - if (rc && rettype == "KSSLCertDlgRet") { - TQDataStream retStream(retval, IO_ReadOnly); - KSSLCertDlgRet drc; - retStream >> drc; - if (drc.ok) { - send = drc.send; - save = drc.save; - certname = drc.choice; - } - } - } - - // The user may have said to not send the certificate, - // but to save the choice - if (!send) { - if (save) { - KSSLCertificateHome::setDefaultCertificate(certname, ourHost, - false, false); - } - return; - } - - // We're almost committed. If we can read the cert, we'll send it now. - KSSLPKCS12 *pkcs = KSSLCertificateHome::getCertificateByName(certname); - if (!pkcs && KSSLCertificateHome::hasCertificateByName(certname)) { // We need the password - TDEIO::AuthInfo ai; - bool first = true; - do { - ai.prompt = i18n("Enter the certificate password:"); - ai.caption = i18n("SSL Certificate Password"); - ai.url.setProtocol("kssl"); - ai.url.setHost(certname); - ai.username = certname; - ai.keepPassword = true; - - bool showprompt; - if (first) - showprompt = !checkCachedAuthentication(ai); - else - showprompt = true; - if (showprompt) { - if (!openPassDlg(ai, first ? TQString::null : - i18n("Unable to open the certificate. Try a new password?"))) - break; - } - - first = false; - pkcs = KSSLCertificateHome::getCertificateByName(certname, ai.password); - } while (!pkcs); - - } - - // If we could open the certificate, let's send it - if (pkcs) { - if (!d->kssl->setClientCertificate(pkcs)) { - messageBox(Information, i18n("The procedure to set the " - "client certificate for the session " - "failed."), i18n("SSL")); - delete pkcs; // we don't need this anymore - pkcs = 0L; - } else { - kdDebug(7029) << "Client SSL certificate is being used." << endl; - setMetaData("ssl_using_client_cert", "TRUE"); - if (save) { - KSSLCertificateHome::setDefaultCertificate(certname, ourHost, - true, false); - } - } - d->pkcs = pkcs; - } -} - - - -bool TCPSlaveBase::usingTLS() const -{ - return d->usingTLS; -} - -// ### remove this for KDE4 (misses const): -bool TCPSlaveBase::usingTLS() -{ - return d->usingTLS; -} - - -// Returns 0 for failed verification, -1 for rejected cert and 1 for ok -int TCPSlaveBase::verifyCertificate() -{ - int rc = 0; - bool permacache = false; - bool isChild = false; - bool _IPmatchesCN = false; - int result; - bool doAddHost = false; - TQString ourHost; - - if (!d->realHost.isEmpty()) - ourHost = d->realHost; - else ourHost = d->host; - - TQString theurl = TQString(m_sServiceName)+"://"+ourHost+":"+TQString::number(m_iPort); - - if (!hasMetaData("ssl_militant") || metaData("ssl_militant") == "FALSE") - d->militantSSL = false; - else if (metaData("ssl_militant") == "TRUE") - d->militantSSL = true; - - if (!d->cc) d->cc = new KSSLCertificateCache; - - KSSLCertificate& pc = d->kssl->peerInfo().getPeerCertificate(); - - KSSLCertificate::KSSLValidationList ksvl = pc.validateVerbose(KSSLCertificate::SSLServer); - - _IPmatchesCN = d->kssl->peerInfo().certMatchesAddress(); - if (!_IPmatchesCN) { -#ifndef Q_WS_WIN //temporary - KNetwork::KResolverResults res = KNetwork::KResolver::resolve(d->kssl->peerInfo().peerHost(), "80", KNetwork::KResolver::CanonName); - if (!res.isEmpty()) { - TQString old = d->kssl->peerInfo().peerHost(); - d->kssl->peerInfo().setPeerHost(res[0].canonicalName()); - _IPmatchesCN = d->kssl->peerInfo().certMatchesAddress(); - if (!_IPmatchesCN) { - d->kssl->peerInfo().setPeerHost(old); - } - } -#endif - if (!_IPmatchesCN && !d->militantSSL) { // force this if the user wants it - if (d->cc->getHostList(pc).contains(ourHost)) { - _IPmatchesCN = true; - } - } - } - - if (!_IPmatchesCN) { - ksvl << KSSLCertificate::InvalidHost; - } - - KSSLCertificate::KSSLValidation ksv = KSSLCertificate::Ok; - if (!ksvl.isEmpty()) - ksv = ksvl.first(); - - /* Setting the various bits of meta-info that will be needed. */ - setMetaData("ssl_cipher", d->kssl->connectionInfo().getCipher()); - setMetaData("ssl_cipher_desc", - d->kssl->connectionInfo().getCipherDescription()); - setMetaData("ssl_cipher_version", - d->kssl->connectionInfo().getCipherVersion()); - setMetaData("ssl_cipher_used_bits", - TQString::number(d->kssl->connectionInfo().getCipherUsedBits())); - setMetaData("ssl_cipher_bits", - TQString::number(d->kssl->connectionInfo().getCipherBits())); - setMetaData("ssl_peer_ip", d->ip); - if (!d->realHost.isEmpty()) { - setMetaData("ssl_proxied", "true"); - } - - TQString errorStr; - for(KSSLCertificate::KSSLValidationList::ConstIterator it = ksvl.begin(); - it != ksvl.end(); ++it) - { - errorStr += TQString::number(*it)+":"; - } - setMetaData("ssl_cert_errors", errorStr); - setMetaData("ssl_peer_certificate", pc.toString()); - - if (pc.chain().isValid() && pc.chain().depth() > 1) { - TQString theChain; - TQPtrList<KSSLCertificate> chain = pc.chain().getChain(); - chain.setAutoDelete(true); - for (KSSLCertificate *c = chain.first(); c; c = chain.next()) { - theChain += c->toString(); - theChain += "\n"; - } - setMetaData("ssl_peer_chain", theChain); - } else setMetaData("ssl_peer_chain", ""); - - setMetaData("ssl_cert_state", TQString::number(ksv)); - - if (ksv == KSSLCertificate::Ok) { - rc = 1; - setMetaData("ssl_action", "accept"); - } - - kdDebug(7029) << "SSL HTTP frame the parent? " << metaData("main_frame_request") << endl; - if (!hasMetaData("main_frame_request") || metaData("main_frame_request") == "TRUE") { - // Since we're the parent, we need to teach the child. - setMetaData("ssl_parent_ip", d->ip); - setMetaData("ssl_parent_cert", pc.toString()); - // - Read from cache and see if there is a policy for this - KSSLCertificateCache::KSSLCertificatePolicy cp = - d->cc->getPolicyByCertificate(pc); - - // - validation code - if (ksv != KSSLCertificate::Ok) { - if (d->militantSSL) { - return -1; - } - - if (cp == KSSLCertificateCache::Unknown || - cp == KSSLCertificateCache::Ambiguous) { - cp = KSSLCertificateCache::Prompt; - } else { - // A policy was already set so let's honor that. - permacache = d->cc->isPermanent(pc); - } - - if (!_IPmatchesCN && cp == KSSLCertificateCache::Accept) { - cp = KSSLCertificateCache::Prompt; -// ksv = KSSLCertificate::Ok; - } - - // Precondition: cp is one of Reject, Accept or Prompt - switch (cp) { - case KSSLCertificateCache::Accept: - rc = 1; - setMetaData("ssl_action", "accept"); - break; - case KSSLCertificateCache::Reject: - rc = -1; - setMetaData("ssl_action", "reject"); - break; - case KSSLCertificateCache::Prompt: - { - do { - if (ksv == KSSLCertificate::InvalidHost) { - TQString msg = i18n("The IP address of the host %1 " - "does not match the one the " - "certificate was issued to."); - result = messageBox( WarningYesNoCancel, - msg.arg(ourHost), - i18n("Server Authentication"), - i18n("&Details"), - i18n("Co&ntinue") ); - } else { - TQString msg = i18n("The server certificate failed the " - "authenticity test (%1)."); - result = messageBox( WarningYesNoCancel, - msg.arg(ourHost), - i18n("Server Authentication"), - i18n("&Details"), - i18n("Co&ntinue") ); - } - - if (result == KMessageBox::Yes) { - if (!d->dcc) { - d->dcc = new DCOPClient; - d->dcc->attach(); - if (!d->dcc->isApplicationRegistered("kio_uiserver")) { - TDEApplication::startServiceByDesktopPath("kio_uiserver.desktop", - TQStringList() ); - } - - } - TQByteArray data, ignore; - TQCString ignoretype; - TQDataStream arg(data, IO_WriteOnly); - arg << theurl << mOutgoingMetaData; - arg << metaData("window-id").toInt(); - d->dcc->call("kio_uiserver", "UIServer", - "showSSLInfoDialog(TQString,TDEIO::MetaData,int)", - data, ignoretype, ignore); - } - } while (result == KMessageBox::Yes); - - if (result == KMessageBox::No) { - setMetaData("ssl_action", "accept"); - rc = 1; - cp = KSSLCertificateCache::Accept; - doAddHost = true; - result = messageBox( WarningYesNo, - i18n("Would you like to accept this " - "certificate forever without " - "being prompted?"), - i18n("Server Authentication"), - i18n("&Forever"), - i18n("&Current Sessions Only")); - if (result == KMessageBox::Yes) - permacache = true; - else - permacache = false; - } else { - setMetaData("ssl_action", "reject"); - rc = -1; - cp = KSSLCertificateCache::Prompt; - } - break; - } - default: - kdDebug(7029) << "TCPSlaveBase/SSL error in cert code." - << "Please report this to kfm-devel@kde.org." - << endl; - break; - } - } - - - // - cache the results - d->cc->addCertificate(pc, cp, permacache); - if (doAddHost) d->cc->addHost(pc, ourHost); - } else { // Child frame - // - Read from cache and see if there is a policy for this - KSSLCertificateCache::KSSLCertificatePolicy cp = - d->cc->getPolicyByCertificate(pc); - isChild = true; - - // Check the cert and IP to make sure they're the same - // as the parent frame - bool certAndIPTheSame = (d->ip == metaData("ssl_parent_ip") && - pc.toString() == metaData("ssl_parent_cert")); - - if (ksv == KSSLCertificate::Ok) { - if (certAndIPTheSame) { // success - rc = 1; - setMetaData("ssl_action", "accept"); - } else { - /* - if (d->militantSSL) { - return -1; - } - result = messageBox(WarningYesNo, - i18n("The certificate is valid but does not appear to have been assigned to this server. Do you wish to continue loading?"), - i18n("Server Authentication")); - if (result == KMessageBox::Yes) { // success - rc = 1; - setMetaData("ssl_action", "accept"); - } else { // fail - rc = -1; - setMetaData("ssl_action", "reject"); - } - */ - setMetaData("ssl_action", "accept"); - rc = 1; // Let's accept this now. It's bad, but at least the user - // will see potential attacks in KDE3 with the pseudo-lock - // icon on the toolbar, and can investigate with the RMB - } - } else { - if (d->militantSSL) { - return -1; - } - - if (cp == KSSLCertificateCache::Accept) { - if (certAndIPTheSame) { // success - rc = 1; - setMetaData("ssl_action", "accept"); - } else { // fail - result = messageBox(WarningYesNo, - i18n("You have indicated that you wish to accept this certificate, but it is not issued to the server who is presenting it. Do you wish to continue loading?"), - i18n("Server Authentication")); - if (result == KMessageBox::Yes) { - rc = 1; - setMetaData("ssl_action", "accept"); - d->cc->addHost(pc, ourHost); - } else { - rc = -1; - setMetaData("ssl_action", "reject"); - } - } - } else if (cp == KSSLCertificateCache::Reject) { // fail - messageBox(Information, i18n("SSL certificate is being rejected as requested. You can disable this in the TDE Control Center."), - i18n("Server Authentication")); - rc = -1; - setMetaData("ssl_action", "reject"); - } else { - do { - TQString msg = i18n("The server certificate failed the " - "authenticity test (%1)."); - result = messageBox(WarningYesNoCancel, - msg.arg(ourHost), - i18n("Server Authentication"), - i18n("&Details"), - i18n("Co&nnect")); - if (result == KMessageBox::Yes) { - if (!d->dcc) { - d->dcc = new DCOPClient; - d->dcc->attach(); - if (!d->dcc->isApplicationRegistered("kio_uiserver")) { - TDEApplication::startServiceByDesktopPath("kio_uiserver.desktop", - TQStringList() ); - } - } - TQByteArray data, ignore; - TQCString ignoretype; - TQDataStream arg(data, IO_WriteOnly); - arg << theurl << mOutgoingMetaData; - arg << metaData("window-id").toInt(); - d->dcc->call("kio_uiserver", "UIServer", - "showSSLInfoDialog(TQString,TDEIO::MetaData,int)", - data, ignoretype, ignore); - } - } while (result == KMessageBox::Yes); - - if (result == KMessageBox::No) { - setMetaData("ssl_action", "accept"); - rc = 1; - cp = KSSLCertificateCache::Accept; - result = messageBox(WarningYesNo, - i18n("Would you like to accept this " - "certificate forever without " - "being prompted?"), - i18n("Server Authentication"), - i18n("&Forever"), - i18n("&Current Sessions Only")); - permacache = (result == KMessageBox::Yes); - d->cc->addCertificate(pc, cp, permacache); - d->cc->addHost(pc, ourHost); - } else { - setMetaData("ssl_action", "reject"); - rc = -1; - cp = KSSLCertificateCache::Prompt; - d->cc->addCertificate(pc, cp, permacache); - } - } - } - } - - - if (rc == -1) { - return rc; - } - - if (metaData("ssl_activate_warnings") == "TRUE") { - // - entering SSL - if (!isChild && metaData("ssl_was_in_use") == "FALSE" && - d->kssl->settings()->warnOnEnter()) { - int result; - do { - result = messageBox( i18n("You are about to " - "enter secure mode. " - "All transmissions " - "will be encrypted " - "unless otherwise " - "noted.\nThis means " - "that no third party " - "will be able to " - "easily observe your " - "data in transit."), - WarningYesNo, - i18n("Security Information"), - i18n("Display SSL " - "&Information"), - i18n("C&onnect"), - "WarnOnEnterSSLMode" ); - // Move this setting into KSSL instead - TDEConfig *config = new TDEConfig("kioslaverc"); - config->setGroup("Notification Messages"); - - if (!config->readBoolEntry("WarnOnEnterSSLMode", true)) { - config->deleteEntry("WarnOnEnterSSLMode"); - config->sync(); - d->kssl->settings()->setWarnOnEnter(false); - d->kssl->settings()->save(); - } - delete config; - - if ( result == KMessageBox::Yes ) - { - if (!d->dcc) { - d->dcc = new DCOPClient; - d->dcc->attach(); - if (!d->dcc->isApplicationRegistered("kio_uiserver")) { - TDEApplication::startServiceByDesktopPath("kio_uiserver.desktop", - TQStringList() ); - } - } - TQByteArray data, ignore; - TQCString ignoretype; - TQDataStream arg(data, IO_WriteOnly); - arg << theurl << mOutgoingMetaData; - arg << metaData("window-id").toInt(); - d->dcc->call("kio_uiserver", "UIServer", - "showSSLInfoDialog(TQString,TDEIO::MetaData,int)", - data, ignoretype, ignore); - } - } while (result != KMessageBox::No); - } - - } // if ssl_activate_warnings - - - kdDebug(7029) << "SSL connection information follows:" << endl - << "+-----------------------------------------------" << endl - << "| Cipher: " << d->kssl->connectionInfo().getCipher() << endl - << "| Description: " << d->kssl->connectionInfo().getCipherDescription() << endl - << "| Version: " << d->kssl->connectionInfo().getCipherVersion() << endl - << "| Strength: " << d->kssl->connectionInfo().getCipherUsedBits() - << " of " << d->kssl->connectionInfo().getCipherBits() - << " bits used." << endl - << "| PEER:" << endl - << "| Subject: " << d->kssl->peerInfo().getPeerCertificate().getSubject() << endl - << "| Issuer: " << d->kssl->peerInfo().getPeerCertificate().getIssuer() << endl - << "| Validation: " << (int)ksv << endl - << "| Certificate matches IP: " << _IPmatchesCN << endl - << "+-----------------------------------------------" - << endl; - - // sendMetaData(); Do not call this function!! - return rc; -} - - -bool TCPSlaveBase::isConnectionValid() -{ - if ( m_iSock == -1 ) - return false; - - fd_set rdfs; - FD_ZERO(&rdfs); - FD_SET(m_iSock , &rdfs); - - struct timeval tv; - tv.tv_usec = 0; - tv.tv_sec = 0; - int retval; -#ifdef Q_OS_UNIX - do { - retval = KSocks::self()->select(m_iSock+1, &rdfs, NULL, NULL, &tv); - if (wasKilled()) - return false; // Beam us out of here - } while ((retval == -1) && (errno == EAGAIN)); -#else - retval = -1; -#endif - // retval == -1 ==> Error - // retval == 0 ==> Connection Idle - // retval >= 1 ==> Connection Active - //kdDebug(7029) << "TCPSlaveBase::isConnectionValid: select returned: " - // << retval << endl; - - if (retval == -1) - return false; - - if (retval == 0) - return true; - - // Connection is active, check if it has closed. - char buffer[100]; -#ifdef Q_OS_UNIX - do { - retval = KSocks::self()->recv(m_iSock, buffer, 80, MSG_PEEK); - - } while ((retval == -1) && (errno == EAGAIN)); -#else - retval = -1; -#endif - //kdDebug(7029) << "TCPSlaveBase::isConnectionValid: recv returned: " - // << retval << endl; - if (retval <= 0) - return false; // Error or connection closed. - - return true; // Connection still valid. -} - - -bool TCPSlaveBase::waitForResponse( int t ) -{ - fd_set rd; - struct timeval timeout; - - if ( (m_bIsSSL || d->usingTLS) && !d->useSSLTunneling && d->kssl ) - if (d->kssl->pending() > 0) - return true; - - FD_ZERO(&rd); - FD_SET(m_iSock, &rd); - - timeout.tv_usec = 0; - timeout.tv_sec = t; - time_t startTime; - - int rc; - int n = t; - -reSelect: - startTime = time(NULL); -#ifdef Q_OS_UNIX - rc = KSocks::self()->select(m_iSock+1, &rd, NULL, NULL, &timeout); -#else - rc = -1; -#endif - if (wasKilled()) - return false; // We're dead. - - if (rc == -1) - return false; - - if (FD_ISSET(m_iSock, &rd)) - return true; - - // Well it returned but it wasn't set. Let's see if it - // returned too early (perhaps from an errant signal) and - // start over with the remaining time - int timeDone = time(NULL) - startTime; - if (timeDone < n) - { - n -= timeDone; - timeout.tv_sec = n; - goto reSelect; - } - - return false; // Timed out! -} - -int TCPSlaveBase::connectResult() -{ - return d->status; -} - -void TCPSlaveBase::setBlockConnection( bool b ) -{ - d->block = b; -} - -void TCPSlaveBase::setConnectTimeout( int t ) -{ - d->timeout = t; -} - -bool TCPSlaveBase::isSSLTunnelEnabled() -{ - return d->useSSLTunneling; -} - -void TCPSlaveBase::setEnableSSLTunnel( bool enable ) -{ - d->useSSLTunneling = enable; -} - -void TCPSlaveBase::setRealHost( const TQString& realHost ) -{ - d->realHost = realHost; -} - -bool TCPSlaveBase::doSSLHandShake( bool sendError ) -{ - kdDebug(7029) << "TCPSlaveBase::doSSLHandShake: " << endl; - TQString msgHost = d->host; - - d->kssl->reInitialize(); - - if (hasMetaData("ssl_session_id")) { - KSSLSession *s = KSSLSession::fromString(metaData("ssl_session_id")); - if (s) { - d->kssl->setSession(s); - delete s; - } - } - certificatePrompt(); - - if ( !d->realHost.isEmpty() ) - { - msgHost = d->realHost; - } - - kdDebug(7029) << "Setting real hostname: " << msgHost << endl; - d->kssl->setPeerHost(msgHost); - - d->status = d->kssl->connect(m_iSock); - if (d->status < 0) - { - closeDescriptor(); - if ( sendError ) - error( ERR_COULD_NOT_CONNECT, msgHost); - return false; - } - - setMetaData("ssl_session_id", d->kssl->session()->toString()); - setMetaData("ssl_in_use", "TRUE"); - - if (!d->kssl->reusingSession()) { - int rc = verifyCertificate(); - if ( rc != 1 ) { - d->status = -1; - closeDescriptor(); - if ( sendError ) - error( ERR_COULD_NOT_CONNECT, msgHost); - return false; - } - } - - d->needSSLHandShake = false; - - d->savedMetaData = mOutgoingMetaData; - return true; -} - - -bool TCPSlaveBase::userAborted() const -{ - return d->userAborted; -} - -void TCPSlaveBase::virtual_hook( int id, void* data ) -{ SlaveBase::virtual_hook( id, data ); } - diff --git a/kio/kio/tcpslavebase.h b/kio/kio/tcpslavebase.h deleted file mode 100644 index 52081c807..000000000 --- a/kio/kio/tcpslavebase.h +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (C) 2000 Alex Zepeda <zipzippy@sonic.net> - * Copyright (C) 2001 George Staikos <staikos@kde.org> - * Copyright (C) 2001 Dawit Alemayehu <adawit@kde.org> - * - * This file is part of the KDE project - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _TCP_SLAVEBASE_H -#define _TCP_SLAVEBASE_H - -#include <sys/types.h> -#include <stdio.h> - -#include <kextsock.h> -#include <kio/slavebase.h> - - -namespace TDEIO { - -/** - * There are two classes that specifies the protocol between application (job) - * and kioslave. SlaveInterface is the class to use on the application end, - * SlaveBase is the one to use on the slave end. - * - * Slave implementations should simply inherit SlaveBase - * - * A call to foo() results in a call to slotFoo() on the other end. - */ -class TDEIO_EXPORT TCPSlaveBase : public SlaveBase -{ -public: - TCPSlaveBase(unsigned short int defaultPort, const TQCString &protocol, - const TQCString &poolSocket, const TQCString &appSocket); - - TCPSlaveBase(unsigned short int defaultPort, const TQCString &protocol, - const TQCString &poolSocket, const TQCString &appSocket, - bool useSSL); - - virtual ~TCPSlaveBase(); - -protected: - -#ifndef KDE_NO_COMPAT - /** - * @deprecated Due to inconsistency with KDE naming convention. - */ - KDE_DEPRECATED ssize_t Write(const void *data, ssize_t len) { return write( data, len ); } - - /** - * @deprecated Due to inconsistency with KDE naming convention. - */ - KDE_DEPRECATED ssize_t Read(void *data, ssize_t len) { return read( data, len ); } - - /** - * @deprecated Due to inconsistency with KDE naming convention. - */ - KDE_DEPRECATED ssize_t ReadLine(char *data, ssize_t len) { return readLine( data, len ); } - - /** - * @deprecated Due to inconsistency with KDE naming convention. - */ - KDE_DEPRECATED unsigned short int GetPort(unsigned short int p) { return port(p); } - - /** - * @deprecated Due to inconsistency with KDE naming convention. - */ - KDE_DEPRECATED bool ConnectToHost( const TQString &host, unsigned int port, - bool sendError ) { return connectToHost( host, port, sendError ); } - - /** - * @deprecated Due to inconsistency with KDE naming convention. - */ - KDE_DEPRECATED void CloseDescriptor() { closeDescriptor(); } - - /** - * @deprecated Due to inconsistency with KDE naming convention. - */ - KDE_DEPRECATED bool AtEOF() { return atEnd(); } - - /** - * @deprecated Due to inconsistency with KDE naming convention. - */ - KDE_DEPRECATED bool InitializeSSL() { return initializeSSL(); } - - /** - * @deprecated Due to inconsistency with KDE naming convention. - */ - KDE_DEPRECATED void CleanSSL() { cleanSSL(); } -#endif - - /** - * This function acts like standard write function call - * except it is also capable of making SSL or SOCKS - * connections. - * - * @param data info to be sent to remote machine - * @param len the length of the data to be sent - * - * @return the actual size of the data that was sent - */ - ssize_t write(const void *data, ssize_t len); - - /** - * This function acts like standard read function call - * except it is also capable of deciphering SSL data as - * well as handling data over SOCKSified connections. - * - * @param data storage for the info read from server - * @param len length of the info to read from the server - * - * @return the actual size of data that was obtained - */ - ssize_t read(void *data, ssize_t len); - - /** - * Same as above except it reads data one line at a time. - */ - ssize_t readLine(char *data, ssize_t len); - - /** - * Sets the maximum size of blocks read in during calls to readLine(). - * This allows a slave to optimize for the protocol which it implements. - * Ideally this should be (common_line_length+1) or so. - * Making this too large will have adverse effects on performance. - * Initial/default value is 256(bytes) - */ - void setBlockSize(int sz); - - /** - * Determines the appropriate port to use. - * - * This functions attempts to discover the appropriate port. - * - * @param _port the port to try, if it works, it is returned - * @return the default port if the given port doesn't work - */ - unsigned short int port(unsigned short int _port); - - /** - * Performs the initial TCP connection stuff and/or - * SSL handshaking as necessary. - * - * Please note that unlike its deprecated counterpart, this - * function allows you to disable any error message from being - * sent back to the calling application! You can then use the - * connectResult() function to determine the result of the - * request for connection. - * - * @param host hostname - * @param port port number to connect to - * @param sendError if true sends error message to calling app. - * - * @return on succes, true is returned. - * on failure, false is returned and an appropriate - * error message is send to the application. - */ - bool connectToHost( const TQString &host, unsigned int port, - bool sendError = true ); - - /** - * Are we using SSL? - * - * @return if so, true is returned. - * if not, true isn't returned. - * @since 3.2 - */ - bool usingSSL() const { return m_bIsSSL; } - - /** - * Are we using TLS? - * - * @return if so, true is returned. - * if not, true isn't returned. - * @since 3.2 - */ - bool usingTLS() const; - - /** - * @obsolete kept for binary compatibility - * Are we using TLS? - * - * @return if so, true is returned. - * if not, true isn't returned. - */ - bool usingTLS(); - - /** - * Can we use TLS? - * - * @return if so, true is returned. - * if not, true isn't returned. - */ - bool canUseTLS(); - - /** - * Start using TLS on the connection. - * - * @return on success, 1 is returned. - * on failure, 0 is returned. - * on TLS init failure, -1 is returned. - * on connect failure, -2 is returned. - * on certificate failure, -3 is returned. - */ - int startTLS(); - - /** - * Stop using TLS on the connection. - */ - void stopTLS(); - - /** - * Closes the current file descriptor. - * - * Call this function to properly close up the socket - * since it also takes care to prroperly close the stdio - * fstream stuff, as well as sets the socket back to -1 - */ - void closeDescriptor(); - - - /** - * Returns true when end of data is reached - */ - bool atEnd(); - - - /** - * Call this if you use persistent connections and want all the - * metadata restored. This is particularly important for SSL - * sessions since the app needs to know the state of connection, - * certificates, etc. - */ - void setSSLMetaData(); - - - /** - * Initializs all SSL variables - */ - bool initializeSSL(); - - - /** - * Cleans up all SSL settings. - */ - void cleanSSL(); - - /** - * Determines whether or not we are still connected - * to the remote machine. - * - * This method may fail to detect a closed SSL connection. - * - * return @p true if the socket is still active or - * false otherwise. - */ - bool isConnectionValid(); - - /** - * Returns the status of the connection. - * - * This function allows you to invoke ConnectToHost - * with the @p sendError flag set to false so that you - * can send the appropriate error message back to the - * calling io-slave. - * - * @return the status code as returned by KExtendedSocket. - */ - int connectResult(); - - /** - * Wait for some type of activity on the socket - * for the period specified by @p t. - * - * @param t length of time in seconds that we should monitor the - * socket before timing out. - * - * @return true if any activity was seen on the socket before the - * timeout value was reached, false otherwise. - */ - bool waitForResponse( int t ); - - /** - * Sets the mode of the connection to blocking or non-blocking. - * - * Be sure to call this function before calling connectToHost. - * Otherwise, this setting will not have any effect until the next - * @p connectToHost. - * - * @param b true to make the connection a blocking one, false otherwise. - */ - void setBlockConnection( bool b ); - - /** - * Sets how long to wait for orignally connecting to - * the requested before timinig out. - * - * Be sure to call this function before calling ConnectToHost, - * otherwise the setting will not take effect until the next call - * to @p ConnectToHost. - * - * @param t timeout value - */ - void setConnectTimeout( int t ); - - /** - * Returns true if SSL tunneling is enabled. - * - * @see setEnableSSlTunnel - */ - bool isSSLTunnelEnabled(); - - /** - * Set up SSL tunneling mode. - * - * Calling this function with a @p true argument will allow - * you to temprarly ignore the @p m_bIsSSL flag setting and - * make a non-SSL connection. It is mostly useful for making - * connections to SSL sites through a non-transparent proxy - * server (i.e. most proxy servers out there). - * - * Note that once you have successfully "tunneled" through the - * proxy server you must call this function with its argument - * set to false to properly connect to the SSL site. - * - * @param enable if true SSL Tunneling will be enabled - */ - void setEnableSSLTunnel( bool enable ); - - /** - * Sets up the the real hostname for an SSL connection - * that goes through a proxy server. - * - * This function is essential in making sure that the - * real hostname is used for validating certificates from - * SSL sites! - * - * @param realHost the actual host name we are connecting to - */ - void setRealHost( const TQString& realHost ); - - // don't use me! - void doConstructorStuff(); - - // For the certificate verification code - int verifyCertificate(); - - // For prompting for the certificate to use - void certificatePrompt(); - - // Did the user abort (as the reason for connectToHost returning false) - bool userAborted() const; - -protected: - int m_iSock; - bool m_bIsSSL; - unsigned short int m_iPort; - unsigned short int m_iDefaultPort; - TQCString m_sServiceName; - FILE *fp; - -private: - bool doSSLHandShake( bool sendError ); - -protected: - virtual void virtual_hook( int id, void* data ); -private: - class TcpSlaveBasePrivate; - TcpSlaveBasePrivate *d; -}; - -} - -#endif diff --git a/kio/kio/tdelficon.cpp b/kio/kio/tdelficon.cpp deleted file mode 100644 index 49ceffd24..000000000 --- a/kio/kio/tdelficon.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "tdelficon.h" - -#include <cstring> - -/* - * Obtain an existing icon resource list - */ -int get_iconlist(libr_file *file_handle, iconlist *icons) -{ - if(icons == NULL) - { - /* Need to be able to return SOMETHING */ - return false; - } - /* Obtain the icon resource list */ - icons->buffer = libr_malloc(file_handle, ICON_SECTION, &(icons->size)); - if(icons->buffer == NULL) - return false; - return true; -} - -/* - * Get the next entry in an icon resource list - */ -iconentry *get_nexticon(iconlist *icons, iconentry *last_entry) -{ - size_t i; - - /* The icon list is needed both for the data buffer and for a call-specific iconentry instance */ - if(icons == NULL) - return NULL; - /* If this is the first call (last_entry == NULL) then return the first entry */ - if(last_entry == NULL) - icons->entry.offset = sizeof(uint32_t)+sizeof(UUID); - else - icons->entry.offset += icons->entry.entry_size; - /* Check to see if we've run out of entries */ - if(icons->entry.offset >= icons->size) - return NULL; - i = icons->entry.offset; - memcpy(&(icons->entry.entry_size), &(icons->buffer[i]), sizeof(uint32_t)); - i += sizeof(uint32_t); - icons->entry.type = (libr_icontype_t)icons->buffer[i]; - i += sizeof(unsigned char); - switch(icons->entry.type) - { - case LIBR_SVG: - icons->entry.icon_size = 0; - icons->entry.name = &(icons->buffer[i]); - break; - case LIBR_PNG: - memcpy(&(icons->entry.icon_size), &(icons->buffer[i]), sizeof(uint32_t)); - i += sizeof(uint32_t); - icons->entry.name = &(icons->buffer[i]); - break; - default: - /* Invalid entry type */ - return NULL; - } - return &(icons->entry); -} - -TQString elf_get_resource(libr_file *handle, char *section_name) -{ - size_t buffer_size = 0; - char *buffer = NULL; - TQString result; - - /* Get the resource from the ELF binary */ - if(!libr_size(handle, section_name, &buffer_size)) - { -// kdWarning() << "failed to obtain ELF resource size: " << libr_errmsg() << endl; - return result; - } - /* Get the resource from the ELF file */ - buffer = (char *) malloc(buffer_size+1); - buffer[buffer_size] = 0; - if(!libr_read(handle, section_name, buffer)) - { -// kdWarning() << "failed to obtain ELF resource: " << libr_errmsg() << endl; - goto fail; - } - result = buffer; - -fail: - free(buffer); - - return result; -} diff --git a/kio/kio/tdelficon.h b/kio/kio/tdelficon.h deleted file mode 100644 index 7a962bdaa..000000000 --- a/kio/kio/tdelficon.h +++ /dev/null @@ -1,54 +0,0 @@ -#include <alloca.h> -#include <stdint.h> -#include <cstdlib> - -#include <tqdict.h> -#include <tqvalidator.h> -#include <tqcstring.h> -#include <tqfile.h> -#include <tqdatetime.h> - -extern "C" { - #include <libr-icons.h> - - // BEGIN HACK - // libr does not export these structures and defines, - // but we need access to them to make the UI behave sanely - // Keep them in sync with libr and all should be OK - - // Valid for libr version 0.6.0 - // See libr detection code in ConfigureChecks.cmake - - typedef uint32_t ID8; - typedef uint16_t ID4; - typedef struct {uint64_t p:48;} __attribute__((__packed__)) ID12; - - typedef struct { - ID8 g1; - ID4 g2; - ID4 g3; - ID4 g4; - ID12 g5; - } __attribute__((__packed__)) UUID; - - typedef struct { - char *name; - size_t offset; - size_t entry_size; - libr_icontype_t type; - unsigned int icon_size; - } iconentry; - - typedef struct{ - size_t size; - char *buffer; - iconentry entry; - } iconlist; - - #define ICON_SECTION ".icon" - // END HACK -} - -int get_iconlist(libr_file *file_handle, iconlist *icons); -iconentry *get_nexticon(iconlist *icons, iconentry *last_entry); -TQString elf_get_resource(libr_file *handle, char *section_name);
\ No newline at end of file diff --git a/kio/kio/thumbcreator.h b/kio/kio/thumbcreator.h deleted file mode 100644 index 79d499e7f..000000000 --- a/kio/kio/thumbcreator.h +++ /dev/null @@ -1,124 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Malte Starostik <malte@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef _THUMBCREATOR_H_ -#define _THUMBCREATOR_H_ - -#include <tqstring.h> - -class TQString; -class TQImage; -/** - * This is the baseclass for "thumbnail-plugins" in KDE. Using the class - * TDEIO::PreviewJob allows you to generate small images (thumbnails) - * for any kind of file, where a "ThumbCreator" is available. Have a look - * at tdebase/kioslave/thumbnail/ for existing ThumbCreators. - * - * What you need to do to create and register a ThumbCreator: - * @li Inherit from this class and reimplement the create() method to - * generate a thumbnail for the given file-path. - * @li Provide a factory method in your implementation file to instantiate - * your plugin, e.g.: - * \code - * extern "C" - * { - * ThumbCreator *new_creator() - * { - * return new YourThumbCreator(); - * } - * }; - * \endcode - * - * Compile your ThumbCreator as a module. The contents of Makefile.am - * need to look like this: - * \code - * INCLUDES = $(all_includes) - * kde_module_LTLIBRARIES = yourthumbcreator.la - * yourthumbcreator_la_SOURCES = yourthumbcreator.cpp - * yourthumbcreator_la_LIBADD = $(LIB_KIO) - * yourthumbcreator_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) - * kde_services_DATA = yourthumbcreator.desktop - * \endcode - * - * @li Create a file yourthumbcreator.desktop with the following contents: - * \code - * [Desktop Entry] - * Encoding=UTF-8 - * Type=Service - * Name=Name of the type of files your ThumbCreator supports - * ServiceTypes=ThumbCreator - * MimeTypes=application/x-somemimetype - * CacheThumbnail=true - * X-TDE-Library=yourthumbcreator - * \endcode - * - * You can supply a comma-separated list of mimetypes to the MimeTypes entry, - * naming all mimetypes your ThumbCreator supports. You can also use simple - * wildcards, like (where you see [slash], put a /) - * \code - * text[slash]* or image[slash]*. - * \endcode - * - * If your plugin is rather inexpensive (e.g. like the text preview ThumbCreator), - * you can set CacheThumbnail=false to prevent your thumbnails from being cached - * on disk. - * - * @short Baseclass for thumbnail-generating plugins. - */ -class ThumbCreator -{ -public: - /** - * The flags of this plugin. - * @see flags() - */ - enum Flags { None = 0, DrawFrame = 1, BlendIcon = 2 }; - virtual ~ThumbCreator() {} - - /** - * Creates a thumbnail - * Note that the width and height parameters should not be used - * for scaling. Only plugins that create an image "from scratch", - * like the TextCreator should directly use the specified size. - * If the resulting preview is larger than width x height, it will be - * scaled down. - * - * @param path the (always local) file path to create a preview for - * @param width maximum width for the preview - * @param height maximum height for the preview - * @param img this image will contain the preview on success - * - * @return true if preview generation succeeded - */ - virtual bool create(const TQString &path, int width, int height, TQImage &img) = 0; - - /** - * The flags of this plugin: - * @li None nothing special - * @li DrawFrame a frame should be painted around the preview - * @li BlendIcon the mimetype icon should be blended over the preview - * - * @return flags for this plugin - */ - virtual Flags flags() const { return None; } -}; - -typedef ThumbCreator *(*newCreator)(); - -#endif diff --git a/kio/kio/yacc.c b/kio/kio/yacc.c deleted file mode 100644 index a6fa63428..000000000 --- a/kio/kio/yacc.c +++ /dev/null @@ -1,1522 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.0. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - - 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, 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 Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Written by Richard Stallman by simplifying the original so called - ``semantic'' parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - -/* Substitute the variable and function names. */ -#define yyparse kiotraderparse -#define yylex kiotraderlex -#define yyerror kiotradererror -#define yylval kiotraderlval -#define yychar kiotraderchar -#define yydebug kiotraderdebug -#define yynerrs kiotradernerrs - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - NOT = 258, - EQ = 259, - NEQ = 260, - LEQ = 261, - GEQ = 262, - LE = 263, - GR = 264, - OR = 265, - AND = 266, - TOKEN_IN = 267, - EXIST = 268, - MAX = 269, - MIN = 270, - VAL_BOOL = 271, - VAL_STRING = 272, - VAL_ID = 273, - VAL_NUM = 274, - VAL_FLOAT = 275 - }; -#endif -#define NOT 258 -#define EQ 259 -#define NEQ 260 -#define LEQ 261 -#define GEQ 262 -#define LE 263 -#define GR 264 -#define OR 265 -#define AND 266 -#define TOKEN_IN 267 -#define EXIST 268 -#define MAX 269 -#define MIN 270 -#define VAL_BOOL 271 -#define VAL_STRING 272 -#define VAL_ID 273 -#define VAL_NUM 274 -#define VAL_FLOAT 275 - - - - -/* Copy the first part of user declarations. */ -#line 1 "yacc.y" - -#include <stdlib.h> -#include <stdio.h> -#include "ktraderparse.h" - -void yyerror(const char *s); -int yylex(); -void KTraderParse_initFlex( const char *s ); - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 13 "yacc.y" -typedef union YYSTYPE { - char valb; - int vali; - double vald; - char *name; - void *ptr; -} YYSTYPE; -/* Line 190 of yacc.c. */ -#line 143 "yacc.tab.c" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 213 of yacc.c. */ -#line 155 "yacc.tab.c" - -#if ! defined (yyoverflow) || YYERROR_VERBOSE - -# ifndef YYFREE -# define YYFREE free -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# endif - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# else -# define YYSTACK_ALLOC alloca -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# endif -#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short int yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined (__GNUC__) && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined (__STDC__) || defined (__cplusplus) - typedef signed char yysigned_char; -#else - typedef short int yysigned_char; -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 27 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 55 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 28 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 12 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 36 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 57 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 275 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const unsigned char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 27, 24, 22, 2, 23, 2, 25, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 21, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const unsigned char yyprhs[] = -{ - 0, 0, 3, 4, 6, 8, 12, 14, 18, 20, - 24, 28, 32, 36, 40, 44, 46, 50, 52, 56, - 58, 62, 66, 68, 72, 76, 78, 81, 83, 87, - 90, 92, 94, 96, 98, 100, 103 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yysigned_char yyrhs[] = -{ - 29, 0, -1, -1, 30, -1, 31, -1, 32, 10, - 31, -1, 32, -1, 33, 11, 32, -1, 33, -1, - 34, 4, 34, -1, 34, 5, 34, -1, 34, 7, - 34, -1, 34, 6, 34, -1, 34, 8, 34, -1, - 34, 9, 34, -1, 34, -1, 35, 12, 18, -1, - 35, -1, 36, 21, 36, -1, 36, -1, 36, 22, - 37, -1, 36, 23, 37, -1, 37, -1, 37, 24, - 38, -1, 37, 25, 38, -1, 38, -1, 3, 39, - -1, 39, -1, 26, 31, 27, -1, 13, 18, -1, - 18, -1, 19, -1, 20, -1, 17, -1, 16, -1, - 14, 18, -1, 15, 18, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned char yyrline[] = -{ - 0, 56, 56, 57, 60, 63, 64, 67, 68, 71, - 72, 73, 74, 75, 76, 77, 80, 81, 84, 85, - 88, 89, 90, 93, 94, 95, 98, 99, 102, 103, - 104, 105, 106, 107, 108, 109, 110 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE -/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "NOT", "EQ", "NEQ", "LEQ", "GEQ", "LE", - "GR", "OR", "AND", "TOKEN_IN", "EXIST", "MAX", "MIN", "VAL_BOOL", - "VAL_STRING", "VAL_ID", "VAL_NUM", "VAL_FLOAT", "'~'", "'+'", "'-'", - "'*'", "'/'", "'('", "')'", "$accept", "constraint", "bool", "bool_or", - "bool_and", "bool_compare", "expr_in", "expr_twiddle", "expr", "term", - "factor_non", "factor", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const unsigned short int yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 126, 43, 45, 42, 47, 40, 41 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const unsigned char yyr1[] = -{ - 0, 28, 29, 29, 30, 31, 31, 32, 32, 33, - 33, 33, 33, 33, 33, 33, 34, 34, 35, 35, - 36, 36, 36, 37, 37, 37, 38, 38, 39, 39, - 39, 39, 39, 39, 39, 39, 39 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const unsigned char yyr2[] = -{ - 0, 2, 0, 1, 1, 3, 1, 3, 1, 3, - 3, 3, 3, 3, 3, 1, 3, 1, 3, 1, - 3, 3, 1, 3, 3, 1, 2, 1, 3, 2, - 1, 1, 1, 1, 1, 2, 2 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const unsigned char yydefact[] = -{ - 2, 0, 0, 0, 0, 34, 33, 30, 31, 32, - 0, 0, 3, 4, 6, 8, 15, 17, 19, 22, - 25, 27, 26, 29, 35, 36, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 28, 5, 7, 9, 10, 12, 11, 13, - 14, 16, 18, 20, 21, 23, 24 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yysigned_char yydefgoto[] = -{ - -1, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -17 -static const yysigned_char yypact[] = -{ - -3, 11, 0, 18, 28, -17, -17, -17, -17, -17, - -3, 47, -17, -17, 38, 39, -2, 37, -1, -16, - -17, -17, -17, -17, -17, -17, 24, -17, -3, -3, - -3, -3, -3, -3, -3, -3, 34, -3, -3, -3, - -3, -3, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, 10, -16, -16, -17, -17 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yysigned_char yypgoto[] = -{ - -17, -17, -17, -9, 25, -17, 8, -17, 16, -4, - 4, 54 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const unsigned char yytable[] = -{ - 1, 26, 30, 31, 32, 33, 34, 35, 40, 41, - 2, 3, 4, 5, 6, 7, 8, 9, 23, 43, - 37, 38, 39, 10, 2, 3, 4, 5, 6, 7, - 8, 9, 38, 39, 53, 54, 24, 10, 45, 46, - 47, 48, 49, 50, 55, 56, 25, 27, 28, 36, - 29, 42, 51, 52, 44, 22 -}; - -static const unsigned char yycheck[] = -{ - 3, 10, 4, 5, 6, 7, 8, 9, 24, 25, - 13, 14, 15, 16, 17, 18, 19, 20, 18, 28, - 21, 22, 23, 26, 13, 14, 15, 16, 17, 18, - 19, 20, 22, 23, 38, 39, 18, 26, 30, 31, - 32, 33, 34, 35, 40, 41, 18, 0, 10, 12, - 11, 27, 18, 37, 29, 1 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const unsigned char yystos[] = -{ - 0, 3, 13, 14, 15, 16, 17, 18, 19, 20, - 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 39, 18, 18, 18, 31, 0, 10, 11, - 4, 5, 6, 7, 8, 9, 12, 21, 22, 23, - 24, 25, 27, 31, 32, 34, 34, 34, 34, 34, - 34, 18, 36, 37, 37, 38, 38 -}; - -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ -while (0) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (N) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (0) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_stack_print (short int *bottom, short int *top) -#else -static void -yy_stack_print (bottom, top) - short int *bottom; - short int *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (/* Nothing. */; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_reduce_print (int yyrule) -#else -static void -yy_reduce_print (yyrule) - int yyrule; -#endif -{ - int yyi; - unsigned int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", - yyrule - 1, yylno); - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - register const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - register char *yyd = yydest; - register const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -#endif /* !YYERROR_VERBOSE */ - - - -#if YYDEBUG -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -#else -static void -yysymprint (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - switch (yytype) - { - default: - break; - } - YYFPRINTF (yyoutput, ")"); -} - -#endif /* ! YYDEBUG */ -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM); -# else -int yyparse (); -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The look-ahead symbol. */ -int yychar; - -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM) -# else -int yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - - register int yystate; - register int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short int yyssa[YYINITDEPTH]; - short int *yyss = yyssa; - register short int *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - register YYSTYPE *yyvsp; - - - -#define YYPOPSTACK (yyvsp--, yyssp--) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ - int yylen; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - - yyvsp[0] = yylval; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short int *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - short int *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a look-ahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to look-ahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a look-ahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; - - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - yystate = yyn; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 56 "yacc.y" - { KTraderParse_setParseTree( 0L ); ;} - break; - - case 3: -#line 57 "yacc.y" - { KTraderParse_setParseTree( (yyvsp[0].ptr) ); ;} - break; - - case 4: -#line 60 "yacc.y" - { (yyval.ptr) = (yyvsp[0].ptr); ;} - break; - - case 5: -#line 63 "yacc.y" - { (yyval.ptr) = KTraderParse_newOR( (yyvsp[-2].ptr), (yyvsp[0].ptr) ); ;} - break; - - case 6: -#line 64 "yacc.y" - { (yyval.ptr) = (yyvsp[0].ptr); ;} - break; - - case 7: -#line 67 "yacc.y" - { (yyval.ptr) = KTraderParse_newAND( (yyvsp[-2].ptr), (yyvsp[0].ptr) ); ;} - break; - - case 8: -#line 68 "yacc.y" - { (yyval.ptr) = (yyvsp[0].ptr); ;} - break; - - case 9: -#line 71 "yacc.y" - { (yyval.ptr) = KTraderParse_newCMP( (yyvsp[-2].ptr), (yyvsp[0].ptr), 1 ); ;} - break; - - case 10: -#line 72 "yacc.y" - { (yyval.ptr) = KTraderParse_newCMP( (yyvsp[-2].ptr), (yyvsp[0].ptr), 2 ); ;} - break; - - case 11: -#line 73 "yacc.y" - { (yyval.ptr) = KTraderParse_newCMP( (yyvsp[-2].ptr), (yyvsp[0].ptr), 3 ); ;} - break; - - case 12: -#line 74 "yacc.y" - { (yyval.ptr) = KTraderParse_newCMP( (yyvsp[-2].ptr), (yyvsp[0].ptr), 4 ); ;} - break; - - case 13: -#line 75 "yacc.y" - { (yyval.ptr) = KTraderParse_newCMP( (yyvsp[-2].ptr), (yyvsp[0].ptr), 5 ); ;} - break; - - case 14: -#line 76 "yacc.y" - { (yyval.ptr) = KTraderParse_newCMP( (yyvsp[-2].ptr), (yyvsp[0].ptr), 6 ); ;} - break; - - case 15: -#line 77 "yacc.y" - { (yyval.ptr) = (yyvsp[0].ptr); ;} - break; - - case 16: -#line 80 "yacc.y" - { (yyval.ptr) = KTraderParse_newIN( (yyvsp[-2].ptr), KTraderParse_newID( (yyvsp[0].name) ) ); ;} - break; - - case 17: -#line 81 "yacc.y" - { (yyval.ptr) = (yyvsp[0].ptr); ;} - break; - - case 18: -#line 84 "yacc.y" - { (yyval.ptr) = KTraderParse_newMATCH( (yyvsp[-2].ptr), (yyvsp[0].ptr) ); ;} - break; - - case 19: -#line 85 "yacc.y" - { (yyval.ptr) = (yyvsp[0].ptr); ;} - break; - - case 20: -#line 88 "yacc.y" - { (yyval.ptr) = KTraderParse_newCALC( (yyvsp[-2].ptr), (yyvsp[0].ptr), 1 ); ;} - break; - - case 21: -#line 89 "yacc.y" - { (yyval.ptr) = KTraderParse_newCALC( (yyvsp[-2].ptr), (yyvsp[0].ptr), 2 ); ;} - break; - - case 22: -#line 90 "yacc.y" - { (yyval.ptr) = (yyvsp[0].ptr); ;} - break; - - case 23: -#line 93 "yacc.y" - { (yyval.ptr) = KTraderParse_newCALC( (yyvsp[-2].ptr), (yyvsp[0].ptr), 3 ); ;} - break; - - case 24: -#line 94 "yacc.y" - { (yyval.ptr) = KTraderParse_newCALC( (yyvsp[-2].ptr), (yyvsp[0].ptr), 4 ); ;} - break; - - case 25: -#line 95 "yacc.y" - { (yyval.ptr) = (yyvsp[0].ptr); ;} - break; - - case 26: -#line 98 "yacc.y" - { (yyval.ptr) = KTraderParse_newNOT( (yyvsp[0].ptr) ); ;} - break; - - case 27: -#line 99 "yacc.y" - { (yyval.ptr) = (yyvsp[0].ptr); ;} - break; - - case 28: -#line 102 "yacc.y" - { (yyval.ptr) = KTraderParse_newBRACKETS( (yyvsp[-1].ptr) ); ;} - break; - - case 29: -#line 103 "yacc.y" - { (yyval.ptr) = KTraderParse_newEXIST( (yyvsp[0].name) ); ;} - break; - - case 30: -#line 104 "yacc.y" - { (yyval.ptr) = KTraderParse_newID( (yyvsp[0].name) ); ;} - break; - - case 31: -#line 105 "yacc.y" - { (yyval.ptr) = KTraderParse_newNUM( (yyvsp[0].vali) ); ;} - break; - - case 32: -#line 106 "yacc.y" - { (yyval.ptr) = KTraderParse_newFLOAT( (yyvsp[0].vald) ); ;} - break; - - case 33: -#line 107 "yacc.y" - { (yyval.ptr) = KTraderParse_newSTRING( (yyvsp[0].name) ); ;} - break; - - case 34: -#line 108 "yacc.y" - { (yyval.ptr) = KTraderParse_newBOOL( (yyvsp[0].valb) ); ;} - break; - - case 35: -#line 109 "yacc.y" - { (yyval.ptr) = KTraderParse_newMAX2( (yyvsp[0].name) ); ;} - break; - - case 36: -#line 110 "yacc.y" - { (yyval.ptr) = KTraderParse_newMIN2( (yyvsp[0].name) ); ;} - break; - - - } - -/* Line 1037 of yacc.c. */ -#line 1281 "yacc.tab.c" - - yyvsp -= yylen; - yyssp -= yylen; - - - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (YYPACT_NINF < yyn && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - const char* yyprefix; - char *yymsg; - int yyx; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 0; - - yyprefix = ", expecting "; - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); - yycount += 1; - if (yycount == 5) - { - yysize = 0; - break; - } - } - yysize += (sizeof ("syntax error, unexpected ") - + yystrlen (yytname[yytype])); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); - - if (yycount < 5) - { - yyprefix = ", expecting "; - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - yyp = yystpcpy (yyp, yyprefix); - yyp = yystpcpy (yyp, yytname[yyx]); - yyprefix = " or "; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("syntax error; also virtual memory exhausted"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* If at end of input, pop the error token, - then the rest of the stack, then return failure. */ - if (yychar == YYEOF) - for (;;) - { - - YYPOPSTACK; - if (yyssp == yyss) - YYABORT; - yydestruct ("Error: popping", - yystos[*yyssp], yyvsp); - } - } - else - { - yydestruct ("Error: discarding", yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse look-ahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - -#ifdef __GNUC__ - /* Pacify GCC when the user code never invokes YYERROR and the label - yyerrorlab therefore never appears in user code. */ - if (0) - goto yyerrorlab; -#endif - -yyvsp -= yylen; - yyssp -= yylen; - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", yystos[yystate], yyvsp); - YYPOPSTACK; - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yydestruct ("Error: discarding lookahead", - yytoken, &yylval); - yychar = YYEMPTY; - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*----------------------------------------------. -| yyoverflowlab -- parser overflow comes here. | -`----------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - return yyresult; -} - - -#line 115 "yacc.y" - - -void yyerror ( const char *s ) /* Called by yyparse on error */ -{ - KTraderParse_error( s ); -} - -void KTraderParse_mainParse( const char *_code ) -{ - KTraderParse_initFlex( _code ); - yyparse(); -} - diff --git a/kio/kio/yacc.h b/kio/kio/yacc.h deleted file mode 100644 index ca84fb025..000000000 --- a/kio/kio/yacc.h +++ /dev/null @@ -1,93 +0,0 @@ -/* A Bison parser, made by GNU Bison 1.875. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. - - 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, 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. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - NOT = 258, - EQ = 259, - NEQ = 260, - LEQ = 261, - GEQ = 262, - LE = 263, - GR = 264, - OR = 265, - AND = 266, - TOKEN_IN = 267, - EXIST = 268, - MAX = 269, - MIN = 270, - VAL_BOOL = 271, - VAL_STRING = 272, - VAL_ID = 273, - VAL_NUM = 274, - VAL_FLOAT = 275 - }; -#endif -#define NOT 258 -#define EQ 259 -#define NEQ 260 -#define LEQ 261 -#define GEQ 262 -#define LE 263 -#define GR 264 -#define OR 265 -#define AND 266 -#define TOKEN_IN 267 -#define EXIST 268 -#define MAX 269 -#define MIN 270 -#define VAL_BOOL 271 -#define VAL_STRING 272 -#define VAL_ID 273 -#define VAL_NUM 274 -#define VAL_FLOAT 275 - - - - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 13 "yacc.y" -typedef union YYSTYPE { - char valb; - int vali; - double vald; - char *name; - void *ptr; -} YYSTYPE; -/* Line 1240 of yacc.c. */ -#line 84 "yacc.tab.h" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE kiotraderlval; - - - diff --git a/kio/kio/yacc.y b/kio/kio/yacc.y deleted file mode 100644 index 1b86f4737..000000000 --- a/kio/kio/yacc.y +++ /dev/null @@ -1,126 +0,0 @@ -%{ -#include <stdlib.h> -#include <stdio.h> -#include "ktraderparse.h" - -void yyerror(const char *s); -int yylex(); -void KTraderParse_initFlex( const char *s ); - -%} - -%union -{ - char valb; - int vali; - double vald; - char *name; - void *ptr; -} - -%token NOT -%token EQ -%token NEQ -%token LEQ -%token GEQ -%token LE -%token GR -%token OR -%token AND -%token TOKEN_IN -%token EXIST -%token MAX -%token MIN - -%token <valb> VAL_BOOL -%token <name> VAL_STRING -%token <name> VAL_ID -%token <vali> VAL_NUM -%token <vald> VAL_FLOAT - -%type <ptr> bool -%type <ptr> bool_or -%type <ptr> bool_and -%type <ptr> bool_compare -%type <ptr> expr_in -%type <ptr> expr_twiddle -%type <ptr> expr -%type <ptr> term -%type <ptr> factor_non -%type <ptr> factor - -/* Grammar follows */ - -%% - -constraint: /* empty */ { KTraderParse_setParseTree( 0L ); } - | bool { KTraderParse_setParseTree( $<ptr>1 ); } -; - -bool: bool_or { $$ = $<ptr>1; } -; - -bool_or: bool_and OR bool_or { $$ = KTraderParse_newOR( $<ptr>1, $<ptr>3 ); } - | bool_and { $$ = $<ptr>1; } -; - -bool_and: bool_compare AND bool_and { $$ = KTraderParse_newAND( $<ptr>1, $<ptr>3 ); } - | bool_compare { $$ = $<ptr>1; } -; - -bool_compare: expr_in EQ expr_in { $$ = KTraderParse_newCMP( $<ptr>1, $<ptr>3, 1 ); } - | expr_in NEQ expr_in { $$ = KTraderParse_newCMP( $<ptr>1, $<ptr>3, 2 ); } - | expr_in GEQ expr_in { $$ = KTraderParse_newCMP( $<ptr>1, $<ptr>3, 3 ); } - | expr_in LEQ expr_in { $$ = KTraderParse_newCMP( $<ptr>1, $<ptr>3, 4 ); } - | expr_in LE expr_in { $$ = KTraderParse_newCMP( $<ptr>1, $<ptr>3, 5 ); } - | expr_in GR expr_in { $$ = KTraderParse_newCMP( $<ptr>1, $<ptr>3, 6 ); } - | expr_in { $$ = $<ptr>1; } -; - -expr_in: expr_twiddle TOKEN_IN VAL_ID { $$ = KTraderParse_newIN( $<ptr>1, KTraderParse_newID( $<name>3 ) ); } - | expr_twiddle { $$ = $<ptr>1; } -; - -expr_twiddle: expr '~' expr { $$ = KTraderParse_newMATCH( $<ptr>1, $<ptr>3 ); } - | expr { $$ = $<ptr>1; } -; - -expr: expr '+' term { $$ = KTraderParse_newCALC( $<ptr>1, $<ptr>3, 1 ); } - | expr '-' term { $$ = KTraderParse_newCALC( $<ptr>1, $<ptr>3, 2 ); } - | term { $$ = $<ptr>1; } -; - -term: term '*' factor_non { $$ = KTraderParse_newCALC( $<ptr>1, $<ptr>3, 3 ); } - | term '/' factor_non { $$ = KTraderParse_newCALC( $<ptr>1, $<ptr>3, 4 ); } - | factor_non { $$ = $<ptr>1; } -; - -factor_non: NOT factor { $$ = KTraderParse_newNOT( $<ptr>2 ); } - | factor { $$ = $<ptr>1; } -; - -factor: '(' bool_or ')' { $$ = KTraderParse_newBRACKETS( $<ptr>2 ); } - | EXIST VAL_ID { $$ = KTraderParse_newEXIST( $<name>2 ); } - | VAL_ID { $$ = KTraderParse_newID( $<name>1 ); } - | VAL_NUM { $$ = KTraderParse_newNUM( $<vali>1 ); } - | VAL_FLOAT { $$ = KTraderParse_newFLOAT( $<vald>1 ); } - | VAL_STRING { $$ = KTraderParse_newSTRING( $<name>1 ); } - | VAL_BOOL { $$ = KTraderParse_newBOOL( $<valb>1 ); } - | MAX VAL_ID { $$ = KTraderParse_newMAX2( $<name>2 ); } - | MIN VAL_ID { $$ = KTraderParse_newMIN2( $<name>2 ); } -; - -/* End of grammar */ - -%% - -void yyerror ( const char *s ) /* Called by yyparse on error */ -{ - KTraderParse_error( s ); -} - -void KTraderParse_mainParse( const char *_code ) -{ - KTraderParse_initFlex( _code ); - yyparse(); -} |