summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/groupwise/gwprotocol.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/groupwise/gwprotocol.cpp')
-rw-r--r--kopete/protocols/groupwise/gwprotocol.cpp283
1 files changed, 283 insertions, 0 deletions
diff --git a/kopete/protocols/groupwise/gwprotocol.cpp b/kopete/protocols/groupwise/gwprotocol.cpp
new file mode 100644
index 00000000..dcf92a17
--- /dev/null
+++ b/kopete/protocols/groupwise/gwprotocol.cpp
@@ -0,0 +1,283 @@
+/*
+ gwprotocol.cpp - Kopete GroupWise Protocol
+
+ Copyright (c) 2004 SUSE Linux AG http://www.suse.com
+
+ Based on Testbed
+ Copyright (c) 2003 by Will Stephenson <will@stevello.free-online.co.uk>
+ rtfizeTest from nm_rtfize_text, from Gaim src/protocols/novell/nmuser.c
+ Copyright (c) 2004 Novell, Inc. All Rights Reserved
+
+ Kopete (c) 2002-2003 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ *************************************************************************
+*/
+#include <qregexp.h>
+#include <qstringlist.h>
+
+#include <kgenericfactory.h>
+#include <kdebug.h>
+
+#include "kopeteaccountmanager.h"
+#include "kopeteonlinestatusmanager.h"
+#include "kopeteglobal.h"
+
+#include "gwaccount.h"
+#include "gwerror.h"
+#include "gwcontact.h"
+#include "gwprotocol.h"
+#include "ui/gwaddcontactpage.h"
+#include "ui/gweditaccountwidget.h"
+
+typedef KGenericFactory<GroupWiseProtocol> GroupWiseProtocolFactory;
+K_EXPORT_COMPONENT_FACTORY( kopete_groupwise, GroupWiseProtocolFactory( "kopete_groupwise" ) )
+
+GroupWiseProtocol *GroupWiseProtocol::s_protocol = 0L;
+
+GroupWiseProtocol::GroupWiseProtocol( QObject* parent, const char *name, const QStringList &/*args*/ )
+ : Kopete::Protocol( GroupWiseProtocolFactory::instance(), parent, name ),
+/* initialise Kopete::OnlineStatus that should be user selectable in the user interface */
+ groupwiseOffline ( Kopete::OnlineStatus::Offline, 0, this, GroupWise::Offline, QString::null,
+ i18n( "Offline" ), i18n( "O&ffline" ), Kopete::OnlineStatusManager::Offline ),
+ groupwiseAvailable ( Kopete::OnlineStatus::Online, 25, this, GroupWise::Available, QString::null,
+ i18n( "Online" ), i18n( "&Online" ), Kopete::OnlineStatusManager::Online ),
+ groupwiseBusy ( Kopete::OnlineStatus::Away, 18, this, GroupWise::Busy, "contact_busy_overlay",
+ i18n( "Busy" ), i18n( "&Busy" ), Kopete::OnlineStatusManager::Busy, Kopete::OnlineStatusManager::HasAwayMessage ),
+ groupwiseAway ( Kopete::OnlineStatus::Away, 20, this, GroupWise::Away, "contact_away_overlay",
+ i18n( "Away" ), i18n( "&Away" ), Kopete::OnlineStatusManager::Away, Kopete::OnlineStatusManager::HasAwayMessage ),
+ groupwiseAwayIdle ( Kopete::OnlineStatus::Away, 15, this, GroupWise::AwayIdle, "contact_away_overlay",
+ i18n( "Idle" ), "FIXME: Make groupwiseAwayIdle unselectable", Kopete::OnlineStatusManager::Idle,
+ Kopete::OnlineStatusManager::HideFromMenu ),
+ groupwiseAppearOffline( Kopete::OnlineStatus::Invisible, 2, this, 98, "contact_invisible_overlay",
+ i18n( "Appear Offline" ), i18n( "A&ppear Offline" ), Kopete::OnlineStatusManager::Invisible ),
+/* initialise Kopete::OnlineStatus used by the protocol, but that are not user selectable */
+ groupwiseUnknown ( Kopete::OnlineStatus::Unknown, 25, this, GroupWise::Unknown, "status_unknown",
+ i18n( "Unknown" ) ),
+ groupwiseInvalid ( Kopete::OnlineStatus::Unknown, 25, this, GroupWise::Invalid, "status_unknown",
+ i18n( "Invalid Status" ) ),
+ groupwiseConnecting ( Kopete::OnlineStatus::Connecting, 25, this, 99, "groupwise_connecting",
+ i18n( "Connecting" ) ),
+ propGivenName( Kopete::Global::Properties::self()->firstName() ),
+ propLastName( Kopete::Global::Properties::self()->lastName() ),
+ propFullName( Kopete::Global::Properties::self()->fullName() ),
+ propAwayMessage( Kopete::Global::Properties::self()->awayMessage() ),
+ propAutoReply( "groupwiseAutoReply", i18n( "Auto Reply Message" ), QString::null, false, false ),
+ propCN( "groupwiseCommonName", i18n( "Common Name" ), QString::null, true, false ),
+ propPhoneWork( Kopete::Global::Properties::self()->workPhone() ),
+ propPhoneMobile( Kopete::Global::Properties::self()->privateMobilePhone() ),
+ propEmail( Kopete::Global::Properties::self()->emailAddress() )
+{
+ // ^^ That is all member initialiser syntax, not broken indentation!
+ kdDebug( GROUPWISE_DEBUG_GLOBAL ) << k_funcinfo << endl;
+
+ s_protocol = this;
+
+ addAddressBookField( "messaging/groupwise", Kopete::Plugin::MakeIndexField );
+}
+
+GroupWiseProtocol::~GroupWiseProtocol()
+{
+}
+
+Kopete::Contact *GroupWiseProtocol::deserializeContact(
+ Kopete::MetaContact *metaContact, const QMap<QString, QString> &serializedData,
+ const QMap<QString, QString> &/* addressBookData */)
+{
+ QString dn = serializedData[ "DN" ];
+ QString accountId = serializedData[ "accountId" ];
+ QString displayName = serializedData[ "displayName" ];
+ int objectId = serializedData[ "objectId" ].toInt();
+ int parentId = serializedData[ "parentId" ].toInt();
+ int sequence = serializedData[ "sequenceNumber" ].toInt();
+
+ QDict<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts( this );
+
+ Kopete::Account *account = accounts[ accountId ];
+ if ( !account )
+ {
+ kdDebug(GROUPWISE_DEBUG_GLOBAL) << "Account doesn't exist, skipping" << endl;
+ return 0;
+ }
+
+ // FIXME: creating a contact with a userId here
+ return new GroupWiseContact(account, dn, metaContact, objectId, parentId, sequence );
+}
+
+AddContactPage * GroupWiseProtocol::createAddContactWidget( QWidget *parent, Kopete::Account * account )
+{
+ kdDebug( GROUPWISE_DEBUG_GLOBAL ) << "Creating Add Contact Page" << endl;
+ return new GroupWiseAddContactPage( account, parent, "addcontactpage");
+}
+
+KopeteEditAccountWidget * GroupWiseProtocol::createEditAccountWidget( Kopete::Account *account, QWidget *parent )
+{
+ kdDebug(GROUPWISE_DEBUG_GLOBAL) << "Creating Edit Account Page" << endl;
+ return new GroupWiseEditAccountWidget( parent, account );
+}
+
+Kopete::Account *GroupWiseProtocol::createNewAccount( const QString &accountId )
+{
+ return new GroupWiseAccount( this, accountId );
+}
+
+GroupWiseProtocol *GroupWiseProtocol::protocol()
+{
+ return s_protocol;
+}
+
+Kopete::OnlineStatus GroupWiseProtocol::gwStatusToKOS( const int gwInternal )
+{
+ Kopete::OnlineStatus status;
+ switch ( gwInternal )
+ {
+ case GroupWise::Unknown:
+ status = groupwiseUnknown;
+ break;
+ case GroupWise::Offline:
+ status = groupwiseOffline;
+ break;
+ case GroupWise::Available:
+ status = groupwiseAvailable;
+ break;
+ case GroupWise::Busy:
+ status = groupwiseBusy;
+ break;
+ case GroupWise::Away:
+ status = groupwiseAway;
+ break;
+ case GroupWise::AwayIdle:
+ status = groupwiseAwayIdle;
+ break;
+ case GroupWise::Invalid:
+ status = groupwiseInvalid;
+ break;
+ default:
+ status = groupwiseInvalid;
+ kdWarning( GROUPWISE_DEBUG_GLOBAL ) << k_funcinfo << "Got unrecognised status value" << gwInternal << endl;
+ }
+ return status;
+}
+
+QString GroupWiseProtocol::rtfizeText( const QString & plain )
+{
+ // transcode a utf-8 encoded string into an rtf string
+ // iterate through the input string converting each char into the equivalent rtf
+ // of single-byte characters with first byte =< 0x7f (127), { } \ are escaped. \n are converted into \par , the rest are appended verbatim
+ // of multi-byte UTF-8 characters 2 to 6 bytes long (with first byte > 0x7f), these are recoded as 32 bit values, escaped as \u<val>? strings
+
+ // vanilla RTF "envelope" that doesn't say much but causes other clients to accept the message
+ QString rtfTemplate = QString::fromLatin1("{\\rtf1\\ansi\n"
+ "{\\fonttbl{\\f0\\fnil Unknown;}}\n"
+ "{\\colortbl ;\\red0\\green0\\blue0;}\n"
+ "\\uc1\\cf1\\f0\\fs18 %1\\par\n}");
+ QString outputText; // output text
+ QCString plainUtf8 = plain.utf8(); // encoded as UTF8, because that's what this encoding algorithm, taken from Gaim's Novell plugin
+ uint index = 0; // current char to transcode
+ while ( index < plainUtf8.length() )
+ {
+ Q_UINT8 current = plainUtf8.data()[ index ];
+ if ( current <= 0x7F )
+ {
+ switch ( current )
+ {
+ case '{':
+ case '}':
+ case '\\':
+ outputText.append( QString( "\\%1" ).arg( QChar( current ) ) );
+ break;
+ case '\n':
+ outputText.append( "\\par " );
+ break;
+ default:
+ outputText.append( QChar( current ) );
+ break;
+ }
+ ++index;
+ }
+ else
+ {
+ Q_UINT32 ucs4Char;
+ int bytesEncoded;
+ QString escapedUnicodeChar;
+ if ( current <= 0xDF )
+ {
+ ucs4Char = (( plainUtf8.data()[ index ] & 0x001F) << 6) |
+ ( plainUtf8.data()[ index+1 ] & 0x003F);
+ bytesEncoded = 2;
+ }
+ else if ( current <= 0xEF )
+ {
+ ucs4Char = (( plainUtf8.data()[ index ] & 0x000F) << 12) |
+ (( plainUtf8.data()[ index+1 ] & 0x003F) << 6) |
+ ( plainUtf8.data()[ index+2 ] & 0x003F);
+ bytesEncoded = 3;
+ }
+ else if ( current <= 0xF7 )
+ {
+ ucs4Char = (( plainUtf8.data()[ index ] & 0x0007) << 18) |
+ (( plainUtf8.data()[ index+1 ] & 0x003F) << 12) |
+ (( plainUtf8.data()[ index+2 ] & 0x003F) << 6) |
+ ( plainUtf8.data()[ index+3 ] & 0x003F);
+ bytesEncoded = 4;
+ }
+ else if ( current <= 0xFB )
+ {
+ ucs4Char = (( plainUtf8.data()[ index ] & 0x0003) << 24 ) |
+ (( plainUtf8.data()[ index+1 ] & 0x003F) << 18) |
+ (( plainUtf8.data()[ index+2 ] & 0x003F) << 12) |
+ (( plainUtf8.data()[ index+3 ] & 0x003F) << 6) |
+ ( plainUtf8.data()[ index+4 ] & 0x003F);
+ bytesEncoded = 5;
+ }
+ else if ( current <= 0xFD )
+ {
+ ucs4Char = (( plainUtf8.data()[ index ] & 0x0001) << 30 ) |
+ (( plainUtf8.data()[ index+1 ] & 0x003F) << 24) |
+ (( plainUtf8.data()[ index+2 ] & 0x003F) << 18) |
+ (( plainUtf8.data()[ index+3 ] & 0x003F) << 12) |
+ (( plainUtf8.data()[ index+4 ] & 0x003F) << 6) |
+ ( plainUtf8.data()[ index+5 ] & 0x003F);
+ bytesEncoded = 6;
+ }
+ else
+ {
+ kdDebug( GROUPWISE_DEBUG_GLOBAL ) << k_funcinfo << "bogus utf-8 lead byte: 0x" << QTextStream::hex << current << endl;
+ ucs4Char = 0x003F;
+ bytesEncoded = 1;
+ }
+ index += bytesEncoded;
+ escapedUnicodeChar = QString("\\u%1?").arg( ucs4Char );
+ kdDebug( GROUPWISE_DEBUG_GLOBAL ) << "unicode escaped char: " << escapedUnicodeChar << endl;
+ outputText.append( escapedUnicodeChar );
+ }
+ }
+ return rtfTemplate.arg( outputText );
+}
+
+QString GroupWiseProtocol::dnToDotted( const QString & dn )
+{
+ QRegExp rx("[a-zA-Z]*=(.*)$", false );
+ if( !dn.find( '=' ) ) // if it's not a DN, return it unprocessed
+ return dn;
+
+ // split the dn into elements
+ QStringList elements = QStringList::split( ',', dn );
+ // remove the key, keep the value
+ for ( QStringList::Iterator it = elements.begin(); it != elements.end(); ++it )
+ {
+ if ( rx.search( *it ) != -1 )
+ *it = rx.cap( 1 );
+ }
+ QString dotted = elements.join( "." );
+ // reassemble as dotted
+
+ return dotted;
+}
+#include "gwprotocol.moc"