[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: [LONG PATCH] Fix for bug #56197: enable charset selection for FTP
From: Thiago Macieira <thiago.macieira () kdemail ! net>
Date: 2003-11-24 14:39:17
[Download RAW message or body]
[Attachment #2 (multipart/mixed)]
I have come up with a patch fixing bug #56197, but I think it is too intrusive
to be added to CVS at this time. In any event, I am posting it for review.
Rough edges:
- introduces one new message, but that could be changed to reuse an existing
one
- reloading the site when changing the encoding seems not to work
What I did for kio_ftp has to be done for other T_FILESYSTEM ioslaves as well
(kio_fish, for instance).
I'd also like to recommend this Charset feature for determining encoding in
other situations as well -- kate/kwrite for instance would benefit from it.
--
Thiago Macieira - Registered Linux user #65028
thiagom@mail.com
ICQ UIN: 1967141 PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
["kio.patch" (text/x-diff)]
Index: slavebase.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/kio/slavebase.cpp,v
retrieving revision 1.155
diff -u -3 -p -r1.155 slavebase.cpp
--- slavebase.cpp 14 Nov 2003 20:56:04 -0000 1.155
+++ slavebase.cpp 24 Nov 2003 14:31:24 -0000
@@ -51,6 +51,7 @@
#include <ksocks.h>
#include "slavebase.h"
+#include "kremotefilename.h"
#include "kio/slavebase.h"
#include "kio/connection.h"
@@ -123,6 +124,7 @@ public:
KIO::filesize_t totalSize;
KIO::filesize_t sentListEntries;
DCOPClient *dcopClient;
+ KRemoteFilename *remotefile;
time_t timeout;
QByteArray timeoutData;
};
@@ -223,6 +225,7 @@ SlaveBase::SlaveBase( const QCString &pr
connectSlave(mAppSocket);
d->dcopClient = 0;
+ d->remotefile = 0;
}
SlaveBase::~SlaveBase()
@@ -366,6 +369,13 @@ void SlaveBase::sendMetaData()
mOutgoingMetaData.clear(); // Clear
}
+KRemoteFilename *SlaveBase::remoteEncoding()
+{
+ if (d->remotefile != 0)
+ return d->remotefile;
+
+ return d->remotefile = new KRemoteFilename(metaData("Charset").latin1());
+}
void SlaveBase::data( const QByteArray &data )
{
@@ -964,6 +974,8 @@ void SlaveBase::dispatch( int command, c
case CMD_CONFIG:
stream >> d->configData;
KSocks::setConfig(d->config);
+ delete d->remotefile;
+ d->remotefile = 0;
break;
case CMD_GET:
{
Index: slavebase.h
===================================================================
RCS file: /home/kde/kdelibs/kio/kio/slavebase.h,v
retrieving revision 1.103
diff -u -3 -p -r1.103 slavebase.h
--- slavebase.h 28 Oct 2003 17:04:49 -0000 1.103
+++ slavebase.h 24 Nov 2003 14:31:24 -0000
@@ -26,6 +26,7 @@
#include <kio/authinfo.h>
class DCOPClient;
+class KRemoteFilename;
namespace KIO {
@@ -290,6 +291,15 @@ public:
*/
KConfigBase* config();
+ /**
+ * Returns an object that can translate remote filenames into proper
+ * Unicode forms. This encoding can be set by the user.
+ *
+ * @since 3.2
+ */
+ KRemoteFilename* remoteEncoding();
+
+
///////////
// Commands sent by the job, the slave has to
// override what it wants to implement
--- /dev/null 1969-12-31 21:00:00.000000000 -0300
+++ kremotefilename.h 2003-11-23 13:30:26.000000000 -0200
@@ -0,0 +1,121 @@
+/* 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef KREMOTEFILENAME_H
+#define KREMOTEFILENAME_H
+
+#include <kurl.h>
+#include <qstring.h>
+#include <qcstring.h>
+#include <qtextcodec.h>
+
+class KRemoteFilenamePrivate;
+/**
+ * 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 @ref UDSEntry. The same is true for decoding
+ * URLs to its components.
+ *
+ * Each @ref SlaveBase has one object of this kind, even if it is not necessary.
+ * It can be accessed through @ref SlaveBase::remoteEncoding.
+ *
+ * @short A class for handling remote filenames
+ * @author Thiago Macieira <thiago.macieira@kdemail.net>
+ * @since 3.2
+ */
+class KRemoteFilename
+{
+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 KRemoteFilename(const char *name = 0L);
+
+ /**
+ * Destructor
+ */
+ virtual ~KRemoteFilename();
+
+ /**
+ * Converts the given full pathname or filename to Unicode.
+ * This function is supposed to work for dirnames, filenames
+ * or a full pathname.
+ */
+ QString decode(const QCString& name);
+
+ /**
+ * Converts the given name from Unicode.
+ * This function is supposed to work for dirnames, filenames
+ * or a full pathname.
+ */
+ QCString encode(const QString& name);
+
+ /**
+ * Converts the given URL into its 8-bit components
+ */
+ QCString encode(const KURL& url);
+
+ /**
+ * 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
+ */
+ QCString directory(const KURL& url, bool ignore_trailing_slash = true);
+
+ /**
+ * Converts the given URL into 8-bit form and retrieve the filename.
+ */
+ QCString fileName(const KURL& url);
+
+ /**
+ * Returns the encoding being used.
+ */
+ inline const char *encoding()
+ { return codec->name(); }
+
+ /**
+ * 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:
+ QTextCodec *codec;
+
+ virtual void virtual_hook(int id, void* data);
+
+private:
+ // copy constructor
+ KRemoteFilename(const KRemoteFilename&);
+
+
+ KRemoteFilenamePrivate *d;
+};
+
+#endif
--- /dev/null 1969-12-31 21:00:00.000000000 -0300
+++ kremotefilename.cpp 2003-11-24 00:57:12.000000000 -0200
@@ -0,0 +1,93 @@
+/* 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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <kdebug.h>
+#include <kstringhandler.h>
+#include "kremotefilename.h"
+
+KRemoteFilename::KRemoteFilename(const char *name)
+ : codec(0L), d(0L)
+{
+ setEncoding(name);
+}
+
+KRemoteFilename::~KRemoteFilename()
+{
+ // delete d; // not necessary yet
+}
+
+QString KRemoteFilename::decode(const QCString& name)
+{
+#ifdef CHECK_UTF8
+ if (codec->mibEnum() == 106 && !KStringHandler::isUtf8(name))
+ return QString::fromLatin1(name);
+#endif
+
+ QString result = codec->toUnicode(name);
+ if (codec->fromUnicode(result) != name)
+ // fallback in case of decoding failure
+ return QString::fromLatin1(name);
+
+ return result;
+}
+
+QCString KRemoteFilename::encode(const QString& name)
+{
+ QCString result = codec->fromUnicode(name);
+ if (codec->toUnicode(result) != name)
+ return name.latin1();
+
+ return result;
+}
+
+QCString KRemoteFilename::encode(const KURL& url)
+{
+ return encode(url.path());
+}
+
+QCString KRemoteFilename::directory(const KURL& url, bool ignore_trailing_slash)
+{
+ QString dir = url.directory(true, ignore_trailing_slash);
+
+ return encode(dir);
+}
+
+QCString KRemoteFilename::fileName(const KURL& url)
+{
+ return encode(url.fileName());
+}
+
+void KRemoteFilename::setEncoding(const char *name)
+{
+ // don't delete codecs
+
+ if (name)
+ codec = QTextCodec::codecForName(name);
+
+ if (codec == 0L)
+ codec = QTextCodec::codecForMib(1);
+
+ kdDebug() << k_funcinfo << "setting encoding " << codec->name()
+ << " for name=" << name << endl;
+}
+
+void KRemoteFilename::virtual_hook(int, void*)
+{
+}
["kio_ftp.patch" (text/x-diff)]
Index: ftp.cc
===================================================================
RCS file: /home/kde/kdelibs/kioslave/ftp/ftp.cc,v
retrieving revision 1.192
diff -u -3 -p -r1.192 ftp.cc
--- ftp.cc 24 Nov 2003 08:14:09 -0000 1.192
+++ ftp.cc 24 Nov 2003 14:33:20 -0000
@@ -59,6 +59,7 @@
#include <ksocks.h>
#include <kio/ioslave_defaults.h>
#include <kio/slaveconfig.h>
+#include <kremotefilename.h>
#define FTP_LOGIN QString::fromLatin1("anonymous")
#define FTP_PASSWD QString::fromLatin1("anonymous@")
@@ -1085,7 +1086,7 @@ bool Ftp::ftpOpenCommand( const char *_c
if ( !_path.isEmpty() ) {
tmp += " ";
- tmp += _path.ascii();
+ tmp += remoteEncoding()->encode(_path);
}
if ( !ftpSendCmd( tmp ) || rspbuf[0] != '1' ) {
@@ -1145,7 +1146,7 @@ bool Ftp::ftpCloseCommand()
void Ftp::mkdir( const KURL & url, int permissions )
{
- QString path = url.path();
+ QString path = remoteEncoding()->encode(url);
if (!m_bLoggedOn)
{
openConnection();
@@ -1159,7 +1160,7 @@ void Ftp::mkdir( const KURL & url, int p
assert( m_bLoggedOn );
QCString buf = "mkd ";
- buf += path.latin1();
+ buf += remoteEncoding()->encode(path);
if ( !ftpSendCmd( buf ) || rspbuf[0] != '2' )
{
@@ -1200,7 +1201,7 @@ bool Ftp::ftpRename( const QString & src
// TODO honor overwrite
assert( m_bLoggedOn );
- QCString filepath = src.ascii();
+ QCString filepath = remoteEncoding()->encode(src);
int pos = filepath.findRev("/");
QCString cwd_cmd = "CWD ";
@@ -1210,7 +1211,7 @@ bool Ftp::ftpRename( const QString & src
from_cmd += filepath.mid(pos+1);
QCString to_cmd = "RNTO ";
- to_cmd += dst.ascii();
+ to_cmd += remoteEncoding()->encode(dst);
if ( !ftpSendCmd( cwd_cmd ) || rspbuf[0] != '2')
return false;
@@ -1226,7 +1227,6 @@ bool Ftp::ftpRename( const QString & src
void Ftp::del( const KURL& url, bool isfile )
{
- QString path = url.path();
if (!m_bLoggedOn)
{
openConnection();
@@ -1244,17 +1244,17 @@ void Ftp::del( const KURL& url, bool isf
// When deleting a directory, we must exit from it first
// The last command probably went into it (to stat it)
QCString tmp = "cwd ";
- tmp += url.directory().ascii();
+ tmp += remoteEncoding()->directory(url);
(void) ftpSendCmd( tmp );
// ignore errors
}
QCString cmd = isfile ? "DELE " : "RMD ";
- cmd += path.ascii();
+ cmd += remoteEncoding()->encode(url);
if ( !ftpSendCmd( cmd ) || rspbuf[0] != '2' )
- error( ERR_CANNOT_DELETE, path );
+ error( ERR_CANNOT_DELETE, url.path() );
else
finished();
}
@@ -1271,7 +1271,7 @@ bool Ftp::ftpChmod( const QString & path
sprintf(buf, "%o ", permissions & 511 );
cmd += buf;
- cmd += path.ascii();
+ cmd += remoteEncoding()->encode(path);
return ftpSendCmd( cmd ) && rspbuf[0] == '2';
}
@@ -1463,7 +1463,7 @@ void Ftp::stat( const KURL &url)
// Try cwd into it, if it works it's a dir (and then we'll list the parent \
directory to get more info) // if it doesn't work, it's a file (and then we'll use \
dir filename) QCString tmp = "cwd ";
- tmp += path.latin1();
+ tmp += remoteEncoding()->encode(path);
if ( !ftpSendCmd( tmp ) )
{
kdDebug(7102) << "stat: ftpSendCmd returned false" << endl;
@@ -1536,7 +1536,7 @@ void Ftp::stat( const KURL &url)
// Now cwd the parent dir, to prepare for listing
tmp = "cwd ";
- tmp += parentDir.latin1();
+ tmp += remoteEncoding()->encode(parentDir);
if ( !ftpSendCmd( tmp ) )
// error already emitted
return;
@@ -1721,7 +1721,7 @@ bool Ftp::ftpOpenDir( const QString & pa
// We try to change to this directory first to see whether it really is a \
directory. // (And also to follow symlinks)
QCString tmp = "cwd ";
- tmp += ( !path.isEmpty() ) ? path.latin1() : "/";
+ tmp += ( !path.isEmpty() ) ? remoteEncoding()->encode(path) : "/";
if ( !ftpSendCmd( tmp ) || rspbuf[0] != '2' )
{
@@ -1811,23 +1811,28 @@ FtpEntry* Ftp::ftpParseDir( char* buffer
if ((p_date_3 = strtok(NULL," ")) != 0)
if ((p_name = strtok(NULL,"\r\n")) != 0)
{
- if ( p_access[0] == 'l' )
- {
- tmp = p_name;
- int i = tmp.findRev( QString::fromLatin1(" -> ") );
- if ( i != -1 ) {
- de.link = p_name + i + 4;
- tmp.truncate( i );
- p_name = tmp.ascii();
- }
- else
- de.link = QString::null;
- }
- else
- de.link = QString::null;
- if (strchr(p_name, '/'))
- return 0L; // Don't trick us!
+ {
+ QCString tmp( p_name );
+ if ( p_access[0] == 'l' )
+ {
+ int i = tmp.findRev( " -> " );
+ if ( i != -1 ) {
+ de.link = remoteEncoding()->decode(p_name + i + 4);
+ tmp.truncate( i );
+ }
+ else
+ de.link = QString::null;
+ }
+ else
+ de.link = QString::null;
+
+ if (tmp.find('/') != -1)
+ return 0L; // Don't trick us!
+ // Some sites put more than one space between the date and the name
+ // e.g. ftp://ftp.uni-marburg.de/mirror/
+ de.name = remoteEncoding()->decode(tmp.stripWhiteSpace());
+ }
de.access = 0;
de.type = S_IFREG;
@@ -1880,13 +1885,9 @@ FtpEntry* Ftp::ftpParseDir( char* buffer
// maybe fromLocal8Bit would be better in some cases,
// but what proves that the ftp server is in the same encoding
// than the user ??
- de.owner = QString::fromLatin1(p_owner);
- de.group = QString::fromLatin1(p_group);
+ de.owner = remoteEncoding()->decode(p_owner);
+ de.group = remoteEncoding()->decode(p_group);
de.size = STRTOLL(p_size, 0, 10);
- QCString tmp( p_name );
- // Some sites put more than one space between the date and the \
name
- // e.g. ftp://ftp.uni-marburg.de/mirror/
- de.name = QString::fromLatin1(tmp.stripWhiteSpace());
// Parsing the date is somewhat tricky
// Examples : "Oct 6 22:49", "May 13 1999"
@@ -1991,7 +1992,7 @@ void Ftp::get( const KURL & url )
{
// Not a file, or doesn't exist. We need to find out.
QCString tmp = "cwd ";
- tmp += url.path().latin1();
+ tmp += remoteEncoding()->encode(url);
if ( ftpSendCmd( tmp ) && rspbuf[0] == '2' )
{
// Ok it's a dir in fact
@@ -2198,7 +2199,7 @@ void Ftp::put( const KURL& dest_url, int
{
if ( m_size == 0 ) { // delete files with zero size
QCString cmd = "DELE ";
- cmd += dest_orig.ascii();
+ cmd += remoteEncoding()->encode(dest_orig);
if ( !ftpSendCmd( cmd ) || rspbuf[0] != '2' )
{
error( ERR_CANNOT_DELETE_PARTIAL, dest_orig );
@@ -2220,7 +2221,7 @@ void Ftp::put( const KURL& dest_url, int
} else if ( bMarkPartial && ftpSize( dest_part, 'I' ) ) { // file with extension \
.part exists if ( m_size == 0 ) { // delete files with zero size
QCString cmd = "DELE ";
- cmd += dest_part.ascii();
+ cmd += remoteEncoding()->encode(dest_part);
if ( !ftpSendCmd( cmd ) || rspbuf[0] != '2' )
{
error( ERR_CANNOT_DELETE_PARTIAL, dest_orig );
@@ -2284,7 +2285,7 @@ void Ftp::put( const KURL& dest_url, int
( m_size < (unsigned long) config()->readNumEntry("MinimumKeepSize", \
DEFAULT_MINIMUM_KEEP_SIZE) ) ) {
QCString cmd = "DELE ";
- cmd += dest.ascii();
+ cmd += remoteEncoding()->encode(dest);
(void) ftpSendCmd( cmd );
}
}
@@ -2337,7 +2338,7 @@ bool Ftp::ftpSize( const QString & path,
}
buf="SIZE ";
- buf+=path.ascii();
+ buf+=remoteEncoding()->encode(path);
if ( !ftpSendCmd( buf ) || rspbuf[0] !='2' ) {
m_size = UnknownSize;
return false;
["remoteencodingplugin.patch" (text/x-diff)]
--- /dev/null 1969-12-31 21:00:00.000000000 -0300
+++ remoteencodingplugin/Makefile.am 2003-11-24 00:08:11.000000000 -0200
@@ -0,0 +1,13 @@
+INCLUDES= -I$(top_srcdir)/libkonq $(all_includes)
+METASOURCES=AUTO
+
+kde_module_LTLIBRARIES = konq_remoteencoding.la
+konq_remoteencoding_la_SOURCES = kremoteencodingplugin.cpp
+konq_remoteencoding_la_LIBADD = $(top_builddir)/libkonq/libkonq.la
+konq_remoteencoding_la_LDFLAGS = -module $(KDE_PLUGIN)
+
+iconviewdir = $(kde_datadir)/konqiconview/kpartplugins
+iconview_DATA = kremoteencodingplugin.rc
+
+listviewdir = $(kde_datadir)/konqlistview/kpartplugins
+listview_DATA = kremoteencodingplugin.rc
--- /dev/null 1969-12-31 21:00:00.000000000 -0300
+++ remoteencodingplugin/kremoteencodingplugin.rc 2003-11-23 22:16:01.000000000 -0200
@@ -0,0 +1,8 @@
+<!DOCTYPE kpartplugin>
+<kpartplugin library="konq_remoteencoding">
+<MenuBar>
+ <Menu name="tools"><text>&Tools</text>
+ <Action name="changeremoteencoding"/>
+ </Menu>
+</MenuBar>
+</kpartplugin>
--- /dev/null 1969-12-31 21:00:00.000000000 -0300
+++ remoteencodingplugin/kremoteencodingplugin.h 2003-11-24 11:47:23.000000000 -0200
@@ -0,0 +1,63 @@
+/*
+ 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 (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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef REMOTEENCODING_PLUGIN_H
+#define REMOTEENCODING_PLUGIN_H
+
+#include <qstringlist.h>
+#include <kurl.h>
+#include <klibloader.h>
+#include <kparts/plugin.h>
+
+class KActionMenu;
+class KConfig;
+class KonqDirPart;
+
+class KRemoteEncodingPlugin: public KParts::Plugin
+{
+ Q_OBJECT
+public:
+ KRemoteEncodingPlugin(QObject * parent, const char *name,
+ const QStringList &);
+ ~KRemoteEncodingPlugin();
+
+protected slots:
+ void slotAboutToOpenURL();
+ void slotAboutToShow();
+ void slotItemSelected(int);
+ void slotReload();
+ void slotDefault();
+
+private:
+ void updateBrowser();
+ void loadSettings();
+ void fillMenu();
+ void updateMenu();
+
+ KonqDirPart *m_part;
+ KActionMenu *m_menu;
+ QStringList m_encodingDescriptions;
+ KURL m_currentURL;
+
+ bool m_loaded;
+ int m_idDefault;
+};
+
+#endif
--- /dev/null 1969-12-31 21:00:00.000000000 -0300
+++ remoteencodingplugin/kremoteencodingplugin.cpp 2003-11-24 11:49:49.000000000 -0200
@@ -0,0 +1,251 @@
+/*
+ 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 (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., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <kdebug.h>
+#include <kaction.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kconfig.h>
+#include <kcharsets.h>
+#include <kpopupmenu.h>
+#include <dcopclient.h>
+#include <kgenericfactory.h>
+#include <kprotocolmanager.h>
+#include <kprotocolinfo.h>
+#include <kio/slaveconfig.h>
+#include <konq_dirpart.h>
+#include <kparts/browserextension.h>
+
+#include "kremoteencodingplugin.h"
+
+#define DATA_KEY QString::fromLatin1("Charset")
+
+KRemoteEncodingPlugin::KRemoteEncodingPlugin(QObject * parent,
+ const char *name,
+ const QStringList &)
+ : KParts::Plugin(parent, name), m_loaded(false), m_idDefault(0)
+{
+ m_menu = new KActionMenu(i18n("Select remote charset"), "charset",
+ actionCollection(), "changeremoteencoding");
+ connect(m_menu->popupMenu(), SIGNAL(aboutToShow()),
+ this, SLOT(slotAboutToShow()));
+ m_menu->setEnabled(false);
+ m_menu->setDelayed(false);
+
+ m_part = dynamic_cast<KonqDirPart*>(parent);
+ if (m_part)
+ // if parent is not a KonqDirPart, our menu will never show
+ QObject::connect(m_part, SIGNAL(aboutToOpenURL()),
+ this, SLOT(slotAboutToOpenURL()));
+}
+
+KRemoteEncodingPlugin::~KRemoteEncodingPlugin()
+{
+}
+
+void
+KRemoteEncodingPlugin::slotReload()
+{
+ loadSettings();
+}
+
+void
+KRemoteEncodingPlugin::loadSettings()
+{
+ m_loaded = true;
+
+ m_encodingDescriptions = KGlobal::charsets()->descriptiveEncodingNames();
+
+ fillMenu();
+}
+
+void
+KRemoteEncodingPlugin::slotAboutToOpenURL()
+{
+ KURL oldURL = m_currentURL;
+ m_currentURL = m_part->url();
+
+ if (m_currentURL.protocol() != oldURL.protocol())
+ {
+ // This plugin works on ftp, fish, etc.
+ // everything whose type is T_FILESYSTEM except for local files
+ if (!m_currentURL.isLocalFile() &&
+ KProtocolInfo::outputType(m_currentURL) == KProtocolInfo::T_FILESYSTEM)
+ {
+ m_menu->setEnabled(true);
+ loadSettings();
+ }
+ else
+ m_menu->setEnabled(false);
+
+ return;
+ }
+
+ if (m_currentURL.host() != oldURL.host())
+ updateMenu();
+}
+
+void
+KRemoteEncodingPlugin::fillMenu()
+{
+ KPopupMenu *menu = m_menu->popupMenu();
+ menu->clear();
+
+ QStringList::ConstIterator it;
+ int count = 0;
+ for (it = m_encodingDescriptions.begin(); it != m_encodingDescriptions.end(); ++it)
+ menu->insertItem(*it, this, SLOT(slotItemSelected(int)), 0, ++count);
+ menu->insertSeparator();
+
+ menu->insertItem(i18n("Reload"), this, SLOT(slotReload()), 0, ++count);
+ menu->insertItem(i18n("Default"), this, SLOT(slotDefault()), 0, ++count);
+ m_idDefault = count;
+}
+
+void
+KRemoteEncodingPlugin::updateMenu()
+{
+ if (!m_loaded)
+ loadSettings();
+
+ // uncheck everything
+ for (unsigned i = 0; i < m_menu->popupMenu()->count(); i++)
+ m_menu->popupMenu()->setItemChecked(m_menu->popupMenu()->idAt(i), false);
+
+ QString charset = KIO::SlaveConfig::self()->configData(m_currentURL.protocol(), m_currentURL.host(),
+ DATA_KEY);
+ if (!charset.isEmpty())
+ {
+ int id = 1;
+ QStringList::Iterator it;
+ for (it = m_encodingDescriptions.begin(); it != m_encodingDescriptions.end(); ++it, ++id)
+ if ((*it).find(charset) != -1)
+ break;
+
+ kdDebug() << k_funcinfo << "URL=" << m_currentURL << " charset=" << charset << endl;
+
+ if (it == m_encodingDescriptions.end())
+ kdWarning() << k_funcinfo << "could not find entry for charset=" << charset << endl;
+ else
+ m_menu->popupMenu()->setItemChecked(id, true);
+ }
+ else
+ m_menu->popupMenu()->setItemChecked(m_idDefault, true);
+}
+
+void
+KRemoteEncodingPlugin::slotAboutToShow()
+{
+ if (!m_loaded)
+ loadSettings();
+ updateMenu();
+}
+
+void
+KRemoteEncodingPlugin::slotItemSelected(int id)
+{
+ KConfig config(("kio_" + m_currentURL.protocol() + "rc").latin1());
+ QString host = m_currentURL.host();
+
+ if (!m_menu->popupMenu()->isItemChecked(id))
+ {
+ QString charset = KGlobal::charsets()->encodingForName(m_encodingDescriptions[id - 1]);
+
+ config.setGroup(host);
+ config.writeEntry(DATA_KEY, charset);
+ config.sync();
+
+ // Update the io-slaves...
+ updateBrowser();
+ }
+}
+
+void
+KRemoteEncodingPlugin::slotDefault()
+{
+ // We have no choice but delete all higher domain level
+ // settings here since it affects what will be matched.
+ KConfig config(("kio_" + m_currentURL.protocol() + "rc").latin1());
+
+ QStringList partList = QStringList::split('.', m_currentURL.host(), false);
+ if (!partList.isEmpty())
+ {
+ partList.remove(partList.begin());
+
+ QStringList domains;
+ // Remove the exact name match...
+ domains << m_currentURL.host();
+
+ while (partList.count())
+ {
+ if (partList.count() == 2)
+ if (partList[0].length() <= 2 && partList[1].length() == 2)
+ break;
+
+ if (partList.count() == 1)
+ break;
+
+ domains << partList.join(".");
+ partList.remove(partList.begin());
+ }
+
+ for (QStringList::Iterator it = domains.begin(); it != domains.end();
+ it++)
+ {
+ kdDebug() << k_funcinfo << "Domain to remove: " << *it << endl;
+ if (config.hasGroup(*it))
+ config.deleteGroup(*it);
+ else if (config.hasKey(*it))
+ config.deleteEntry(*it);
+ }
+ }
+ config.sync();
+
+ // Update the io-slaves.
+ updateBrowser();
+}
+
+void
+KRemoteEncodingPlugin::updateBrowser()
+{
+ // Inform running io-slaves about the change...
+ DCOPClient *client = new DCOPClient();
+
+ if (!client->attach())
+ kdDebug() << "Can't connect with DCOP server." << endl;
+
+ QByteArray data;
+ QDataStream stream(data, IO_WriteOnly);
+ stream << QString::null;
+ client->send("*", "KIO::Scheduler", "reparseSlaveConfiguration(QString)",
+ data);
+ delete client;
+
+ // Reload the page with the new charset
+ KParts::URLArgs args = m_part->extension()->urlArgs();
+ args.reload = true;
+ m_part->extension()->setURLArgs(args);
+ m_part->openURL(m_currentURL);
+}
+
+typedef KGenericFactory < KRemoteEncodingPlugin > KRemoteEncodingPluginFactory;
+K_EXPORT_COMPONENT_FACTORY(konq_remoteencoding,
+ KRemoteEncodingPluginFactory("kremoteencodingplugin"))
+#include "kremoteencodingplugin.moc"
[Attachment #8 (application/pgp-signature)]
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic