summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/oscar/aim
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/oscar/aim')
-rw-r--r--kopete/protocols/oscar/aim/Makefile.am18
-rw-r--r--kopete/protocols/oscar/aim/aim.protocol13
-rw-r--r--kopete/protocols/oscar/aim/aimaccount.cpp924
-rw-r--r--kopete/protocols/oscar/aim/aimaccount.h146
-rw-r--r--kopete/protocols/oscar/aim/aimchatsession.cpp73
-rw-r--r--kopete/protocols/oscar/aim/aimchatsession.h77
-rw-r--r--kopete/protocols/oscar/aim/aimcontact.cpp517
-rw-r--r--kopete/protocols/oscar/aim/aimcontact.h102
-rw-r--r--kopete/protocols/oscar/aim/aimjoinchat.cpp94
-rw-r--r--kopete/protocols/oscar/aim/aimjoinchat.h62
-rw-r--r--kopete/protocols/oscar/aim/aimprotocol.cpp320
-rw-r--r--kopete/protocols/oscar/aim/aimprotocol.h85
-rw-r--r--kopete/protocols/oscar/aim/aimuserinfo.cpp224
-rw-r--r--kopete/protocols/oscar/aim/aimuserinfo.h59
-rw-r--r--kopete/protocols/oscar/aim/kopete_aim.desktop77
-rw-r--r--kopete/protocols/oscar/aim/ui/Makefile.am15
-rw-r--r--kopete/protocols/oscar/aim/ui/aimaddcontactpage.cpp83
-rw-r--r--kopete/protocols/oscar/aim/ui/aimaddcontactpage.h41
-rw-r--r--kopete/protocols/oscar/aim/ui/aimaddcontactui.ui64
-rw-r--r--kopete/protocols/oscar/aim/ui/aimeditaccountui.ui540
-rw-r--r--kopete/protocols/oscar/aim/ui/aimeditaccountwidget.cpp172
-rw-r--r--kopete/protocols/oscar/aim/ui/aimeditaccountwidget.h58
-rw-r--r--kopete/protocols/oscar/aim/ui/aiminfobase.ui246
-rw-r--r--kopete/protocols/oscar/aim/ui/aimjoinchatbase.ui124
24 files changed, 4134 insertions, 0 deletions
diff --git a/kopete/protocols/oscar/aim/Makefile.am b/kopete/protocols/oscar/aim/Makefile.am
new file mode 100644
index 00000000..91d12552
--- /dev/null
+++ b/kopete/protocols/oscar/aim/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS = ui
+METASOURCES = AUTO
+AM_CPPFLAGS = -I$(srcdir)/../ \
+ -I$(srcdir)/ui/ \
+ -I$(top_builddir)/kopete/protocols/oscar/aim/ui \
+ -I$(srcdir)/../liboscar \
+ $(KOPETE_INCLUDES) $(all_includes)
+
+kde_module_LTLIBRARIES = kopete_aim.la
+
+kopete_aim_la_SOURCES = aimprotocol.cpp aimaccount.cpp aimcontact.cpp aimuserinfo.cpp aimjoinchat.cpp aimchatsession.cpp
+
+kopete_aim_la_LDFLAGS = -no-undefined -module $(KDE_PLUGIN) $(all_libraries)
+kopete_aim_la_LIBADD = ../libkopete_oscar.la ui/libkopeteaimui.la \
+ $(top_builddir)/kopete/libkopete/libkopete.la
+
+service_DATA = kopete_aim.desktop aim.protocol
+servicedir = $(kde_servicesdir)
diff --git a/kopete/protocols/oscar/aim/aim.protocol b/kopete/protocols/oscar/aim/aim.protocol
new file mode 100644
index 00000000..ae9f6c69
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aim.protocol
@@ -0,0 +1,13 @@
+[Protocol]
+exec=kopete "%u"
+protocol=aim
+input=none
+output=none
+helper=true
+listing=false
+reading=false
+writing=false
+makedir=false
+deleting=false
+URIMode=rawuri
+Icon=aim_icon
diff --git a/kopete/protocols/oscar/aim/aimaccount.cpp b/kopete/protocols/oscar/aim/aimaccount.cpp
new file mode 100644
index 00000000..c6228040
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimaccount.cpp
@@ -0,0 +1,924 @@
+/*
+ aimaccount.cpp - Oscar Protocol Plugin, AIM part
+
+ Kopete (c) 2002-2003 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ *************************************************************************
+*/
+
+#include <qdom.h>
+#include <qfile.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kdialogbase.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kmessagebox.h>
+#include <kmdcodec.h>
+
+#include "kopeteawayaction.h"
+#include "kopetepassword.h"
+#include "kopetestdaction.h"
+#include "kopeteuiglobal.h"
+#include "kopetecontactlist.h"
+#include "kopetemetacontact.h"
+#include "kopeteprotocol.h"
+#include "kopetechatsessionmanager.h"
+#include "kopeteview.h"
+#include <kopeteuiglobal.h>
+
+#include "aimprotocol.h"
+#include "aimaccount.h"
+#include "aimchatsession.h"
+#include "aimcontact.h"
+#include "aimuserinfo.h"
+#include "aimjoinchat.h"
+#include "oscarmyselfcontact.h"
+#include "oscarvisibilitydialog.h"
+
+#include "oscarutils.h"
+#include "client.h"
+#include "ssimanager.h"
+
+
+const DWORD AIM_ONLINE = 0x0;
+const DWORD AIM_AWAY = 0x1;
+
+namespace Kopete { class MetaContact; }
+
+AIMMyselfContact::AIMMyselfContact( AIMAccount *acct )
+: OscarMyselfContact( acct )
+{
+ m_acct = acct;
+}
+
+void AIMMyselfContact::userInfoUpdated()
+{
+ if ( ( details().userClass() & 32 ) == 0 )
+ setOnlineStatus( static_cast<AIMProtocol*>( protocol() )->statusOnline ); //we're online
+ else
+ setOnlineStatus( static_cast<AIMProtocol*>( protocol() )->statusAway ); //we're away
+}
+
+void AIMMyselfContact::setOwnProfile( const QString& newProfile )
+{
+ m_profileString = newProfile;
+ if ( m_acct->isConnected() )
+ m_acct->engine()->updateProfile( newProfile );
+}
+
+QString AIMMyselfContact::userProfile()
+{
+ return m_profileString;
+}
+
+Kopete::ChatSession* AIMMyselfContact::manager( Kopete::Contact::CanCreateFlags canCreate,
+ Oscar::WORD exchange, const QString& room )
+{
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << endl;
+ Kopete::ContactPtrList chatMembers;
+ chatMembers.append( this );
+ Kopete::ChatSession* genericManager = 0L;
+ genericManager = Kopete::ChatSessionManager::self()->findChatSession( account()->myself(), chatMembers, protocol() );
+ AIMChatSession* session = dynamic_cast<AIMChatSession*>( genericManager );
+
+ if ( !session && canCreate == Contact::CanCreate )
+ {
+ session = new AIMChatSession( this, chatMembers, account()->protocol(), exchange, room );
+ session->setEngine( m_acct->engine() );
+
+ connect( session, SIGNAL( messageSent( Kopete::Message&, Kopete::ChatSession* ) ),
+ this, SLOT( sendMessage( Kopete::Message&, Kopete::ChatSession* ) ) );
+ m_chatRoomSessions.append( session );
+ }
+ return session;
+}
+
+void AIMMyselfContact::chatSessionDestroyed( Kopete::ChatSession* session )
+{
+ m_chatRoomSessions.remove( session );
+}
+
+void AIMMyselfContact::sendMessage( Kopete::Message& message, Kopete::ChatSession* session )
+{
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "sending a message" << endl;
+ //TODO: remove duplication - factor into a message utils class or something
+ Oscar::Message msg;
+ QString s;
+
+ if (message.plainBody().isEmpty()) // no text, do nothing
+ return;
+ //okay, now we need to change the message.escapedBody from real HTML to aimhtml.
+ //looking right now for docs on that "format".
+ //looks like everything except for alignment codes comes in the format of spans
+
+ //font-style:italic -> <i>
+ //font-weight:600 -> <b> (anything > 400 should be <b>, 400 is not bold)
+ //text-decoration:underline -> <u>
+ //font-family: -> <font face="">
+ //font-size:xxpt -> <font ptsize=xx>
+
+ s=message.escapedBody();
+ s.replace ( QRegExp( QString::fromLatin1("<span style=\"([^\"]*)\">([^<]*)</span>")),
+ QString::fromLatin1("<style>\\1;\"\\2</style>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-style:italic;([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<i><style>\\1\\2\"\\3</style></i>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-weight:600;([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<b><style>\\1\\2\"\\3</style></b>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)text-decoration:underline;([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<u><style>\\1\\2\"\\3</style></u>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-family:([^;]*);([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<font face=\"\\2\"><style>\\1\\3\"\\4</style></font>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-size:([^p]*)pt;([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<font ptsize=\"\\2\"><style>\\1\\3\"\\4</style></font>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)color:([^;]*);([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<font color=\"\\2\"><style>\\1\\3\"\\4</style></font>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("\\2"));
+
+ //okay now change the <font ptsize="xx"> to <font size="xx">
+
+ //0-9 are size 1
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"\\d\">")),
+ QString::fromLatin1("<font size=\"1\">"));
+ //10-11 are size 2
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"1[01]\">")),
+ QString::fromLatin1("<font size=\"2\">"));
+ //12-13 are size 3
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"1[23]\">")),
+ QString::fromLatin1("<font size=\"3\">"));
+ //14-16 are size 4
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"1[456]\">")),
+ QString::fromLatin1("<font size=\"4\">"));
+ //17-22 are size 5
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"(?:1[789]|2[012])\">")),
+ QString::fromLatin1("<font size=\"5\">"));
+ //23-29 are size 6
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"2[3456789]\">")),QString::fromLatin1("<font size=\"6\">"));
+ //30- (and any I missed) are size 7
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"[^\"]*\">")),QString::fromLatin1("<font size=\"7\">"));
+
+ s.replace ( QRegExp ( QString::fromLatin1("<br[ /]*>")), QString::fromLatin1("<br>") );
+
+ kdDebug(14190) << k_funcinfo << "sending "
+ << s << endl;
+
+ msg.setSender( contactId() );
+ msg.setText( Oscar::Message::UserDefined, s, m_acct->defaultCodec() );
+ msg.setTimestamp(message.timestamp());
+ msg.setType(0x03);
+ msg.addProperty( Oscar::Message::ChatRoom );
+
+ AIMChatSession* aimSession = dynamic_cast<AIMChatSession*>( session );
+ if ( !aimSession )
+ {
+ kdWarning(OSCAR_AIM_DEBUG) << "couldn't convert to AIM chat room session!" << endl;
+ session->messageSucceeded();
+ return;
+ }
+ msg.setExchange( aimSession->exchange() );
+ msg.setChatRoom( aimSession->roomName() );
+
+ m_acct->engine()->sendMessage( msg );
+ //session->appendMessage( message );
+ session->messageSucceeded();
+}
+
+
+AIMAccount::AIMAccount(Kopete::Protocol *parent, QString accountID, const char *name)
+ : OscarAccount(parent, accountID, name, false)
+{
+ kdDebug(14152) << k_funcinfo << accountID << ": Called."<< endl;
+ AIMMyselfContact* mc = new AIMMyselfContact( this );
+ setMyself( mc );
+ myself()->setOnlineStatus( static_cast<AIMProtocol*>( parent )->statusOffline );
+ QString profile = configGroup()->readEntry( "Profile",
+ i18n( "Visit the Kopete website at <a href=\"http://kopete.kde.org\">http://kopete.kde.org</a>") );
+ mc->setOwnProfile( profile );
+
+ m_joinChatDialog = 0;
+ m_visibilityDialog = 0;
+ QObject::connect( Kopete::ContactList::self(),
+ SIGNAL( globalIdentityChanged( const QString&, const QVariant& ) ),
+ this,
+ SLOT( slotGlobalIdentityChanged( const QString&, const QVariant& ) ) );
+
+ QObject::connect( engine(), SIGNAL( chatRoomConnected( WORD, const QString& ) ),
+ this, SLOT( connectedToChatRoom( WORD, const QString& ) ) );
+
+ QObject::connect( engine(), SIGNAL( userJoinedChat( Oscar::WORD, const QString&, const QString& ) ),
+ this, SLOT( userJoinedChat( Oscar::WORD, const QString&, const QString& ) ) );
+
+ QObject::connect( engine(), SIGNAL( userLeftChat( Oscar::WORD, const QString&, const QString& ) ),
+ this, SLOT( userLeftChat( Oscar::WORD, const QString&, const QString& ) ) );
+
+ QObject::connect( this, SIGNAL( buddyIconChanged() ), this, SLOT( slotBuddyIconChanged() ) );
+
+}
+
+AIMAccount::~AIMAccount()
+{
+}
+
+OscarContact *AIMAccount::createNewContact( const QString &contactId, Kopete::MetaContact *parentContact, const SSI& ssiItem )
+{
+ AIMContact* contact = new AIMContact( this, contactId, parentContact, QString::null, ssiItem );
+ if ( !ssiItem.alias().isEmpty() )
+ contact->setProperty( Kopete::Global::Properties::self()->nickName(), ssiItem.alias() );
+
+ return contact;
+}
+
+QString AIMAccount::sanitizedMessage( const QString& message )
+{
+ QDomDocument doc;
+ QString domError;
+ int errLine = 0, errCol = 0;
+ doc.setContent( message, false, &domError, &errLine, &errCol );
+ if ( !domError.isEmpty() ) //error parsing, do nothing
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "error from dom document conversion: "
+ << domError << endl;
+ return message;
+ }
+ else
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "conversion to dom document successful."
+ << "looking for font tags" << endl;
+ QDomNodeList fontTagList = doc.elementsByTagName( "font" );
+ if ( fontTagList.count() == 0 )
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "No font tags found. Returning normal message" << endl;
+ return message;
+ }
+ else
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Found font tags. Attempting replacement" << endl;
+ uint numFontTags = fontTagList.count();
+ for ( uint i = 0; i < numFontTags; i++ )
+ {
+ QDomNode fontNode = fontTagList.item(i);
+ QDomElement fontEl;
+ if ( !fontNode.isNull() && fontNode.isElement() )
+ fontEl = fontTagList.item(i).toElement();
+ else
+ continue;
+ if ( fontEl.hasAttribute( "back" ) )
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Found attribute to replace. Doing replacement" << endl;
+ QString backgroundColor = fontEl.attribute( "back" );
+ backgroundColor.insert( 0, "background-color: " );
+ backgroundColor.append( ';' );
+ fontEl.setAttribute( "style", backgroundColor );
+ fontEl.removeAttribute( "back" );
+ }
+ }
+ }
+ }
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "sanitized message is " << doc.toString();
+ return doc.toString();
+}
+
+KActionMenu* AIMAccount::actionMenu()
+{
+// kdDebug(14152) << k_funcinfo << accountId() << ": Called." << endl;
+ // mActionMenu is managed by Kopete::Account. It is deleted when
+ // it is no longer shown, so we can (safely) just make a new one here.
+ KActionMenu *mActionMenu = new KActionMenu(accountId(),
+ myself()->onlineStatus().iconFor( this ), this, "AIMAccount::mActionMenu");
+
+ AIMProtocol *p = AIMProtocol::protocol();
+
+ QString accountNick = myself()->property( Kopete::Global::Properties::self()->nickName() ).value().toString();
+ mActionMenu->popupMenu()->insertTitle( myself()->onlineStatus().iconFor( myself() ),
+ i18n( "%2 <%1>" ).arg( accountId(), accountNick ));
+
+ mActionMenu->insert( new KAction( i18n("Online"), p->statusOnline.iconFor( this ), 0, this,
+ SLOT( slotGoOnline() ), mActionMenu, "AIMAccount::mActionOnline") );
+
+ KAction* mActionAway = new Kopete::AwayAction(i18n("Away"), p->statusAway.iconFor( this ), 0, this,
+ SLOT(slotGoAway( const QString & )), this, "AIMAccount::mActionNA" );
+ mActionAway->setEnabled( isConnected() );
+ mActionMenu->insert( mActionAway );
+
+ KAction* mActionOffline = new KAction( i18n("Offline"), p->statusOffline.iconFor(this), 0, this,
+ SLOT( slotGoOffline() ), mActionMenu, "AIMAccount::mActionOffline");
+
+ mActionMenu->insert( mActionOffline );
+ mActionMenu->popupMenu()->insertSeparator();
+
+ KAction* m_joinChatAction = new KAction( i18n( "Join Chat..." ), QString::null, 0, this,
+ SLOT( slotJoinChat() ), mActionMenu, "join_a_chat" );
+
+ mActionMenu->insert( new KToggleAction( i18n( "Set Visibility..." ), 0, 0,
+ this, SLOT( slotSetVisiblility() ), this,
+ "AIMAccount::mActionSetVisibility") );
+
+ mActionMenu->insert( m_joinChatAction );
+
+ KAction* m_editInfoAction = new KAction( i18n( "Edit User Info..." ), "identity", 0,
+ this, SLOT( slotEditInfo() ), mActionMenu, "actionEditInfo");
+
+ mActionMenu->insert( m_editInfoAction );
+
+ return mActionMenu;
+}
+
+void AIMAccount::setAway(bool away, const QString &awayReason)
+{
+// kdDebug(14152) << k_funcinfo << accountId() << "reason is " << awayReason << endl;
+ if ( away )
+ {
+ engine()->setStatus( Client::Away, awayReason );
+ AIMMyselfContact* me = static_cast<AIMMyselfContact *> ( myself() );
+ me->setLastAwayMessage(awayReason);
+ me->setProperty( Kopete::Global::Properties::self()->awayMessage(), awayReason );
+ }
+ else
+ {
+ engine()->setStatus( Client::Online );
+ AIMMyselfContact* me = static_cast<AIMMyselfContact *> ( myself() );
+ me->setLastAwayMessage(QString::null);
+ me->removeProperty( Kopete::Global::Properties::self()->awayMessage() );
+ }
+}
+
+void AIMAccount::setOnlineStatus( const Kopete::OnlineStatus& status, const QString& reason )
+{
+ kdDebug(14152) << k_funcinfo << "called with reason = " << reason <<" status = "<< status.status() << endl;;
+ if ( status.status() == Kopete::OnlineStatus::Online )
+ setAway( false );
+ if ( status.status() == Kopete::OnlineStatus::Away )
+ setAway( true, reason );
+}
+
+
+void AIMAccount::setUserProfile(const QString &profile)
+{
+ kdDebug(14152) << k_funcinfo << "called." << endl;
+ AIMMyselfContact* aimmc = dynamic_cast<AIMMyselfContact*>( myself() );
+ if ( aimmc )
+ aimmc->setOwnProfile( profile );
+ configGroup()->writeEntry( QString::fromLatin1( "Profile" ), profile );
+}
+
+void AIMAccount::slotEditInfo()
+{
+ if ( !isConnected() )
+ {
+ KMessageBox::sorry( Kopete::UI::Global::mainWidget(),
+ i18n( "Editing your user info is not possible because "
+ "you are not connected." ),
+ i18n( "Unable to edit user info" ) );
+ return;
+ }
+ AIMUserInfoDialog *myInfo = new AIMUserInfoDialog(static_cast<AIMContact *>( myself() ), this, true, 0L, "myInfo");
+ myInfo->exec(); // This is a modal dialog
+}
+
+void AIMAccount::slotGlobalIdentityChanged( const QString& key, const QVariant& value )
+{
+ //do something with the photo
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Global identity changed" << endl;
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "key: " << key << endl;
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "value: " << value << endl;
+
+ if( !configGroup()->readBoolEntry("ExcludeGlobalIdentity", false) )
+ {
+ if ( key == Kopete::Global::Properties::self()->nickName().key() )
+ {
+ //edit ssi item to change alias (if possible)
+ }
+
+ if ( key == Kopete::Global::Properties::self()->photo().key() )
+ {
+ setBuddyIcon( value.toString() );
+ }
+ }
+}
+
+void AIMAccount::slotBuddyIconChanged()
+{
+ // need to disconnect because we could end up with many connections
+ QObject::disconnect( engine(), SIGNAL( iconServerConnected() ), this, SLOT( slotBuddyIconChanged() ) );
+ if ( !engine()->isActive() )
+ {
+ QObject::connect( engine(), SIGNAL( iconServerConnected() ), this, SLOT( slotBuddyIconChanged() ) );
+ return;
+ }
+
+ QString photoPath = myself()->property( Kopete::Global::Properties::self()->photo() ).value().toString();
+
+ SSIManager* ssi = engine()->ssiManager();
+ Oscar::SSI item = ssi->findItemForIconByRef( 1 );
+
+ if ( photoPath.isEmpty() )
+ {
+ if ( item )
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Removing icon hash item from ssi" << endl;
+ Oscar::SSI s(item);
+
+ //remove hash and alias
+ QValueList<TLV> tList( item.tlvList() );
+ TLV t = Oscar::findTLV( tList, 0x00D5 );
+ if ( t )
+ tList.remove( t );
+
+ item.setTLVList( tList );
+ //s is old, item is new. modification will occur
+ engine()->modifySSIItem( s, item );
+ }
+ }
+ else
+ {
+ QFile iconFile( photoPath );
+ iconFile.open( IO_ReadOnly );
+
+ KMD5 iconHash;
+ iconHash.update( iconFile );
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "hash is :" << iconHash.hexDigest() << endl;
+
+ //find old item, create updated item
+ if ( !item )
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "no existing icon hash item in ssi. creating new" << endl;
+
+ TLV t;
+ t.type = 0x00D5;
+ t.data.resize( 18 );
+ t.data[0] = 0x00;
+ t.data[1] = 0x10;
+ memcpy(t.data.data() + 2, iconHash.rawDigest(), 16);
+ t.length = t.data.size();
+
+ QValueList<Oscar::TLV> list;
+ list.append( t );
+
+ Oscar::SSI s( "1", 0, ssi->nextContactId(), ROSTER_BUDDYICONS, list );
+
+ //item is a non-valid ssi item, so the function will add an item
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "setting new icon item" << endl;
+ engine()->modifySSIItem( item, s );
+ }
+ else
+ { //found an item
+ Oscar::SSI s(item);
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "modifying old item in ssi." << endl;
+ QValueList<TLV> tList( item.tlvList() );
+
+ TLV t = Oscar::findTLV( tList, 0x00D5 );
+ if ( t )
+ tList.remove( t );
+ else
+ t.type = 0x00D5;
+
+ t.data.resize( 18 );
+ t.data[0] = 0x00;
+ t.data[1] = 0x10;
+ memcpy(t.data.data() + 2, iconHash.rawDigest(), 16);
+ t.length = t.data.size();
+ tList.append( t );
+
+ item.setTLVList( tList );
+ //s is old, item is new. modification will occur
+ engine()->modifySSIItem( s, item );
+ }
+ iconFile.close();
+ }
+}
+
+void AIMAccount::slotJoinChat()
+{
+ if ( !isConnected() )
+ {
+ KMessageBox::sorry( Kopete::UI::Global::mainWidget(),
+ i18n( "Joining an AIM chat room is not possible because "
+ "you are not connected." ),
+ i18n( "Unable to Join AIM Chat Room" ) );
+ return;
+ }
+
+ //get the exchange info
+ //create the dialog
+ //join the chat room
+ if ( !m_joinChatDialog )
+ {
+ m_joinChatDialog = new AIMJoinChatUI( this, false, Kopete::UI::Global::mainWidget() );
+ QObject::connect( m_joinChatDialog, SIGNAL( closing( int ) ),
+ this, SLOT( joinChatDialogClosed( int ) ) );
+ QValueList<int> list = engine()->chatExchangeList();
+ m_joinChatDialog->setExchangeList( list );
+ m_joinChatDialog->show();
+ }
+ else
+ m_joinChatDialog->raise();
+}
+
+void AIMAccount::slotGoOnline()
+{
+ if ( myself()->onlineStatus().status() == Kopete::OnlineStatus::Away )
+ {
+ kdDebug(14152) << k_funcinfo << accountId() << " was away. welcome back." << endl;
+ engine()->setStatus( Client::Online );
+ myself()->removeProperty( Kopete::Global::Properties::self()->awayMessage() );
+ }
+ else if ( myself()->onlineStatus().status() == Kopete::OnlineStatus::Offline )
+ {
+ kdDebug(14152) << k_funcinfo << accountId() << " was offline. time to connect" << endl;
+ OscarAccount::connect();
+ }
+ else
+ {
+ kdDebug(14152) << k_funcinfo << accountId() << " is already online, doing nothing" << endl;
+ }
+}
+
+void AIMAccount::slotGoAway(const QString &message)
+{
+ kdDebug(14152) << k_funcinfo << message << endl;
+ setAway(true, message);
+}
+
+void AIMAccount::joinChatDialogClosed( int code )
+{
+ if ( code == QDialog::Accepted )
+ {
+ //join the chat
+ kdDebug(14152) << k_funcinfo << "chat accepted." << endl;
+ engine()->joinChatRoom( m_joinChatDialog->roomName(),
+ m_joinChatDialog->exchange().toInt() );
+ }
+
+ m_joinChatDialog->delayedDestruct();
+ m_joinChatDialog = 0L;
+}
+
+void AIMAccount::loginActions()
+{
+ OscarAccount::loginActions();
+
+ using namespace AIM::PrivacySettings;
+ int privacySetting = this->configGroup()->readNumEntry( "PrivacySetting", AllowAll );
+ this->setPrivacySettings( privacySetting );
+}
+
+void AIMAccount::disconnected( DisconnectReason reason )
+{
+ kdDebug( OSCAR_AIM_DEBUG ) << k_funcinfo << "Attempting to set status offline" << endl;
+ myself()->setOnlineStatus( static_cast<AIMProtocol*>( protocol() )->statusOffline );
+
+ QDictIterator<Kopete::Contact> it( contacts() );
+ for( ; it.current(); ++it )
+ {
+ OscarContact* oc = dynamic_cast<OscarContact*>( it.current() );
+ if ( oc )
+ oc->setOnlineStatus( static_cast<AIMProtocol*>( protocol() )->statusOffline );
+ }
+
+ OscarAccount::disconnected( reason );
+}
+
+void AIMAccount::messageReceived( const Oscar::Message& message )
+{
+ kdDebug(14152) << k_funcinfo << " Got a message, calling OscarAccount::messageReceived" << endl;
+ // Want to call the parent to do everything else
+ if ( message.type() != 0x0003 )
+ {
+ OscarAccount::messageReceived(message);
+
+ // Check to see if our status is away, and send an away message
+ // Might be duplicate code from the parent class to get some needed information
+ // Perhaps a refactoring is needed.
+ kdDebug(14152) << k_funcinfo << "Checking to see if I'm online.." << endl;
+ if( myself()->onlineStatus().status() == Kopete::OnlineStatus::Away )
+ {
+ QString sender = Oscar::normalize( message.sender() );
+ AIMContact* aimSender = static_cast<AIMContact *> ( contacts()[sender] ); //should exist now
+ if ( !aimSender )
+ {
+ kdWarning(OSCAR_RAW_DEBUG) << "For some reason, could not get the contact "
+ << "That this message is from: " << message.sender() << ", Discarding message" << endl;
+ return;
+ }
+ // Create, or get, a chat session with the contact
+ Kopete::ChatSession* chatSession = aimSender->manager( Kopete::Contact::CanCreate );
+
+ // get the away message we have set
+ AIMMyselfContact* myContact = static_cast<AIMMyselfContact *> ( myself() );
+ QString msg = myContact->lastAwayMessage();
+ kdDebug(14152) << k_funcinfo << "Got away message: " << msg << endl;
+ // Create the message
+ Kopete::Message chatMessage( myself(), aimSender, msg, Kopete::Message::Outbound,
+ Kopete::Message::RichText );
+ kdDebug(14152) << k_funcinfo << "Sending autoresponse" << endl;
+ // Send the message
+ aimSender->sendAutoResponse( chatMessage );
+ }
+ }
+
+ if ( message.type() == 0x0003 )
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "have chat message" << endl;
+ //handle chat room messages seperately
+ QValueList<Kopete::ChatSession*> chats = Kopete::ChatSessionManager::self()->sessions();
+ QValueList<Kopete::ChatSession*>::iterator it, itEnd = chats.end();
+ for ( it = chats.begin(); it != itEnd; ++it )
+ {
+ Kopete::ChatSession* kcs = ( *it );
+ AIMChatSession* session = dynamic_cast<AIMChatSession*>( kcs );
+ if ( !session )
+ continue;
+
+ if ( session->exchange() == message.exchange() &&
+ Oscar::normalize( session->roomName() ) ==
+ Oscar::normalize( message.chatRoom() ) )
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "found chat session for chat room" << endl;
+ Kopete::Contact* ocSender = contacts()[Oscar::normalize( message.sender() )];
+ //sanitize;
+ QString sanitizedMsg = sanitizedMessage( message.text( defaultCodec() ) );
+
+ Kopete::ContactPtrList me;
+ me.append( myself() );
+ Kopete::Message chatMessage( message.timestamp(), ocSender, me, sanitizedMsg,
+ Kopete::Message::Inbound, Kopete::Message::RichText );
+
+ session->appendMessage( chatMessage );
+ }
+ }
+ }
+}
+
+void AIMAccount::connectedToChatRoom( WORD exchange, const QString& room )
+{
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Creating chat room session" << endl;
+ Kopete::ContactPtrList emptyList;
+ AIMMyselfContact* me = static_cast<AIMMyselfContact*>( myself() );
+ AIMChatSession* session = dynamic_cast<AIMChatSession*>( me->manager( Kopete::Contact::CanCreate,
+ exchange, room ) );
+ session->setDisplayName( room );
+ if ( session->view( true ) )
+ session->raiseView();
+}
+
+void AIMAccount::userJoinedChat( WORD exchange, const QString& room, const QString& contact )
+{
+ if ( Oscar::normalize( contact ) == Oscar::normalize( myself()->contactId() ) )
+ return;
+
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "user " << contact << " has joined the chat" << endl;
+ QValueList<Kopete::ChatSession*> chats = Kopete::ChatSessionManager::self()->sessions();
+ QValueList<Kopete::ChatSession*>::iterator it, itEnd = chats.end();
+ for ( it = chats.begin(); it != itEnd; ++it )
+ {
+ Kopete::ChatSession* kcs = ( *it );
+ AIMChatSession* session = dynamic_cast<AIMChatSession*>( kcs );
+ if ( !session )
+ continue;
+
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << session->exchange() << " " << exchange << endl;
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << session->roomName() << " " << room << endl;
+ if ( session->exchange() == exchange && session->roomName() == room )
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "found correct chat session" << endl;
+ Kopete::Contact* c;
+ if ( contacts()[Oscar::normalize( contact )] )
+ c = contacts()[Oscar::normalize( contact )];
+ else
+ {
+ Kopete::MetaContact* mc = addContact( Oscar::normalize( contact ),
+ contact, 0, Kopete::Account::Temporary );
+ if ( !mc )
+ kdWarning(OSCAR_AIM_DEBUG) << "Unable to add contact for chat room" << endl;
+
+ c = mc->contacts().first();
+ c->setNickName( contact );
+ }
+
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "adding contact" << endl;
+ session->addContact( c, static_cast<AIMProtocol*>( protocol() )->statusOnline, true /* suppress */ );
+ }
+ }
+}
+
+void AIMAccount::userLeftChat( WORD exchange, const QString& room, const QString& contact )
+{
+ if ( Oscar::normalize( contact ) == Oscar::normalize( myself()->contactId() ) )
+ return;
+
+ QValueList<Kopete::ChatSession*> chats = Kopete::ChatSessionManager::self()->sessions();
+ QValueList<Kopete::ChatSession*>::iterator it, itEnd = chats.end();
+ for ( it = chats.begin(); it != itEnd; ++it )
+ {
+ Kopete::ChatSession* kcs = ( *it );
+ AIMChatSession* session = dynamic_cast<AIMChatSession*>( kcs );
+ if ( !session )
+ continue;
+
+ if ( session->exchange() == exchange && session->roomName() == room )
+ {
+ //delete temp contact
+ Kopete::Contact* c = contacts()[Oscar::normalize( contact )];
+ if ( !c )
+ {
+ kdWarning(OSCAR_AIM_DEBUG) << k_funcinfo << "couldn't find the contact that's left the chat!" << endl;
+ continue;
+ }
+ session->removeContact( c );
+ Kopete::MetaContact* mc = c->metaContact();
+ if ( mc->isTemporary() )
+ {
+ mc->removeContact( c );
+ delete c;
+ delete mc;
+ }
+ }
+ }
+}
+
+
+void AIMAccount::connectWithPassword( const QString & )
+{
+ kdDebug(14152) << k_funcinfo << "accountId='" << accountId() << "'" << endl;
+
+ // Get the screen name for this account
+ QString screenName = accountId();
+ QString server = configGroup()->readEntry( "Server", QString::fromLatin1( "login.oscar.aol.com" ) );
+ uint port = configGroup()->readNumEntry( "Port", 5190 );
+
+ Connection* c = setupConnection( server, port );
+
+ QString _password = password().cachedValue();
+ if ( _password.isEmpty() )
+ {
+ kdDebug(14150) << "Kopete is unable to attempt to sign-on to the "
+ << "AIM network because no password was specified in the "
+ << "preferences." << endl;
+ }
+ else if ( myself()->onlineStatus() == static_cast<AIMProtocol*>( protocol() )->statusOffline )
+ {
+ kdDebug(14152) << k_funcinfo << "Logging in as " << accountId() << endl ;
+ updateVersionUpdaterStamp();
+ engine()->start( server, port, accountId(), _password );
+ engine()->connectToServer( c, server, true /* doAuth */ );
+ myself()->setOnlineStatus( static_cast<AIMProtocol*>( protocol() )->statusConnecting );
+ }
+}
+
+void AIMAccount::slotSetVisiblility()
+{
+ if( !isConnected() )
+ {
+ KMessageBox::sorry( Kopete::UI::Global::mainWidget(),
+ i18n("You must be online to set users visibility."),
+ i18n("ICQ Plugin") );
+ return;
+ }
+
+ if ( !m_visibilityDialog )
+ {
+ m_visibilityDialog = new OscarVisibilityDialog( engine(), Kopete::UI::Global::mainWidget() );
+ QObject::connect( m_visibilityDialog, SIGNAL( closing() ),
+ this, SLOT( slotVisibilityDialogClosed() ) );
+
+ //add all contacts;
+ OscarVisibilityDialog::ContactMap contactMap;
+ QMap<QString, QString> revContactMap;
+
+ QValueList<Oscar::SSI> contactList = engine()->ssiManager()->contactList();
+ QValueList<Oscar::SSI>::const_iterator it, cEnd = contactList.constEnd();
+
+ for ( it = contactList.constBegin(); it != cEnd; ++it )
+ {
+ QString contactId = ( *it ).name();
+
+ OscarContact* oc = dynamic_cast<OscarContact*>( contacts()[( *it ).name()] );
+ if ( oc )
+ {
+ contactMap.insert( oc->nickName(), contactId );
+ revContactMap.insert( contactId, oc->nickName() );
+ }
+ else
+ {
+ contactMap.insert( contactId, contactId );
+ revContactMap.insert( contactId, contactId );
+ }
+ }
+ m_visibilityDialog->addContacts( contactMap );
+
+ //add contacts from visible list
+ QStringList tmpList;
+
+ contactList = engine()->ssiManager()->visibleList();
+ cEnd = contactList.constEnd();
+
+ for ( it = contactList.constBegin(); it != cEnd; ++it )
+ tmpList.append( revContactMap[( *it ).name()] );
+
+ m_visibilityDialog->addVisibleContacts( tmpList );
+
+ //add contacts from invisible list
+ tmpList.clear();
+
+ contactList = engine()->ssiManager()->invisibleList();
+ cEnd = contactList.constEnd();
+
+ for ( it = contactList.constBegin(); it != cEnd; ++it )
+ tmpList.append( revContactMap[( *it ).name()] );
+
+ m_visibilityDialog->addInvisibleContacts( tmpList );
+
+ m_visibilityDialog->resize( 550, 350 );
+ m_visibilityDialog->show();
+ }
+ else
+ {
+ m_visibilityDialog->raise();
+ }
+}
+
+void AIMAccount::slotVisibilityDialogClosed()
+{
+ m_visibilityDialog->delayedDestruct();
+ m_visibilityDialog = 0L;
+}
+
+void AIMAccount::setPrivacySettings( int privacy )
+{
+ using namespace AIM::PrivacySettings;
+
+ BYTE privacyByte = 0x01;
+ DWORD userClasses = 0xFFFFFFFF;
+
+ switch ( privacy )
+ {
+ case AllowAll:
+ privacyByte = 0x01;
+ break;
+ case BlockAll:
+ privacyByte = 0x02;
+ break;
+ case AllowPremitList:
+ privacyByte = 0x03;
+ break;
+ case BlockDenyList:
+ privacyByte = 0x04;
+ break;
+ case AllowMyContacts:
+ privacyByte = 0x05;
+ break;
+ case BlockAIM:
+ privacyByte = 0x01;
+ userClasses = 0x00000004;
+ break;
+ }
+
+ this->setPrivacyTLVs( privacyByte, userClasses );
+}
+
+void AIMAccount::setPrivacyTLVs( BYTE privacy, DWORD userClasses )
+{
+ SSIManager* ssi = engine()->ssiManager();
+ Oscar::SSI item = ssi->findItem( QString::null, ROSTER_VISIBILITY );
+
+ QValueList<Oscar::TLV> tList;
+
+ tList.append( TLV( 0x00CA, 1, (char *)&privacy ) );
+ tList.append( TLV( 0x00CB, sizeof(userClasses), (char *)&userClasses ) );
+
+ if ( !item )
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Adding new privacy TLV item" << endl;
+ Oscar::SSI s( QString::null, 0, ssi->nextContactId(), ROSTER_VISIBILITY, tList );
+ engine()->modifySSIItem( item, s );
+ }
+ else
+ { //found an item
+ Oscar::SSI s(item);
+
+ if ( Oscar::uptateTLVs( s, tList ) == true )
+ {
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Updating privacy TLV item" << endl;
+ engine()->modifySSIItem( item, s );
+ }
+ }
+}
+
+#include "aimaccount.moc"
+//kate: tab-width 4; indent-mode csands;
diff --git a/kopete/protocols/oscar/aim/aimaccount.h b/kopete/protocols/oscar/aim/aimaccount.h
new file mode 100644
index 00000000..034b9836
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimaccount.h
@@ -0,0 +1,146 @@
+/*
+ AIMAccount - Oscar Protocol Account
+
+ Copyright (c) 2002 by Chris TenHarmsel <tenharmsel@staticmethod.net>
+
+ Kopete (c) 2002 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ *************************************************************************
+
+*/
+
+#ifndef AIMACCOUNT_H
+#define AIMACCOUNT_H
+
+#include <qdict.h>
+#include <qstring.h>
+#include <qwidget.h>
+#include "oscartypeclasses.h"
+
+#include "oscaraccount.h"
+#include "oscarmyselfcontact.h"
+
+namespace AIM
+{
+ namespace PrivacySettings
+ {
+ enum { AllowAll = 0, AllowMyContacts, AllowPremitList, BlockAll, BlockAIM, BlockDenyList };
+ }
+}
+
+namespace Kopete
+{
+class Contact;
+class Group;
+class ChatSession;
+}
+
+class KAction;
+class OscarContact;
+class AIMContact;
+class AIMAccount;
+class AIMJoinChatUI;
+class AIMChatSession;
+class OscarVisibilityDialog;
+
+class AIMMyselfContact : public OscarMyselfContact
+{
+Q_OBJECT
+public:
+ AIMMyselfContact( AIMAccount *acct );
+ void userInfoUpdated();
+ void setOwnProfile( const QString& newProfile );
+ QString userProfile();
+ void setLastAwayMessage( const QString& msg) {m_lastAwayMessage = msg;}
+ QString lastAwayMessage() { return m_lastAwayMessage; };
+
+ virtual Kopete::ChatSession* manager( Kopete::Contact::CanCreateFlags = Kopete::Contact::CannotCreate,
+ WORD exchange = 0, const QString& room = QString::null);
+
+public slots:
+ void sendMessage( Kopete::Message&, Kopete::ChatSession* session );
+ void chatSessionDestroyed( Kopete::ChatSession* );
+
+private:
+ QString m_profileString;
+ AIMAccount* m_acct;
+ /**
+ * There has GOT to be a better way to get this away message
+ */
+ QString m_lastAwayMessage;
+ QValueList<Kopete::ChatSession*> m_chatRoomSessions;
+
+
+};
+
+class AIMAccount : public OscarAccount
+{
+Q_OBJECT
+
+public:
+ AIMAccount(Kopete::Protocol *parent, QString accountID, const char *name=0L);
+ virtual ~AIMAccount();
+
+ // Accessor method for the action menu
+ virtual KActionMenu* actionMenu();
+
+ void setAway(bool away, const QString &awayReason = QString::null );
+
+ virtual void connectWithPassword( const QString &password );
+
+ void setUserProfile(const QString &profile);
+
+ void setPrivacySettings( int privacy );
+
+public slots:
+ /** Reimplementation from Kopete::Account */
+ void setOnlineStatus( const Kopete::OnlineStatus& status, const QString& reason = QString::null );
+ void slotEditInfo();
+ void slotGoOnline();
+
+ void slotGlobalIdentityChanged( const QString&, const QVariant& );
+ void slotBuddyIconChanged();
+
+ void slotJoinChat();
+
+protected slots:
+ void slotGoAway(const QString&);
+ void joinChatDialogClosed( int );
+
+ virtual void loginActions();
+ virtual void disconnected( Kopete::Account::DisconnectReason reason );
+ virtual void messageReceived( const Oscar::Message& message );
+
+ void connectedToChatRoom( WORD exchange, const QString& roomName );
+ void userJoinedChat( Oscar::WORD exchange, const QString& room, const QString& contact );
+ void userLeftChat( Oscar::WORD exchange, const QString& room, const QString& contact );
+
+ void slotSetVisiblility();
+ void slotVisibilityDialogClosed();
+
+protected:
+
+ /**
+ * Implement virtual method from OscarAccount
+ * This allows OscarAccount to take care of adding new contacts
+ */
+ OscarContact *createNewContact( const QString &contactId, Kopete::MetaContact *parentContact, const SSI& ssiItem );
+
+ QString sanitizedMessage( const QString& message );
+
+private:
+ // Set privacy tlv item
+ void setPrivacyTLVs( BYTE privacy, DWORD userClasses );
+
+ AIMJoinChatUI* m_joinChatDialog;
+ OscarVisibilityDialog* m_visibilityDialog;
+};
+#endif
+//kate: tab-width 4; indent-mode csands;
diff --git a/kopete/protocols/oscar/aim/aimchatsession.cpp b/kopete/protocols/oscar/aim/aimchatsession.cpp
new file mode 100644
index 00000000..fa0616a6
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimchatsession.cpp
@@ -0,0 +1,73 @@
+// aimchatsession.cpp
+
+// Copyright (C) 2005 Matt Rogers <mattr@kde.org>
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+
+#include "aimchatsession.h"
+#include "kopetecontact.h"
+#include "kopetechatsessionmanager.h"
+#include "kopeteprotocol.h"
+#include "client.h"
+
+AIMChatSession::AIMChatSession( const Kopete::Contact* user, Kopete::ContactPtrList others,
+ Kopete::Protocol* protocol, Oscar::WORD exchange,
+ const QString& room )
+
+ : Kopete::ChatSession( user, others, protocol, "AIMChatSession" )
+{
+ Kopete::ChatSessionManager::self()->registerChatSession( this );
+ setInstance( protocol->instance() );
+ setMayInvite( false );
+ m_exchange = exchange;
+ m_roomName = room;
+ m_engine = 0;
+}
+
+AIMChatSession::~AIMChatSession()
+{
+ m_engine->disconnectChatRoom( m_exchange, m_roomName );
+}
+
+void AIMChatSession::setEngine( Client* engine )
+{
+ m_engine = engine;
+}
+
+QString AIMChatSession::roomName() const
+{
+
+ return m_roomName;
+}
+
+void AIMChatSession::setRoomName( const QString& room )
+{
+ m_roomName = room;
+}
+
+Oscar::WORD AIMChatSession::exchange() const
+{
+ return m_exchange;
+}
+
+void AIMChatSession::setExchange( Oscar::WORD exchange )
+{
+ m_exchange = exchange;
+}
+
+
+#include "aimchatsession.moc"
diff --git a/kopete/protocols/oscar/aim/aimchatsession.h b/kopete/protocols/oscar/aim/aimchatsession.h
new file mode 100644
index 00000000..79c0685e
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimchatsession.h
@@ -0,0 +1,77 @@
+// aimchatsession.h
+// Copyright (C) 2005 Matt Rogers <mattr@kde.org>
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA
+// 02110-1301, USA.
+
+#ifndef AIMCHATSESSION_H
+#define AIMCHATSESSION_H
+
+#include "kopetechatsession.h"
+#include "oscartypes.h"
+
+class Client;
+
+class AIMChatSession : public Kopete::ChatSession
+{
+Q_OBJECT
+public:
+ AIMChatSession( const Kopete::Contact* contact, Kopete::ContactPtrList others,
+ Kopete::Protocol* protocol, Oscar::WORD exchange = 0,
+ const QString& room = QString::null );
+ virtual ~AIMChatSession();
+
+ /**
+ * Set the engine to use so that we can disconnect from the chat service
+ * properly
+ */
+ void setEngine( Client* engine );
+
+ /**
+ * Get the name of the AIM chat room represented by
+ * this ChatSession object
+ * @return the name of the chat room
+ */
+ QString roomName() const;
+
+ /**
+ * Set the name of the AIM chat room represented by
+ * this ChatSession object
+ * @param room the name of the AIM chat room
+ */
+ void setRoomName( const QString& room );
+
+ /**
+ * Get the exchange of the AIM chat room represented by
+ * this ChatSession object
+ * @return the exchange of the chat room
+ */
+ Oscar::WORD exchange() const;
+
+ /**
+ * Set the exchange of the AIM chat room represented by
+ * this ChatSession object
+ * @param exchange the exchange of the AIM chat room
+ */
+ void setExchange( Oscar::WORD exchange );
+
+private:
+ QString m_roomName;
+ Oscar::WORD m_exchange;
+ Client* m_engine;
+};
+
+
+#endif
diff --git a/kopete/protocols/oscar/aim/aimcontact.cpp b/kopete/protocols/oscar/aim/aimcontact.cpp
new file mode 100644
index 00000000..7e46c585
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimcontact.cpp
@@ -0,0 +1,517 @@
+/*
+ aimcontact.cpp - Oscar Protocol Plugin
+
+ Copyright (c) 2003 by Will Stephenson
+ Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ *************************************************************************
+*/
+
+#include <time.h>
+
+#include <qimage.h>
+#include <qregexp.h>
+#include <qtimer.h>
+#include <qtextcodec.h>
+
+#include <kapplication.h>
+#include <kactionclasses.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+
+#include "kopeteaway.h"
+#include "kopetechatsession.h"
+#include "kopeteuiglobal.h"
+#include "kopetemetacontact.h"
+
+//liboscar
+#include "client.h"
+#include "oscartypes.h"
+#include "oscarutils.h"
+#include "ssimanager.h"
+
+#include "aimprotocol.h"
+#include "aimuserinfo.h"
+#include "aimcontact.h"
+#include "aimaccount.h"
+
+AIMContact::AIMContact( Kopete::Account* account, const QString& name, Kopete::MetaContact* parent,
+ const QString& icon, const Oscar::SSI& ssiItem )
+: OscarContact(account, name, parent, icon, ssiItem )
+{
+ mProtocol=static_cast<AIMProtocol *>(protocol());
+ setOnlineStatus( mProtocol->statusOffline );
+
+ m_infoDialog = 0L;
+ m_warnUserAction = 0L;
+ mUserProfile="";
+ m_haveAwayMessage = false;
+ m_mobile = false;
+ // Set the last autoresponse time to the current time yesterday
+ m_lastAutoresponseTime = QDateTime::currentDateTime().addDays(-1);
+
+ QObject::connect( mAccount->engine(), SIGNAL( receivedUserInfo( const QString&, const UserDetails& ) ),
+ this, SLOT( userInfoUpdated( const QString&, const UserDetails& ) ) );
+ QObject::connect( mAccount->engine(), SIGNAL( userIsOffline( const QString& ) ),
+ this, SLOT( userOffline( const QString& ) ) );
+ QObject::connect( mAccount->engine(), SIGNAL( receivedAwayMessage( const QString&, const QString& ) ),
+ this, SLOT( updateAwayMessage( const QString&, const QString& ) ) );
+ QObject::connect( mAccount->engine(), SIGNAL( receivedProfile( const QString&, const QString& ) ),
+ this, SLOT( updateProfile( const QString&, const QString& ) ) );
+ QObject::connect( mAccount->engine(), SIGNAL( userWarned( const QString&, Q_UINT16, Q_UINT16 ) ),
+ this, SLOT( gotWarning( const QString&, Q_UINT16, Q_UINT16 ) ) );
+ QObject::connect( mAccount->engine(), SIGNAL( haveIconForContact( const QString&, QByteArray ) ),
+ this, SLOT( haveIcon( const QString&, QByteArray ) ) );
+ QObject::connect( mAccount->engine(), SIGNAL( iconServerConnected() ),
+ this, SLOT( requestBuddyIcon() ) );
+ QObject::connect( this, SIGNAL( featuresUpdated() ), this, SLOT( updateFeatures() ) );
+}
+
+AIMContact::~AIMContact()
+{
+}
+
+bool AIMContact::isReachable()
+{
+ return true;
+}
+
+QPtrList<KAction> *AIMContact::customContextMenuActions()
+{
+
+ QPtrList<KAction> *actionCollection = new QPtrList<KAction>();
+ if ( !m_warnUserAction )
+ {
+ m_warnUserAction = new KAction( i18n( "&Warn User" ), 0, this, SLOT( warnUser() ), this, "warnAction" );
+ }
+ m_actionVisibleTo = new KToggleAction(i18n("Always &Visible To"), "", 0,
+ this, SLOT(slotVisibleTo()), this, "actionVisibleTo");
+ m_actionInvisibleTo = new KToggleAction(i18n("Always &Invisible To"), "", 0,
+ this, SLOT(slotInvisibleTo()), this, "actionInvisibleTo");
+
+ bool on = account()->isConnected();
+
+ m_warnUserAction->setEnabled( on );
+
+ m_actionVisibleTo->setEnabled(on);
+ m_actionInvisibleTo->setEnabled(on);
+
+ SSIManager* ssi = account()->engine()->ssiManager();
+ m_actionVisibleTo->setChecked( ssi->findItem( m_ssiItem.name(), ROSTER_VISIBLE ));
+ m_actionInvisibleTo->setChecked( ssi->findItem( m_ssiItem.name(), ROSTER_INVISIBLE ));
+
+ actionCollection->append( m_warnUserAction );
+
+ actionCollection->append(m_actionVisibleTo);
+ actionCollection->append(m_actionInvisibleTo);
+
+
+ return actionCollection;
+}
+
+const QString AIMContact::awayMessage()
+{
+ return property(mProtocol->awayMessage).value().toString();
+}
+
+void AIMContact::setAwayMessage(const QString &message)
+{
+ kdDebug(14152) << k_funcinfo <<
+ "Called for '" << contactId() << "', away msg='" << message << "'" << endl;
+ QString filteredMessage = message;
+ filteredMessage.replace(
+ QRegExp(QString::fromLatin1("<[hH][tT][mM][lL].*>(.*)</[hH][tT][mM][lL]>")),
+ QString::fromLatin1("\\1"));
+ filteredMessage.replace(
+ QRegExp(QString::fromLatin1("<[bB][oO][dD][yY].*>(.*)</[bB][oO][dD][yY]>")),
+ QString::fromLatin1("\\1") );
+ QRegExp fontRemover( QString::fromLatin1("<[fF][oO][nN][tT].*>(.*)</[fF][oO][nN][tT]>") );
+ fontRemover.setMinimal(true);
+ while ( filteredMessage.find( fontRemover ) != -1 )
+ filteredMessage.replace( fontRemover, QString::fromLatin1("\\1") );
+ setProperty(mProtocol->awayMessage, filteredMessage);
+}
+
+int AIMContact::warningLevel() const
+{
+ return m_warningLevel;
+}
+
+void AIMContact::updateSSIItem()
+{
+ if ( m_ssiItem.type() != 0xFFFF && m_ssiItem.waitingAuth() == false &&
+ onlineStatus() == Kopete::OnlineStatus::Unknown )
+ {
+ //make sure they're offline
+ setOnlineStatus( static_cast<AIMProtocol*>( protocol() )->statusOffline );
+ }
+}
+
+void AIMContact::slotUserInfo()
+{
+ if ( !m_infoDialog)
+ {
+ m_infoDialog = new AIMUserInfoDialog( this, static_cast<AIMAccount*>( account() ), false, Kopete::UI::Global::mainWidget(), 0 );
+ if( !m_infoDialog )
+ return;
+ connect( m_infoDialog, SIGNAL( finished() ), this, SLOT( closeUserInfoDialog() ) );
+ m_infoDialog->show();
+ if ( mAccount->isConnected() )
+ {
+ mAccount->engine()->requestAIMProfile( contactId() );
+ mAccount->engine()->requestAIMAwayMessage( contactId() );
+ }
+ }
+ else
+ m_infoDialog->raise();
+}
+
+void AIMContact::userInfoUpdated( const QString& contact, const UserDetails& details )
+{
+ if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
+ return;
+
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << contact << endl;
+
+ //if they don't have an SSI alias, make sure we use the capitalization from the
+ //server so their contact id looks all pretty.
+ QString nickname = property( Kopete::Global::Properties::self()->nickName() ).value().toString();
+ if ( nickname.isEmpty() || Oscar::normalize( nickname ) == Oscar::normalize( contact ) )
+ setNickName( contact );
+
+ ( details.userClass() & CLASS_WIRELESS ) ? m_mobile = true : m_mobile = false;
+
+ if ( ( details.userClass() & CLASS_AWAY ) == STATUS_ONLINE )
+ {
+ if ( m_mobile )
+ {
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is mobile-online." << endl;
+ setOnlineStatus( mProtocol->statusWirelessOnline );
+ }
+ else
+ {
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is online." << endl;
+ setOnlineStatus( mProtocol->statusOnline ); //we're online
+ }
+ removeProperty( mProtocol->awayMessage );
+ m_haveAwayMessage = false;
+ }
+ else if ( ( details.userClass() & CLASS_AWAY ) ) // STATUS_AWAY
+ {
+ if ( m_mobile )
+ {
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is mobile-away." << endl;
+ setOnlineStatus( mProtocol->statusWirelessOnline );
+ }
+ else
+ {
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " is away." << endl;
+ setOnlineStatus( mProtocol->statusAway ); //we're away
+ }
+ if ( !m_haveAwayMessage ) //prevent cyclic away message requests
+ {
+ mAccount->engine()->requestAIMAwayMessage( contactId() );
+ m_haveAwayMessage = true;
+ }
+ }
+ else
+ {
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Contact: " << contact << " class " << details.userClass() << " is unhandled... defaulting to away." << endl;
+ setOnlineStatus( mProtocol->statusAway ); //we're away
+ if ( !m_haveAwayMessage ) //prevent cyclic away message requests
+ {
+ mAccount->engine()->requestAIMAwayMessage( contactId() );
+ m_haveAwayMessage = true;
+ }
+ }
+
+ if ( details.buddyIconHash().size() > 0 && details.buddyIconHash() != m_details.buddyIconHash() )
+ {
+ if ( !mAccount->engine()->hasIconConnection() )
+ mAccount->engine()->requestServerRedirect( 0x0010 );
+
+ int time = ( KApplication::random() % 10 ) * 1000;
+ kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "updating buddy icon in " << time/1000 << " seconds" << endl;
+ QTimer::singleShot( time, this, SLOT( requestBuddyIcon() ) );
+ }
+
+ OscarContact::userInfoUpdated( contact, details );
+}
+
+void AIMContact::userOnline( const QString& userId )
+{
+ if ( Oscar::normalize( userId ) == Oscar::normalize( contactId() ) )
+ {
+ kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Getting more contact info" << endl;
+ setOnlineStatus( mProtocol->statusOnline );
+ }
+}
+
+void AIMContact::userOffline( const QString& userId )
+{
+ if ( Oscar::normalize( userId ) == Oscar::normalize( contactId() ) )
+ {
+ setOnlineStatus( mProtocol->statusOffline );
+ removeProperty( mProtocol->awayMessage );
+ }
+}
+
+void AIMContact::updateAwayMessage( const QString& contact, const QString& message )
+{
+ if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
+ return;
+ else
+ {
+ if ( message.isEmpty() )
+ {
+ removeProperty( mProtocol->awayMessage );
+ if ( !m_mobile )
+ setOnlineStatus( mProtocol->statusOnline );
+ else
+ setOnlineStatus( mProtocol->statusWirelessOnline );
+ m_haveAwayMessage = false;
+ }
+ else
+ {
+ m_haveAwayMessage = true;
+ setAwayMessage( message );
+ if ( !m_mobile )
+ setOnlineStatus( mProtocol->statusAway );
+ else
+ setOnlineStatus( mProtocol->statusWirelessAway );
+ }
+ }
+
+ emit updatedProfile();
+}
+
+void AIMContact::updateProfile( const QString& contact, const QString& profile )
+{
+ if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
+ return;
+
+ setProperty( mProtocol->clientProfile, profile );
+ emit updatedProfile();
+}
+
+void AIMContact::gotWarning( const QString& contact, Q_UINT16 increase, Q_UINT16 newLevel )
+{
+ //somebody just got bitchslapped! :O
+ Q_UNUSED( increase );
+ if ( Oscar::normalize( contact ) == Oscar::normalize( contactId() ) )
+ m_warningLevel = newLevel;
+
+ //TODO add a KNotify event after merge to HEAD
+}
+
+void AIMContact::requestBuddyIcon()
+{
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Updating buddy icon for " << contactId() << endl;
+ if ( m_details.buddyIconHash().size() > 0 )
+ {
+ account()->engine()->requestBuddyIcon( contactId(), m_details.buddyIconHash(),
+ m_details.iconCheckSumType() );
+ }
+}
+
+void AIMContact::haveIcon( const QString& user, QByteArray icon )
+{
+ if ( Oscar::normalize( user ) != Oscar::normalize( contactId() ) )
+ return;
+
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Updating icon for " << contactId() << endl;
+ QImage buddyIcon( icon );
+ if ( buddyIcon.isNull() )
+ {
+ kdWarning(OSCAR_AIM_DEBUG) << k_funcinfo << "Failed to convert buddy icon to QImage" << endl;
+ return;
+ }
+
+ setProperty( Kopete::Global::Properties::self()->photo(), buddyIcon );
+}
+
+void AIMContact::closeUserInfoDialog()
+{
+ m_infoDialog->delayedDestruct();
+ m_infoDialog = 0L;
+}
+
+void AIMContact::warnUser()
+{
+ QString nick = property( Kopete::Global::Properties::self()->nickName() ).value().toString();
+ QString message = i18n( "<qt>Would you like to warn %1 anonymously or with your name?<br>" \
+ "(Warning a user on AIM will result in a \"Warning Level\"" \
+ " increasing for the user you warn. Once this level has reached a" \
+ " certain point, they will not be able to sign on. Please do not abuse" \
+ " this function, it is meant for legitimate practices.)</qt>" ).arg( nick );
+
+
+ int result = KMessageBox::questionYesNoCancel( Kopete::UI::Global::mainWidget(), message,
+ i18n( "Warn User %1?" ).arg( nick ),
+ i18n( "Warn Anonymously" ), i18n( "Warn" ) );
+
+ if ( result == KMessageBox::Yes )
+ mAccount->engine()->sendWarning( contactId(), true);
+ else if ( result == KMessageBox::No )
+ mAccount->engine()->sendWarning( contactId(), false);
+}
+
+void AIMContact::slotVisibleTo()
+{
+ account()->engine()->setVisibleTo( contactId(), m_actionVisibleTo->isChecked() );
+}
+
+void AIMContact::slotInvisibleTo()
+{
+ account()->engine()->setInvisibleTo( contactId(), m_actionInvisibleTo->isChecked() );
+}
+
+void AIMContact::slotSendMsg(Kopete::Message& message, Kopete::ChatSession *)
+{
+ Oscar::Message msg;
+ QString s;
+
+ if (message.plainBody().isEmpty()) // no text, do nothing
+ return;
+ //okay, now we need to change the message.escapedBody from real HTML to aimhtml.
+ //looking right now for docs on that "format".
+ //looks like everything except for alignment codes comes in the format of spans
+
+ //font-style:italic -> <i>
+ //font-weight:600 -> <b> (anything > 400 should be <b>, 400 is not bold)
+ //text-decoration:underline -> <u>
+ //font-family: -> <font face="">
+ //font-size:xxpt -> <font ptsize=xx>
+
+ s=message.escapedBody();
+ s.replace ( QRegExp( QString::fromLatin1("<span style=\"([^\"]*)\">([^<]*)</span>")),
+ QString::fromLatin1("<style>\\1;\"\\2</style>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-style:italic;([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<i><style>\\1\\2\"\\3</style></i>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-weight:600;([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<b><style>\\1\\2\"\\3</style></b>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)text-decoration:underline;([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<u><style>\\1\\2\"\\3</style></u>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-family:([^;]*);([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<font face=\"\\2\"><style>\\1\\3\"\\4</style></font>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)font-size:([^p]*)pt;([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<font ptsize=\"\\2\"><style>\\1\\3\"\\4</style></font>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)color:([^;]*);([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("<font color=\"\\2\"><style>\\1\\3\"\\4</style></font>"));
+
+ s.replace ( QRegExp( QString::fromLatin1("<style>([^\"]*)\"([^<]*)</style>")),
+ QString::fromLatin1("\\2"));
+
+ //okay now change the <font ptsize="xx"> to <font size="xx">
+
+ //0-9 are size 1
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"\\d\">")),
+ QString::fromLatin1("<font size=\"1\">"));
+ //10-11 are size 2
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"1[01]\">")),
+ QString::fromLatin1("<font size=\"2\">"));
+ //12-13 are size 3
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"1[23]\">")),
+ QString::fromLatin1("<font size=\"3\">"));
+ //14-16 are size 4
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"1[456]\">")),
+ QString::fromLatin1("<font size=\"4\">"));
+ //17-22 are size 5
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"(?:1[789]|2[012])\">")),
+ QString::fromLatin1("<font size=\"5\">"));
+ //23-29 are size 6
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"2[3456789]\">")),QString::fromLatin1("<font size=\"6\">"));
+ //30- (and any I missed) are size 7
+ s.replace ( QRegExp ( QString::fromLatin1("<font ptsize=\"[^\"]*\">")),QString::fromLatin1("<font size=\"7\">"));
+
+ s.replace ( QRegExp ( QString::fromLatin1("<br[ /]*>")), QString::fromLatin1("<br>") );
+
+ // strip left over line break
+ s.remove( QRegExp( QString::fromLatin1( "<br>$" ) ) );
+
+ kdDebug(14190) << k_funcinfo << "sending "
+ << s << endl;
+
+ // XXX Need to check for message size?
+
+ if ( m_details.hasCap( CAP_UTF8 ) )
+ msg.setText( Oscar::Message::UCS2, s );
+ else
+ msg.setText( Oscar::Message::UserDefined, s, contactCodec() );
+
+ msg.setReceiver(mName);
+ msg.setTimestamp(message.timestamp());
+ msg.setType(0x01);
+
+ mAccount->engine()->sendMessage(msg);
+
+ // Show the message we just sent in the chat window
+ manager(Kopete::Contact::CanCreate)->appendMessage(message);
+ manager(Kopete::Contact::CanCreate)->messageSucceeded();
+}
+
+void AIMContact::updateFeatures()
+{
+ setProperty( static_cast<AIMProtocol*>(protocol())->clientFeatures, m_clientFeatures );
+}
+
+void AIMContact::sendAutoResponse(Kopete::Message& msg)
+{
+ // The target time is 2 minutes later than the last message
+ int delta = m_lastAutoresponseTime.secsTo( QDateTime::currentDateTime() );
+ kdDebug(14152) << k_funcinfo << "Last autoresponse time: " << m_lastAutoresponseTime << endl;
+ kdDebug(14152) << k_funcinfo << "Current time: " << QDateTime::currentDateTime() << endl;
+ kdDebug(14152) << k_funcinfo << "Difference: " << delta << endl;
+ // Check to see if we're past that time
+ if(delta > 120)
+ {
+ kdDebug(14152) << k_funcinfo << "Sending auto response" << endl;
+
+ // This code was yoinked straight from OscarContact::slotSendMsg()
+ // If only that slot wasn't private, but I'm not gonna change it right now.
+ Oscar::Message message;
+
+ if ( m_details.hasCap( CAP_UTF8 ) )
+ {
+ message.setText( Oscar::Message::UCS2, msg.plainBody() );
+ }
+ else
+ {
+ QTextCodec* codec = contactCodec();
+ message.setText( Oscar::Message::UserDefined, msg.plainBody(), codec );
+ }
+
+ message.setTimestamp( msg.timestamp() );
+ message.setSender( mAccount->accountId() );
+ message.setReceiver( mName );
+ message.setType( 0x01 );
+
+ // isAuto defaults to false
+ mAccount->engine()->sendMessage( message, true);
+ kdDebug(14152) << k_funcinfo << "Sent auto response" << endl;
+ manager(Kopete::Contact::CanCreate)->appendMessage(msg);
+ manager(Kopete::Contact::CanCreate)->messageSucceeded();
+ // Update the last autoresponse time
+ m_lastAutoresponseTime = QDateTime::currentDateTime();
+ }
+ else
+ {
+ kdDebug(14152) << k_funcinfo << "Not enough time since last autoresponse, NOT sending" << endl;
+ }
+}
+#include "aimcontact.moc"
+//kate: tab-width 4; indent-mode csands;
diff --git a/kopete/protocols/oscar/aim/aimcontact.h b/kopete/protocols/oscar/aim/aimcontact.h
new file mode 100644
index 00000000..458db2f5
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimcontact.h
@@ -0,0 +1,102 @@
+/*
+ aimcontact.h - Oscar Protocol Plugin
+
+ Copyright (c) 2003 by Will Stephenson
+ Copyright (c) 2004 by Matt Rogers <mattr@kde.org>
+ Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ *************************************************************************
+*/
+
+#ifndef AIMCONTACT_H
+#define AIMCONTACT_H
+
+#include <qdatetime.h>
+
+#include "oscarcontact.h"
+
+
+namespace Kopete
+{
+class ChatSession;
+}
+
+class AIMAccount;
+class AIMProtocol;
+class AIMUserInfoDialog;
+
+class AIMContact : public OscarContact
+{
+Q_OBJECT
+
+public:
+ AIMContact( Kopete::Account*, const QString&, Kopete::MetaContact*,
+ const QString& icon = QString::null, const Oscar::SSI& ssiItem = Oscar::SSI() );
+ virtual ~AIMContact();
+
+ bool isReachable();
+ QPtrList<KAction> *customContextMenuActions();
+
+ const QString &userProfile() { return mUserProfile; }
+
+ virtual const QString awayMessage();
+ virtual void setAwayMessage( const QString &message );
+
+ int warningLevel() const;
+
+ /**
+ * Gets the last time an autoresponse was sent to this contact
+ * @returns QDateTime Object that represents the date/time
+ */
+ QDateTime lastAutoResponseTime() {return m_lastAutoresponseTime;}
+
+ /** Sends an auto response to this contact */
+ virtual void sendAutoResponse(Kopete::Message& msg);
+
+public slots:
+ void updateSSIItem();
+ void slotUserInfo();
+ void userInfoUpdated( const QString& contact, const UserDetails& details );
+ void userOnline( const QString& userId );
+ void userOffline( const QString& userId );
+ void updateAwayMessage( const QString& userId, const QString& message );
+ void updateProfile( const QString& contact, const QString& profile );
+ void gotWarning( const QString& contact, Q_UINT16, Q_UINT16 );
+
+signals:
+ void updatedProfile();
+
+protected slots:
+ virtual void slotSendMsg(Kopete::Message& message, Kopete::ChatSession *);
+ virtual void updateFeatures();
+
+private slots:
+ void requestBuddyIcon();
+ void haveIcon( const QString&, QByteArray );
+ void closeUserInfoDialog();
+ void warnUser();
+
+ void slotVisibleTo();
+ void slotInvisibleTo();
+
+private:
+ AIMProtocol* mProtocol;
+ AIMUserInfoDialog* m_infoDialog;
+ QString mUserProfile;
+ bool m_haveAwayMessage;
+ bool m_mobile; // Is this user mobile (i.e. do they have message forwarding on, or mobile AIM)
+ QDateTime m_lastAutoresponseTime;
+
+ KAction* m_warnUserAction;
+ KToggleAction *m_actionVisibleTo;
+ KToggleAction *m_actionInvisibleTo;
+};
+#endif
+//kate: tab-width 4; indent-mode csands;
diff --git a/kopete/protocols/oscar/aim/aimjoinchat.cpp b/kopete/protocols/oscar/aim/aimjoinchat.cpp
new file mode 100644
index 00000000..8b8c78a9
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimjoinchat.cpp
@@ -0,0 +1,94 @@
+// aimjoinchat.cpp
+
+// Copyright (C) 2005 Matt Rogers <mattr@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 as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301 USA
+
+#include "aimjoinchat.h"
+
+#include <qlineedit.h>
+#include <qcombobox.h>
+#include <klocale.h>
+
+#include "aimjoinchatbase.h"
+#include "aimaccount.h"
+
+AIMJoinChatUI::AIMJoinChatUI( AIMAccount* account, bool modal,
+ QWidget* parent, const char* name )
+ : KDialogBase( parent, name, modal, i18n( "Join AIM Chat Room" ),
+ Cancel | User1, User1, true, i18n( "Join" ) )
+{
+
+ kdDebug(OSCAR_AIM_DEBUG) << k_funcinfo << "Account " << account->accountId()
+ << " joining a chat room" << endl;
+
+ m_account = account;
+
+ m_joinUI = new AIMJoinChatBase( this, "aimjoinchatbase" );
+
+ setMainWidget( m_joinUI );
+
+ QObject::connect( this, SIGNAL( user1Clicked() ), this, SLOT( joinChat() ) );
+ QObject::connect( this, SIGNAL( cancelClicked() ), this, SLOT( closeClicked() ) );
+}
+
+AIMJoinChatUI::~AIMJoinChatUI()
+{
+ m_exchanges.clear();
+}
+
+void AIMJoinChatUI::setExchangeList( const QValueList<int>& list )
+{
+ m_exchanges = list;
+ QStringList exchangeList;
+ QValueList<int>::const_iterator it = list.begin();
+ while ( it != list.end() )
+ {
+ exchangeList.append( QString::number( ( *it ) ) );
+ ++it;
+ }
+
+
+ m_joinUI->exchange->insertStringList( exchangeList );
+}
+
+void AIMJoinChatUI::joinChat()
+{
+ m_roomName = m_joinUI->roomName->text();
+ int item = m_joinUI->exchange->currentItem();
+ m_exchange = m_joinUI->exchange->text( item );
+
+ emit closing( QDialog::Accepted );
+}
+
+void AIMJoinChatUI::closeClicked()
+{
+ //hmm, do nothing?
+ emit closing( QDialog::Rejected );
+}
+
+QString AIMJoinChatUI::roomName() const
+{
+ return m_roomName;
+}
+
+QString AIMJoinChatUI::exchange() const
+{
+ return m_exchange;
+}
+
+#include "aimjoinchat.moc"
+//kate: space-indent on; indent-width 4;
diff --git a/kopete/protocols/oscar/aim/aimjoinchat.h b/kopete/protocols/oscar/aim/aimjoinchat.h
new file mode 100644
index 00000000..dc74a8a9
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimjoinchat.h
@@ -0,0 +1,62 @@
+// aimjoinchat.h
+
+// Copyright (C) 2005 Matt Rogers <mattr@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 as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+// 02110-1301 USA
+
+#ifndef AIMJOINCHAT_H
+#define AIMJOINCHAT_H
+
+#include <kdialogbase.h>
+
+#include "oscartypes.h"
+
+class AIMAccount;
+class AIMJoinChatBase;
+
+class AIMJoinChatUI : public KDialogBase
+{
+Q_OBJECT
+public:
+ AIMJoinChatUI( AIMAccount*, bool modal, QWidget* parent = 0,
+ const char* name = 0 );
+ ~AIMJoinChatUI();
+
+ void setExchangeList( const QValueList<int>& );
+ QValueList<int> exchangeList() const;
+
+ QString roomName() const;
+ QString exchange() const;
+
+
+protected slots:
+ void joinChat();
+ void closeClicked();
+
+signals:
+ void closing( int );
+
+private:
+ AIMJoinChatBase* m_joinUI;
+ AIMAccount* m_account;
+ QValueList<int> m_exchanges;
+ QString m_roomName;
+ QString m_exchange;
+
+};
+
+#endif
+//kate: space-indent on; indent-width 4;
diff --git a/kopete/protocols/oscar/aim/aimprotocol.cpp b/kopete/protocols/oscar/aim/aimprotocol.cpp
new file mode 100644
index 00000000..9f64fe28
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimprotocol.cpp
@@ -0,0 +1,320 @@
+/*
+ oscarprotocol.cpp - Oscar Protocol Plugin
+
+ Copyright (c) 2002 by Tom Linsky <twl6@po.cwru.edu>
+
+ Kopete (c) 2002-2003 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ *************************************************************************
+ */
+
+#include <qstringlist.h>
+#include <kgenericfactory.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+
+#include "aimprotocol.h"
+#include "aimaccount.h"
+#include "aimcontact.h"
+#include "aimaddcontactpage.h"
+#include "aimeditaccountwidget.h"
+
+#include "accountselector.h"
+#include "kopeteaccountmanager.h"
+#include "kopeteonlinestatusmanager.h"
+#include "kopeteglobal.h"
+#include "kopeteuiglobal.h"
+#include "kopetemetacontact.h"
+
+#include <kdialogbase.h>
+#include <kmessagebox.h>
+#include <kimageio.h>
+
+typedef KGenericFactory<AIMProtocol> AIMProtocolFactory;
+
+K_EXPORT_COMPONENT_FACTORY( kopete_aim, AIMProtocolFactory( "kopete_aim" ) )
+
+AIMProtocol* AIMProtocol::protocolStatic_ = 0L;
+
+
+AIMProtocolHandler::AIMProtocolHandler() : Kopete::MimeTypeHandler(false)
+{
+ registerAsProtocolHandler(QString::fromLatin1("aim"));
+}
+
+void AIMProtocolHandler::handleURL(const KURL &url) const
+{
+/**
+ * Send a Message =================================================
+ * aim:goim
+ * aim:goim?screenname=screen+name
+ * aim:goim?screenname=screen+name&message=message
+ * Add Buddy ======================================================
+ * aim:addbuddy
+ * aim:addbuddy?screenname=screen+name
+ * Buddy Icon =====================================================
+ * aim:buddyicon
+ * aim:buddyicon?src=image_source
+ * aim:buddyicon?screename=screen+name
+ * aim:buddyicon?src=image_source&screename=screen+name
+ * Get and Send Files =============================================
+ * aim:getfile?screename=(sn)
+ * aim:sendfile?screenname=(sn)
+ * Register User ==================================================
+ * aim:RegisterUser?ScreenName=sn&Password=pw&SignonNow=False
+ * Away Message ===================================================
+ * aim:goaway?message=brb+or+something
+ * Chat Rooms =====================================================
+ * aim:GoChat?RoomName=room+name&Exchange=number
+ **/
+
+ AIMProtocol *proto = AIMProtocol::protocol();
+ kdDebug(14152) << k_funcinfo << "URL url : '" << url.url() << "'" << endl;
+ kdDebug(14152) << k_funcinfo << "URL path : '" << url.path() << "'" << endl;
+ QString command = url.path();
+ QString realCommand, firstParam, secondParam;
+ bool needContactAddition = false;
+ if ( command.find( "goim", 0, false ) != -1 )
+ {
+ realCommand = "goim";
+ kdDebug(14152) << k_funcinfo << "Handling send IM request" << endl;
+ command.remove(0,4);
+ if ( command.find( "?screenname=", 0, false ) == -1 )
+ {
+ kdWarning(14152) << k_funcinfo << "Unhandled AIM URI:" << url.url() << endl;
+ return;
+ }
+ command.remove( 0, 12 );
+ int andSign = command.find( "&" );
+ if ( andSign > 0 )
+ command = command.left( andSign );
+
+ firstParam = command;
+ firstParam.replace( "+", " " );
+ needContactAddition = true;
+ }
+ else
+ if ( command.find( "addbuddy", 0, false ) != -1 )
+ {
+ realCommand = "addbuddy";
+ kdDebug(14152) << k_funcinfo << "Handling AIM add buddy request" << endl;
+ command.remove( 0, 8 );
+ if ( command.find( "?screenname=", 0, false ) == -1 )
+ {
+ kdWarning(14152) << k_funcinfo << "Unhandled AIM URI:" << url.url() << endl;
+ return;
+ }
+
+ command.remove(0, 12);
+ int andSign = command.find("&");
+ if ( andSign > 0 )
+ command = command.left(andSign);
+ command.replace("+", " ");
+
+ firstParam = command;
+ needContactAddition = true;
+ }
+ else
+ if ( command.find( "gochat", 0, false ) != -1 )
+ {
+ realCommand = "gochat";
+ kdDebug(14152) << k_funcinfo << "Handling AIM chat room request" << endl;
+ command.remove( 0, 6 );
+
+ if ( command.find( "?RoomName=", 0, false ) == -1 )
+ {
+ kdWarning(14152) << "Unhandled AIM URI: " << url.url() << endl;
+ return;
+ }
+
+ command.remove( 0, 10 );
+
+ int andSign = command.find("&");
+ if (andSign > 0) // strip off anything else for now
+ {
+ firstParam = command.left(andSign);
+ }
+ command.remove( 0, andSign );
+ kdDebug(14152) << "command is now: " << command << endl;
+ command.remove( 0, 10 ); //remove "&Exchange="
+ secondParam = command;
+ kdDebug(14152) << k_funcinfo << firstParam << " " << secondParam << endl;
+ firstParam.replace("+", " ");
+ }
+
+ Kopete::Account *account = 0;
+ QDict<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts(proto);
+
+ if (accounts.count() == 1)
+ {
+ QDictIterator<Kopete::Account> it(accounts);
+ account = it.current();
+
+ }
+ else
+ {
+ KDialogBase *chooser = new KDialogBase(0, "chooser", true,
+ i18n("Choose Account"), KDialogBase::Ok|KDialogBase::Cancel,
+ KDialogBase::Ok, false);
+ AccountSelector *accSelector = new AccountSelector(proto, chooser, "accSelector");
+ chooser->setMainWidget(accSelector);
+
+ int ret = chooser->exec();
+ account = accSelector->selectedItem();
+
+ delete chooser;
+ if (ret == QDialog::Rejected || account == 0)
+ {
+ kdDebug(14152) << k_funcinfo << "Cancelled" << endl;
+ return;
+ }
+ }
+
+ Kopete::MetaContact* mc = 0;
+ if ( needContactAddition || realCommand == "addbuddy" )
+ {
+ if ( !account->isConnected() )
+ {
+ kdDebug(14152) << k_funcinfo << "Can't add contact, we are offline!" << endl;
+ KMessageBox::sorry( Kopete::UI::Global::mainWidget(), i18n("You need to be connected to be able to add contacts."),
+ i18n("AIM") );
+ return;
+ }
+
+ if (KMessageBox::questionYesNo(Kopete::UI::Global::mainWidget(),
+ i18n("Do you want to add '%1' to your contact list?").arg(command),
+ QString::null, i18n("Add"), i18n("Do Not Add"))
+ != KMessageBox::Yes)
+ {
+ kdDebug(14152) << k_funcinfo << "Cancelled" << endl;
+ return;
+ }
+
+ kdDebug(14152) << k_funcinfo <<
+ "Adding Contact; screenname = " << firstParam << endl;
+ mc = account->addContact(firstParam, command, 0L, Kopete::Account::Temporary);
+ }
+
+ if ( realCommand == "gochat" )
+ {
+ AIMAccount* aimAccount = dynamic_cast<AIMAccount*>( account );
+ if ( aimAccount && aimAccount->isConnected() )
+ {
+ aimAccount->engine()->joinChatRoom( firstParam, secondParam.toInt() );
+ }
+ else
+ KMessageBox::sorry( Kopete::UI::Global::mainWidget(),
+ i18n( "Unable to connect to the chat room %1 because the account"
+ " for %2 is not connected." ).arg( firstParam ).arg( aimAccount->accountId() ),
+ QString::null );
+
+ }
+
+ if ( mc && realCommand == "goim" )
+ {
+ mc->execute();
+ }
+
+}
+
+
+
+
+AIMProtocol::AIMProtocol(QObject *parent, const char *name, const QStringList &)
+ : Kopete::Protocol( AIMProtocolFactory::instance(), parent, name ),
+ statusOnline( Kopete::OnlineStatus::Online, 2, this, 0, QString::null, i18n("Online"), i18n("Online"), Kopete::OnlineStatusManager::Online ),
+ statusOffline( Kopete::OnlineStatus::Offline, 2, this, 10, QString::null, i18n("Offline"), i18n("Offline"), Kopete::OnlineStatusManager::Offline ),
+ statusAway( Kopete::OnlineStatus::Away, 2, this, 20, "contact_away_overlay", i18n("Away"), i18n("Away"), Kopete::OnlineStatusManager::Away,
+ Kopete::OnlineStatusManager::HasAwayMessage ),
+ statusWirelessOnline( Kopete::OnlineStatus::Online, 1, this, 30, "contact_phone_overlay", i18n("Mobile"), i18n("Mobile"),
+ Kopete::OnlineStatusManager::Online, Kopete::OnlineStatusManager::HideFromMenu ),
+ statusWirelessAway( Kopete::OnlineStatus::Away, 1, this, 31, QStringList::split( " ", "contact_phone_overlay contact_away_overlay"),
+ i18n("Mobile Away"), i18n("Mobile Away"), Kopete::OnlineStatusManager::Away, Kopete::OnlineStatusManager::HideFromMenu ),
+ statusConnecting(Kopete::OnlineStatus::Connecting, 99, this, 99, "aim_connecting", i18n("Connecting...")),
+ awayMessage(Kopete::Global::Properties::self()->awayMessage()),
+ clientFeatures("clientFeatures", i18n("Client Features"), 0, false),
+ clientProfile( "clientProfile", i18n( "User Profile"), 0, false, true),
+ iconHash("iconHash", i18n("Buddy Icon MD5 Hash"), QString::null, true, false, true)
+{
+ if (protocolStatic_)
+ kdDebug(14152) << k_funcinfo << "AIM plugin already initialized" << endl;
+ else
+ protocolStatic_ = this;
+
+ setCapabilities(0x1FFF); // setting capabilities - FIXME to use proper enum
+ kdDebug(14152) << k_funcinfo << "capabilities set to 0x1FFF" << endl;
+ addAddressBookField("messaging/aim", Kopete::Plugin::MakeIndexField);
+ KImageIO::registerFormats();
+}
+
+AIMProtocol::~AIMProtocol()
+{
+ protocolStatic_ =0L;
+}
+
+AIMProtocol *AIMProtocol::protocol(void)
+{
+ return protocolStatic_;
+}
+
+Kopete::Contact *AIMProtocol::deserializeContact(Kopete::MetaContact *metaContact,
+ const QMap<QString, QString> &serializedData,
+ const QMap<QString, QString> &/*addressBookData*/)
+{
+
+ QString contactId = serializedData["contactId"];
+ QString accountId = serializedData["accountId"];
+ QString displayName = serializedData["displayName"];
+
+ // Get the account it belongs to
+ QDict<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts( this );
+ Kopete::Account *account = accounts[accountId];
+
+ if ( !account ) //no account
+ return 0;
+
+ uint ssiGid = 0, ssiBid = 0, ssiType = 0xFFFF;
+ QString ssiName;
+ bool ssiWaitingAuth = false;
+ if ( serializedData.contains( "ssi_type" ) )
+ {
+ ssiName = serializedData["ssi_name"];
+ QString authStatus = serializedData["ssi_waitingAuth"];
+ if ( authStatus == "true" )
+ ssiWaitingAuth = true;
+ ssiGid = serializedData["ssi_gid"].toUInt();
+ ssiBid = serializedData["ssi_bid"].toUInt();
+ ssiType = serializedData["ssi_type"].toUInt();
+ }
+
+ Oscar::SSI item( ssiName, ssiGid, ssiBid, ssiType, QValueList<TLV>(), 0 );
+ item.setWaitingAuth( ssiWaitingAuth );
+
+ AIMContact *c = new AIMContact( account, contactId, metaContact, QString::null, item );
+ return c;
+}
+
+AddContactPage *AIMProtocol::createAddContactWidget(QWidget *parent, Kopete::Account *account)
+{
+ return ( new AIMAddContactPage( account->isConnected(), parent ) );
+}
+
+KopeteEditAccountWidget *AIMProtocol::createEditAccountWidget(Kopete::Account *account, QWidget *parent)
+{
+ return ( new AIMEditAccountWidget( this, account, parent ) );
+}
+
+Kopete::Account *AIMProtocol::createNewAccount(const QString &accountId)
+{
+ return ( new AIMAccount( this, accountId ) );
+}
+
+#include "aimprotocol.moc"
+// vim: set noet ts=4 sts=4 sw=4:
diff --git a/kopete/protocols/oscar/aim/aimprotocol.h b/kopete/protocols/oscar/aim/aimprotocol.h
new file mode 100644
index 00000000..e6c578e6
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimprotocol.h
@@ -0,0 +1,85 @@
+/*
+ oscarprotocol.h - Oscar Protocol Plugin
+
+ Copyright (c) 2002 by Tom Linsky <twl6@po.cwru.edu>
+ Copyright (c) 2005 by Matt Rogers <mattr@kde.org>
+ Kopete (c) 2002 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef AIMPROTOCOL_H
+#define AIMPROTOCOL_H
+
+#include "kopeteprotocol.h"
+#include "kopetecontactproperty.h"
+#include "kopetemimetypehandler.h"
+#include "kopeteonlinestatus.h"
+
+#include <qmap.h>
+
+namespace Kopete
+{
+class OnlineStatus;
+}
+
+class AIMProtocolHandler : public Kopete::MimeTypeHandler
+{
+public:
+ AIMProtocolHandler();
+ void handleURL( const KURL & url ) const;
+};
+
+class AIMProtocol : public Kopete::Protocol
+{
+ Q_OBJECT
+
+public:
+ AIMProtocol( QObject *parent, const char *name, const QStringList &args );
+ virtual ~AIMProtocol();
+ /**
+ * Return the active instance of the protocol
+ * because it's a singleton, can only be used inside AIM classes, not in oscar lib
+ */
+ static AIMProtocol *protocol();
+
+ bool canSendOffline() const { return false; }
+
+ virtual Kopete::Contact *deserializeContact( Kopete::MetaContact *metaContact,
+ const QMap<QString, QString> &serializedData,
+ const QMap<QString, QString> &addressBookData );
+
+ AddContactPage*createAddContactWidget( QWidget *parent, Kopete::Account *account );
+ KopeteEditAccountWidget* createEditAccountWidget( Kopete::Account *account, QWidget *parent );
+ Kopete::Account* createNewAccount( const QString &accountId );
+
+ /**
+ * The set of online statuses that AIM contacts can have
+ */
+ const Kopete::OnlineStatus statusOnline;
+ const Kopete::OnlineStatus statusOffline;
+ const Kopete::OnlineStatus statusAway;
+ const Kopete::OnlineStatus statusWirelessOnline;
+ const Kopete::OnlineStatus statusWirelessAway;
+ const Kopete::OnlineStatus statusConnecting;
+
+ const Kopete::ContactPropertyTmpl awayMessage;
+ const Kopete::ContactPropertyTmpl clientFeatures;
+ const Kopete::ContactPropertyTmpl clientProfile;
+ const Kopete::ContactPropertyTmpl iconHash;
+
+private:
+ /** The active instance of oscarprotocol */
+ static AIMProtocol *protocolStatic_;
+ AIMProtocolHandler protohandler;
+};
+
+#endif
+//kate: tab-width 4; indent-mode csands;
diff --git a/kopete/protocols/oscar/aim/aimuserinfo.cpp b/kopete/protocols/oscar/aim/aimuserinfo.cpp
new file mode 100644
index 00000000..81bdd9c7
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimuserinfo.cpp
@@ -0,0 +1,224 @@
+/*
+ oscaruserinfo.cpp - Oscar Protocol Plugin
+
+ Copyright (c) 2002 by Tom Linsky <twl6@po.cwru.edu>
+
+ Kopete (c) 2002 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ *************************************************************************
+ */
+
+#include "aimuserinfo.h"
+
+#include "aimaccount.h"
+#include "aimcontact.h"
+#include "aimprotocol.h"
+
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qtimer.h>
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <ktextbrowser.h>
+#include <kdebug.h>
+#include <kapplication.h>
+
+#include <ktextedit.h>
+#include <krun.h>
+
+AIMUserInfoDialog::AIMUserInfoDialog( Kopete::Contact *c, AIMAccount *acc, bool modal,
+ QWidget *parent, const char* name )
+ : KDialogBase( parent, name, modal, i18n( "User Information on %1" )
+ .arg( c->property( Kopete::Global::Properties::self()->nickName() ).value().toString() ),
+ Cancel | Ok , Ok, true )
+{
+ kdDebug(14200) << k_funcinfo << "for contact '" << c->contactId() << "'" << endl;
+
+ m_contact = c;
+ mAccount = acc;
+
+ mMainWidget = new AIMUserInfoWidget(this, "aimuserinfowidget");
+ setMainWidget(mMainWidget);
+
+ QObject::connect(this, SIGNAL(okClicked()), this, SLOT(slotSaveClicked()));
+ QObject::connect(this, SIGNAL(user1Clicked()), this, SLOT(slotUpdateClicked()));
+ QObject::connect(this, SIGNAL(cancelClicked()), this, SLOT(slotCloseClicked()));
+ QObject::connect(c, SIGNAL(updatedProfile()), this, SLOT(slotUpdateProfile()));
+
+ mMainWidget->txtScreenName->setText( c->contactId() );
+
+ QString nickName = c->property( Kopete::Global::Properties::self()->nickName() ).value().toString();
+ if( nickName.isEmpty() )
+ mMainWidget->txtNickName->setText( c->contactId() );
+ else
+ mMainWidget->txtNickName->setText( nickName );
+
+ if(m_contact == mAccount->myself()) // edit own account profile
+ {
+ mMainWidget->lblWarnLevel->hide();
+ mMainWidget->txtWarnLevel->hide();
+ mMainWidget->lblIdleTime->hide();
+ mMainWidget->txtIdleTime->hide();
+ mMainWidget->lblOnlineSince->hide();
+ mMainWidget->txtOnlineSince->hide();
+ mMainWidget->txtAwayMessage->hide();
+ mMainWidget->lblAwayMessage->hide();
+
+ userInfoView=0L;
+ mMainWidget->userInfoFrame->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
+ QVBoxLayout *l = new QVBoxLayout(mMainWidget->userInfoFrame);
+ userInfoEdit = new KTextEdit(QString::null, QString::null,
+ mMainWidget->userInfoFrame, "userInfoEdit");
+ userInfoEdit->setTextFormat(PlainText);
+
+ AIMMyselfContact* aimmc = dynamic_cast<AIMMyselfContact*>( c );
+ if ( aimmc )
+ userInfoEdit->setText( aimmc->userProfile() );
+ else
+ userInfoEdit->setText( QString::null );
+
+ setButtonText(Ok, i18n("&Save Profile"));
+ showButton(User1, false);
+ l->addWidget(userInfoEdit);
+ }
+ else
+ {
+ userInfoEdit=0L;
+ mMainWidget->userInfoFrame->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
+ QVBoxLayout *l = new QVBoxLayout(mMainWidget->userInfoFrame);
+ userInfoView = new KTextBrowser(mMainWidget->userInfoFrame, "userInfoView");
+ userInfoView->setTextFormat(AutoText);
+ userInfoView->setNotifyClick(true);
+ QObject::connect(
+ userInfoView, SIGNAL(urlClick(const QString&)),
+ this, SLOT(slotUrlClicked(const QString&)));
+ QObject::connect(
+ userInfoView, SIGNAL(mailClick(const QString&, const QString&)),
+ this, SLOT(slotMailClicked(const QString&, const QString&)));
+ showButton(Cancel, false);
+ setButtonText(Ok, i18n("&Close"));
+ setEscapeButton(Ok);
+ l->addWidget(userInfoView);
+
+ if(m_contact->isOnline())
+ {
+ // Update the user view to indicate that we're requesting the user's profile
+ userInfoView->setText(i18n("Requesting User Profile, please wait..."));
+ }
+ QTimer::singleShot(0, this, SLOT(slotUpdateProfile()));
+ }
+}
+
+AIMUserInfoDialog::~AIMUserInfoDialog()
+{
+ kdDebug(14200) << k_funcinfo << "Called." << endl;
+}
+
+void AIMUserInfoDialog::slotUpdateClicked()
+{
+ kdDebug(14200) << k_funcinfo << "Called." << endl;
+ QString newNick = mMainWidget->txtNickName->text();
+ QString currentNick = m_contact->property( Kopete::Global::Properties::self()->nickName() ).value().toString();
+ if ( !newNick.isEmpty() && ( newNick != currentNick ) )
+ {
+ //m_contact->rename(newNick);
+ //emit updateNickname(newNick);
+ setCaption(i18n("User Information on %1").arg(newNick));
+ }
+
+}
+
+void AIMUserInfoDialog::slotSaveClicked()
+{
+ kdDebug(14200) << k_funcinfo << "Called." << endl;
+
+ if (userInfoEdit)
+ { // editable mode, set profile
+ QString newNick = mMainWidget->txtNickName->text();
+ QString currentNick = m_contact->property( Kopete::Global::Properties::self()->nickName() ).value().toString();
+ if(!newNick.isEmpty() && ( newNick != currentNick ) )
+ {
+ //m_contact->rename(newNick);
+ //emit updateNickname(newNick);
+ setCaption(i18n("User Information on %1").arg(newNick));
+ }
+
+ mAccount->setUserProfile(userInfoEdit->text());
+ }
+
+ emit closing();
+}
+
+void AIMUserInfoDialog::slotCloseClicked()
+{
+ kdDebug(14200) << k_funcinfo << "Called." << endl;
+ emit closing();
+}
+
+void AIMUserInfoDialog::slotUpdateProfile()
+{
+ kdDebug(14152) << k_funcinfo << "Got User Profile." << endl;
+ AIMProtocol* p = static_cast<AIMProtocol*>( mAccount->protocol() );
+ QString awayMessage = m_contact->property( p->awayMessage ).value().toString();
+ mMainWidget->txtAwayMessage->setText( awayMessage );
+
+ if ( awayMessage.isNull() )
+ {
+ mMainWidget->txtAwayMessage->hide();
+ mMainWidget->lblAwayMessage->hide();
+ }
+ else
+ {
+ mMainWidget->txtAwayMessage->show();
+ mMainWidget->lblAwayMessage->show();
+ }
+
+ QString onlineSince = m_contact->property("onlineSince").value().toString();
+ //QString onlineSince = m_details.onlineSinceTime().toString();
+ mMainWidget->txtOnlineSince->setText( onlineSince );
+
+ AIMContact* c = static_cast<AIMContact*>( m_contact );
+ mMainWidget->txtIdleTime->setText(c->formattedIdleTime());
+ mMainWidget->txtWarnLevel->setText(QString::number(c->warningLevel()));
+
+ QString contactProfile = m_contact->property( p->clientProfile ).value().toString();
+ if ( contactProfile.isNull() )
+ {
+ contactProfile =
+ i18n("<html><body><I>No user information provided</I></body></html>");
+ }
+
+ if(userInfoEdit)
+ {
+ userInfoEdit->setText(contactProfile);
+ }
+ else if(userInfoView)
+ {
+ userInfoView->setText(contactProfile);
+ }
+
+}
+
+void AIMUserInfoDialog::slotUrlClicked(const QString &url)
+{
+ new KRun(KURL(url));
+}
+
+void AIMUserInfoDialog::slotMailClicked(const QString&, const QString &address)
+{
+ new KRun(KURL(address));
+}
+
+#include "aimuserinfo.moc"
+
+//kate: indent-mode csands; tab-width 4; space-indent off; replace-tabs off;
diff --git a/kopete/protocols/oscar/aim/aimuserinfo.h b/kopete/protocols/oscar/aim/aimuserinfo.h
new file mode 100644
index 00000000..f128610f
--- /dev/null
+++ b/kopete/protocols/oscar/aim/aimuserinfo.h
@@ -0,0 +1,59 @@
+/*
+ oscaruserinfo.h - Oscar Protocol Plugin
+
+ Copyright (c) 2002 by Tom Linsky <twl6@po.cwru.edu>
+
+ Kopete (c) 2002 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ *************************************************************************
+*/
+
+#ifndef AIMUSERINFO_H
+#define AIMUSERINFO_H
+
+#include <kdialogbase.h>
+#include "aiminfobase.h"
+
+namespace Kopete { class Contact; }
+class KTextEdit;
+class OscarAccount;
+class AIMMyselfContact;
+class AIMAccount;
+
+class AIMUserInfoDialog : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ AIMUserInfoDialog(Kopete::Contact *c, AIMAccount *acc, bool modal,
+ QWidget *parent, const char* name);
+ ~AIMUserInfoDialog();
+
+ private:
+ AIMAccount *mAccount;
+ Kopete::Contact* m_contact;
+ AIMUserInfoWidget *mMainWidget;
+ KTextBrowser *userInfoView;
+ KTextEdit *userInfoEdit;
+
+ private slots:
+ void slotSaveClicked();
+ void slotCloseClicked();
+ void slotUpdateClicked();
+ void slotUpdateProfile();
+ void slotUrlClicked(const QString&);
+ void slotMailClicked(const QString&, const QString&);
+
+ signals:
+// void updateNickname(const QString &);
+ void closing();
+};
+
+#endif
+
diff --git a/kopete/protocols/oscar/aim/kopete_aim.desktop b/kopete/protocols/oscar/aim/kopete_aim.desktop
new file mode 100644
index 00000000..0ab4fe69
--- /dev/null
+++ b/kopete/protocols/oscar/aim/kopete_aim.desktop
@@ -0,0 +1,77 @@
+[Desktop Entry]
+Type=Service
+X-Kopete-Version=1000900
+Icon=aim_protocol
+ServiceTypes=Kopete/Protocol
+X-KDE-Library=kopete_aim
+X-Kopete-Messaging-Protocol=messaging/aim
+X-KDE-PluginInfo-Author=Kopete Developers
+X-KDE-PluginInfo-Email=kopete-devel@kde.org
+X-KDE-PluginInfo-Name=kopete_aim
+X-KDE-PluginInfo-Version=0.10.0
+X-KDE-PluginInfo-Website=http://kopete.kde.org
+X-KDE-PluginInfo-Category=Protocols
+X-KDE-PluginInfo-Depends=
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=false
+Name=AIM
+Name[bn]=এ-আই-এম
+Name[hi]=एआरईएम
+Name[ne]=एआईएम
+Comment=Protocol to connect to AIM
+Comment[ar]=البرتوكول سيتصل بـ AIM
+Comment[be]=Пратакол AIM
+Comment[bg]=Протокол за връзка с AIM
+Comment[bn]=এ-আই-এমতে সংযোগ করতে প্রোটোকল
+Comment[br]=Komenad kevreañ ouzh AIM
+Comment[bs]=AIM protokol
+Comment[ca]=Protocol per a connectar-se a AIM
+Comment[cs]=Protokol k připojení k AIM
+Comment[cy]=Protocol i gysylltu ag AIM
+Comment[da]=Protokol til at forbinde til AIM
+Comment[de]=Protokoll zur Verbindung mit dem AIM
+Comment[el]=Πρωτόκολλο για σύνδεση στο AIM
+Comment[es]=Protocolo para conectar a AIM
+Comment[et]=Protokoll ühendumiseks AIM-iga
+Comment[eu]=AIM-era konektatzeko protokoloa
+Comment[fa]=قرارداد برای اتصال به AIM
+Comment[fi]=Yhteyskäytäntö AIM-verkkoon kytkeytymiseen
+Comment[fr]=Protocole pour se connecter sur AIM
+Comment[ga]=Prótacal chun ceangal le AIM
+Comment[gl]=Protocolo para se conectar ó AIM
+Comment[he]=פרוטוקול התחברות ל- AIM
+Comment[hi]=से जुड़ने का प्रोटोकॉल
+Comment[hr]=Protokol za povezivanje na AIM
+Comment[hu]=Protokoll az AIM használatához
+Comment[is]=Samskiptamáti til að tengjast AIM
+Comment[it]=Protocollo per connessione a AIM
+Comment[ja]=AIM に接続するプロトコル
+Comment[ka]=AIM დაკავშირების ოქმი
+Comment[kk]=AIM-ге қосылу протоколы
+Comment[km]=ពិធីការ​ភ្ជាប់​ទៅ AIM
+Comment[lt]=Protokolas prisijungimui prie AIM
+Comment[mk]=Протокол за поврзување на AIM
+Comment[nb]=Protokoll for å koble til AIM
+Comment[nds]=Protokoll för't Tokoppeln na AIM
+Comment[ne]=एआईएम मा जडान गर्नुपर्ने प्रोटोकल
+Comment[nl]=Protocol voor AOL Instant Messenger
+Comment[nn]=Protokoll for å kopla til AIM
+Comment[pl]=Protokół połączenia z serwerem AIM
+Comment[pt]=Um protocolo para se ligar ao AIM
+Comment[pt_BR]=Protocolo de conexão ao AIM
+Comment[ro]=Protocol de conectare la AIM
+Comment[ru]=Протокол для подключения к AIM
+Comment[sk]=Protokol pre pripojenie k AIM
+Comment[sl]=Protokol za povezavo na AIM
+Comment[sr]=Протокол за повезивање на AIM
+Comment[sr@Latn]=Protokol za povezivanje na AIM
+Comment[sv]=Protokoll för att ansluta till AIM
+Comment[ta]=IRC உடன் இணைக்க விதிமுறை
+Comment[tg]=Қарордоди пайвастшавӣ ба AIM
+Comment[tr]=AIM'e bağlantı iletişim kuralı
+Comment[uk]=Протокол для з'єднання з AIM
+Comment[uz]=AIM bilan aloqa oʻrnatish uchun protokol
+Comment[uz@cyrillic]=AIM билан алоқа ўрнатиш учун протокол
+Comment[zh_CN]=连接到 AIM 协议
+Comment[zh_HK]=用來連接至 AIM 的通訊協定
+Comment[zh_TW]=連線到 AIM 的協定
diff --git a/kopete/protocols/oscar/aim/ui/Makefile.am b/kopete/protocols/oscar/aim/ui/Makefile.am
new file mode 100644
index 00000000..aa690449
--- /dev/null
+++ b/kopete/protocols/oscar/aim/ui/Makefile.am
@@ -0,0 +1,15 @@
+METASOURCES = AUTO
+AM_CPPFLAGS = $(KOPETE_INCLUDES) \
+ -I$(srcdir)/.. \
+ -I$(srcdir)/../.. \
+ -I$(srcdir)/../../liboscar \
+ $(all_includes)
+
+noinst_LTLIBRARIES = libkopeteaimui.la
+
+libkopeteaimui_la_SOURCES = aimaddcontactui.ui aimeditaccountui.ui \
+ aiminfobase.ui aimjoinchatbase.ui aimaddcontactpage.cpp aimeditaccountwidget.cpp
+
+libkopeteaimui_la_LIBADD = $(top_builddir)/kopete/libkopete/libkopete.la
+
+
diff --git a/kopete/protocols/oscar/aim/ui/aimaddcontactpage.cpp b/kopete/protocols/oscar/aim/ui/aimaddcontactpage.cpp
new file mode 100644
index 00000000..cf5fbae5
--- /dev/null
+++ b/kopete/protocols/oscar/aim/ui/aimaddcontactpage.cpp
@@ -0,0 +1,83 @@
+/***************************************************************************
+ description
+ -------------------
+ begin :
+ copyright : (C) 2002 by nbetcher
+ email : nbetcher@usinternet.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "aimaddcontactui.h"
+#include "aimaddcontactpage.h"
+
+#include "kopeteaccount.h"
+
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+AIMAddContactPage::AIMAddContactPage(bool connected, QWidget *parent,
+ const char *name )
+ : AddContactPage(parent,name)
+{
+ m_gui = 0;
+ (new QVBoxLayout(this))->setAutoAdd(true);
+
+ if(connected)
+ {
+ m_gui = new aimAddContactUI(this);
+ canadd = true;
+ }
+ else
+ {
+ noaddMsg1 = new QLabel(i18n("You need to be connected to be able to add contacts."), this);
+ noaddMsg2 = new QLabel(i18n("Connect to the AIM network and try again."), this);
+ canadd = false;
+ }
+}
+
+
+AIMAddContactPage::~AIMAddContactPage()
+{
+}
+
+bool AIMAddContactPage::validateData()
+{
+ if ( !canadd )
+ return false;
+
+ if ( !m_gui )
+ return false;
+
+ QString sn = m_gui->addSN->text();
+ if ( sn.isEmpty() )
+ {
+ KMessageBox::sorry ( this,
+ i18n("<qt>You must enter a valid screen name.</qt>"),
+ i18n("No Screen Name") );
+ return false;
+ }
+ return true;
+}
+
+bool AIMAddContactPage::apply(Kopete::Account *account,
+ Kopete::MetaContact *metaContact)
+{
+ if(validateData())
+ { // If everything is ok
+ return account->addContact( m_gui->addSN->text(), metaContact, Kopete::Account::ChangeKABC );
+ }
+ return false;
+}
+//kate: tab-width 4; indent-mode csands;
+
+#include "aimaddcontactpage.moc"
diff --git a/kopete/protocols/oscar/aim/ui/aimaddcontactpage.h b/kopete/protocols/oscar/aim/ui/aimaddcontactpage.h
new file mode 100644
index 00000000..979d0472
--- /dev/null
+++ b/kopete/protocols/oscar/aim/ui/aimaddcontactpage.h
@@ -0,0 +1,41 @@
+
+#ifndef AIMADDCONTACTPAGE_H
+#define AIMADDCONTACTPAGE_H
+
+#include <qwidget.h>
+#include <qlabel.h>
+#include "addcontactpage.h"
+
+class aimAddContactUI;
+class AIMAccount;
+namespace Kopete
+{
+class Account;
+class MetaContact;
+}
+
+class AIMAddContactPage : public AddContactPage
+{
+Q_OBJECT
+
+public:
+ AIMAddContactPage(bool connected, QWidget *parent=0,
+ const char *name=0);
+ ~AIMAddContactPage();
+
+ /** Validates the data entered */
+ virtual bool validateData();
+ /** Applies the addition to the account */
+ virtual bool apply( Kopete::Account *account, Kopete::MetaContact *);
+
+protected:
+ /** The actual GUI */
+ aimAddContactUI *m_gui;
+ QLabel *noaddMsg1;
+ QLabel *noaddMsg2;
+ bool canadd;
+};
+#endif
+
+//kate: tab-width 4; indent-mode csands;
+
diff --git a/kopete/protocols/oscar/aim/ui/aimaddcontactui.ui b/kopete/protocols/oscar/aim/ui/aimaddcontactui.ui
new file mode 100644
index 00000000..b3267eb0
--- /dev/null
+++ b/kopete/protocols/oscar/aim/ui/aimaddcontactui.ui
@@ -0,0 +1,64 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>aimAddContactUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>aimAddContactUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>455</width>
+ <height>131</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>GroupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Contact Information</string>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>addSN</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>AIM screen name:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+</widget>
+<tabstops>
+ <tabstop>addSN</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kopete/protocols/oscar/aim/ui/aimeditaccountui.ui b/kopete/protocols/oscar/aim/ui/aimeditaccountui.ui
new file mode 100644
index 00000000..d8a7b9f3
--- /dev/null
+++ b/kopete/protocols/oscar/aim/ui/aimeditaccountui.ui
@@ -0,0 +1,540 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>aimEditAccountUI</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>aimEditAccountUI</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>560</width>
+ <height>583</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Account Preferences - AIM</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>labelStatusMessage</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>tabWidget6</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Basic Setup</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox72</cstring>
+ </property>
+ <property name="title">
+ <string>Account Information</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>lblAccountId</cstring>
+ </property>
+ <property name="text">
+ <string>AIM &amp;screen name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>edtAccountId</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>The screen name of your AIM account.</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The screen name of your AIM account. This should be in the form of an alphanumeric string (spaces allowed, not case sensitive).</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>edtAccountId</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>The screen name of your AIM account.</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The screen name of your AIM account. This should be in the form of an alphanumeric string (spaces allowed, not case sensitive).</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="Kopete::UI::PasswordWidget" row="1" column="0">
+ <property name="name">
+ <cstring>mPasswordWidget</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="3" column="0">
+ <property name="name">
+ <cstring>mGlobalIdentity</cstring>
+ </property>
+ <property name="text">
+ <string>Exclu&amp;de from Global Identity</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>mAutoLogon</cstring>
+ </property>
+ <property name="text">
+ <string>E&amp;xclude from connect all</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If you check that case, the account will not be connected when you press the "Connect All" button, or at startup even if you selected to automatically connect at startup</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox5</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Registration</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>To connect to the AOL Instant Messaging network, you will need to use a screen name from AIM, AOL, or .Mac.&lt;br&gt;&lt;br&gt;If you do not currently have an AIM screen name, please click the button to create one.</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonRegister</cstring>
+ </property>
+ <property name="text">
+ <string>Re&amp;gister New Account</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>90</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Accou&amp;nt Preferences</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>groupBox73</cstring>
+ </property>
+ <property name="title">
+ <string>Connection Preferences</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>optionOverrideServer</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Override default server information</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout58</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>lblServer</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Ser&amp;ver:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>edtServerAddress</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>The IP address or hostmask of the AIM server you wish to connect to.</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The IP address or hostmask of the AIM server you wish to connect to. Normally you will want the default (login.oscar.aol.com).</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>edtServerAddress</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>login.oscar.aol.com</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>The IP address or hostmask of the AIM server you wish to connect to.</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The IP address or hostmask of the AIM server you wish to connect to. Normally you will want the default (login.oscar.aol.com).</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>lblPort</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Po&amp;rt:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>sbxServerPort</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>The port on the AIM server that you would like to connect to.</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The port on the AIM server that you would like to connect to. Normally this is 5190.</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>sbxServerPort</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maxValue">
+ <number>65534</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>5190</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>The port on the AIM server that you would like to connect to.</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The port on the AIM server that you would like to connect to. Normally this is 5190.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer21</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>200</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>encodingCombo</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Default to the following &amp;encoding for messages:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>encodingCombo</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Pri&amp;vacy</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QButtonGroup" row="0" column="0">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Visibility settings</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="2" column="0">
+ <property name="name">
+ <cstring>rbAllowPerimtList</cstring>
+ </property>
+ <property name="text">
+ <string>Allow only from visible list</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="1">
+ <property name="name">
+ <cstring>rbBlockAll</cstring>
+ </property>
+ <property name="text">
+ <string>Block all users</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="1">
+ <property name="name">
+ <cstring>rbBlockAIM</cstring>
+ </property>
+ <property name="text">
+ <string>Block AIM users</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="2" column="1">
+ <property name="name">
+ <cstring>rbBlockDenyList</cstring>
+ </property>
+ <property name="text">
+ <string>Block only from invisible list</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>rbAllowAll</cstring>
+ </property>
+ <property name="text">
+ <string>Allow all users</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>rbAllowMyContacts</cstring>
+ </property>
+ <property name="text">
+ <string>Allow only contact list's users</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>31</width>
+ <height>225</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>Kopete::UI::PasswordWidget</class>
+ <header location="local">kopetepasswordwidget.h</header>
+ <sizehint>
+ <width>50</width>
+ <height>50</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>1</hordata>
+ <verdata>0</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ <signal>changed()</signal>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>optionOverrideServer</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lblServer</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>optionOverrideServer</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>lblPort</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>optionOverrideServer</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>edtServerAddress</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>optionOverrideServer</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>sbxServerPort</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>tabWidget6</tabstop>
+ <tabstop>edtAccountId</tabstop>
+ <tabstop>mAutoLogon</tabstop>
+ <tabstop>buttonRegister</tabstop>
+ <tabstop>optionOverrideServer</tabstop>
+ <tabstop>edtServerAddress</tabstop>
+ <tabstop>sbxServerPort</tabstop>
+ <tabstop>encodingCombo</tabstop>
+ <tabstop>rbAllowAll</tabstop>
+ <tabstop>rbAllowMyContacts</tabstop>
+ <tabstop>rbAllowPerimtList</tabstop>
+ <tabstop>rbBlockAll</tabstop>
+ <tabstop>rbBlockAIM</tabstop>
+ <tabstop>rbBlockDenyList</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kopetepasswordwidget.h</includehint>
+</includehints>
+</UI>
diff --git a/kopete/protocols/oscar/aim/ui/aimeditaccountwidget.cpp b/kopete/protocols/oscar/aim/ui/aimeditaccountwidget.cpp
new file mode 100644
index 00000000..de720e17
--- /dev/null
+++ b/kopete/protocols/oscar/aim/ui/aimeditaccountwidget.cpp
@@ -0,0 +1,172 @@
+#include "aimeditaccountwidget.h"
+#include "aimeditaccountui.h"
+
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qlineedit.h>
+#include <qspinbox.h>
+
+#include <kdebug.h>
+#include <krun.h>
+#include <kpassdlg.h>
+#include <kconfig.h>
+
+#include "kopetepassword.h"
+#include "kopetepasswordwidget.h"
+
+#include "aimprotocol.h"
+#include "aimaccount.h"
+
+AIMEditAccountWidget::AIMEditAccountWidget( AIMProtocol *protocol,
+ Kopete::Account *account, QWidget *parent, const char *name )
+ : QWidget( parent, name ), KopeteEditAccountWidget( account )
+{
+ //kdDebug(14152) << k_funcinfo << "Called." << endl;
+
+ mAccount = dynamic_cast<AIMAccount*>( account );
+ mProtocol = protocol;
+
+ // create the gui (generated from a .ui file)
+ ( new QVBoxLayout( this ) )->setAutoAdd( true );
+ mGui = new aimEditAccountUI( this, "AIMEditAccountWidget::mGui" );
+
+ // Read in the settings from the account if it exists
+ if ( mAccount )
+ {
+ mGui->mPasswordWidget->load( &mAccount->password() );
+ mGui->edtAccountId->setText( account->accountId() );
+ //Remove me after we can change Account IDs (Matt)
+ mGui->edtAccountId->setDisabled( true );
+ mGui->mAutoLogon->setChecked( account->excludeConnect() );
+ QString serverEntry = account->configGroup()->readEntry( "Server", "login.oscar.aol.com" );
+ int portEntry = account->configGroup()->readNumEntry( "Port", 5190 );
+ if ( serverEntry != "login.oscar.aol.com" || portEntry != 5190 )
+ mGui->optionOverrideServer->setChecked( true );
+ else
+ mGui->optionOverrideServer->setChecked( false );
+
+ mGui->edtServerAddress->setText( serverEntry );
+ mGui->sbxServerPort->setValue( portEntry );
+
+ using namespace AIM::PrivacySettings;
+
+ int privacySetting = mAccount->configGroup()->readNumEntry( "PrivacySetting", AllowAll );
+ switch( privacySetting )
+ {
+ case AllowAll:
+ mGui->rbAllowAll->setChecked( true );
+ break;
+ case AllowMyContacts:
+ mGui->rbAllowMyContacts->setChecked( true );
+ break;
+ case AllowPremitList:
+ mGui->rbAllowPerimtList->setChecked( true );
+ break;
+ case BlockAll:
+ mGui->rbBlockAll->setChecked( true );
+ break;
+ case BlockAIM:
+ mGui->rbBlockAIM->setChecked( true );
+ break;
+ case BlockDenyList:
+ mGui->rbBlockDenyList->setChecked( true );
+ break;
+ default:
+ mGui->rbAllowAll->setChecked( true );
+ }
+
+ // Global Identity
+ mGui->mGlobalIdentity->setChecked( account->configGroup()->readBoolEntry("ExcludeGlobalIdentity", false) );
+ }
+ QObject::connect( mGui->buttonRegister, SIGNAL( clicked() ), this, SLOT( slotOpenRegister() ) );
+
+ /* Set tab order to password custom widget correctly */
+ QWidget::setTabOrder( mGui->edtAccountId, mGui->mPasswordWidget->mRemembered );
+ QWidget::setTabOrder( mGui->mPasswordWidget->mRemembered, mGui->mPasswordWidget->mPassword );
+ QWidget::setTabOrder( mGui->mPasswordWidget->mPassword, mGui->mAutoLogon );
+}
+
+AIMEditAccountWidget::~AIMEditAccountWidget()
+{}
+
+Kopete::Account *AIMEditAccountWidget::apply()
+{
+ kdDebug( 14152 ) << k_funcinfo << "Called." << endl;
+
+ // If this is a new account, create it
+ if ( !mAccount )
+ {
+ kdDebug( 14152 ) << k_funcinfo << "creating a new account" << endl;
+ QString newId = mGui->edtAccountId->text();
+ mAccount = new AIMAccount( mProtocol, newId );
+ }
+
+ mGui->mPasswordWidget->save( &mAccount->password() );
+
+ mAccount->setExcludeConnect( mGui->mAutoLogon->isChecked() ); // save the autologon choice
+ if ( mGui->optionOverrideServer->isChecked() )
+ {
+ static_cast<OscarAccount *>( mAccount )->setServerAddress( mGui->edtServerAddress->text() );
+ static_cast<OscarAccount *>( mAccount )->setServerPort( mGui->sbxServerPort->value() );
+ }
+ else
+ {
+ static_cast<OscarAccount *>( mAccount )->setServerAddress( "login.oscar.aol.com" );
+ static_cast<OscarAccount *>( mAccount )->setServerPort( 5190 );
+ }
+
+ using namespace AIM::PrivacySettings;
+ int privacySetting = AllowAll;
+
+ if ( mGui->rbAllowAll->isChecked() )
+ privacySetting = AllowAll;
+ else if ( mGui->rbAllowMyContacts->isChecked() )
+ privacySetting = AllowMyContacts;
+ else if ( mGui->rbAllowPerimtList->isChecked() )
+ privacySetting = AllowPremitList;
+ else if ( mGui->rbBlockAll->isChecked() )
+ privacySetting = BlockAll;
+ else if ( mGui->rbBlockAIM->isChecked() )
+ privacySetting = BlockAIM;
+ else if ( mGui->rbBlockDenyList->isChecked() )
+ privacySetting = BlockDenyList;
+
+ mAccount->configGroup()->writeEntry( "PrivacySetting", privacySetting );
+ mAccount->setPrivacySettings( privacySetting );
+
+ // Global Identity
+ mAccount->configGroup()->writeEntry( "ExcludeGlobalIdentity", mGui->mGlobalIdentity->isChecked() );
+ return mAccount;
+}
+
+bool AIMEditAccountWidget::validateData()
+{
+ //kdDebug(14152) << k_funcinfo << "Called." << endl;
+
+ QString userName = mGui->edtAccountId->text();
+ QString server = mGui->edtServerAddress->text();
+ int port = mGui->sbxServerPort->value();
+
+ if ( userName.length() < 1 )
+ return false;
+
+ if ( port < 1 )
+ return false;
+
+ if ( server.length() < 1 )
+ return false;
+
+ // Seems good to me
+ //kdDebug(14152) << k_funcinfo << "Account data validated successfully." << endl;
+ return true;
+}
+
+void AIMEditAccountWidget::slotOpenRegister()
+{
+ KRun::runURL( "http://my.screenname.aol.com/_cqr/login/login.psp?siteId=snshomepage&mcState=initialized&createSn=1", "text/html" );
+}
+
+#include "aimeditaccountwidget.moc"
+// vim: set noet ts=4 sts=4 sw=4:
diff --git a/kopete/protocols/oscar/aim/ui/aimeditaccountwidget.h b/kopete/protocols/oscar/aim/ui/aimeditaccountwidget.h
new file mode 100644
index 00000000..ccb2b451
--- /dev/null
+++ b/kopete/protocols/oscar/aim/ui/aimeditaccountwidget.h
@@ -0,0 +1,58 @@
+/*
+ AIMeditaccountwidget.h - AIM Account Widget
+
+ Copyright (c) 2003 by Chris TenHarmsel <tenharmsel@staticmethod.net>
+
+ Kopete (c) 2003 by the Kopete developers <kopete-devel@kde.org>
+
+ *************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ *************************************************************************
+*/
+
+
+#ifndef AIMEDITACCOUNTWIDGET_H
+#define AIMEDITACCOUNTWIDGET_H
+
+#include <qwidget.h>
+#include "editaccountwidget.h"
+/**
+ * @author Chris TenHarmsel <tenharmsel@staticmethod.net>
+ */
+
+namespace Kopete
+{
+class Account;
+}
+
+class AIMAccount;
+class AIMProtocol;
+class aimEditAccountUI;
+
+class AIMEditAccountWidget : public QWidget, public KopeteEditAccountWidget
+{
+Q_OBJECT
+
+public:
+ AIMEditAccountWidget(AIMProtocol *protocol, Kopete::Account *account,
+ QWidget *parent=0, const char *name=0);
+ virtual ~AIMEditAccountWidget();
+
+ virtual bool validateData();
+ virtual Kopete::Account *apply();
+
+private slots:
+ void slotOpenRegister();
+
+protected:
+ AIMAccount *mAccount;
+ AIMProtocol *mProtocol;
+ aimEditAccountUI *mGui;
+};
+#endif
+//kate: tab-width 4; indent-mode csands;
diff --git a/kopete/protocols/oscar/aim/ui/aiminfobase.ui b/kopete/protocols/oscar/aim/ui/aiminfobase.ui
new file mode 100644
index 00000000..db22a574
--- /dev/null
+++ b/kopete/protocols/oscar/aim/ui/aiminfobase.ui
@@ -0,0 +1,246 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>AIMUserInfoWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>AIMUserInfoWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>360</width>
+ <height>408</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>360</width>
+ <height>400</height>
+ </size>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout9</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>lblNickName</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Nickname:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>txtNickName</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>lblScreenName</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Screen name:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>txtScreenName</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout10</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>lblWarnLevel</cstring>
+ </property>
+ <property name="text">
+ <string>Warning level:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>txtWarnLevel</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>lblIdleTime</cstring>
+ </property>
+ <property name="text">
+ <string>Idle minutes:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>txtIdleTime</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout11</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>lblOnlineSince</cstring>
+ </property>
+ <property name="text">
+ <string>Online since:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>txtOnlineSince</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>lblAwayMessage</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Away message:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ </widget>
+ <widget class="KTextBrowser">
+ <property name="name">
+ <cstring>txtAwayMessage</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="textFormat">
+ <enum>AutoText</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Profile:</string>
+ </property>
+ </widget>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>userInfoFrame</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>64</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<tabstops>
+ <tabstop>txtNickName</tabstop>
+ <tabstop>txtScreenName</tabstop>
+ <tabstop>txtWarnLevel</tabstop>
+ <tabstop>txtIdleTime</tabstop>
+ <tabstop>txtOnlineSince</tabstop>
+ <tabstop>txtAwayMessage</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>ktextbrowser.h</includehint>
+</includehints>
+</UI>
diff --git a/kopete/protocols/oscar/aim/ui/aimjoinchatbase.ui b/kopete/protocols/oscar/aim/ui/aimjoinchatbase.ui
new file mode 100644
index 00000000..d1d93edf
--- /dev/null
+++ b/kopete/protocols/oscar/aim/ui/aimjoinchatbase.ui
@@ -0,0 +1,124 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>AIMJoinChatBase</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>AIMJoinChatBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>343</width>
+ <height>99</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Please enter the name of the chat room you wish to join.</string>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Maximum</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Room &amp;name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>roomName</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>E&amp;xchange:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>exchange</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="2">
+ <property name="name">
+ <cstring>roomName</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="3" column="2">
+ <property name="name">
+ <cstring>exchange</cstring>
+ </property>
+ </widget>
+ <spacer row="4" column="2">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>